From 3caa421b3b39af2a37991bff97eb46d2bde3b7b6 Mon Sep 17 00:00:00 2001 From: jfecher Date: Sat, 22 Jul 2017 10:37:22 -0400 Subject: [PATCH] Replaced binop ';' with a dedicated sequence node to limit recursion --- include/parser.h | 8 ++++++++ include/ptree.h | 1 + src/nodeprinter.cpp | 11 +++++++---- src/operator.cpp | 23 ++++++++++++++--------- src/ptree.cpp | 16 ++++++++++++++-- src/syntax.y | 24 ++++++++++++------------ 6 files changed, 56 insertions(+), 27 deletions(-) diff --git a/include/parser.h b/include/parser.h index d091d282..e29cab38 100644 --- a/include/parser.h +++ b/include/parser.h @@ -175,6 +175,14 @@ namespace ante { ~BinOpNode(){} }; + struct SeqNode : public Node{ + vector> sequence; + TypedValue* compile(Compiler*); + void print(void); + SeqNode(LOC_TY& loc) : Node(loc), sequence(){} + ~SeqNode(){} + }; + struct BlockNode : public Node{ unique_ptr block; TypedValue* compile(Compiler*); diff --git a/include/ptree.h b/include/ptree.h index 79b187d2..4097e1fd 100644 --- a/include/ptree.h +++ b/include/ptree.h @@ -42,6 +42,7 @@ Node* mkTypeNode(LOC_TY loc, TypeTag type, char* typeName, Node *extTy = nullptr Node* mkTypeCastNode(LOC_TY loc, Node *l, Node *r); Node* mkUnOpNode(LOC_TY loc, int op, Node *r); Node* mkBinOpNode(LOC_TY loc, int op, Node* l, Node* r); +Node* mkSeqNode(LOC_TY loc, Node *l, Node *r); Node* mkBlockNode(LOC_TY loc, Node* b); Node* mkNamedValNode(LOC_TY loc, Node* nodes, Node* tExpr, Node* prev); Node* mkVarNode(LOC_TY loc, char* s); diff --git a/src/nodeprinter.cpp b/src/nodeprinter.cpp index 648855e2..9f954b9a 100644 --- a/src/nodeprinter.cpp +++ b/src/nodeprinter.cpp @@ -138,14 +138,17 @@ void UnOpNode::print(){ maybePrintArr(next.get()); } +void SeqNode::print(){ + for(auto &n : sequence){ + n->print(); + puts(";"); + } +} + void BinOpNode::print(){ if(op == '('){ lval->print(); rval->print(); - }else if(op == ';'){ - lval->print(); - puts(";"); - rval->print(); }else{ putchar('('); lval->print(); diff --git a/src/operator.cpp b/src/operator.cpp index 497d9124..8eb97b05 100644 --- a/src/operator.cpp +++ b/src/operator.cpp @@ -1482,15 +1482,22 @@ TypedValue* checkForOperatorOverload(Compiler *c, TypedValue *lhs, int op, Typed } -TypedValue* compSequence(Compiler *c, BinOpNode *seq){ - try{ - seq->lval->compile(c); - }catch(CtError *e){ - delete e; +TypedValue* SeqNode::compile(Compiler *c){ + TypedValue *ret; + size_t i = 1; + + for(auto &n : sequence){ + try{ + ret = n->compile(c); + }catch(CtError *e){ + //Unless the final value throws, delete the error + if(i == sequence.size()) throw e; + else delete e; + } + i++; } - //let CompilationError's of rval percolate - return seq->rval->compile(c); + return ret; } @@ -1505,8 +1512,6 @@ TypedValue* BinOpNode::compile(Compiler *c){ case Tok_Or: return c->compLogicalOr(lval.get(), rval.get(), this); } - if(op == ';') return compSequence(c, this); - TypedValue *lhs = lval->compile(c); TypedValue *rhs = rval->compile(c); diff --git a/src/ptree.cpp b/src/ptree.cpp index b0241d0d..e50f79b3 100644 --- a/src/ptree.cpp +++ b/src/ptree.cpp @@ -27,9 +27,9 @@ Node* setElse(Node *ifn, Node *elseN){ else n->elseN.reset(elseN); }else{ - auto *binop = dynamic_cast(ifn); + auto *seq = dynamic_cast(ifn); - if(binop and (n = dynamic_cast(binop->rval.get()))){ + if(seq and (n = dynamic_cast(seq->sequence[1].get()))){ while(auto *tmp = dynamic_cast(n->elseN.get())) n = tmp; @@ -366,6 +366,18 @@ Node* mkBinOpNode(LOC_TY loc, int op, Node* l, Node* r){ return new BinOpNode(loc, op, l, r); } +Node* mkSeqNode(LOC_TY loc, Node *l, Node *r){ + if(SeqNode *seq = dynamic_cast(l)){ + seq->sequence.emplace_back(r); + return seq; + }else{ + SeqNode *s = new SeqNode(loc); + s->sequence.emplace_back(l); + s->sequence.emplace_back(r); + return s; + } +} + Node* mkBlockNode(LOC_TY loc, Node *b){ return new BlockNode(loc, b); } diff --git a/src/syntax.y b/src/syntax.y index c716201a..916beac9 100644 --- a/src/syntax.y +++ b/src/syntax.y @@ -392,13 +392,13 @@ block: Indent expr Unindent {$$ = mkBlockNode(@$, $2);} | Indent continue Unindent {$$ = mkBlockNode(@$, $2);} | Indent ret_expr Unindent {$$ = mkBlockNode(@$, $2);} - | Indent expr Newline break Unindent {$$ = mkBlockNode(@$, mkBinOpNode(@$, ';', $2, $4));} - | Indent expr Newline continue Unindent {$$ = mkBlockNode(@$, mkBinOpNode(@$, ';', $2, $4));} - | Indent expr Newline ret_expr Unindent {$$ = mkBlockNode(@$, mkBinOpNode(@$, ';', $2, $4));} + | Indent expr Newline break Unindent {$$ = mkBlockNode(@$, mkSeqNode(@$, $2, $4));} + | Indent expr Newline continue Unindent {$$ = mkBlockNode(@$, mkSeqNode(@$, $2, $4));} + | Indent expr Newline ret_expr Unindent {$$ = mkBlockNode(@$, mkSeqNode(@$, $2, $4));} - | Indent expr break Unindent {$$ = mkBlockNode(@$, mkBinOpNode(@$, ';', $2, $3));} - | Indent expr continue Unindent {$$ = mkBlockNode(@$, mkBinOpNode(@$, ';', $2, $3));} - | Indent expr ret_expr Unindent {$$ = mkBlockNode(@$, mkBinOpNode(@$, ';', $2, $3));} + | Indent expr break Unindent {$$ = mkBlockNode(@$, mkSeqNode(@$, $2, $3));} + | Indent expr continue Unindent {$$ = mkBlockNode(@$, mkSeqNode(@$, $2, $3));} + | Indent expr ret_expr Unindent {$$ = mkBlockNode(@$, mkSeqNode(@$, $2, $3));} ; @@ -686,7 +686,7 @@ expr_no_decl: expr_no_decl '+' maybe_newline expr_no_decl {$$ = mkB | expr_no_decl '>' maybe_newline expr_no_decl {$$ = mkBinOpNode(@$, '>', $1, $4);} | type_expr '.' maybe_newline var {$$ = mkBinOpNode(@$, '.', $1, $4);} | expr_no_decl '.' maybe_newline var {$$ = mkBinOpNode(@$, '.', $1, $4);} - | expr_no_decl ';' maybe_newline expr_no_decl {$$ = mkBinOpNode(@$, ';', $1, $4);} + | expr_no_decl ';' maybe_newline expr_no_decl {$$ = mkSeqNode(@$, $1, $4);} | expr_no_decl '#' maybe_newline expr_no_decl {$$ = mkBinOpNode(@$, '#', $1, $4);} | expr_no_decl Eq maybe_newline expr_no_decl {$$ = mkBinOpNode(@$, Tok_Eq, $1, $4);} | expr_no_decl NotEq maybe_newline expr_no_decl {$$ = mkBinOpNode(@$, Tok_NotEq, $1, $4);} @@ -714,10 +714,10 @@ expr_no_decl: expr_no_decl '+' maybe_newline expr_no_decl {$$ = mkB | expr_no_decl Elif expr_no_decl Then expr_no_decl_or_jump %prec MEDIF {auto*elif = mkIfNode(@$, $3, $5, 0); $$ = setElse($1, elif);} | expr_no_decl Else expr_no_decl_or_jump %prec Else {$$ = setElse($1, $3);} - | match_expr Newline expr_no_decl %prec Match {$$ = mkBinOpNode(@$, ';', $1, $3);} + | match_expr Newline expr_no_decl %prec Match {$$ = mkSeqNode(@$, $1, $3);} | match_expr Newline %prec LOW {$$ = $1;} | expr_no_decl Newline {$$ = $1;} - | expr_no_decl Newline expr_no_decl {$$ = mkBinOpNode(@$, ';', $1, $3);} + | expr_no_decl Newline expr_no_decl {$$ = mkSeqNode(@$, $1, $3);} ; @@ -738,7 +738,7 @@ expr: expr '+' maybe_newline expr {$$ = mkBinOpNode(@$, '+', $1, | expr '>' maybe_newline expr {$$ = mkBinOpNode(@$, '>', $1, $4);} | type_expr '.' maybe_newline var {$$ = mkBinOpNode(@$, '.', $1, $4);} | expr '.' maybe_newline var {$$ = mkBinOpNode(@$, '.', $1, $4);} - | expr ';' maybe_newline expr {$$ = mkBinOpNode(@$, ';', $1, $4);} + | expr ';' maybe_newline expr {$$ = mkSeqNode(@$, $1, $4);} | expr '#' maybe_newline expr {$$ = mkBinOpNode(@$, '#', $1, $4);} | expr Eq maybe_newline expr {$$ = mkBinOpNode(@$, Tok_Eq, $1, $4);} | expr NotEq maybe_newline expr {$$ = mkBinOpNode(@$, Tok_NotEq, $1, $4);} @@ -766,10 +766,10 @@ expr: expr '+' maybe_newline expr {$$ = mkBinOpNode(@$, '+', $1, | expr Elif expr Then expr_or_jump %prec MEDIF {auto*elif = mkIfNode(@$, $3, $5, 0); $$ = setElse($1, elif);} | expr Else expr_or_jump {$$ = setElse($1, $3);} - | match_expr Newline expr %prec Match {$$ = mkBinOpNode(@$, ';', $1, $3);} + | match_expr Newline expr %prec Match {$$ = mkSeqNode(@$, $1, $3);} | match_expr Newline %prec LOW {$$ = $1;} | expr Newline {$$ = $1;} - | expr Newline expr {$$ = mkBinOpNode(@$, ';', $1, $3);} + | expr Newline expr {$$ = mkSeqNode(@$, $1, $3);} ; %%