diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2018-09-21 00:30:28 -0700 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2018-09-21 00:30:44 -0700 |
| commit | f2048235f5cc7ff02db39a0e2fe5c79c7f390e0b (patch) | |
| tree | 738faa0d4692e53d0fe2deb61399b6d7a9eedc9f /core | |
| parent | 79d4bd5125de7ff220fbf8a8a5493d437ed16963 (diff) | |
Incremental checkin, currently not working, just saving progress.
Diffstat (limited to 'core')
| -rw-r--r-- | core/control_flow.nom | 31 | ||||
| -rw-r--r-- | core/metaprogramming.nom | 34 |
2 files changed, 58 insertions, 7 deletions
diff --git a/core/control_flow.nom b/core/control_flow.nom index a9e0ae0..c496d18 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -79,6 +79,10 @@ test: %i += 1 unless (%i == 10): go to %loop assume (%i == 10) + === (Loop) === + %i -= 1 + unless (%i == 0): go to (Loop) + assume (%i == 0) compile [=== %label ===, --- %label ---, *** %label ***] to (..) Lua "::label_\(%label as lua identifier)::" @@ -240,10 +244,8 @@ test: # For-each loop (lua's "ipairs()") compile [for %var in %iterable %body] to: - # This uses Lua's approach of only allowing loop-scoped variables in a loop - unless (%var.type is "Var"): - compile error at %var "Expected a variable here, not a \(%var.type)." define mangler + # This uses Lua's approach of only allowing loop-scoped variables in a loop %lua = (..) Lua "\ ..for \(mangle "i"),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do @@ -264,6 +266,29 @@ compile [for %var in %iterable %body] to: return %lua +# TODO: reduce code duplication +compile [for %var in %iterable at %i %body] to: + # This uses Lua's approach of only allowing loop-scoped variables in a loop + %lua = (..) + Lua "\ + ..for \(%i as lua identifier),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do + \(%body as lua statements)" + + if (%body has subtree \(do next)): + %lua::append "\n ::continue::" + if (%body has subtree \(do next %var)): + %lua::append (Lua "\n\(compile as (===next %var ===))") + %lua::append "\nend --foreach-loop" + if (%body has subtree \(stop %var)): + %lua = (..) + Lua "\ + ..do -- scope for stopping for-loop + \%lua + \(compile as (===stop %var ===)) + end -- end of scope for stopping for-loop" + + return %lua + test: %d = {a:10, b:20, c:30, d:40, e:50} %result = [] diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom index 51831ec..1503905 100644 --- a/core/metaprogramming.nom +++ b/core/metaprogramming.nom @@ -145,7 +145,7 @@ compile [action %actions %body] to (..) test: assume ((action (say %)) == (=lua "say_1")) -compile [action %action] to (Lua value (%action as lua id)) +compile [action %action] to (Lua value (%action.stub as lua id)) test: parse [swap %x and %y] as (..) @@ -233,7 +233,12 @@ action [%var as lua identifier, %var as lua id] (..) lua> "\ ..if type(\%var) == 'string' then return \%var:as_lua_id() elseif AST.is_syntax_tree(\%var, 'Var') then return \%var[1]:as_lua_id() - elseif AST.is_syntax_tree(\%var, 'Action') then return \%var.stub:as_lua_id() + elseif AST.is_syntax_tree(\%var) then + local lua = \(%var as lua expr) + if not tostring(lua):match("^[_a-zA-Z][_a-zA-Z0-9]*$") then + \(compile error at %var "This is not a valid Lua identifier.") + end + return lua else error("Unknown type: "..tostring(\%var)) end" @@ -317,8 +322,29 @@ test: compile [quote %s] to (Lua value "tostring(\(%s as lua expr)):as_lua()") test: - assume ((type of {}) == "table") or barf "type of failed." -compile [type of %obj] to (Lua value "type(\(%obj as lua expr))") + assume (lua type of {}) == "Lua table" + assume (type of {}) == "Dict" + assume ({} is a "Dict") + assume ("" is text) + assume ("" isn't a "Dict") + +%dict_mt = (=lua "getmetatable(\{})") +%list_mt = (=lua "getmetatable(\[])") + +action [% is text] (=lua "\(lua type of %) == 'string'") +action [% is not text, % isn't text] (=lua "\(lua type of %) ~= 'string'") +action [type of %]: + lua> "\ + local lua_type = \(lua type of %) + if lua_type == 'string' then return 'Text' + elseif lua_type == 'table' then + local mt = getmetatable(\%) + if mt and mt.__type then return mt.__type end + return 'Lua table' + else return lua_type end" +parse [% is a %type, % is an %type] as ((type of %) == %type) +parse [% isn't a %type, % isn't an %type, % is not a %type, % is not an %type] +..as ((type of %) == %type) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
