From 9fcbcedcda35394402b87d3b3e33353a48797d5d Mon Sep 17 00:00:00 2001 From: Larry Xue Date: Mon, 24 Aug 2020 00:15:15 -0400 Subject: [PATCH] fixed func calls --- c2logic/compiler.py | 28 +++++++++++++++------------- c2logic/instructions.py | 5 ++++- examples/func_calls.c | 12 +++++++++--- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/c2logic/compiler.py b/c2logic/compiler.py index a624f8f..1b77320 100644 --- a/c2logic/compiler.py +++ b/c2logic/compiler.py @@ -1,3 +1,4 @@ +import site from dataclasses import dataclass from pycparser import c_ast, parse_file @@ -44,11 +45,13 @@ class Compiler(c_ast.NodeVisitor): self.curr_function = None self.loop_start = None self.cond_jump_offset = None - ast = parse_file(filename, use_cpp=True, cpp_args=["-I", "include/"]) + ast = parse_file( + filename, use_cpp=True, cpp_args=["-I", site.getuserbase() + "/include/python3.8"] + ) self.visit(ast) #TODO actually handle functions properly init_call = FunctionCall("main") - preamble = [Set("__retaddr", "2"), init_call, End()] + preamble = [Set("__retaddr_main", "2"), init_call, End()] offset = len(preamble) #set function starts @@ -63,8 +66,10 @@ class Compiler(c_ast.NodeVisitor): for instruction in instructions: if isinstance(instruction, RelativeJump): instruction.func_start = function.start - if isinstance(instruction, FunctionCall): + elif isinstance(instruction, FunctionCall): instruction.func_start = self.functions[instruction.func_name].start + elif isinstance(instruction, Set) and instruction.dest.startswith("__retaddr"): + instruction.src += function.start out = ["\n".join(map(str, preamble))] out.extend( "\n".join(map(str, function.instructions)) for function in self.functions.values() @@ -121,12 +126,6 @@ class Compiler(c_ast.NodeVisitor): self.loop_start = None self.loop_end_jumps = None - def push_ret(self): - if self.curr_function.name == "main": - self.push(End()) - else: - self.push(Return()) - def optimize_psuedofunc_args(self, args): if self.opt_level >= 1: for i, arg in reversed(list(enumerate(args))): @@ -147,7 +146,7 @@ class Compiler(c_ast.NodeVisitor): #implicit return #needed unconditionally in case loop/if body is at end of function self.push(Set("__rax", "null")) - self.push(Return()) + self.push(Return(self.curr_function.name)) self.functions[func_name] = self.curr_function def visit_Decl(self, node): @@ -274,11 +273,14 @@ class Compiler(c_ast.NodeVisitor): def visit_Return(self, node): self.visit(node.expr) - self.push(Return()) + self.push(Return(self.curr_function.name)) def visit_FuncCall(self, node): name = node.name.name - args = node.args.exprs + if node.args is not None: + args = node.args.exprs + else: + args = [] #TODO avoid duplication in psuedo-function calls if name == "asm": arg = args[0] @@ -370,7 +372,7 @@ class Compiler(c_ast.NodeVisitor): for param, arg in zip(func.params, args): self.visit(arg) self.set_to_rax(param) - self.push(Set("__retaddr", self.curr_offset() + 2)) + self.push(Set("__retaddr_" + name, self.curr_offset() + 3)) self.push(FunctionCall(name)) def generic_visit(self, node): diff --git a/c2logic/instructions.py b/c2logic/instructions.py index 45f59ec..80c5050 100644 --- a/c2logic/instructions.py +++ b/c2logic/instructions.py @@ -71,8 +71,11 @@ class FunctionCall(Instruction): return f"jump {self.func_start} {JumpCondition.always}" class Return(Instruction): + def __init__(self, func_name: str): + self.func_name = func_name + def __str__(self): - return "set @counter __retaddr" + return f"set @counter __retaddr_{self.func_name}" class Print(Instruction): def __init__(self, val: str): diff --git a/examples/func_calls.c b/examples/func_calls.c index f06e5cb..935c27a 100644 --- a/examples/func_calls.c +++ b/examples/func_calls.c @@ -1,15 +1,21 @@ #include "c2logic/builtins.h" extern struct MindustryObject message1; -double factorial(int x) { +/*double factorial(int x) { int ret = 1; for (int i = 2; i <= x; i++) { ret *= x; } return ret; +}*/ + +double a(void) { + return 5; } void main(void) { - printd(factorial(4)); + printd(a()); print("\n"); - printd(factorial(5)); + /*printd(factorial(4)); + print("\n"); + printd(factorial(5));*/ printflush(message1); } \ No newline at end of file