removed old `core.string.reader`
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 7 Feb 2023 20:02:45 +0000 (14:02 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 7 Feb 2023 20:02:45 +0000 (14:02 -0600)
22 files changed:
core/conv/conv.onyx
core/std.onyx
core/string/reader.onyx [deleted file]
core/string/string.onyx
core/string/string_pool.onyx
tests/aoc-2020/day10.onyx
tests/aoc-2020/day11.onyx
tests/aoc-2020/day12.onyx
tests/aoc-2020/day13.onyx
tests/aoc-2020/day14.onyx
tests/aoc-2020/day15.onyx
tests/aoc-2020/day16.onyx
tests/aoc-2020/day17.onyx
tests/aoc-2020/day18.onyx
tests/aoc-2020/day19.onyx
tests/aoc-2020/day20.onyx
tests/aoc-2020/day21.onyx
tests/aoc-2020/day22.onyx
tests/aoc-2020/day25.onyx
tests/aoc-2020/day7.onyx
tests/aoc-2020/day8.onyx
tests/aoc-2020/day9.onyx

index a587266ac6cbcebe26549c70b45b8f12a8aa6303..b41e6e29f6ef2f099c98b0bffd880961554858a1 100644 (file)
@@ -17,6 +17,8 @@ str_to_i64 :: macro (s: str, base: u32 = 10) -> i64 {
 str_to_i64 :: (s: ^str, base: u32 = 10) -> i64 {
     use package core
 
+    string.strip_leading_whitespace(s);
+
     value: i64 = 0;
     mul := 1;
 
index c5e4af4514276f0fa6c43123b719c1884d0a5426..fd0eb0c830ef92c365031cdf0d9242674f505664 100644 (file)
@@ -24,7 +24,6 @@ package core
 #load "./hash/hash"
 
 #load "./string/string"
-#load "./string/reader"
 #load "./string/buffer"
 #load "./string/char_utils"
 #load "./string/string_pool"
diff --git a/core/string/reader.onyx b/core/string/reader.onyx
deleted file mode 100644 (file)
index 503c9d6..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-package core.string.reader
-
-String_Reader :: struct {
-    // Think of this as `use s : str`;
-    data : ^u8;
-    count : u32;
-
-    // The original string.
-    original_str : str;
-}
-
-make :: (s: str) -> String_Reader {
-    reader : String_Reader;
-    init(^reader, s);
-    return reader;
-}
-
-init :: (use reader: ^String_Reader, orig_str: str) {
-    original_str = orig_str;
-    data  = original_str.data;
-    count = original_str.count;
-}
-
-reset :: (use reader: ^String_Reader) {
-    data  = original_str.data;
-    count = original_str.count;
-}
-
-empty :: (use reader: ^String_Reader) -> bool do return count == 0;
-
-read_u32 :: (use reader: ^String_Reader) -> u32 {
-    n: u32 = 0;
-
-    skip_whitespace(reader);
-
-    while count > 0 && data[0] >= #char "0" && data[0] <= #char "9" {
-        n *= 10;
-        n += cast(u32) (data[0] - #char "0");
-
-        data += 1;
-        count -= 1;
-    }
-
-    return n;
-}
-
-read_u64 :: (use reader: ^String_Reader) -> u64 {
-    n: u64 = 0;
-
-    skip_whitespace(reader);
-
-    while count > 0 && data[0] >= #char "0" && data[0] <= #char "9" {
-        n *= 10;
-        n += cast(u64) (data[0] - #char "0");
-
-        data += 1;
-        count -= 1;
-    }
-
-    return n;
-}
-
-read_byte :: (use reader: ^String_Reader) -> u8 {
-    if count == 0 do return #char "\0";
-
-    defer {
-        data += 1;
-        count -= 1;
-    }
-
-    return data[0];
-}
-
-peek_byte :: (use reader: ^String_Reader) -> u8 do return data[0];
-
-read_bytes :: (use reader: ^String_Reader, byte_count := 1) -> str {
-    bc := byte_count;
-    if count < bc do bc = count;
-
-    defer {
-        data += bc;
-        count -= bc;
-    }
-
-    return str.{ data, bc };
-}
-
-read_line :: (use reader: ^String_Reader) -> str {
-    out : str;
-    out.data = data;
-    out.count = 0;
-
-    for ch: *(cast(^str) reader) {
-        if ch == #char "\n" do break;
-        out.count += 1;
-    }
-
-    data += out.count;
-    count -= out.count;
-
-    if count > 0 {
-        data += 1;
-        count -= 1;
-    }
-
-    return out;
-}
-
-read_until :: (use reader: ^String_Reader, skip: u32, uptos: ..u8) -> str {
-    if count == 0 do return str.{ null, 0 };
-
-    out : str;
-    out.data = data;
-    out.count = 0;
-
-    s := skip;
-    
-    for ch: *(cast(^str) reader) {
-        for upto: uptos do if ch == upto {
-            if s == 0 do break break;
-            else do s -= 1;
-
-            break;
-        }
-
-        out.count += 1;
-    }
-
-    data += out.count;
-    count -= out.count;
-
-    return out;
-}
-
-// Reads a continuous string of alphabetic chars along with underscores '_'
-read_word :: (use reader: ^String_Reader, numeric_allowed := false) -> str {
-    if count == 0 do return str.{ null, 0 };
-
-    out := str.{ data, 0 };
-    for ch: *(cast(^str) reader) {
-        if     (ch >= #char "a" && ch <= #char "z")
-            || (ch >= #char "A" && ch <= #char "Z")
-            || (numeric_allowed && (ch >= #char "0" && ch <= #char "9"))
-            || ch == #char "_" {
-            out.count += 1;            
-        }
-        else do break;
-    }
-
-    data += out.count;
-    count -= out.count;
-
-    return out;
-}
-
-advance_line :: (use reader: ^String_Reader) {
-    if count == 0 do return;
-
-    adv := 0;
-    while data[adv] != #char "\n" && adv <= count - 1 do adv += 1;
-
-    data += adv + 1;
-    count -= adv + 1;
-}
-
-
-skip_whitespace :: (use reader: ^String_Reader) {
-    while count > 0 do switch data[0] {
-        case #char " ", #char "\t", #char "\n", #char "\r" {
-            data += 1;
-            count -= 1;
-        }
-
-        case #default do return;
-    }
-}
-
-skip_bytes :: (use reader: ^String_Reader, byte_count := 1) {
-    bc := byte_count;
-    if count < bc do bc = count;
-
-    data += bc;
-    count -= bc;
-}
-
-
-
-starts_with :: (use reader: ^String_Reader, s: str) -> bool {
-    if count < s.count do return false;
-    while i := 0; i < s.count {
-        if data[i] != s[i] do return false;
-        i += 1;
-    }
-    return true;
-}
index 685282e2c254fd7f7bf5c99e5351b4d88e0c30c6..f3056d25600548298d45b055a6ba301812a4cd63 100644 (file)
@@ -541,7 +541,7 @@ advance_line :: (s: ^str) {
     if s.count == 0 do return;
 
     adv := 0;
-    while s.data[adv] != #char "\n" do adv += 1;
+    while s.data[adv] != #char "\n" && adv <= s.count do adv += 1;
 
     s.data += adv + 1;
     s.count -= adv + 1;
index 9a9514cadea739c5890e97da3b91f106e0a06374..4305e4493546d60f270635e40b6219f92cb7b9d7 100644 (file)
@@ -3,6 +3,16 @@ package core.string
 use core { alloc, memory }
 use core.alloc { arena }
 
+//
+// Many times, storing strings is annoying because you need
+// to keep the data alive, while moving pointers around and
+// changing them.
+//
+// To remedy this, a StringPool is a simple wrapper around
+// an arena allocator that enables you to quickly copy a
+// string to the pool. From there, you can use the string
+// until the pool is cleared or freed.
+//
 StringPool :: struct {
     arena: arena.Arena;
 }
@@ -13,11 +23,16 @@ StringPool :: struct {
     free  :: pool_free;
 }
 
+//
+// Creates a StringPool capable of storing a string of at
+// most `maximum_string_length` bytes.
 pool_make :: (maximum_string_length := 16384, allocator := context.allocator)
     => StringPool.{
-        arena.make(allocator, maximum_string_length * 2)
+        arena.make(allocator, maximum_string_length)
     }
 
+//
+// Copies a string into the pool, returning the copied string.
 pool_add :: (sp: ^StringPool, s: str) -> str {
     if s.count > sp.arena.arena_size do return "";
 
@@ -28,10 +43,14 @@ pool_add :: (sp: ^StringPool, s: str) -> str {
     return new_str;
 }
 
+//
+// Clears all entries in the pool.
 pool_flush :: (sp: ^StringPool) {
     arena.clear(^sp.arena);
 }
 
+//
+// Completely frees all memory in the pool.
 pool_free :: (sp: ^StringPool) {
     arena.free(^sp.arena);
 }
index 29a66ba023aed4baccbaa1e614184ca59f808e68..2c04665ed2cc71235a40326907e9f38872cd0bc9 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 count_ending_paths :: (nums: [..] u32) -> u64 {
     tally := array.make(u64, nums.count);
@@ -26,14 +25,14 @@ count_ending_paths :: (nums: [..] u32) -> u64 {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day10.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
     nums := array.make(u32);
     defer array.free(^nums);
 
-    while !reader.empty(^file) {
-        array.push(^nums, reader.read_u32(^file)); 
-        reader.advance_line(^file);
+    while !string.empty(file) {
+        array.push(^nums, ~~ conv.parse_int(^file)); 
+        string.advance_line(^file);
     }
 
     // Slight hack, but having 0 in the array makes both parts easier
index 40a5df5a1a3a649e3a939f2a8b7cf807ab6f26a2..a8c189d0894005180a317c7c3f124a099e33fd72 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 GameOfSeats :: struct {
     width  : u32;
@@ -68,7 +67,7 @@ gos_iter :: (use gos: ^GameOfSeats) -> bool {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day11.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
     gos : GameOfSeats;
     array.init(^gos.seats, 32);
@@ -76,8 +75,8 @@ main :: (args: [] cstr) {
 
     gos.height = 0;
 
-    while !reader.empty(^file) {
-        line := reader.read_line(^file);
+    while !string.empty(file) {
+        line, file' := string.bisect(file, #char "\n");
         for ch: line do switch ch {
             case #char "." do array.push(^gos.seats, SeatState.Floor);
             case #char "L" do array.push(^gos.seats, SeatState.Empty);
index 6269127dbf99e2b9b40b021b4a527b82dba15e2a..40b65009f4d07a9cd8817ae6238809233c70d267 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 Ship :: struct {
     x : i32 = 0;
@@ -35,13 +34,15 @@ turn_around :: (ship: ^Ship) {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day12.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
     ship := Ship.{ fx = 10, fy = -1 };
-    while !reader.empty(^file) {
-        dir := reader.read_byte(^file);
-        val := reader.read_u32(^file);
-        reader.advance_line(^file); 
+    while !string.empty(file) {
+        dir := file[0];
+        string.advance(^file, 1);
+
+        val := cast(u32, conv.parse_int(^file));
+        string.advance_line(^file); 
         
         switch dir {
             case #char "N" do ship.fy -= val;
index 97fe1603c98928120f34b2159f4087f11dcceacd..1134d7bad660b5bbcc5884c95be6e497add48482 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 inv_mod :: (a_: i64, m_: i64) -> i64 {
     if m_ <= 1 do return 0;
@@ -39,10 +38,10 @@ chinese_remainder_theorem :: (mods: [..] i64, rems: [..] i64) -> i64 {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day13.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
-    est := reader.read_u32(^file);
-    reader.advance_line(^file);
+    est := cast(u32, conv.parse_int(^file));
+    string.advance_line(^file);
 
     buses := array.make(i64);
     defer array.free(^buses);
@@ -51,15 +50,15 @@ main :: (args: [] cstr) {
     defer array.free(^rems);
 
     offset: i64 = 0;
-    while !reader.empty(^file) {
+    while !string.empty(file) {
         if *file.data == #char "x" {
-            reader.skip_bytes(^file, 2);
+            string.advance(^file, 2);
         } else {
-            bus := reader.read_u64(^file);
+            bus := conv.parse_int(^file);
             array.push(^buses, ~~bus);
             array.push(^rems, bus - offset);
 
-            reader.skip_bytes(^file, 1);
+            string.advance(^file, 1);
         }
 
         offset += 1;
index a5a333279f101578a1b21d95c8a2f317e7d94a73..152e4ced3bf7c79d3329bc54d1c9813e550a6593 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 MASK_SIZE :: 36
 Bitmask :: [MASK_SIZE] u8;
@@ -76,7 +75,7 @@ bitmask_p2 :: (mask: Bitmask, val: u64) -> Iterator(u64) {
 main :: (args: [] cstr) {
        contents := #file_contents "./tests/aoc-2020/input/day14.txt";
 
-       file := reader.make(contents);
+       file := contents;
 
        mem := map.make(u64, u64, default=0);
        defer map.free(^mem);
@@ -84,13 +83,14 @@ main :: (args: [] cstr) {
        mask : Bitmask;
        for ^m: mask do *m = 2;
 
-       while !reader.empty(^file) {
-               word := reader.read_word(^file);
+       while !string.empty(file) {
+               word := string.read_alphanum(^file);
                if string.equal(word, "mask") {
-                       reader.skip_bytes(^file, 3);
+            string.advance(^file, 3);
 
                        i := 35;
-                       while ch := reader.read_byte(^file); ch != #char "\n" {
+            m, file' := string.bisect(file, #char "\n");
+            for ch: m {
                                switch ch {
                                        case #char "0" do mask[i] = 0;
                                        case #char "1" do mask[i] = 1;
@@ -98,17 +98,15 @@ main :: (args: [] cstr) {
                                }
 
                                i -= 1;
-
-                               ch = reader.read_byte(^file);
                        }
                }
                elseif string.equal(word, "mem") {
-                       reader.skip_bytes(^file, 1);
+                       string.advance(^file, 1);
 
-                       addr := reader.read_u64(^file);
-                       reader.skip_bytes(^file, 4);
+                       addr := cast(u64, conv.parse_int(^file));
+                       string.advance(^file, 4);
 
-                       val := reader.read_u64(^file);
+                       val := cast(u64, conv.parse_int(^file));
 
                        // Part 1
                        // map.put(^mem, addr, bitmask_p1(mask, val));
@@ -118,7 +116,7 @@ main :: (args: [] cstr) {
                 map.put(^mem, real_addr, val);
             }
 
-                       reader.advance_line(^file);
+                       string.advance_line(^file);
                }       
        }       
 
index 50d2aa6179b8533f8c4a9e94afe1e3f540ad13eb..61317ff9d82f48823258dd1c1bc871a80dc57c1f 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 initial_numbers := u32.[ 1, 20, 8, 12, 0, 14 ];
 
index 1742a204a749c178e88665ea43b9ce8a20dd2c59..452cf76ceaa3309d16d8e9f86b806f901d59fa26 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 Field :: struct {
        name : str = "";
@@ -20,14 +19,14 @@ field_valid :: (use field: ^Field, n: u32) -> bool {
 
 total_scanning_error := 0;
 
-read_ticket_and_validate :: (file: ^reader.String_Reader, fields: [..] Field, ticket_store: ^u32) -> bool {
+read_ticket_and_validate :: (file: ^str, fields: [..] Field, ticket_store: ^u32) -> bool {
        retval := true;
 
        for i: 0 .. fields.count {
-               n := reader.read_u32(file);
+               n := cast(u32, conv.parse_int(file));
                ticket_store[i] = n;
 
-               if file.data[0] == #char "," do reader.skip_bytes(file, 1);
+               if file.data[0] == #char "," do string.advance(file, 1);
 
                valid_count := 0;
                for ^field: fields {
@@ -40,52 +39,52 @@ read_ticket_and_validate :: (file: ^reader.String_Reader, fields: [..] Field, ti
                }
        }
 
-       reader.advance_line(file);
+    string.advance_line(file);
        return retval;
 }
 
 main :: (args: [] cstr) {
        contents := #file_contents "./tests/aoc-2020/input/day16.txt";
 
-       file := reader.make(contents);
+       file := contents;
 
        fields := array.make(Field, 20);
        defer array.free(^fields);
 
        // Read until the first empty line
-       while *file.data != #char "\n" {
+       while file.data[0] != #char "\n" {
                field := Field.{};
-               field.name = reader.read_until(^file, 0, #char ":");            
+               field.name, file = string.bisect(file, #char ":");              
 
-               reader.skip_bytes(^file, 2);
-               field.lower0 = reader.read_u32(^file);
+               string.advance(^file, 1);
+               field.lower0 = ~~ conv.parse_int(^file);
 
-               reader.skip_bytes(^file, 1);
-               field.upper0 = reader.read_u32(^file);
+               string.advance(^file, 1);
+               field.upper0 = ~~ conv.parse_int(^file);
 
-               reader.skip_bytes(^file, 4);
-               field.lower1 = reader.read_u32(^file);
+               string.advance(^file, 4);
+               field.lower1 = ~~ conv.parse_int(^file);
 
-               reader.skip_bytes(^file, 1);
-               field.upper1 = reader.read_u32(^file);
+               string.advance(^file, 1);
+               field.upper1 = ~~ conv.parse_int(^file);
 
-               reader.advance_line(^file);
+               string.advance_line(^file);
 
                array.push(^fields, field);
        }
 
-       for i: 0 .. 2 do reader.advance_line(^file);
+       for i: 0 .. 2 do string.advance_line(^file);
 
        my_ticket := array.make(u32, fields.count);
        defer array.free(^my_ticket);
        read_ticket_and_validate(^file, fields, my_ticket.data);
 
-       for i: 0 .. 2 do reader.advance_line(^file);
+       for i: 0 .. 2 do string.advance_line(^file);
 
        ticket_data := array.make(u32, 1024);
        defer array.free(^ticket_data);
 
-       while !reader.empty(^file) {
+       while !string.empty(file) {
                array.ensure_capacity(^ticket_data, ticket_data.count + fields.count);
                if read_ticket_and_validate(^file, fields, ^ticket_data[ticket_data.count]) {
                        ticket_data.count += fields.count;
index 916bb576b916810a50b2e3cdb142abfefdcb3494..6be8030702e529f65aa0314589fb38cd52434c9c 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use core
-use core.string {reader}
 
 OverloadsEqual :: interface (t: $T) {
     { T.equals(t, t) } -> bool;
@@ -54,14 +53,14 @@ get_neighbor_count :: (cubes: ^Map(CubePos, CubeState), pos: CubePos) -> u32 {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day17.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
     cubes := map.make(CubePos, CubeState, .{});
     defer map.free(^cubes);
 
     z := 0;
-    while !reader.empty(^file) {
-        line := reader.read_line(^file);
+    while !string.empty(file) {
+        line, file' := string.bisect(file, #char "\n");
 
         x := 0;
         for ch: line {
index 1d7981056ff9f432246052febb1b1eb879548a05..0a8e0cb45c615ffefec92412a368a774e31d2671 100644 (file)
@@ -1,24 +1,22 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
-parse_factor :: (file: ^reader.String_Reader) -> u64 {
-       reader.skip_whitespace(file);
+parse_factor :: (file: ^str) -> u64 {
+       string.strip_leading_whitespace(file);
 
        switch *file.data {
-               // Now may be a good time to add a range based case statement...
                case #char "0" .. #char "9" {
-                       return reader.read_u64(file);
+                       return conv.parse_int(file);
                }
 
                case #char "(" {
-                       reader.skip_bytes(file, 1);
+            string.advance(file, 1);
 
                        value := parse_expression_mul(file);
 
-                       reader.skip_whitespace(file);
-                       reader.skip_bytes(file, 1);
+            string.strip_leading_whitespace(file);
+            string.advance(file, 1);
 
                        return value;
                }
@@ -27,37 +25,41 @@ parse_factor :: (file: ^reader.String_Reader) -> u64 {
        return 0;
 }
 
-parse_expression_add :: (file: ^reader.String_Reader) -> u64 {
-       reader.skip_whitespace(file);
+parse_expression_add :: (file: ^str) -> u64 {
+       string.strip_leading_whitespace(file);
 
        left := parse_factor(file);
 
-       reader.skip_whitespace(file);
+       string.strip_leading_whitespace(file);
        while *file.data == #char "+" {
-               op := reader.read_byte(file);
+               op    := file.data[0];
+        string.advance(file, 1);
+
                right := parse_factor(file);
 
                left += right;
 
-               reader.skip_whitespace(file);
+               string.strip_leading_whitespace(file);
        }
 
        return left;
 }
 
-parse_expression_mul :: (file: ^reader.String_Reader) -> u64 {
-       reader.skip_whitespace(file);
+parse_expression_mul :: (file: ^str) -> u64 {
+    string.strip_leading_whitespace(file);
 
        left := parse_expression_add(file);
 
-       reader.skip_whitespace(file);
+    string.strip_leading_whitespace(file);
        while *file.data == #char "*" {
-               op   := reader.read_byte(file);
+               op    := file.data[0];
+        string.advance(file, 1);
+
                right := parse_expression_add(file);
 
                left *= right;
 
-               reader.skip_whitespace(file);
+               string.strip_leading_whitespace(file);
        }
 
        return left;
@@ -65,11 +67,10 @@ parse_expression_mul :: (file: ^reader.String_Reader) -> u64 {
 
 main :: (args: [] cstr) {
        contents := #file_contents "./tests/aoc-2020/input/day18.txt";
-
-       file := reader.make(contents);
+    file := contents;
 
        total: u64 = 0;
-       while !reader.empty(^file) {
+       while !string.empty(file) {
                total += parse_expression_mul(^file);
        }
 
index 9bc9bb526e9575a1cee16ce47b9332139c0be25c..202e53a096d1678b4999ad82742cf37d2e2c1159 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 // nt -> t
 Term :: struct {
@@ -108,45 +107,46 @@ cyk_algorithm :: (use grammar: ^Grammar, input: str) -> bool {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day19.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
     grammar : Grammar;
     grammar_init(^grammar);
     defer grammar_free(^grammar);
 
     while *file.data != #char "\n" {
-        nt0 := reader.read_u32(^file);
+        nt0 := cast(u32, conv.parse_int(^file));
 
-        reader.skip_bytes(^file, 2); // ': '
+        string.advance(^file, 2); // ': '
 
         if *file.data == #char "\"" {
-            reader.skip_bytes(^file, 1); // '"'
-            t := reader.read_byte(^file);
+            string.advance(^file, 1); // '"'
+            t := file[0];
+            string.advance(^file, 1);
 
             array.push(^grammar.terminate_rules, Term.{ nt0, t });
 
         } else {
             while true {
-                nt1 := reader.read_u32(^file);
+                nt1 := cast(u32, conv.parse_int(^file));
 
                 if *file.data == #char "\n" {
                     array.push(^grammar.unit_rules, Unit.{ nt0, nt1 });
                     break;
 
                 } else {
-                    reader.skip_bytes(^file, 1); // ' '
+                    string.advance(^file, 1); // ' '
 
                     if next_ch := *file.data; next_ch >= #char "0" && next_ch <= #char "9" {
-                        nt2 := reader.read_u32(^file);
+                        nt2 := cast(u32, conv.parse_int(^file));
                         array.push(^grammar.production_rules, Prod.{ nt0, nt1, nt2 });
 
-                        if *file.data == #char " " do reader.skip_bytes(^file, 1);
+                        if *file.data == #char " " do string.advance(^file, 1);
                     } else {
                         array.push(^grammar.unit_rules, Unit.{ nt0, nt1 });
                     }
 
                     if *file.data == #char "|" {
-                        reader.skip_bytes(^file, 1); // ' |'
+                        string.advance(^file, 1); // ' |'
                     } else {
                         break;
                     }
@@ -154,15 +154,15 @@ main :: (args: [] cstr) {
             }
         }
 
-        reader.advance_line(^file);
+        string.advance_line(^file);
     }
 
     grammar_prepare(^grammar);
 
     valid_count := 0;
-    reader.advance_line(^file);
-    while !reader.empty(^file) {
-        line := reader.read_line(^file);
+    string.advance_line(^file);
+    while !string.empty(file) {
+        line, file' := string.bisect(file, #char "\n");
         if cyk_algorithm(^grammar, line) do valid_count += 1;
     }
 
index 9cdd389e394275f0ada7e965caa9a1277bf74cdb..6c4bf7ed4f29a6f3659b9d41addc5d1d3ddeaefd 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 TILE_DATA_WIDTH  :: 10
 TILE_DATA_HEIGHT :: 10
@@ -241,7 +240,7 @@ scan_for_monsters :: (forest: ^u8, ori: TO, width: u32, height: u32) -> bool {
 main :: (args: [] cstr) {
        contents := #file_contents "./tests/aoc-2020/input/day20.txt";
 
-       file := reader.make(contents);  
+       file := contents;       
 
        tiles := array.make(Tile);
        defer array.free(^tiles);
@@ -259,16 +258,16 @@ main :: (args: [] cstr) {
        tile_data_ring := alloc.ring.make(.{ ~~ tile_data, 200 * sizeof TileData });
        tile_allocator := alloc.ring.make_allocator(^tile_data_ring);
 
-       while !reader.empty(^file) {
-               reader.read_word(^file); // 'Tile '
-               id := reader.read_u32(^file);
+       while !string.empty(file) {
+               string.advance(^file, 5); // 'Tile '
+               id := cast(u32, conv.parse_int(^file));
 
-               reader.advance_line(^file);
+               string.advance_line(^file);
 
                td := cast(^bool) raw_alloc(tile_allocator, sizeof TileData);
 
                for y: 0 .. 10 {
-                       line := reader.read_line(^file);
+                       line, file' := string.bisect(file, #char "\n");
 
                        for x: 0 .. 10 {
                                td[x + y * TILE_DATA_WIDTH] = (line[x] == #char "#");
@@ -285,7 +284,7 @@ main :: (args: [] cstr) {
                        edges = edges,
                });
 
-               reader.advance_line(^file);
+               string.advance_line(^file);
        }
 
     for ^t: tiles do map.put(^tile_map, t.id, t);
index f45788724d6060b3d165e52afd4405d3c46c51f8..6e1c6c037e8262a693f5275555ba46601058aede 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 /*
        What questions the data layout needs to answer easily:
@@ -34,7 +33,7 @@ allergen_map   : map.Map(str, Allergen);
 main :: (args: [] cstr) {
        contents := #file_contents "./tests/aoc-2020/input/day21.txt";
 
-       file := reader.make(contents);
+       file := contents;
 
     map.init(^ingredient_map, .{});
     map.init(^allergen_map, .{});
@@ -47,14 +46,14 @@ main :: (args: [] cstr) {
     defer array.free(^foods);
 
     line_num := 0;
-       while !reader.empty(^file) {
+       while !string.empty(file) {
         food : Food;
         array.init(^food.ingredients, 16);
         array.init(^food.allergens);
 
         while *file.data != #char "(" {
-            ingredient_name := reader.read_word(^file);
-            reader.skip_bytes(^file, 1); // ' '
+            ingredient_name := string.read_alphanum(^file);
+            string.advance(^file, 1); // ' '
 
             array.push(^food.ingredients, ingredient_name);
 
@@ -69,11 +68,11 @@ main :: (args: [] cstr) {
             map.put(^ingredient_map, ingredient_name, ingredient);
         }
 
-        reader.skip_bytes(^file, 10); // '(contains '
+        string.advance(^file, 10); // '(contains '
 
         while *file.data != #char ")" {
-            allergen_name := reader.read_word(^file);
-            if *file.data == #char "," do reader.skip_bytes(^file, 2); // ', '
+            allergen_name := string.read_alphanum(^file);
+            if *file.data == #char "," do string.advance(^file, 2); // ', '
 
             array.push(^food.allergens, allergen_name);
 
@@ -90,7 +89,7 @@ main :: (args: [] cstr) {
 
         array.push(^foods, food);
         
-        reader.advance_line(^file);
+        string.advance_line(^file);
         line_num += 1;
        }
 
index 077477b8c3d052b5e5e95ecb1c6c91448986c655..3dcc7c9569bb75097e85b34d62316dd147248313 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 key_arena : alloc.arena.ArenaState;
 key_alloc : Allocator;
@@ -103,28 +102,28 @@ recursive_combat :: (player1: ^[..] u32, player2: ^[..] u32) -> u32 {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day22.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
     player1 := array.make(u32);
     player2 := array.make(u32);
     defer array.free(^player1);
     defer array.free(^player2);
 
-    reader.advance_line(^file); // 'Player 1:'
+    string.advance_line(^file); // 'Player 1:'
     while *file.data != #char "\n" {
-        card := reader.read_u32(^file);
+        card := cast(u32, conv.parse_int(^file));
         array.push(^player1, card);
 
-        reader.advance_line(^file);
+        string.advance_line(^file);
     }
 
-    reader.advance_line(^file); // '\n'
-    reader.advance_line(^file); // 'Player 2:'
-    while !reader.empty(^file) {
-        card := reader.read_u32(^file);
+    string.advance_line(^file); // '\n'
+    string.advance_line(^file); // 'Player 2:'
+    while !string.empty(file) {
+        card := cast(u32, conv.parse_int(^file));
         array.push(^player2, card);
 
-        reader.advance_line(^file);
+        string.advance_line(^file);
     }
 
     {
index 5d47bfaead120331f5e73673f002e483c0083616..75a5904979fce49c2a367151f2faeb87ce5d93cc 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 power_mod :: (base: u32, exp: u32, mod: u32) -> u32 {
     t: u64 = 1;
@@ -55,10 +54,10 @@ transform_subject :: (subject: u32, loop_size: u32) -> u32 {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day25.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
-    card_pub_key := reader.read_u32(^file);
-    door_pub_key := reader.read_u32(^file);
+    card_pub_key := cast(u32, conv.parse_int(^file));
+    door_pub_key := cast(u32, conv.parse_int(^file));
 
     card_loop_secret := dlp_bsgs(20201227, 7, card_pub_key);
     door_loop_secret := dlp_bsgs(20201227, 7, door_pub_key);
index 434e70fb81abb1062f96db87599286d217d0ed49..5cea2f585a300bd144dd15c125dd73db8a2ea6af 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 BagGraph :: struct {
     nodes    : [..] ^BagNode;
@@ -53,27 +52,27 @@ bg_get_node :: (use graph: ^BagGraph, name: str) -> ^BagNode {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day7.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
     graph : BagGraph;
     bg_init(^graph);
     defer bg_free(^graph);
 
     while true {
-        name := reader.read_until(^file, 1, #char " ");
+        name := string.read_until(^file, #char " ", 1);
         if name.count == 0 do break;
 
         container := bg_get_node(^graph, name);
 
-        reader.read_until(^file, 2, #char " ");
+        string.read_until(^file, #char " ", 2);
 
         while true {
-            if reader.starts_with(^file, " no") do break;
+            if string.starts_with(file, " no") do break;
 
-            count := reader.read_u32(^file);
-            reader.skip_bytes(^file, 1);
+            count := cast(u32, conv.parse_int(^file));
+            string.advance(^file, 1);
 
-            contained_name := reader.read_until(^file, 1, #char " ");
+            contained_name := string.read_until(^file, #char " ", 1);
             contained := bg_get_node(^graph, contained_name);
 
             // Part 1
@@ -85,11 +84,11 @@ main :: (args: [] cstr) {
             // Part 2
             array.push(^container.contain, .{ bag = contained, count = count });
 
-            bag_word := reader.read_until(^file, 1, #char " ", #char "\n");
+            bag_word := string.read_until_any(^file, 1, #char " ", #char "\n");
             if bag_word[bag_word.count - 1] == #char "." do break;
         }
 
-        reader.advance_line(^file);
+        string.advance_line(^file);
     }
 
     // Part 1
index d121d690a78950cf69fa4c5242fb459bc68185a7..842c4cd2e56b3a0d1befcb9e3ca667f0278611c3 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 OpCode :: enum (u16) {
     Nop; Acc; Jmp;
@@ -46,19 +45,20 @@ get_acc_value :: (instrs: [..] Instruction, ret_acc: ^i32) -> bool {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day8.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
     instrs := array.make(Instruction, 32);
     defer array.free(^instrs);
 
-    while !reader.empty(^file) {
-        word := reader.read_bytes(^file, 3);
-        reader.skip_bytes(^file, 1);
+    while !string.empty(file) {
+        word := file.data[0 .. 3];
+        string.advance(^file, 4);
 
-        sign := reader.read_byte(^file);
-        val := cast(i32) reader.read_u32(^file);
+        sign := file.data[0];
+        string.advance(^file, 1);
+        val := cast(i32) conv.parse_int(^file);
 
-        reader.advance_line(^file);
+        string.advance_line(^file);
 
         if sign == #char "-" do val *= -1;
 
index 9bcd661fe8cb4391bd0cf270f5c448476376731a..9acb88f23549364d709d38ec4bd3b68d076719ed 100644 (file)
@@ -1,7 +1,6 @@
 #load "core/std"
 
 use package core
-reader :: package core.string.reader
 
 find_contiguous_subarray_with_sum :: (nums: [..] u64, sum: u64) -> (i32, i32) {
     start := 0;
@@ -28,13 +27,13 @@ find_contiguous_subarray_with_sum :: (nums: [..] u64, sum: u64) -> (i32, i32) {
 main :: (args: [] cstr) {
     contents := #file_contents "./tests/aoc-2020/input/day9.txt";
 
-    file := reader.make(contents);
+    file := contents;
 
     nums := array.make(u64, 32);
     defer array.free(^nums);
 
-    while !reader.empty(^file) {
-        num := reader.read_u64(^file);
+    while !string.empty(file) {
+        num := conv.parse_int(^file);
         array.push(^nums, num);
     }