summaryrefslogtreecommitdiff
path: root/Compiler/CCompilerVisitor.cs
diff options
context:
space:
mode:
authorMelodi <62381002+Melodi17@users.noreply.github.com>2025-08-07 00:02:00 +1000
committerMelodi <62381002+Melodi17@users.noreply.github.com>2025-08-07 00:02:00 +1000
commit33e1c5fc6e37549b4eba833ae7e534f9da250b10 (patch)
tree051c846326eae94712337baf4ac65ce837d02b95 /Compiler/CCompilerVisitor.cs
parent7a8d2bcd75d88a5429937bf551878c55e1dcf0fd (diff)
added binary, logical and bitwise operators to compiler
Diffstat (limited to 'Compiler/CCompilerVisitor.cs')
-rw-r--r--Compiler/CCompilerVisitor.cs208
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