added 'StringReader'; subpackage bugfix
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 9 Dec 2020 04:25:21 +0000 (22:25 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 9 Dec 2020 04:25:21 +0000 (22:25 -0600)
core/std/js.onyx
core/std/wasi.onyx
core/string/reader.onyx [new file with mode: 0644]
include/onyxutils.h
onyx
src/onyxparser.c
src/onyxutils.c

index 8dfb8d975214ab1a8fab1cbbc0ef82c6889824b8..72453ddce8803ebd0fb3d706bbd67d46b5805aeb 100644 (file)
@@ -12,6 +12,7 @@ package core
 #include_file "core/random"
 #include_file "core/stdio"
 #include_file "core/string"
+#include_file "core/string/reader"
 #include_file "core/strmap"
 
 #include_file "core/sys/js"
index dabf7e5d098f4c8933e7017e223e35c53d337f13..c6669203d8a32c76d9e0b44a457bc10854970c93 100644 (file)
@@ -13,6 +13,7 @@ package core
 #include_file "core/random"
 #include_file "core/stdio"
 #include_file "core/string"
+#include_file "core/string/reader"
 #include_file "core/strmap"
 #include_file "core/wasi"
 
diff --git a/core/string/reader.onyx b/core/string/reader.onyx
new file mode 100644 (file)
index 0000000..8348570
--- /dev/null
@@ -0,0 +1,144 @@
+package core.str.reader
+
+StringReader :: struct {
+    data : ^u8;
+    count : u32;
+
+    // The original string.
+    original_str : string;
+}
+
+make :: proc (str: string) -> StringReader {
+    reader : StringReader;
+    init(^reader, str);
+    return reader;
+}
+
+init :: proc (use reader: ^StringReader, str: string) {
+    original_str = str;
+    data  = original_str.data;
+    count = original_str.count;
+}
+
+reset :: proc (use reader: ^StringReader) {
+    data  = original_str.data;
+    count = original_str.count;
+}
+
+empty :: proc (use reader: ^StringReader) -> bool do return count == 0;
+
+read_u32 :: proc (use reader: ^StringReader) -> 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_byte :: proc (use reader: ^StringReader) -> u8 {
+    if count == 0 do return #char "\0";
+
+    defer {
+        data += 1;
+        count -= 1;
+    }
+
+    return data[0];
+}
+
+read_bytes :: proc (use reader: ^StringReader, byte_count := 1) -> string {
+    bc := byte_count;
+    if count < bc do bc = count;
+
+    defer {
+        data += bc;
+        count -= bc;
+    }
+
+    return string.{ data, bc };
+}
+
+read_line :: proc (use reader: ^StringReader) -> string {
+    out : string;
+    out.data = data;
+    out.count = 0;
+
+    // HACK(Brendan): I want to use a for loop, but I don't know why.
+    for ch: *(cast(^string) 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 :: proc (use reader: ^StringReader, skip: u32, uptos: ..u8) -> string {
+    if count == 0 do return string.{ null, 0 };
+
+    out : string;
+    out.data = data;
+    out.count = 0;
+
+    s := skip;
+    
+    // HACK(Brendan): See above.
+    for ch: *(cast(^string) reader) {
+        for upto: uptos do if ch == upto {
+            if s <= 0 do break;
+            else do s -= 1;
+        }
+
+        out.count += 1;
+    }
+
+    data += out.count;
+    count -= out.count;
+
+    return out;
+}
+
+advance_line :: proc (use reader: ^StringReader) {
+    if count == 0 do return;
+
+    adv := 0;
+    while data[adv] != #char "\n" do adv += 1;
+
+    data += adv + 1;
+    count -= adv + 1;
+}
+
+
+skip_whitespace :: proc (use reader: ^StringReader) {
+    while count > 0 do switch *data {
+        case #char " ", #char "\t", #char "\n", #char "\r" {
+            data += 1;
+            count -= 1;
+        }
+
+        case #default do return;
+    }
+}
+
+skip_bytes :: proc (use reader: ^StringReader, byte_count := 1) {
+    bc := byte_count;
+    if count < bc do bc = count;
+
+    data += bc;
+    count -= bc;
+}
index bf6b9ba36bcb23f86ee68c61c3ee77b9c8c2a951..78ba0a4e8bc34ad1e811392e934945a029d64e2f 100644 (file)
@@ -18,6 +18,7 @@ void scope_include(Scope* target, Scope* source);
 b32 symbol_introduce(Scope* scope, OnyxToken* tkn, AstNode* symbol);
 b32 symbol_raw_introduce(Scope* scope, char* tkn, OnyxFilePos pos, AstNode* symbol);
 void symbol_builtin_introduce(Scope* scope, char* sym, AstNode *node);
+void symbol_subpackage_introduce(Scope* scope, OnyxToken* sym, AstPackage *node);
 AstNode* symbol_raw_resolve(Scope* start_scope, char* sym);
 AstNode* symbol_resolve(Scope* start_scope, OnyxToken* tkn);
 
diff --git a/onyx b/onyx
index d28cdf91964c1a1cea7eebe449c576f2ff50ef92..6080827acab7ad4acd354efff3e600bca7b66ee4 100755 (executable)
Binary files a/onyx and b/onyx differ
index cd7b85eb0c01617dab21bda1bf9ae070ee23da36..1938311d02acb328b8f28ea37fa07c0d900a07be 100644 (file)
@@ -2071,7 +2071,7 @@ static AstPackage* parse_package_name(OnyxParser* parser) {
             pnode->token = symbol;
             pnode->package = newpackage;
 
-            symbol_introduce(package->scope, symbol, (AstNode *) pnode);
+            symbol_subpackage_introduce(package->scope, symbol, pnode);
         }
 
         package = newpackage;
index f626db5d5d0b244472959c6f6a908e1e353749fe..666814e9b42b670d7c01078f959cfc2e8ff4c8de 100644 (file)
@@ -204,6 +204,19 @@ void symbol_builtin_introduce(Scope* scope, char* sym, AstNode *node) {
     bh_table_put(AstNode *, scope->symbols, sym, node);
 }
 
+void symbol_subpackage_introduce(Scope* scope, OnyxToken* sym, AstPackage* package) {
+    token_toggle_end(sym);
+
+    if (bh_table_has(AstNode *, scope->symbols, sym->text)) {
+        AstNode* maybe_package = bh_table_get(AstNode *, scope->symbols, sym->text);
+        assert(maybe_package->kind == Ast_Kind_Package);
+    } else {
+        bh_table_put(AstNode *, scope->symbols, sym->text, package);
+    }
+
+    token_toggle_end(sym);
+}
+
 AstNode* symbol_raw_resolve(Scope* start_scope, char* sym) {
     AstNode* res = NULL;
     Scope* scope = start_scope;