stdin works i think

This commit is contained in:
SpookyDervish
2025-09-13 15:48:41 +10:00
parent 983e1e8a74
commit cc82d27b03
5 changed files with 90 additions and 2 deletions

View File

@@ -31,12 +31,15 @@ class Generator:
self.global_scope = SymbolTable()
self.current_var_scope = self.global_scope
self.constants = {}
self.buffers = {}
self.structs = {}
self.functions: dict[str, dict] = {}
self.labels = []
self.arg_list = []
self.constants_reverse = {}
self.constant_counter = 0
self.buffer_counter = 0
self.included_functions = []
def ground_type_to_node(self, ground_type: str):
if ground_type == "string":
@@ -58,6 +61,12 @@ class Generator:
self.constant_counter += 1
return "[LC" + str(self.constant_counter-1) + "]"
def add_buffer(self, size: int):
buffer_name = "BUF" + str(self.buffer_counter)
self.buffers[buffer_name] = size
self.buffer_counter += 1
return buffer_name
def add_function(self, node: FunctionNode):
self.functions[node.name] = {
"func": node,

View File

@@ -31,6 +31,8 @@ class X86_64Generator(Generator):
var = scope.lookup(var_name)
var_pos = self.get_var_pos(var_name, scope)
print(self.stack_size, var_name, var_pos)
if isinstance(var_pos, str): # in a reg, not on the stack
waste = {
"rax": "eax",
@@ -130,6 +132,7 @@ class X86_64Generator(Generator):
self.push("rax", lines)
lines.append(f"mov rax, {string_len[1:-1]}\n\t")
self.push("rax", lines)
print(self.stack_size)
elif type(starting_value) == BoolNode:
self.push("1" if starting_value.value else "0", lines)
@@ -140,7 +143,11 @@ class X86_64Generator(Generator):
lines.append(f"movsd [rsp], {starting_value}\n\t")
self.stack_size += 1
else:
self.push(starting_value, lines)
if starting_value.startswith("BUF"):
self.push(starting_value, lines) # push buffer
self.push("rax", lines) # push length
else:
self.push(starting_value, lines)
scope.define(var_name, {"stack_loc": stack_location, "type": var_type, "used": False})
def change_variable(self, lines, var_name: str, new_value, scope: SymbolTable = None):
@@ -261,6 +268,7 @@ class X86_64Generator(Generator):
#self.generate_InstructionNode(inst, self.function_lines)
def generate_InstructionNode(self, node: InstructionNode, lines = None):
print(node.instruction, self.stack_size)
lines = lines or self.lines
### MISC ###
@@ -424,6 +432,26 @@ class X86_64Generator(Generator):
lines.append("syscall\n\t")
self.pop("rdi", lines) # restore rdi
elif node.instruction == "stdin":
self.clamp_instruction_args(node, 1, 1)
arg = node.arguments[0]
if not isinstance(arg, VarPointerNode):
traceback(self.code, "TypeError", f"Argument 1 of stdin has to be a variable pointer, not \"{arg}\"")
buf_size = 255
buffer = self.add_buffer(buf_size)
lines.append("mov rax, 0\n\t") # sys_read syscall
lines.append("mov rdi, 0\n\t") # a file descriptor of 0 is stdin
lines.append(f"mov rsi, {buffer}\n\t")
lines.append(f"mov rdx, {buf_size}")
lines.append("syscall")
if not self.current_var_scope.table.get(arg.var_name):
self.create_variable(lines, arg.var_name, buffer, StringNode)
else:
self.change_variable(lines, arg.var_name, buffer)
elif node.instruction == "jump":
self.clamp_instruction_args(node, 1, 1)
if not isinstance(node.arguments[0], LabelRefNode):
@@ -668,6 +696,11 @@ class X86_64Generator(Generator):
elif value_type == float or value_type == int:
f.write(f"dq {float(value)}")
f.write("\n")
f.write("section .bss\n")
for buf, size in self.buffers.items():
f.write(f"{buf} resb {size}\n")
f.write("section .text\n")
optimizer = X86_64Optimizer(self.lines + self.function_lines)

BIN
out

Binary file not shown.

43
out.asm Normal file
View File

@@ -0,0 +1,43 @@
; ~~~ Auto generated by the GroundPY compiler for Linux x86_64 targets. ~~~
section .data
LC0: db "Type something: ", 0
LC1: equ $ - LC0
LC2: db "You said: ", 0
LC3: equ $ - LC2
section .bss
BUF0 resb 255
section .text
global _start
_start:
mov rsi, LC0
mov rdx, LC1
push rdi
mov rax, 1
mov rdi, 1
syscall
pop rdi
mov rax, 0
mov rdi, 0
mov rsi, BUF0
mov rdx, 255
syscall
push BUF0
push rax
mov rsi, LC2
mov rdx, LC3
push rdi
mov rax, 1
mov rdi, 1
syscall
pop rdi
mov rsi, [rsp + 8]
mov rdx, [rsp + 0]
push rdi
mov rax, 1
mov rdi, 1
syscall
pop rdi
mov rdi, 0
mov rax, 60
syscall

View File

@@ -1,2 +1,5 @@
stdout "Hello, World!\n"
stdout "Type something: "
stdin &myString
stdout "You said: "
stdout $myString
end 0