diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2018-07-18 01:27:56 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2018-07-18 01:28:17 -0700 |
| commit | d5cfaa37be9e278c44a25ef448a071390597306e (patch) | |
| tree | 7fbe78b5153bb9c761c283533943ab80da3a1844 /core/control_flow.nom | |
| parent | c7c657d38f999901225b33482ef3a15994526feb (diff) | |
Upgrading to version 2.3 (main change: "=" instead of "<-" for
assignment)
Diffstat (limited to 'core/control_flow.nom')
| -rw-r--r-- | core/control_flow.nom | 154 |
1 files changed, 83 insertions, 71 deletions
diff --git a/core/control_flow.nom b/core/control_flow.nom index bb30e49..b3f0978 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V2.2.4.3 +#!/usr/bin/env nomsu -V2.3.4.3 # This file contains compile-time actions that define basic control flow structures like "if" statements and loops. @@ -15,10 +15,7 @@ compile [do nothing] to (Lua "") # Conditionals 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 + Lua "if \(%condition as lua expr) then\n \(%if_body as lua statements)\nend" test: unless (yes): barf "conditional fail" parse [unless %condition %unless_body] as (if (not %condition) %unless_body) @@ -43,10 +40,9 @@ compile [..] %when_false_expr unless %condition else %when_true_expr %when_false_expr unless %condition then %when_true_expr ..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): + if {Text: yes, List: yes, Dict: yes, Number: yes}.(%when_true_expr.type): return (..) Lua value ".." (\(%condition as lua expr) and \(%when_true_expr as lua expr) or \(%when_false_expr as lua expr)) @@ -65,13 +61,11 @@ compile [..] end end)()) - # GOTOs compile [=== %label ===, --- %label ---, *** %label ***] to (..) Lua "::label_\(%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 as lua identifier)") # Basic loop control compile [do next] to (Lua "continue") @@ -96,18 +90,19 @@ compile [%tree has subtree %subtree where %condition] to (..) compile [do next repeat] to (Lua "goto continue_repeat") compile [stop repeating] to (Lua "goto stop_repeat") compile [repeat while %condition %body] to: - %lua <- (..) - Lua ".." - while \(%condition as lua expr) do - \(%body as lua statements) + %lua = (..) + Lua "while \(%condition as lua expr) do\n \(%body as lua statements)" if (..) - %body has subtree % where ((%.type = "Action") and (%.stub is "do next repeat")) - ..: to %lua write "\n ::continue_repeat::" + %body has subtree % where ((%.type == "Action") and (%.stub is "do next repeat")) + ..: + to %lua write "\n ::continue_repeat::" to %lua write "\nend --while-loop" - if (%body has subtree % where ((%.type = "Action") and (%.stub is "stop repeating"))): - %lua <- (..) + if (..) + %body has subtree % where ((%.type == "Action") and (%.stub is "stop repeating")) + ..: + %lua = (..) Lua ".." do -- scope of "stop repeating" label \%lua @@ -119,13 +114,19 @@ compile [repeat while %condition %body] to: parse [repeat %body] as (repeat while (yes) %body) parse [repeat until %condition %body] as (repeat while (not %condition) %body) compile [repeat %n times %body] to: - %lua <- (Lua "for i=1,\(%n as lua expr) do\n \(%body as lua statements)") - if (%body has subtree % where ((%.type = "Action") and (%.stub is "do next repeat"))): + %lua = (..) + Lua "for i=1,\(%n as lua expr) do\n \(%body as lua statements)" + + if (..) + %body has subtree % where ((%.type == "Action") and (%.stub is "do next repeat")) + ..: to %lua write "\n ::continue_repeat::" to %lua write "\nend --numeric for-loop" - if (%body has subtree % where ((%.type = "Action") and (%.stub is "stop repeating"))): - %lua <- (..) + if (..) + %body has subtree % where ((%.type == "Action") and (%.stub is "stop repeating")) + ..: + %lua = (..) Lua ".." do -- scope of "stop repeating" label \%lua @@ -151,24 +152,26 @@ compile [..] for %var in %start to %stop by %step %body for %var in %start to %stop via %step %body ..to: + # This uses Lua's approach of only allowing loop-scoped variables in a loop assume (%var.type is "Var") or barf "Loop expected variable, not: \%var" - %lua <- (..) + %lua = (..) Lua ".." for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(%step as lua expr) do \(%body as lua statements) if (..) %body has subtree % where (..) - (%.type = "Action") and ((%.stub is "do next %") and (%.(3).1 = %var.1)) - ..: to %lua write "\n \(compile as (===next %var ===))" + (%.type == "Action") and ((%.stub is "do next %") and (%.(3).1 == %var.1)) + ..: + to %lua write "\n \(compile as (===next %var ===))" to %lua write "\nend --numeric for-loop" if (..) %body has subtree % where (..) - (%.type = "Action") and ((%.stub is "stop %") and (%.(2).1 = %var.1)) + (%.type == "Action") and ((%.stub is "stop %") and (%.(2).1 == %var.1)) ..: - %lua <- (..) + %lua = (..) Lua ".." do -- scope for stopping for-loop \%lua @@ -185,24 +188,27 @@ parse [for %var in %start to %stop %body] as (..) # 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 assume (%var.type is "Var") or barf "Loop expected variable, not: \%var" - %lua <- (..) + %lua = (..) Lua ".." for i,\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do \(%body as lua statements) if (..) %body has subtree % where (..) - (%.type = "Action") and ((%.stub is "do next %") and (%.(3).1 = %var.1)) - ..: to %lua write (Lua "\n\(compile as (===next %var ===))") + (%.type == "Action") and ((%.stub is "do next %") and (%.(3).1 == %var.1)) + ..: + to %lua write (..) + Lua "\n\(compile as (===next %var ===))" to %lua write "\nend --foreach-loop" if (..) %body has subtree % where (..) - (%.type = "Action") and ((%.stub is "stop %") and (%.(2).1 = %var.1)) + (%.type == "Action") and ((%.stub is "stop %") and (%.(2).1 == %var.1)) ..: - %lua <- (..) + %lua = (..) Lua ".." do -- scope for stopping for-loop \%lua @@ -213,39 +219,47 @@ compile [for %var in %iterable %body] to: # Dict iteration (lua's "pairs()") -compile [for %key = %value in %iterable %body, for %key %value in %iterable %body] to: +compile [for %key = %value in %iterable %body, for %key %value in %iterable %body] +..to: + # This uses Lua's approach of only allowing loop-scoped variables in a loop assume (%key.type is "Var") or barf "Loop expected variable, not: \%key" assume (%value.type is "Var") or barf "Loop expected variable, not: \%value" - %lua <- (..) + %lua = (..) Lua ".." for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(%iterable as lua expr)) do \(%body as lua statements) if (..) %body has subtree % where (..) - (%.type = "Action") and ((%.stub is "do next %") and (%.(3).1 = %key.1)) - ..: to %lua write (Lua "\n\(compile as (===next %key ===))") + (%.type == "Action") and ((%.stub is "do next %") and (%.(3).1 == %key.1)) + ..: + to %lua write (..) + Lua "\n\(compile as (===next %key ===))" if (..) %body has subtree % where (..) - (%.type = "Action") and ((%.stub is "do next %") and (%.(3).1 = %value.1)) - ..: to %lua write (Lua "\n\(compile as (===next %value ===))") + (%.type == "Action") and ((%.stub is "do next %") and (%.(3).1 == %value.1)) + ..: + to %lua write (..) + Lua "\n\(compile as (===next %value ===))" to %lua write "\nend --foreach-loop" - %stop_labels <- (Lua "") + %stop_labels = (Lua "") if (..) %body has subtree % where (..) - (%.type = "Action") and ((%.stub is "stop %") and (%.(2).1 = %key.1)) - ..: to %stop_labels write "\n\(compile as (===stop %key ===))" + (%.type == "Action") and ((%.stub is "stop %") and (%.(2).1 == %key.1)) + ..: + to %stop_labels write "\n\(compile as (===stop %key ===))" if (..) %body has subtree % where (..) - (%.type = "Action") and ((%.stub is "stop %") and (%.(2).1 = %value.1)) - ..: to %stop_labels write "\n\(compile as (===stop %value ===))" + (%.type == "Action") and ((%.stub is "stop %") and (%.(2).1 == %value.1)) + ..: + to %stop_labels write "\n\(compile as (===stop %value ===))" if ((length of "\%stop_labels") > 0): - %lua <- (..) + %lua = (..) Lua "do -- scope for stopping for % = % loop\n \%lua\%stop_labels\nend" return %lua @@ -254,15 +268,15 @@ compile [for %key = %value in %iterable %body, for %key %value in %iterable %bod # Switch statement/multi-branch if compile [when %body] to: - %code <- (Lua "") - %fallthroughs <- [] - %is_first <- (yes) - %seen_else <- (no) - %branches <- (%body if (%body.type = "Block") else [%body]) + %code = (Lua "") + %fallthroughs = [] + %is_first = (yes) + %seen_else = (no) + %branches = (%body if (%body.type == "Block") else [%body]) for %func_call in %branches: assume (%func_call.type is "Action") or barf "Invalid format for 'when' statement. Only '*' blocks are allowed." with {%star: %func_call.1, %condition: %func_call.2, %action: %func_call.3}: - assume (%star = "*") or barf "Invalid format for 'when' statement. Lines must begin with '*'" + assume (%star == "*") or barf "Invalid format for 'when' statement. Lines must begin with '*'" assume %condition or barf ".." Invalid format for 'when' statement. Lines must begin with '*' and have a condition \ ..or the word "else" @@ -271,11 +285,11 @@ compile [when %body] to: lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" do next %func_call - if (%condition = "else"): + if (%condition == "else"): assume (not %is_first) or barf "'else' clause cannot be first in 'when % = ?' block" to %code write "\nelse\n " to %code write (%action as lua statements) - %seen_else <- (yes) + %seen_else = (yes) ..else: assume (not %seen_else) or barf "'else' clause needs to be last in 'when' block" lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" @@ -287,26 +301,26 @@ compile [when %body] to: to %code write " then\n " to %code write (%action as lua statements) - %fallthroughs <- [] - %is_first <- (no) + %fallthroughs = [] + %is_first = (no) - assume (%fallthroughs = []) or barf "Unfinished fallthrough conditions in 'when' block" + assume (%fallthroughs == []) or barf "Unfinished fallthrough conditions in 'when' block" assume ((length of "\%code") > 0) or barf "Empty body for 'when' block" to %code write "\nend --when" return %code # Switch statement -compile [when %branch_value = ? %body, when %branch_value is ? %body] to: - %code <- (Lua "") - %fallthroughs <- [] - %is_first <- (yes) - %seen_else <- (no) - %branches <- (%body if (%body.type = "Block") else [%body]) +compile [when %branch_value = ? %body, when %branch_value is? %body] to: + %code = (Lua "") + %fallthroughs = [] + %is_first = (yes) + %seen_else = (no) + %branches = (%body if (%body.type == "Block") else [%body]) for %func_call in %branches: assume (%func_call.type is "Action") or barf "Invalid format for 'when' statement. Only '*' blocks are allowed." with {%star: %func_call.1, %condition: %func_call.2, %action: %func_call.3}: - assume (%star = "*") or barf "Invalid format for 'when' statement. Lines must begin with '*'" + assume (%star == "*") or barf "Invalid format for 'when' statement. Lines must begin with '*'" assume %condition or barf ".." Invalid format for 'when' statement. Lines must begin with '*' and have a condition \ ..or the word "else" @@ -315,7 +329,7 @@ compile [when %branch_value = ? %body, when %branch_value is ? %body] to: lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" do next %func_call - if (%condition = "else"): + if (%condition == "else"): assume (not %is_first) or barf "'else' clause cannot be first in 'when % = ?' block" to %code write "\nelse\n " to %code write (%action as lua statements) @@ -332,13 +346,13 @@ compile [when %branch_value = ? %body, when %branch_value is ? %body] to: to %code write "then\n " to %code write (%action as lua statements) - %fallthroughs <- [] - %is_first <- (no) + %fallthroughs = [] + %is_first = (no) - assume (%fallthroughs = []) or barf "Unfinished fallthrough conditions in 'when' block" + assume (%fallthroughs == []) or barf "Unfinished fallthrough conditions in 'when' block" assume ((length of "\%code") > 0) or barf "No body for 'when % = ?' block!" to %code write "\nend" - %code <- (..) + %code = (..) Lua ".." do --when % = ? local branch_value = \(%branch_value as lua expr) @@ -350,10 +364,8 @@ compile [when %branch_value = ? %body, when %branch_value is ? %body] to: # Do/finally compile [do %action] to (..) - Lua ".." - do - \(%action as lua statements) - end --do + Lua "do\n \(%action as lua statements)\nend --do" + compile [do %action then always %final_action] to (..) Lua ".." do |
