diff options
| author | Melodi <62381002+Melodi17@users.noreply.github.com> | 2026-03-17 20:49:22 +1000 |
|---|---|---|
| committer | Melodi <62381002+Melodi17@users.noreply.github.com> | 2026-03-17 20:49:22 +1000 |
| commit | 18868128e18d38b706e7df14e8e683e1a9739c17 (patch) | |
| tree | 6f0e0e5eee646f10cbad9c0c89c24d330bc58cc6 /Compiler/visitors | |
| parent | d87ab8af4c86a3fc6ee237444e372d87e536e3ef (diff) | |
chore: Initial commit
Diffstat (limited to 'Compiler/visitors')
| -rw-r--r-- | Compiler/visitors/Constants.cs | 50 | ||||
| -rw-r--r-- | Compiler/visitors/Definitions.cs | 132 | ||||
| -rw-r--r-- | Compiler/visitors/Expressions.cs | 154 | ||||
| -rw-r--r-- | Compiler/visitors/FlowControl.cs | 177 | ||||
| -rw-r--r-- | Compiler/visitors/Main.cs | 183 | ||||
| -rw-r--r-- | Compiler/visitors/Operations.cs | 305 | ||||
| -rw-r--r-- | Compiler/visitors/Targets.cs | 40 |
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 |
