fixing struct regurns
This commit is contained in:
parent
5c38115119
commit
0aec47e985
|
@ -9,7 +9,8 @@ Ty2 := struct {
|
|||
}
|
||||
|
||||
main := fn(): int {
|
||||
inst := Ty2.{ ty: Ty.{ a: 4, b: 1 }, c: 3 };
|
||||
finst := Ty2.{ ty: Ty.{ a: 4, b: 1 }, c: 3 };
|
||||
inst := odher_pass(finst);
|
||||
if inst.c == 3 {
|
||||
return pass(&inst.ty);
|
||||
}
|
||||
|
@ -19,3 +20,7 @@ main := fn(): int {
|
|||
pass := fn(t: *Ty): int {
|
||||
return t.a - t.b;
|
||||
}
|
||||
|
||||
odher_pass := fn(t: Ty2): Ty2 {
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -388,7 +388,7 @@ impl<'a> Codegen<'a> {
|
|||
let fn_label = self.labels[frame.label as usize].clone();
|
||||
|
||||
log::dbg!("fn-args");
|
||||
let mut parama = 2..12;
|
||||
let mut parama = 3..12;
|
||||
for (arg, &ty) in args.iter().zip(fn_label.args.iter()) {
|
||||
let loc = self.load_arg(ty, &mut parama);
|
||||
self.vars.push(Variable {
|
||||
|
@ -694,18 +694,50 @@ impl<'a> Codegen<'a> {
|
|||
} => {
|
||||
let func = self.get_label(*id);
|
||||
let fn_label = self.labels[func as usize].clone();
|
||||
let mut parama = 2..12;
|
||||
let mut parama = 3..12;
|
||||
for (earg, &ty) in args.iter().zip(fn_label.args.iter()) {
|
||||
let arg = self.expr(earg, Some(ty))?;
|
||||
self.assert_ty(earg.pos(), ty, arg.ty);
|
||||
self.pass_arg(arg, &mut parama);
|
||||
}
|
||||
self.code.call(func);
|
||||
|
||||
let size = self.size_of(fn_label.ret);
|
||||
let loc = match size {
|
||||
0 => Loc::Imm(0),
|
||||
8 => Loc::RegRef(1),
|
||||
16 => {
|
||||
let stack = self.alloc_stack(16);
|
||||
Loc::Stack(stack)
|
||||
}
|
||||
24..=u64::MAX => {
|
||||
let stack = self.alloc_stack(size as u32);
|
||||
let reg = self.gpa.allocate();
|
||||
self.code.encode(instrs::cp(reg.0, 1));
|
||||
self.code
|
||||
.encode(instrs::addi64(reg.0, STACK_PTR, stack as u64));
|
||||
self.code.encode(instrs::cp(1, reg.0));
|
||||
self.gpa.free(reg);
|
||||
Loc::Stack(stack)
|
||||
}
|
||||
s => todo!("call return size: {}", s),
|
||||
};
|
||||
|
||||
self.code.call(func);
|
||||
|
||||
match size {
|
||||
0 => {}
|
||||
8 => {}
|
||||
16 => {
|
||||
if let Loc::Stack(stack) = loc {
|
||||
self.store_stack(1, stack, 16);
|
||||
}
|
||||
}
|
||||
24..=u64::MAX => {}
|
||||
s => todo!("call return size: {}", s),
|
||||
}
|
||||
|
||||
Some(Value {
|
||||
ty: self.ret,
|
||||
loc: Loc::Reg(reg),
|
||||
ty: fn_label.ret,
|
||||
loc,
|
||||
})
|
||||
}
|
||||
E::Ident { name, id, .. } => {
|
||||
|
@ -721,13 +753,27 @@ impl<'a> Codegen<'a> {
|
|||
if let Some(val) = val {
|
||||
let val = self.expr(val, Some(self.ret))?;
|
||||
self.assert_ty(pos, self.ret, val.ty);
|
||||
self.assign(
|
||||
Value {
|
||||
ty: self.ret,
|
||||
loc: Loc::RegRef(1),
|
||||
},
|
||||
val,
|
||||
);
|
||||
let size = self.size_of(val.ty);
|
||||
match size {
|
||||
8 => {
|
||||
let val = self.loc_to_reg(val.loc);
|
||||
self.code.encode(instrs::cp(1, val.0));
|
||||
self.gpa.free(val);
|
||||
}
|
||||
16 => {
|
||||
let (ptr, off) = self.loc_to_ptr(val.loc);
|
||||
self.code.encode(instrs::ld(1, ptr.0, off, 16));
|
||||
self.gpa.free(ptr);
|
||||
}
|
||||
24..=u64::MAX => {
|
||||
let (ptr, off) = self.loc_to_ptr(val.loc);
|
||||
self.code.encode(instrs::addi64(ptr.0, ptr.0, off));
|
||||
self.code
|
||||
.encode(instrs::bmc(ptr.0, 1, size.try_into().unwrap()));
|
||||
self.gpa.free(ptr);
|
||||
}
|
||||
s => todo!("return size: {}", s),
|
||||
};
|
||||
}
|
||||
self.ret_relocs.push(RetReloc {
|
||||
offset: self.code.code.len() as u32,
|
||||
|
@ -847,13 +893,15 @@ impl<'a> Codegen<'a> {
|
|||
None
|
||||
}
|
||||
E::BinOp { left, op, right } => {
|
||||
if op == T::Assign {
|
||||
let left = self.expr(left, expeted)?;
|
||||
let right = self.expr(right, Some(left.ty))?;
|
||||
if op == T::Assign {
|
||||
return self.assign(left, right);
|
||||
}
|
||||
|
||||
let left = self.expr(left, expeted)?;
|
||||
let lhs = self.loc_to_reg(left.loc);
|
||||
let right = self.expr(right, Some(left.ty))?;
|
||||
let rhs = self.loc_to_reg(right.loc);
|
||||
|
||||
let op = match op {
|
||||
|
@ -1062,6 +1110,7 @@ impl<'a> Codegen<'a> {
|
|||
todo!("expected stack location, got {:?}", value.loc);
|
||||
};
|
||||
self.code.encode(instrs::addi64(p, STACK_PTR, stack));
|
||||
return;
|
||||
}
|
||||
|
||||
match value.loc {
|
||||
|
@ -1254,8 +1303,8 @@ mod tests {
|
|||
fn generate(input: &'static str, output: &mut String) {
|
||||
let path = "test";
|
||||
let arena = crate::parser::Arena::default();
|
||||
let mut parser = super::parser::Parser::new(input, path, &arena);
|
||||
let exprs = parser.file();
|
||||
let mut parser = super::parser::Parser::new(&arena);
|
||||
let exprs = parser.file(input, path);
|
||||
let mut codegen = super::Codegen::default();
|
||||
codegen.file(path, input.as_bytes(), &exprs);
|
||||
let mut out = Vec::new();
|
||||
|
|
|
@ -14,12 +14,12 @@ fn main() -> io::Result<()> {
|
|||
.skip(1)
|
||||
.map(|path| std::fs::read_to_string(&path).map(|src| (path, src)))
|
||||
.collect::<io::Result<Vec<_>>>()?;
|
||||
let mut arena = parser::Arena::default();
|
||||
let arena = parser::Arena::default();
|
||||
let mut parser = parser::Parser::new(&arena);
|
||||
let mut codegen = codegen::Codegen::default();
|
||||
for (path, content) in files.iter() {
|
||||
let file = parser::Parser::new(content, path, &arena).file();
|
||||
let file = parser.file(&path, content.as_str());
|
||||
codegen.file(path, content.as_bytes(), file);
|
||||
arena.clear();
|
||||
}
|
||||
codegen.dump(&mut std::io::stdout())
|
||||
}
|
||||
|
|
|
@ -23,19 +23,23 @@ pub struct Parser<'a, 'b> {
|
|||
}
|
||||
|
||||
impl<'a, 'b> Parser<'a, 'b> {
|
||||
pub fn new(input: &'a str, path: &'a str, arena: &'b Arena<'a>) -> Self {
|
||||
let mut lexer = Lexer::new(input);
|
||||
pub fn new(arena: &'b Arena<'a>) -> Self {
|
||||
let mut lexer = Lexer::new("");
|
||||
let token = lexer.next();
|
||||
Self {
|
||||
lexer,
|
||||
token,
|
||||
path,
|
||||
path: "",
|
||||
arena,
|
||||
idents: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn file(&mut self) -> &'a [Expr<'a>] {
|
||||
pub fn file(&mut self, input: &'a str, path: &'a str) -> &'a [Expr<'a>] {
|
||||
self.path = path;
|
||||
self.lexer = Lexer::new(input);
|
||||
self.token = self.lexer.next();
|
||||
|
||||
let f = self.collect(|s| (s.token.kind != TokenKind::Eof).then(|| s.expr()));
|
||||
self.pop_scope(0);
|
||||
let has_undeclared = !self.idents.is_empty();
|
||||
|
@ -717,8 +721,8 @@ mod tests {
|
|||
fn parse(input: &'static str, output: &mut String) {
|
||||
use std::fmt::Write;
|
||||
let mut arena = super::Arena::default();
|
||||
let mut parser = super::Parser::new(input, "test", &arena);
|
||||
for expr in parser.file() {
|
||||
let mut parser = super::Parser::new(&arena);
|
||||
for expr in parser.file(input, "test") {
|
||||
writeln!(output, "{}", expr).unwrap();
|
||||
}
|
||||
arena.clear();
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
code size: 1120
|
||||
code size: 1114
|
||||
ret: 0
|
||||
status: Ok(())
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
code size: 342
|
||||
code size: 339
|
||||
ret: 0
|
||||
status: Ok(())
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
code size: 470
|
||||
code size: 691
|
||||
ret: 3
|
||||
status: Ok(())
|
||||
|
|
0
tests/hblang_codegen_tests_arithmetic.txt
Normal file
0
tests/hblang_codegen_tests_arithmetic.txt
Normal file
0
tests/hblang_codegen_tests_example.txt
Normal file
0
tests/hblang_codegen_tests_example.txt
Normal file
0
tests/hblang_codegen_tests_functions.txt
Normal file
0
tests/hblang_codegen_tests_functions.txt
Normal file
0
tests/hblang_codegen_tests_variables.txt
Normal file
0
tests/hblang_codegen_tests_variables.txt
Normal file
Loading…
Reference in a new issue