From 3f11e19a91ccc4057f727bddad7c69acc6e9d08d Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Wed, 25 Dec 2024 21:29:30 +0100 Subject: [PATCH] properly handling generic method calls Signed-off-by: Jakub Doka --- lang/src/lib.rs | 3 --- lang/src/nodes.rs | 3 +-- lang/src/son.rs | 22 ++++++++++++++----- .../son_tests_generic_function_in_struct.txt | 21 ++++++++++++++++++ 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/lang/src/lib.rs b/lang/src/lib.rs index 525e7ab..e93bde2 100644 --- a/lang/src/lib.rs +++ b/lang/src/lib.rs @@ -42,9 +42,6 @@ extern crate alloc; #[cfg(any(feature = "std", test))] extern crate std; -#[cfg(test)] -const README: &str = include_str!("../README.md"); - #[cfg(test)] #[macro_export] macro_rules! run_tests { diff --git a/lang/src/nodes.rs b/lang/src/nodes.rs index 311bb69..ff4e252 100644 --- a/lang/src/nodes.rs +++ b/lang/src/nodes.rs @@ -4,12 +4,11 @@ use { debug, lexer::{self, TokenKind}, parser::Pos, - ty::{self, Loc, Offset, Types}, + ty::{self, Loc, Types}, utils::{BitSet, Vc}, }, alloc::{string::String, vec::Vec}, core::{ - assert_matches::debug_assert_matches, cell::Cell, fmt::{self, Debug, Write}, mem, diff --git a/lang/src/son.rs b/lang/src/son.rs index 9812104..0adfeb4 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -28,7 +28,7 @@ use { assert_matches::debug_assert_matches, cell::RefCell, fmt::{self, Debug, Display, Write}, - format_args as fa, mem, + format_args as fa, mem, usize, }, hbbytecode::DisasmError, }; @@ -2602,7 +2602,7 @@ impl<'a> Codegen<'a> { if let Some((_, f)) = self.tys.find_union_field(u, name) { Some(Value::ptr(vtarget.id).ty(f.ty)) } else if let ty = self.find_type(pos, self.ci.file, u, name) - && let ty::Kind::Func(_) = ty.expand() + && let ty::Kind::Func(_) | ty::Kind::Template(_) = ty.expand() { return Some(Err((ty, vtarget))); } else { @@ -2626,7 +2626,7 @@ impl<'a> Codegen<'a> { if let Some((offset, ty)) = OffsetIter::offset_of(self.tys, s, name) { Some(Value::ptr(self.offset(vtarget.id, offset)).ty(ty)) } else if let ty = self.find_type(pos, self.ci.file, s, name) - && let ty::Kind::Func(_) = ty.expand() + && let ty::Kind::Func(_) | ty::Kind::Template(_) = ty.expand() { return Some(Err((ty, vtarget))); } else { @@ -2788,7 +2788,7 @@ impl<'a> Codegen<'a> { ref e => (self.ty(e), None), }; - let Some(fu) = self.compute_signature(ty, func.pos(), args) else { + let Some(fu) = self.compute_signature(ty, func.pos(), args, caller.is_some()) else { return Value::NEVER; }; @@ -3170,7 +3170,13 @@ impl<'a> Codegen<'a> { } } - fn compute_signature(&mut self, func: ty::Id, pos: Pos, args: &[Expr]) -> Option { + fn compute_signature( + &mut self, + func: ty::Id, + pos: Pos, + args: &[Expr], + implici_caller: bool, + ) -> Option { let template = match func.expand() { ty::Kind::Func(f) => return Some(f), ty::Kind::Template(t) => t, @@ -3191,7 +3197,11 @@ impl<'a> Codegen<'a> { let arg_base = self.tys.tmp.args.len(); let base = self.ci.scope.vars.len(); - for (arg, carg) in args.iter().zip(cargs) { + if implici_caller { + let caller = self.ty_in(file, parent, &cargs[0].ty); + self.tys.tmp.args.push(caller); + } + for (arg, carg) in args.iter().zip(cargs.iter().skip(implici_caller as usize)) { let ty = self.ty_in(file, parent, &carg.ty); self.tys.tmp.args.push(ty); diff --git a/lang/tests/son_tests_generic_function_in_struct.txt b/lang/tests/son_tests_generic_function_in_struct.txt index e69de29..22ae842 100644 --- a/lang/tests/son_tests_generic_function_in_struct.txt +++ b/lang/tests/son_tests_generic_function_in_struct.txt @@ -0,0 +1,21 @@ +b: + CP r13, r3 + CP r1, r13 + JALA r0, r31, 0a +main: + ADDI64 r254, r254, -32d + ST r31, r254, 8a, 24h + ADDI64 r32, r254, 0d + LI64 r33, 100d + ST r33, r254, 0a, 8h + CP r2, r32 + CP r3, r33 + JAL r31, r0, :b + CP r32, r1 + CP r1, r32 + LD r31, r254, 8a, 24h + ADDI64 r254, r254, 32d + JALA r0, r31, 0a +code size: 137 +ret: 100 +status: Ok(())