summaryrefslogtreecommitdiff
path: root/Compiler/visitors/Operations.cs
diff options
context:
space:
mode:
authorMelodi <62381002+Melodi17@users.noreply.github.com>2025-08-27 21:22:55 +1000
committerMelodi <62381002+Melodi17@users.noreply.github.com>2025-08-27 21:22:55 +1000
commit634681ce2bb36cd686943102a0f071cd6a09049f (patch)
tree6710047aa231d50f57114bdd54a27c559fb20a73 /Compiler/visitors/Operations.cs
parent94ddc02e03ab942d0c881e29053e8df3d2940c30 (diff)
fixed bugs and revolutionized the universe
Diffstat (limited to 'Compiler/visitors/Operations.cs')
-rw-r--r--Compiler/visitors/Operations.cs305
1 files changed, 305 insertions, 0 deletions
diff --git a/Compiler/visitors/Operations.cs b/Compiler/visitors/Operations.cs
new file mode 100644
index 0000000..8483747
--- /dev/null
+++ b/Compiler/visitors/Operations.cs
@@ -0,0 +1,305 @@
+namespace Q1.Compiler.visitors;
+
+public partial class CCompilerVisitor
+{
+ private void BaseBinaryOperation(CGrammarParser.ExpressionContext leftExpr, CGrammarParser.ExpressionContext rightExpr, string operation, string operationFriendlyName)
+ {
+ string left = this.VisitExpression(leftExpr);
+
+ this.Instruction($"push {left}", "left operand");
+
+ string right = this.VisitExpression(rightExpr);
+
+ this.Instruction($"mov {right}, V1", "right operand");
+ this.Instruction($"pop V0", "get left operand back");
+ this.Instruction($"{operation} V0, V1", $"compute {operationFriendlyName}");
+ }
+
+ private string BaseBinaryCompoundOperation(CGrammarParser.TargetContext leftTarget, CGrammarParser.ExpressionContext rightExpr, string operation, string operationFriendlyName, string operationOutput)
+ {
+ Target left = this.VisitTarget(leftTarget);
+
+ this.Instruction($"push {left.Value}", "left operand");
+
+ string? right = this.VisitExpression(rightExpr);
+ if (right == null)
+ throw new CompilerException($"Right operand for {operationFriendlyName} was not an expression.");
+
+ this.Instruction($"mov {right}, V1", "right operand");
+ this.Instruction($"pop V0", "get left operand back");
+ this.Instruction($"{operation} V0, V1", $"compute {operationFriendlyName}");
+
+ this.Instruction($"push {operationOutput}", "computation results");
+
+ left = this.VisitTarget(leftTarget);
+ this.Instruction("pop V1", "get computation results back");
+ this.DynamicMove(left.Type, "V1", left.Value, "store back into left param");
+
+ return left.Value;
+ }
+
+ public override string VisitNotExpression(CGrammarParser.NotExpressionContext context)
+ {
+ string value = this.VisitExpression(context.expression());
+
+ this.Instruction($"not {value}");
+ return "LX";
+ }
+ public override string VisitInvertExpression(CGrammarParser.InvertExpressionContext context)
+ {
+ string value = this.VisitExpression(context.expression());
+
+ this.Instruction($"inv {value}");
+ return "DX";
+ }
+ public override string VisitAddExpression(CGrammarParser.AddExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "add", "addition");
+ return "AX";
+ }
+ public override string VisitSubtractExpression(CGrammarParser.SubtractExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "sub", "subtraction");
+ return "AX";
+ }
+ public override string VisitMultiplyExpression(CGrammarParser.MultiplyExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "mul", "multiplication");
+ return "AX";
+ }
+ public override string VisitDivideExpression(CGrammarParser.DivideExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "div", "division");
+ return "AX";
+ }
+ public override string VisitModulusExpression(CGrammarParser.ModulusExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "mod", "modulus");
+ return "AX";
+ }
+ public override string VisitEqualExpression(CGrammarParser.EqualExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "cmp", "equality check");
+ return "LX";
+ }
+ public override string VisitNotEqualExpression(CGrammarParser.NotEqualExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "cmp", "inequality check");
+ this.Instruction($"not"); // lx is implicit
+ return "LX";
+ }
+ public override string VisitGreaterThanExpression(CGrammarParser.GreaterThanExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "gt", "greater than check");
+ return "LX";
+ }
+ public override string VisitLessThanExpression(CGrammarParser.LessThanExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "lt", "less than check");
+ return "LX";
+ }
+ public override string VisitLogicalOrExpression(CGrammarParser.LogicalOrExpressionContext context)
+ {
+ string left = this.VisitExpression(context.left);
+
+ string clauseBranch = this.GenerateBranchLabel("clause");
+ string endBranch = this.GenerateBranchLabel("end");
+
+ this.Instruction($"cmp {left}, 0", "logical or");
+ this.Instruction("bz"); // implicit LX
+ this.Instruction($"jmp {clauseBranch}"); // only if bz is not 0
+ this.Instruction("mov 1, V0", "first operand succeeded, store 1 and skip second operand");
+ this.Instruction($"jmp {endBranch}");
+ this.Branch(clauseBranch);
+
+ string right = this.VisitExpression(context.right);
+
+ this.Instruction($"cmp {right}, 0", "compare result from second operand to 0");
+ this.Instruction("not");
+ this.Instruction("mov LX, V0", "store second operand result");
+ this.Branch(endBranch);
+
+ return "V0";
+ }
+ public override string VisitLogicalAndExpression(CGrammarParser.LogicalAndExpressionContext context)
+ {
+ string left = this.VisitExpression(context.left);
+
+ string clauseBranch = this.GenerateBranchLabel("clause");
+ string endBranch = this.GenerateBranchLabel("end");
+
+ this.Instruction($"cmp {left}, 0", "logical and");
+ this.Instruction("not");
+ this.Instruction("bz"); // implicit LX
+ this.Instruction($"jmp {clauseBranch}"); // only if bz is not 0
+ this.Instruction("mov 0, V0", "first operand failed, store 0 and skip second");
+ this.Instruction($"jmp {endBranch}");
+ this.Branch(clauseBranch);
+
+ string right = this.VisitExpression(context.right);
+
+ this.Instruction($"cmp {right}, 0", "compare result from second operand to 0");
+ this.Instruction("not");
+ this.Instruction("mov LX, V0", "store second operand result");
+ this.Branch(endBranch);
+
+ return "V0";
+ }
+ public override string VisitGreaterThanOrEqualExpression(CGrammarParser.GreaterThanOrEqualExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "cmp", "equality check");
+ string endBranch = this.GenerateBranchLabel("end");
+
+ this.Instruction("bz");
+ this.Instruction($"jmp {endBranch}");
+ this.Instruction($"gt V0, V1");
+ this.Branch(endBranch);
+
+ return "LX";
+ }
+ public override string VisitLessThanOrEqualExpression(CGrammarParser.LessThanOrEqualExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "cmp", "equality check");
+ string endBranch = this.GenerateBranchLabel("end");
+
+ this.Instruction("bz");
+ this.Instruction($"jmp {endBranch}");
+ this.Instruction($"lt V0, V1");
+ this.Branch(endBranch);
+
+ return "LX";
+ }
+ public override string VisitBitwiseXorExpression(CGrammarParser.BitwiseXorExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "xor", "exclusive or");
+ return "DX";
+ }
+ public override string VisitBitwiseOrExpression(CGrammarParser.BitwiseOrExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "or", "or");
+ return "DX";
+ }
+ public override string VisitBitwiseAndExpression(CGrammarParser.BitwiseAndExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "and", "and");
+ return "DX";
+ }
+ public override string VisitBitwiseLeftShiftExpression(CGrammarParser.BitwiseLeftShiftExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "shl", "left shift");
+ return "DX";
+ }
+ public override string VisitBitwiseRightShiftExpression(CGrammarParser.BitwiseRightShiftExpressionContext context)
+ {
+ this.BaseBinaryOperation(context.left, context.right, "shr", "right shift");
+ return "DX";
+ }
+ public override string VisitCompoundAddExpression(CGrammarParser.CompoundAddExpressionContext context)
+ {
+ return this.BaseBinaryCompoundOperation(context.target(),
+ context.expression(),
+ "add",
+ "addition",
+ "AX");
+ }
+ public override string VisitCompoundSubtractExpression(CGrammarParser.CompoundSubtractExpressionContext context)
+ {
+ return this.BaseBinaryCompoundOperation(context.target(),
+ context.expression(),
+ "sub",
+ "subtraction",
+ "AX");
+ }
+ public override string VisitCompoundMultiplyExpression(CGrammarParser.CompoundMultiplyExpressionContext context)
+ {
+ return this.BaseBinaryCompoundOperation(context.target(),
+ context.expression(),
+ "mul",
+ "multiplication",
+ "AX");
+ }
+ public override string VisitCompoundDivideExpression(CGrammarParser.CompoundDivideExpressionContext context)
+ {
+ return this.BaseBinaryCompoundOperation(context.target(),
+ context.expression(),
+ "div",
+ "division",
+ "AX");
+ }
+ public override string VisitCompoundModulusExpression(CGrammarParser.CompoundModulusExpressionContext context)
+ {
+ return this.BaseBinaryCompoundOperation(context.target(),
+ context.expression(),
+ "mod",
+ "modulus",
+ "AX");
+ }
+ public override string VisitCompoundBitwiseOrExpression(CGrammarParser.CompoundBitwiseOrExpressionContext context)
+ {
+ return this.BaseBinaryCompoundOperation(context.target(),
+ context.expression(),
+ "or",
+ "or",
+ "DX");
+ }
+ public override string VisitCompoundBitwiseXorExpression(CGrammarParser.CompoundBitwiseXorExpressionContext context)
+ {
+ return this.BaseBinaryCompoundOperation(context.target(),
+ context.expression(),
+ "xor",
+ "exclusive or",
+ "DX");
+ }
+ public override string VisitCompoundBitwiseAndExpression(CGrammarParser.CompoundBitwiseAndExpressionContext context)
+ {
+ return this.BaseBinaryCompoundOperation(context.target(),
+ context.expression(),
+ "and",
+ "and",
+ "DX");
+ }
+ public override string VisitCompoundBitwiseLeftShiftExpression(CGrammarParser.CompoundBitwiseLeftShiftExpressionContext context)
+ {
+ return this.BaseBinaryCompoundOperation(context.target(),
+ context.expression(),
+ "shl",
+ "left shift",
+ "DX");
+ }
+ public override string VisitCompoundBitwiseRightShiftExpression(CGrammarParser.CompoundBitwiseRightShiftExpressionContext context)
+ {
+ return this.BaseBinaryCompoundOperation(context.target(),
+ context.expression(),
+ "shr",
+ "right shift",
+ "DX");
+ }
+ public override string VisitIncrementPrefixExpression(CGrammarParser.IncrementPrefixExpressionContext context)
+ {
+ Target target = this.VisitTarget(context.target());
+ this.Instruction($"inc {target.Value}", "++i");
+ return target.Value;
+ }
+ public override string VisitDecrementPrefixExpression(CGrammarParser.DecrementPrefixExpressionContext context)
+ {
+ Target target = this.VisitTarget(context.target());
+ this.Instruction($"dec {target.Value}", "--i");
+ return target.Value;
+ }
+ public override string VisitIncrementPostfixExpression(CGrammarParser.IncrementPostfixExpressionContext context)
+ {
+ Target target = this.VisitTarget(context.target());
+ this.Instruction($"push {target.Value}", "i++");
+ this.Instruction($"inc {target.Value}");
+ this.Instruction("pop V0");
+ return "V0";
+ }
+ public override string VisitDecrementPostfixExpression(CGrammarParser.DecrementPostfixExpressionContext context)
+ {
+ Target target = this.VisitTarget(context.target());
+ this.Instruction($"push {target.Value}", "i--");
+ this.Instruction($"dec {target.Value}");
+ this.Instruction($"pop V0");
+ return "V0";
+ }
+} \ No newline at end of file