aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-06-14 23:25:05 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2018-06-14 23:25:34 -0700
commitb12744d831c4158671fc22401590eaac00f7c141 (patch)
tree203b80de68d89c7333172337f8def46ba11294d3
parent49f1eb3d08caf7605046373b7b3a001f28aa8aab (diff)
Some cleanup and fixes. Simplifying a lot of code, and extending the
flexibility of scoping. Redesigned Object system too.
-rw-r--r--core/control_flow.nom59
-rw-r--r--core/coroutines.nom17
-rw-r--r--core/errors.nom46
-rw-r--r--core/metaprogramming.nom8
-rw-r--r--core/operators.nom2
-rw-r--r--core/scopes.nom66
-rw-r--r--lib/object.nom85
-rw-r--r--nomsu.lua10
-rwxr-xr-xnomsu.moon4
-rw-r--r--tests/collections.nom2
-rw-r--r--tests/control_flow.nom14
-rw-r--r--tests/math.nom2
-rw-r--r--tests/metaprogramming.nom2
-rw-r--r--tests/object.nom3
-rw-r--r--tests/operators.nom2
-rw-r--r--tests/scopes.nom29
-rw-r--r--tests/text.nom2
17 files changed, 163 insertions, 190 deletions
diff --git a/core/control_flow.nom b/core/control_flow.nom
index e760b00..15c1ca1 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -359,51 +359,6 @@ immediately
end --when % = ?
return %code
-# Try/except
-immediately
- compile [..]
- try %action and if it succeeds %success or if it barfs %msg %fallback
- try %action and if it barfs %msg %fallback or if it succeeds %success
- ..to
- Lua ".."
- do
- local fell_through = false
- local err, erred = nil, false
- local ok, ret = xpcall(function()
- \(%action as lua statements)
- fell_through = true
- end, function(\(%msg as lua expr))
- local ok, ret = pcall(function()
- \(%fallback as lua statements)
- end)
- if not ok then err, erred = ret, true end
- end)
- if ok then
- \(%success as lua statements)
- if not fell_through then
- return ret
- end
- elseif erred then
- error(err, 0)
- end
- end
-immediately
- parse [..]
- try %action and if it succeeds %success or if it barfs %fallback
- try %action and if it barfs %fallback or if it succeeds %success
- ..as: try %action and if it succeeds %success or if it barfs (=lua "") %fallback
-immediately
- parse [try %action] as
- try %action and if it succeeds: do nothing
- ..or if it barfs: do nothing
- parse [try %action and if it barfs %fallback] as
- try %action and if it succeeds: do nothing
- ..or if it barfs %fallback
- parse [try %action and if it barfs %msg %fallback] as
- try %action and if it succeeds: do nothing
- ..or if it barfs %msg %fallback
- parse [try %action and if it succeeds %success] as
- try %action and if it succeeds %success or if it barfs: do nothing
# Do/finally
immediately
@@ -433,17 +388,7 @@ immediately
declare locals in %body
return
Lua value ".."
- ((function()
+ (function()
\%body
- end)())
+ end)()
-# Coroutines:
-immediately
- compile [values %body, coroutine %body, generator %body] to
- Lua value ".."
- (function()
- \(%body as lua statements)
- end)
- compile [->] to: Lua "coroutine.yield(true);"
- compile [-> %] to: Lua "coroutine.yield(true, \(% as lua expr));"
- compile [-> %k = %v] to: Lua "coroutine.yield(\(%k as lua expr), \(%v as lua expr));"
diff --git a/core/coroutines.nom b/core/coroutines.nom
new file mode 100644
index 0000000..d0d9c36
--- /dev/null
+++ b/core/coroutines.nom
@@ -0,0 +1,17 @@
+#
+ This file defines the code that creates and manipulates coroutines
+
+use "core/metaprogramming.nom"
+
+compile [coroutine %body, generator %body] to
+ Lua value ".."
+ (function()
+ \(%body as lua statements)
+ end)
+compile [->] to: Lua value "coroutine.yield(true)"
+compile [-> %] to: Lua value "coroutine.yield(true, \(% as lua expr))"
+compile [for % in coroutine %co %body] to
+ Lua ".."
+ for junk,\(% as lua expr) in coroutine.wrap(\(%co as lua expr)) do
+ \(%body as lua statements)
+ end
diff --git a/core/errors.nom b/core/errors.nom
index dc585be..8c6261a 100644
--- a/core/errors.nom
+++ b/core/errors.nom
@@ -20,3 +20,49 @@ compile [assume %condition or barf %message] to
if not \(%condition as lua expr) then
error(\(%message as lua expr), 0);
end
+
+# Try/except
+immediately
+ compile [..]
+ try %action and if it succeeds %success or if it barfs %msg %fallback
+ try %action and if it barfs %msg %fallback or if it succeeds %success
+ ..to
+ Lua ".."
+ do
+ local fell_through = false
+ local err, erred = nil, false
+ local ok, ret = xpcall(function()
+ \(%action as lua statements)
+ fell_through = true
+ end, function(\(%msg as lua expr))
+ local ok, ret = pcall(function()
+ \(%fallback as lua statements)
+ end)
+ if not ok then err, erred = ret, true end
+ end)
+ if ok then
+ \(%success as lua statements)
+ if not fell_through then
+ return ret
+ end
+ elseif erred then
+ error(err, 0)
+ end
+ end
+immediately
+ parse [..]
+ try %action and if it succeeds %success or if it barfs %fallback
+ try %action and if it barfs %fallback or if it succeeds %success
+ ..as: try %action and if it succeeds %success or if it barfs (=lua "") %fallback
+immediately
+ parse [try %action] as
+ try %action and if it succeeds: do nothing
+ ..or if it barfs: do nothing
+ parse [try %action and if it barfs %fallback] as
+ try %action and if it succeeds: do nothing
+ ..or if it barfs %fallback
+ parse [try %action and if it barfs %msg %fallback] as
+ try %action and if it succeeds: do nothing
+ ..or if it barfs %msg %fallback
+ parse [try %action and if it succeeds %success] as
+ try %action and if it succeeds %success or if it barfs: do nothing
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 301c092..82447b3 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -117,8 +117,12 @@ immediately
action [%tree as lua return]
=lua "nomsu:tree_to_lua(\%tree):as_statements('return ')"
- action [%var as lua identifier]
- =lua "type(\%var) == 'string' and string.as_lua_id(\%var) or nomsu:tree_to_lua(\%var)"
+ action [%var as lua identifier, %var as lua id]
+ lua> ".."
+ if type(\%var) == 'string' then return string.as_lua_id(\%var)
+ elseif \%var.type == 'Var' then return string.as_lua_id(\%var[1])
+ elseif \%var.type == 'Action' then return "A"..string.as_lua_id(\%var.stub)
+ end
immediately
compile [%tree with %t -> %replacement] to
diff --git a/core/operators.nom b/core/operators.nom
index 2b44df4..f07ab3f 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -40,7 +40,7 @@ immediately
immediately
# Simultaneous mutli-assignments like: x,y,z = 1,x,3;
- compile [<- %assignments] to
+ compile [<- %assignments, assign %assignments] to
assume (%assignments.type is "Dict") or barf ".."
Expected a Dict for the assignments part of '<- %' statement, not \%assignments
lua> ".."
diff --git a/core/scopes.nom b/core/scopes.nom
index 02ad73d..b5fdded 100644
--- a/core/scopes.nom
+++ b/core/scopes.nom
@@ -1,54 +1,30 @@
use "core/metaprogramming.nom"
-use "core/text.nom"
use "core/operators.nom"
use "core/collections.nom"
use "core/control_flow.nom"
-compile [using %definitions %body, using %definitions do %body] to
- %setup_lua <-
- Lua ".."
- local fell_through = false
- local ok, ret = pcall(function()
- \(%definitions as lua statements)
- fell_through = true
- end)
- %body_lua <-
- Lua ".."
- local fell_through = false
- local ok, ret = pcall(function()
- \(%body as lua statements)
- fell_through = true
- end)
- remove free vars (declare locals in %setup_lua) from %body_lua
- %lua <-
+compile [with local %locals %body, with local %locals do %body] to
+ %body_lua <- (%body as lua statements)
+ when %locals.type = ?
+ * "Dict"
+ %body_lua <-
+ Lua ".."
+ \(=lua "A_assign_1(\%locals, \%locals)")
+ \%body_lua
+ declare locals
+ (%.1 as lua id) for % in %locals
+ .. in %body_lua
+ * "List"
+ declare locals
+ (% as lua id) for % in %locals
+ .. in %body_lua
+ * "Var"
+ * "Action"
+ declare locals [%locals as lua id] in %body_lua
+ * else
+ barf "Unexpected local: \(%locals as nomsu)"
+ return
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})
- \%setup_lua
- if not ok then
- ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders
- error(ret, 0)
- end
- if not fell_through then
- 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
\%body_lua
- ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders
- if not ok then
- error(ret, 0)
- end
- if not fell_through then
- 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 eb9beb8..27ef6c9 100644
--- a/lib/object.nom
+++ b/lib/object.nom
@@ -1,7 +1,5 @@
use "core"
-# TODO: make codegen less verbose
-
lua> "CLASSES = {}"
immediately
@@ -11,50 +9,41 @@ action [new %classname %inst]
immediately
parse [new %classname] as: new %classname {}
-compile [as %instance %body] to
- Lua ".."
- do
- local self = \(%instance as lua expr)
- local old_self = self.class:set_self(self)
- old_actions, ACTIONS = ACTIONS, self.class.ACTIONS
- old_compile_actions, COMPILE_ACTIONS = COMPILE_ACTIONS, self.class.COMPILE_ACTIONS
- old_arg_orders, ARG_ORDERS = ARG_ORDERS, self.class.ARG_ORDERS
- local fell_through = false
- local ok, ret = pcall(function()
- \(%body as lua statements)
- fell_through = true
- end)
- self.class:set_self(old_self)
- ACTIONS = old_actions
- COMPILE_ACTIONS = old_compile_actions
- ARG_ORDERS = old_arg_orders
- if not ok then error(ret) end
- if not fell_through then return ret end
- end
+immediately
+ compile [call method %method] to: Lua value "self:\(%method as lua expr)"
-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> ".."
- 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
+parse [as %instance %body] as
+ result of
+ %old_self <- (me)
+ (me) <- %instance
+ try
+ %body
+ ..and if it barfs %msg
+ (me) <- %old_self
+ barf %msg
+ ..or if it succeeds
+ (me) <- %old_self
+
+compile [object %classname %class_body] to
+ %lua <-
+ Lua ".."
+ do
+ local class = {name=\(%classname as lua expr)}
+ setmetatable(class, {__tostring=function(cls) return cls.name end})
+ CLASSES[class.name] = class
+ class.__index = class
+ class.class = class
+
+ if: %class_body.type != "Block"
+ %class_body <- [%class_body]
+ for %statement in %class_body
+ assume: (%statement.type is "Action") and (%statement.stub is "action % %")
+ to %lua write "\n class."
+ to %lua write (%statement as lua)
+
+ to %lua write ".."
+
+ class.__tostring = class["A"..string.as_lua_id("as text")]
+ end
+
+ return %lua
diff --git a/nomsu.lua b/nomsu.lua
index 4d06969..2482e46 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -1305,6 +1305,16 @@ do
self.environment.LOADED = { }
self.environment.AST = AST
self.environment._ENV = self.environment
+ setmetatable(self.environment, {
+ __index = function(self, k)
+ do
+ local _self = rawget(self, "self")
+ if _self then
+ return _self[k]
+ end
+ end
+ end
+ })
return self:initialize_core()
end,
__base = _base_0,
diff --git a/nomsu.moon b/nomsu.moon
index bf26844..fe18530 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -299,6 +299,10 @@ class NomsuCompiler
@environment.LOADED = {}
@environment.AST = AST
@environment._ENV = @environment
+ setmetatable @environment,
+ __index: (k)=>
+ if _self = rawget(@, "self")
+ return _self[k]
@initialize_core!
parse: (nomsu_code)=>
diff --git a/tests/collections.nom b/tests/collections.nom
index 4170d17..d08a20e 100644
--- a/tests/collections.nom
+++ b/tests/collections.nom
@@ -1,5 +1,5 @@
#..
- Tests for the stuff defined in lib/control_flow.nom
+ Tests for the stuff defined in core/control_flow.nom
use "core"
diff --git a/tests/control_flow.nom b/tests/control_flow.nom
index 20ccabe..238bcbf 100644
--- a/tests/control_flow.nom
+++ b/tests/control_flow.nom
@@ -1,5 +1,5 @@
#
- Tests for the stuff defined in lib/control_flow.nom
+ Tests for the stuff defined in core/control_flow.nom
use "core"
@@ -193,15 +193,3 @@ assume
return %n
..= 6
-#
- %nums <- []
- for % in
- values
- -> 4
- -> 5
- -> 6
- ..
- add % to %nums
-
- assume (%nums = [4,5,6]) or barf "Coroutine iteration failed"
-
diff --git a/tests/math.nom b/tests/math.nom
index 115354c..ffc0a2f 100644
--- a/tests/math.nom
+++ b/tests/math.nom
@@ -1,5 +1,5 @@
#..
- Tests for the stuff defined in lib/control_flow.nom
+ Tests for the stuff defined in core/control_flow.nom
use "core"
diff --git a/tests/metaprogramming.nom b/tests/metaprogramming.nom
index d5ef07f..af43269 100644
--- a/tests/metaprogramming.nom
+++ b/tests/metaprogramming.nom
@@ -1,5 +1,5 @@
#..
- Tests for the stuff defined in lib/metaprogramming.nom
+ Tests for the stuff defined in core/metaprogramming.nom
use "core"
diff --git a/tests/object.nom b/tests/object.nom
index 8ad5b82..b3e8164 100644
--- a/tests/object.nom
+++ b/tests/object.nom
@@ -1,3 +1,6 @@
+#
+ Tests for the object model defined in lib/object.nom
+
use "core"
use "lib/object.nom"
diff --git a/tests/operators.nom b/tests/operators.nom
index 2452ba5..7cdf964 100644
--- a/tests/operators.nom
+++ b/tests/operators.nom
@@ -1,5 +1,5 @@
#..
- Tests for the stuff defined in lib/operators.nom
+ Tests for the stuff defined in core/operators.nom
use "core"
diff --git a/tests/scopes.nom b/tests/scopes.nom
index d3a2eb9..b9d1f4f 100644
--- a/tests/scopes.nom
+++ b/tests/scopes.nom
@@ -1,25 +1,16 @@
use "core"
-using
- %x <- 99
-..do
- assume: %x = 99
+%x <- "outer"
+with local %x
+ %x <- "inner"
+ assume: %x = "inner"
+assume: %x = "outer"
-using
- action [foo]
- return 99
-
-..do
- assume: (foo) = 99
+action [foo] "outer foo"
+with local (foo)
+ action [foo] "inner foo"
+ assume: (foo) = "inner foo"
+assume: (foo) = "outer foo"
-action [baz]
- return "outer"
-
-#
- do
- local action [baz]
- return "inner"
- assume: (baz) = "inner"
- assume: (baz) = "outer"
say "Scopes test passed."
diff --git a/tests/text.nom b/tests/text.nom
index 600cce4..134fff2 100644
--- a/tests/text.nom
+++ b/tests/text.nom
@@ -1,5 +1,5 @@
#..
- Tests for the stuff defined in lib/text.nom
+ Tests for the stuff defined in core/text.nom
use "core"