Reworking some stuff so that functions only allow expressions to be
return values with either an explicit "return" statement or if they're the only line in the function, and the line is an expression.
This commit is contained in:
parent
c92e5fbc81
commit
568a44ef19
@ -51,7 +51,7 @@ compile [%list ->* %indices] to:
|
||||
%ret = "\(%list as lua)"
|
||||
for %index in (%indices's "value"):
|
||||
%ret join= "[\(%index as lua)]"
|
||||
"\%ret"
|
||||
return "\%ret"
|
||||
|
||||
# Assignment
|
||||
compile [..]
|
||||
@ -76,35 +76,35 @@ rule [flatten %lists] =:
|
||||
for %list in %lists:
|
||||
for %item in %list:
|
||||
add %item to %flat
|
||||
%flat
|
||||
return %flat
|
||||
|
||||
rule [dict %items] =:
|
||||
%dict = []
|
||||
for %pair in %items:
|
||||
%dict -> (%pair -> 1) = (%pair -> 2)
|
||||
%dict
|
||||
return %dict
|
||||
|
||||
rule [entries in %dict] =:
|
||||
%entries = []
|
||||
for %k = %v in %dict:
|
||||
add {key=%k, value=%v} to %entries
|
||||
%entries
|
||||
return %entries
|
||||
|
||||
rule [keys in %dict] =:
|
||||
%keys = []
|
||||
for %k = %v in %dict: add %k to %keys
|
||||
%keys
|
||||
return %keys
|
||||
|
||||
rule [values in %dict] =:
|
||||
%values = []
|
||||
for %k = %v in %dict: add %v to %values
|
||||
%values
|
||||
return %values
|
||||
|
||||
# List Comprehension
|
||||
compile [%expression for %item in %iterable] to:
|
||||
assert ((%item's "type") == "Var") ".."
|
||||
List comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
|
||||
".."
|
||||
return ".."
|
||||
(function(nomsu, vars);
|
||||
local comprehension = {};
|
||||
for i,item in ipairs(\(%iterable as lua)) do;
|
||||
@ -120,7 +120,7 @@ compile [%expression for %key = %value in %iterable] to:
|
||||
List comprehension has the wrong type for the key loop variable. Expected Var, but got: \(%key's "type")
|
||||
assert ((%value's "type") == "Var") ".."
|
||||
List comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%value's "type")
|
||||
".."
|
||||
return ".."
|
||||
(function(nomsu, vars);
|
||||
local comprehension = {};
|
||||
for key,value in pairs(\(%iterable as lua)) do;
|
||||
@ -133,11 +133,11 @@ compile [%expression for %key = %value in %iterable] to:
|
||||
rule [%items sorted] =:
|
||||
%copy = (% for all %items)
|
||||
sort %copy
|
||||
%copy
|
||||
return %copy
|
||||
rule [%items sorted by %key] =:
|
||||
%copy = (% for all %items)
|
||||
sort %copy by %key
|
||||
%copy
|
||||
return %copy
|
||||
rule [unique %items] =:
|
||||
keys in (dict ([%,yes] for all %items))
|
||||
|
||||
@ -165,7 +165,7 @@ rule [chain %dict to %fallback] =:
|
||||
compile [%key = %value for %item in %iterable] to:
|
||||
assert ((%item's "type") == "Var") ".."
|
||||
Dict comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
|
||||
".."
|
||||
return ".."
|
||||
(function(nomsu, vars);
|
||||
local comprehension = {};
|
||||
for i,value in ipairs(\(%iterable as lua)) do;
|
||||
@ -181,7 +181,7 @@ compile [%key = %value for %src_key = %src_value in %iterable] to:
|
||||
Dict comprehension has the wrong type for the key loop variable. Expected Var, but got: \(%src_key's "type")
|
||||
assert ((%src_value's "type") == "Var") ".."
|
||||
Dict comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%src_value's "type")
|
||||
".."
|
||||
return ".."
|
||||
(function(nomsu, vars);
|
||||
local comprehension = {};
|
||||
for key,value in pairs(\(%iterable as lua)) do;
|
||||
|
@ -210,7 +210,7 @@ compile [when %body] to code:
|
||||
|
||||
if (%result != ""):
|
||||
%result join= "\nend"
|
||||
%result
|
||||
return %result
|
||||
|
||||
# Switch statement
|
||||
compile [when %branch_value == ? %body] to code:
|
||||
@ -259,7 +259,7 @@ compile [when %branch_value == ? %body] to code:
|
||||
..\%result
|
||||
end
|
||||
end --when == ?
|
||||
%result
|
||||
return %result
|
||||
|
||||
# Try/except
|
||||
compile [..]
|
||||
|
@ -12,8 +12,8 @@ compile [phi, PHI, golden ratio] to: "((1+math.sqrt(5))/2)"
|
||||
compile [nop, pass] to code: ""
|
||||
|
||||
# Ternary operator
|
||||
#.. Note: this uses a function instead of (condition and if_expr or else_expr)
|
||||
because that breaks if %if_expr is falsey.
|
||||
#.. Note: this uses a function instead of "(condition and if_expr or else_expr)"
|
||||
because that breaks if %if_expr is falsey, e.g. "x < 5 and false or 99"
|
||||
compile [..]
|
||||
%when_true_expr if %condition else %when_false_expr
|
||||
%when_true_expr if %condition otherwise %when_false_expr
|
||||
@ -27,6 +27,17 @@ compile [..]
|
||||
return \(%when_false_expr as lua);
|
||||
end
|
||||
end)(nomsu, vars)
|
||||
parse [..]
|
||||
%true if %x == %y else %false, %true if %x == %y otherwise %false
|
||||
%false unless %x == %y else %true, %false unless %x == %y otherwise %true
|
||||
..as:
|
||||
%true if (%x == %y) else %false
|
||||
|
||||
parse [..]
|
||||
%true if %x != %y else %false, %true if %x != %y otherwise %false
|
||||
%false unless %x != %y else %true, %false unless %x != %y otherwise %true
|
||||
..as:
|
||||
%true if (%x != %y) else %false
|
||||
|
||||
# Indexing:
|
||||
compile [%obj'%key, %obj's %key, %obj -> %key] to: "(\(%obj as lua))[\(%key as lua)]"
|
||||
|
@ -6,16 +6,12 @@ require "lib/collections.nom"
|
||||
|
||||
|
||||
compile [say %str] to:
|
||||
if ((%str's "type") == "String"):
|
||||
"nomsu:writeln(\(%str as lua))"
|
||||
..else:
|
||||
"nomsu:writeln(nomsu:stringify(\(%str as lua)))"
|
||||
"nomsu:writeln(\(%str as lua))" if ((%str's "type") == "String")
|
||||
..else "nomsu:writeln(nomsu:stringify(\(%str as lua)))"
|
||||
|
||||
compile [do %action] to code:
|
||||
if ((%action's "type") == "Thunk"):
|
||||
%action as lua statements
|
||||
..else:
|
||||
"(\(%action as lua))(nomsu, vars);"
|
||||
(%action as lua statements) if ((%action's "type") == "Thunk")
|
||||
..else "(\(%action as lua))(nomsu, vars);"
|
||||
|
||||
# With statement
|
||||
compile [with %assignments %action] to code:
|
||||
@ -33,7 +29,7 @@ compile [with %assignments %action] to code:
|
||||
"local old_value\(%->"i") = \((%->"var") as lua); \((%->"var") as lua) = \((%->"value") as lua);"
|
||||
..for all %data
|
||||
..with glue "\n "
|
||||
".."
|
||||
return ".."
|
||||
do
|
||||
\%setup
|
||||
local fell_through = false;
|
||||
@ -51,26 +47,17 @@ parse [with %thing = %value %action] as: with [%thing = %value] %action
|
||||
|
||||
# Any/all/none
|
||||
compile [all of %items, all %items] to:
|
||||
if (%items' "type") == "List":
|
||||
"(\(join ((% as lua) for all (%items' "value")) with glue " and "))"
|
||||
..else:
|
||||
"nomsu.utils.all(\(%items as lua))"
|
||||
"(\(join ((% as lua) for all (%items' "value")) with glue " and "))"
|
||||
..if (%items' "type") == "List" else "nomsu.utils.all(\(%items as lua))"
|
||||
parse [not all of %items, not all %items] as: not (all of %items)
|
||||
compile [any of %items, any %items] to:
|
||||
if (%items' "type") == "List":
|
||||
"(\(join ((% as lua) for all (%items' "value")) with glue " or "))"
|
||||
..else:
|
||||
"nomsu.utils.any(\(%items as lua))"
|
||||
"(\(join ((% as lua) for all (%items' "value")) with glue " or "))"
|
||||
..if (%items' "type") == "List" else "nomsu.utils.any(\(%items as lua))"
|
||||
parse [none of %items, none %items] as: not (any of %items)
|
||||
|
||||
|
||||
compile [sum of %items, sum %items] to:
|
||||
if (%items' "type") == "List":
|
||||
"(\(join ((% as lua) for all (%items' "value")) with glue " + "))"
|
||||
..else:
|
||||
"nomsu.utils.sum(\(%items as lua))"
|
||||
"(\(join ((% as lua) for all (%items' "value")) with glue " + "))"
|
||||
..if (%items' "type") == "List" else "nomsu.utils.sum(\(%items as lua))"
|
||||
compile [product of %items, product %items] to:
|
||||
if (%items' "type") == "List":
|
||||
"(\(join ((% as lua) for all (%items' "value")) with glue " * "))"
|
||||
..else:
|
||||
"nomsu.utils.product(\(%items as lua))"
|
||||
"(\(join ((% as lua) for all (%items' "value")) with glue " * "))"
|
||||
..if (%items' "type") == "List" else "nomsu.utils.product(\(%items as lua))"
|
||||
|
29
nomsu.lua
29
nomsu.lua
@ -528,7 +528,6 @@ do
|
||||
self:assert(tree, "Tree failed to compile: " .. tostring(src))
|
||||
self:assert(tree.type == "File", "Attempt to run non-file: " .. tostring(tree.type))
|
||||
local buffer = { }
|
||||
local return_value = nil
|
||||
local _list_0 = tree.value
|
||||
for _index_0 = 1, #_list_0 do
|
||||
local statement = _list_0[_index_0]
|
||||
@ -544,8 +543,7 @@ do
|
||||
end
|
||||
local code_for_statement = ([[return (function(nomsu, vars)
|
||||
%s
|
||||
return %s;
|
||||
end);]]):format(statements or "", expr or "ret")
|
||||
end);]]):format(statements or ("return " .. expr .. ";"))
|
||||
if output_file then
|
||||
if statements and #statements > 0 then
|
||||
output_file:write("lua> \"..\"\n " .. tostring(self:indent(statements:gsub("\\", "\\\\"))) .. "\n")
|
||||
@ -571,9 +569,6 @@ end);]]):format(statements or "", expr or "ret")
|
||||
local run_statement = lua_thunk()
|
||||
local ret
|
||||
ok, ret = pcall(run_statement, self, vars)
|
||||
if expr then
|
||||
return_value = ret
|
||||
end
|
||||
if not ok then
|
||||
self:errorln(tostring(colored.red("Error occurred in statement:")) .. "\n" .. tostring(colored.yellow(statement.src)))
|
||||
self:errorln(debug.traceback())
|
||||
@ -583,18 +578,16 @@ end);]]):format(statements or "", expr or "ret")
|
||||
insert(buffer, statements)
|
||||
end
|
||||
if expr then
|
||||
insert(buffer, "ret = " .. tostring(expr) .. ";")
|
||||
insert(buffer, tostring(expr) .. ";")
|
||||
end
|
||||
end
|
||||
if max_operations then
|
||||
debug.sethook()
|
||||
end
|
||||
local lua_code = ([[return (function(nomsu, vars)
|
||||
local ret;
|
||||
%s
|
||||
return ret;
|
||||
end);]]):format(concat(buffer, "\n"))
|
||||
return return_value, lua_code, vars
|
||||
return nil, lua_code, vars
|
||||
end,
|
||||
tree_to_value = function(self, tree, vars, filename)
|
||||
local code = "return (function(nomsu, vars)\nreturn " .. tostring(self:tree_to_lua(tree, filename)) .. ";\nend);"
|
||||
@ -817,7 +810,7 @@ end);]]):format(concat(buffer, "\n"))
|
||||
insert(lua_bits, statement)
|
||||
end
|
||||
if expr then
|
||||
insert(lua_bits, "ret = " .. tostring(expr) .. ";")
|
||||
insert(lua_bits, tostring(expr) .. ";")
|
||||
end
|
||||
end
|
||||
return nil, concat(lua_bits, "\n")
|
||||
@ -829,17 +822,20 @@ end);]]):format(concat(buffer, "\n"))
|
||||
for _index_0 = 1, #_list_0 do
|
||||
local arg = _list_0[_index_0]
|
||||
local expr, statement = self:tree_to_lua(arg, filename)
|
||||
if #tree.value == 1 and expr and not statement then
|
||||
return ([[(function(nomsu, vars)
|
||||
return %s;
|
||||
end)]]):format(expr)
|
||||
end
|
||||
if statement then
|
||||
insert(lua_bits, statement)
|
||||
end
|
||||
if expr then
|
||||
insert(lua_bits, "ret = " .. tostring(expr) .. ";")
|
||||
insert(lua_bits, tostring(expr) .. ";")
|
||||
end
|
||||
end
|
||||
return ([[(function(nomsu, vars)
|
||||
local ret;
|
||||
%s
|
||||
return ret;
|
||||
end)]]):format(concat(lua_bits, "\n"))
|
||||
elseif "FunctionCall" == _exp_0 then
|
||||
insert(self.compilestack, tree)
|
||||
@ -1441,7 +1437,7 @@ if arg then
|
||||
colors = require('consolecolors')
|
||||
local parser = re.compile([[ args <- {| {:flags: flags? :} ({:input: input :} ";" ("-o;"{:output: output :} ";")?)? (";")? |} !.
|
||||
flags <- (({| ({flag} ";")* |}) -> set)
|
||||
flag <- "-c" / "-i" / "-p" / "-O" / "--help" / "-h"
|
||||
flag <- "-c" / "-i" / "-p" / "-O" / "--help" / "-h" / "-v"
|
||||
input <- "-" / [^;]+
|
||||
output <- "-" / [^;]+
|
||||
]], {
|
||||
@ -1454,6 +1450,9 @@ if arg then
|
||||
os.exit()
|
||||
end
|
||||
local c = NomsuCompiler()
|
||||
if args.flags["-v"] then
|
||||
c.debug = true
|
||||
end
|
||||
c.skip_precompiled = not args.flags["-O"]
|
||||
if args.input then
|
||||
if args.flags["-c"] and not args.output then
|
||||
|
28
nomsu.moon
28
nomsu.moon
@ -342,7 +342,7 @@ class NomsuCompiler
|
||||
@assert tree.type == "File", "Attempt to run non-file: #{tree.type}"
|
||||
|
||||
buffer = {}
|
||||
return_value = nil
|
||||
-- TODO: handle return statements in a file
|
||||
for statement in *tree.value
|
||||
if @debug
|
||||
@writeln "#{colored.bright "RUNNING NOMSU:"}\n#{colored.bright colored.yellow statement.src}"
|
||||
@ -355,8 +355,7 @@ class NomsuCompiler
|
||||
code_for_statement = ([[
|
||||
return (function(nomsu, vars)
|
||||
%s
|
||||
return %s;
|
||||
end);]])\format(statements or "", expr or "ret")
|
||||
end);]])\format(statements or ("return "..expr..";"))
|
||||
if output_file
|
||||
if statements and #statements > 0
|
||||
output_file\write "lua> \"..\"\n #{@indent statements\gsub("\\","\\\\")}\n"
|
||||
@ -374,7 +373,6 @@ end);]])\format(statements or "", expr or "ret")
|
||||
error("Failed to compile generated code:\n#{colored.bright colored.blue colored.onblack code}\n\n#{err}\n\nProduced by statement:\n#{colored.bright colored.yellow statement.src}")
|
||||
run_statement = lua_thunk!
|
||||
ok,ret = pcall(run_statement, self, vars)
|
||||
if expr then return_value = ret
|
||||
if not ok
|
||||
@errorln "#{colored.red "Error occurred in statement:"}\n#{colored.yellow statement.src}"
|
||||
@errorln debug.traceback!
|
||||
@ -382,17 +380,15 @@ end);]])\format(statements or "", expr or "ret")
|
||||
if statements
|
||||
insert buffer, statements
|
||||
if expr
|
||||
insert buffer, "ret = #{expr};"
|
||||
insert buffer, "#{expr};"
|
||||
|
||||
if max_operations
|
||||
debug.sethook!
|
||||
lua_code = ([[
|
||||
return (function(nomsu, vars)
|
||||
local ret;
|
||||
%s
|
||||
return ret;
|
||||
end);]])\format(concat(buffer, "\n"))
|
||||
return return_value, lua_code, vars
|
||||
return nil, lua_code, vars
|
||||
|
||||
tree_to_value: (tree, vars, filename)=>
|
||||
code = "return (function(nomsu, vars)\nreturn #{@tree_to_lua(tree, filename)};\nend);"
|
||||
@ -546,7 +542,7 @@ end);]])\format(concat(buffer, "\n"))
|
||||
for line in *tree.value
|
||||
expr,statement = @tree_to_lua line, filename
|
||||
if statement then insert lua_bits, statement
|
||||
if expr then insert lua_bits, "ret = #{expr};"
|
||||
if expr then insert lua_bits, "#{expr};"
|
||||
return nil, concat(lua_bits, "\n")
|
||||
|
||||
when "Nomsu"
|
||||
@ -556,13 +552,16 @@ end);]])\format(concat(buffer, "\n"))
|
||||
lua_bits = {}
|
||||
for arg in *tree.value
|
||||
expr,statement = @tree_to_lua arg, filename
|
||||
if #tree.value == 1 and expr and not statement
|
||||
return ([[
|
||||
(function(nomsu, vars)
|
||||
return %s;
|
||||
end)]])\format(expr)
|
||||
if statement then insert lua_bits, statement
|
||||
if expr then insert lua_bits, "ret = #{expr};"
|
||||
if expr then insert lua_bits, "#{expr};"
|
||||
return ([[
|
||||
(function(nomsu, vars)
|
||||
local ret;
|
||||
%s
|
||||
return ret;
|
||||
end)]])\format(concat(lua_bits, "\n"))
|
||||
|
||||
when "FunctionCall"
|
||||
@ -889,7 +888,7 @@ if arg
|
||||
parser = re.compile([[
|
||||
args <- {| {:flags: flags? :} ({:input: input :} ";" ("-o;"{:output: output :} ";")?)? (";")? |} !.
|
||||
flags <- (({| ({flag} ";")* |}) -> set)
|
||||
flag <- "-c" / "-i" / "-p" / "-O" / "--help" / "-h"
|
||||
flag <- "-c" / "-i" / "-p" / "-O" / "--help" / "-h" / "-v"
|
||||
input <- "-" / [^;]+
|
||||
output <- "-" / [^;]+
|
||||
]], {:set})
|
||||
@ -901,6 +900,9 @@ if arg
|
||||
|
||||
c = NomsuCompiler()
|
||||
|
||||
if args.flags["-v"]
|
||||
c.debug = true
|
||||
|
||||
c.skip_precompiled = not args.flags["-O"]
|
||||
if args.input
|
||||
-- Read a file or stdin and output either the printouts or the compiled lua
|
||||
|
Loading…
Reference in New Issue
Block a user