aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code_obj.lua8
-rw-r--r--code_obj.moon8
-rw-r--r--core/control_flow.nom98
-rw-r--r--core/metaprogramming.nom49
-rw-r--r--core/operators.nom4
-rw-r--r--core/scopes.nom41
-rw-r--r--lib/object.nom176
-rw-r--r--nomsu.lua21
-rwxr-xr-xnomsu.moon23
-rw-r--r--nomsu_tree.lua74
-rw-r--r--nomsu_tree.moon20
-rw-r--r--tests/object.nom33
12 files changed, 249 insertions, 306 deletions
diff --git a/code_obj.lua b/code_obj.lua
index 848ed84..dcdd95a 100644
--- a/code_obj.lua
+++ b/code_obj.lua
@@ -22,17 +22,17 @@ Source = immutable({
return filename, start, stop
end,
from_string = function(self, str)
- local filename, start, stop = str:match("^(.-)%[(%d+):(%d+)%]$")
+ local filename, start, stop = str:match("^@(.-)%[(%d+):(%d+)%]$")
if not (filename) then
- filename, start = str:match("^(.-)%[(%d+)%]$")
+ filename, start = str:match("^@(.-)%[(%d+)%]$")
end
return Source(filename or str, tonumber(start or 1), tonumber(stop))
end,
__tostring = function(self)
if self.stop then
- return "\"" .. tostring(self.filename) .. "[" .. tostring(self.start) .. ":" .. tostring(self.stop) .. "]\""
+ return "@" .. tostring(self.filename) .. "[" .. tostring(self.start) .. ":" .. tostring(self.stop) .. "]"
else
- return "\"" .. tostring(self.filename) .. "[" .. tostring(self.start) .. "]\""
+ return "@" .. tostring(self.filename) .. "[" .. tostring(self.start) .. "]"
end
end,
__lt = function(self, other)
diff --git a/code_obj.moon b/code_obj.moon
index 665d0f1..8dfc0a1 100644
--- a/code_obj.moon
+++ b/code_obj.moon
@@ -12,15 +12,15 @@ Source = immutable {"filename","start","stop"}, {
if stop and start > stop+1 then error("Invalid range: #{start}, #{stop}")
return filename, start, stop
from_string: (str)=>
- filename,start,stop = str\match("^(.-)%[(%d+):(%d+)%]$")
+ filename,start,stop = str\match("^@(.-)%[(%d+):(%d+)%]$")
unless filename
- filename,start = str\match("^(.-)%[(%d+)%]$")
+ filename,start = str\match("^@(.-)%[(%d+)%]$")
return Source(filename or str, tonumber(start or 1), tonumber(stop))
__tostring: =>
if @stop
- "\"#{@filename}[#{@start}:#{@stop}]\""
+ "@#{@filename}[#{@start}:#{@stop}]"
else
- "\"#{@filename}[#{@start}]\""
+ "@#{@filename}[#{@start}]"
__lt: (other)=>
assert(@filename == other.filename, "Cannot compare sources from different files")
return if @start == other.start
diff --git a/core/control_flow.nom b/core/control_flow.nom
index e54f10a..9120356 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -51,23 +51,23 @@ immediately
Lua value ".."
(function()
if \(%condition as lua expr) then
- return \(%when_true_expr as lua expr);
+ return \(%when_true_expr as lua expr)
else
- return \(%when_false_expr as lua expr);
+ return \(%when_false_expr as lua expr)
end
end)()
# GOTOs
immediately
compile [=== %label ===, --- %label ---, *** %label ***] to
- Lua "::label_\(%label as lua identifier)::;"
+ Lua "::label_\(%label as lua identifier)::"
compile [go to %label] to
- Lua "goto label_\(%label as lua identifier);"
+ Lua "goto label_\(%label as lua identifier)"
# Basic loop control
immediately
- compile [do next] to: Lua "continue;"
- compile [stop] to: Lua "break;"
+ compile [do next] to: Lua "continue"
+ compile [stop] to: Lua "break"
# Helper function
immediately
@@ -84,25 +84,25 @@ immediately
# While loops
immediately
- compile [do next repeat] to: Lua "goto continue_repeat;"
- compile [stop repeating] to: Lua "goto stop_repeat;"
+ compile [do next repeat] to: Lua "goto continue_repeat"
+ compile [stop repeating] to: Lua "goto stop_repeat"
compile [repeat while %condition %body] to
%lua <-
Lua ".."
while \(%condition as lua expr) do
\(%body as lua statements)
if
- %body has subtree % where: (%.type = "Action") and ((%'s stub) is "do next repeat")
- ..: to %lua write "\n ::continue_repeat::;"
+ %body has subtree % where: (%.type = "Action") and (%.stub is "do next repeat")
+ ..: to %lua write "\n ::continue_repeat::"
to %lua write "\nend --while-loop"
if
- %body has subtree % where: (%.type = "Action") and ((%'s stub) is "stop repeating")
+ %body has subtree % where: (%.type = "Action") and (%.stub is "stop repeating")
..
%lua <-
Lua ".."
do -- scope of "stop repeating" label
\%lua
- ::stop_repeat::;
+ ::stop_repeat::
end -- end of "stop repeating" label scope
return %lua
parse [repeat %body] as: repeat while (yes) %body
@@ -116,26 +116,26 @@ immediately
for i=1,\(%n as lua expr) do
\(%body as lua statements)
if
- %body has subtree % where: (%.type = "Action") and ((%'s stub) is "do next repeat")
- ..: to %lua write "\n ::continue_repeat::;"
+ %body has subtree % where: (%.type = "Action") and (%.stub is "do next repeat")
+ ..: to %lua write "\n ::continue_repeat::"
to %lua write "\nend --numeric for-loop"
if
- %body has subtree % where: (%.type = "Action") and ((%'s stub) is "stop repeating")
+ %body has subtree % where: (%.type = "Action") and (%.stub is "stop repeating")
..
%lua <-
Lua ".."
do -- scope of "stop repeating" label
\%lua
- ::stop_repeat::;
+ ::stop_repeat::
end -- end of "stop repeating" label scope
return %lua
# For loop control flow
immediately
compile [stop %var] to
- Lua "goto stop_\(%var as lua identifier);"
+ Lua "goto stop_\(%var as lua identifier)"
compile [do next %var] to
- Lua "goto continue_\(%var as lua identifier);"
+ Lua "goto continue_\(%var as lua identifier)"
# Numeric range for loops
immediately
@@ -152,22 +152,22 @@ immediately
if
%body has subtree % where
(%.type = "Action") and
- ((%'s stub) is "do next %") and
+ (%.stub is "do next %") and
%.3 = %var
- ..: to %lua write "\n ::continue_\(%var as lua identifier)::;"
+ ..: to %lua write "\n ::continue_\(%var as lua identifier)::"
to %lua write "\nend --numeric for-loop"
if
%body has subtree % where
(%.type = "Action") and
- ((%'s stub) is "stop %") and
+ (%.stub is "stop %") and
%.2 = %var
..
%lua <-
Lua ".."
do -- scope for stopping for-loop
\%lua
- ::stop_\(%var as lua identifier)::;
+ ::stop_\(%var as lua identifier)::
end -- end of scope for stopping for-loop
return %lua
@@ -187,21 +187,21 @@ immediately
if
%body has subtree % where
(%.type = "Action") and
- ((%'s stub) is "do next %") and
+ (%.stub is "do next %") and
%.value.3.value = %var.value
- ..: to %lua write (Lua "\n ::continue_\(%var as lua identifier)::;")
+ ..: to %lua write (Lua "\n ::continue_\(%var as lua identifier)::")
to %lua write "\nend --foreach-loop"
if
%body has subtree % where
(%.type = "Action") and
- ((%'s stub) is "stop %") and
+ (%.stub is "stop %") and
%.value.2.value = %var.value
..
%lua <-
Lua ".."
do -- scope for stopping for-loop
\%lua
- ::stop_\(%var as lua identifier)::;
+ ::stop_\(%var as lua identifier)::
end -- end of scope for stopping for-loop
return %lua
@@ -221,32 +221,32 @@ immediately
if
%body has subtree % where
(%.type = "Action") and
- ((%'s stub) is "do next %") and
+ (%.stub is "do next %") and
%.value.3.value = %key.value
- ..: to %lua write (Lua "\n ::continue_\(%key as lua identifier)::;")
+ ..: to %lua write (Lua "\n ::continue_\(%key as lua identifier)::")
if
%body has subtree % where
(%.type = "Action") and
- ((%'s stub) is "do next %") and
+ (%.stub is "do next %") and
%.value.3.value = %value.value
- ..: to %lua write (Lua "\n ::continue_\(%value as lua identifier)::;")
+ ..: to %lua write (Lua "\n ::continue_\(%value as lua identifier)::")
to %lua write "\nend --foreach-loop"
%stop_labels <- (Lua "")
if
%body has subtree % where
(%.type = "Action") and
- ((%'s stub) is "stop %") and
+ (%.stub is "stop %") and
%.value.2.value = %key.value
- ..: to %stop_labels write "\n::stop_\(%key as lua identifier)::;"
+ ..: to %stop_labels write "\n::stop_\(%key as lua identifier)::"
if
%body has subtree % where
(%.type = "Action") and
- ((%'s stub) is "stop %") and
+ (%.stub is "stop %") and
%.value.2.value = %value.value
- ..: to %stop_labels write "\n::stop_\(%value as lua identifier)::;"
+ ..: to %stop_labels write "\n::stop_\(%value as lua identifier)::"
if: (length of %stop_labels) > 0
%lua <-
@@ -279,7 +279,7 @@ immediately
assume %condition or barf ".."
Invalid format for 'when' statement. Lines must begin with '*' and have a condition or the word "else"
if: %action is (nil)
- lua> "table.insert(\%fallthroughs, \(%condition as lua expr));"
+ lua> "table.insert(\%fallthroughs, \(%condition as lua expr))"
do next %func_call
if: %condition = "else"
@@ -289,7 +289,7 @@ immediately
%seen_else <- (yes)
..else
assume (not %seen_else) or barf "'else' clause needs to be last in 'when' block"
- lua> "table.insert(\%fallthroughs, \(%condition as lua expr));"
+ lua> "table.insert(\%fallthroughs, \(%condition as lua expr))"
to %code write "\("if" if %is_first else "\nelseif") "
for %i = %condition in %fallthroughs
if (%i > 1): to %code write " or "
@@ -333,7 +333,7 @@ immediately
..else
assume (not %seen_else) or barf "'else' clause needs to be last in 'when % = ?' block"
to %code write "\("if" if %is_first else "\nelseif") "
- lua> "table.insert(\%fallthroughs, \(%condition as lua expr));"
+ lua> "table.insert(\%fallthroughs, \(%condition as lua expr))"
for %i = % in %fallthroughs
if: %i > 1
to %code write " or "
@@ -353,7 +353,7 @@ immediately
%code <-
Lua ".."
do --when % = ?
- local branch_value = \(%branch_value as lua expr);
+ local branch_value = \(%branch_value as lua expr)
\%code
end --when % = ?
return %code
@@ -366,18 +366,18 @@ immediately
..to
Lua ".."
do
- local fell_through = false;
+ local fell_through = false
local ok, ret = pcall(function()
\(%action as lua statements)
- fell_through = true;
- end);
+ fell_through = true
+ end)
if ok then
\(%success as lua statements)
end
if not ok then
\(%fallback as lua statements)
elseif not fell_through then
- return ret;
+ return ret
end
end
parse [try %action] as
@@ -400,18 +400,18 @@ immediately
compile [do %action then always %final_action] to
Lua ".."
do
- local fell_through = false;
+ local fell_through = false
local ok, ret1 = pcall(function()
\(%action as lua statements)
- fell_through = true;
- end);
+ fell_through = true
+ end)
local ok2, ret2 = pcall(function()
\(%final_action as lua statements)
- end);
- if not ok then error(ret1); end
- if not ok2 then error(ret2); end
+ end)
+ if not ok then error(ret1) end
+ if not ok2 then error(ret2) end
if not fell_through then
- return ret1;
+ return ret1
end
end --do-then-always
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 36f7d34..c343ae9 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -7,15 +7,15 @@ immediately
lua> ".."
nomsu:define_compile_action("compile %actions to %lua", function(tree, \%actions, \%lua)
local lua = Lua(tree.source, "nomsu:define_compile_action(")
- local stubs = {}
+ local specs = {}
for i, action in ipairs(\%actions.value) do
- stubs[i] = action:get_stub(true)
+ specs[i] = action:get_spec()
end
- stubs = repr(stubs)
- if #stubs > 80 then
- lua:append("\n ",stubs,",\n ")
+ specs = repr(specs)
+ if #specs > 80 then
+ lua:append("\n ",specs,",\n ")
else
- lua:append(stubs,", ")
+ lua:append(specs,", ")
end
lua:append("function(tree")
local args = {}
@@ -37,15 +37,15 @@ immediately
compile [action %actions %body] to
lua> ".."
local lua = Lua(tree.source, "nomsu:define_action(")
- local stubs = {}
+ local specs = {}
for i, action in ipairs(\%actions.value) do
- stubs[i] = action:get_stub(true)
+ specs[i] = action:get_spec()
end
- stubs = repr(stubs)
- if #stubs > 80 then
- lua:append("\n ",stubs,",\n ")
+ specs = repr(specs)
+ if #specs > 80 then
+ lua:append("\n ",specs,",\n ")
else
- lua:append(stubs,", ")
+ lua:append(specs,", ")
end
lua:append("function(")
local args = {}
@@ -67,15 +67,15 @@ immediately
compile [parse %shorthand as %longhand] to
lua> ".."
local lua = Lua(tree.source, "nomsu:define_compile_action(")
- local stubs = {}
+ local specs = {}
for i, action in ipairs(\%shorthand.value) do
- stubs[i] = action:get_stub(true)
+ specs[i] = action:get_spec()
end
- stubs = repr(stubs)
- if #stubs > 80 then
- lua:append("\n ",stubs,",\n ")
+ specs = repr(specs)
+ if #specs > 80 then
+ lua:append("\n ",specs,",\n ")
else
- lua:append(stubs,", ")
+ lua:append(specs,", ")
end
lua:append("function(tree")
local replacements = {}
@@ -93,15 +93,15 @@ immediately
elseif t.type == 'Var' and replacements[t.value] then
return replacements[t.value]
elseif t.type == 'Var' then
- return t.type.."("..repr(t.value.."#"..tostring(MANGLE_INDEX))..", "..repr(t.source)..")"
+ return t.type.."("..repr(t.value.."#"..tostring(MANGLE_INDEX))..", "..repr(tostring(t.source))..")"
elseif t.is_multi then
local bits = {}
for i, entry in ipairs(t.value) do
bits[i] = make_tree(entry)
end
- return t.type.."(Tuple("..table.concat(bits, ", ").."), "..repr(t.source)..")"
+ return t.type.."(Tuple("..table.concat(bits, ", ").."), "..repr(tostring(t.source))..")"
else
- return t.type.."("..repr(t.value)..", "..repr(t.source)..")"
+ return t.type.."("..repr(t.value)..", "..repr(tostring(t.source))..")"
end
end
lua:append(")\n local tree = ", make_tree(\%longhand), "\n return nomsu:tree_to_lua(tree)\nend);")
@@ -110,7 +110,7 @@ immediately
compile [remove action %action] to
Lua ".."
do
- local fn = ACTIONS[\(=lua "repr(\%action:get_stub())")]
+ local fn = ACTIONS[\(=lua "repr(\%action.stub)")]
local stubs = ARG_ORDERS[fn]
for stub in pairs(stubs) do
ACTIONS[stub] = nil
@@ -159,9 +159,6 @@ immediately
local lua = Lua(\%tree.source, "return ",nomsu:tree_to_lua(\%tree))
return nomsu:run_lua(lua)
- action [%tree's stub]
- =lua "\%tree:get_stub()"
-
immediately
parse [%var <-write %code] as: lua> "\%var:append(\%code);"
parse [to %var write %code] as: lua> "\%var:append(\%code);"
@@ -178,7 +175,7 @@ immediately
# Compiler tools
immediately
compile [run %code] to
- Lua "nomsu:run(Nomsu(\(%code.source as text), \(%code as lua expr)))"
+ Lua "nomsu:run(Nomsu(\"\(%code.source as text)\", \(%code as lua expr)))"
immediately
compile [show lua %block] to
diff --git a/core/operators.nom b/core/operators.nom
index c3b56c6..9b6b68a 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -51,7 +51,7 @@ immediately
assume %var_lua.is_value or barf "Invalid target for assignment: \%var"
lua> ".."
\%value = \%value:map(function(t)
- if Action:is_instance(t) and t:get_stub() == "?" then
+ if Action:is_instance(t) and t.stub == "?" then
return \%var
end
end)
@@ -75,7 +75,7 @@ immediately
for i, item in ipairs(\%assignments.value) do
local \%target, \%value = item.value[1], item.value[2]
\%value = \%value:map(function(t)
- if Action:is_instance(t) and t:get_stub() == "?" then
+ if Action:is_instance(t) and t.stub == "?" then
return \%target
end
end)
diff --git a/core/scopes.nom b/core/scopes.nom
index e4e574a..72631c0 100644
--- a/core/scopes.nom
+++ b/core/scopes.nom
@@ -7,47 +7,48 @@ use "core/control_flow.nom"
compile [using %definitions %body, using %definitions do %body] to
%setup_lua <-
Lua ".."
- local fell_through = false;
+ local fell_through = false
local ok, ret = pcall(function()
\(%definitions as lua statements)
- fell_through = true;
- end);
+ fell_through = true
+ end)
%body_lua <-
Lua ".."
- local fell_through = false;
+ local fell_through = false
local ok, ret = pcall(function()
\(%body as lua statements)
- fell_through = true;
- end);
+ fell_through = true
+ end)
remove free vars (declare locals in %setup_lua) from %body_lua
%lua <-
Lua ".."
do
- local old_actions, old_compile_actions, old_arg_orders = ACTIONS, COMPILE_ACTIONS, ARG_ORDERS;
- ACTIONS = setmetatable({}, {__index=old_actions});
- COMPILE_ACTIONS = setmetatable({}, {__index=old_compile_actions});
- ARG_ORDERS = setmetatable({}, {__index=old_arg_orders});
+ local old_actions, old_compile_actions, old_arg_orders = ACTIONS, COMPILE_ACTIONS, ARG_ORDERS
+ ACTIONS = setmetatable({}, {__index=old_actions})
+ COMPILE_ACTIONS = setmetatable({}, {__index=old_compile_actions})
+ ARG_ORDERS = setmetatable({}, {__index=old_arg_orders})
\%setup_lua
if not ok then
- ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders;
- error(ret);
+ ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders
+ error(ret)
end
if not fell_through then
- ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders;
- return ret;
+ ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders
+ return ret
end
- getmetatable(ACTIONS).__newindex = old_actions;
- getmetatable(COMPILE_ACTIONS).__newindex = old_compile_actions;
- getmetatable(ARG_ORDERS).__newindex = old_arg_orders;
+ getmetatable(ACTIONS).__newindex = old_actions
+ getmetatable(COMPILE_ACTIONS).__newindex = old_compile_actions
+ getmetatable(ARG_ORDERS).__newindex = old_arg_orders
\%body_lua
- ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders;
+ ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders
if not ok then
- error(ret);
+ error(ret)
end
if not fell_through then
- return ret;
+ return ret
end
end
declare locals in %lua
return %lua
+parse [using %] as: using % (do nothing)
diff --git a/lib/object.nom b/lib/object.nom
index 07b3613..638dee4 100644
--- a/lib/object.nom
+++ b/lib/object.nom
@@ -1,136 +1,54 @@
use "core"
-compile [@, me] to: Lua value "self"
+lua> "CLASSES = {}"
-compile [as %instance %body] to
- Lua ".."
- do
- local self = \(%instance as lua expr);
- local global_actions = ACTIONS;
- local ACTIONS = setmetatable({}, {__index=function(_,key)
- local method = self[key];
- if method then return (function(...) return method(self, ...); end); end
- return global_actions[key];
- end});
- \(%body as lua statements)
- end
+immediately
+ compile [@, me] to: Lua value "self"
+action [new %classname %inst]
+ =lua "setmetatable(\%inst, CLASSES[\%classname])"
+immediately
+ parse [new %classname] as: new %classname {}
-compile [object %classname %class_body] to
- %class_id <- (=lua "string.as_lua_id(\(%classname as value)):sub(2,-1)")
- if: %class_id is ""
- %class_id <- "class"
- %methods <-: Lua ""
- %__index <- %class_id
- %__newindex <- "nil"
- for %line in %class_body.value
- if: %line.type is "Comment"
- do next %line
- if: (%line.type is "Action") and ((%line's stub) is "slots %")
- %slot_index_clauses <- []
- %slot_newindex_clauses <- []
- %slots <- %line.value.2
- for %slot_index = %slot_var in %slots.value
- to %slot_index_clauses add ".."
- if key == \(repr %slot_var.value) or key == \(repr (%slot_var as lua expr)) then
- return rawget(self, \%slot_index);
- end
- to %slot_newindex_clauses add ".."
- if key == \(repr %slot_var.value) or key == \(repr (%slot_var as lua expr)) or key == \%slot_index then
- rawset(self, \%slot_index, value);
- end
+parse [as %instance %body] as
+ lua> "local self;"
+ do
+ using
+ lua> ".."
+ self = \%instance
+ local cls = self.class
+ local old_self = self.class:set_self(self)
+ ACTIONS = cls.ACTIONS
+ COMPILE_ACTIONS = cls.COMPILE_ACTIONS
+ ARG_ORDERS = cls.ARG_ORDERS
+ ..do
+ %body
+ ..then always
+ lua> ".."
+ self.class:set_self(old_self)
- %__index <- ".."
- function(self, key)
- \(%slot_index_clauses joined with "\n")
- return \%class_id[key];
- end
- %__newindex <- ".."
- function(self, key, value)
- \(%slot_newindex_clauses joined with "\n")
- error("Attempt to store data in "..repr(key)..", which is not a valid slot on "..tostring(self.class));
- end
- do next %line
- assume ((%line.type is "Action") and ((%line's stub) is "action % %"))
- ..or barf "Only action definitions are supported inside 'object % %'"
- %actions <- %line.value.2
- %body <- %line.value.3
+parse [object %classname %class_body] as
+ using
+ %cls <- {..}
+ name:%classname
+ ACTIONS:=lua "ACTIONS", COMPILE_ACTIONS:=lua "COMPILE_ACTIONS"
+ ARG_ORDERS:=lua "ARG_ORDERS"
+ (=lua "CLASSES").%classname <- %cls
lua> ".."
- do
- local stubs = {}
- for i, action in ipairs(\%actions.value) do
- stubs[i] = action:get_stub(true)
- end
- local lua = Lua(\(%line.source), \%class_id, "[ ", repr(stubs[1]), "] = function(self")
- local args = {}
- for i,tok in ipairs(\%actions[1]) do
- if tok.type == "Var" then args[#args+1] = tok end
- end
- for i, arg in ipairs(args) do
- lua:append(", ", nomsu:tree_to_lua(arg))
- end
- local body_lua = nomsu:tree_to_lua(\%body):as_statements("return ")
- body_lua:remove_free_vars(args)
- body_lua:declare_locals()
- lua:append(")\n ", body_lua, "\nend;\n")
- \%methods:append(lua)
+ setmetatable(\%cls, {__tostring=function() return \%classname end})
+ local self = nil
+ \%cls.set_self = function(_, inst)
+ local old_self = self
+ self = inst
+ return old_self
+ end
+ \%cls.__index = \%cls
+ \%cls.class = \%cls
+ %class_body
+ run ".."
+ action [new \%classname %inst]
+ say "NEWING"
+ return: =lua "setmetatable(\\%inst, \\%cls)"
+ lua> ".."
+ if ACTIONS["as text"] then
+ \%cls.__tostring = ACTIONS["as text"]
end
-
- return
- Lua ".."
- do -- \%class_id
- -- Create the class object
- local \%class_id = setmetatable({
- name=\(%classname as lua expr), instances=setmetatable({}, {__mode="k"}),
- }, {
- __tostring=function(c) return c.name; end,
- __call=function(cls, initial_values)
- local inst = setmetatable({}, cls.instance_metatable);
- for k,v in pairs(initial_values) do inst[k] = v; end
- cls.instances[inst] = true;
- if inst['set % up'] then
- inst['set % up'](inst);
- end
- return inst;
- end,
- });
- \%class_id.class = \%class_id;
-
- -- Define the methods
- \%methods
-
- -- Define class methods for instantiating and accessing instances
- \%class_id.instance_metatable = {
- __index=\%__index,
- __newindex=\%__newindex,
- __tostring=\%class_id['as text'] or function(inst)
- return "<"..inst.class.name..": "..nomsu.ids[inst]..">";
- end,
- __len=\%class_id['size of'],
- __unm=\%class_id['-'],
- __add=\%class_id['+ %'],
- __sub=\%class_id['- %'],
- __mul=\%class_id['* %'],
- __div=\%class_id['/ %'],
- __mod=\%class_id['wrapped around %'],
- __pow=\%class_id['^ %'],
- __band=\%class_id['AND %'],
- __bor=\%class_id['OR %'],
- __bxor=\%class_id['XOR %'],
- __bshl=\%class_id['<< %'],
- __bshr=\%class_id['>> %'],
- __eq=\%class_id['= %'],
- __lt=\%class_id['< %'],
- __le=\%class_id['<= %'],
- };
- nomsu:define_action("instances of "..\%class_id.name, function()
- return utils.keys(\%class_id.instances);
- end);
- nomsu:define_action("new "..\%class_id.name.." %instance", function(_instance)
- return \%class_id(_instance);
- end);
- nomsu:define_action("new "..\%class_id.name, function()
- return \%class_id({});
- end);
- end -- End of definition of \%class_id
- \("\n\n")
-
diff --git a/nomsu.lua b/nomsu.lua
index c5f1c92..5a51cb3 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -201,7 +201,7 @@ do
end
if utils.size(seen_errors) >= 10 then
seen_errors[start_pos + 1] = colored.bright(colored.yellow(colored.onred("Too many errors, canceling parsing...")))
- return #src
+ return #src + 1
end
local err_pos = start_pos
local text_loc = userdata.source:sub(err_pos, err_pos)
@@ -436,7 +436,8 @@ do
local line_numbered_lua = "1 |" .. lua_string:gsub("\n", fn)
error("Failed to compile generated code:\n" .. tostring(colored.bright(colored.blue(colored.onblack(line_numbered_lua)))) .. "\n\n" .. tostring(err), 0)
end
- if not (self.source_map[tostring(lua.source)]) then
+ local source_key = tostring(lua.source)
+ if not (self.source_map[source_key]) then
local map = { }
local offset = 1
local source = lua.source
@@ -480,14 +481,14 @@ do
fn(lua)
map[lua_line] = map[lua_line] or nomsu_line
map[0] = 0
- self.source_map[tostring(lua.source)] = map
+ self.source_map[source_key] = map
end
return run_lua_fn()
end,
tree_to_lua = function(self, tree)
local _exp_0 = tree.type
if "Action" == _exp_0 then
- local stub = tree:get_stub()
+ local stub = tree.stub
local compile_action = self.environment.COMPILE_ACTIONS[stub]
if compile_action then
local args
@@ -603,9 +604,9 @@ do
end
bits = _accum_0
end
- return t.type .. "(Tuple(" .. table.concat(bits, ", ") .. "), " .. repr(t.source) .. ")"
+ return t.type .. "(Tuple(" .. table.concat(bits, ", ") .. "), " .. repr(tostring(t.source)) .. ")"
else
- return t.type .. "(" .. repr(t.value) .. ", " .. repr(t.source) .. ")"
+ return t.type .. "(" .. repr(t.value) .. ", " .. repr(tostring(t.source)) .. ")"
end
end
return Lua.Value(tree.source, make_tree(tree.value[1]))
@@ -1129,13 +1130,13 @@ do
end
end
self:define_compile_action("Lua %code", function(self, _code)
- local lua = Lua.Value(_code.source, "Lua(", repr(_code.source))
+ local lua = Lua.Value(_code.source, "Lua(", repr(tostring(_code.source)))
add_lua_string_bits(lua, _code)
lua:append(")")
return lua
end)
self:define_compile_action("Lua value %code", function(self, _code)
- local lua = Lua.Value(_code.source, "Lua.Value(", repr(_code.source))
+ local lua = Lua.Value(_code.source, "Lua.Value(", repr(tostring(_code.source)))
add_lua_string_bits(lua, _code)
lua:append(")")
return lua
@@ -1436,7 +1437,6 @@ OPTIONS
if info.lastlinedefined then
info.lastlinedefined = assert(map[info.lastlinedefined])
end
- info.short_src = info.source:match('"([^[]*)')
end
end
end
@@ -1504,8 +1504,7 @@ OPTIONS
if calling_fn.lastlinedefined then
calling_fn.lastlinedefined = assert(map[calling_fn.lastlinedefined])
end
- calling_fn.short_src = calling_fn.source:match('"([^[]*)')
- local filename, start, stop = calling_fn.source:match('"([^[]*)%[([0-9]+):([0-9]+)]"')
+ local filename, start, stop = calling_fn.source:match('@([^[]*)%[([0-9]+):([0-9]+)]')
assert(filename)
local file = FILE_CACHE[filename]:sub(tonumber(start), tonumber(stop))
local err_line = get_line(file, calling_fn.currentline):sub(1, -2)
diff --git a/nomsu.moon b/nomsu.moon
index 4951aba..6d53d58 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -169,7 +169,7 @@ NOMSU_DEFS = with {}
return true
if utils.size(seen_errors) >= 10
seen_errors[start_pos+1] = colored.bright colored.yellow colored.onred "Too many errors, canceling parsing..."
- return #src
+ return #src+1
err_pos = start_pos
--if src\sub(err_pos,err_pos)\match("[\r\n]")
-- err_pos += #src\match("[ \t\n\r]*", err_pos)
@@ -398,7 +398,8 @@ class NomsuCompiler
("\n%-3d|")\format(n)
line_numbered_lua = "1 |"..lua_string\gsub("\n", fn)
error("Failed to compile generated code:\n#{colored.bright colored.blue colored.onblack line_numbered_lua}\n\n#{err}", 0)
- unless @source_map[tostring(lua.source)]
+ source_key = tostring(lua.source)
+ unless @source_map[source_key]
map = {}
offset = 1
source = lua.source
@@ -433,7 +434,7 @@ class NomsuCompiler
map[lua_line] or= nomsu_line
map[0] = 0
-- Mapping from lua line number to nomsu line numbers
- @source_map[tostring(lua.source)] = map
+ @source_map[source_key] = map
return run_lua_fn!
@@ -442,7 +443,7 @@ class NomsuCompiler
tree_to_lua: (tree)=>
switch tree.type
when "Action"
- stub = tree\get_stub!
+ stub = tree.stub
compile_action = @environment.COMPILE_ACTIONS[stub]
if compile_action
args = [arg for arg in *tree.value when type(arg) != "string"]
@@ -499,9 +500,9 @@ class NomsuCompiler
return repr(t)
if t.is_multi
bits = [make_tree(bit) for bit in *t.value]
- return t.type.."(Tuple("..table.concat(bits, ", ").."), "..repr(t.source)..")"
+ return t.type.."(Tuple("..table.concat(bits, ", ").."), "..repr(tostring t.source)..")"
else
- return t.type.."("..repr(t.value)..", "..repr(t.source)..")"
+ return t.type.."("..repr(t.value)..", "..repr(tostring t.source)..")"
Lua.Value tree.source, make_tree(tree.value[1])
when "Block"
@@ -901,13 +902,13 @@ class NomsuCompiler
lua\append bit_lua
@define_compile_action "Lua %code", (_code)=>
- lua = Lua.Value(_code.source, "Lua(", repr(_code.source))
+ lua = Lua.Value(_code.source, "Lua(", repr(tostring _code.source))
add_lua_string_bits(lua, _code)
lua\append ")"
return lua
@define_compile_action "Lua value %code", (_code)=>
- lua = Lua.Value(_code.source, "Lua.Value(", repr(_code.source))
+ lua = Lua.Value(_code.source, "Lua.Value(", repr(tostring _code.source))
add_lua_string_bits(lua, _code)
lua\append ")"
return lua
@@ -1008,7 +1009,7 @@ OPTIONS
info.linedefined = assert(map[info.linedefined])
if info.lastlinedefined
info.lastlinedefined = assert(map[info.lastlinedefined])
- info.short_src = info.source\match('"([^[]*)')
+ --info.short_src = info.source\match('@([^[]*)')
return info
print_err_msg = (error_message, stack_offset=3)->
@@ -1048,8 +1049,8 @@ OPTIONS
calling_fn.linedefined = assert(map[calling_fn.linedefined])
if calling_fn.lastlinedefined
calling_fn.lastlinedefined = assert(map[calling_fn.lastlinedefined])
- calling_fn.short_src = calling_fn.source\match('"([^[]*)')
- filename,start,stop = calling_fn.source\match('"([^[]*)%[([0-9]+):([0-9]+)]"')
+ --calling_fn.short_src = calling_fn.source\match('"([^[]*)')
+ filename,start,stop = calling_fn.source\match('@([^[]*)%[([0-9]+):([0-9]+)]')
assert(filename)
file = FILE_CACHE[filename]\sub(tonumber(start),tonumber(stop))
err_line = get_line(file, calling_fn.currentline)\sub(1,-2)
diff --git a/nomsu_tree.lua b/nomsu_tree.lua
index dee5cc2..9245509 100644
--- a/nomsu_tree.lua
+++ b/nomsu_tree.lua
@@ -25,7 +25,7 @@ Tree = function(name, kind, methods)
do
methods.type = name
methods.name = name
- methods.__new = function(self, value, source)
+ methods.__new = methods.__new or function(self, value, source)
assert(source)
if type(source) == 'string' then
source = Source:from_string(source)
@@ -93,10 +93,18 @@ Tree = function(name, kind, methods)
end
end
end
- Types[name] = immutable({
- "value",
- "source"
- }, methods)
+ if name == "Action" then
+ Types[name] = immutable({
+ "value",
+ "source",
+ "stub"
+ }, methods)
+ else
+ Types[name] = immutable({
+ "value",
+ "source"
+ }, methods)
+ end
end
Tree("Block", 'multi')
Tree("EscapedNomsu", 'multi')
@@ -109,35 +117,35 @@ Tree("Number", 'single')
Tree("Comment", 'single')
Tree("Var", 'single')
Tree("Action", 'multi', {
- get_stub = function(self, include_names)
- if include_names == nil then
- include_names = false
- end
- if include_names then
- return concat((function()
- local _accum_0 = { }
- local _len_0 = 1
- local _list_0 = self.value
- for _index_0 = 1, #_list_0 do
- local a = _list_0[_index_0]
- _accum_0[_len_0] = type(a) == "string" and a or "%" .. tostring(a.value)
- _len_0 = _len_0 + 1
- end
- return _accum_0
- end)(), " ")
- else
- return concat((function()
- local _accum_0 = { }
- local _len_0 = 1
- local _list_0 = self.value
- for _index_0 = 1, #_list_0 do
- local a = _list_0[_index_0]
- _accum_0[_len_0] = type(a) == "string" and a or "%"
- _len_0 = _len_0 + 1
- end
- return _accum_0
- end)(), " ")
+ __new = function(self, value, source)
+ assert(source)
+ if type(source) == 'string' then
+ source = Source:from_string(source)
end
+ local stub = concat((function()
+ local _accum_0 = { }
+ local _len_0 = 1
+ for _index_0 = 1, #value do
+ local a = value[_index_0]
+ _accum_0[_len_0] = type(a) == "string" and a or "%"
+ _len_0 = _len_0 + 1
+ end
+ return _accum_0
+ end)(), " ")
+ return value, source, stub
+ end,
+ get_spec = function(self)
+ return concat((function()
+ local _accum_0 = { }
+ local _len_0 = 1
+ local _list_0 = self.value
+ for _index_0 = 1, #_list_0 do
+ local a = _list_0[_index_0]
+ _accum_0[_len_0] = type(a) == "string" and a or "%" .. tostring(a.value)
+ _len_0 = _len_0 + 1
+ end
+ return _accum_0
+ end)(), " ")
end
})
return Types
diff --git a/nomsu_tree.moon b/nomsu_tree.moon
index 1e662d7..4e9ec3d 100644
--- a/nomsu_tree.moon
+++ b/nomsu_tree.moon
@@ -20,7 +20,7 @@ Tree = (name, kind, methods)->
with methods
.type = name
.name = name
- .__new = (value, source)=>
+ .__new or= (value, source)=>
assert source
if type(source) == 'string'
source = Source\from_string(source)
@@ -46,7 +46,10 @@ Tree = (name, kind, methods)->
._map = (fn)=>
fn(@) or @
- Types[name] = immutable {"value", "source"}, methods
+ if name == "Action"
+ Types[name] = immutable {"value", "source", "stub"}, methods
+ else
+ Types[name] = immutable {"value", "source"}, methods
Tree "Block", 'multi'
Tree "EscapedNomsu", 'multi'
@@ -60,10 +63,13 @@ Tree "Comment", 'single'
Tree "Var", 'single'
Tree "Action", 'multi',
- get_stub: (include_names=false)=>
- if include_names
- concat [type(a) == "string" and a or "%#{a.value}" for a in *@value], " "
- else
- concat [type(a) == "string" and a or "%" for a in *@value], " "
+ __new: (value, source)=>
+ assert source
+ if type(source) == 'string'
+ source = Source\from_string(source)
+ stub = concat [type(a) == "string" and a or "%" for a in *value], " "
+ return value, source, stub
+ get_spec: =>
+ concat [type(a) == "string" and a or "%#{a.value}" for a in *@value], " "
return Types
diff --git a/tests/object.nom b/tests/object.nom
index 6433c86..aeeb559 100644
--- a/tests/object.nom
+++ b/tests/object.nom
@@ -1,16 +1,15 @@
use "core"
use "lib/object.nom"
-immediately
- object "Dog"
- action [bark]
- %barks <- ("Bark!" for % in 1 to ((me).barks))
- return: %barks joined with " "
+object "Dog"
+ action [bark]
+ %barks <- ("Bark!" for % in 1 to ((me).barks))
+ return: %barks joined with " "
- action [get pissed off]
- ((me).barks) +<- 1
+ action [get pissed off]
+ ((me).barks) +<- 1
-%d <-: new Dog {barks:2}
+%d <-: new "Dog" {barks:2}
as %d
assume: (me) = %d
assume: ((me).barks) = 2
@@ -18,10 +17,24 @@ as %d
get pissed off
assume: ((me).barks) = 3
assume: (bark) = "Bark! Bark! Bark!"
-assume: "\(%d's "class")" = "Dog"
+assume: "\(%d.class)" = "Dog"
assume: (%d's "barks") = 3
-as: new Dog {barks:1}
+as: new "Dog" {barks:1}
assume: (bark) = "Bark!"
+action [foo]
+ as: new "Dog" {barks:23}
+ return: (me).barks
+ barf "Reached unreachable code"
+
+assume: (foo) = 23
+
+as: new "Dog" {barks:101}
+ try: as (new "Dog" {barks:8}) (barf)
+ ..and if it succeeds: barf
+
+ assume: (me).barks = 101
+ ..or barf "Error in nested 'as % %' failed to properly reset 'self'"
+
say "Object test passed."