aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-07-18 17:55:29 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2018-07-18 17:56:15 -0700
commitbf67a610135c0803187cf6ed896638962f142d14 (patch)
treea0b126c954168282c8c69ea728d4abbae712ac33 /core
parentacb86f78c3f79479ac3a73f0e5862f8f5d8f31f5 (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.nom2
-rw-r--r--core/control_flow.nom164
-rw-r--r--core/coroutines.nom2
-rw-r--r--core/errors.nom5
-rw-r--r--core/io.nom2
-rw-r--r--core/math.nom2
-rw-r--r--core/metaprogramming.nom16
-rw-r--r--core/operators.nom12
-rw-r--r--core/scopes.nom13
-rw-r--r--core/text.nom2
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.