add boolean and bit operations

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

View File

@ -21,8 +21,9 @@ class EmitVisitor : public xlangBaseVisitor {
std::any visitFile(xlangParser::FileContext *ctx) override;
std::any visitFunction(xlangParser::FunctionContext *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 visitSum(xlangParser::SumContext *ctx) override;
std::any visitTerm(xlangParser::TermContext *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)*;
block : LeftBrace statement* RightBrace;
statement : Identifier Assign expr Semicolon
| If expr block (Else block)?
| While expr block
| If condition block (Else block)?
| While condition block
| Return expr Semicolon
| Print expr Semicolon
;
expr : sum ((Less|LessEqual|Greater|GreaterEqual|Equal|NotEqual) sum)
| sum
condition : condition (And|Or|Xor) boolean
| 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 : term ((Mul|Div) factor)
term : term (Mul|Div) factor
| factor
;
factor : Integer
factor : Minus factor
| BitNot factor
| Integer
| Identifier
| Identifier LeftParen exprList? RightParen
| LeftParen sum RightParen
| LeftParen expr RightParen
;
exprList : expr (Comma expr)*;
@ -31,6 +39,12 @@ Else : 'else';
While : 'while';
Return : 'return';
Print : 'print';
And : 'and';
Or : 'or';
Xor : 'xor';
Not : 'not';
True : 'true';
False : 'false';
LeftParen : '(';
RightParen : ')';
@ -45,6 +59,12 @@ Equal : '==';
NotEqual : '!=';
Plus : '+';
Minus : '-';
BitAnd : '&';
BitOr : '|';
BitXor : '^';
ShiftLeft : '<<';
ShiftRight : '>>';
BitNot : '~';
Mul : '*';
Div : '/';
Comma : ',';