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 elseif t == "dot" then
return ".", tostring(arg) return ".", tostring(arg)
elseif t == "colon" then elseif t == "colon" then
return ":", arg, chain_item(node[3]) return ":", tostring(arg)
elseif t == "colon_stub" then elseif t == "colon_stub" then
return user_error("Uncalled colon stub") return user_error("Uncalled colon stub")
else else

View File

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

View File

@ -27,10 +27,10 @@ Num = Space * (Num / function(v)
v v
} }
end) 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 do
local _obj_0 = require("moonscript.parse.util") 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 end
local build_grammar = wrap_env(debug_grammar, function(root) local build_grammar = wrap_env(debug_grammar, function(root)
local _indent = Stack(0) local _indent = Stack(0)
@ -148,13 +148,12 @@ local build_grammar = wrap_env(debug_grammar, function(root)
CharOperators = Space * C(S("+-*/%^><")), CharOperators = Space * C(S("+-*/%^><")),
WordOperators = op("or") + op("and") + op("<=") + op(">=") + op("~=") + op("!=") + op("==") + op(".."), WordOperators = op("or") + op("and") + op("<=") + op(">=") + op("~=") + op("!=") + op("==") + op(".."),
BinaryOperator = (WordOperators + CharOperators) * SpaceBreak ^ 0, 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"), 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, 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, ChainValue = (Chain + Callable) * Ct(InvokeArgs ^ -1) / join_chain,
Value = pos(SimpleValue + Ct(KeyValueList) / mark("table") + ChainValue), Value = pos(SimpleValue + Ct(KeyValueList) / mark("table") + ChainValue + String),
SliceValue = SimpleValue + ChainValue, SliceValue = SimpleValue + ChainValue,
StringChain = String * (Ct((ColonCall + ColonSuffix) * ChainTail ^ -1) * Ct(InvokeArgs ^ -1)) ^ -1 / flatten_string_chain,
String = Space * DoubleString + Space * SingleString + LuaString, String = Space * DoubleString + Space * SingleString + LuaString,
SingleString = simple_string("'"), SingleString = simple_string("'"),
DoubleString = simple_string('"', true), 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"), Callable = pos(Name / mark("ref")) + SelfName + VarArg + Parens / mark("parens"),
Parens = sym("(") * SpaceBreak ^ 0 * Exp * SpaceBreak ^ 0 * sym(")"), Parens = sym("(") * SpaceBreak ^ 0 * Exp * SpaceBreak ^ 0 * sym(")"),
FnArgs = symx("(") * SpaceBreak ^ 0 * Ct(ExpList ^ -1) * SpaceBreak ^ 0 * sym(")") + sym("!") * -P("=") * Ct(""), FnArgs = symx("(") * SpaceBreak ^ 0 * Ct(ExpList ^ -1) * SpaceBreak ^ 0 * sym(")") + sym("!") * -P("=") * Ct(""),
ChainTail = ChainItem ^ 1 * ColonSuffix ^ -1 + ColonSuffix, Chain = (Callable + String + -S(".\\")) * ChainItems / mark("chain"),
Chain = Callable * ChainTail / mark("chain"), ChainItems = ChainItem ^ 1 * ColonChainItem ^ -1 + ColonChainItem,
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 + symx(".") * _Name / mark("dot") + Slice + symx("[") * Exp / mark("index") * sym("]"),
ChainItem = Invoke + Slice + symx("[") * Exp / mark("index") * sym("]") + symx(".") * _Name / mark("dot") + ColonCall, ColonChainItem = symx("\\") * _Name / mark("colon") * (Invoke * ChainItems ^ -1) ^ -1,
Slice = symx("[") * (SliceValue + Cc(1)) * sym(",") * (SliceValue + Cc("")) * (sym(",") * SliceValue) ^ -1 * sym("]") / mark("slice"), 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, Invoke = FnArgs / mark("call") + SingleString / wrap_func_arg + DoubleString / wrap_func_arg + #P("[") * LuaString / wrap_func_arg,
TableValue = KeyValue + Ct(Exp), 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"), 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 lpeg.setmaxstack 10000 -- whoa
err_msg = "Failed to parse:%s\n [%d] >> %s" err_msg = "Failed to parse:%s\n [%d] >> %s"
import Stack from require "moonscript.data" 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, :Indent, :Cut, :ensure, :extract_line, :mark, :pos, :flatten_or_mark,
:is_assignable, :check_assignable, :format_assign, :format_single_assign, :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 :flatten_string_chain, :wrap_decorator, :check_lua_string, :self_assign
} = require "moonscript.parse.util" } = 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".." WordOperators: op"or" + op"and" + op"<=" + op">=" + op"~=" + op"!=" + op"==" + op".."
BinaryOperator: (WordOperators + CharOperators) * SpaceBreak^0 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" Exp: Ct(Value * (BinaryOperator * Value)^0) / flatten_or_mark"exp"
SimpleValue: SimpleValue:
@ -202,20 +203,17 @@ build_grammar = wrap_env debug_grammar, (root) ->
FunLit + FunLit +
Num Num
ChainValue: -- a function call or an object access -- a function call or an object access
StringChain + ChainValue: (Chain + Callable) * Ct(InvokeArgs^-1) / join_chain
((Chain + DotChain + Callable) * Ct(InvokeArgs^-1)) / flatten_func
Value: pos( Value: pos(
SimpleValue + SimpleValue +
Ct(KeyValueList) / mark"table" + Ct(KeyValueList) / mark"table" +
ChainValue) ChainValue +
String)
SliceValue: SimpleValue + ChainValue SliceValue: SimpleValue + ChainValue
StringChain: String *
(Ct((ColonCall + ColonSuffix) * ChainTail^-1) * Ct(InvokeArgs^-1))^-1 / flatten_string_chain
String: Space * DoubleString + Space * SingleString + LuaString String: Space * DoubleString + Space * SingleString + LuaString
SingleString: simple_string("'") SingleString: simple_string("'")
DoubleString: simple_string('"', true) 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"" 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 -- 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 ChainItems: ChainItem^1 * ColonChainItem^-1 + ColonChainItem
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: ChainItem:
Invoke + Invoke +
Slice +
symx"[" * Exp/mark"index" * sym"]" +
symx"." * _Name/mark"dot" + 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"") * Slice: symx"[" * (SliceValue + Cc(1)) * sym"," * (SliceValue + Cc"") *
(sym"," * SliceValue)^-1 *sym"]" / mark"slice" (sym"," * SliceValue)^-1 *sym"]" / mark"slice"
ColonCall: symx"\\" * (_Name * Invoke) / mark"colon" Invoke: FnArgs / mark"call" +
ColonSuffix: symx"\\" * _Name / mark"colon_stub"
Invoke: FnArgs/mark"call" +
SingleString / wrap_func_arg + SingleString / wrap_func_arg +
DoubleString / wrap_func_arg + DoubleString / wrap_func_arg +
#P"[" * LuaString / wrap_func_arg #P"[" * LuaString / wrap_func_arg
@ -314,6 +302,7 @@ build_grammar = wrap_env debug_grammar, (root) ->
ExpList: Exp * (sym"," * Exp)^0 ExpList: Exp * (sym"," * Exp)^0
ExpListLow: Exp * ((sym"," + sym";") * Exp)^0 ExpListLow: Exp * ((sym"," + sym";") * Exp)^0
-- open args
InvokeArgs: -P"-" * (ExpList * (sym"," * (TableBlock + SpaceBreak * Advance * ArgBlock * TableBlock^-1) + TableBlock)^-1 + TableBlock) InvokeArgs: -P"-" * (ExpList * (sym"," * (TableBlock + SpaceBreak * Advance * ArgBlock * TableBlock^-1) + TableBlock)^-1 + TableBlock)
ArgBlock: ArgLine * (sym"," * SpaceBreak * ArgLine)^0 * PopIndent ArgBlock: ArgLine * (sym"," * SpaceBreak * ArgLine)^0 * PopIndent
ArgLine: CheckIndent * ExpList ArgLine: CheckIndent * ExpList

View File

@ -178,8 +178,8 @@ wrap_func_arg = function(value)
} }
} }
end end
local flatten_func local join_chain
flatten_func = function(callee, args) join_chain = function(callee, args)
if #args == 0 then if #args == 0 then
return callee return callee
end end
@ -188,13 +188,7 @@ flatten_func = function(callee, args)
args args
} }
if ntype(callee) == "chain" then 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) table.insert(callee, args)
end
return callee return callee
end end
return { return {
@ -208,7 +202,7 @@ flatten_string_chain = function(str, chain, args)
if not (chain) then if not (chain) then
return str return str
end end
return flatten_func({ return flatten_chain({
"chain", "chain",
str, str,
unpack(chain) unpack(chain)
@ -259,7 +253,7 @@ return {
symx = symx, symx = symx,
simple_string = simple_string, simple_string = simple_string,
wrap_func_arg = wrap_func_arg, wrap_func_arg = wrap_func_arg,
flatten_func = flatten_func, join_chain = join_chain,
flatten_string_chain = flatten_string_chain, flatten_string_chain = flatten_string_chain,
wrap_decorator = wrap_decorator, wrap_decorator = wrap_decorator,
check_lua_string = check_lua_string, 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 -- wraps a single value in format needed to be passed as function arguments
wrap_func_arg = (value) -> {"call", {value}} wrap_func_arg = (value) -> {"call", {value}}
-- flatten out the parsed function node -- chains are parsed in two captures, the chain and then the open arguments
flatten_func = (callee, args) -> -- 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 return callee if #args == 0
args = {"call", args} args = {"call", args}
if ntype(callee) == "chain" 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 table.insert callee, args
return callee return callee
{"chain", callee, args} {"chain", callee, args}
flatten_string_chain = (str, chain, args) -> flatten_string_chain = (str, chain, args) ->
return str unless chain return str unless chain
flatten_func {"chain", str, unpack chain}, args flatten_chain {"chain", str, unpack chain}, args
-- constructor for decorator node -- constructor for decorator node
wrap_decorator = (stm, dec) -> wrap_decorator = (stm, dec) ->
@ -163,5 +157,5 @@ self_assign = (name, pos) ->
{ :Indent, :Cut, :ensure, :extract_line, :mark, :pos, :flatten_or_mark, { :Indent, :Cut, :ensure, :extract_line, :mark, :pos, :flatten_or_mark,
:is_assignable, :check_assignable, :format_assign, :format_single_assign, :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 } :flatten_string_chain, :wrap_decorator, :check_lua_string, :self_assign }

View File

@ -12,10 +12,10 @@ do
local _obj_0 = require("moonscript.transform.names") local _obj_0 = require("moonscript.transform.names")
NameProxy, LocalName = _obj_0.NameProxy, _obj_0.LocalName NameProxy, LocalName = _obj_0.NameProxy, _obj_0.LocalName
end end
local Run, transform_last_stm, last_stm local Run, transform_last_stm, last_stm, chain_is_stub
do do
local _obj_0 = require("moonscript.transform.statements") 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 end
local destructure = require("moonscript.transform.destructure") local destructure = require("moonscript.transform.destructure")
local NOOP = { local NOOP = {
@ -1498,7 +1498,6 @@ Value = Transformer({
}) })
end, end,
chain = function(self, node) chain = function(self, node)
local stub = node[#node]
for i = 3, #node do for i = 3, #node do
local part = node[i] local part = node[i]
if ntype(part) == "dot" and data.lua_keywords[part[2]] then if ntype(part) == "dot" and data.lua_keywords[part[2]] then
@ -1517,10 +1516,11 @@ Value = Transformer({
"parens", "parens",
node[2] node[2]
} }
elseif type(stub) == "table" and stub[1] == "colon_stub" then end
table.remove(node, #node) if chain_is_stub(node) then
local base_name = NameProxy("base") local base_name = NameProxy("base")
local fn_name = NameProxy("fn") local fn_name = NameProxy("fn")
local colon = table.remove(node)
local is_super = ntype(node[2]) == "ref" and node[2][2] == "super" local is_super = ntype(node[2]) == "ref" and node[2][2] == "super"
return build.block_exp({ return build.block_exp({
build.assign({ build.assign({
@ -1540,7 +1540,7 @@ Value = Transformer({
base = base_name, base = base_name,
{ {
"dot", "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 insert from table
import NameProxy, LocalName from require "moonscript.transform.names" 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" destructure = require "moonscript.transform.destructure"
NOOP = {"noop"} NOOP = {"noop"}
@ -910,8 +910,6 @@ Value = Transformer {
-- pull out colon chain -- pull out colon chain
chain: (node) => chain: (node) =>
stub = node[#node]
-- escape lua keywords used in dot accessors -- escape lua keywords used in dot accessors
for i=3,#node for i=3,#node
part = node[i] part = node[i]
@ -921,12 +919,11 @@ Value = Transformer {
if ntype(node[2]) == "string" if ntype(node[2]) == "string"
-- add parens if callee is raw string -- add parens if callee is raw string
node[2] = {"parens", node[2] } 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" base_name = NameProxy "base"
fn_name = NameProxy "fn" fn_name = NameProxy "fn"
colon = table.remove node
is_super = ntype(node[2]) == "ref" and node[2][2] == "super" is_super = ntype(node[2]) == "ref" and node[2][2] == "super"
build.block_exp { build.block_exp {
@ -938,7 +935,7 @@ Value = Transformer {
build.assign { build.assign {
names: {fn_name} names: {fn_name}
values: { 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 return _accum_0
end)() end)()
end end
local chain_is_stub
chain_is_stub = function(chain)
local stub = chain[#chain]
return stub and ntype(stub) == "colon"
end
return { return {
Run = Run, Run = Run,
last_stm = last_stm, 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 else
stm 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}