Skip to content

Commit

Permalink
Replaced binop ';' with a dedicated sequence node to limit recursion
Browse files Browse the repository at this point in the history
  • Loading branch information
jfecher committed Jul 22, 2017
1 parent 62a0e62 commit 3caa421
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 27 deletions.
8 changes: 8 additions & 0 deletions include/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ namespace ante {
~BinOpNode(){}
};

struct SeqNode : public Node{
vector<unique_ptr<Node>> sequence;
TypedValue* compile(Compiler*);
void print(void);
SeqNode(LOC_TY& loc) : Node(loc), sequence(){}
~SeqNode(){}
};

struct BlockNode : public Node{
unique_ptr<Node> block;
TypedValue* compile(Compiler*);
Expand Down
1 change: 1 addition & 0 deletions include/ptree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
11 changes: 7 additions & 4 deletions src/nodeprinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
23 changes: 14 additions & 9 deletions src/operator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}


Expand All @@ -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);

Expand Down
16 changes: 14 additions & 2 deletions src/ptree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ Node* setElse(Node *ifn, Node *elseN){
else
n->elseN.reset(elseN);
}else{
auto *binop = dynamic_cast<BinOpNode*>(ifn);
auto *seq = dynamic_cast<SeqNode*>(ifn);

if(binop and (n = dynamic_cast<IfNode*>(binop->rval.get()))){
if(seq and (n = dynamic_cast<IfNode*>(seq->sequence[1].get()))){
while(auto *tmp = dynamic_cast<IfNode*>(n->elseN.get()))
n = tmp;

Expand Down Expand Up @@ -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<SeqNode*>(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);
}
Expand Down
24 changes: 12 additions & 12 deletions src/syntax.y
Original file line number Diff line number Diff line change
Expand Up @@ -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));}
;


Expand Down Expand Up @@ -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);}
Expand Down Expand Up @@ -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);}
;


Expand All @@ -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);}
Expand Down Expand Up @@ -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);}
;

%%
Expand Down

0 comments on commit 3caa421

Please sign in to comment.