Browse Source

fixed func calls

rlbr-dev
Larry Xue 5 years ago
parent
commit
9fcbcedcda
  1. 28
      c2logic/compiler.py
  2. 5
      c2logic/instructions.py
  3. 12
      examples/func_calls.c

28
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):

5
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):

12
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);
}
Loading…
Cancel
Save