From c841427eff913c642251e3663747d8299e15f2fc Mon Sep 17 00:00:00 2001 From: CHatingPython Date: Fri, 14 Aug 2026 13:58:29 +0200 Subject: [PATCH] feat(furas): introduce global variables --- furas/examples/ops.furas | 12 +++++++----- furas/include/furas/token.hpp | 15 +++++++++------ furas/src/gen.cpp | 25 +++++++++++++++++++++++++ furas/src/lexer.cpp | 3 +++ 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/furas/examples/ops.furas b/furas/examples/ops.furas index d320ea1..3880ddd 100644 --- a/furas/examples/ops.furas +++ b/furas/examples/ops.furas @@ -1,22 +1,24 @@ func println $u32 = native println +allocate uwu + public func main = #main main: push $u32 0 - store %0 + storeg %uwu loop_header: - load %0 + loadg %uwu push $u32 10 ge jnz #loop_end loop_body: - load %0 + loadg %uwu call $u32 println - load %0 + loadg %uwu push $u32 1 add - store %0 + storeg %uwu jmp #loop_header loop_end: diff --git a/furas/include/furas/token.hpp b/furas/include/furas/token.hpp index d34baab..b50edb7 100644 --- a/furas/include/furas/token.hpp +++ b/furas/include/furas/token.hpp @@ -23,12 +23,13 @@ struct token { Colon, /**< `:` */ // Keywords - Func, /**< `func` keyword for defining functions. */ - Type, /**< `type` keyword for defining types. */ - Native, /**< `native` keyword for native functions. :v: */ - Import, /**< `import` keyword for importing functions and types. */ - Public, /**< `public` access specifier. */ - Private, /**< `private` access specifier. */ + Func, /**< `func` keyword for defining functions. */ + Type, /**< `type` keyword for defining types. */ + Native, /**< `native` keyword for native functions. :v: */ + Import, /**< `import` keyword for importing functions and types. */ + Public, /**< `public` access specifier. */ + Private, /**< `private` access specifier. */ + Allocate, /**< `allocate` keyword for global variables. */ // Instructions Push, @@ -56,6 +57,8 @@ struct token { Lenof, Load, Store, + LoadGlobal, + StoreGlobal, Call, Jmp, Jnz, diff --git a/furas/src/gen.cpp b/furas/src/gen.cpp index 43c3548..e6d1245 100644 --- a/furas/src/gen.cpp +++ b/furas/src/gen.cpp @@ -47,6 +47,8 @@ std::unordered_map instructions = { { token::Lenof, furvm::instruction_t::Lengthof }, { token::Load, furvm::instruction_t::Load }, { token::Store, furvm::instruction_t::Store }, + { token::LoadGlobal, furvm::instruction_t::LoadGlobal }, + { token::StoreGlobal, furvm::instruction_t::StoreGlobal }, { token::Call, furvm::instruction_t::Call }, { token::Jmp, furvm::instruction_t::Jump }, { token::Jnz, furvm::instruction_t::JumpNotZero }, @@ -72,6 +74,7 @@ const char* token_type(enum token::type type) { case token::Import: return "import"; case token::Public: return "public"; case token::Private: return "private"; + case token::Allocate: return "allocate"; case token::Push: return "push"; case token::Array: return "array"; case token::Get: return "get"; @@ -97,6 +100,8 @@ const char* token_type(enum token::type type) { case token::Lenof: return "lenof"; case token::Load: return "load"; case token::Store: return "store"; + case token::LoadGlobal: return "loadg"; + case token::StoreGlobal: return "storeg"; case token::Call: return "call"; case token::Jmp: return "jmp"; case token::Jnz: return "jnz"; @@ -128,6 +133,7 @@ struct mod_context { pair_hash, furvm::detail::function_sig_hash>> functions; std::unordered_map types; + std::unordered_map variables; std::unordered_map labels; @@ -214,6 +220,15 @@ struct mod_context { return { generator_error::Success }; } + case token::Allocate: { + result = eat_token(lexer, token::Identifier); + if (!result) return result.error; + std::string name = std::string(result->value.string); + variables.emplace(name, variables.size()); + mod.set_global_variable_count(variables.size()); + return { generator_error::Success }; + } + case token::Func: case token::Type: case token::Public: @@ -465,6 +480,16 @@ struct mod_context { if (!result) return result.error; instr.arg.u16 = result->value.uint; } break; + case furvm::instruction_argument::GlobalVariable: { + result = eat_token(lexer, token::Percent); + if (!result) return result.error; + result = eat_token(lexer, token::Identifier); + if (!result) return result.error; + if (auto it = variables.find(std::string(result->value.string)); it != variables.end()) + instr.arg.u16 = it->second; + else + throw std::runtime_error("Unknown global variable"); + } break; case furvm::instruction_argument::Function: { furvm::function_sig signature; while ((result = next_token(lexer)).error.type == generator_error::Success && diff --git a/furas/src/lexer.cpp b/furas/src/lexer.cpp index 89c3e11..7278dec 100644 --- a/furas/src/lexer.cpp +++ b/furas/src/lexer.cpp @@ -39,6 +39,7 @@ token_r lexer::next_token() { { "import", token::Import }, { "public", token::Public }, { "private", token::Private }, + { "allocate", token::Allocate }, { "push", token::Push }, { "array", token::Array }, @@ -65,6 +66,8 @@ token_r lexer::next_token() { { "lenof", token::Lenof }, { "load", token::Load }, { "store", token::Store }, + { "loadg", token::LoadGlobal }, + { "storeg", token::StoreGlobal }, { "call", token::Call }, { "jmp", token::Jmp }, { "jnz", token::Jnz },