From f2048235f5cc7ff02db39a0e2fe5c79c7f390e0b Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 21 Sep 2018 00:30:28 -0700 Subject: Incremental checkin, currently not working, just saving progress. --- core/control_flow.nom | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'core/control_flow.nom') 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 = [] -- cgit v1.2.3 From b43432e647fbb3bb76aa2836e3899d5e407c50f9 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 26 Sep 2018 13:05:28 -0700 Subject: Fixed all syntax errors, got original (non-nomnom) tests passing. --- core/control_flow.nom | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'core/control_flow.nom') diff --git a/core/control_flow.nom b/core/control_flow.nom index c496d18..a3814b7 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -72,6 +72,8 @@ compile [..] end end)())" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # GOTOs test: %i = 0 @@ -84,9 +86,10 @@ test: unless (%i == 0): go to (Loop) assume (%i == 0) compile [=== %label ===, --- %label ---, *** %label ***] to (..) - Lua "::label_\(%label as lua identifier)::" + Lua "::label_\((%label.stub if (%label.type == "Action") else %label) as lua identifier)::" -compile [go to %label] to (Lua "goto label_\(%label as lua identifier)") +compile [go to %label] to (..) + Lua "goto label_\((%label.stub if (%label.type == "Action") else %label) as lua identifier)" # Basic loop control compile [do next] to (Lua "goto continue") @@ -165,13 +168,15 @@ compile [repeat %n times %body] to: return %lua # For loop control flow -compile [stop %var] to (Lua "goto stop_\(%var as lua identifier)") -compile [do next %var] to (Lua "goto continue_\(%var as lua identifier)") +compile [stop %var] to (..) + Lua "goto stop_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)" +compile [do next %var] to (..) + Lua "goto continue_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)" compile [===stop %var ===, ---stop %var ---, ***stop %var ***] to (..) - Lua "::stop_\(%var as lua identifier)::" + Lua "::stop_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)::" compile [===next %var ===, ---next %var ---, ***next %var ***] to (..) - Lua "::continue_\(%var as lua identifier)::" + Lua "::continue_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)::" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -516,11 +521,11 @@ test: %t = [1, [2, [[3], 4], 5, [[[6]]]]] %flat = [] for % in recursive %t: - if ((type of %) is "table"): + if ((lua type of %) is "table"): for %2 in %: recurse % on %2 ..else: %flat::add % - assume ((sorted %flat) == [1, 2, 3, 4, 5, 6]) + assume (sorted %flat) == [1, 2, 3, 4, 5, 6] # Recurion control flow compile [for %var in recursive %structure %body] to (..) -- cgit v1.2.3 From 84931a6f0e0c8627a4835a9ce886aba28b0e76bc Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 28 Sep 2018 18:34:40 -0700 Subject: Fixes for indentation of generated lua code. --- core/control_flow.nom | 106 ++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 56 deletions(-) (limited to 'core/control_flow.nom') diff --git a/core/control_flow.nom b/core/control_flow.nom index a3814b7..4254abc 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -129,12 +129,13 @@ compile [repeat while %condition %body] to: %lua::append "\n ::continue_repeat::" %lua::append "\nend --while-loop" if (%body has subtree \(stop repeating)): - %lua = (..) - Lua "\ - ..do -- scope of "stop repeating" label - \%lua + %inner_lua = %lua + %lua = (Lua "do -- scope of 'stop repeating' label\n ") + %lua::append %inner_lua + %lua::append "\ + .. ::stop_repeat:: - end -- end of "stop repeating" label scope" + end -- end of 'stop repeating' label scope" return %lua @@ -158,12 +159,13 @@ compile [repeat %n times %body] to: %lua::append "\n ::continue_repeat::" %lua::append "\nend --numeric for-loop" if (%body has subtree \(stop repeating)): - %lua = (..) - Lua "\ - ..do -- scope of "stop repeating" label - \%lua + %inner_lua = %lua + %lua = (Lua "do -- scope of 'stop repeating' label\n ") + %lua::append %inner_lua + %lua::append "\ + .. ::stop_repeat:: - end -- end of "stop repeating" label scope" + end -- end of 'stop repeating' label scope" return %lua @@ -220,12 +222,12 @@ compile [..] %lua::append "\n \(compile as (===next %var ===))" %lua::append "\nend --numeric for-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" + %inner_lua = %lua + %lua = (Lua "do -- scope for stopping for-loop\n ") + %lua::append %inner_lua + %lua::append "\n " + %lua::append (compile as (===stop %var ===)) + %lua::append "\nend -- end of scope for stopping for-loop" return %lua @@ -262,12 +264,12 @@ compile [for %var in %iterable %body] to: %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" + %inner_lua = %lua + %lua = (Lua "do -- scope for stopping for-loop\n ") + %lua::append %inner_lua + %lua::append "\n " + %lua::append (compile as (===stop %var ===)) + %lua::append "\nend -- end of scope for stopping for-loop" return %lua @@ -285,12 +287,12 @@ compile [for %var in %iterable at %i %body] to: %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" + %inner_lua = %lua + %lua = (Lua "do -- scope for stopping for-loop\n ") + %lua::append %inner_lua + %lua::append "\n " + %lua::append (compile as (===stop %var ===)) + %lua::append "\nend -- end of scope for stopping for-loop" return %lua @@ -333,11 +335,11 @@ compile [..] if (%body has subtree \(stop %value)): %stop_labels::append "\n\(compile as (===stop %value ===))" if ((size of "\%stop_labels") > 0): - %lua = (..) - Lua "\ - ..do -- scope for stopping for % = % loop - \%lua\%stop_labels - end" + %inner_lua = %lua + %lua = (Lua "do -- scope for stopping for % = % loop\n ") + %lua::append %inner_lua + %lua::append %stop_labels + %lua::append "\nend" return %lua @@ -384,11 +386,8 @@ compile [if %body, when %body] to: ..need a conditional block around it. Otherwise, make sure the 'else' \ ..block comes last." - %code::append "\ - .. - else - \(%action as lua statements)" - + %code::append "\nelse\n " + %code::append (%action as lua statements) %else_allowed = (no) ..else: %code::append "\%clause " @@ -397,10 +396,8 @@ compile [if %body, when %body] to: %code::append " or " %code::append (%line.%i as lua expr) - %code::append "\ - .. then - \(%action as lua statements)" - + %code::append " then\n " + %code::append (%action as lua statements) %clause = "\nelseif" if ((size of "\%code") == 0): @@ -449,11 +446,8 @@ compile [if %branch_value is %body, when %branch_value is %body] to: ..need a conditional block around it. Otherwise, make sure the 'else' \ ..block comes last." - %code::append "\ - .. - else - \(%action as lua statements)" - + %code::append "\nelse\n " + %code::append (%action as lua statements) %else_allowed = (no) ..else: %code::append "\%clause " @@ -462,22 +456,22 @@ compile [if %branch_value is %body, when %branch_value is %body] to: %code::append " or " %code::append "\(mangle "branch value") == \(%line.%i as lua expr)" - %code::append "\ - .. then - \(%action as lua statements)" - + %code::append " then\n " + %code::append (%action as lua statements) %clause = "\nelseif" if ((size of "\%code") == 0): compile error at %body "'if' block has an empty body." ..hint "This means nothing would happen, so the 'if' block should be deleted." %code::append "\nend --when" - return (..) + %lua = (..) Lua "\ - ..do --if % is - local \(mangle "branch value") = \(%branch_value as lua expr) - \%code - end --if % is" + ..do --if % is... + local \(mangle "branch value") = \(%branch_value as lua expr)" + %lua::append "\n " + %lua::append %code + %lua::append "\nend --if % is..." + return %lua # Do/finally compile [do %action] to (..) -- cgit v1.2.3 From 63d8b1cd3f34b15bf86210b99209e8b57e7019bb Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 28 Sep 2018 22:15:06 -0700 Subject: Fully working, I think? (with a lot of shims) --- core/control_flow.nom | 129 +++++++++++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 55 deletions(-) (limited to 'core/control_flow.nom') diff --git a/core/control_flow.nom b/core/control_flow.nom index 4254abc..243df96 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -16,11 +16,13 @@ compile [do nothing] to (Lua "") test: if (no): barf "conditional fail" -compile [if %condition %if_body] to (..) - Lua "\ - ..if \(%condition as lua expr) then - \(%if_body as lua statements) - end" +compile [if %condition %if_body] to: + %lua = (Lua "if ") + %lua::append (%condition as lua expr) + %lua::append " then\n " + %lua::append (%if_body as lua statements) + %lua::append "\nend" + return %lua test: unless (yes): @@ -28,13 +30,15 @@ test: parse [unless %condition %unless_body] as (if (not %condition) %unless_body) compile [..] if %condition %if_body else %else_body, unless %condition %else_body else %if_body -..to (..) - Lua "\ - ..if \(%condition as lua expr) then - \(%if_body as lua statements) - else - \(%else_body as lua statements) - end" +..to: + %lua = (Lua "if ") + %lua::append (%condition as lua expr) + %lua::append " then\n " + %lua::append (%if_body as lua statements) + %lua::append "\nelse\n " + %lua::append (%else_body as lua statements) + %lua::append "\nend" + return %lua ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -149,9 +153,8 @@ test: compile [repeat %n times %body] to: define mangler %lua = (..) - Lua "\ - ..for \(mangle "i")=1,\(%n as lua expr) do - \(%body as lua statements)" + Lua "for \(mangle "i")=1,\(%n as lua expr) do\n " + %lua::append (%body as lua statements) if (%body has subtree \(do next)): %lua::append "\n ::continue::" @@ -208,18 +211,20 @@ compile [..] ..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)." + compile error at %var "Expected a variable here, not a \(%var.type)" %lua = (..) Lua "\ ..for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(..) %step as lua expr - .. do - \(%body as lua statements)" + .. do" + %lua::append "\n " + %lua::append (%body as lua statements) if (%body has subtree \(do next)): %lua::append "\n ::continue::" if (%body has subtree \(do next %var)): - %lua::append "\n \(compile as (===next %var ===))" + %lua::append "\n " + %lua::append (compile as (===next %var ===)) %lua::append "\nend --numeric for-loop" if (%body has subtree \(stop %var)): %inner_lua = %lua @@ -254,14 +259,14 @@ compile [for %var in %iterable %body] to: 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 - \(%body as lua statements)" + Lua "for \(mangle "i"),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do\n " + %lua::append (%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 "\n " + %lua::append (compile as (===next %var ===)) %lua::append "\nend --foreach-loop" if (%body has subtree \(stop %var)): %inner_lua = %lua @@ -277,14 +282,14 @@ compile [for %var in %iterable %body] to: 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)" + Lua "for \(%i as lua identifier),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do\n " + %lua::append (%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 "\n " + %lua::append (compile as (===next %var ===)) %lua::append "\nend --foreach-loop" if (%body has subtree \(stop %var)): %inner_lua = %lua @@ -312,28 +317,33 @@ compile [..] ..to: # This uses Lua's approach of only allowing loop-scoped variables in a loop unless (%key.type is "Var"): - compile error at %key "Expected a variable here, not a \(%key.type)." + compile error at %key "Expected a variable here, not a \(%key.type)" unless (%value.type is "Var"): - compile error at %value "Expected a variable here, not a \(%value.type)." + compile error at %value "Expected a variable here, not a \(%value.type)" %lua = (..) Lua "\ ..for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(..) %iterable as lua expr - ..) do - \(%body as lua statements)" + ..) do" + %lua::append "\n " + %lua::append (%body as lua statements) if (%body has subtree \(do next)): %lua::append "\n ::continue::" if (%body has subtree \(do next %key)): - %lua::append (Lua "\n\(compile as (===next %key ===))") + %lua::append "\n " + %lua::append (compile as (===next %key ===)) if (%body has subtree \(do next %value)): - %lua::append (Lua "\n\(compile as (===next %value ===))") + %lua::append "\n " + %lua::append (compile as (===next %value ===)) %lua::append "\nend --foreach-loop" %stop_labels = (Lua "") if (%body has subtree \(stop %key)): - %stop_labels::append "\n\(compile as (===stop %key ===))" + %stop_labels::append "\n" + %stop_labels::append (compile as (===stop %key ===)) if (%body has subtree \(stop %value)): - %stop_labels::append "\n\(compile as (===stop %value ===))" + %stop_labels::append "\n" + %stop_labels::append (compile as (===stop %value ===)) if ((size of "\%stop_labels") > 0): %inner_lua = %lua %lua = (Lua "do -- scope for stopping for % = % loop\n ") @@ -390,7 +400,8 @@ compile [if %body, when %body] to: %code::append (%action as lua statements) %else_allowed = (no) ..else: - %code::append "\%clause " + %code::append %clause + %code::append " " for %i in 1 to ((size of %line) - 1): if (%i > 1): %code::append " or " @@ -450,11 +461,13 @@ compile [if %branch_value is %body, when %branch_value is %body] to: %code::append (%action as lua statements) %else_allowed = (no) ..else: - %code::append "\%clause " + %code::append %clause + %code::append " " for %i in 1 to ((size of %line) - 1): if (%i > 1): %code::append " or " - %code::append "\(mangle "branch value") == \(%line.%i as lua expr)" + %code::append "\(mangle "branch value") == " + %code::append (%line.%i as lua expr) %code::append " then\n " %code::append (%action as lua statements) @@ -467,18 +480,19 @@ compile [if %branch_value is %body, when %branch_value is %body] to: %lua = (..) Lua "\ ..do --if % is... - local \(mangle "branch value") = \(%branch_value as lua expr)" + local \(mangle "branch value") = " + %lua::append (%branch_value as lua expr) %lua::append "\n " %lua::append %code %lua::append "\nend --if % is..." return %lua # Do/finally -compile [do %action] to (..) - Lua "\ - ..do - \(%action as lua statements) - end --do" +compile [do %action] to: + %lua = (Lua "do\n ") + %lua::append (%action as lua statements) + %lua::append "\nend -- do" + return %lua test: %d = {} @@ -492,18 +506,22 @@ test: assume (%d.x == "good") compile [do %action then always %final_action] to: define mangler - return (..) + %lua = (..) Lua "\ ..do local \(mangle "fell_through") = false - local \(mangle "ok"), \(mangle "ret") = pcall(function() - \(%action as lua statements) - \(mangle "fell_through") = true - end) - \(%final_action as lua statements) - if not \(mangle "ok") then error(ret, 0) end - if not \(mangle "fell_through") then return ret end - end" + local \(mangle "ok"), \(mangle "ret") = pcall(function()" + %lua::append "\n " + %lua::append (%action as lua statements) + %lua::append "\ + .. \(mangle "fell_through") = true + end)" + %lua::append "\n " + %lua::append (%final_action as lua statements) + %lua::append "\ + .. if not \(mangle "ok") then error(ret, 0) end + if not \(mangle "fell_through") then return ret end + end" test: assume ((result of (: return 99)) == 99) @@ -532,8 +550,9 @@ compile [for %var in recursive %structure %body] to (..) ..do local \(mangle "stack \(%var.1)") = _List{\(%structure as lua expr)} while #\(mangle "stack \(%var.1)") > 0 do - \(%var as lua expr) = table.remove(\(mangle "stack \(%var.1)"), 1) - \(%body as lua statements)" + \(%var as lua expr) = table.remove(\(mangle "stack \(%var.1)"), 1)" + %lua::append "\n " + %lua::append (%body as lua statements) if (%body has subtree \(do next)): %lua::append "\n ::continue::" -- cgit v1.2.3 From 0c982d2aa285e6c095470667c1d0c21999ddad58 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 28 Sep 2018 22:16:10 -0700 Subject: Oops, refactor bug. --- core/control_flow.nom | 1 + 1 file changed, 1 insertion(+) (limited to 'core/control_flow.nom') diff --git a/core/control_flow.nom b/core/control_flow.nom index 243df96..48b9c85 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -522,6 +522,7 @@ compile [do %action then always %final_action] to: .. if not \(mangle "ok") then error(ret, 0) end if not \(mangle "fell_through") then return ret end end" + return %lua test: assume ((result of (: return 99)) == 99) -- cgit v1.2.3 From 23abab4f809e8d4b825746580082292db700036b Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 29 Oct 2018 13:00:08 -0700 Subject: Some cleanups and fixes, made the parser more permissive of prematurely terminated files. --- core/control_flow.nom | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'core/control_flow.nom') diff --git a/core/control_flow.nom b/core/control_flow.nom index 48b9c85..37b2b9c 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -53,7 +53,7 @@ compile [..] %when_true_expr if %condition otherwise %when_false_expr %when_false_expr unless %condition else %when_true_expr %when_false_expr unless %condition then %when_true_expr -..to (..) +..to: # If %when_true_expr is guaranteed to be truthy, we can use Lua's idiomatic equivalent of a conditional expression: (cond and if_true or if_false) if {Text:yes, List:yes, Dict:yes, Number:yes}.(%when_true_expr.type): @@ -541,7 +541,7 @@ test: assume (sorted %flat) == [1, 2, 3, 4, 5, 6] # Recurion control flow -compile [for %var in recursive %structure %body] to (..) +compile [for %var in recursive %structure %body] to: with local compile actions: define mangler compile [recurse %v on %x] to (..) -- cgit v1.2.3 From ea3197aaffba00318920ed5e1e33ca5f2a5e6c5c Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 30 Oct 2018 23:42:04 -0700 Subject: Fully working version of (action [foo]: baz) -> ((foo) means: baz) refactor and misc other changes. --- core/control_flow.nom | 140 +++++++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 65 deletions(-) (limited to 'core/control_flow.nom') diff --git a/core/control_flow.nom b/core/control_flow.nom index 37b2b9c..2b53ce7 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V4.8.8.6 +#!/usr/bin/env nomsu -V4.8.10 # This file contains compile-time actions that define basic control flow structures like "if" statements and loops. @@ -10,13 +10,13 @@ use "core/errors.nom" # No-Op test: do nothing -compile [do nothing] to (Lua "") +(do nothing) compiles to (Lua "") # Conditionals test: if (no): barf "conditional fail" -compile [if %condition %if_body] to: +(if %condition %if_body) compiles to: %lua = (Lua "if ") %lua::append (%condition as lua expr) %lua::append " then\n " @@ -27,10 +27,10 @@ compile [if %condition %if_body] to: test: unless (yes): barf "conditional fail" -parse [unless %condition %unless_body] as (if (not %condition) %unless_body) -compile [..] +(unless %condition %unless_body) parses as (if (not %condition) %unless_body) +[..] if %condition %if_body else %else_body, unless %condition %else_body else %if_body -..to: +..all compile to: %lua = (Lua "if ") %lua::append (%condition as lua expr) %lua::append " then\n " @@ -48,12 +48,12 @@ compile [..] test: assume ((1 if (yes) else 2) == 1) assume ((1 if (no) else 2) == 2) -compile [..] +[..] %when_true_expr if %condition else %when_false_expr %when_true_expr if %condition otherwise %when_false_expr %when_false_expr unless %condition else %when_true_expr %when_false_expr unless %condition then %when_true_expr -..to: +..all compile to: # If %when_true_expr is guaranteed to be truthy, we can use Lua's idiomatic equivalent of a conditional expression: (cond and if_true or if_false) if {Text:yes, List:yes, Dict:yes, Number:yes}.(%when_true_expr.type): @@ -89,15 +89,21 @@ test: %i -= 1 unless (%i == 0): go to (Loop) assume (%i == 0) -compile [=== %label ===, --- %label ---, *** %label ***] to (..) - Lua "::label_\((%label.stub if (%label.type == "Action") else %label) as lua identifier)::" - -compile [go to %label] to (..) - Lua "goto label_\((%label.stub if (%label.type == "Action") else %label) as lua identifier)" +[=== %label ===, --- %label ---, *** %label ***] all compile to (..) + Lua "\ + ..::label_\(..) + (%label.stub if (%label.type == "Action") else %label) as lua identifier + ..::" + +(go to %label) compiles to (..) + Lua "\ + ..goto label_\(..) + (%label.stub if (%label.type == "Action") else %label) as lua identifier + .." # Basic loop control -compile [do next] to (Lua "goto continue") -compile [stop] to (Lua "break") +(do next) compiles to (Lua "goto continue") +(stop) compiles to (Lua "break") # While loops test: @@ -119,9 +125,9 @@ test: barf "Failed to 'do next repeat'" assume (%x == 30) -compile [do next repeat] to (Lua "goto continue_repeat") -compile [stop repeating] to (Lua "goto stop_repeat") -compile [repeat while %condition %body] to: +(do next repeat) compiles to (Lua "goto continue_repeat") +(stop repeating) compiles to (Lua "goto stop_repeat") +(repeat while %condition %body) compiles to: %lua = (..) Lua "\ ..while \(%condition as lua expr) do @@ -137,25 +143,24 @@ compile [repeat while %condition %body] to: %lua = (Lua "do -- scope of 'stop repeating' label\n ") %lua::append %inner_lua %lua::append "\ - .. - ::stop_repeat:: - end -- end of 'stop repeating' label scope" + .. + ::stop_repeat:: + end -- end of 'stop repeating' label scope" return %lua -parse [repeat %body] as (repeat while (yes) %body) -parse [repeat until %condition %body] as (repeat while (not %condition) %body) +(repeat %body) parses as (repeat while (yes) %body) +(repeat until %condition %body) parses as (repeat while (not %condition) %body) test: %x = 0 repeat 10 times: %x += 1 assume (%x == 10) -compile [repeat %n times %body] to: +(repeat %n times %body) compiles to: define mangler %lua = (..) Lua "for \(mangle "i")=1,\(%n as lua expr) do\n " %lua::append (%body as lua statements) - if (%body has subtree \(do next)): %lua::append "\n ::continue::" if (%body has subtree \(do next repeat)): @@ -166,21 +171,20 @@ compile [repeat %n times %body] to: %lua = (Lua "do -- scope of 'stop repeating' label\n ") %lua::append %inner_lua %lua::append "\ - .. - ::stop_repeat:: - end -- end of 'stop repeating' label scope" + .. + ::stop_repeat:: + end -- end of 'stop repeating' label scope" return %lua # For loop control flow -compile [stop %var] to (..) +(stop %var) compiles to (..) Lua "goto stop_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)" -compile [do next %var] to (..) +(do next %var) compiles to (..) Lua "goto continue_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)" -compile [===stop %var ===, ---stop %var ---, ***stop %var ***] to (..) +[===stop %var ===, ---stop %var ---, ***stop %var ***] all compile to (..) Lua "::stop_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)::" - -compile [===next %var ===, ---next %var ---, ***next %var ***] to (..) +[===next %var ===, ---next %var ---, ***next %var ***] all compile to (..) Lua "::continue_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)::" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -205,10 +209,10 @@ test: assume (%nums == [1, -2, 3, -2, 3, 4, 3, 4, 5]) # Numeric range for loops -compile [..] +[..] for %var in %start to %stop by %step %body for %var in %start to %stop via %step %body -..to: +..all compile 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)" @@ -217,28 +221,29 @@ compile [..] ..for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(..) %step as lua expr .. do" + %lua::append "\n " %lua::append (%body as lua statements) - if (%body has subtree \(do next)): %lua::append "\n ::continue::" if (%body has subtree \(do next %var)): %lua::append "\n " - %lua::append (compile as (===next %var ===)) + %lua::append (what (===next %var ===) compiles to) + %lua::append "\nend --numeric for-loop" if (%body has subtree \(stop %var)): %inner_lua = %lua %lua = (Lua "do -- scope for stopping for-loop\n ") %lua::append %inner_lua %lua::append "\n " - %lua::append (compile as (===stop %var ===)) + %lua::append (what (===stop %var ===) compiles to) %lua::append "\nend -- end of scope for stopping for-loop" return %lua ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -parse [for %var in %start to %stop %body] as (..) +(for %var in %start to %stop %body) parses as (..) for %var in %start to %stop via 1 %body test: @@ -255,48 +260,48 @@ test: assume (%b == [20, 30, 40]) # For-each loop (lua's "ipairs()") -compile [for %var in %iterable %body] to: +(for %var in %iterable %body) compiles to: 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\n " %lua::append (%body as lua statements) - if (%body has subtree \(do next)): %lua::append "\n ::continue::" if (%body has subtree \(do next %var)): %lua::append "\n " - %lua::append (compile as (===next %var ===)) + %lua::append (what (===next %var ===) compiles to) + %lua::append "\nend --foreach-loop" if (%body has subtree \(stop %var)): %inner_lua = %lua %lua = (Lua "do -- scope for stopping for-loop\n ") %lua::append %inner_lua %lua::append "\n " - %lua::append (compile as (===stop %var ===)) + %lua::append (what (===stop %var ===) compiles to) %lua::append "\nend -- end of scope for stopping for-loop" return %lua # TODO: reduce code duplication -compile [for %var in %iterable at %i %body] to: +(for %var in %iterable at %i %body) compiles 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\n " %lua::append (%body as lua statements) - if (%body has subtree \(do next)): %lua::append "\n ::continue::" if (%body has subtree \(do next %var)): %lua::append "\n " - %lua::append (compile as (===next %var ===)) + %lua::append (what (===next %var ===) compiles to) + %lua::append "\nend --foreach-loop" if (%body has subtree \(stop %var)): %inner_lua = %lua %lua = (Lua "do -- scope for stopping for-loop\n ") %lua::append %inner_lua %lua::append "\n " - %lua::append (compile as (===stop %var ===)) + %lua::append (what (===stop %var ===) compiles to) %lua::append "\nend -- end of scope for stopping for-loop" return %lua @@ -312,9 +317,9 @@ test: assume ((%result sorted) == ["c = 30", "d = 40", "e = 50"]) # Dict iteration (lua's "pairs()") -compile [..] +[..] for %key = %value in %iterable %body, for %key %value in %iterable %body -..to: +..all compile to: # This uses Lua's approach of only allowing loop-scoped variables in a loop unless (%key.type is "Var"): compile error at %key "Expected a variable here, not a \(%key.type)" @@ -325,25 +330,29 @@ compile [..] ..for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(..) %iterable as lua expr ..) do" + %lua::append "\n " %lua::append (%body as lua statements) - if (%body has subtree \(do next)): %lua::append "\n ::continue::" if (%body has subtree \(do next %key)): %lua::append "\n " - %lua::append (compile as (===next %key ===)) + %lua::append (what (===next %key ===) compiles to) + if (%body has subtree \(do next %value)): %lua::append "\n " - %lua::append (compile as (===next %value ===)) + %lua::append (what (===next %value ===) compiles to) + %lua::append "\nend --foreach-loop" %stop_labels = (Lua "") if (%body has subtree \(stop %key)): %stop_labels::append "\n" - %stop_labels::append (compile as (===stop %key ===)) + %stop_labels::append (what (===stop %key ===) compiles to) + if (%body has subtree \(stop %value)): %stop_labels::append "\n" - %stop_labels::append (compile as (===stop %value ===)) + %stop_labels::append (what (===stop %value ===) compiles to) + if ((size of "\%stop_labels") > 0): %inner_lua = %lua %lua = (Lua "do -- scope for stopping for % = % loop\n ") @@ -368,13 +377,14 @@ test: barf "bad conditional" # Multi-branch conditional (if..elseif..else) -compile [if %body, when %body] to: +[if %body, when %body] all compile to: %code = (Lua "") %clause = "if" %else_allowed = (yes) unless (%body.type is "Block"): compile error at %body "'if' expected a Block, but got a \(%body.type)." ..hint "Perhaps you forgot to put a ':' after 'if'?" + for %line in %body: unless (..) ((%line.type is "Action") and ((size of %line) >= 2)) and (..) @@ -389,13 +399,14 @@ compile [if %body, when %body] to: unless %else_allowed: compile error at %line "You can't have two 'else' blocks." ..hint "Merge all of the 'else' blocks together." + unless ((size of "\%code") > 0): compile error at %line "\ ..You can't have an 'else' block without a preceeding condition" ..hint "If you want the code in this block to always execute, you don't \ ..need a conditional block around it. Otherwise, make sure the 'else' \ ..block comes last." - + %code::append "\nelse\n " %code::append (%action as lua statements) %else_allowed = (no) @@ -428,7 +439,7 @@ test: barf "bad switch statement" # Switch statement -compile [if %branch_value is %body, when %branch_value is %body] to: +[if %branch_value is %body, when %branch_value is %body] all compile to: %code = (Lua "") %clause = "if" %else_allowed = (yes) @@ -488,7 +499,7 @@ compile [if %branch_value is %body, when %branch_value is %body] to: return %lua # Do/finally -compile [do %action] to: +(do %action) compiles to: %lua = (Lua "do\n ") %lua::append (%action as lua statements) %lua::append "\nend -- do" @@ -504,7 +515,7 @@ test: ..and if it barfs: do nothing assume (%d.x == "good") -compile [do %action then always %final_action] to: +(do %action then always %final_action) compiles to: define mangler %lua = (..) Lua "\ @@ -528,7 +539,7 @@ test: assume ((result of (: return 99)) == 99) # Inline thunk: -compile [result of %body] to (Lua value "\(compile as ([] -> %body))()") +(result of %body) compiles to (Lua value "\(what ([] -> %body) compiles to)()") test: %t = [1, [2, [[3], 4], 5, [[[6]]]]] @@ -541,10 +552,10 @@ test: assume (sorted %flat) == [1, 2, 3, 4, 5, 6] # Recurion control flow -compile [for %var in recursive %structure %body] to: +(for %var in recursive %structure %body) compiles to: with local compile actions: define mangler - compile [recurse %v on %x] to (..) + (recurse %v on %x) compiles to (..) Lua "table.insert(\(mangle "stack \(%v.1)"), \(%x as lua expr))" %lua = (..) Lua "\ @@ -554,13 +565,12 @@ compile [for %var in recursive %structure %body] to: \(%var as lua expr) = table.remove(\(mangle "stack \(%var.1)"), 1)" %lua::append "\n " %lua::append (%body as lua statements) - if (%body has subtree \(do next)): %lua::append "\n ::continue::" if (%body has subtree \(do next %var)): - %lua::append "\n \(compile as (===next %var ===))" + %lua::append "\n \(what (===next %var ===) compiles to)" %lua::append "\n end -- Recursive loop" if (%body has subtree \(stop %var)): - %lua::append "\n \(compile as (===stop %var ===))" + %lua::append "\n \(what (===stop %var ===) compiles to)" %lua::append "\nend -- Recursive scope" return %lua -- cgit v1.2.3 From 7a35e38d8778670fe0662f203e82638355db3bba Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 31 Oct 2018 15:05:17 -0700 Subject: Renamed (action %) -> (%'s meaning) --- core/control_flow.nom | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/control_flow.nom') diff --git a/core/control_flow.nom b/core/control_flow.nom index 2b53ce7..0cabf95 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -406,7 +406,7 @@ test: ..hint "If you want the code in this block to always execute, you don't \ ..need a conditional block around it. Otherwise, make sure the 'else' \ ..block comes last." - + %code::append "\nelse\n " %code::append (%action as lua statements) %else_allowed = (no) -- cgit v1.2.3 From 307dea18815ba4a06a3098edb170d7ad90708815 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 2 Nov 2018 14:38:24 -0700 Subject: Changed stub convention to (foo 1 baz 2) -> foo_1_baz instead of foo_1_baz_2, removed "smext", made some cleanup changes. --- core/control_flow.nom | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'core/control_flow.nom') diff --git a/core/control_flow.nom b/core/control_flow.nom index 0cabf95..bbc98f1 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -102,8 +102,20 @@ test: .." # Basic loop control -(do next) compiles to (Lua "goto continue") -(stop) compiles to (Lua "break") +(stop %var) compiles to: + if %var: + return (..) + Lua "goto stop_\((%var.stub if (%var.type == "action") else %var) as lua identifier)" + ..else: return (Lua "break") +(do next %var) compiles to: + if %var: + return (..) + Lua "goto continue_\((%var.stub if (%var.type == "action") else %var) as lua identifier)" + ..else: return (Lua "goto continue") +[===stop %var ===, ---stop %var ---, ***stop %var ***] all compile to (..) + Lua "::stop_\((%var.stub if (%var.type == "action") else %var) as lua identifier)::" +[===next %var ===, ---next %var ---, ***next %var ***] all compile to (..) + Lua "::continue_\((%var.stub if (%var.type == "action") else %var) as lua identifier)::" # While loops test: @@ -177,16 +189,6 @@ test: return %lua -# For loop control flow -(stop %var) compiles to (..) - Lua "goto stop_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)" -(do next %var) compiles to (..) - Lua "goto continue_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)" -[===stop %var ===, ---stop %var ---, ***stop %var ***] all compile to (..) - Lua "::stop_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)::" -[===next %var ===, ---next %var ---, ***next %var ***] all compile to (..) - Lua "::continue_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)::" - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: @@ -365,7 +367,7 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: - if: + when: (1 == 2) (100 < 0): barf "bad conditional" (1 == 0) (1 == 1) %not_a_variable.x: do nothing @@ -377,7 +379,7 @@ test: barf "bad conditional" # Multi-branch conditional (if..elseif..else) -[if %body, when %body] all compile to: +(when %body) compiles to: %code = (Lua "") %clause = "if" %else_allowed = (yes) @@ -512,8 +514,6 @@ test: %d.x = "bad" barf ..then always: %d.x = "good" - ..and if it barfs: do nothing - assume (%d.x == "good") (do %action then always %final_action) compiles to: define mangler -- cgit v1.2.3