summaryrefslogtreecommitdiff
path: root/Compiler/visitors/Targets.cs
blob: 10d97f4ac837ab904211b2739efb493f40dac684 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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");
    }
}