aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-05-30 17:20:22 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2018-05-30 17:21:19 -0700
commitb53516c47c0dd1f9325f9f721f561487510cca98 (patch)
tree92961e19bc94eec3ab8b0f19357c57399c205b7d /lib
parent5637676bc45ce9aa3015726485f63a2a5745a45a (diff)
Simplified and correctified lib/object (though the codegen still need
streamlining), added a .stub member to Action trees, and switched Source's repr to be @filename[start:stop] instead of "filename[start:stop]"
Diffstat (limited to 'lib')
-rw-r--r--lib/object.nom176
1 files changed, 47 insertions, 129 deletions
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")
-