From cc82d27b03738d7b866999593a3943ab777365c6 Mon Sep 17 00:00:00 2001 From: SpookyDervish <78246495+SpookyDervish@users.noreply.github.com> Date: Sat, 13 Sep 2025 15:48:41 +1000 Subject: [PATCH] stdin works i think --- generators/generator.py | 9 +++++++++ generators/x86_64.py | 35 +++++++++++++++++++++++++++++++- out | Bin 8864 -> 9040 bytes out.asm | 43 ++++++++++++++++++++++++++++++++++++++++ test2.grnd | 5 ++++- 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 out.asm diff --git a/generators/generator.py b/generators/generator.py index 8c4927f..32b6ac0 100644 --- a/generators/generator.py +++ b/generators/generator.py @@ -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, diff --git a/generators/x86_64.py b/generators/x86_64.py index cf77374..24ee65a 100644 --- a/generators/x86_64.py +++ b/generators/x86_64.py @@ -30,6 +30,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 = { @@ -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) diff --git a/out b/out index b73af82cb5e81262c9ad9930a854ca921cd8eec8..e03fddb92dca07090500a551c1d6f977c3b49bdc 100644 GIT binary patch delta 498 zcmZ4BdckdihWG?U1~_nFuwYDhazX zFfcK|j0V{X0-|8@$zk#ZMFmF9$sZN%8Tlt0D#-&~At5TD08|PD i2f!o)0}GI5nY>p?oAZJKL