labels work im pretty sure

This commit is contained in:
SpookyDervish
2025-09-07 11:58:01 +10:00
parent bee2087ab4
commit cf1ea42232
12 changed files with 87 additions and 44 deletions

8
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,8 @@
{
"files.associations": {
"*.embeddedhtml": "html",
"*.spk": "code-text-binary",
"*.mem": "code-text-binary",
"stdio.h": "c"
}
}

BIN
a.out

Binary file not shown.

View File

@@ -10,6 +10,7 @@ class Generator:
self.output_path = output_path
self.variables = {}
self.constants = {}
self.labels = []
self.constants_reverse = {}
self.constant_counter = 0

View File

@@ -8,7 +8,7 @@ class X86_64Generator(Generator):
self.stack_size = 0
def init(self):
self.lines.append("global _start\n\n")
self.lines.append("global _start\n")
self.lines.append("_start:\n\t")
# generate code
@@ -105,7 +105,6 @@ class X86_64Generator(Generator):
def change_variable(self, var_name: str, new_value):
var_pos = self.get_var_pos(var_name)
print(self.variables[var_name]["type"])
if type(new_value) == IntNode: # we're changing a variable to a number
self.lines.append(f"mov QWORD [rsp + {var_pos}], {new_value.value}\n\t")
self.variables[var_name]["type"] = IntNode
@@ -135,7 +134,10 @@ class X86_64Generator(Generator):
elif type(new_value) == str: # we're changing a variable to the value of a register
self.lines.append(f"mov QWORD [rsp + {var_pos}], {new_value}\n\t")
self.variables[var_name]["type"] = IntNode
print(self.variables[var_name]["type"])
def generate_LabelDecNode(self, node: LabelDecNode):
self.labels.append(node.name)
self.lines.append("." + node.name + ":\n\t")
def generate_InstructionNode(self, node: InstructionNode):
### MISC ###
@@ -409,6 +411,15 @@ class X86_64Generator(Generator):
self.lines.append("mov rdi, 1\n\t") # a file descriptor of 1 is stdout
self.lines.append("syscall\n\t")
elif node.instruction == "jump":
if len(node.arguments) < 1: # example: "jump"
traceback(self.code, "TypeError", "jump expects atleast 1 argument.")
elif len(node.arguments) > 1: # example: "jump %label 123"
traceback(self.code, "TypeError", "jump expects at most 1 argument.")
elif not isinstance(node.arguments[0], LabelRefNode):
traceback(self.code, "TypeError", f"jump expects a label reference as the first argument, not \"{node.arguments[0]}\"")
self.lines.append(f"jmp .{node.arguments[0].name}\n\t")
else:
self.lines.append("; FUCK\n\t")
#raise NotImplementedError(f"A generate method hasn't been made for the \"{node.instruction}\" instruction.")
@@ -431,5 +442,5 @@ class X86_64Generator(Generator):
elif value_type == float or value_type == int:
f.write(f"dq {float(value)}")
f.write("\n")
f.write("\nsection .text\n")
f.write("section .text\n")
f.writelines(self.lines)

View File

@@ -3,6 +3,7 @@ from dataclasses import dataclass
from tokenizer import Token, TokenType
from typing import Optional, Any
from error import traceback
from console import console
@dataclass
@@ -100,8 +101,8 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode:
# todo: this is the absolute WORST way i could do this, but i could not care less lmao
# its not even performant......
for token in tokens:
#print(token.type)
if token.type == TokenType.INSTRUCTION:
if current_node:
scope.statements.append(current_node)
@@ -125,6 +126,11 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode:
else:
current_node = FunctionNode([], [], scope)
current_node_type = "func"
elif token.type == TokenType.LABEL_DECLERATION:
if current_node:
scope.statements.append(current_node)
current_node = None
scope.statements.append(LabelDecNode(token.value))
if current_node:
if token.type == TokenType.STRING:
@@ -199,9 +205,6 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode:
current_node.arguments.append(FunctionCallNode(token.value))
else:
traceback(code, "SyntaxError", "Expected instruction or function return type, got function reference.")
elif token.type == TokenType.LABEL_DECLERATION:
scope.statements.append(LabelDecNode(token.value))
elif token.type == TokenType.COMMENT:
continue

BIN
out

Binary file not shown.

35
out.asm
View File

@@ -1,38 +1,11 @@
; ~~~ Auto generated by the GroundPY compiler for Linux x86_64 targets. ~~~
section .data
.LC0: db "hiii", 0
.LC1: equ $ - .LC0
.LC2: db "", 10, 0
.LC3: equ $ - .LC2
section .text
global _start
_start:
; InstructionNode(instruction='set', parent=RootNode(statements=[..., InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='stdout', parent=..., arguments=[String]), InstructionNode(instruction='end', parent=..., arguments=[Int])]), arguments=[VariablePointer, Int])
mov rax, 123
push rax
; InstructionNode(instruction='set', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), ..., InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='stdout', parent=..., arguments=[String]), InstructionNode(instruction='end', parent=..., arguments=[Int])]), arguments=[VariablePointer, String])
mov QWORD [rsp + 0], 0
lea rax, [.LC0]
push rax
mov rax, .LC1
push rax
; InstructionNode(instruction='stdout', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), ..., InstructionNode(instruction='stdout', parent=..., arguments=[String]), InstructionNode(instruction='end', parent=..., arguments=[Int])]), arguments=[VariableReference])
mov rsi, [rsp + 8]
mov rdx, [rsp + 0]
mov rax, 1
mov rdi, 1
syscall
; InstructionNode(instruction='stdout', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), ..., InstructionNode(instruction='end', parent=..., arguments=[Int])]), arguments=[String])
mov rsi, .LC2
mov rdx, .LC3
mov rax, 1
mov rdi, 1
syscall
; InstructionNode(instruction='end', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='stdout', parent=..., arguments=[String]), ...]), arguments=[Int])
mov rax, 60
mov rdi, 0
syscall
; LabelDecleration
.myLabel:
; InstructionNode(instruction='jump', parent=RootNode(statements=[LabelDecleration, ...]), arguments=[LabelReference])
jmp .myLabel

BIN
test Normal file

Binary file not shown.

5
test.c Normal file
View File

@@ -0,0 +1,5 @@
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}

BIN
test.o Normal file

Binary file not shown.

45
test.s Normal file
View File

@@ -0,0 +1,45 @@
.file "test.c"
.text
.section .rodata
.LC0:
.string "Hello, World!"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
leaq .LC0(%rip), %rax
movq %rax, %rdi
call puts@PLT
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"
.section .note.GNU-stack,"",@progbits
.section .note.gnu.property,"a"
.align 8
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 8
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 8
4:

View File

@@ -1,5 +1,2 @@
set &x 123
set &x "hiii"
stdout $x
stdout "\n"
end 0
@myLabel
jump %myLabel