summaryrefslogtreecommitdiff
path: root/src/main/java/no/eliashaugsbakk/kompilator/AssemblyBuilder.java
blob: 4e8959011132080c413037100dc7bd6e24074326 (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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package no.eliashaugsbakk.kompilator;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AssemblyBuilder {
  Map<String, String> stringVariables = new HashMap<>();

  StringBuilder finalAssembly;
  StringBuilder text;
  StringBuilder rodata;
  StringBuilder data;


  private final static String exit = """
      mov rax, 60
      xor rdi, rdi
      syscall
      """;

  private final static String printHelloWorld = """
      mov rax, 1
      mov rdi, 1
      lea rsi, [hellostring]
      lea rdx, [hellolen]
      syscall
      """;

  public AssemblyBuilder() {
    this.finalAssembly = new StringBuilder(".intel_syntax noprefix\n.global _start\n");
    // CPU instructions
    this.text = new StringBuilder(".text\n_start:\n\n");
    // Read only data
    this.rodata = new StringBuilder("\n.section .rodata\n");
    // Global initialized variables, Read - Write
    this.data = new StringBuilder("\n.data\n");
  }

  String createAssembly(List<String> IR) {
    for (String line : IR) {
      line = line.trim();

      if (line.startsWith("print")) {
        handlePrint(line);
      } else if (line.contains("=")) {
        handleAssignment(line);
      }
    }
    this.text.append(exit);
    this.finalAssembly.append(text);
    this.finalAssembly.append(rodata);
    this.finalAssembly.append(data);
    return this.finalAssembly.toString();
  }

  private void handleAssignment(String line) {
    /* Example IR:
    variable_name: type = data
    str1: string = "Hello world"
     */
    String name = line.substring(0, line.indexOf(":"));

    String dataType = line.substring(line.indexOf(":") + 2, line.indexOf("=") - 1);

    String value = line.substring(line.indexOf("=") + 2);

    if (dataType.contains("string")) {
      assignString(name, value);
    } else {
      IO.println("err: Unknown data type: " + dataType);
    }
  }

  private void assignString(String name, String value) {
    value = value.substring(1, value.length() - 1);
    this.rodata.append(String.format("""
        %s: .ascii "%s"
        """, name, value));
    this.stringVariables.put(name, value);
  }

  void handlePrint(String line) {
    String variableName = line.substring(line.indexOf("(") + 1, line.lastIndexOf(")"));

    this.text.append(String.format("""
        mov rax, 1
        mov rdi, 1
        lea rsi, [%s]
        lea rdx, [%d]
        syscall
        
        """, variableName, this.stringVariables.get(variableName).length()));
  }
}