Removed some dead code and streamlined the API a bit. Also added
training wheels for ease of transitions.
This commit is contained in:
parent
756c1f718e
commit
3fbc89273d
@ -21,7 +21,7 @@ parse [last in %list, last %list] as: 1 st to last in %list
|
|||||||
# Membership testing
|
# Membership testing
|
||||||
action [%item is in %list, %list contains %item, %list has %item]:
|
action [%item is in %list, %list contains %item, %list has %item]:
|
||||||
for %key = %value in %list:
|
for %key = %value in %list:
|
||||||
if (%key == %item): return (yes)
|
if (%key is %item): return (yes)
|
||||||
return (no)
|
return (no)
|
||||||
|
|
||||||
action [..]
|
action [..]
|
||||||
@ -30,7 +30,7 @@ action [..]
|
|||||||
%list doesn't have %item, %list does not have %item
|
%list doesn't have %item, %list does not have %item
|
||||||
..:
|
..:
|
||||||
for %key = %value in %list:
|
for %key = %value in %list:
|
||||||
if (%key == %item): return (no)
|
if (%key is %item): return (no)
|
||||||
return (yes)
|
return (yes)
|
||||||
|
|
||||||
compile [%list has key %index, %list has index %index] to: ".."
|
compile [%list has key %index, %list has index %index] to: ".."
|
||||||
@ -46,7 +46,7 @@ compile [length of %list, size of %list, size %list, number of %list, len %list]
|
|||||||
|
|
||||||
# Chained lookup
|
# Chained lookup
|
||||||
compile [%list ->* %indices] to:
|
compile [%list ->* %indices] to:
|
||||||
assert ((%indices's "type") == "List") ".."
|
assume ((%indices's "type") is "List") or barf ".."
|
||||||
Expected List for chained lookup, not \(%indices's "type")
|
Expected List for chained lookup, not \(%indices's "type")
|
||||||
set %ret = "\(%list as lua)"
|
set %ret = "\(%list as lua)"
|
||||||
for %index in (%indices's "value"):
|
for %index in (%indices's "value"):
|
||||||
@ -91,32 +91,62 @@ action [values in %dict]:
|
|||||||
[%v for %k=%v in %dict]
|
[%v for %k=%v in %dict]
|
||||||
|
|
||||||
# List Comprehension
|
# List Comprehension
|
||||||
compile [%expression for %item in %iterable] to:
|
immediately:
|
||||||
assert ((%item's "type") == "Var") ".."
|
compile [%expression for %item in %iterable] to:
|
||||||
List comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
|
assume ((%item's "type") is "Var") or barf ".."
|
||||||
return ".."
|
List comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
|
||||||
(function(nomsu);
|
return ".."
|
||||||
local comprehension = {};
|
(function(nomsu);
|
||||||
for i,\(%item as lua) in ipairs(\(%iterable as lua)) do;
|
local comprehension = {};
|
||||||
comprehension[i] = \(%expression as lua);
|
for i,\(%item as lua) in ipairs(\(%iterable as lua)) do;
|
||||||
end;
|
comprehension[i] = \(%expression as lua);
|
||||||
return comprehension;
|
end;
|
||||||
end)(nomsu)
|
return comprehension;
|
||||||
parse [%expression for all %iterable] as: %expression for % in %iterable
|
end)(nomsu)
|
||||||
|
parse [%expression for all %iterable] as: %expression for % in %iterable
|
||||||
|
|
||||||
compile [%expression for %key = %value in %iterable] to:
|
compile [%expression for %key = %value in %iterable] to:
|
||||||
assert ((%key's "type") == "Var") ".."
|
assume ((%key's "type") is "Var") or barf ".."
|
||||||
List comprehension has the wrong type for the key loop variable. Expected Var, but got: \(%key's "type")
|
List comprehension has the wrong type for the key loop variable. Expected Var, but got: \(%key's "type")
|
||||||
assert ((%value's "type") == "Var") ".."
|
assume ((%value's "type") is "Var") or barf ".."
|
||||||
List comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%value's "type")
|
List comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%value's "type")
|
||||||
return ".."
|
return ".."
|
||||||
(function(nomsu);
|
(function(nomsu);
|
||||||
local comprehension = {};
|
local comprehension = {};
|
||||||
for \(%key as lua), \(%value as lua) in pairs(\(%iterable as lua)) do;
|
for \(%key as lua), \(%value as lua) in pairs(\(%iterable as lua)) do;
|
||||||
comprehension[i] = \(%expression as lua);
|
comprehension[i] = \(%expression as lua);
|
||||||
end;
|
end;
|
||||||
return comprehension;
|
return comprehension;
|
||||||
end)(nomsu)
|
end)(nomsu)
|
||||||
|
|
||||||
|
# Dict comprehensions
|
||||||
|
immediately:
|
||||||
|
compile [%key = %value for %item in %iterable] to:
|
||||||
|
assume ((%item's "type") is "Var") or barf ".."
|
||||||
|
Dict comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
|
||||||
|
return ".."
|
||||||
|
(function(nomsu);
|
||||||
|
local comprehension = {};
|
||||||
|
for i,\(%item as lua) in ipairs(\(%iterable as lua)) do;
|
||||||
|
comprehension[\(%key as lua)] = \(%value as lua);
|
||||||
|
end;
|
||||||
|
return comprehension;
|
||||||
|
end)(nomsu)
|
||||||
|
parse [%key = %value for all %iterable] as: %key = %value for % in %iterable
|
||||||
|
|
||||||
|
compile [%key = %value for %src_key = %src_value in %iterable] to:
|
||||||
|
assume ((%src_key's "type") is "Var") or barf ".."
|
||||||
|
Dict comprehension has the wrong type for the key loop variable. Expected Var, but got: \(%src_key's "type")
|
||||||
|
assume ((%src_value's "type") is "Var") or barf ".."
|
||||||
|
Dict comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%src_value's "type")
|
||||||
|
return ".."
|
||||||
|
(function(nomsu);
|
||||||
|
local comprehension = {};
|
||||||
|
for \(%src_key as lua), \(%src_value as lua) in pairs(\(%iterable as lua)) do;
|
||||||
|
comprehension[\(%key as lua)] = \(%value as lua);
|
||||||
|
end;
|
||||||
|
return comprehension;
|
||||||
|
end)(nomsu)
|
||||||
|
|
||||||
action [%items sorted]:
|
action [%items sorted]:
|
||||||
%copy = (% for all %items)
|
%copy = (% for all %items)
|
||||||
@ -127,7 +157,7 @@ action [%items sorted by %key]:
|
|||||||
sort %copy by %key
|
sort %copy by %key
|
||||||
return %copy
|
return %copy
|
||||||
action [unique %items]:
|
action [unique %items]:
|
||||||
keys in (dict ([%,yes] for all %items))
|
[%k for %k=%v in {%=(yes) for all %items}]
|
||||||
|
|
||||||
# Metatable stuff
|
# Metatable stuff
|
||||||
compile [counter] to: "setmetatable({}, {__index=function() return 0; end})"
|
compile [counter] to: "setmetatable({}, {__index=function() return 0; end})"
|
||||||
@ -138,7 +168,7 @@ compile [default dict] to: ".."
|
|||||||
return t;
|
return t;
|
||||||
end})"
|
end})"
|
||||||
action [chain %dict to %fallback]:
|
action [chain %dict to %fallback]:
|
||||||
when (type of %fallback) == ?:
|
when (type of %fallback) is ?:
|
||||||
* "table":
|
* "table":
|
||||||
=lua "setmetatable(\%dict, \%fallback)"
|
=lua "setmetatable(\%dict, \%fallback)"
|
||||||
* "function":
|
* "function":
|
||||||
@ -149,31 +179,3 @@ action [chain %dict to %fallback]:
|
|||||||
|
|
||||||
# TODO: maybe make a generator/coroutine?
|
# TODO: maybe make a generator/coroutine?
|
||||||
|
|
||||||
# Dict comprehensions
|
|
||||||
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);
|
|
||||||
local comprehension = {};
|
|
||||||
for i,\(%item as lua) in ipairs(\(%iterable as lua)) do;
|
|
||||||
comprehension[\(%key as lua)] = \(%value as lua);
|
|
||||||
end;
|
|
||||||
return comprehension;
|
|
||||||
end)(nomsu)
|
|
||||||
parse [%key = %value for all %iterable] as: %key = %value for % in %iterable
|
|
||||||
|
|
||||||
compile [%key = %value for %src_key = %src_value in %iterable] to:
|
|
||||||
assert ((%src_key's "type") == "Var") ".."
|
|
||||||
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);
|
|
||||||
local comprehension = {};
|
|
||||||
for \(%src_key as lua), \(%src_value as lua) in pairs(\(%iterable as lua)) do;
|
|
||||||
comprehension[\(%key as lua)] = \(%value as lua);
|
|
||||||
end;
|
|
||||||
return comprehension;
|
|
||||||
end)(nomsu)
|
|
||||||
|
|
||||||
|
@ -9,10 +9,6 @@ immediately:
|
|||||||
\(%if_body as lua statements)
|
\(%if_body as lua statements)
|
||||||
end --end if
|
end --end if
|
||||||
parse [unless %condition %unless_body] as: if (not %condition) %unless_body
|
parse [unless %condition %unless_body] as: if (not %condition) %unless_body
|
||||||
parse [if %x == %y %if_body] as: if (%x == %y) %if_body
|
|
||||||
parse [if %x != %y %if_body] as: if (%x != %y) %if_body
|
|
||||||
parse [unless %x == %y %if_body] as: if (%x != %y) %if_body
|
|
||||||
parse [unless %x != %y %if_body] as: if (%x == %y) %if_body
|
|
||||||
|
|
||||||
compile [if %condition %if_body else %else_body, unless %condition %else_body else %if_body] to code: ".."
|
compile [if %condition %if_body else %else_body, unless %condition %else_body else %if_body] to code: ".."
|
||||||
if \(%condition as lua) then
|
if \(%condition as lua) then
|
||||||
@ -20,10 +16,6 @@ immediately:
|
|||||||
else
|
else
|
||||||
\(%else_body as lua statements)
|
\(%else_body as lua statements)
|
||||||
end --end if
|
end --end if
|
||||||
parse [if %x == %y %if_body else %else_body] as: if (%x == %y) %if_body else %else_body
|
|
||||||
parse [if %x != %y %if_body else %else_body] as: if (%x != %y) %if_body else %else_body
|
|
||||||
parse [unless %x == %y %if_body else %else_body] as: if (%x != %y) %if_body else %else_body
|
|
||||||
parse [unless %x != %y %if_body else %else_body] as: if (%x == %y) %if_body else %else_body
|
|
||||||
|
|
||||||
# Return
|
# Return
|
||||||
immediately:
|
immediately:
|
||||||
@ -37,6 +29,11 @@ immediately:
|
|||||||
compile [go to %label] to code: ".."
|
compile [go to %label] to code: ".."
|
||||||
goto label_\(nomsu "var_to_lua_identifier" [%label]);
|
goto label_\(nomsu "var_to_lua_identifier" [%label]);
|
||||||
|
|
||||||
|
# Basic loop control
|
||||||
|
immediately:
|
||||||
|
compile [do next] to code: "continue;"
|
||||||
|
compile [stop] to code: "break;"
|
||||||
|
|
||||||
# Helper function
|
# Helper function
|
||||||
immediately:
|
immediately:
|
||||||
action [tree %tree has function call %call]:
|
action [tree %tree has function call %call]:
|
||||||
@ -71,10 +68,6 @@ immediately:
|
|||||||
return %code
|
return %code
|
||||||
parse [repeat %body] as: repeat while (true) %body
|
parse [repeat %body] as: repeat while (true) %body
|
||||||
parse [repeat until %condition %body] as: repeat while (not %condition) %body
|
parse [repeat until %condition %body] as: repeat while (not %condition) %body
|
||||||
parse [repeat while %x == %y %body] as: repeat while (%x == %y) %body
|
|
||||||
parse [repeat while %x != %y %body] as: repeat while (%x != %y) %body
|
|
||||||
parse [repeat until %x == %y %body] as: repeat while (%x != %y) %body
|
|
||||||
parse [repeat until %x != %y %body] as: repeat while (%x == %y) %body
|
|
||||||
|
|
||||||
# For loop control flow:
|
# For loop control flow:
|
||||||
immediately:
|
immediately:
|
||||||
@ -115,7 +108,7 @@ immediately:
|
|||||||
\%code\
|
\%code\
|
||||||
..\%stop_labels
|
..\%stop_labels
|
||||||
end --for-loop label scope
|
end --for-loop label scope
|
||||||
..if %stop_labels != "" else %code
|
..if (%stop_labels is not "") else %code
|
||||||
|
|
||||||
immediately:
|
immediately:
|
||||||
parse [for %var from %start to %stop %body] as: for %var from %start to %stop via 1 %body
|
parse [for %var from %start to %stop %body] as: for %var from %start to %stop via 1 %body
|
||||||
@ -145,7 +138,7 @@ immediately:
|
|||||||
%stop_labels join= "\n::stop_for::;"
|
%stop_labels join= "\n::stop_for::;"
|
||||||
if (tree %body has function call (tree \(stop %) with {""=%var})):
|
if (tree %body has function call (tree \(stop %) with {""=%var})):
|
||||||
%stop_labels join= "\n::stop_\(nomsu "var_to_lua_identifier" [%var])::;"
|
%stop_labels join= "\n::stop_\(nomsu "var_to_lua_identifier" [%var])::;"
|
||||||
if %stop_labels != "":
|
if (%stop_labels is not ""):
|
||||||
set %code = ".."
|
set %code = ".."
|
||||||
do --for-loop label scope
|
do --for-loop label scope
|
||||||
\%code\%stop_labels
|
\%code\%stop_labels
|
||||||
@ -153,6 +146,31 @@ immediately:
|
|||||||
return %code
|
return %code
|
||||||
parse [for all %iterable %body] as: for % in %iterable %body
|
parse [for all %iterable %body] as: for % in %iterable %body
|
||||||
|
|
||||||
|
immediately:
|
||||||
|
compile [..]
|
||||||
|
repeat %n times %body, repeat %n x %body
|
||||||
|
..to code:
|
||||||
|
lua> "local \%continue_labels, \%code, \%stop_labels"
|
||||||
|
set %continue_labels = ""
|
||||||
|
if (tree %body has function call \(do next repeat-loop)):
|
||||||
|
%continue_labels join= "\n::continue_repeat::;"
|
||||||
|
# This trashes the loop variables, just like in Python.
|
||||||
|
set %code = ".."
|
||||||
|
for i=1,\(%n as lua) do
|
||||||
|
\(%body as lua statements)\
|
||||||
|
..\%continue_labels
|
||||||
|
end --numeric for-loop
|
||||||
|
set %stop_labels = ""
|
||||||
|
if (tree %body has function call \(stop repeat-loop)):
|
||||||
|
%stop_labels join= "\n::stop_repeat::;"
|
||||||
|
return (..)
|
||||||
|
".."
|
||||||
|
do --repeat-loop label scope
|
||||||
|
\%code\
|
||||||
|
..\%stop_labels
|
||||||
|
end --repeat-loop label scope
|
||||||
|
..if (%stop_labels is not "") else %code
|
||||||
|
|
||||||
# Dict iteration (lua's "pairs()")
|
# Dict iteration (lua's "pairs()")
|
||||||
immediately:
|
immediately:
|
||||||
compile [for %key = %value in %iterable %body] to code:
|
compile [for %key = %value in %iterable %body] to code:
|
||||||
@ -183,7 +201,7 @@ immediately:
|
|||||||
\%code\
|
\%code\
|
||||||
..\%stop_labels
|
..\%stop_labels
|
||||||
end --for-loop label scope
|
end --for-loop label scope
|
||||||
..if %stop_labels != "" else %code
|
..if (%stop_labels is not "") else %code
|
||||||
|
|
||||||
# Switch statement/multi-branch if
|
# Switch statement/multi-branch if
|
||||||
immediately:
|
immediately:
|
||||||
@ -194,19 +212,19 @@ immediately:
|
|||||||
set %first = (yes)
|
set %first = (yes)
|
||||||
for %func_call in (%body's "value"):
|
for %func_call in (%body's "value"):
|
||||||
lua> "local \%tokens, \%star, \%condition, \%action"
|
lua> "local \%tokens, \%star, \%condition, \%action"
|
||||||
assert ((%func_call's "type") == "FunctionCall") ".."
|
assume ((%func_call's "type") == "FunctionCall") or barf ".."
|
||||||
Invalid format for 'when' statement. Only '*' blocks are allowed.
|
Invalid format for 'when' statement. Only '*' blocks are allowed.
|
||||||
set %tokens = (%func_call's "value")
|
set %tokens = (%func_call's "value")
|
||||||
set %star = (%tokens -> 1)
|
set %star = (%tokens -> 1)
|
||||||
assert (=lua "\%star and \%star.type == 'Word' and \%star.value == '*'") ".."
|
assume (=lua "\%star and \%star.type == 'Word' and \%star.value == '*'") or barf ".."
|
||||||
Invalid format for 'when' statement. Lines must begin with '*'
|
Invalid format for 'when' statement. Lines must begin with '*'
|
||||||
|
|
||||||
set %condition = (%tokens -> 2)
|
set %condition = (%tokens -> 2)
|
||||||
assert %condition ".."
|
assume %condition or barf ".."
|
||||||
Invalid format for 'when' statement. Lines must begin with '*' and have a condition or the word "else"
|
Invalid format for 'when' statement. Lines must begin with '*' and have a condition or the word "else"
|
||||||
|
|
||||||
set %action = (%tokens -> 3)
|
set %action = (%tokens -> 3)
|
||||||
if (%action == (nil)):
|
if (%action is (nil)):
|
||||||
lua do> "table.insert(\%fallthroughs, \%condition)"
|
lua do> "table.insert(\%fallthroughs, \%condition)"
|
||||||
do next %func_call
|
do next %func_call
|
||||||
|
|
||||||
@ -234,24 +252,24 @@ immediately:
|
|||||||
|
|
||||||
# Switch statement
|
# Switch statement
|
||||||
immediately:
|
immediately:
|
||||||
compile [when %branch_value == ? %body] to code:
|
compile [when %branch_value = ? %body, when %branch_value is ? %body] to code:
|
||||||
set %result = ""
|
set %result = ""
|
||||||
set %fallthroughs = []
|
set %fallthroughs = []
|
||||||
set %first = (yes)
|
set %first = (yes)
|
||||||
for %func_call in (%body's "value"):
|
for %func_call in (%body's "value"):
|
||||||
assert ((%func_call's "type") == "FunctionCall") ".."
|
assume ((%func_call's "type") is "FunctionCall") or barf ".."
|
||||||
Invalid format for 'when' statement. Only '*' blocks are allowed.
|
Invalid format for 'when' statement. Only '*' blocks are allowed.
|
||||||
set %tokens = (%func_call's "value")
|
set %tokens = (%func_call's "value")
|
||||||
set %star = (%tokens -> 1)
|
set %star = (%tokens -> 1)
|
||||||
assert (=lua "\%star and \%star.type == 'Word' and \%star.value == '*'") ".."
|
assume (=lua "\%star and \%star.type == 'Word' and \%star.value == '*'") or barf ".."
|
||||||
Invalid format for 'when' statement. Lines must begin with '*'
|
Invalid format for 'when' statement. Lines must begin with '*'
|
||||||
|
|
||||||
set %condition = (%tokens -> 2)
|
set %condition = (%tokens -> 2)
|
||||||
assert %condition ".."
|
assume %condition or barf ".."
|
||||||
Invalid format for 'when' statement. Lines must begin with '*' and have a condition or the word "else"
|
Invalid format for 'when' statement. Lines must begin with '*' and have a condition or the word "else"
|
||||||
|
|
||||||
set %action = (%tokens -> 3)
|
set %action = (%tokens -> 3)
|
||||||
if (%action == (nil)):
|
if (%action is (nil)):
|
||||||
lua> "table.insert(\%fallthroughs, \%condition)"
|
lua> "table.insert(\%fallthroughs, \%condition)"
|
||||||
do next %func_call
|
do next %func_call
|
||||||
|
|
||||||
@ -275,11 +293,11 @@ immediately:
|
|||||||
|
|
||||||
if (%result != ""):
|
if (%result != ""):
|
||||||
set %result = ".."
|
set %result = ".."
|
||||||
do --when == ?
|
do --when % = ?
|
||||||
local branch_value = \(%branch_value as lua);\
|
local branch_value = \(%branch_value as lua);\
|
||||||
..\%result
|
..\%result
|
||||||
end
|
end
|
||||||
end --when == ?
|
end --when % = ?
|
||||||
return %result
|
return %result
|
||||||
|
|
||||||
# Try/except
|
# Try/except
|
||||||
@ -304,13 +322,13 @@ immediately:
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
parse [try %action] as:
|
parse [try %action] as:
|
||||||
try %action and if it succeeds: pass
|
try %action and if it succeeds: do nothing
|
||||||
..or if it fails: pass
|
..or if it fails: do nothing
|
||||||
parse [try %action and if it fails %fallback] as:
|
parse [try %action and if it fails %fallback] as:
|
||||||
try %action and if it succeeds: pass
|
try %action and if it succeeds: do nothing
|
||||||
..or if it fails %fallback
|
..or if it fails %fallback
|
||||||
parse [try %action and if it succeeds %success] as:
|
parse [try %action and if it succeeds %success] as:
|
||||||
try %action and if it succeeds %success or if it fails: pass
|
try %action and if it succeeds %success or if it fails: do nothing
|
||||||
|
|
||||||
# Do/finally:
|
# Do/finally:
|
||||||
immediately:
|
immediately:
|
||||||
|
@ -4,5 +4,4 @@ use "lib/operators.nom"
|
|||||||
use "lib/control_flow.nom"
|
use "lib/control_flow.nom"
|
||||||
use "lib/collections.nom"
|
use "lib/collections.nom"
|
||||||
use "lib/utils2.nom"
|
use "lib/utils2.nom"
|
||||||
use "lib/scopes.nom"
|
|
||||||
lua> "nomsu.core_defs = nomsu.__class.def_number;"
|
lua> "nomsu.core_defs = nomsu.__class.def_number;"
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
use "lib/metaprogramming.nom"
|
|
||||||
|
|
||||||
# Moonscript!
|
|
||||||
parse [moonscript do> %moonscript_code] as:
|
|
||||||
lua do> ".."
|
|
||||||
|local parse, compile = require('moonscript.parse'), require('moonscript.compile');
|
|
||||||
|local moon_code = nomsu:tree_to_value(vars.moonscript_code, vars);
|
|
||||||
|local tree, err = parse.string(moon_code);
|
|
||||||
|if not tree then
|
|
||||||
| nomsu:error("Failed to parse moonscript: "..err);
|
|
||||||
|end
|
|
||||||
|local lua_code, err, pos = compile.tree(tree);
|
|
||||||
|if not lua_code then
|
|
||||||
| nomsu:error(compile.format_error(err, pos, moon_code));
|
|
||||||
|end
|
|
||||||
|return "do\\n"..lua_code.."\\nend";
|
|
||||||
|
|
||||||
parse [moonscript> %moonscript_code] as:
|
|
||||||
lua do> ".."
|
|
||||||
|local parse, compile = require('moonscript.parse'), require('moonscript.compile');
|
|
||||||
|local moon_code = nomsu:tree_to_value(vars.moonscript_code, vars);
|
|
||||||
|local tree, err = parse.string(moon_code);
|
|
||||||
|if not tree then
|
|
||||||
| nomsu:error("Failed to parse moonscript: "..err);
|
|
||||||
|end
|
|
||||||
|local lua_code, err, pos = compile.tree(tree);
|
|
||||||
|if not lua_code then
|
|
||||||
| nomsu:error(compile.format_error(err, pos, moon_code));
|
|
||||||
|end
|
|
||||||
|return "(function(nomsu, vars)\\n"..lua_code.."\\nend)(nomsu, vars)";
|
|
@ -1,15 +1,15 @@
|
|||||||
use "lib/metaprogramming.nom"
|
use "lib/metaprogramming.nom"
|
||||||
|
|
||||||
# Literals
|
# Literals
|
||||||
compile [true, yes] to: "true"
|
compile [yes] to: "true"
|
||||||
compile [false, no] to: "false"
|
compile [no] to: "false"
|
||||||
compile [nil, null] to: "nil"
|
compile [nil, null] to: "nil"
|
||||||
compile [inf, infinity] to: "math.huge"
|
compile [infinity, inf] to: "math.huge"
|
||||||
compile [nan, NaN, not a number] to: "(0/0)"
|
compile [not a number, NaN, nan] to: "(0/0)"
|
||||||
compile [pi, PI] to: "math.pi"
|
compile [pi, Pi, PI] to: "math.pi"
|
||||||
compile [tau, TAU] to: "(2*math.pi)"
|
compile [tau, Tau, TAU] to: "(2*math.pi)"
|
||||||
compile [phi, PHI, golden ratio] to: "((1+math.sqrt(5))/2)"
|
compile [phi, Phi, PHI, golden ratio] to: "((1+math.sqrt(5))/2)"
|
||||||
compile [nop, pass] to code: ""
|
compile [do nothing] to code: ""
|
||||||
|
|
||||||
# Ternary operator
|
# Ternary operator
|
||||||
#.. Note: this uses a function instead of "(condition and if_expr or else_expr)"
|
#.. Note: this uses a function instead of "(condition and if_expr or else_expr)"
|
||||||
@ -37,22 +37,12 @@ compile [..]
|
|||||||
end
|
end
|
||||||
end)(nomsu)]]):format(condition, when_true, when_false);
|
end)(nomsu)]]):format(condition, when_true, when_false);
|
||||||
end
|
end
|
||||||
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:
|
# Indexing:
|
||||||
compile [%obj'%key, %obj's %key, %obj -> %key] to: "(\(%obj as lua))[\(%key as lua)]"
|
compile [%obj'%key, %obj's %key, %obj -> %key] to: "(\(%obj as lua))[\(%key as lua)]"
|
||||||
|
|
||||||
# Substring
|
# Substring
|
||||||
|
# TODO: improve this syntax
|
||||||
compile [%str |%start|] to: "\(%str as lua):sub(\(%start as lua), \(%start as lua))"
|
compile [%str |%start|] to: "\(%str as lua):sub(\(%start as lua), \(%start as lua))"
|
||||||
compile [%str |%start - %stop|] to: "\(%str as lua):sub(\(%start as lua), \(%stop as lua))"
|
compile [%str |%start - %stop|] to: "\(%str as lua):sub(\(%start as lua), \(%stop as lua))"
|
||||||
|
|
||||||
@ -91,7 +81,6 @@ compile [%x < %y] to: "(\(%x as lua) < \(%y as lua))"
|
|||||||
compile [%x > %y] to: "(\(%x as lua) > \(%y as lua))"
|
compile [%x > %y] to: "(\(%x as lua) > \(%y as lua))"
|
||||||
compile [%x <= %y] to: "(\(%x as lua) <= \(%y as lua))"
|
compile [%x <= %y] to: "(\(%x as lua) <= \(%y as lua))"
|
||||||
compile [%x >= %y] to: "(\(%x as lua) >= \(%y as lua))"
|
compile [%x >= %y] to: "(\(%x as lua) >= \(%y as lua))"
|
||||||
# == and != do equivalence checking, rather than identity checking
|
|
||||||
compile [%a is %b, %a = %b, %a == %b] to:
|
compile [%a is %b, %a = %b, %a == %b] to:
|
||||||
lua> ".."
|
lua> ".."
|
||||||
local safe = {Text=true, Number=true};
|
local safe = {Text=true, Number=true};
|
||||||
@ -101,7 +90,7 @@ compile [%a is %b, %a = %b, %a == %b] to:
|
|||||||
else
|
else
|
||||||
return "nomsu.utils.equivalent("..a_lua..", "..b_lua..")";
|
return "nomsu.utils.equivalent("..a_lua..", "..b_lua..")";
|
||||||
end
|
end
|
||||||
compile [%a isn't %b, %a is not %b, %a != %b] to:
|
compile [%a isn't %b, %a is not %b, %a not= %b, %a != %b] to:
|
||||||
lua> ".."
|
lua> ".."
|
||||||
local safe = {Text=true, Number=true};
|
local safe = {Text=true, Number=true};
|
||||||
local a_lua, b_lua = nomsu:tree_to_lua(\%a).expr, nomsu:tree_to_lua(\%b).expr;
|
local a_lua, b_lua = nomsu:tree_to_lua(\%a).expr, nomsu:tree_to_lua(\%b).expr;
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
use "lib/metaprogramming.nom"
|
|
||||||
use "lib/control_flow.nom"
|
|
||||||
use "lib/operators.nom"
|
|
||||||
use "lib/collections.nom"
|
|
||||||
|
|
||||||
action [called by %whitelist]:
|
|
||||||
if ((%whitelist's "type") != "List"): %whitelist = [%whitelist]
|
|
||||||
%defs = (..)
|
|
||||||
dict ([(nomsu's "defs")->(nomsu "get_stub" [%]), yes] for all %whitelist)
|
|
||||||
for %caller in (nomsu's "callstack"):
|
|
||||||
if (%caller == "#macro"): do next %caller
|
|
||||||
if (%defs -> (nomsu "get_stub" [%caller's 1])): return (yes)
|
|
||||||
return (no)
|
|
||||||
|
|
||||||
parse [fail unless called by %whitelist] as:
|
|
||||||
unless (called by %whitelist): error "Failed to find \(%whitelist) in callstack."
|
|
||||||
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
use "lib/core.nom"
|
|
||||||
|
|
||||||
# Plurals
|
|
||||||
using:
|
|
||||||
<%endings> = (chain {x="es",c="es",s="es"} to "s")
|
|
||||||
<%plurals> = (chain {} to (: "\%\((<%endings>)->(%| -1|))"))
|
|
||||||
<%singulars> = (..)
|
|
||||||
chain {} to:
|
|
||||||
when:
|
|
||||||
* (((%| -2|) == "es") and (=lua"rawget(\(<%endings>), \(%| -3|))")):
|
|
||||||
%|1 - -3|
|
|
||||||
* (%| -1| == "s"):
|
|
||||||
%|1 - -2|
|
|
||||||
else: %
|
|
||||||
..do:
|
|
||||||
rule [the plural of %singular is %plural] =:
|
|
||||||
(<%plurals>)->%singular = %plural
|
|
||||||
(<%singulars>)->%plural = %singular
|
|
||||||
|
|
||||||
rule [singular %plural] =:
|
|
||||||
(<%singulars>)->%plural
|
|
||||||
|
|
||||||
rule [plural %singular] =:
|
|
||||||
(<%plurals>)->%singular
|
|
@ -1,46 +0,0 @@
|
|||||||
use "lib/metaprogramming.nom"
|
|
||||||
use "lib/operators.nom"
|
|
||||||
use "lib/control_flow.nom"
|
|
||||||
use "lib/collections.nom"
|
|
||||||
|
|
||||||
compile [<%var> = %value] to code: ".."
|
|
||||||
nomsu.defs['#vars'][\(repr (%var's "value"))] = \(%value as lua);
|
|
||||||
|
|
||||||
compile [<%var>] to: "nomsu.defs['#vars'][\(repr (%var's "value"))]"
|
|
||||||
|
|
||||||
compile [str %] to: "tostring(\(% as lua))"
|
|
||||||
|
|
||||||
compile [scope] to: "nomsu.defs"
|
|
||||||
compile [parent scope] to: "getmetatable(nomsu.defs).__index"
|
|
||||||
|
|
||||||
# TODO: fix this file
|
|
||||||
return
|
|
||||||
compile [using %scoped do %actions] to code: ".."
|
|
||||||
do
|
|
||||||
local old_scope, old_vars = nomsu.defs, vars;
|
|
||||||
local use_vars = setmetatable({}, {__index=old_scope['#vars']});
|
|
||||||
local scope = setmetatable({['#vars']=use_vars}, {__index=old_scope});
|
|
||||||
nomsu.defs = scope;
|
|
||||||
local ok, ret = pcall(function(nomsu, vars)
|
|
||||||
local ret;
|
|
||||||
do
|
|
||||||
\(%scoped as lua statements)
|
|
||||||
end
|
|
||||||
getmetatable(scope).__newindex = old_scope;
|
|
||||||
getmetatable(use_vars).__newindex = old_vars;
|
|
||||||
do
|
|
||||||
\(%actions as lua statements)
|
|
||||||
end
|
|
||||||
return ret;
|
|
||||||
end, nomsu, use_vars);
|
|
||||||
nomsu.defs = old_scope;
|
|
||||||
if not ok then nomsu:error(ret); end
|
|
||||||
end
|
|
||||||
|
|
||||||
parse [scoped %actions] as: using %actions do (:pass)
|
|
||||||
|
|
||||||
parse [wrap %signature with %body] as:
|
|
||||||
using:
|
|
||||||
run ((nomsu)->*["defs",nomsu "get_stub" [\%signature->*["value",1]],"src"])
|
|
||||||
..do:
|
|
||||||
rule %signature = %body
|
|
@ -1,13 +0,0 @@
|
|||||||
use "lib/metaprogramming.nom"
|
|
||||||
|
|
||||||
# For unit testing
|
|
||||||
rule [test tree %generated == %expected] =:
|
|
||||||
if (%generated != %expected):
|
|
||||||
error ".."
|
|
||||||
Test Failed!
|
|
||||||
Expected:
|
|
||||||
\(%expected)
|
|
||||||
But got:
|
|
||||||
\(%generated)
|
|
||||||
parse [test %code yields %expected] as:
|
|
||||||
test tree (nomsu "tree_to_str" [\%code]) == %expected
|
|
22
lib/training_wheels.nom
Normal file
22
lib/training_wheels.nom
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
use "lib/core.nom"
|
||||||
|
|
||||||
|
parse [%a == %b] as: %a is %b
|
||||||
|
parse [%a ~= %b, %a != %b, %a <> %b] as: %a is not %b
|
||||||
|
parse [%a === %b] as: (%a's id) is (%b's id)
|
||||||
|
parse [%a !== %b] as: (%a's id) is not (%b's id)
|
||||||
|
parse [%a mod %b] as: %a wrapped around %b
|
||||||
|
parse [function %names %body, def %names %body] as: action %names %body
|
||||||
|
parse [switch %branch_value %body] as: when %branch_value = ? %body
|
||||||
|
parse [None, Null] as: nil
|
||||||
|
parse [True, true] as: yes
|
||||||
|
parse [False, false] as: no
|
||||||
|
parse [pass] as: do nothing
|
||||||
|
parse [%a || %b] as: %a or %b
|
||||||
|
parse [%a && %b] as: %a and %b
|
||||||
|
parse [continue] as: do next
|
||||||
|
parse [break] as: stop
|
||||||
|
parse [let %thing = %value in %action] as: with %thing = %value %action
|
||||||
|
parse [let %assignments in %action] as: with %assignemnts %action
|
||||||
|
parse [error!, panic!, fail!, abort!] as: barf!
|
||||||
|
parse [error %, panic %, fail %, abort %] as: barf %
|
||||||
|
parse [assert %condition %message] as: assume %condition or barf %message
|
@ -1,16 +1,16 @@
|
|||||||
use "lib/metaprogramming.nom"
|
use "lib/metaprogramming.nom"
|
||||||
|
|
||||||
# Error functions
|
# Error functions
|
||||||
action [error!, panic!, fail!, abort!]:
|
action [barf!]:
|
||||||
nomsu "error" []
|
nomsu "error" []
|
||||||
action [error %msg]:
|
action [barf %msg]:
|
||||||
nomsu "error"[%msg]
|
nomsu "error"[%msg]
|
||||||
compile [assert %condition %msg] to code: ".."
|
compile [assume %condition or barf %msg] to code: ".."
|
||||||
if not (\(%condition as lua)) then
|
if not (\(%condition as lua)) then
|
||||||
nomsu:error(\(%msg as lua));
|
nomsu:error(\(%msg as lua));
|
||||||
end
|
end
|
||||||
|
|
||||||
parse [assert %condition] as: assert %condition (nil)
|
parse [assume %condition] as: assume %condition or barf (nil)
|
||||||
|
|
||||||
# Text functions
|
# Text functions
|
||||||
action [join %strs with glue %glue]:
|
action [join %strs with glue %glue]:
|
||||||
|
@ -6,11 +6,11 @@ use "lib/collections.nom"
|
|||||||
|
|
||||||
|
|
||||||
compile [say %str] to:
|
compile [say %str] to:
|
||||||
"nomsu:writeln(\(%str as lua))" if ((%str's "type") == "Text")
|
"nomsu:writeln(\(%str as lua))" if ((%str's "type") is "Text")
|
||||||
..else "nomsu:writeln(nomsu:stringify(\(%str as lua)))"
|
..else "nomsu:writeln(nomsu:stringify(\(%str as lua)))"
|
||||||
|
|
||||||
compile [do %action] to code:
|
compile [do %action] to code:
|
||||||
(%action as lua statements) if ((%action's "type") == "Block")
|
(%action as lua statements) if ((%action's "type") is "Block")
|
||||||
..else "(\(%action as lua))(nomsu);"
|
..else "(\(%action as lua))(nomsu);"
|
||||||
|
|
||||||
# With statement
|
# With statement
|
||||||
@ -20,7 +20,7 @@ compile [with %assignments %action] to code:
|
|||||||
set %tokens = (%assignment's "value")
|
set %tokens = (%assignment's "value")
|
||||||
set %var = (%tokens -> 1)
|
set %var = (%tokens -> 1)
|
||||||
set %eq = (%tokens -> 2)
|
set %eq = (%tokens -> 2)
|
||||||
assert (=lua "\%eq and \%eq.type == 'Word' and \%eq.value == '='") ".."
|
assume (=lua "\%eq and \%eq.type == 'Word' and \%eq.value == '='") or barf ".."
|
||||||
Invalid format for 'with' statement. List entries must have the form %var = (value)
|
Invalid format for 'with' statement. List entries must have the form %var = (value)
|
||||||
set %value = (%tokens -> 3)
|
set %value = (%tokens -> 3)
|
||||||
add {i=%i, var=%var, value=%value} to %data
|
add {i=%i, var=%var, value=%value} to %data
|
||||||
@ -48,16 +48,16 @@ parse [with %thing = %value %action] as: with [%thing = %value] %action
|
|||||||
# Any/all/none
|
# Any/all/none
|
||||||
compile [all of %items, all %items] to:
|
compile [all of %items, all %items] to:
|
||||||
"(\(join ((% as lua) for all (%items' "value")) with glue " and "))"
|
"(\(join ((% as lua) for all (%items' "value")) with glue " and "))"
|
||||||
..if (%items' "type") == "List" else "nomsu.utils.all(\(%items as lua))"
|
..if ((%items' "type") is "List") else "nomsu.utils.all(\(%items as lua))"
|
||||||
parse [not all of %items, not all %items] as: not (all of %items)
|
parse [not all of %items, not all %items] as: not (all of %items)
|
||||||
compile [any of %items, any %items] to:
|
compile [any of %items, any %items] to:
|
||||||
"(\(join ((% as lua) for all (%items' "value")) with glue " or "))"
|
"(\(join ((% as lua) for all (%items' "value")) with glue " or "))"
|
||||||
..if (%items' "type") == "List" else "nomsu.utils.any(\(%items as lua))"
|
..if ((%items' "type") is "List") else "nomsu.utils.any(\(%items as lua))"
|
||||||
parse [none of %items, none %items] as: not (any of %items)
|
parse [none of %items, none %items] as: not (any of %items)
|
||||||
|
|
||||||
compile [sum of %items, sum %items] to:
|
compile [sum of %items, sum %items] to:
|
||||||
"(\(join ((% as lua) for all (%items' "value")) with glue " + "))"
|
"(\(join ((% as lua) for all (%items' "value")) with glue " + "))"
|
||||||
..if (%items' "type") == "List" else "nomsu.utils.sum(\(%items as lua))"
|
..if ((%items' "type") is "List") else "nomsu.utils.sum(\(%items as lua))"
|
||||||
compile [product of %items, product %items] to:
|
compile [product of %items, product %items] to:
|
||||||
"(\(join ((% as lua) for all (%items' "value")) with glue " * "))"
|
"(\(join ((% as lua) for all (%items' "value")) with glue " * "))"
|
||||||
..if (%items' "type") == "List" else "nomsu.utils.product(\(%items as lua))"
|
..if ((%items' "type") is "List") else "nomsu.utils.product(\(%items as lua))"
|
||||||
|
Loading…
Reference in New Issue
Block a user