From 65dd230959dbab99b52b99fd807534c254fb4ed9 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Wed, 19 Jul 2017 11:05:45 +0800 Subject: add codes. --- MoonParser/moon_ast.cpp | 1718 +++++++++-------------------------------------- 1 file changed, 311 insertions(+), 1407 deletions(-) (limited to 'MoonParser/moon_ast.cpp') diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp index 1595220..41d0c55 100644 --- a/MoonParser/moon_ast.cpp +++ b/MoonParser/moon_ast.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -6,58 +5,7 @@ #include #include #include -#include "parserlib.hpp" -using namespace parserlib; - -template -struct deletable_facet : Facet -{ - template - deletable_facet(Args&& ...args): Facet(std::forward(args)...) {} - ~deletable_facet() {} -}; -typedef std::wstring_convert>, char32_t> Converter; - -static inline std::string& trim(std::string& s) -{ - s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) - { - return !std::isspace(ch); - })); - s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) - { - return !std::isspace(ch); - }).base(), s.end()); - return s; -} - -#define p(expr) user(expr, [](const item_t& item) \ -{ \ - stringstream stream; \ - for (input_it i = item.begin; i != item.end; ++i) stream << static_cast(*i); \ - cout << #expr << ": [" << stream.str() << "]\n"; \ - return true; \ -}) - -struct State -{ - State() - { - indents.push(0); - stringOpen = -1; - } - std::stringstream buffer; - size_t stringOpen; - std::stack indents; - std::stack doStack; - std::unordered_set keywords = { - "and", "while", "else", "using", "continue", - "local", "not", "then", "return", "from", - "extends", "for", "do", "or", "export", - "class", "in", "unless", "when", "elseif", - "switch", "break", "if", "with", "import" - }; -}; +#include "moon_ast.h" class Data { @@ -178,1457 +126,413 @@ private: std::stack _scopeStack; }; -rule Any = any(); -rule plain_space = *set(" \t"); -rule Break = nl(-expr('\r') >> '\n'); -rule White = *(set(" \t") | Break); -rule Stop = Break | eof(); -rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); -rule Indent = *set(" \t"); -rule Space = plain_space >> -Comment; -rule SomeSpace = +set(" \t") >> -Comment; -rule SpaceBreak = Space >> Break; -rule EmptyLine = SpaceBreak; -rule AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_'; -rule _Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum; -rule SpaceName = Space >> _Name; -rule _Num = - ( - "0x" >> - +(range('0', '9') | range('a', 'f') | range('A', 'F')) >> - -(-set("uU") >> set("lL") >> set("lL")) - ) | ( - +range('0', '9') >> -set("uU") >> set("lL") >> set("lL") - ) | ( - ( - (+range('0', '9') >> -('.' >> +range('0', '9'))) | - ('.' >> +range('0', '9')) - ) >> -(set("eE") >> -expr('-') >> +range('0', '9')) - ); -rule Num = Space >> _Num; -rule Cut = false_(); -rule Seperator = true_(); - -#define sym(str) (Space >> str) -#define symx(str) expr(str) -#define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut))) -#define key(str) (Space >> str >> not_(AlphaNum)) -#define opWord(str) (Space >> str >> not_(AlphaNum)) -#define op(str) (Space >> str) - -rule Name = user(SpaceName, [](const item_t& item) -{ - State* st = reinterpret_cast(item.user_data); - for (auto it = item.begin; it != item.end; ++it) st->buffer << static_cast(*it); - std::string name; - st->buffer >> name; - st->buffer.str(""); - st->buffer.clear(); - auto it = st->keywords.find(name); - return it == st->keywords.end(); -}); - -rule self = expr('@'); -rule self_name = '@' >> _Name; -rule self_class = expr("@@"); -rule self_class_name = "@@" >> _Name; - -rule SelfName = Space >> (self_class_name | self_class | self_name | self); -rule KeyName = SelfName | Space >> _Name; -rule VarArg = Space >> "..."; - -rule check_indent = user(Indent, [](const item_t& item) +std::string& trim(std::string& s) { - int indent = 0; - for (input_it i = item.begin; i != item.end; ++i) - { - switch (*i) - { - case ' ': indent++; break; - case '\t': indent += 4; break; - } - } - State* st = reinterpret_cast(item.user_data); - return st->indents.top() == indent; -}); -rule CheckIndent = and_(check_indent); - -rule advance = user(Indent, [](const item_t& item) -{ - int indent = 0; - for (input_it i = item.begin; i != item.end; ++i) + s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { - switch (*i) - { - case ' ': indent++; break; - case '\t': indent += 4; break; - } - } - State* st = reinterpret_cast(item.user_data); - int top = st->indents.top(); - if (top != -1 && indent > top) + return !std::isspace(ch); + })); + s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { - st->indents.push(indent); - return true; - } - return false; -}); -rule Advance = and_(advance); + return !std::isspace(ch); + }).base(), s.end()); + return s; +} -rule push_indent = user(Indent, [](const item_t& item) +const std::string& AstLeaf::getValue() { - int indent = 0; - for (input_it i = item.begin; i != item.end; ++i) + if (_value.empty()) { - switch (*i) + for (auto it = m_begin.m_it; it != m_end.m_it; ++it) { - case ' ': indent++; break; - case '\t': indent += 4; break; + char ch = static_cast(*it); + _value.append(&ch, 1); } + return trim(_value); } - State* st = reinterpret_cast(item.user_data); - st->indents.push(indent); - return true; -}); -rule PushIndent = and_(push_indent); + return _value; +} -rule PreventIndent = user(true_(), [](const item_t& item) +#define AST_IMPL(type) \ + ast __##type##_t(type); + +AST_IMPL(Num) +AST_IMPL(_Name) +AST_IMPL(Name) +AST_IMPL(self) +AST_IMPL(self_name) +AST_IMPL(self_class) +AST_IMPL(self_class_name) +AST_IMPL(SelfName) +AST_IMPL(KeyName) +AST_IMPL(VarArg) +AST_IMPL(local_flag) +AST_IMPL(Seperator) +AST_IMPL(NameList) +AST_IMPL(Local) +AST_IMPL(colon_import_name) +AST_IMPL(ImportName) +AST_IMPL(Import) +AST_IMPL(ExpListLow) +AST_IMPL(ExpList) +AST_IMPL(Return) +AST_IMPL(With) +AST_IMPL(SwitchCase) +AST_IMPL(Switch) +AST_IMPL(IfCond) +AST_IMPL(IfElseIf) +AST_IMPL(If) +AST_IMPL(Unless) +AST_IMPL(While) +AST_IMPL(for_step_value) +AST_IMPL(For) +AST_IMPL(ForEach) +AST_IMPL(Do) +AST_IMPL(Comprehension) +AST_IMPL(comp_value) +AST_IMPL(TblComprehension) +AST_IMPL(star_exp) +AST_IMPL(CompForEach) +AST_IMPL(CompFor) +AST_IMPL(CompClause) +AST_IMPL(CompInner) +AST_IMPL(Assign) +AST_IMPL(update_op) +AST_IMPL(Update) +AST_IMPL(BinaryOperator) +AST_IMPL(Assignable) +AST_IMPL(exp_op_value) +AST_IMPL(Exp) +AST_IMPL(Callable) +AST_IMPL(ChainValue) +AST_IMPL(simple_table) +AST_IMPL(SimpleValue) +AST_IMPL(Chain) +AST_IMPL(Value) +AST_IMPL(LuaString) +AST_IMPL(SingleString) +AST_IMPL(double_string_inner) +AST_IMPL(double_string_content) +AST_IMPL(DoubleString) +AST_IMPL(String) +AST_IMPL(Parens) +AST_IMPL(FnArgs) +AST_IMPL(chain_call) +AST_IMPL(chain_item) +AST_IMPL(DotChainItem) +AST_IMPL(ColonChainItem) +AST_IMPL(chain_dot_chain) +AST_IMPL(ChainItem) +AST_IMPL(ChainItems) +AST_IMPL(invoke_chain) +AST_IMPL(ColonChain) +AST_IMPL(default_value) +AST_IMPL(Slice) +AST_IMPL(Invoke) +AST_IMPL(TableValue) +AST_IMPL(TableLit) +AST_IMPL(TableBlock) +AST_IMPL(class_member_list) +AST_IMPL(ClassLine) +AST_IMPL(ClassBlock) +AST_IMPL(ClassDecl) +AST_IMPL(export_values) +AST_IMPL(export_op) +AST_IMPL(Export) +AST_IMPL(variable_pair) +AST_IMPL(normal_pair) +AST_IMPL(KeyValue) +AST_IMPL(FnArgDef) +AST_IMPL(FnArgDefList) +AST_IMPL(outer_var_shadow) +AST_IMPL(FnArgsDef) +AST_IMPL(fn_arrow) +AST_IMPL(FunLit) +AST_IMPL(NameOrDestructure) +AST_IMPL(AssignableNameList) +AST_IMPL(ArgBlock) +AST_IMPL(invoke_args_with_table) +AST_IMPL(InvokeArgs) +AST_IMPL(const_value) +AST_IMPL(unary_exp) +AST_IMPL(Assignment) +AST_IMPL(if_else_line) +AST_IMPL(unless_line) +AST_IMPL(statement_appendix) +AST_IMPL(BreakLoop) +AST_IMPL(Statement) +AST_IMPL(Body) +AST_IMPL(Line) +AST_IMPL(Block) +AST_IMPL(BlockEnd) + +void Num_t::visit(void* ud) { - State* st = reinterpret_cast(item.user_data); - st->indents.push(-1); - return true; -}); + Data* data = static_cast(ud); + std::string str = data->conv.to_bytes(&*m_begin.m_it, &*m_end.m_it); + data->buffer << trim(str); +} -rule PopIndent = user(true_(), [](const item_t& item) +void _Name_t::visit(void* ud) { - State* st = reinterpret_cast(item.user_data); - st->indents.pop(); - return true; -}); - -extern rule Block; - -rule InBlock = Advance >> Block >> PopIndent; - -extern rule NameList; - -rule local_flag = op('*') | op('^'); -rule Local = key("local") >> (local_flag | NameList); - -rule colon_import_name = sym('\\') >> Name; -rule ImportName = colon_import_name | Name; -rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); - -extern rule Exp; - -rule Import = key("import") >> ImportNameList >> *SpaceBreak >> key("from") >> Exp; -rule BreakLoop = key("break") | key("continue"); - -extern rule ExpListLow, ExpList, Assign; - -rule Return = key("return") >> -ExpListLow; -rule WithExp = ExpList >> -Assign; - -extern rule DisableDo, PopDo, Body; - -rule With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body; -rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body; -rule SwitchElse = key("else") >> Body; - -rule SwitchBlock = *EmptyLine >> - Advance >> Seperator >> - SwitchCase >> - *(+Break >> SwitchCase) >> - -(+Break >> SwitchElse) >> - PopIndent; - -rule Switch = key("switch") >> - DisableDo >> ensure(Exp, PopDo) >> - -key("do") >> -Space >> Break >> SwitchBlock; - -rule IfCond = Exp >> -Assign; -rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body; -rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body; -rule If = key("if") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse; -rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse; - -rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; - -rule for_step_value = sym(',') >> Exp; -rule for_args = Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; - -rule For = key("for") >> DisableDo >> - ensure(for_args, PopDo) >> - -key("do") >> Body; - -extern rule AssignableNameList; - -rule for_in = sym('*') >> Exp | ExpList; - -rule ForEach = key("for") >> AssignableNameList >> key("in") >> - DisableDo >> ensure(for_in, PopDo) >> - -key("do") >> Body; + Data* data = static_cast(ud); + data->buffer << getValue(); +} -rule Do = user(key("do") >> Body, [](const item_t& item) +void Name_t::visit(void* ud) { - State* st = reinterpret_cast(item.user_data); - return st->doStack.empty() || st->doStack.top(); -}); + name->visit(ud); +} -rule DisableDo = user(true_(), [](const item_t& item) +void self_t::visit(void* ud) { - State* st = reinterpret_cast(item.user_data); - st->doStack.push(false); - return true; -}); + Data* data = static_cast(ud); + data->buffer << "self"; +} -rule PopDo = user(true_(), [](const item_t& item) +void self_name_t::visit(void* ud) { - State* st = reinterpret_cast(item.user_data); - st->doStack.pop(); - return true; -}); - -extern rule CompInner; - -rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); -rule comp_value = sym(',') >> Exp; -rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}'); - -extern rule CompForEach, CompFor, CompClause; - -rule CompInner = (CompForEach | CompFor) >> Seperator >> *CompClause; -rule star_exp = sym('*') >> Exp; -rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp); -rule CompFor = key("for") >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; -rule CompClause = CompFor | CompForEach | key("when") >> Exp; - -extern rule TableBlock; - -rule Assign = sym('=') >> (With | If | Switch | TableBlock | ExpListLow); - -rule update_op = - sym("..=") | - sym("+=") | - sym("-=") | - sym("*=") | - sym("/=") | - sym("%=") | - sym("or=") | - sym("and=") | - sym("&=") | - sym("|=") | - sym(">>=") | - sym("<<="); - -rule Update = update_op >> Exp; - -rule CharOperators = Space >> set("+-*/%^><|&"); -rule WordOperators = - opWord("or") | - opWord("and") | - op("<=") | - op(">=") | - op("~=") | - op("!=") | - op("==") | - op("..") | - op("<<") | - op(">>") | - op("//"); - -rule BinaryOperator = (WordOperators | CharOperators) >> *SpaceBreak; - -extern rule Chain; - -rule Assignable = Chain | Name | SelfName; - -extern rule Value; - -rule exp_op_value = BinaryOperator >> Value; -rule Exp = Value >> *exp_op_value; - -extern rule Callable, InvokeArgs; - -rule ChainValue = (Chain | Callable) >> -InvokeArgs; - -extern rule KeyValue, String, SimpleValue; - -rule simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue); -rule Value = SimpleValue | simple_table | ChainValue | String; - -extern rule LuaString; - -rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any; -rule SingleString = symx('\'') >> *single_string_inner >> sym('\''); -rule interp = symx("#{") >> Exp >> sym('}'); -rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any; -rule double_string_inner = +(not_(interp) >> double_string_plain); -rule double_string_content = double_string_inner | interp; -rule DoubleString = symx('"') >> Seperator >> *double_string_content >> sym('"'); -rule String = Space >> (DoubleString | SingleString | LuaString); - -rule lua_string_open = '[' >> *expr('=') >> '['; -rule lua_string_close = ']' >> *expr('=') >> ']'; + Data* data = static_cast(ud); + data->buffer << (data->callerStack.top() ? "self:" : "self."); + name->visit(ud); +} -rule LuaStringOpen = user(lua_string_open, [](const item_t& item) +void self_class_t::visit(void* ud) { - size_t count = std::distance(item.begin, item.end); - State* st = reinterpret_cast(item.user_data); - st->stringOpen = count; - return true; -}); + Data* data = static_cast(ud); + data->buffer << "self.__class"; +} -rule LuaStringClose = user(lua_string_close, [](const item_t& item) +void self_class_name_t::visit(void* ud) { - size_t count = std::distance(item.begin, item.end); - State* st = reinterpret_cast(item.user_data); - return st->stringOpen == count; -}); - -rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any)); + Data* data = static_cast(ud); + data->buffer << (data->callerStack.top() ? "self.__class:" : "self.__class."); + name->visit(ud); +} -rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) +void SelfName_t::visit(void* ud) { - State* st = reinterpret_cast(item.user_data); - st->stringOpen = -1; - return true; -}); - -rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); -rule Callable = Name | SelfName | VarArg | Parens; -rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); - -rule FnArgs = Seperator >> -( - ( - symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')') - ) | ( - sym('!') >> not_(expr('=')) - ) -); - -extern rule ChainItems, DotChainItem, ColonChain; - -rule chain_call = (Callable | String) >> ChainItems; -rule chain_item = not_(set(".\\")) >> ChainItems; -rule chain_dot_chain = DotChainItem >> -ChainItems; - -rule Chain = - chain_call | - chain_item | - Space >> (chain_dot_chain | ColonChain); - -extern rule ChainItem; - -rule chain_with_colon = +ChainItem >> -ColonChain; -rule ChainItems = Seperator >> (chain_with_colon | ColonChain); - -extern rule Invoke, Slice; - -rule Index = symx('[') >> Exp >> sym(']'); -rule ChainItem = Invoke | DotChainItem | Slice | Index; -rule DotChainItem = symx('.') >> _Name; -rule ColonChainItem = symx('\\') >> _Name; -rule invoke_chain = Invoke >> -ChainItems; -rule ColonChain = ColonChainItem >> -invoke_chain; - -rule default_value = true_(); -rule Slice = - symx('[') >> - (Exp | default_value) >> - sym(',') >> - (Exp | default_value) >> - (sym(',') >> Exp | default_value) >> - sym(']'); - -rule Invoke = - FnArgs | - SingleString | - DoubleString | - and_(expr('[')) >> LuaString; - -extern rule TableValueList, TableLitLine; - -rule TableValue = KeyValue | Exp; - -rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(','); - -rule TableLit = - sym('{') >> Seperator >> - -TableValueList >> - -sym(',') >> - -table_lit_lines >> - White >> sym('}'); - -rule TableValueList = TableValue >> *(sym(',') >> TableValue); - -rule TableLitLine = -( - PushIndent >> (TableValueList >> PopIndent | PopIndent) -) | ( - Space -); - -extern rule KeyValueLine; - -rule TableBlockInner = Seperator >> KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine); -rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent); - -extern rule Statement; - -rule class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue); -rule ClassLine = CheckIndent >> (class_member_list | Statement | Exp) >> -sym(','); -rule ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent; - -rule ClassDecl = - key("class") >> not_(expr(':')) >> - -Assignable >> - -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >> - -ClassBlock; - -rule export_values = NameList >> -(sym('=') >> ExpListLow); -rule export_op = op('*') | op('^'); -rule Export = key("export") >> (ClassDecl | export_op | export_values); - -rule variable_pair = sym(':') >> not_(SomeSpace) >> Name; - -rule normal_pair = -( - KeyName | - sym('[') >> Exp >> sym(']') | - Space >> DoubleString | - Space >> SingleString -) >> -symx(':') >> -(Exp | TableBlock | +(SpaceBreak) >> Exp); - -rule KeyValue = variable_pair | normal_pair; - -rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue); -rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); - -rule FnArgDef = (Name | SelfName) >> -(sym('=') >> Exp); - -rule FnArgDefList = Seperator >> -( - ( - FnArgDef >> - *((sym(',') | Break) >> White >> FnArgDef) >> - -((sym(',') | Break) >> White >> VarArg) - ) | ( - VarArg - ) -); - -rule outer_var_shadow = key("using") >> (NameList | Space >> expr("nil")); - -rule FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')'); -rule fn_arrow = sym("->") | sym("=>"); -rule FunLit = -FnArgsDef >> fn_arrow >> -Body; - -rule NameList = Seperator >> Name >> *(sym(',') >> Name); -rule NameOrDestructure = Name | TableLit; -rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure); - -rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp); -rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp); - -rule ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp); -rule ArgBlock = Seperator >> ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent; - -rule invoke_args_with_table = - sym(',') >> - ( - TableBlock | - SpaceBreak >> Advance >> ArgBlock >> -TableBlock - ); - -rule InvokeArgs = - not_(expr('-')) >> - ( - ExpList >> -(invoke_args_with_table | TableBlock) | - TableBlock - ); - -rule const_value = key("nil") | key("true") | key("false"); -rule minus_exp = sym('-') >> not_(SomeSpace) >> Exp; -rule sharp_exp = sym('#') >> Exp; -rule tilde_exp = sym('~') >> Exp; -rule not_exp = key("not") >> Exp; -rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp; - -rule SimpleValue = - const_value | - If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do | - unary_exp | - TblComprehension | TableLit | Comprehension | FunLit | Num; - -rule Assignment = ExpList >> (Update | Assign); - -rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | default_value); -rule unless_line = key("unless") >> Exp; - -rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space; -rule Statement = -( - Import | While | With | For | ForEach | - Switch | Return | Local | Export | BreakLoop | - Assignment | ExpList -) >> Space >> --statement_appendix; - -rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement; - -rule empty_line_stop = Space >> and_(Stop); -rule Line = CheckIndent >> Statement | empty_line_stop; -rule Block = Seperator >> Line >> *(+Break >> Line); -rule BlockEnd = Block >> eof(); + name->visit(ud); +} -class AstLeaf : public ast_node +void KeyName_t::visit(void* ud) { -public: - const std::string& getValue() - { - if (_value.empty()) - { - for (auto it = m_begin.m_it; it != m_end.m_it; ++it) - { - char ch = static_cast(*it); - _value.append(&ch, 1); - } - return trim(_value); - } - return _value; - } -private: - std::string _value; -}; - -#define AST_LEAF(type) \ -class type##_t : public AstLeaf \ -{ \ -public: \ - virtual int get_type() override { return ast_type(); } - -#define AST_NODE(type) \ -class type##_t : public ast_container \ -{ \ -public: \ - virtual int get_type() override { return ast_type(); } - -#define AST_END(type) \ -}; \ -ast __##type##_t(type); - -AST_LEAF(Num) - virtual void visit(void* ud) override - { - Data* data = static_cast(ud); - std::string str = data->conv.to_bytes(&*m_begin.m_it, &*m_end.m_it); - data->buffer << trim(str); - } -AST_END(Num) - -AST_LEAF(_Name) - virtual void visit(void* ud) override - { - Data* data = static_cast(ud); - data->buffer << getValue(); - } -AST_END(_Name) - -AST_NODE(Name) - ast_ptr<_Name_t> name; - virtual void visit(void* ud) override - { - name->visit(ud); - } -AST_END(Name) - -AST_LEAF(self) - virtual void visit(void* ud) override - { - Data* data = static_cast(ud); - data->buffer << "self"; - } -AST_END(self) - -AST_NODE(self_name) - ast_ptr<_Name_t> name; - virtual void visit(void* ud) override - { - Data* data = static_cast(ud); - data->buffer << (data->callerStack.top() ? "self:" : "self."); - name->visit(ud); - } -AST_END(self_name) - -AST_LEAF(self_class) - virtual void visit(void* ud) override - { - Data* data = static_cast(ud); - data->buffer << "self.__class"; - } -AST_END(self_class) - -AST_NODE(self_class_name) - ast_ptr<_Name_t> name; - virtual void visit(void* ud) override - { - Data* data = static_cast(ud); - data->buffer << (data->callerStack.top() ? "self.__class:" : "self.__class."); - name->visit(ud); - } -AST_END(self_class_name) + name->visit(ud); +} -AST_NODE(SelfName) - ast_ptr name; // self_class_name_t | self_class_t | self_name_t | self_t - virtual void visit(void* ud) override - { - name->visit(ud); - } -AST_END(SelfName) +void VarArg_t::visit(void* ud) +{ + Data* data = static_cast(ud); + data->buffer << "..."; +} -AST_NODE(KeyName) - ast_ptr name; // SelfName_t | _Name_t - virtual void visit(void* ud) override - { +void NameList_t::visit(void* ud) +{ + Data* data = static_cast(ud); + auto it = names.objects().begin(); + Name_t* name = *it; + name->visit(ud); + ++it; + for (; it != names.objects().end(); ++it) + { + name = *it; + data->buffer << ", "; name->visit(ud); } -AST_END(KeyName) +} -AST_LEAF(VarArg) - virtual void visit(void* ud) override +void Import_t::visit(void* ud) +{ + Data* data = static_cast(ud); + std::vector> nameItems; + nameItems.reserve(names.objects().size()); + for (ImportName_t* importName : names.objects()) { - Data* data = static_cast(ud); - data->buffer << "..."; + if (Name_t* name = ast_cast(importName->name)) + { + nameItems.push_back(std::make_tuple(&name->name->getValue(), false)); + } + else + { + colon_import_name_t* colonName = ast_cast(importName->name); + nameItems.push_back(std::make_tuple(&colonName->name->name->getValue(), true)); + } } -AST_END(VarArg) - -AST_LEAF(local_flag) -AST_END(local_flag) - -AST_LEAF(Seperator) -AST_END(Seperator) - -AST_NODE(NameList) - ast_ptr sep; - ast_list names; - virtual void visit(void* ud) override + data->buffer << "local "; + for (const auto& item : nameItems) { - Data* data = static_cast(ud); - auto it = names.objects().begin(); - Name_t* name = *it; - name->visit(ud); - ++it; - for (; it != names.objects().end(); ++it) + data->buffer << *std::get<0>(item); + if (&item != &nameItems.back()) { - name = *it; data->buffer << ", "; - name->visit(ud); } } -AST_END(NameList) + data->endLine(); -AST_NODE(Local) - ast_ptr name; // local_flag_t | NameList_t -AST_END(Local) + data->beginLine(); + data->pushScope(); + data->buffer << "do"; + data->endLine(); -AST_NODE(colon_import_name) - ast_ptr name; -AST_END(colon_import_name) + std::string fromObj = data->getNewLocalObj(); -AST_NODE(Exp) - ast_ptr value; - ast_list opValues; -AST_END(Exp) + data->beginLine(); + data->buffer << "local " << fromObj << " = "; + exp->visit(ud); + data->endLine(); -AST_NODE(ImportName) - ast_ptr name; // colon_import_name_t | Name_t -AST_END(ImportName) - -AST_NODE(Import) - ast_ptr sep; - ast_list names; - ast_ptr exp; - virtual void visit(void* ud) override + data->beginLine(); + for (const auto& item : nameItems) { - Data* data = static_cast(ud); - std::vector> nameItems; - nameItems.reserve(names.objects().size()); - for (ImportName_t* importName : names.objects()) - { - if (Name_t* name = ast_cast(importName->name)) - { - nameItems.push_back(std::make_tuple(&name->name->getValue(), false)); - } - else - { - colon_import_name_t* colonName = ast_cast(importName->name); - nameItems.push_back(std::make_tuple(&colonName->name->name->getValue(), true)); - } - } - data->buffer << "local "; - for (const auto& item : nameItems) - { - data->buffer << *std::get<0>(item); - if (&item != &nameItems.back()) - { - data->buffer << ", "; - } - } - data->endLine(); - - data->beginLine(); - data->pushScope(); - data->buffer << "do"; - data->endLine(); - - std::string fromObj = data->getNewLocalObj(); - - data->beginLine(); - data->buffer << "local " << fromObj << " = "; - ((ast_node*)exp.get())->visit(ud); - data->endLine(); - - data->beginLine(); - for (const auto& item : nameItems) + data->buffer << *std::get<0>(item); + if (&item != &nameItems.back()) { - data->buffer << *std::get<0>(item); - if (&item != &nameItems.back()) - { - data->buffer << ", "; - } + data->buffer << ", "; } - data->buffer << " = "; - for (const auto& item : nameItems) + } + data->buffer << " = "; + for (const auto& item : nameItems) + { + if (std::get<1>(item)) { - if (std::get<1>(item)) - { - data->pushScope(); - data->buffer << "(function()"; - data->endLine(); + data->pushScope(); + data->buffer << "(function()"; + data->endLine(); - std::string varBase = data->getNewLocalBase(); + std::string varBase = data->getNewLocalBase(); - data->beginLine(); - data->buffer << "local " << varBase << " = " << fromObj; - data->endLine(); + data->beginLine(); + data->buffer << "local " << varBase << " = " << fromObj; + data->endLine(); - std::string varFn = data->getNewLocalFn(); + std::string varFn = data->getNewLocalFn(); - data->beginLine(); - data->buffer << "local " << varFn << " = " << varBase << '.' << *std::get<0>(item); - data->endLine(); + data->beginLine(); + data->buffer << "local " << varFn << " = " << varBase << '.' << *std::get<0>(item); + data->endLine(); - data->beginLine(); - data->buffer << "return function(...)"; - data->endLine(); + data->beginLine(); + data->buffer << "return function(...)"; + data->endLine(); - data->beginLine(); - data->pushScope(); - data->buffer << varFn << '(' << varBase << ", ...)"; - data->endLine(); + data->beginLine(); + data->pushScope(); + data->buffer << varFn << '(' << varBase << ", ...)"; + data->endLine(); - data->beginLine(); - data->buffer << "end"; - data->popScope(); - data->endLine(); + data->beginLine(); + data->buffer << "end"; + data->popScope(); + data->endLine(); - data->beginLine(); - data->buffer << "end)()"; - data->popScope(); - } - else - { - data->buffer << fromObj << '.' << *std::get<0>(item); - } - if (&item != &nameItems.back()) - { - data->buffer << ", "; - } + data->beginLine(); + data->buffer << "end)()"; + data->popScope(); } - data->endLine(); - - data->beginLine(); - data->buffer << "end"; - data->popScope(); - } -AST_END(Import) - -AST_NODE(ExpListLow) - ast_ptr sep; - ast_list exprs; - virtual void visit(void* ud) override - { - Data* data = static_cast(ud); - for (Exp_t* expr : exprs.objects()) + else { - ((ast_node*)expr)->visit(ud); - if (expr != exprs.objects().back()) - { - data->buffer << ", "; - } + data->buffer << fromObj << '.' << *std::get<0>(item); } - } -AST_END(ExpListLow) - -AST_NODE(ExpList) - ast_ptr sep; - ast_list exprs; - virtual void visit(void* ud) override - { - Data* data = static_cast(ud); - for (Exp_t* expr : exprs.objects()) + if (&item != &nameItems.back()) { - ((ast_node*)expr)->visit(ud); - if (expr != exprs.objects().back()) - { - data->buffer << ", "; - } + data->buffer << ", "; } } -AST_END(ExpList) + data->endLine(); + + data->beginLine(); + data->buffer << "end"; + data->popScope(); +} -AST_NODE(Return) - ast_ptr valueList; - virtual void visit(void* ud) override +void ExpListLow_t::visit(void* ud) +{ + Data* data = static_cast(ud); + for (Exp_t* expr : exprs.objects()) { - Data* data = static_cast(ud); - data->buffer << "return"; - if (valueList && !valueList->exprs.objects().empty()) + expr->visit(ud); + if (expr != exprs.objects().back()) { - data->buffer << ' '; - valueList->visit(ud); + data->buffer << ", "; } } -AST_END(Return) - -class Assign_t; -class Body_t; +} -AST_NODE(With) - ast_ptr valueList; - ast_ptr assigns; - ast_ptr body; - /* - (function() - do - local _with_0 = Something() - _with_0:write("hello world") - return _with_0 - end - end)() - */ - virtual void visit(void* ud) override +void ExpList_t::visit(void* ud) +{ + Data* data = static_cast(ud); + for (Exp_t* expr : exprs.objects()) { - Data* data = static_cast(ud); - for (Exp_t* expr : valueList->exprs.objects()) + expr->visit(ud); + if (expr != exprs.objects().back()) { + data->buffer << ", "; } - ((ast_node*)expr)->visit(ud); - if (expr != exprs.objects().back()) - { - data->buffer << ", "; - } } -AST_END(With) - -AST_NODE(SwitchCase) - ast_ptr valueList; - ast_ptr body; -AST_END(SwitchCase) - -AST_NODE(Switch) - ast_ptr target; - ast_ptr sep; - ast_list branches; - ast_ptr lastBranch; -AST_END(Switch) - -AST_NODE(IfCond) - ast_ptr condition; - ast_ptr assign; -AST_END(IfCond) - -AST_NODE(IfElseIf) - ast_ptr condition; - ast_ptr body; -AST_END(IfElseIf) - -AST_NODE(If) - ast_ptr firstCondition; - ast_ptr firstBody; - ast_ptr sep; - ast_list branches; - ast_ptr lastBranch; -AST_END(If) - -AST_NODE(Unless) - ast_ptr firstCondition; - ast_ptr firstBody; - ast_ptr sep; - ast_list branches; - ast_ptr lastBranch; -AST_END(Unless) - -AST_NODE(While) - ast_ptr condition; - ast_ptr body; -AST_END(While) - -AST_NODE(for_step_value) - ast_ptr value; -AST_END(for_step_value) - -AST_NODE(For) - ast_ptr varName; - ast_ptr startValue; - ast_ptr stopValue; - ast_ptr stepValue; - ast_ptr body; -AST_END(For) - -class AssignableNameList_t; - -AST_NODE(ForEach) - ast_ptr nameList; - ast_ptr loopValue; // Exp_t | ExpList_t - ast_ptr body; -AST_END(ForEach) - -AST_NODE(Do) - ast_ptr body; -AST_END(Do) - -class CompInner_t; - -AST_NODE(Comprehension) - ast_ptr value; - ast_ptr forLoop; -AST_END(Comprehension) - -AST_NODE(comp_value) - ast_ptr value; -AST_END(comp_value) - -AST_NODE(TblComprehension) - ast_ptr key; - ast_ptr value; - ast_ptr forLoop; -AST_END(TblComprehension) - -AST_NODE(star_exp) - ast_ptr value; -AST_END(star_exp) - -AST_NODE(CompForEach) - ast_ptr nameList; - ast_ptr loopValue; // star_exp_t | Exp_t -AST_END(CompForEach) - -AST_NODE(CompFor) - ast_ptr varName; - ast_ptr startValue; - ast_ptr stopValue; - ast_ptr stepValue; -AST_END(CompFor) - -AST_NODE(CompClause) - ast_ptr nestExp; // CompFor_t | CompForEach_t | Exp_t -AST_END(CompClause) - -AST_NODE(CompInner) - ast_ptr compFor; // CompFor_t | CompForEach_t - ast_ptr sep; - ast_list clauses; -AST_END(CompInner) - -class TableBlock_t; - -AST_NODE(Assign) - ast_ptr value; // With_t | If_t | Switch_t | TableBlock_t | ExpListLow_t -AST_END(Assign) - -AST_LEAF(update_op) -AST_END(update_op) - -AST_NODE(Update) - ast_ptr op; - ast_ptr value; -AST_END(Update) - -AST_LEAF(BinaryOperator) -AST_END(BinaryOperator) - -class Chain_t; - -AST_NODE(Assignable) - ast_ptr item; // Chain_t | Name_t | SelfName_t -AST_END(Assignable) - -class Value_t; - -AST_NODE(exp_op_value) - ast_ptr op; - ast_ptr value; -AST_END(exp_op_value) - -AST_NODE(Callable) - ast_ptr item; // Name_t | SelfName_t | VarArg_t | Parens_t -AST_END(Callable) - -class InvokeArgs_t; - -AST_NODE(ChainValue) - ast_ptr caller; // Chain_t | Callable_t - ast_ptr arguments; +} - virtual void visit(void* ud) override +void Return_t::visit(void* ud) +{ + Data* data = static_cast(ud); + data->buffer << "return"; + if (valueList && !valueList->exprs.objects().empty()) { - + data->buffer << ' '; + valueList->visit(ud); } -AST_END(ChainValue) - -class KeyValue_t; - -AST_NODE(simple_table) - ast_ptr sep; - ast_list pairs; -AST_END(simple_table) - -class String_t; - -AST_NODE(SimpleValue) - ast_ptr value; /* - const_value_t | - If_t | Unless_t | Switch_t | With_t | ClassDecl_t | ForEach_t | For_t | While_t | Do_t | - unary_exp_t | - TblComprehension_t | TableLit_t | Comprehension_t | FunLit_t | Num_t; - */ -AST_END(SimpleValue) - -AST_NODE(Chain) - ast_ptr item; // chain_call_t | chain_item_t | chain_dot_chain_t | ColonChain_t -AST_END(Chain) +} -AST_NODE(Value) - ast_ptr item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t - ast_node* getFlattenedNode() +void With_t::visit(void* ud) +{ + Data* data = static_cast(ud); + data->buffer << "return"; + for (Exp_t* expr : valueList->exprs.objects()) { - if (SimpleValue_t* simpleValue = ast_cast(item)) + if (assigns && (!expr->opValues.objects().empty() || expr->value->getFlattened())) { - return simpleValue->value; + throw std::logic_error("left hand expression is not assignable."); } - else if (simple_table_t* simple_table = ast_cast(item)) - { - return simple_table; - } - else if (ChainValue_t* chainValue = ast_cast(item)) - { - if (chainValue->arguments) - { - return chainValue; - } - else - { - if (Chain_t* chain = ast_cast(chainValue->caller)) - { - return chain->item; - } - else if (Callable_t* callable = ast_cast(chainValue->caller)) - { - return callable->item; - } - } - } - return item; - } -AST_END(Value) - -AST_LEAF(LuaString) -AST_END(LuaString) - -AST_LEAF(SingleString) -AST_END(SingleString) - -AST_LEAF(double_string_inner) -AST_END(double_string_inner) - -AST_NODE(double_string_content) - ast_ptr content; // double_string_inner_t | Exp_t -AST_END(double_string_content) - -AST_NODE(DoubleString) - ast_ptr sep; - ast_list segments; -AST_END(DoubleString) - -AST_NODE(String) - ast_ptr str; // DoubleString_t | SingleString_t | LuaString_t -AST_END(String) - -AST_NODE(Parens) - ast_ptr expr; -AST_END(Parens) - -AST_NODE(FnArgs) - ast_ptr sep; - ast_list args; -AST_END(FnArgs) - -class ChainItems_t; - -AST_NODE(chain_call) - ast_ptr caller; // Callable_t | String_t - ast_ptr chain; -AST_END(chain_call) - -AST_NODE(chain_item) - ast_ptr chain; -AST_END(chain_item) - -AST_NODE(DotChainItem) - ast_ptr<_Name_t> name; -AST_END(DotChainItem) - -AST_NODE(ColonChainItem) - ast_ptr<_Name_t> name; -AST_END(ColonChainItem) - -AST_NODE(chain_dot_chain) - ast_ptr caller; - ast_ptr chain; -AST_END(chain_dot_chain) - -class ColonChain_t; - -class Invoke_t; -class Slice_t; - -AST_NODE(ChainItem) - ast_ptr item; // Invoke_t | DotChainItem_t | Slice_t | [Exp_t] -AST_END(ChainItem) - -AST_NODE(ChainItems) - ast_ptr sep; - ast_list simpleChain; - ast_ptr colonChain; -AST_END(ChainItems) - -AST_NODE(invoke_chain) - ast_ptr invoke; - ast_ptr chain; -AST_END(invoke_chain) - -AST_NODE(ColonChain) - ast_ptr colonChain; - ast_ptr invokeChain; -AST_END(ColonChain) - -AST_LEAF(default_value) -AST_END(default_value) - -AST_NODE(Slice) - ast_ptr startValue; // Exp_t | default_value_t - ast_ptr stopValue; // Exp_t | default_value_t - ast_ptr stepValue; // Exp_t | default_value_t -AST_END(Slice) - -AST_NODE(Invoke) - ast_ptr argument; // FnArgs_t | SingleString_t | DoubleString_t | LuaString_t -AST_END(Invoke) - -class KeyValue_t; - -AST_NODE(TableValue) - ast_ptr value; // KeyValue_t | Exp_t -AST_END(TableValue) - -AST_NODE(TableLit) - ast_ptr sep; - ast_list values; -AST_END(TableLit) - -AST_NODE(TableBlock) - ast_ptr sep; - ast_list values; -AST_END(TableBlock) - -AST_NODE(class_member_list) - ast_ptr sep; - ast_list values; -AST_END(class_member_list) - -AST_NODE(ClassLine) - ast_ptr content; // class_member_list_t | Statement_t | Exp_t -AST_END(ClassLine) - -AST_NODE(ClassBlock) - ast_ptr sep; - ast_list lines; -AST_END(ClassBlock) - -AST_NODE(ClassDecl) - ast_ptr name; - ast_ptr extend; - ast_ptr body; -AST_END(ClassDecl) - -AST_NODE(export_values) - ast_ptr nameList; - ast_ptr valueList; -AST_END(export_values) - -AST_LEAF(export_op) -AST_END(export_op) - -AST_NODE(Export) - ast_ptr item; // ClassDecl_t | export_op_t | export_values_t -AST_END(Export) - -AST_NODE(variable_pair) - ast_ptr name; -AST_END(variable_pair) - -AST_NODE(normal_pair) - ast_ptr key; // KeyName_t | [Exp_t] | DoubleString_t | SingleString_t - ast_ptr value; // Exp_t | TableBlock_t -AST_END(normal_pair) - -AST_NODE(KeyValue) - ast_ptr item; // variable_pair_t | normal_pair_t -AST_END(KeyValue) - -AST_NODE(FnArgDef) - ast_ptr name; // Name_t | SelfName_t - ast_ptr defaultValue; -AST_END(FnArgDef) - -AST_NODE(FnArgDefList) - ast_ptr sep; - ast_list definitions; - ast_ptr varArg; -AST_END(FnArgDefList) - -AST_NODE(outer_var_shadow) - ast_ptr varList; -AST_END(outer_var_shadow) - -AST_NODE(FnArgsDef) - ast_ptr defList; - ast_ptr shadowOption; -AST_END(FnArgsDef) - -AST_LEAF(fn_arrow) -AST_END(fn_arrow) - -AST_NODE(FunLit) - ast_ptr argsDef; - ast_ptr arrow; - ast_ptr body; -AST_END(FunLit) - -AST_NODE(NameOrDestructure) - ast_ptr item; // Name_t | TableLit_t -AST_END(NameOrDestructure) - -AST_NODE(AssignableNameList) - ast_ptr sep; - ast_list items; -AST_END(AssignableNameList) - -AST_NODE(ArgBlock) - ast_ptr sep; - ast_list arguments; -AST_END(ArgBlock) - -AST_NODE(invoke_args_with_table) - ast_ptr argBlock; - ast_ptr tableBlock; -AST_END(invoke_args_with_table) - -AST_NODE(InvokeArgs) - ast_ptr argsList; - ast_ptr argsTableBlock; - ast_ptr tableBlock; -AST_END(InvokeArgs) - -AST_LEAF(const_value) -AST_END(const_value) - -AST_NODE(unary_exp) - ast_ptr item; -AST_END(unary_exp) - -AST_NODE(Assignment) - ast_ptr assignable; - ast_ptr target; // Update_t | Assign_t -AST_END(Assignment) - -AST_NODE(if_else_line) - ast_ptr condition; - ast_ptr elseExpr; // Exp_t | default_value_t -AST_END(if_else_line) - -AST_NODE(unless_line) - ast_ptr condition; -AST_END(unless_line) - -AST_NODE(statement_appendix) - ast_ptr item; // if_else_line_t | unless_line_t | CompInner_t -AST_END(statement_appendix) - -AST_LEAF(BreakLoop) -AST_END(BreakLoop) - -AST_NODE(Statement) - ast_ptr content; /* - Import_t | While_t | With_t | For_t | ForEach_t | - Switch_t | Return_t | Local_t | Export_t | BreakLoop_t | - Assignment_t | ExpList_t - */ - ast_ptr appendix; - - virtual void construct(ast_stack& st) override - { - std::wstring_convert>, char32_t> conv; - value = conv.to_bytes(&*m_begin.m_it, &*m_end.m_it); - ast_container::construct(st); + // TODO } - - virtual void visit(void* ud) override + if (valueList && !valueList->exprs.objects().empty()) { - std::cout << value << '\n'; + data->buffer << ' '; + valueList->visit(ud); } - std::string value; -AST_END(Statement) - -class Block_t; +} -AST_NODE(Body) - ast_ptr content; // Block | Statement - virtual void visit(void* ud) override +ast_node* Value_t::getFlattened() +{ + if (SimpleValue_t* simpleValue = ast_cast(item)) { - Data* data = static_cast(ud); - data->pushScope(); - content->visit(ud); - data->popScope(); + return simpleValue->value; } -AST_END(Body) - -AST_NODE(Line) - ast_ptr statment; - int line; - - virtual void construct(ast_stack& st) override + else if (simple_table_t* simple_table = ast_cast(item)) { - ast_container::construct(st); - line = m_begin.m_line; + return simple_table; } - - virtual void visit(void* ud) override + else if (ChainValue_t* chainValue = ast_cast(item)) { - if (statment) + if (chainValue->arguments) { - std::cout << line << ": "; - statment->visit(ud); + return chainValue; } - } -AST_END(Line) - -AST_NODE(Block) - ast_ptr sep; - ast_list lines; - virtual void visit(void* ud) override - { - Data* data = static_cast(ud); - const auto& objs = lines.objects(); - for (auto it = objs.begin(); it != objs.end(); ++it) + else { - Line_t* line = *it; - if (!line->statment) continue; - if (Local_t* local = ast_cast(line->statment->content)) + if (Chain_t* chain = ast_cast(chainValue->caller)) { - if (local_flag_t* local_flag = ast_cast(local->name)) - { - std::vector names; - for (auto cur = it; cur != objs.end(); ++cur) - { - Line_t* item = *cur; - if (!item->statment) continue; - if (Assignment_t* assignment = ast_cast(item->statment->content)) - { - for (Exp_t* expr : assignment->assignable->exprs.objects()) - { - if (ChainValue_t* chainValue = ast_cast(expr->value->item)) - if (Callable_t* callable = ast_cast(chainValue->caller)) - if (Name_t* name = ast_cast(callable->item)) - { - const std::string& value = name->name->getValue(); - if (local_flag->getValue() == "*") - { - names.push_back(&value); - } - else if (std::isupper(value[0])) - { - names.push_back(&value); - } - } - } - } - } - if (!names.empty()) - { - data->beginLine(); - data->buffer << "local "; - auto nameIt = names.begin(); - auto name = *(*nameIt); - data->putLocal(name); - data->buffer << name; - nameIt++; - for (; nameIt != names.end(); ++nameIt) - { - auto name = *(*nameIt); - data->putLocal(name); - data->buffer << ", "; - data->buffer << name; - } - data->endLine(line->m_begin.m_line); - } - } - else - { - NameList_t* nameList = static_cast(local->name.get()); - data->beginLine(); - data->buffer << "local "; - nameList->visit(ud); - for (Name_t* name : nameList->names.objects()) - { - data->putLocal(name->name->getValue()); - } - data->endLine(line->m_begin.m_line); - } + return chain->item; } - else + else if (Callable_t* callable = ast_cast(chainValue->caller)) { - line->visit(ud); + return callable->item; } } } -AST_END(Block) + return item; +} -AST_NODE(BlockEnd) - ast_ptr block; - virtual void visit(void* ud) override - { - Data* data = static_cast(ud); - data->pushScope(); - block->visit(ud); - data->popScope(); - } -AST_END(BlockEnd) +#include int main() { -- cgit v1.2.3-55-g6feb