diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2019-01-14 15:42:48 -0800 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2019-01-14 15:43:24 -0800 |
| commit | c1c32688a4afc43f6addb99b8b5fa878944a70e3 (patch) | |
| tree | c886f21b5b08a9053aa74fcba4b241dae5ede76d /core/operators.nom | |
| parent | 2309b696fc34b24f05f6658b94f9105ca8ee76e4 (diff) | |
Overhaul in progress, mostly working. Moved all the nomsu packages into
lib/, including core/*. Changes to how nomsu environments and importing
work.
Diffstat (limited to 'core/operators.nom')
| -rw-r--r-- | core/operators.nom | 263 |
1 files changed, 0 insertions, 263 deletions
diff --git a/core/operators.nom b/core/operators.nom deleted file mode 100644 index dee76b6..0000000 --- a/core/operators.nom +++ /dev/null @@ -1,263 +0,0 @@ -#!/usr/bin/env nomsu -V6.14 -# - This file contains definitions of operators like "+" and "and". - -use "core/metaprogramming" - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -test: - assume (all [1 < 2, 2 > 1, 1 <= 2, 2 >= 1, 1 == 1, 1 != 2]) - -# Comparison Operators -($x < $y) compiles to "(\($x as lua expr) < \($y as lua expr))" -($x > $y) compiles to "(\($x as lua expr) > \($y as lua expr))" -($x <= $y) compiles to "(\($x as lua expr) <= \($y as lua expr))" -($x >= $y) compiles to "(\($x as lua expr) >= \($y as lua expr))" -[$a is $b, $a == $b] all compile to "(\($a as lua expr) == \($b as lua expr))" -[$a isn't $b, $a is not $b, $a not= $b, $a != $b] all compile to - "(\($a as lua expr) ~= \($b as lua expr))" - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -test: - $x = 10 - assume ($x == 10) - [$x, $y] = [10, 20] - unless (($x == 10) and ($y == 20)): - fail "mutli-assignment failed." - [$x, $y] = [$y, $x] - unless (($y == 10) and ($x == 20)): - fail "swapping vars failed." - $vals = [4, 5] - [$x, $y] = (unpack $vals) - unless (($x == 4) and ($y == 5)): - fail "unpacking failed" - -# Variable assignment operator -($var = $value) compiles to: - lua> (" - local lua = LuaCode() - if \$var.type == "List" then - for i, \$assignment in ipairs(\$var) do - if i > 1 then lua:add(", ") end - local assignment_lua = \($assignment as lua expr) - lua:add(assignment_lua) - if \$assignment.type == 'Var' then - lua:add_free_vars({assignment_lua:text()}) - end - end - lua:add(' = ') - 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:add(", ") end - local val_lua = \($val as lua expr) - lua:add(val_lua) - end - lua:add(";") - else - lua:add(\($value as lua expr), ';') - end - else - local var_lua = \($var as lua expr) - lua:add(var_lua) - if \$var.type == 'Var' then - lua:add_free_vars({var_lua:text()}) - end - lua:add(' = ', \($value as lua expr)) - end - return lua - ") - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -test: - [$foozle, $y] = ["outer", "outer"] - externally (set global x local y) means: - external $foozle = "inner" - $y = "inner" - set global x local y - unless (($foozle == "inner") and ($y == "outer")): fail "external failed." -(external $var = $value) compiles to: - $lua = ((SyntaxTree {.type = "Action", .source = $var.source, .1 = $var, .2 = "=", .3 = $value}) as lua) - $lua, remove free vars - return $lua -test: - [$foozle, $y] = ["outer", "outer"] - externally (set global x local y) means: - with external [$foozle]: - $foozle = "inner" - $y = "inner" - set global x local y - unless (($foozle == "inner") and ($y == "outer")): - fail "'with external' failed." - -(with external $externs $body) compiles to: - $body_lua = ($body as lua) - lua> (" - \$body_lua:remove_free_vars(table.map(\$externs, function(v) return \(nomsu environment):compile(v):text() end)) - ") - return $body_lua - -test: - [$x, $y] = [1, 2] - with [$z, $x = 999]: - assume $z == (nil) - $z = 999 - unless ($z == 999): - fail "'with' failed." - - unless ($x == 999): - fail "'with' assignment failed." - - unless ($x == 1): - fail "'with' scoping failed" - - unless ($z == (nil)): - fail "'with' scoping failed" - -(with $assignments $body) compiles to: - lua> (" - local \$defs = LuaCode() - for i, \$item in ipairs(\$assignments) do - if i > 1 then \$defs:add("\\n") end - local item_lua = \($item as lua) - if \$item.type == 'Action' and \$item.stub == '1 =' then - item_lua:remove_free_vars(item_lua.free_vars) - end - \$defs:add("local ", item_lua, ";") - end - ") - - return - Lua (" - do - \$defs - \($body as lua) - end -- 'with' block - ") - -# Math Operators -test: - unless ((5 wrapped around 2) == 1): - fail "mod not working" - -[$x wrapped around $y, $x mod $y] all compile to - "((\($x as lua expr)) % (\($y as lua expr)))" - -# 3-part chained comparisons -# (uses a lambda to avoid re-evaluating middle value, while still being an expression) -test: - $calls = 0 - (one) means: - external $calls = ($calls + 1) - return 1 - - unless (0 <= (one) <= 2): - fail "Three-way chained comparison failed." - - unless ($calls == 1): - fail "Three-way comparison evaluated middle value multiple times" -($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 -test: - (barfer) means (fail "short circuiting failed") - assume (((no) and (barfer)) == (no)) - assume ((no) or (yes)) - assume ((yes) or (barfer)) -($x and $y) compiles to "(\($x as lua expr) and \($y as lua expr))" -($x or $y) compiles to "(\($x as lua expr) or \($y as lua expr))" - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -# Bitwise Operators -# TODO: implement OR, XOR, AND for multiple operands? -test: - assume ((~ (~ 5)) == 5) - assume ((1 | 4) == 5) - assume ((1 ~ 3) == 2) - assume ((1 & 3) == 1) - assume ((1 << 2) == 4) - assume ((4 >> 2) == 1) - -# Lua 5.3 introduced bit operators like | and &. Use them when possible, otherwise - fall back to bit.bor(), bit.band(), etc. -lua> "if \((is jit) or ((Lua version) == "Lua 5.2")) then" -[NOT $, ~ $] all compile to "bit.bnot(\($ as lua expr))" -[$x OR $y, $x | $y] all compile to - "bit.bor(\($x as lua expr), \($y as lua expr))" - -[$x XOR $y, $x ~ $y] all compile to - "bit.bxor(\($x as lua expr), \($y as lua expr))" - -[$x AND $y, $x & $y] all compile to - "bit.band(\($x as lua expr), \($y as lua expr))" - -[$x LSHIFT $shift, $x << $shift] all compile to - "bit.lshift(\($x as lua expr), \($shift as lua expr))" - -[$x RSHIFT $shift, $x >> $shift] all compile to - "bit.rshift(\($x as lua expr), \($shift as lua expr))" - -lua> "else" -[NOT $, ~ $] all compile to "~(\($ as lua expr))" -[$x OR $y, $x | $y] all compile to "(\($x as lua expr) | \($y as lua expr))" -[$x XOR $y, $x ~ $y] all compile to "(\($x as lua expr) ~ \($y as lua expr))" -[$x AND $y, $x & $y] all compile to "(\($x as lua expr) & \($y as lua expr))" -[$x LSHIFT $shift, $x << $shift] all compile to - "(\($x as lua expr) << \($shift as lua expr))" - -[$x RSHIFT $shift, $x >> $shift] all compile to - "(\($x as lua expr) >> \($shift as lua expr))" - -lua> "end" - -# Unary operators -test: - assume ((- 5) == -5) - assume ((not (yes)) == (no)) -(- $) compiles to "(- \($ as lua expr))" -(not $) compiles to "(not \($ as lua expr))" -test: - assume ((size of [1, 2, 3]) == 3) - assume ((#[1, 2, 3]) == 3) -[#$list, size of $list] all compile to "(#\($list as lua expr))" -($list is empty) compiles to "(#\($list as lua expr) == 0)" - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -# Update operators -test: - $x = 1 - $x += 1 - unless ($x == 2): - fail "+= failed" - $x *= 2 - unless ($x == 4): - fail "*= failed" - wrap $x around 3 - unless ($x == 1): - fail "wrap around failed" -($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 $)) -($var or= $) parses as ($var = ($var or $)) -(wrap $var around $) parses as ($var = ($var wrapped around $)) |
