diff --git a/stdlib/fs/fstream.sn b/stdlib/fs/fstream.sn index 33b97cdf..73a05253 100644 --- a/stdlib/fs/fstream.sn +++ b/stdlib/fs/fstream.sn @@ -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 { - 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() { @@ -27,7 +69,6 @@ public class InputFileStream implements stream::ReadStream { break; } } - let c = self.buffer[self.pos]; self.pos = self.pos + 1; if c == '\n' { @@ -37,19 +78,53 @@ public class InputFileStream implements stream::ReadStream { } 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 { - 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); diff --git a/stdlib/fs/path.sn b/stdlib/fs/path.sn index 0c1c2898..3026ab2f 100644 --- a/stdlib/fs/path.sn +++ b/stdlib/fs/path.sn @@ -1,8 +1,6 @@ import std::env; import std::c_bindings; -// TODO: support all platforms - @cfg(target_os="windows") @export macro PATH_SEPARATOR() = "\\"; diff --git a/stdlib/internal/integers.sn b/stdlib/internal/integers.sn index 48107646..dbc61afd 100644 --- a/stdlib/internal/integers.sn +++ b/stdlib/internal/integers.sn @@ -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. diff --git a/stdlib/math.sn b/stdlib/math.sn index 46a20457..534ee84b 100644 --- a/stdlib/math.sn +++ b/stdlib/math.sn @@ -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(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. diff --git a/stdlib/rand.sn b/stdlib/rand.sn index fba03538..0a557446 100644 --- a/stdlib/rand.sn +++ b/stdlib/rand.sn @@ -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()) 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()) 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. diff --git a/stdlib/std.sn b/stdlib/std.sn index 9b560bf4..0bf104f8 100644 --- a/stdlib/std.sn +++ b/stdlib/std.sn @@ -758,7 +758,7 @@ public class StringView implements ToString, Clone { // 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. @@ -787,7 +787,7 @@ public class StringView implements ToString, Clone { 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. diff --git a/tests/numbers.sn b/tests/numbers.sn index 36d82198..3e6fbe40 100644 --- a/tests/numbers.sn +++ b/tests/numbers.sn @@ -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")