Skip to content

Commit

Permalink
Commented the stdlib a bit, making things look good
Browse files Browse the repository at this point in the history
  • Loading branch information
mauro-balades committed Jan 24, 2024
1 parent f1e192f commit 7a3d251
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 44 deletions.
103 changes: 89 additions & 14 deletions stdlib/fs/fstream.sn
Original file line number Diff line number Diff line change
@@ -1,22 +1,64 @@
@use_macro(assert)
import std::asserts;
import std::stream;
import std::fs::file;
import std::fs::file::{File};

/**
* @brief A class implementing the `ReadStream` interface to read lines from an input file.
* @tparam String The type of data elements in the stream.
*
* The `InputFileStream` class facilitates reading lines from a specified input file. It implements the `ReadStream`
* interface, allowing the sequential retrieval of lines until the end of the file is reached. The class maintains an
* internal buffer to efficiently handle file reading operations and provides methods to query the end-of-file status.
*
* @note This class assumes that the input file is opened and available for reading.
*
* ```snowball
* // Opening an input file stream.
* let inputFile = std::fs::file::open("input.txt", std::fs::file::Mode::Read);
* let inputStream = new InputFileStream(inputFile);
*
* // Reading lines from the input file.
* while (!inputStream.eof()) {
* let line = inputStream.read();
* // Process the line...
* }
* ```
*/
public class InputFileStream implements stream::ReadStream<String> {
let mut file: file::File;
/**
* The file object representing the input file.
*/
let mut file: File;
/**
* A buffer to store read data from the file.
*/
let mut buffer: String;
/**
* The current position in the buffer.
*/
let mut pos: i32;
/**
* A flag indicating whether the end of the file has been reached.
*/
let mut eof: bool;

public:
InputFileStream(mut file: file::File) : file(file), buffer(file.read()), pos(0), eof(false) {}

/**
* @brief Constructs an `InputFileStream` object with an input file.
* @param[in] file The input file to read from.
* @remark The constructor initializes the file, buffer, position, and end-of-file flag.
*/
InputFileStream(mut file: File) : file(file), buffer(file.read()), pos(0), eof(false) {}
/**
* @brief Reads the next line from the input file.
* @return The next line from the input file.
* @remark The `read` method reads lines from the input file until a newline character is encountered.
* It returns an empty string when the end of the file is reached.
*/
mut func read() String {
if self.eof {
return "";
}

let mut result = "";
while (true) {
if self.pos >= self.buffer.size() {
Expand All @@ -27,7 +69,6 @@ public class InputFileStream implements stream::ReadStream<String> {
break;
}
}

let c = self.buffer[self.pos];
self.pos = self.pos + 1;
if c == '\n' {
Expand All @@ -37,19 +78,53 @@ public class InputFileStream implements stream::ReadStream<String> {
}
return result;
}

/**
* @brief Checks if the end of the input file has been reached.
* @return `true` if the end of the file has been reached, `false` otherwise.
* @remark The `eof` method provides a quick check for determining whether the end of the file has been reached.
*/
@inline
func eof() bool {
return self.eof;
}
}

/**
* @brief A class implementing the `WriteStream` interface to write data to an output file.
* @tparam String The type of data elements in the stream.
*
* The `OutputFileStream` class facilitates writing data to a specified output file. It implements the `WriteStream`
* interface, allowing the sequential appending of data to the file. The class provides a convenient wrapper for
* file writing operations and ensures that the data is written to the specified file.
*
* @note This class assumes that the output file is opened and available for writing.
*
* @example
* ```snowball
* // Opening an output file stream.
* let outputFile = std::fs::file::open("output.txt", std::fs::file::Mode::Write);
* let outputStream = new OutputFileStream(outputFile);
*
* // Writing data to the output file.
* outputStream.write("Hello, World!");
* outputStream.write("This is a test.");
* ```
*/
public class OutputFileStream implements stream::WriteStream<String> {
let mut file: file::File;

public:
OutputFileStream(mut file: file::File) : file(file) {}

/**
* The file object representing the output file.
*/
let mut file: File;
/**
* @brief Constructs an `OutputFileStream` object with an output file.
* @param[in] file The output file to write to.
* @remark The constructor initializes the file object.
*/
public: OutputFileStream(mut file: File) : file(file) {}
/**
* @brief Writes the provided data to the output file.
* @param[in] data The data to write to the output file.
* @remark The `write` method appends the provided data to the output file.
*/
@inline
func write(data: String) {
self.file.write(data);
Expand Down
2 changes: 0 additions & 2 deletions stdlib/fs/path.sn
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import std::env;
import std::c_bindings;

// TODO: support all platforms

@cfg(target_os="windows")
@export
macro PATH_SEPARATOR() = "\\";
Expand Down
1 change: 0 additions & 1 deletion stdlib/internal/integers.sn
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ const DEC_DIGITS_LUT: *const u8 = b"\
class extends IntegerImpl {
public:
func to_string(self: IntegerType) String {
// TODO: float impl
// TODO: static assert sizeof is larger than 2

// Copy the number value to a local variable, so we can modify it.
Expand Down
2 changes: 1 addition & 1 deletion stdlib/math.sn
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public external func "llvm.sqrt.f64" as sqrt(f64) f64;
* @return The minimum of the two given numbers.
*/
public func min<T: Numeric>(x: T, y: T) T
{ if x < y { return x } else { return y } } // TODO: importternary operator once implemented
{ if x < y { return x } else { return y } } // TODO: ternary operator once implemented
/**
* @brief The number we all know, love and hate.
* The constant value of pi, accurate to 35 decimal places.
Expand Down
66 changes: 46 additions & 20 deletions stdlib/rand.sn
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,59 @@
import std::ptr;
import std::c_bindings;

/**
* @brief A class representing a generic random number generator.
* Provides a virtual method `rand_int` for generating random unsigned 64-bit integers.
* TODO: make it abstract once abstract classes are implemented
*/
public class RandomGenerator {
public:
RandomGenerator() {}
virtual func rand_int() u64 {}
/**
* @brief Default constructor for the `RandomGenerator` class.
*/
public: RandomGenerator() {}
/**
* @brief Generates a random unsigned 64-bit integer.
* @return A random unsigned 64-bit integer.
*/
virtual func rand_int() u64 {}
}

/**
* @brief A class extending `RandomGenerator` and implementing the linear congruential generator (LCG) algorithm.
* The LCG algorithm is used to generate random unsigned 64-bit integers.
* TODO: make it final once final classes are implemented
*/
public class DefaultRNG extends RandomGenerator {
private:
let mut seed: u64 = 0;
public:
DefaultRNG() : super() {}

@inline
override virtual mut func rand_int() u64 {
// We use the linear congruential generator (LCG) algorithm.
if self.seed == 0 {
unsafe {
self.seed = c_bindings::time(ptr::null_ptr<?i32>()) as u64;
}
/**
* The seed value used in the LCG algorithm.
*/
let mut seed: u64 = 0;
/**
* @brief Default constructor for the `DefaultRNG` class.
* @remark The constructor initializes the seed to 0.
*/
public: DefaultRNG() : super() {}
/**
* @brief Generates a random unsigned 64-bit integer using the linear congruential generator (LCG) algorithm.
* @return A random unsigned 64-bit integer.
* @remark If the seed is 0, it initializes the seed using the current time.
*/
@inline
override virtual mut func rand_int() u64 {
// We use the linear congruential generator (LCG) algorithm.
if self.seed == 0 {
unsafe {
self.seed = c_bindings::time(ptr::null_ptr<?i32>()) as u64;
}
self.seed = (self.seed * 1103515245U + 12345U) & 0x7fffffffU;
return self.seed;
}
// LCG algorithm for generating random unsigned 64-bit integers.
self.seed = (self.seed * 1103515245U + 12345U) & 0x7fffffffU;
return self.seed;
}
}

/**
* Global variable representing the default random number generator.
*/
let mut _global_rng: RandomGenerator = new DefaultRNG() as RandomGenerator;

/**
* @brief It generates a random number between 0 and RAND_MAX.
* @return A random number between 0 and RAND_MAX.
Expand Down
4 changes: 2 additions & 2 deletions stdlib/std.sn
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ public class StringView<Char: Sized = u8> implements ToString, Clone<Self> {
// If the index is greater than or equal to the length of the string view,
// we throw an IndexError. We make sure we don't overflow.
// todo: add a better error message
throw new IndexError("Index out of bounds.");
throw new IndexError("Index out of bounds!");
}
// safety: we are praying to the gods that the buffer is not null.
// if the buffer is null, we are in trouble. It should never be null.
Expand Down Expand Up @@ -787,7 +787,7 @@ public class StringView<Char: Sized = u8> implements ToString, Clone<Self> {
return self.substr((range.begin())..(self.length + range.stop()));
} else if (range.stop() > self.length) || (range.begin() > self.length) {
// TODO: add a better error message
throw new IndexError("Index out of bounds.");
throw new IndexError("Index out of bounds!");
}
// safety: we make sure the buffer is not null. Unless explicitly trying to make us look bad.
// or something whent wrong on the C side. But unless that happens, the buffer should never be null.
Expand Down
4 changes: 0 additions & 4 deletions tests/numbers.sn
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ func to_string() i32 {
assert!((1 as i32).to_string() == "1")
assert!((1 as i16).to_string() == "1")
assert!((1 as i8).to_string() == "1")
// TODO: floats
//assert!((1 as f64).to_string() == "1.000000")
//assert!((1 as f32).to_string() == "1.000000")

assert!((-1 as i64).to_string() == "-1")
assert!((-1 as i32).to_string() == "-1")
assert!((-1 as i16).to_string() == "-1")
Expand Down

0 comments on commit 7a3d251

Please sign in to comment.