stdin works i think
This commit is contained in:
@@ -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,
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user