add boolean and bit operations

This commit is contained in:
Thomas Lindner 2023-01-06 17:44:57 +01:00
parent 7d87aa758f
commit 9d14c30d81
3 changed files with 85 additions and 29 deletions

View file

@ -45,7 +45,7 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
int block = blockcount++; int block = blockcount++;
output << "@if" << block << "_expr" << std::endl; output << "@if" << block << "_expr" << std::endl;
tmpcount = 0; tmpcount = 0;
visitExpr(ctx->expr()); visitCondition(ctx->condition());
output << " jnz " << last << ", @if" << block << "_then, @if" << block output << " jnz " << last << ", @if" << block << "_then, @if" << block
<< "_else" << std::endl; << "_else" << std::endl;
output << "@if" << block << "_then" << std::endl; output << "@if" << block << "_then" << std::endl;
@ -62,7 +62,7 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
int block = blockcount++; int block = blockcount++;
output << "@while" << block << "_expr" << std::endl; output << "@while" << block << "_expr" << std::endl;
tmpcount = 0; tmpcount = 0;
visitExpr(ctx->expr()); visitCondition(ctx->condition());
output << " jnz " << last << ", @while" << block << "_body, @while" output << " jnz " << last << ", @while" << block << "_body, @while"
<< block << "_end" << std::endl; << block << "_end" << std::endl;
output << "@while" << block << "_body" << std::endl; output << "@while" << block << "_body" << std::endl;
@ -100,20 +100,47 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
return {}; \ return {}; \
} }
std::any EmitVisitor::visitExpr(xlangParser::ExprContext *ctx) { std::any EmitVisitor::visitCondition(xlangParser::ConditionContext *ctx) {
OPERATOR(Less, visitSum, sum(0), visitSum, sum(1), "csltw"); OPERATOR(And, visitCondition, condition(), visitBoolean, boolean(), "and");
OPERATOR(LessEqual, visitSum, sum(0), visitSum, sum(1), "cslew"); OPERATOR(Or, visitCondition, condition(), visitBoolean, boolean(), "or");
OPERATOR(Greater, visitSum, sum(0), visitSum, sum(1), "csgtw"); OPERATOR(Xor, visitCondition, condition(), visitBoolean, boolean(), "xor");
OPERATOR(GreaterEqual, visitSum, sum(0), visitSum, sum(1), "csgew"); visitBoolean(ctx->boolean());
OPERATOR(Equal, visitSum, sum(0), visitSum, sum(1), "ceqw");
OPERATOR(NotEqual, visitSum, sum(0), visitSum, sum(1), "cnew");
visitSum(ctx->sum(0));
return {}; return {};
} }
std::any EmitVisitor::visitSum(xlangParser::SumContext *ctx) { std::any EmitVisitor::visitBoolean(xlangParser::BooleanContext *ctx) {
OPERATOR(Plus, visitSum, sum(), visitTerm, term(), "add"); if (ctx->Not()) {
OPERATOR(Minus, visitSum, sum(), visitTerm, term(), "sub"); visitBoolean(ctx->boolean());
std::string b = last;
output << " " << tmp() << " = w xor 1, " << b << std::endl;
return {};
}
OPERATOR(Less, visitExpr, expr(0), visitExpr, expr(1), "csltw");
OPERATOR(LessEqual, visitExpr, expr(0), visitExpr, expr(1), "cslew");
OPERATOR(Greater, visitExpr, expr(0), visitExpr, expr(1), "csgtw");
OPERATOR(GreaterEqual, visitExpr, expr(0), visitExpr, expr(1), "csgew");
OPERATOR(Equal, visitExpr, expr(0), visitExpr, expr(1), "ceqw");
OPERATOR(NotEqual, visitExpr, expr(0), visitExpr, expr(1), "cnew");
if (ctx->True()) {
last = "1";
return {};
}
if (ctx->False()) {
last = "0";
return {};
}
visitCondition(ctx->condition());
return {};
}
std::any EmitVisitor::visitExpr(xlangParser::ExprContext *ctx) {
OPERATOR(Plus, visitExpr, expr(), visitTerm, term(), "add");
OPERATOR(Minus, visitExpr, expr(), visitTerm, term(), "sub");
OPERATOR(BitAnd, visitExpr, expr(), visitTerm, term(), "and");
OPERATOR(BitOr, visitExpr, expr(), visitTerm, term(), "or");
OPERATOR(BitXor, visitExpr, expr(), visitTerm, term(), "xor");
OPERATOR(ShiftLeft, visitExpr, expr(), visitTerm, term(), "shl");
OPERATOR(ShiftRight, visitExpr, expr(), visitTerm, term(), "shr");
visitTerm(ctx->term()); visitTerm(ctx->term());
return {}; return {};
} }
@ -126,6 +153,18 @@ std::any EmitVisitor::visitTerm(xlangParser::TermContext *ctx) {
} }
std::any EmitVisitor::visitFactor(xlangParser::FactorContext *ctx) { std::any EmitVisitor::visitFactor(xlangParser::FactorContext *ctx) {
if (ctx->Minus()) {
visitFactor(ctx->factor());
std::string f = last;
output << " " << tmp() << " = w neg " << f << std::endl;
return {};
}
if (ctx->BitNot()) {
visitFactor(ctx->factor());
std::string f = last;
output << " " << tmp() << " = w xor -1, " << f << std::endl;
return {};
}
if (auto integer = ctx->Integer()) { if (auto integer = ctx->Integer()) {
last = integer->getSymbol()->getText(); last = integer->getSymbol()->getText();
return {}; return {};
@ -150,11 +189,7 @@ std::any EmitVisitor::visitFactor(xlangParser::FactorContext *ctx) {
} }
return {}; return {};
} }
if (auto sum = ctx->sum()) { visitExpr(ctx->expr());
visitSum(sum);
return {};
}
// unreachable
return {}; return {};
} }

View file

@ -21,8 +21,9 @@ class EmitVisitor : public xlangBaseVisitor {
std::any visitFile(xlangParser::FileContext *ctx) override; std::any visitFile(xlangParser::FileContext *ctx) override;
std::any visitFunction(xlangParser::FunctionContext *ctx) override; std::any visitFunction(xlangParser::FunctionContext *ctx) override;
std::any visitStatement(xlangParser::StatementContext *ctx) override; std::any visitStatement(xlangParser::StatementContext *ctx) override;
std::any visitCondition(xlangParser::ConditionContext *ctx) override;
std::any visitBoolean(xlangParser::BooleanContext *ctx) override;
std::any visitExpr(xlangParser::ExprContext *ctx) override; std::any visitExpr(xlangParser::ExprContext *ctx) override;
std::any visitSum(xlangParser::SumContext *ctx) override;
std::any visitTerm(xlangParser::TermContext *ctx) override; std::any visitTerm(xlangParser::TermContext *ctx) override;
std::any visitFactor(xlangParser::FactorContext *ctx) override; std::any visitFactor(xlangParser::FactorContext *ctx) override;
}; };

View file

@ -5,24 +5,32 @@ function : Identifier LeftParen argumentList? RightParen block;
argumentList : Identifier (Comma Identifier)*; argumentList : Identifier (Comma Identifier)*;
block : LeftBrace statement* RightBrace; block : LeftBrace statement* RightBrace;
statement : Identifier Assign expr Semicolon statement : Identifier Assign expr Semicolon
| If expr block (Else block)? | If condition block (Else block)?
| While expr block | While condition block
| Return expr Semicolon | Return expr Semicolon
| Print expr Semicolon | Print expr Semicolon
; ;
expr : sum ((Less|LessEqual|Greater|GreaterEqual|Equal|NotEqual) sum) condition : condition (And|Or|Xor) boolean
| sum | boolean
;
boolean : Not boolean
| expr (Less|LessEqual|Greater|GreaterEqual|Equal|NotEqual) expr
| True
| False
| LeftParen condition RightParen
;
expr : expr (Plus|Minus|BitAnd|BitOr|BitXor|ShiftLeft|ShiftRight) term
| term
; ;
sum : sum ((Plus|Minus) term) term : term (Mul|Div) factor
| term
;
term : term ((Mul|Div) factor)
| factor | factor
; ;
factor : Integer factor : Minus factor
| BitNot factor
| Integer
| Identifier | Identifier
| Identifier LeftParen exprList? RightParen | Identifier LeftParen exprList? RightParen
| LeftParen sum RightParen | LeftParen expr RightParen
; ;
exprList : expr (Comma expr)*; exprList : expr (Comma expr)*;
@ -31,6 +39,12 @@ Else : 'else';
While : 'while'; While : 'while';
Return : 'return'; Return : 'return';
Print : 'print'; Print : 'print';
And : 'and';
Or : 'or';
Xor : 'xor';
Not : 'not';
True : 'true';
False : 'false';
LeftParen : '('; LeftParen : '(';
RightParen : ')'; RightParen : ')';
@ -45,6 +59,12 @@ Equal : '==';
NotEqual : '!='; NotEqual : '!=';
Plus : '+'; Plus : '+';
Minus : '-'; Minus : '-';
BitAnd : '&';
BitOr : '|';
BitXor : '^';
ShiftLeft : '<<';
ShiftRight : '>>';
BitNot : '~';
Mul : '*'; Mul : '*';
Div : '/'; Div : '/';
Comma : ','; Comma : ',';