diff --git a/bootstrap/emit.cc b/bootstrap/emit.cc index e121da8..dcada32 100644 --- a/bootstrap/emit.cc +++ b/bootstrap/emit.cc @@ -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 {}; } diff --git a/bootstrap/emit.hh b/bootstrap/emit.hh index 7f1a3dc..e86c9c0 100644 --- a/bootstrap/emit.hh +++ b/bootstrap/emit.hh @@ -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; }; diff --git a/bootstrap/xlang.g4 b/bootstrap/xlang.g4 index 69a6f2f..6b23f6c 100644 --- a/bootstrap/xlang.g4 +++ b/bootstrap/xlang.g4 @@ -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 : ',';