From fb8bfb740c9db2920b0a9b53f8db5cf7e1f0788b Mon Sep 17 00:00:00 2001 From: leaf corcoran Date: Sat, 26 Sep 2015 17:46:21 -0700 Subject: [PATCH] new transform.statments module, last_stm function --- moonscript/transform/statements.lua | 50 ++++++++++++++++++++++++++++ moonscript/transform/statements.moon | 30 +++++++++++++++++ moonscript/types.moon | 1 + spec/transform_spec.moon | 48 ++++++++++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 moonscript/transform/statements.lua create mode 100644 moonscript/transform/statements.moon create mode 100644 spec/transform_spec.moon diff --git a/moonscript/transform/statements.lua b/moonscript/transform/statements.lua new file mode 100644 index 0000000..afad5c4 --- /dev/null +++ b/moonscript/transform/statements.lua @@ -0,0 +1,50 @@ +local ntype, mtype +do + local _obj_0 = require("moonscript.types") + ntype, mtype = _obj_0.ntype, _obj_0.mtype +end +local Run +do + local _base_0 = { + call = function(self, state) + return self.fn(state) + end + } + _base_0.__index = _base_0 + local _class_0 = setmetatable({ + __init = function(self, fn) + self.fn = fn + self[1] = "run" + end, + __base = _base_0, + __name = "Run" + }, { + __index = _base_0, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + Run = _class_0 +end +local last_stm +last_stm = function(stms) + local last_exp_id = 0 + for i = #stms, 1, -1 do + local stm = stms[i] + if stm and mtype(stm) ~= Run then + if ntype(stm) == "group" then + return last_stm(stm[2]) + end + last_exp_id = i + break + end + end + return stms[last_exp_id], last_exp_id, stms +end +return { + last_stm = last_stm, + Run = Run +} diff --git a/moonscript/transform/statements.moon b/moonscript/transform/statements.moon new file mode 100644 index 0000000..bf214a6 --- /dev/null +++ b/moonscript/transform/statements.moon @@ -0,0 +1,30 @@ + +import ntype, mtype from require "moonscript.types" + +-- A Run is a special statement node that lets a function run and mutate the +-- state of the compiler +class Run + new: (@fn) => + @[1] = "run" + + call: (state) => + @.fn state + +-- extract the last statment from an array of statements +-- is group aware +-- returns: the last statement, the index, the table it was fetched from +last_stm = (stms) -> + last_exp_id = 0 + for i = #stms, 1, -1 + stm = stms[i] + if stm and mtype(stm) != Run + if ntype(stm) == "group" + return last_stm stm[2] + + last_exp_id = i + break + + stms[last_exp_id], last_exp_id, stms + +{:last_stm, :Run} + diff --git a/moonscript/types.moon b/moonscript/types.moon index 9b41523..d7bf3c5 100644 --- a/moonscript/types.moon +++ b/moonscript/types.moon @@ -23,6 +23,7 @@ ntype = (node) -> else "value" +-- gets the class of a type if possible mtype = do moon_type = util.moon.type -- lets us check a smart node without throwing an error diff --git a/spec/transform_spec.moon b/spec/transform_spec.moon new file mode 100644 index 0000000..807175f --- /dev/null +++ b/spec/transform_spec.moon @@ -0,0 +1,48 @@ + +describe "moonscript.transform.statements", -> + describe "last_stm", -> + import last_stm, Run from require "moonscript.transform.statements" + + it "gets last statement from empty list", -> + assert.same nil, (last_stm {}) + + it "gets last statement", -> + stms = { + {"ref", "butt_world"} + {"ref", "hello_world"} + } + + stm, idx, t = last_stm stms + assert stms[2] == stm + assert.same 2, idx + assert stms == t + + it "gets last statement ignoring run", -> + stms = { + {"ref", "butt_world"} + {"ref", "hello_world"} + Run => print "hi" + } + + stm, idx, t = last_stm stms + assert stms[2] == stm + assert.same 2, idx + assert stms == t + + it "gets last from within group", -> + stms = { + {"ref", "butt_world"} + {"group", { + {"ref", "hello_world"} + {"ref", "cool_world"} + }} + } + + last = stms[2][2][2] + + stm, idx, t = last_stm stms + assert stm == last, "should get last" + assert.same 2, idx + assert t == stms[2][2], "should get correct table" + +