diff options
Diffstat (limited to 'core/operators.nom')
| -rw-r--r-- | core/operators.nom | 120 |
1 files changed, 53 insertions, 67 deletions
diff --git a/core/operators.nom b/core/operators.nom index cc86398..a7cb116 100644 --- a/core/operators.nom +++ b/core/operators.nom @@ -24,57 +24,58 @@ test: test: %x = 10 assume (%x == 10) - -# Variable assignment operator -(%var = %value) compiles to: - lua> "\ - ..local \%var_lua = \(%var as lua expr) - local \%value_lua = \(%value as lua expr) - local lua = LuaCode(\%var_lua, ' = ', \%value_lua, ';') - if \%var.type == 'Var' then - lua:add_free_vars({compile(\%var):text()}) - end - return lua" - -test: - set {%x: 10, %y: 20} + [%x, %y] = [10, 20] assume ((%x == 10) and (%y == 20)) or barf "mutli-assignment failed." - set {%x: %y, %y: %x} + [%x, %y] = [%y, %x] assume ((%y == 10) and (%x == 20)) or barf "swapping vars failed." + %vals = [4, 5] + [%x, %y] = (unpack %vals) + assume ((%x == 4) and (%y == 5)) or barf "unpacking failed" -# Simultaneous mutli-assignments like: x,y,z = 1,x,3; -# TODO: deprecate? -(set %assignments) compiles to: - assume (%assignments.type is "Dict") or barf "\ - ..Expected a Dict for the assignments part of '<- %' statement, not \%assignments" - +# Variable assignment operator +(%var = %value) compiles to: lua> "\ - ..local lhs, rhs = LuaCode(), LuaCode() - for i, item in ipairs(\%assignments) do - local \%target, \%value = item[1], item[2] - \%value = \%value:map(function(t) - if SyntaxTree:is_instance(t) and t.type == "Action" and t.stub == "?" then - return \%target + .. + local lua = LuaCode() + if \%var.type == "List" then + for i, \%assignment in ipairs(\%var) do + if i > 1 then lua:append(", ") end + local assignment_lua = \(%assignment as lua expr) + lua:append(assignment_lua) + if \%assignment.type == 'Var' then + lua:add_free_vars({assignment_lua:text()}) end - end) - local target_lua = \(%target as lua) - local value_lua = \(%value as lua) - if \%target.type == "Var" then - lhs:add_free_vars({target_lua:text()}) end - if i > 1 then - lhs:append(", ") - rhs:append(", ") + lua:append(' = ') + if \%value.type == "List" then + if #\%value ~= #\%var then + compile_error_at(\%value, + "This assignment has too "..(#\%value > #\%var and "many" or "few").." values.", + "Make sure it has the same number of values on the left and right hand side of the '=' operator.") + end + for i, \%val in ipairs(\%value) do + if i > 1 then lua:append(", ") end + local val_lua = \(%val as lua expr) + lua:append(val_lua) + end + lua:append(";") + else + lua:append(\(%value as lua expr), ';') end - lhs:append(target_lua) - rhs:append(value_lua) + else + local var_lua = \(%var as lua expr) + lua:append(var_lua) + if \%var.type == 'Var' then + lua:add_free_vars({var_lua:text()}) + end + lua:append(' = ', \(%value as lua expr), ';') end - return LuaCode(lhs, " = ", rhs, ";")" + return lua" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: - set {%foozle: "outer", %y: "outer"} + [%foozle, %y] = ["outer", "outer"] externally (set global x local y) means: external %foozle = "inner" %y = "inner" @@ -82,7 +83,7 @@ test: assume ((%foozle == "inner") and (%y == "outer")) or barf "external failed." (external %var = %value) compiles to "\(%var as lua) = \(%value as lua)" test: - set {%foozle: "outer", %y: "outer"} + [%foozle, %y] = ["outer", "outer"] externally (set global x local y) means: with external [%foozle]: %foozle = "inner" @@ -97,7 +98,7 @@ test: return %body_lua test: - set {%x: 1, %y: 2} + [%x, %y] = [1, 2] with {%z: nil, %x: 999}: %z = 999 assume (%z == 999) or barf "'with' failed." @@ -149,29 +150,14 @@ test: assume (%calls == 1) or barf "\ ..Three-way comparison evaluated middle value multiple times" -(%x < %y < %z) parses as (..) - call ([%a, %b, %c] -> ((%a < %b) and (%b < %c))) with [%x, %y, %z] - -(%x <= %y < %z) parses as (..) - call ([%a, %b, %c] -> ((%a <= %b) and (%b < %c))) with [%x, %y, %z] - -(%x < %y <= %z) parses as (..) - call ([%a, %b, %c] -> ((%a < %b) and (%b <= %c))) with [%x, %y, %z] - -(%x <= %y <= %z) parses as (..) - call ([%a, %b, %c] -> ((%a <= %b) and (%b <= %c))) with [%x, %y, %z] - -(%x > %y > %z) parses as (..) - call ([%a, %b, %c] -> ((%a > %b) and (%b > %c))) with [%x, %y, %z] - -(%x >= %y > %z) parses as (..) - call ([%a, %b, %c] -> ((%a >= %b) and (%b > %c))) with [%x, %y, %z] - -(%x > %y >= %z) parses as (..) - call ([%a, %b, %c] -> ((%a > %b) and (%b >= %c))) with [%x, %y, %z] - -(%x >= %y >= %z) parses as (..) - call ([%a, %b, %c] -> ((%a >= %b) and (%b >= %c))) with [%x, %y, %z] +(%x < %y < %z) parses as (((%a %b %c) -> ((%a < %b) and (%b < %c))) %x %y %z) +(%x <= %y < %z) parses as (((%a %b %c) -> ((%a <= %b) and (%b < %c))) %x %y %z) +(%x < %y <= %z) parses as (((%a %b %c) -> ((%a < %b) and (%b <= %c))) %x %y %z) +(%x <= %y <= %z) parses as (((%a %b %c) -> ((%a <= %b) and (%b <= %c))) %x %y %z) +(%x > %y > %z) parses as (((%a %b %c) -> ((%a > %b) and (%b > %c))) %x %y %z) +(%x >= %y > %z) parses as (((%a %b %c) -> ((%a >= %b) and (%b > %c))) %x %y %z) +(%x > %y >= %z) parses as (((%a %b %c) -> ((%a > %b) and (%b >= %c))) %x %y %z) +(%x >= %y >= %z) parses as (((%a %b %c) -> ((%a >= %b) and (%b >= %c))) %x %y %z) # TODO: optimize for common case where x,y,z are all either variables or number literals # Boolean Operators @@ -249,9 +235,9 @@ test: assume (%x == 4) or barf "*= failed" wrap %x around 3 assume (%x == 1) or barf "wrap around failed" -(%var += %) parses as (%var = (%var + %)) -(%var -= %) parses as (%var = (%var - %)) -(%var *= %) parses as (%var = (%var * %)) +(%var += %) parses as (%var = ((%var or 0) + %)) +(%var -= %) parses as (%var = ((%var or 0) - %)) +(%var *= %) parses as (%var = ((%var or 1) * %)) (%var /= %) parses as (%var = (%var / %)) (%var ^= %) parses as (%var = (%var ^ %)) (%var and= %) parses as (%var = (%var and %)) |
