diff options
| author | Melodi <62381002+Melodi17@users.noreply.github.com> | 2025-08-07 00:02:00 +1000 |
|---|---|---|
| committer | Melodi <62381002+Melodi17@users.noreply.github.com> | 2025-08-07 00:02:00 +1000 |
| commit | 33e1c5fc6e37549b4eba833ae7e534f9da250b10 (patch) | |
| tree | 051c846326eae94712337baf4ac65ce837d02b95 /Compiler | |
| parent | 7a8d2bcd75d88a5429937bf551878c55e1dcf0fd (diff) | |
added binary, logical and bitwise operators to compiler
Diffstat (limited to 'Compiler')
| -rw-r--r-- | Compiler/CCompilerVisitor.cs | 208 |
1 files changed, 144 insertions, 64 deletions
diff --git a/Compiler/CCompilerVisitor.cs b/Compiler/CCompilerVisitor.cs index cee69f4..7bbbeda 100644 --- a/Compiler/CCompilerVisitor.cs +++ b/Compiler/CCompilerVisitor.cs @@ -2,19 +2,37 @@ namespace Q1.Compiler; public class CCompilerVisitor : CGrammarBaseVisitor<string?> { - private List<string> Instructions = new(); + private int _branchCount = 1; + private List<string> _instructions = new(); + private string GetBranchLabel(string type) + { + return $"_{type}_{_branchCount++}"; + } + private void Instruction(string instruction) + { + this._instructions.Add($" {instruction}"); + } + private void Blank() + { + this._instructions.Add(""); + } + private void Label(string name) + { + this._instructions.Add($"{name}:"); + } + public IEnumerable<string> Compile(CGrammarParser.ProgramContext program) { this.Visit(program); - return this.Instructions; + return this._instructions; } public override string? VisitFunction(CGrammarParser.FunctionContext context) { string functionName = context.ID().GetText(); - Instructions.Add($"_{functionName}:"); + this.Label($"_{functionName}"); this.VisitChildren(context); - this.Instructions.Add(""); + this.Blank(); return null; } @@ -29,14 +47,14 @@ public class CCompilerVisitor : CGrammarBaseVisitor<string?> string? expression = this.Visit(context.expression()); if (expression != null) { - this.Instructions.Add($"MOV {expression}, V0"); - Instructions.Add($"RET"); + this.Instruction($"mov {expression}, V0"); + this.Instruction($"ret"); } else throw new CompilerException("Return value was not an expression."); } else - Instructions.Add("RET"); + this.Instruction("ret"); return null; } @@ -55,7 +73,7 @@ public class CCompilerVisitor : CGrammarBaseVisitor<string?> if (value == null) throw new CompilerException("Value for negating was not an expression."); - this.Instructions.Add($"NOT {value}"); + this.Instruction($"not {value}"); return "LX"; } @@ -65,108 +83,170 @@ public class CCompilerVisitor : CGrammarBaseVisitor<string?> if (value == null) throw new CompilerException("Value for inversion was not an expression."); - this.Instructions.Add($"INV {value}"); + this.Instruction($"inv {value}"); return "DX"; } - public override string? VisitAddExpression(CGrammarParser.AddExpressionContext context) + private void BaseBinaryOperation(CGrammarParser.ExpressionContext leftExpr, CGrammarParser.ExpressionContext rightExpr, string operation, string operationFriendlyName) { - string? left = this.Visit(context.left); - string? right = this.Visit(context.right); + string? left = this.Visit(leftExpr); + if (left == null) + throw new CompilerException($"Left operand for {operationFriendlyName} was not an expression."); + + this.Instruction($"push {left}"); - if (left == null || right == null) - throw new CompilerException("Left or right operand for addition was not an expression."); + string? right = this.Visit(rightExpr); + if (right == null) + throw new CompilerException($"Right operand for {operationFriendlyName} was not an expression."); - this.Instructions.Add($"ADD {left}, {right}"); + this.Instruction($"mov {right}, V1"); + this.Instruction($"pop V0"); + this.Instruction($"{operation} V0, V1"); + } + public override string? VisitAddExpression(CGrammarParser.AddExpressionContext context) + { + BaseBinaryOperation(context.left, context.right, "add", "addition"); return "AX"; } public override string? VisitSubtractExpression(CGrammarParser.SubtractExpressionContext context) { - string? left = this.Visit(context.left); - string? right = this.Visit(context.right); - - if (left == null || right == null) - throw new CompilerException("Left or right operand for subtraction was not an expression."); - - this.Instructions.Add($"SUB {left}, {right}"); + BaseBinaryOperation(context.left, context.right, "sub", "subtraction"); return "AX"; } public override string? VisitMultiplyExpression(CGrammarParser.MultiplyExpressionContext context) { - string? left = this.Visit(context.left); - string? right = this.Visit(context.right); - - if (left == null || right == null) - throw new CompilerException("Left or right operand for multiplication was not an expression."); - - this.Instructions.Add($"MUL {left}, {right}"); + BaseBinaryOperation(context.left, context.right, "mul", "multiplication"); return "AX"; } public override string? VisitDivideExpression(CGrammarParser.DivideExpressionContext context) { - string? left = this.Visit(context.left); - string? right = this.Visit(context.right); - - if (left == null || right == null) - throw new CompilerException("Left or right operand for division was not an expression."); - - this.Instructions.Add($"DIV {left}, {right}"); + BaseBinaryOperation(context.left, context.right, "div", "division"); return "AX"; } public override string? VisitModulusExpression(CGrammarParser.ModulusExpressionContext context) { - string? left = this.Visit(context.left); - string? right = this.Visit(context.right); - - if (left == null || right == null) - throw new CompilerException("Left or right operand for modulus was not an expression."); - - this.Instructions.Add($"MOD {left}, {right}"); + BaseBinaryOperation(context.left, context.right, "mod", "modulus"); return "AX"; } - public override string? VisitBitwiseXorExpression(CGrammarParser.BitwiseXorExpressionContext context) - { - throw new NotImplementedException(); - } - public override string? VisitLessThanOrEqualExpression(CGrammarParser.LessThanOrEqualExpressionContext context) + public override string? VisitEqualExpression(CGrammarParser.EqualExpressionContext context) { - throw new NotImplementedException(); + BaseBinaryOperation(context.left, context.right, "cmp", "equality check"); + return "LX"; } + public override string? VisitNotEqualExpression(CGrammarParser.NotEqualExpressionContext context) { - throw new NotImplementedException(); + BaseBinaryOperation(context.left, context.right, "cmp", "inequality check"); + this.Instruction($"not"); // lx is implicit + return "LX"; } + public override string? VisitGreaterThanExpression(CGrammarParser.GreaterThanExpressionContext context) { - throw new NotImplementedException(); + BaseBinaryOperation(context.left, context.right, "gt", "greater than check"); + return "LX"; + } + + public override string? VisitLessThanExpression(CGrammarParser.LessThanExpressionContext context) + { + BaseBinaryOperation(context.left, context.right, "lt", "less than check"); + return "LX"; } + public override string? VisitLogicalOrExpression(CGrammarParser.LogicalOrExpressionContext context) { - throw new NotImplementedException(); + string? left = this.Visit(context.left); + if (left == null) + throw new CompilerException("Left operand for logical OR was not an expression."); + + string clauseBranch = this.GetBranchLabel("clause"); + string endBranch = this.GetBranchLabel("end"); + + this.Instruction($"cmp {left}, 0"); + this.Instruction("bz"); // implicit LX + this.Instruction($"jmp {clauseBranch}"); // only if bz is not 0 + this.Instruction("mov 1, V0"); + this.Instruction($"jmp {endBranch}"); + this.Label(clauseBranch); + + string? right = this.Visit(context.right); + if (right == null) + throw new CompilerException("Right operand for logical OR was not an expression."); + + this.Instruction($"cmp {right}, 0"); + this.Instruction("not"); + this.Instruction("mov LX, V0"); + this.Label(endBranch); + + return "V0"; } - public override string? VisitGreaterThanOrEqualExpression(CGrammarParser.GreaterThanOrEqualExpressionContext context) + public override string? VisitLogicalAndExpression(CGrammarParser.LogicalAndExpressionContext context) { - throw new NotImplementedException(); + string? left = this.Visit(context.left); + if (left == null) + throw new CompilerException("Left operand for logical OR was not an expression."); + + string clauseBranch = this.GetBranchLabel("clause"); + string endBranch = this.GetBranchLabel("end"); + + this.Instruction($"cmp {left}, 0"); + this.Instruction("not"); + this.Instruction("bz"); // implicit LX + this.Instruction($"jmp {clauseBranch}"); // only if bz is not 0 + this.Instruction("mov 0, V0"); + this.Instruction($"jmp {endBranch}"); + this.Label(clauseBranch); + + string? right = this.Visit(context.right); + if (right == null) + throw new CompilerException("Right operand for logical OR was not an expression."); + + this.Instruction($"cmp {right}, 0"); + this.Instruction("not"); + this.Instruction("mov LX, V0"); + this.Label(endBranch); + + return "V0"; } - public override string? VisitBitwiseOrExpression(CGrammarParser.BitwiseOrExpressionContext context) + + public override string? VisitGreaterThanOrEqualExpression(CGrammarParser.GreaterThanOrEqualExpressionContext context) { - throw new NotImplementedException(); + BaseBinaryOperation(context.left, context.right, "cmp", "equality check"); + string endBranch = this.GetBranchLabel("end"); + + this.Instruction("bz"); + this.Instruction($"jmp {endBranch}"); + this.Instruction($"gt V0, V1"); + this.Label(endBranch); + + return "LX"; } - public override string? VisitBitwiseAndExpression(CGrammarParser.BitwiseAndExpressionContext context) + public override string? VisitLessThanOrEqualExpression(CGrammarParser.LessThanOrEqualExpressionContext context) { - throw new NotImplementedException(); + BaseBinaryOperation(context.left, context.right, "cmp", "equality check"); + string endBranch = this.GetBranchLabel("end"); + + this.Instruction("bz"); + this.Instruction($"jmp {endBranch}"); + this.Instruction($"lt V0, V1"); + this.Label(endBranch); + + return "LX"; } - public override string? VisitLessThanExpression(CGrammarParser.LessThanExpressionContext context) + public override string? VisitBitwiseXorExpression(CGrammarParser.BitwiseXorExpressionContext context) { - throw new NotImplementedException(); + this.BaseBinaryOperation(context.left, context.right, "xor", "exclusive or"); + return "DX"; } - public override string? VisitLogicalAndExpression(CGrammarParser.LogicalAndExpressionContext context) + public override string? VisitBitwiseOrExpression(CGrammarParser.BitwiseOrExpressionContext context) { - throw new NotImplementedException(); + this.BaseBinaryOperation(context.left, context.right, "or", "or"); + return "DX"; } - public override string? VisitEqualExpression(CGrammarParser.EqualExpressionContext context) + public override string? VisitBitwiseAndExpression(CGrammarParser.BitwiseAndExpressionContext context) { - throw new NotImplementedException(); + this.BaseBinaryOperation(context.left, context.right, "and", "and"); + return "DX"; } }
\ No newline at end of file |
