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 b73af82..e03fddb 100644 Binary files a/out and b/out differ diff --git a/out.asm b/out.asm new file mode 100644 index 0000000..ba544ef --- /dev/null +++ b/out.asm @@ -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 diff --git a/test2.grnd b/test2.grnd index af77f5a..9bbdc1b 100644 --- a/test2.grnd +++ b/test2.grnd @@ -1,2 +1,5 @@ -stdout "Hello, World!\n" +stdout "Type something: " +stdin &myString +stdout "You said: " +stdout $myString end 0 \ No newline at end of file