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.output_path = output_path
self.variables = {} self.variables = {}
self.constants = {} self.constants = {}
self.labels = []
self.constants_reverse = {} self.constants_reverse = {}
self.constant_counter = 0 self.constant_counter = 0

View File

@@ -8,7 +8,7 @@ class X86_64Generator(Generator):
self.stack_size = 0 self.stack_size = 0
def init(self): def init(self):
self.lines.append("global _start\n\n") self.lines.append("global _start\n")
self.lines.append("_start:\n\t") self.lines.append("_start:\n\t")
# generate code # generate code
@@ -105,7 +105,6 @@ class X86_64Generator(Generator):
def change_variable(self, var_name: str, new_value): def change_variable(self, var_name: str, new_value):
var_pos = self.get_var_pos(var_name) 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 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.lines.append(f"mov QWORD [rsp + {var_pos}], {new_value.value}\n\t")
self.variables[var_name]["type"] = IntNode 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 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.lines.append(f"mov QWORD [rsp + {var_pos}], {new_value}\n\t")
self.variables[var_name]["type"] = IntNode 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): def generate_InstructionNode(self, node: InstructionNode):
### MISC ### ### 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("mov rdi, 1\n\t") # a file descriptor of 1 is stdout
self.lines.append("syscall\n\t") 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: else:
self.lines.append("; FUCK\n\t") self.lines.append("; FUCK\n\t")
#raise NotImplementedError(f"A generate method hasn't been made for the \"{node.instruction}\" instruction.") #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: elif value_type == float or value_type == int:
f.write(f"dq {float(value)}") f.write(f"dq {float(value)}")
f.write("\n") f.write("\n")
f.write("\nsection .text\n") f.write("section .text\n")
f.writelines(self.lines) f.writelines(self.lines)

View File

@@ -3,6 +3,7 @@ from dataclasses import dataclass
from tokenizer import Token, TokenType from tokenizer import Token, TokenType
from typing import Optional, Any from typing import Optional, Any
from error import traceback from error import traceback
from console import console
@dataclass @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 # todo: this is the absolute WORST way i could do this, but i could not care less lmao
# its not even performant...... # its not even performant......
for token in tokens: for token in tokens:
#print(token.type)
if token.type == TokenType.INSTRUCTION: if token.type == TokenType.INSTRUCTION:
if current_node: if current_node:
scope.statements.append(current_node) scope.statements.append(current_node)
@@ -125,6 +126,11 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode:
else: else:
current_node = FunctionNode([], [], scope) current_node = FunctionNode([], [], scope)
current_node_type = "func" 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 current_node:
if token.type == TokenType.STRING: if token.type == TokenType.STRING:
@@ -200,9 +206,6 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode:
else: else:
traceback(code, "SyntaxError", "Expected instruction or function return type, got function reference.") 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: elif token.type == TokenType.COMMENT:
continue 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. ~~~ ; ~~~ Auto generated by the GroundPY compiler for Linux x86_64 targets. ~~~
section .data section .data
.LC0: db "hiii", 0
.LC1: equ $ - .LC0
.LC2: db "", 10, 0
.LC3: equ $ - .LC2
section .text section .text
global _start global _start
_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]) ; LabelDecleration
mov rax, 123 .myLabel:
push rax ; InstructionNode(instruction='jump', parent=RootNode(statements=[LabelDecleration, ...]), arguments=[LabelReference])
; 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]) jmp .myLabel
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

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 @myLabel
set &x "hiii" jump %myLabel
stdout $x
stdout "\n"
end 0