summaryrefslogtreecommitdiff
path: root/Compiler/visitors
diff options
context:
space:
mode:
Diffstat (limited to 'Compiler/visitors')
-rw-r--r--Compiler/visitors/Constants.cs50
-rw-r--r--Compiler/visitors/Definitions.cs132
-rw-r--r--Compiler/visitors/Expressions.cs154
-rw-r--r--Compiler/visitors/FlowControl.cs177
-rw-r--r--Compiler/visitors/Main.cs183
-rw-r--r--Compiler/visitors/Operations.cs305
-rw-r--r--Compiler/visitors/Targets.cs40
7 files changed, 0 insertions, 1041 deletions
diff --git a/Compiler/visitors/Constants.cs b/Compiler/visitors/Constants.cs
deleted file mode 100644
index 598c642..0000000
--- a/Compiler/visitors/Constants.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-namespace Q1.Compiler.visitors;
-
-using System.Text;
-
-public partial class CCompilerVisitor
-{
- public Encoding Encoding;
- public override string VisitIntConstant(CGrammarParser.IntConstantContext context)
- {
- string valueString = context.INT().GetText();
- if (int.TryParse(valueString, out int value))
- return $"{value}";
- else
- throw new CompilerException($"Invalid integer value: {valueString}");
- }
- public override string VisitHexConstant(CGrammarParser.HexConstantContext context)
- {
- string valueString = context.HEX().GetText();
- valueString = valueString[2..]; // Remove 0x
- return $"${valueString}";
- }
-
- public override object? VisitCharConstant(CGrammarParser.CharConstantContext context)
- {
- char c = context.LETTER().GetText()[1];
- return $"{this.Encoding.GetBytes(c.ToString())[0]}";
- }
-
- public override object? VisitStringConstant(CGrammarParser.StringConstantContext context)
- {
- string text = context.STRING().GetText()[1..^1];
-
- int? arrPtr = null;
-
- if (text.Length == 0)
- throw new CompilerException("Cannot create empty string");
-
- foreach (char c in text)
- {
- int itemPtr = Alloc(CType.Int.Size);
-
- if (arrPtr == null)
- arrPtr = itemPtr;
-
- this.DynamicMove(CType.Int, $"{this.Encoding.GetBytes(c.ToString())[0]}", $"[${itemPtr:X4}]");
- }
-
- return $"${arrPtr:X4}";
- }
-} \ No newline at end of file
diff --git a/Compiler/visitors/Definitions.cs b/Compiler/visitors/Definitions.cs
deleted file mode 100644
index c27405e..0000000
--- a/Compiler/visitors/Definitions.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-namespace Q1.Compiler.visitors;
-
-public partial class CCompilerVisitor
-{
- private List<(CGrammarParser.FunctionDefinitionContext context,
- FunctionReference function, FunctionOverload overload,
- List<string> paramNames, List<CType> paramTypes)> _functionBodies = new();
-
- private VariableReference FindVariable(string varName)
- {
- foreach (Dictionary<string, VariableReference> variables in this._variableStack)
- {
- if (variables.TryGetValue(varName, out VariableReference? reference))
- return reference;
- }
-
- throw new CompilerException($"Variable {varName} could not be found in current scope.");
- }
- private int Alloc(int size)
- {
- int loc = CCompilerVisitor._memPointer;
- CCompilerVisitor._memPointer += size;
-
- return loc;
- }
- private FunctionReference CreateOrGetFunctionReference(string name, CType type)
- {
- FunctionReference? function = this._methods.FirstOrDefault(x => x.Name == name);
- if (function != null)
- return function;
-
- function = new FunctionReference(name, type);
- this._methods.Add(function);
-
- return function;
- }
- private FunctionReference GetFunctionReference(string name)
- {
- FunctionReference? function = this._methods.FirstOrDefault(x => x.Name == name);
- if (function != null)
- return function;
-
- throw new CompilerException($"Function '{name}' has not been defined or prototyped.");
- }
-
- public override string? VisitFunctionPrototype(CGrammarParser.FunctionPrototypeContext context)
- {
- string functionName = context.name.Text;
- CType type = this.VisitCType(context._type);
-
- List<CType> parameterTypes = context._types.Select(this.VisitCType).ToList();
- List<string> parameterNames = context._params.Select(x => x.Text).ToList();
-
- FunctionReference function = this.CreateOrGetFunctionReference(functionName, type);
- FunctionOverload overload =
- function.CreateOverloadWithoutBody(parameterNames, parameterTypes);
-
- function.Overloads.Add(overload);
-
- return null;
- }
- public override string? VisitFunctionDefinition(
- CGrammarParser.FunctionDefinitionContext context)
- {
- string functionName = context.name.Text;
- CType type = this.VisitCType(context.rtype);
-
- List<CType> paramTypes = context._types.Select(this.VisitCType).ToList();
- List<string> paramNames = context._params.Select(x => x.Text).ToList();
-
- FunctionReference function = this.CreateOrGetFunctionReference(functionName, type);
- FunctionOverload overload = function.CreateOverloadWithBody(paramNames, paramTypes);
-
- this._functionBodies.Add((context, function, overload, paramNames, paramTypes));
-
- return null;
- }
- private void VisitFunctionBody(
- CGrammarParser.FunctionDefinitionContext context,
- FunctionReference function,
- FunctionOverload overload,
- List<string> paramNames,
- List<CType> paramTypes)
- {
- this.Branch(function.GetBranchName(overload), function.GetBranchFriendlyName(overload));
-
- if (paramNames.Count > 0)
- this.Instruction("pop V0", "preserve function return address");
-
- Dictionary<string, VariableReference> scope = this.EnterScope();
- foreach ((string paramName, CType paramType) in paramNames.Zip(paramTypes))
- {
- int addr = this.Alloc(paramType.Size);
- scope[paramName] = new(addr, paramType);
- this.Instruction($"pop [${addr:X4}]", $"param {paramType} {paramName}");
- }
-
- if (paramNames.Count > 0)
- this.Instruction("push V0", "restore function return address");
-
- this.VisitChildren(context);
- this.ExitScope();
-
- this.Instruction("mov 0, V0", "fallback return 0");
- this.Instruction("ret");
-
- this.Blank();
- }
- public override string? VisitVariableDeclaration(
- CGrammarParser.VariableDeclarationContext context)
- {
- CType type = this.VisitCType(context.type());
- int addr = this.Alloc(CType.Int.Size);
- string name = context.name.Text;
-
- Dictionary<string, VariableReference> scope = this._variableStack.Peek();
- if (scope.ContainsKey(name))
- throw new CompilerException($"Variable {name} already exists in current scope.");
-
- scope[name] = new VariableReference(addr, type);
- string initialValue = "0";
-
- if (context.value != null)
- {
- initialValue = this.VisitExpression(context.value);
- }
-
- this.DynamicMove(CType.Int, initialValue, $"[${addr:X4}]", $"int {name} = {initialValue}");
-
- return null;
- }
-} \ No newline at end of file
diff --git a/Compiler/visitors/Expressions.cs b/Compiler/visitors/Expressions.cs
deleted file mode 100644
index 1cc4291..0000000
--- a/Compiler/visitors/Expressions.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-namespace Q1.Compiler.visitors;
-
-public partial class CCompilerVisitor
-{
- private string VisitExpression(CGrammarParser.ExpressionContext expression)
- {
- string? expressionString = this.Visit(expression) as string;
- if (expressionString == null)
- throw new CompilerException("Expression did not return a string");
-
- return expressionString;
- }
-
- public override string VisitCallExpression(CGrammarParser.CallExpressionContext context)
- {
- string functionName = context.ID().GetText();
-
- FunctionReference function = this.GetFunctionReference(functionName);
- FunctionOverload overload = function.GetOverload(context._params.Count);
-
- // We reverse arugments so when we perform pop, its in the right order
- CGrammarParser.ExpressionContext[] argumentsReversed = context._params.Reverse().ToArray();
-
- for (int i = 0; i < argumentsReversed.Length; i++)
- {
- CGrammarParser.ExpressionContext argument = argumentsReversed[i];
- string result = this.VisitExpression(argument);
-
- int indexReverse = argumentsReversed.Length - i - 1;
-
- this.Instruction(
- $"push {result}", $"arg {overload.ParameterTypes[indexReverse]} {overload.ParameterNames[indexReverse]}");
- }
-
- this.Instruction(
- $"call {function.GetBranchName(overload)}", function.GetBranchFriendlyName(overload));
-
- return "V0";
- }
- public override string VisitParenthesizedExpression(
- CGrammarParser.ParenthesizedExpressionContext context)
- {
- return this.VisitExpression(context.expression());
- }
- public override string VisitVariableExpression(CGrammarParser.VariableExpressionContext context)
- {
- string varName = context.ID().GetText();
- VariableReference reference = this.FindVariable(varName);
-
- return $"[${reference.Address:X4}]";
- }
- public override string VisitAssignmentExpression(
- CGrammarParser.AssignmentExpressionContext context)
- {
- Target target = this.VisitTarget(context.target());
- string value = this.VisitExpression(context.expression());
-
- this.DynamicMove(target.Type, value, target.Value, $"{target.Value} = {value}");
- return target.Value;
- }
- public override string VisitTernaryExpression(CGrammarParser.TernaryExpressionContext context)
- {
- string cond = this.VisitExpression(context.cond);
-
- string thenBranch = this.GenerateBranchLabel("then");
- string endBranch = this.GenerateBranchLabel("end");
- string result;
-
- // Else branch is first since it saves us from having to perform a NOT operation.
- // If cond, jump to then, else fall through to else, then jump to end
-
- this.Instruction($"bz {cond}", "check ternary condition");
- this.Instruction($"jmp {thenBranch}");
-
- result = this.VisitExpression(context.@else);
- this.Instruction($"mov {result}, V0", "store ternary fail result");
- this.Instruction($"jmp {endBranch}");
-
- this.Branch(thenBranch);
- result = this.VisitExpression(context.then);
- this.Instruction($"mov {result}, V0", "store ternary success result");
-
- this.Branch(endBranch);
-
- return "V0";
- }
- public override string VisitAddressOfExpression(
- CGrammarParser.AddressOfExpressionContext context)
- {
- Target target = this.VisitTarget(context.target());
-
- return target.Address;
- }
- public override string VisitDereferenceExpression(
- CGrammarParser.DereferenceExpressionContext context)
- {
- string value = this.VisitExpression(context.expression());
-
- this.Instruction($"mov {value}, V0", "move pointer into register for dereference");
- return "[V0]";
- }
-
- public override object? VisitIndexExpression(CGrammarParser.IndexExpressionContext context)
- {
- Target obj = this.VisitTarget(context.obj);
- if (obj.Type is not CTypePtr ptr)
- throw new CompilerException("Indexer target was not a pointer!");
-
- this.Instruction($"push {obj.Value}", "store index obj");
-
- string indexer = this.VisitExpression(context.indexer);
-
- this.Instruction($"mov {indexer}, V1", "store indexer");
- this.Instruction($"pop V0", "restore index obj");
- this.Instruction($"mul V1, {ptr.Sub.Size}", $"multiply indexer by {ptr.Sub.Size}");
- this.Instruction($"add AX, V0", "add indexer and index obj");
- this.Instruction($"mov AX, V0", "move to general purpose register");
- return "[V0]";
- }
-
- public override object? VisitArrayExpression(CGrammarParser.ArrayExpressionContext context)
- {
- CType type = this.VisitCType(context.type());
- int? arrPtr = null;
-
- int length = context.INT() != null
- ? int.Parse(context.INT().GetText())
- : context._params.Count;
-
- if (length == 0)
- throw new CompilerException("Cannot create empty array");
-
- foreach (CGrammarParser.ExpressionContext? param in context._params)
- {
- int itemPtr = Alloc(type.Size);
-
- if (arrPtr == null)
- arrPtr = itemPtr;
-
- string value = this.VisitExpression(param);
- this.DynamicMove(type, value, $"[${itemPtr:X4}]");
- }
-
- int remainingSize = (length - context._params.Count) * type.Size;
- if (remainingSize < 0)
- throw new CompilerException("Array length larger than specified length");
- int blockPtr = Alloc(remainingSize);
-
- if (arrPtr == null)
- arrPtr = blockPtr;
-
- return $"${arrPtr:X4}";
- }
-} \ No newline at end of file
diff --git a/Compiler/visitors/FlowControl.cs b/Compiler/visitors/FlowControl.cs
deleted file mode 100644
index 944595d..0000000
--- a/Compiler/visitors/FlowControl.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-namespace Q1.Compiler.visitors;
-
-public partial class CCompilerVisitor
-{
- public override string? VisitBlock(CGrammarParser.BlockContext context)
- {
- this.EnterScope();
-
- this.VisitChildren(context);
-
- this.ExitScope();
-
- return null;
- }
- public override string? VisitReturnStatement(CGrammarParser.ReturnStatementContext context)
- {
- if (context.expression() != null)
- {
- string expression = this.VisitExpression(context.expression());
- this.Instruction($"mov {expression}, V0", "return value");
- this.Instruction($"ret");
- }
- else
- this.Instruction("ret");
-
- return null;
- }
- public override string? VisitIfStatement(CGrammarParser.IfStatementContext context)
- {
- string cond = this.VisitExpression(context.expression());
- string endBranch = this.GenerateBranchLabel("end");
-
- if (context.@else != null)
- {
- this.Instruction($"bz {cond}", "check if condition");
- // Else branch is first since it saves us from having to perform a NOT operation.
- // If cond, jump to then, else fall through to else, then jump to end
-
- string thenBranch = this.GenerateBranchLabel("then");
-
- this.Instruction($"jmp {thenBranch}");
-
- this.GeneratedComment("if failed");
- if (context.@else != null)
- this.Visit(context.@else);
- this.Instruction($"jmp {endBranch}");
-
- this.Branch(thenBranch, "if succeeded");
- this.Visit(context.then);
- }
- else
- {
- this.Instruction($"not {cond}");
- this.Instruction($"bz", "check if condition");
- this.Instruction($"jmp {endBranch}", "if succeeds, continue, else jump to end");
- this.Visit(context.then);
- }
-
- this.Branch(endBranch);
-
- return null;
- }
- public override string? VisitForExprStatement(CGrammarParser.ForExprStatementContext context)
- {
- string bodyBranch = this.GenerateBranchLabel("body");
- string endBranch = this.GenerateBranchLabel("end");
-
- context.LoopBodyBranch = bodyBranch;
- context.LoopEndBranch = endBranch;
-
- this.EnterScope();
- this.Visit(context.initializer);
-
- this.Branch(bodyBranch);
- string cond = this.VisitExpression(context.cond);
-
- this.Instruction($"not {cond}");
- this.Instruction($"bz");
- this.Instruction($"jmp {endBranch}", "if for condition fails, jump to end");
-
- this.Visit(context.body);
- this.Visit(context.post);
-
- this.Branch(endBranch);
- this.ExitScope();
-
- return null;
- }
- public override string? VisitForDeclStatement(CGrammarParser.ForDeclStatementContext context)
- {
- string bodyBranch = this.GenerateBranchLabel("body");
- string endBranch = this.GenerateBranchLabel("end");
-
- context.LoopBodyBranch = bodyBranch;
- context.LoopEndBranch = endBranch;
-
- this.EnterScope();
- this.Visit(context.initializer);
-
- this.Branch(bodyBranch);
- string cond = this.VisitExpression(context.cond);
-
- this.Instruction($"not {cond}");
- this.Instruction($"bz");
- this.Instruction($"jmp {endBranch}", "if for condition fails, jump to end");
-
- this.Visit(context.body);
- this.Visit(context.post);
-
- this.Instruction($"jmp {bodyBranch}");
-
- this.Branch(endBranch);
- this.ExitScope();
-
- return null;
- }
- public override string? VisitWhileStatement(CGrammarParser.WhileStatementContext context)
- {
- string bodyBranch = this.GenerateBranchLabel("body");
- string endBranch = this.GenerateBranchLabel("end");
-
- context.LoopBodyBranch = bodyBranch;
- context.LoopEndBranch = endBranch;
-
- this.Branch(bodyBranch);
- string cond = this.VisitExpression(context.cond);
-
- this.Instruction($"not {cond}");
- this.Instruction($"bz");
- this.Instruction($"jmp {endBranch}", "if while condition fails, jump to end");
-
- this.Visit(context.body);
- this.Instruction($"jmp {bodyBranch}");
-
- this.Branch(endBranch);
-
- return null;
- }
- public override string? VisitDoWhileStatement(CGrammarParser.DoWhileStatementContext context)
- {
- string bodyBranch = this.GenerateBranchLabel("body");
- string endBranch = this.GenerateBranchLabel("end");
-
- context.LoopBodyBranch = bodyBranch;
- context.LoopEndBranch = endBranch;
-
- this.Branch(bodyBranch);
- this.Visit(context.body);
-
- string cond = this.VisitExpression(context.cond);
-
- this.Instruction($"bz {cond}");
- this.Instruction($"jmp {bodyBranch}", "if while condition succeeds, jump back to start");
-
- this.Branch(endBranch);
-
- return null;
- }
- public override string? VisitBreakStatement(CGrammarParser.BreakStatementContext context)
- {
- if (context.LoopEndBranch == null)
- throw new CompilerException("Cannot break, not inside loop with end");
-
- this.Instruction($"jmp {context.LoopEndBranch}", "break");
-
- return null;
- }
- public override string? VisitContinueStatement(CGrammarParser.ContinueStatementContext context)
- {
- if (context.LoopBodyBranch == null)
- throw new CompilerException("Cannot skip body (continue), not inside loop with body");
-
- this.Instruction($"jmp {context.LoopBodyBranch}", "continue");
-
- return null;
- }
-} \ No newline at end of file
diff --git a/Compiler/visitors/Main.cs b/Compiler/visitors/Main.cs
deleted file mode 100644
index 3b32399..0000000
--- a/Compiler/visitors/Main.cs
+++ /dev/null
@@ -1,183 +0,0 @@
-namespace Q1.Compiler.visitors;
-
-using System.Text;
-using Antlr4.Runtime.Tree;
-using Q1.Emulator;
-
-public partial class CCompilerVisitor : CGrammarBaseVisitor<object?>
-{
- private int _branchCount = 1;
- private List<string> _instructions = new();
- private Stack<Dictionary<string, VariableReference>> _variableStack = new();
- private List<FunctionReference> _methods = new();
- private static int _memLowest = Q1Layout.FreeMemoryStart;
- private static int _memPointer = CCompilerVisitor._memLowest;
-
- private const int ColumnWidth = 30;
-
- public readonly CommentCompilationMode CommentMode;
-
- public CCompilerVisitor(CommentCompilationMode commentMode, Encoding encoding)
- {
- this.CommentMode = commentMode;
- this.Encoding = encoding;
- }
-
- private string GenerateBranchLabel(string type)
- {
- return $"_{type}_{this._branchCount++}";
- }
- private void Instruction(string instruction, string? generatedComment = null)
- {
- this._instructions.Add($" {instruction}");
- if (generatedComment != null)
- this.CommentLastInstruction(generatedComment);
- }
- private void Blank()
- {
- this._instructions.Add("");
- }
- private void Branch(string name, string? generatedComment = null)
- {
- this._instructions.Add($"{name}:");
- if (generatedComment != null)
- this.CommentLastInstruction(generatedComment);
- }
- private void UserComment(string comment)
- {
- if (this.CommentMode.HasFlag(CommentCompilationMode.UserDefined))
- this._instructions.Add($" ; {comment}");
- }
-
- private void GeneratedComment(string comment)
- {
- if (this.CommentMode.HasFlag(CommentCompilationMode.Generated))
- this._instructions.Add($"{"".PadRight(CCompilerVisitor.ColumnWidth)}; {comment}");
- }
-
- private void CommentLastInstruction(string comment)
- {
- if (!this.CommentMode.HasFlag(CommentCompilationMode.Generated))
- return;
-
- if (this._instructions.Count == 0)
- throw new Exception("Cannot add comment to last instruction, there are none");
-
- string lastInstruction = this._instructions[^1];
- lastInstruction = $"{lastInstruction.PadRight(CCompilerVisitor.ColumnWidth)}; {comment}";
-
- this._instructions[^1] = lastInstruction;
- }
-
-
- public IEnumerable<string> Compile(CGrammarParser.ProgramContext program)
- {
- this.Instruction("jmp _main");
- this.Visit(program);
-
- foreach ((CGrammarParser.FunctionDefinitionContext context,
- FunctionReference function, FunctionOverload overload,
- List<string> paramNames, List<CType> paramTypes) in this._functionBodies)
- this.VisitFunctionBody(context, function, overload, paramNames, paramTypes);
-
- return this._instructions;
- }
-
- private Dictionary<string, VariableReference> EnterScope()
- {
- Dictionary<string, VariableReference> scope = new();
- this._variableStack.Push(scope);
-
- return scope;
- }
- private void ExitScope()
- {
- foreach ((string key, VariableReference value) in this._variableStack.Peek())
- {
- // CCompilerVisitor._memPointer -= value.Type.Size;
- // if (CCompilerVisitor._memPointer < CCompilerVisitor._memLowest)
- // throw new CompilerException("Memory pointer is lower than mem lowest!");
- }
-
- // Delete scope
- this._variableStack.Pop();
- }
-
- public void DynamicMove(CType type, string source, string dest, string? comment = null)
- {
- if (type.Size == 1)
- this.Instruction($"movb {source}, {dest}", comment);
- else if (type.Size == 2)
- this.Instruction($"mov {source}, {dest}", comment);
- else
- throw new CompilerException($"Cannot move {type.Size} bytes {source} to {dest}");
- }
-
- private CType VisitCType(CGrammarParser.TypeContext typeContext)
- {
- return GetCType(typeContext.GetText().Trim());
- }
-
- private CType GetCType(string type)
- {
- return type switch
- {
- "int" => CType.Int,
- "char" => CType.Char,
- _ when type.EndsWith("*") => new CTypePtr(this.GetCType(type[..^1])),
- _ => throw new CompilerException($"Unknown CTYPE '{type}'")
- };
- }
-
- public override object? VisitErrorNode(IErrorNode node)
- {
- if (node.Symbol.Type == CGrammarParser.COMMENT)
- {
- // strip // and \n and whitespace
- string comment = node
- .Symbol.Text
- .TrimStart("//")
- .TrimEnd('\n')
- .Trim();
-
- this.UserComment(comment);
- }
-
- if (node.Symbol.Type == CGrammarParser.DIRECTIVE)
- {
- // strip // and \n and whitespace
- string directive = node
- .Symbol.Text
- .TrimStart("#")
- .TrimEnd('\n')
- .Trim();
-
- this.Instruction(directive);
- }
-
- return base.VisitErrorNode(node);
- }
-
- public override object? Visit(IParseTree tree)
- {
- if (tree is Context childCtx && tree.Parent is Context ctx)
- ctx.SyncProps(childCtx);
-
- return base.Visit(tree);
- }
-
- /// <summary>
- /// Basically identical to base version, except calls Visit on each child, making Visit not redundant.
- /// </summary>
- public override object? VisitChildren(IRuleNode node)
- {
- object? result = this.DefaultResult;
- int childCount = node.ChildCount;
- for (int i = 0; i < childCount && this.ShouldVisitNextChild(node, result); ++i)
- {
- object? nextResult = this.Visit(node.GetChild(i));
- result = this.AggregateResult(result, nextResult);
- }
- return result;
- }
-} \ No newline at end of file
diff --git a/Compiler/visitors/Operations.cs b/Compiler/visitors/Operations.cs
deleted file mode 100644
index 8483747..0000000
--- a/Compiler/visitors/Operations.cs
+++ /dev/null
@@ -1,305 +0,0 @@
-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
diff --git a/Compiler/visitors/Targets.cs b/Compiler/visitors/Targets.cs
deleted file mode 100644
index 10d97f4..0000000
--- a/Compiler/visitors/Targets.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-namespace Q1.Compiler.visitors;
-
-public partial class CCompilerVisitor
-{
- private Target VisitTarget(CGrammarParser.TargetContext target)
- {
- Target? expressionString = this.Visit(target) as Target;
- if (expressionString == null)
- throw new CompilerException("Target did not return a target");
-
- return expressionString;
- }
-
- public override Target VisitVariableTarget(CGrammarParser.VariableTargetContext context)
- {
- string varName = context.ID().GetText();
- VariableReference reference = this.FindVariable(varName);
-
- return new Target(reference.Type, $"[${reference.Address:X4}]", $"${reference.Address:X4}");
- }
-
- public override object? VisitIndexerTarget(CGrammarParser.IndexerTargetContext context)
- {
- Target obj = this.VisitTarget(context.obj);
- if (obj.Type is not CTypePtr ptr)
- throw new CompilerException("Indexer target was not a pointer!");
-
- this.Instruction($"push {obj.Value}", "store index obj");
-
- string indexer = this.VisitExpression(context.indexer);
-
- this.Instruction($"mov {indexer}, V1", "store indexer");
- this.Instruction($"pop V0", "restore index obj");
- this.Instruction($"mul V1, {ptr.Sub.Size}", $"multiply indexer by {ptr.Sub.Size}");
- this.Instruction($"add AX, V0", "add indexer and index obj");
- this.Instruction($"mov AX, V0", "move to general purpose register");
-
- return new Target(ptr.Sub, $"[V0]", $"V0");
- }
-} \ No newline at end of file