diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2018-07-18 17:55:29 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2018-07-18 17:56:15 -0700 |
| commit | bf67a610135c0803187cf6ed896638962f142d14 (patch) | |
| tree | a0b126c954168282c8c69ea728d4abbae712ac33 /core | |
| parent | acb86f78c3f79479ac3a73f0e5862f8f5d8f31f5 (diff) | |
Updating to version 2.4.4.3, with new syntax for multi-statement 'if'
and switch statements.
Diffstat (limited to 'core')
| -rw-r--r-- | core/collections.nom | 2 | ||||
| -rw-r--r-- | core/control_flow.nom | 164 | ||||
| -rw-r--r-- | core/coroutines.nom | 2 | ||||
| -rw-r--r-- | core/errors.nom | 5 | ||||
| -rw-r--r-- | core/io.nom | 2 | ||||
| -rw-r--r-- | core/math.nom | 2 | ||||
| -rw-r--r-- | core/metaprogramming.nom | 16 | ||||
| -rw-r--r-- | core/operators.nom | 12 | ||||
| -rw-r--r-- | core/scopes.nom | 13 | ||||
| -rw-r--r-- | core/text.nom | 2 |
10 files changed, 112 insertions, 108 deletions
diff --git a/core/collections.nom b/core/collections.nom index 45ca74c..428ed4d 100644 --- a/core/collections.nom +++ b/core/collections.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V2.3.4.3 +#!/usr/bin/env nomsu -V2.4.4.3 # This file contains code that supports manipulating and using collections like lists and dictionaries. diff --git a/core/control_flow.nom b/core/control_flow.nom index b3f0978..5719d72 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -154,7 +154,7 @@ compile [..] ..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" + unless (%var.type is "Var"): compile error at %var.source "Loop expected variable, not: %s" %lua = (..) Lua ".." for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(%step as lua expr) do @@ -185,12 +185,11 @@ compile [..] parse [for %var in %start to %stop %body] as (..) for %var in %start to %stop via 1 %body - # 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" + unless (%var.type is "Var"): compile error at %var.source "Loop expected variable, not: %s" %lua = (..) Lua ".." for i,\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do @@ -223,8 +222,8 @@ compile [for %key = %value in %iterable %body, for %key %value in %iterable %bod ..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" + unless (%key.type is "Var"): compile error at %key.source "Loop expected variable, not: %s" + unless (%value.type is "Var"): compile error at %value.source "Loop expected variable, not: %s" %lua = (..) Lua ".." for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(%iterable as lua expr)) do @@ -266,101 +265,88 @@ compile [for %key = %value in %iterable %body, for %key %value in %iterable %bod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Switch statement/multi-branch if -compile [when %body] to: +# Multi-branch conditional (if..elseif..else) +compile [if %body, when %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 %condition or barf ".." - Invalid format for 'when' statement. Lines must begin with '*' and have a condition \ - ..or the word "else" - - if (%action is (nil)): - lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" - do next %func_call - - 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) - ..else: - assume (not %seen_else) or barf "'else' clause needs to be last in 'when' block" - lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" - to %code write "\("if" if %is_first else "\nelseif") " - for %i = %condition in %fallthroughs: - if (%i > 1): to %code write " or " - to %code write %condition - - to %code write " then\n " - to %code write (%action as lua statements) - - %fallthroughs = [] - %is_first = (no) + %clause = "if" + %else_allowed = (yes) + unless (%body.type is "Block"): compile error at %body.source "'if' expected a Block, but got: %s" + for %line in %body: + unless (..) + ((%line.type is "Action") and ((length of %line) >= 2)) + ..and (%line.(length of %line) is "Block" syntax tree) + ..: + compile error at %line.source ".." + Invalid line for 'if', each line should contain conditional expressions \ + ..followed by a block, or "else" followed by a block: + %s + %action = %line.(length of %line) + if ((%line.1 is "else") and ((length of %line) == 2)): + unless %else_allowed: compile error at %line.source "Can't have two 'else' blocks" + unless ((length of "\%code") > 0): + compile error at %line.source "Can't have an 'else' block without a preceeding condition" + to %code write "\nelse\n \(%action as lua statements)" + %else_allowed = (no) + ..else: + to %code write "\%clause " + for %i in 1 to ((length of %line) - 1): + unless (%line.%i is syntax tree): + compile error at %line.source ".." + Invalid condition for 'if' statement: + %s + if (%i > 1): to %code write " or " + to %code write (%line.%i as lua expr) + to %code write " then\n \(%action as lua statements)" + %clause = "\nelseif" - assume (%fallthroughs == []) or barf "Unfinished fallthrough conditions in 'when' block" - assume ((length of "\%code") > 0) or barf "Empty body for 'when' block" + if ((length of "\%code") == 0): + compile error at %body.source "'if' block has an empty body" to %code write "\nend --when" return %code - # Switch statement -compile [when %branch_value = ? %body, when %branch_value is? %body] to: +compile [if %branch_value is %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 %condition or barf ".." - Invalid format for 'when' statement. Lines must begin with '*' and have a condition \ - ..or the word "else" - - if (%action is (nil)): - lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" - do next %func_call - - 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) - ..else: - assume (not %seen_else) or barf "'else' clause needs to be last in 'when % = ?' block" - to %code write "\("if" if %is_first else "\nelseif") " - lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" - for %i = % in %fallthroughs: - if (%i > 1): to %code write " or " - if ((%.type is "Text") or (%.type is "Number")): - to %code write "branch_value == \%" - ..else: to %code write "utils.equivalent(branch_value, \%)" - - to %code write "then\n " - to %code write (%action as lua statements) - - %fallthroughs = [] - %is_first = (no) + %clause = "if" + %else_allowed = (yes) + unless (%body.type is "Block"): compile error at %body.source "'if' expected a Block, but got: %s" + for %line in %body: + unless (..) + ((%line.type is "Action") and ((length of %line) >= 2)) + ..and (%line.(length of %line) is "Block" syntax tree) + ..: + compile error at %line.source ".." + Invalid line for 'if % is % %', each line should contain expressions \ + ..followed by a block, or "else" followed by a block: + %s + %action = %line.(length of %line) + if ((%line.1 is "else") and ((length of %line) == 2)): + unless %else_allowed: compile error at %line.source "Can't have two 'else' blocks" + unless ((length of "\%code") > 0): + compile error at %line.source "Can't have an 'else' block without a preceeding condition" + to %code write "\nelse\n \(%action as lua statements)" + %else_allowed = (no) + ..else: + to %code write "\%clause " + for %i in 1 to ((length of %line) - 1): + unless (%line.%i is syntax tree): + compile error at %line.source ".." + Invalid condition for 'if' statement: + %s + if (%i > 1): to %code write " or " + to %code write "branch_value == \(%line.%i as lua expr)" + to %code write " then\n \(%action as lua statements)" + %clause = "\nelseif" - 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 = (..) + if ((length of "\%code") == 0): + compile error at %body.source "'if % is % %' block has an empty body" + to %code write "\nend --when" + return (..) Lua ".." - do --when % = ? + do --if % is local branch_value = \(%branch_value as lua expr) \%code - end --when % = ? - - return %code - + end --if % is # Do/finally compile [do %action] to (..) diff --git a/core/coroutines.nom b/core/coroutines.nom index 54889d4..bff115d 100644 --- a/core/coroutines.nom +++ b/core/coroutines.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V2.3.4.3 +#!/usr/bin/env nomsu -V2.4.4.3 # This file defines the code that creates and manipulates coroutines diff --git a/core/errors.nom b/core/errors.nom index efa69a8..5dfed1e 100644 --- a/core/errors.nom +++ b/core/errors.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V2.3.4.3 +#!/usr/bin/env nomsu -V2.4.4.3 # This file contains basic error reporting code @@ -7,6 +7,9 @@ compile [traceback] to (Lua value "debug.traceback()") compile [traceback %] to (Lua value "debug.traceback('', \(% as lua expr))") compile [barf] to (Lua "error(nil, 0);") compile [barf %msg] to (Lua "error(\(%msg as lua expr), 0);") +compile [compile error at %source %msg] to (..) + Lua "nomsu:compile_error(\(%source as lua expr), \(%msg as lua expr))" + compile [assume %condition] to: lua> ".." local \%assumption = 'Assumption failed: '..tostring(nomsu:tree_to_nomsu(\%condition)) diff --git a/core/io.nom b/core/io.nom index 2659b3b..b06ebb3 100644 --- a/core/io.nom +++ b/core/io.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V2.3.4.3 +#!/usr/bin/env nomsu -V2.4.4.3 # This file contains basic input/output code diff --git a/core/math.nom b/core/math.nom index d8952f6..e0c58a3 100644 --- a/core/math.nom +++ b/core/math.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V2.3.4.3 +#!/usr/bin/env nomsu -V2.4.4.3 # This file defines some common math literals and functions diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom index 8328d26..028a914 100644 --- a/core/metaprogramming.nom +++ b/core/metaprogramming.nom @@ -1,9 +1,9 @@ -#!/usr/bin/env nomsu -V2.3.4.3 +#!/usr/bin/env nomsu -V2.4.4.3 # This File contains actions for making actions and compile-time actions and some helper functions to make that easier. -lua> "NOMSU_CORE_VERSION = 3" +lua> "NOMSU_CORE_VERSION = 4" lua> ".." nomsu.COMPILE_ACTIONS["% -> %"] = function(nomsu, tree, \%args, \%body) local lua = LuaCode.Value(tree.source, "function(") @@ -119,8 +119,16 @@ compile [parse %actions as %body] to (..) local ret = \(compile as (compile %actions to %new_body)) return ret -compile [%tree as lua expr] to (..) - Lua value "nomsu:compile(\(=lua "nomsu:compile(\%tree):as_expr()")):as_expr()" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +action [%tree as lua expr]: + lua> ".." + \%tree_lua = nomsu:compile(\%tree) + if not \%tree_lua.is_value then + nomsu:compile_error(\%tree.source, "Could not convert %s to a Lua expression", + nomsu:tree_to_nomsu(\%tree)) + end + return \%tree_lua ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/core/operators.nom b/core/operators.nom index 70b0207..bce91c4 100644 --- a/core/operators.nom +++ b/core/operators.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V2.3.4.3 +#!/usr/bin/env nomsu -V2.4.4.3 # This file contains definitions of operators like "+" and "and". @@ -147,21 +147,29 @@ compile [%x wrapped around %y, %x mod %y] to (..) # (uses a lambda to avoid re-evaluating middle value, while still being an expression) parse [%x < %y < %z] as (..) =lua "(function(x,y,z) return x < y and y < z; end)(\%x,\%y,\%z)" + parse [%x <= %y < %z] as (..) =lua "(function(x,y,z) return x <= y and y < z; end)(\%x,\%y,\%z)" + parse [%x < %y <= %z] as (..) =lua "(function(x,y,z) return x < y and y <= z; end)(\%x,\%y,\%z)" + parse [%x <= %y <= %z] as (..) =lua "(function(x,y,z) return x <= y and y <= z; end)(\%x,\%y,\%z)" + parse [%x > %y > %z] as (..) =lua "(function(x,y,z) return x > y and y > z; end)(\%x,\%y,\%z)" + parse [%x >= %y > %z] as (..) =lua "(function(x,y,z) return x >= y and y > z; end)(\%x,\%y,\%z)" + parse [%x > %y >= %z] as (..) =lua "(function(x,y,z) return x > y and y >= z; end)(\%x,\%y,\%z)" + parse [%x >= %y >= %z] as (..) =lua "(function(x,y,z) return x >= y and y >= z; end)(\%x,\%y,\%z)" + # TODO: optimize for common case where x,y,z are all either variables or number literals # Boolean Operators compile [%x and %y] to (Lua value "(\(%x as lua expr) and \(%y as lua expr))") @@ -204,4 +212,4 @@ parse [%var /= %] as (%var = (%var / %)) parse [%var ^= %] as (%var = (%var ^ %)) parse [%var and= %] as (%var = (%var and %)) parse [%var or= %] as (%var = (%var or %)) -parse [wrap %var around %] as (%var = (%var wrapped around %)) +parse [wrap %var around %] as (%var = (%var wrapped around %))
\ No newline at end of file diff --git a/core/scopes.nom b/core/scopes.nom index 2be24e6..30bdea0 100644 --- a/core/scopes.nom +++ b/core/scopes.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V2.3.4.3 +#!/usr/bin/env nomsu -V2.4.4.3 # This file contains definitions pertaining to variable scoping @@ -8,17 +8,16 @@ use "core/collections.nom" use "core/control_flow.nom" compile [with local %locals %body, with local %locals do %body] to: %body_lua = (%body as lua statements) - when %locals.type = ?: - * "Dict": + if %locals.type is: + "Dict": %body_lua = (..) Lua "\(compile as (<- %locals))\n\%body_lua" declare locals ("\(%.1 as lua)" for % in %locals) in %body_lua - * "List": declare locals ("\(% as lua)" for % in %locals) in %body_lua - * "Var" - * "Action": declare locals ["\(%locals as lua)"] in %body_lua - *else (barf "Unexpected local: \(%locals as nomsu)") + "List": declare locals ("\(% as lua)" for % in %locals) in %body_lua + "Var" "Action": declare locals ["\(%locals as lua)"] in %body_lua + else: compile error at %locals.source "Unexpected locals: %s" return (..) Lua "do\n \%body_lua\nend"
\ No newline at end of file diff --git a/core/text.nom b/core/text.nom index 62ec056..30eab50 100644 --- a/core/text.nom +++ b/core/text.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V2.3.4.3 +#!/usr/bin/env nomsu -V2.4.4.3 # This file contains some definitions of text escape sequences, including ANSI console color codes. |
