fixing quite a few bugs
This commit is contained in:
		| @@ -52,11 +52,11 @@ class Generator: | ||||
|  | ||||
| 	def add_constant(self, value: Any, no_string: bool = False): | ||||
| 		existing_constant_name = self.constants_reverse.get(value, None) | ||||
| 		if existing_constant_name != None: return f"[.{existing_constant_name}]" | ||||
| 		if existing_constant_name != None: return f"[{existing_constant_name}]" | ||||
| 		self.constants["LC" + str(self.constant_counter)] = {"value": value, "no_string": no_string} | ||||
| 		self.constants_reverse[value] = "LC" + str(self.constant_counter) | ||||
| 		self.constant_counter += 1 | ||||
| 		return "[.LC" + str(self.constant_counter-1) + "]" | ||||
| 		return "[LC" + str(self.constant_counter-1) + "]" | ||||
| 	 | ||||
| 	def add_function(self, node: FunctionNode): | ||||
| 		self.functions[node.name] = { | ||||
|   | ||||
| @@ -32,6 +32,14 @@ class X86_64Generator(Generator): | ||||
| 		var_pos = self.get_var_pos(var_name, scope) | ||||
| 		 | ||||
| 		if isinstance(var_pos, str): # in a reg, not on the stack | ||||
| 			waste = { | ||||
| 				"rax": "eax", | ||||
| 				"rdi": "edi", | ||||
| 				"rsi": "esi" | ||||
| 			} | ||||
| 			if waste[var_pos] == reg: # literally useless | ||||
| 				return | ||||
|  | ||||
| 			if offset == 0: | ||||
| 				lines.append(f"mov {reg}, {var_pos}\n\t") | ||||
| 			elif offset == -8: | ||||
| @@ -248,7 +256,9 @@ class X86_64Generator(Generator): | ||||
|  | ||||
| 		for inst in node.statements: | ||||
| 			#self.function_lines.append(f"; {inst}\n\t") | ||||
| 			self.generate_InstructionNode(inst, self.function_lines) | ||||
| 			node_type = str(type(inst))[19:-2] | ||||
| 			getattr(self, f"generate_{node_type}")(inst, self.function_lines) | ||||
| 			#self.generate_InstructionNode(inst, self.function_lines) | ||||
|  | ||||
| 	def generate_InstructionNode(self, node: InstructionNode, lines = None): | ||||
| 		lines = lines or self.lines | ||||
| @@ -438,6 +448,7 @@ class X86_64Generator(Generator): | ||||
| 				if node.arguments[0].value != 0: | ||||
| 					lines.append(f"jmp .{node.arguments[1].name}\n\t") | ||||
| 			elif isinstance(node.arguments[0], VarRefNode): | ||||
| 				self.current_var_scope.table[node.arguments[0].var_name]["used"] = True # putting a variable in an if statement means we're accessing it | ||||
| 				self.get_variable(lines, node.arguments[0].var_name, "eax") | ||||
| 				lines.append(f"test eax, eax\n\t") | ||||
| 				lines.append(f"jnz .{node.arguments[1].name}\n\t") | ||||
| @@ -491,7 +502,7 @@ class X86_64Generator(Generator): | ||||
| 				"lesser": "setl" | ||||
| 			} | ||||
| 			lines.append(f"{instructions[node.instruction]} al\n\t") | ||||
| 			lines.append("movzx rax, al\n\t") | ||||
| 			lines.append("movzx eax, al\n\t") | ||||
|  | ||||
|  | ||||
| 			var_name = node.arguments[2].var_name | ||||
| @@ -513,7 +524,7 @@ class X86_64Generator(Generator): | ||||
| 				if isinstance(node.arguments[0], IntNode): | ||||
| 					lines.append(f"mov rax, {node.arguments[0].value}") | ||||
| 				elif isinstance(node.arguments[0], BoolNode): | ||||
| 					lines.append(f"mov rax, {int(node.arguments[0].value)}") | ||||
| 					lines.append(f"mov eax, {int(node.arguments[0].value)}") | ||||
| 				elif isinstance(node.arguments[0], FloatNode): | ||||
| 					lines.append(f"mov xmm0, {node.arguments[0].value}") | ||||
| 					#self.get_variable(lines, node.arguments[0].var_name, "rax") | ||||
| @@ -526,10 +537,11 @@ class X86_64Generator(Generator): | ||||
| 					#self.push("rax", lines) | ||||
| 				elif isinstance(node.arguments[0], VarRefNode): | ||||
| 					var = func_scope.lookup(node.arguments[0].var_name) | ||||
| 					 | ||||
| 					if var["type"] == StringNode: | ||||
| 						self.get_variable(self.function_lines, node.arguments[0].var_name, "rax", offset=0, scope=func["scope"]) | ||||
| 						self.get_variable(self.function_lines, node.arguments[0].var_name, "rdx", offset=-8, scope=func["scope"]) | ||||
| 					elif var["type"] == BoolNode: | ||||
| 						self.get_variable(self.function_lines, node.arguments[0].var_name, "eax", scope=func["scope"]) | ||||
| 					else: | ||||
| 						self.get_variable(self.function_lines, node.arguments[0].var_name, "rax", scope=func["scope"]) | ||||
| 			else: | ||||
| @@ -644,7 +656,7 @@ class X86_64Generator(Generator): | ||||
| 			f.write("section .data\n") | ||||
| 			for name, const in self.constants.items(): | ||||
| 				value = const["value"] | ||||
| 				f.write("." + name + ": ") | ||||
| 				f.write(name + ": ") | ||||
| 				value_type = type(value) | ||||
| 				if value_type == str: | ||||
| 					if not const["no_string"]: | ||||
|   | ||||
| @@ -128,6 +128,9 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode: | ||||
| 		elif token.type == TokenType.LABEL_DECLERATION: | ||||
| 			if current_node: | ||||
| 				scope.statements.append(current_node) | ||||
| 				if current_node_type == "func": | ||||
| 					scope = current_node | ||||
| 				current_node_type = None | ||||
| 				current_node = None | ||||
| 			scope.statements.append(LabelDecNode(token.value)) | ||||
| 		 | ||||
|   | ||||
| @@ -161,5 +161,5 @@ class X86_64Optimizer(Optimizer): | ||||
| 			PeepholeRule( | ||||
| 				match=[Instruction("mov", ["x", "x"])], | ||||
| 				replace=[] | ||||
| 			) | ||||
| 			), | ||||
| 		] | ||||
							
								
								
									
										38
									
								
								out.asm
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								out.asm
									
									
									
									
									
								
							| @@ -1,19 +1,47 @@ | ||||
| ; ~~~ Auto generated by the GroundPY compiler for Linux x86_64 targets. ~~~ | ||||
|  | ||||
| section .data | ||||
| LC0: db "yep!", 10, 0 | ||||
| LC1: equ $ - LC0 | ||||
| LC2: db "nope...", 10, 0 | ||||
| LC3: equ $ - LC2 | ||||
| section .text | ||||
| global _start | ||||
| _start:  | ||||
| mov rdi, 1 | ||||
| mov rsi, 4 | ||||
| call add | ||||
| mov rdi, rax | ||||
| mov rsi, 3 | ||||
| call greater | ||||
| test eax, eax | ||||
| jnz .yes | ||||
| jmp .no | ||||
| .yes:  | ||||
| mov rsi, LC0 | ||||
| mov rdx, LC1 | ||||
| push rdi | ||||
| mov rax, 1 | ||||
| mov rdi, 1 | ||||
| syscall  | ||||
| pop rdi | ||||
| mov rdi, 0 | ||||
| mov rax, 60 | ||||
| syscall  | ||||
| add:  | ||||
| .no:  | ||||
| mov rsi, LC2 | ||||
| mov rdx, LC3 | ||||
| push rdi | ||||
| mov rax, 1 | ||||
| mov rdi, 1 | ||||
| syscall  | ||||
| pop rdi | ||||
| mov rdi, 0 | ||||
| mov rax, 60 | ||||
| syscall  | ||||
| greater:  | ||||
| push rbp | ||||
| mov rbp, rsp | ||||
| mov rax, rdi | ||||
| add rax, rsi | ||||
| cmp rax, rsi | ||||
| setg al | ||||
| movzx eax, al | ||||
| pop rbp | ||||
| ret  | ||||
|   | ||||
							
								
								
									
										20
									
								
								test2.grnd
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								test2.grnd
									
									
									
									
									
								
							| @@ -1,9 +1,17 @@ | ||||
| fun -int !add -int &a -int &b | ||||
| 	add $a $b &a | ||||
| 	return $a | ||||
| fun -bool !greater -int &x -int &y | ||||
| 	greater $x $y &x | ||||
| 	return $x | ||||
| endfun | ||||
|  | ||||
| pusharg 1 | ||||
| pusharg 4 | ||||
| call !add &result | ||||
| end $result | ||||
| pusharg 3 | ||||
| call !greater &bigger | ||||
|  | ||||
| if $bigger %yes | ||||
| jump %no | ||||
| @yes | ||||
| stdout "yep!\n" | ||||
| end 0 | ||||
| @no | ||||
| stdout "nope...\n" | ||||
| end 0 | ||||
		Reference in New Issue
	
	Block a user
	 SpookyDervish
					SpookyDervish