diff --git a/src/include/parser.h b/src/include/parser.h index 38b2cbf..56ef39a 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -72,6 +72,11 @@ ParseReturn parse_unary(vector tokens); */ ParseReturn parse_val(vector tokens); +/** + * Parse Arguments of a function call +*/ +ParseReturn parse_args_values(vector tokens); + /** * Parse something derivated from ParIdentifier * (An identifier with 0+ parentheses around it) diff --git a/src/include/types.h b/src/include/types.h index b2fba99..8b94074 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -163,6 +163,7 @@ enum class NodeType { FunctionDeclaration, // -> Type ParIdentifier ( Args ) { Prog } FunctionCall, // -> ParIdentifier ( Expr ) FunctionArgs, // -> Type ParIdentifier, Args | Type ParIdentifier | void + FunctionArgsValues, // as Expr, but returns a vector of comp instead of a tree Return, // -> Return ; | Return Expr ; }; diff --git a/src/parser.cpp b/src/parser.cpp index fab176a..1be0b1d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -19,7 +19,7 @@ const char* _debug_ast_node_names[] = { "Prog", "Epsilon", "AssignedDeclaration", "Declaration", "Plus", "Minus", "Mult", "Div", "Mod", "UnaryMinus", "UnaryPlus", "Neg", "Assignment", "LIncr", "RIncr", "LDecr", "RDecr", "If", "IfElse", "For", "While", "Bloc", "Lt", "Gt", "Leq", "Geq", "Eq", "Neq", "Land", "Lor", "Comma", - "FunctionPrototype", "FunctionDeclaration", "FunctionCall", "FunctionArgs", "Return" + "FunctionPrototype", "FunctionDeclaration", "FunctionCall", "FunctionArgs", "FunctionArgsValues", "Return" }; void _debug_print_tree(const Node& node, int depth, const string& prefix) { if (holds_alternative(node)) { @@ -567,6 +567,55 @@ ParseReturn parse_expr(vector tokens) { }; } +ParseReturn parse_args_values(vector tokens) { + vector children; + CodePosition pos = null_pos; + + try { + ParseReturn ret = parse_comp(tokens); + tokens = ret.tokens; + pos = get_node_pos(ret.node); + children.push_back(ret.node); + } catch (const ParseException& pex) { + InnerNode node = { + .type=NodeType::FunctionArgsValues, + .children=children, + .pos=pos + }; + return { + .node=node, + .tokens=tokens + }; + } + + + while (tokens.size() != 0 && tokens.back().type == TokenType::Comma) { + Token last_token; + try { + last_token = tokens.back(); + tokens.pop_back(); + + ParseReturn ret = parse_comp(tokens); + tokens = ret.tokens; + + children.push_back(ret.node); + } catch (const ParseException& pex) { + tokens.emplace_back(last_token); + break; + } + } + + InnerNode node = { + .type=NodeType::FunctionArgsValues, + .children=children, + .pos=pos + }; + return { + .node=node, + .tokens=tokens + }; +} + ParseReturn parse_args(vector tokens) { vector nodes; CodePosition pos = tokens.back().pos; @@ -918,7 +967,7 @@ ParseReturn parse_val(vector tokens) { case TokenType::LParenthese: { ret.tokens.pop_back(); - ParseReturn ret_expr = parse_expr(ret.tokens); + ParseReturn ret_expr = parse_args_values(ret.tokens); if (ret_expr.tokens.size() < 1 || ret_expr.tokens.back().type != TokenType::RParenthese) throw SyntaxError(