From: Brendan Hansen Date: Wed, 9 Dec 2020 04:25:21 +0000 (-0600) Subject: added 'StringReader'; subpackage bugfix X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=3e8006c1d2dc883e8245479d3d74e9488ee8aad8;p=onyx.git added 'StringReader'; subpackage bugfix --- diff --git a/core/std/js.onyx b/core/std/js.onyx index 8dfb8d97..72453ddc 100644 --- a/core/std/js.onyx +++ b/core/std/js.onyx @@ -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" diff --git a/core/std/wasi.onyx b/core/std/wasi.onyx index dabf7e5d..c6669203 100644 --- a/core/std/wasi.onyx +++ b/core/std/wasi.onyx @@ -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 index 00000000..83485706 --- /dev/null +++ b/core/string/reader.onyx @@ -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; +} diff --git a/include/onyxutils.h b/include/onyxutils.h index bf6b9ba3..78ba0a4e 100644 --- a/include/onyxutils.h +++ b/include/onyxutils.h @@ -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 d28cdf91..6080827a 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyxparser.c b/src/onyxparser.c index cd7b85eb..1938311d 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -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; diff --git a/src/onyxutils.c b/src/onyxutils.c index f626db5d..666814e9 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -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;