mirror of
https://github.com/leafo/moonscript.git
synced 2025-01-09 00:04:22 +00:00
start simplifying chain ast
This commit is contained in:
parent
b9efd31af7
commit
8db1006916
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"),
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 }
|
||||
|
@ -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]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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]} }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user