diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2017-09-28 17:49:15 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2017-09-28 17:49:15 -0700 |
| commit | ac25e20b9f94505175841d9a8da7253f8996926d (patch) | |
| tree | 965a766f89b826f80a61569e1c7084e5e669558a /lib/operators.nom | |
| parent | 10d61df78bdbf002a3701e468b0a3c88be2cad03 (diff) | |
Kinda mostly working, except for closure vars like in lib/secrets.nom.
Diffstat (limited to 'lib/operators.nom')
| -rw-r--r-- | lib/operators.nom | 89 |
1 files changed, 42 insertions, 47 deletions
diff --git a/lib/operators.nom b/lib/operators.nom index 4e7bd59..4d81806 100644 --- a/lib/operators.nom +++ b/lib/operators.nom @@ -1,15 +1,18 @@ require "lib/metaprogramming.nom" # Literals -parse (true; yes) as lua expr "true" -parse (false; no) as lua expr "false" -parse (nil; null) as lua expr "nil" -parse (inf; infinity) as lua expr "math.huge" -parse (nan; NaN; not a number) as lua expr "(0/0)" -parse (nop; pass) as lua code "" +compile (true; yes) to: "true" +compile (false; no) to: "false" +compile (nil; null) to: "nil" +compile (inf; infinity) to: "math.huge" +compile (nan; NaN; not a number) to: "(0/0)" +compile (pi; PI) to: "math.pi" +compile (tau; TAU) to: "(2*math.pi)" +compile (phi; PHI; golden ratio) to: "((1+math.sqrt(5))/2)" +compile (nop; pass) to code: "" # Ternary operator -parse (%if_expr if %condition else %else_expr) as lua expr ".." +compile (%if_expr if %condition else %else_expr) to: ".." |(function(nomsu, vars) # TODO: fix compiler bug that breaks this code if comments immediately follow ".." #.. Note: this uses a function instead of (condition and if_expr or else_expr) @@ -21,54 +24,46 @@ parse (%if_expr if %condition else %else_expr) as lua expr ".." | end |end)(nomsu, vars) +# Indexing: +compile (%obj's %key; %obj -> %key) to: "\(%obj as lua)[\(%key as lua)]" + # Variable assignment operator, and += type versions -lua block ".." - |local function assign(callback) - | return function(nomsu, vars, kind) - | if kind == "Expression" then - | nomsu:error("Cannot use an assignment operation as an expression value.") - | end - | if vars.var.type ~= "Var" then - | nomsu:error("Assignment operation has the wrong type for the left hand side. " - | .."Expected Var, but got: "..vars.var.type.."\\nMaybe you forgot a percent sign on the variable name?") - | end - | if vars.rhs.type ~= "Thunk" then - | nomsu:error("Assignment operation has the wrong type for the right hand side. " - | .."Expected Thunk, but got: "..vars.rhs.type.."\\nMaybe you used '=' instead of '=:'?") - | end - | if #vars.rhs.value.value > 1 then - | nomsu:error("Assignment operation should not have more than one value on the right hand side.") - | end - | return callback(nomsu:tree_to_lua(vars.var), - | nomsu:tree_to_lua(vars.rhs.value.value[1].value)), true - | end - |end - |nomsu:defmacro("%var = %rhs", assign(function(var,result) return var.." = "..result end)) - |nomsu:defmacro("%var += %rhs", assign(function(var,result) return var.." = "..var.." + "..result end)) - |nomsu:defmacro("%var -= %rhs", assign(function(var,result) return var.." = "..var.." - "..result end)) - |nomsu:defmacro("%var *= %rhs", assign(function(var,result) return var.." = "..var.." * "..result end)) - |nomsu:defmacro("%var /= %rhs", assign(function(var,result) return var.." = "..var.." / "..result end)) - |nomsu:defmacro("%var ^= %rhs", assign(function(var,result) return var.." = "..var.." ^ "..result end)) - |nomsu:defmacro("%var and= %rhs", assign(function(var,result) return var.." = "..var.." and "..result end)) - |nomsu:defmacro("%var or= %rhs", assign(function(var,result) return var.." = "..var.." or "..result end)) - |nomsu:defmacro("%var join= %rhs", assign(function(var,result) return var.." = "..var.." .. "..result end)) - |nomsu:defmacro("%var mod= %rhs", assign(function(var,result) return var.." = "..var.." % "..result end)) +compile (%var = %val) to code: "\(%var as lua) = \(%val as lua)" +compile (%var += %val) to code: "\(%var as lua) += \(%val as lua)" +compile (%var -= %val) to code: "\(%var as lua) -= \(%val as lua)" +compile (%var *= %val) to code: "\(%var as lua) *= \(%val as lua)" +compile (%var /= %val) to code: "\(%var as lua) /= \(%val as lua)" +compile (%var ^= %val) to code: "\(%var as lua) ^= \(%val as lua)" +compile (%var and= %val) to code: "\(%var as lua) = \(%var as lua) and\(%val as lua)" +compile (%var or= %val) to code: "\(%var as lua) = \(%var as lua) or \(%val as lua)" +compile (%var join= %val) to code: "\(%var as lua) = \(%var as lua) .. \(%val as lua)" +compile (%var mod= %val) to code: "\(%var as lua) = \(%var as lua) % \(%val as lua)" + +%x =: 5 # Binary Operators lua block ".." - |local binops = {"+","-","*","/","<","<=",">",">=","^",{"===","=="},{"!==","~="},"and","or",{"mod","%"}} + |local binops = {"-","/","<","<=",">",">=","^",{"===","=="},{"!==","~="},{"mod","%"}} |for _,op in ipairs(binops) do | local nomsu_alias = op | if type(op) == 'table' then | nomsu_alias, op = unpack(op) | end - | nomsu:defmacro("%a "..nomsu_alias.." %b", (function(nomsu, vars, kind) + | nomsu:defmacro("%a "..nomsu_alias.." %b", (function(nomsu, vars) | return "("..nomsu:tree_to_lua(vars.a).." "..op.." "..nomsu:tree_to_lua(vars.b)..")" | end), [["(\\(%a) ]]..op..[[ \\(%b))"]]) |end +# TODO: implement OR, XOR, AND for multiple operands +compile (%a OR %b; %a | %b) to: "bit32.bor(\(%a as lua), \(%b as lua))" +compile (%a XOR %b) to: "bit32.bxor(\(%a as lua), \(%b as lua))" +compile (%a AND %b; %a & %b) to: "bit32.band(\(%a as lua), \(%b as lua))" +compile (NOT %; ~ %) to: "bit32.bnot(\(% as lua))" +compile (%x LSHIFT %shift; %x << %shift) to: "bit32.lshift(\(%x as lua), \(%shift as lua))" +compile (%x RSHIFT %shift) to: "bit32.rshift(\(%x as lua), \(%shift as lua))" +compile (%x ARSHIFT %shift; %x >> %shift) to: "bit32.arshift(\(%x as lua), \(%shift as lua))" # == and != do equivalence checking, rather than identity checking -parse (%a == %b) as lua expr "nomsu.utils.equivalent(\(%a), \(%b))" -parse (%a != %b) as lua expr "(not nomsu.utils.equivalent(\(%a), \(%b)))" +compile (%a == %b) to: "nomsu.utils.equivalent(\(%a as lua), \(%b as lua))" +compile (%a != %b) to: "(not nomsu.utils.equivalent(\(%a as lua), \(%b as lua)))" # Commutative Operators defined for up to 8 operands # TODO: work out solution for commutative operators using more clever macros @@ -77,10 +72,10 @@ lua block ".." |local comops = {"+","*","and","or"} |for _,_op in ipairs(comops) do | local op = _op - | local spec = "%1 "..op.." %2" - | for n=3,max_operands do + | local spec = "%1 " + | for n=2,max_operands do | spec = spec .." "..op.." %"..tostring(n) - | nomsu:defmacro(spec, (function(nomsu, vars, kind) + | nomsu:defmacro(spec, (function(nomsu, vars) | local bits = {} | for i=1,n do | table.insert(bits, (nomsu:tree_to_lua(vars[tostring(i)]))) @@ -125,5 +120,5 @@ lua block ".." |end # Unary operators -parse (- %a) as lua expr "-(\(%a))" -parse (not %a) as lua expr "not (\(%a))" +compile (- %) to: "-(\(% as lua))" +compile (not %) to: "not (\(% as lua))" |
