start simplifying chain ast

This commit is contained in:
leaf corcoran 2015-09-27 00:39:31 -07:00
parent b9efd31af7
commit 8db1006916
10 changed files with 58 additions and 78 deletions

View File

@ -95,7 +95,7 @@ return {
elseif t == "dot" then
return ".", tostring(arg)
elseif t == "colon" then
return ":", arg, chain_item(node[3])
return ":", tostring(arg)
elseif t == "colon_stub" then
return user_error("Uncalled colon stub")
else

View File

@ -64,7 +64,7 @@ string_chars = {
elseif t == "dot"
".", tostring arg
elseif t == "colon"
":", arg, chain_item(node[3])
":", tostring arg
elseif t == "colon_stub"
user_error "Uncalled colon stub"
else

View File

@ -27,10 +27,10 @@ Num = Space * (Num / function(v)
v
}
end)
local Indent, Cut, ensure, extract_line, mark, pos, flatten_or_mark, is_assignable, check_assignable, format_assign, format_single_assign, sym, symx, simple_string, wrap_func_arg, flatten_func, flatten_string_chain, wrap_decorator, check_lua_string, self_assign
local Indent, Cut, ensure, extract_line, mark, pos, flatten_or_mark, is_assignable, check_assignable, format_assign, format_single_assign, sym, symx, simple_string, wrap_func_arg, join_chain, flatten_string_chain, wrap_decorator, check_lua_string, self_assign
do
local _obj_0 = require("moonscript.parse.util")
Indent, Cut, ensure, extract_line, mark, pos, flatten_or_mark, is_assignable, check_assignable, format_assign, format_single_assign, sym, symx, simple_string, wrap_func_arg, flatten_func, flatten_string_chain, wrap_decorator, check_lua_string, self_assign = _obj_0.Indent, _obj_0.Cut, _obj_0.ensure, _obj_0.extract_line, _obj_0.mark, _obj_0.pos, _obj_0.flatten_or_mark, _obj_0.is_assignable, _obj_0.check_assignable, _obj_0.format_assign, _obj_0.format_single_assign, _obj_0.sym, _obj_0.symx, _obj_0.simple_string, _obj_0.wrap_func_arg, _obj_0.flatten_func, _obj_0.flatten_string_chain, _obj_0.wrap_decorator, _obj_0.check_lua_string, _obj_0.self_assign
Indent, Cut, ensure, extract_line, mark, pos, flatten_or_mark, is_assignable, check_assignable, format_assign, format_single_assign, sym, symx, simple_string, wrap_func_arg, join_chain, flatten_string_chain, wrap_decorator, check_lua_string, self_assign = _obj_0.Indent, _obj_0.Cut, _obj_0.ensure, _obj_0.extract_line, _obj_0.mark, _obj_0.pos, _obj_0.flatten_or_mark, _obj_0.is_assignable, _obj_0.check_assignable, _obj_0.format_assign, _obj_0.format_single_assign, _obj_0.sym, _obj_0.symx, _obj_0.simple_string, _obj_0.wrap_func_arg, _obj_0.join_chain, _obj_0.flatten_string_chain, _obj_0.wrap_decorator, _obj_0.check_lua_string, _obj_0.self_assign
end
local build_grammar = wrap_env(debug_grammar, function(root)
local _indent = Stack(0)
@ -148,13 +148,12 @@ local build_grammar = wrap_env(debug_grammar, function(root)
CharOperators = Space * C(S("+-*/%^><")),
WordOperators = op("or") + op("and") + op("<=") + op(">=") + op("~=") + op("!=") + op("==") + op(".."),
BinaryOperator = (WordOperators + CharOperators) * SpaceBreak ^ 0,
Assignable = Cmt(DotChain + Chain, check_assignable) + Name + SelfName,
Assignable = Cmt(Chain, check_assignable) + Name + SelfName,
Exp = Ct(Value * (BinaryOperator * Value) ^ 0) / flatten_or_mark("exp"),
SimpleValue = If + Unless + Switch + With + ClassDecl + ForEach + For + While + Cmt(Do, check_do) + sym("-") * -SomeSpace * Exp / mark("minus") + sym("#") * Exp / mark("length") + key("not") * Exp / mark("not") + TblComprehension + TableLit + Comprehension + FunLit + Num,
ChainValue = StringChain + ((Chain + DotChain + Callable) * Ct(InvokeArgs ^ -1)) / flatten_func,
Value = pos(SimpleValue + Ct(KeyValueList) / mark("table") + ChainValue),
ChainValue = (Chain + Callable) * Ct(InvokeArgs ^ -1) / join_chain,
Value = pos(SimpleValue + Ct(KeyValueList) / mark("table") + ChainValue + String),
SliceValue = SimpleValue + ChainValue,
StringChain = String * (Ct((ColonCall + ColonSuffix) * ChainTail ^ -1) * Ct(InvokeArgs ^ -1)) ^ -1 / flatten_string_chain,
String = Space * DoubleString + Space * SingleString + LuaString,
SingleString = simple_string("'"),
DoubleString = simple_string('"', true),
@ -164,13 +163,11 @@ local build_grammar = wrap_env(debug_grammar, function(root)
Callable = pos(Name / mark("ref")) + SelfName + VarArg + Parens / mark("parens"),
Parens = sym("(") * SpaceBreak ^ 0 * Exp * SpaceBreak ^ 0 * sym(")"),
FnArgs = symx("(") * SpaceBreak ^ 0 * Ct(ExpList ^ -1) * SpaceBreak ^ 0 * sym(")") + sym("!") * -P("=") * Ct(""),
ChainTail = ChainItem ^ 1 * ColonSuffix ^ -1 + ColonSuffix,
Chain = Callable * ChainTail / mark("chain"),
DotChain = (sym(".") * Cc(-1) * (_Name / mark("dot")) * ChainTail ^ -1) / mark("chain") + (sym("\\") * Cc(-1) * ((_Name * Invoke / mark("colon")) * ChainTail ^ -1 + (_Name / mark("colon_stub")))) / mark("chain"),
ChainItem = Invoke + Slice + symx("[") * Exp / mark("index") * sym("]") + symx(".") * _Name / mark("dot") + ColonCall,
Chain = (Callable + String + -S(".\\")) * ChainItems / mark("chain"),
ChainItems = ChainItem ^ 1 * ColonChainItem ^ -1 + ColonChainItem,
ChainItem = Invoke + symx(".") * _Name / mark("dot") + Slice + symx("[") * Exp / mark("index") * sym("]"),
ColonChainItem = symx("\\") * _Name / mark("colon") * (Invoke * ChainItems ^ -1) ^ -1,
Slice = symx("[") * (SliceValue + Cc(1)) * sym(",") * (SliceValue + Cc("")) * (sym(",") * SliceValue) ^ -1 * sym("]") / mark("slice"),
ColonCall = symx("\\") * (_Name * Invoke) / mark("colon"),
ColonSuffix = symx("\\") * _Name / mark("colon_stub"),
Invoke = FnArgs / mark("call") + SingleString / wrap_func_arg + DoubleString / wrap_func_arg + #P("[") * LuaString / wrap_func_arg,
TableValue = KeyValue + Ct(Exp),
TableLit = sym("{") * Ct(TableValueList ^ -1 * sym(",") ^ -1 * (SpaceBreak * TableLitLine * (sym(",") ^ -1 * SpaceBreak * TableLitLine) ^ 0 * sym(",") ^ -1) ^ -1) * White * sym("}") / mark("table"),

View File

@ -3,6 +3,7 @@ lpeg = require "lpeg"
lpeg.setmaxstack 10000 -- whoa
err_msg = "Failed to parse:%s\n [%d] >> %s"
import Stack from require "moonscript.data"
@ -27,7 +28,7 @@ Num = Space * (Num / (v) -> {"number", v})
{
:Indent, :Cut, :ensure, :extract_line, :mark, :pos, :flatten_or_mark,
:is_assignable, :check_assignable, :format_assign, :format_single_assign,
:sym, :symx, :simple_string, :wrap_func_arg, :flatten_func,
:sym, :symx, :simple_string, :wrap_func_arg, :join_chain,
:flatten_string_chain, :wrap_decorator, :check_lua_string, :self_assign
} = require "moonscript.parse.util"
@ -183,7 +184,7 @@ build_grammar = wrap_env debug_grammar, (root) ->
WordOperators: op"or" + op"and" + op"<=" + op">=" + op"~=" + op"!=" + op"==" + op".."
BinaryOperator: (WordOperators + CharOperators) * SpaceBreak^0
Assignable: Cmt(DotChain + Chain, check_assignable) + Name + SelfName
Assignable: Cmt(Chain, check_assignable) + Name + SelfName
Exp: Ct(Value * (BinaryOperator * Value)^0) / flatten_or_mark"exp"
SimpleValue:
@ -202,20 +203,17 @@ build_grammar = wrap_env debug_grammar, (root) ->
FunLit +
Num
ChainValue: -- a function call or an object access
StringChain +
((Chain + DotChain + Callable) * Ct(InvokeArgs^-1)) / flatten_func
-- a function call or an object access
ChainValue: (Chain + Callable) * Ct(InvokeArgs^-1) / join_chain
Value: pos(
SimpleValue +
Ct(KeyValueList) / mark"table" +
ChainValue)
ChainValue +
String)
SliceValue: SimpleValue + ChainValue
StringChain: String *
(Ct((ColonCall + ColonSuffix) * ChainTail^-1) * Ct(InvokeArgs^-1))^-1 / flatten_string_chain
String: Space * DoubleString + Space * SingleString + LuaString
SingleString: simple_string("'")
DoubleString: simple_string('"', true)
@ -232,33 +230,23 @@ build_grammar = wrap_env debug_grammar, (root) ->
FnArgs: symx"(" * SpaceBreak^0 * Ct(ExpList^-1) * SpaceBreak^0 * sym")" + sym"!" * -P"=" * Ct""
ChainTail: ChainItem^1 * ColonSuffix^-1 + ColonSuffix
-- a list of funcalls and indexes on a callable
Chain: Callable * ChainTail / mark"chain"
Chain: (Callable + String + -S".\\") * ChainItems / mark"chain"
-- shorthand dot call for use in with statement
DotChain:
(sym"." * Cc(-1) * (_Name / mark"dot") * ChainTail^-1) / mark"chain" +
(sym"\\" * Cc(-1) * (
(_Name * Invoke / mark"colon") * ChainTail^-1 +
(_Name / mark"colon_stub")
)) / mark"chain"
ChainItems: ChainItem^1 * ColonChainItem^-1 + ColonChainItem
ChainItem:
Invoke +
Slice +
symx"[" * Exp/mark"index" * sym"]" +
symx"." * _Name/mark"dot" +
ColonCall
Slice +
symx"[" * Exp/mark"index" * sym"]"
ColonChainItem: symx"\\" * _Name / mark"colon" * (Invoke * ChainItems^-1)^-1
Slice: symx"[" * (SliceValue + Cc(1)) * sym"," * (SliceValue + Cc"") *
(sym"," * SliceValue)^-1 *sym"]" / mark"slice"
ColonCall: symx"\\" * (_Name * Invoke) / mark"colon"
ColonSuffix: symx"\\" * _Name / mark"colon_stub"
Invoke: FnArgs/mark"call" +
Invoke: FnArgs / mark"call" +
SingleString / wrap_func_arg +
DoubleString / wrap_func_arg +
#P"[" * LuaString / wrap_func_arg
@ -314,6 +302,7 @@ build_grammar = wrap_env debug_grammar, (root) ->
ExpList: Exp * (sym"," * Exp)^0
ExpListLow: Exp * ((sym"," + sym";") * Exp)^0
-- open args
InvokeArgs: -P"-" * (ExpList * (sym"," * (TableBlock + SpaceBreak * Advance * ArgBlock * TableBlock^-1) + TableBlock)^-1 + TableBlock)
ArgBlock: ArgLine * (sym"," * SpaceBreak * ArgLine)^0 * PopIndent
ArgLine: CheckIndent * ExpList

View File

@ -178,8 +178,8 @@ wrap_func_arg = function(value)
}
}
end
local flatten_func
flatten_func = function(callee, args)
local join_chain
join_chain = function(callee, args)
if #args == 0 then
return callee
end
@ -188,13 +188,7 @@ flatten_func = function(callee, args)
args
}
if ntype(callee) == "chain" then
local stub = callee[#callee]
if ntype(stub) == "colon_stub" then
stub[1] = "colon"
table.insert(stub, args)
else
table.insert(callee, args)
end
return callee
end
return {
@ -208,7 +202,7 @@ flatten_string_chain = function(str, chain, args)
if not (chain) then
return str
end
return flatten_func({
return flatten_chain({
"chain",
str,
unpack(chain)
@ -259,7 +253,7 @@ return {
symx = symx,
simple_string = simple_string,
wrap_func_arg = wrap_func_arg,
flatten_func = flatten_func,
join_chain = join_chain,
flatten_string_chain = flatten_string_chain,
wrap_decorator = wrap_decorator,
check_lua_string = check_lua_string,

View File

@ -127,27 +127,21 @@ simple_string = (delim, allow_interpolation) ->
-- wraps a single value in format needed to be passed as function arguments
wrap_func_arg = (value) -> {"call", {value}}
-- flatten out the parsed function node
flatten_func = (callee, args) ->
-- chains are parsed in two captures, the chain and then the open arguments
-- if there are open arguments, then append them to the end of the chain as a call
join_chain = (callee, args) ->
return callee if #args == 0
args = {"call", args}
if ntype(callee) == "chain"
-- check for colon stub needing arguments
stub = callee[#callee]
if ntype(stub) == "colon_stub"
stub[1] = "colon"
table.insert stub, args
else
table.insert callee, args
return callee
{"chain", callee, args}
flatten_string_chain = (str, chain, args) ->
return str unless chain
flatten_func {"chain", str, unpack chain}, args
flatten_chain {"chain", str, unpack chain}, args
-- constructor for decorator node
wrap_decorator = (stm, dec) ->
@ -163,5 +157,5 @@ self_assign = (name, pos) ->
{ :Indent, :Cut, :ensure, :extract_line, :mark, :pos, :flatten_or_mark,
:is_assignable, :check_assignable, :format_assign, :format_single_assign,
:sym, :symx, :simple_string, :wrap_func_arg, :flatten_func,
:sym, :symx, :simple_string, :wrap_func_arg, :join_chain,
:flatten_string_chain, :wrap_decorator, :check_lua_string, :self_assign }

View File

@ -12,10 +12,10 @@ do
local _obj_0 = require("moonscript.transform.names")
NameProxy, LocalName = _obj_0.NameProxy, _obj_0.LocalName
end
local Run, transform_last_stm, last_stm
local Run, transform_last_stm, last_stm, chain_is_stub
do
local _obj_0 = require("moonscript.transform.statements")
Run, transform_last_stm, last_stm = _obj_0.Run, _obj_0.transform_last_stm, _obj_0.last_stm
Run, transform_last_stm, last_stm, chain_is_stub = _obj_0.Run, _obj_0.transform_last_stm, _obj_0.last_stm, _obj_0.chain_is_stub
end
local destructure = require("moonscript.transform.destructure")
local NOOP = {
@ -1498,7 +1498,6 @@ Value = Transformer({
})
end,
chain = function(self, node)
local stub = node[#node]
for i = 3, #node do
local part = node[i]
if ntype(part) == "dot" and data.lua_keywords[part[2]] then
@ -1517,10 +1516,11 @@ Value = Transformer({
"parens",
node[2]
}
elseif type(stub) == "table" and stub[1] == "colon_stub" then
table.remove(node, #node)
end
if chain_is_stub(node) then
local base_name = NameProxy("base")
local fn_name = NameProxy("fn")
local colon = table.remove(node)
local is_super = ntype(node[2]) == "ref" and node[2][2] == "super"
return build.block_exp({
build.assign({
@ -1540,7 +1540,7 @@ Value = Transformer({
base = base_name,
{
"dot",
stub[2]
colon[2]
}
})
}

View File

@ -8,7 +8,7 @@ import ntype, mtype, build, smart_node, is_slice, value_is_singular from types
import insert from table
import NameProxy, LocalName from require "moonscript.transform.names"
import Run, transform_last_stm, last_stm from require "moonscript.transform.statements"
import Run, transform_last_stm, last_stm, chain_is_stub from require "moonscript.transform.statements"
destructure = require "moonscript.transform.destructure"
NOOP = {"noop"}
@ -910,8 +910,6 @@ Value = Transformer {
-- pull out colon chain
chain: (node) =>
stub = node[#node]
-- escape lua keywords used in dot accessors
for i=3,#node
part = node[i]
@ -921,12 +919,11 @@ Value = Transformer {
if ntype(node[2]) == "string"
-- add parens if callee is raw string
node[2] = {"parens", node[2] }
elseif type(stub) == "table" and stub[1] == "colon_stub"
-- convert colon stub into code
table.remove node, #node
if chain_is_stub node
base_name = NameProxy "base"
fn_name = NameProxy "fn"
colon = table.remove node
is_super = ntype(node[2]) == "ref" and node[2][2] == "super"
build.block_exp {
@ -938,7 +935,7 @@ Value = Transformer {
build.assign {
names: {fn_name}
values: {
build.chain { base: base_name, {"dot", stub[2]} }
build.chain { base: base_name, {"dot", colon[2]} }
}
}

View File

@ -68,8 +68,14 @@ transform_last_stm = function(stms, fn)
return _accum_0
end)()
end
local chain_is_stub
chain_is_stub = function(chain)
local stub = chain[#chain]
return stub and ntype(stub) == "colon"
end
return {
Run = Run,
last_stm = last_stm,
transform_last_stm = transform_last_stm
transform_last_stm = transform_last_stm,
chain_is_stub = chain_is_stub
}

View File

@ -40,6 +40,9 @@ transform_last_stm = (stms, fn) ->
else
stm
chain_is_stub = (chain) ->
stub = chain[#chain]
stub and ntype(stub) == "colon"
{:Run, :last_stm, :transform_last_stm}
{:Run, :last_stm, :transform_last_stm, :chain_is_stub}