Test associated functions, cleanup codegen a bit
This commit is contained in:
parent
537167fe4f
commit
f3471473a2
@ -24,5 +24,5 @@ fn main() -> u32 {
|
|||||||
print(from_str("i32: ") + i32::test(54) as u64);
|
print(from_str("i32: ") + i32::test(54) as u64);
|
||||||
print(from_str("sizeof i32: ") + i32::sizeof());
|
print(from_str("sizeof i32: ") + i32::sizeof());
|
||||||
|
|
||||||
return Otus::test(&otus);
|
return i32::sizeof() as u32;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
self,
|
self,
|
||||||
implement::TypeCategory,
|
implement::TypeCategory,
|
||||||
pass::{AssociatedFunctionKey, BinopKey},
|
pass::{AssociatedFunctionKey, BinopKey},
|
||||||
CustomTypeKey, FunctionDefinitionKind, NamedVariableRef, SourceModuleId, StructField, StructType,
|
CustomTypeKey, FunctionCall, FunctionDefinitionKind, NamedVariableRef, SourceModuleId, StructField, StructType,
|
||||||
TypeDefinition, TypeDefinitionKind, TypeKind, WhileStatement,
|
TypeDefinition, TypeDefinitionKind, TypeKind, WhileStatement,
|
||||||
},
|
},
|
||||||
util::try_all,
|
util::try_all,
|
||||||
@ -898,72 +898,7 @@ impl mir::Expression {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::ExprKind::FunctionCall(call) => {
|
mir::ExprKind::FunctionCall(call) => codegen_function_call(None, call, scope, state)?,
|
||||||
let ret_type_kind = call.return_type.known().expect("function return type unknown");
|
|
||||||
|
|
||||||
let ret_type = ret_type_kind.get_type(scope.type_values);
|
|
||||||
|
|
||||||
let params = try_all(
|
|
||||||
call.parameters
|
|
||||||
.iter()
|
|
||||||
.map(|e| e.codegen(scope, state))
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
)
|
|
||||||
.map_err(|e| e.first().cloned().unwrap())?
|
|
||||||
.into_iter()
|
|
||||||
.map(|v| v.unwrap())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let callee = scope.functions.get(&call.name).expect("function not found!");
|
|
||||||
|
|
||||||
let val = callee.codegen(
|
|
||||||
&call.name,
|
|
||||||
params.as_slice(),
|
|
||||||
&call.return_type,
|
|
||||||
if let Some(debug) = &scope.debug {
|
|
||||||
call.meta.into_debug(scope.tokens, debug.scope)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
scope,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let ptr = if ret_type_kind != TypeKind::Void {
|
|
||||||
let ptr = scope
|
|
||||||
.block
|
|
||||||
.build_named(&call.name, Instr::Alloca(ret_type.clone()))
|
|
||||||
.unwrap();
|
|
||||||
scope
|
|
||||||
.block
|
|
||||||
.build_named(format!("{}.store", call.name), Instr::Store(ptr, val.instr()))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Some(ptr)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(ptr) = ptr {
|
|
||||||
if state.should_load {
|
|
||||||
Some(StackValue(
|
|
||||||
StackValueKind::Immutable(
|
|
||||||
scope
|
|
||||||
.block
|
|
||||||
.build_named(call.name.clone(), Instr::Load(ptr, ret_type))
|
|
||||||
.unwrap(),
|
|
||||||
),
|
|
||||||
ret_type_kind,
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Some(StackValue(
|
|
||||||
StackValueKind::Immutable(ptr),
|
|
||||||
TypeKind::CodegenPtr(Box::new(ret_type_kind)),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mir::ExprKind::If(if_expression) => if_expression.codegen(scope, state)?,
|
mir::ExprKind::If(if_expression) => if_expression.codegen(scope, state)?,
|
||||||
mir::ExprKind::Block(block) => {
|
mir::ExprKind::Block(block) => {
|
||||||
let inner = scope.function.block("inner");
|
let inner = scope.function.block("inner");
|
||||||
@ -1323,9 +1258,27 @@ impl mir::Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::ExprKind::AssociatedFunctionCall(ty, call) => {
|
mir::ExprKind::AssociatedFunctionCall(ty, call) => codegen_function_call(Some(ty), call, scope, state)?,
|
||||||
|
};
|
||||||
|
if let Some(value) = &value {
|
||||||
|
value.instr().maybe_location(&mut scope.block, location);
|
||||||
|
}
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn codegen_function_call<'ctx, 'a>(
|
||||||
|
associated_type: Option<&TypeKind>,
|
||||||
|
call: &FunctionCall,
|
||||||
|
scope: &mut Scope<'ctx, 'a>,
|
||||||
|
state: &State,
|
||||||
|
) -> Result<Option<StackValue>, ErrorKind> {
|
||||||
let ret_type_kind = call.return_type.known().expect("function return type unknown");
|
let ret_type_kind = call.return_type.known().expect("function return type unknown");
|
||||||
let call_name = format!("{}::{}", ty, call.name);
|
let call_name = if let Some(ty) = &associated_type {
|
||||||
|
format!("{}::{}", ty, call.name)
|
||||||
|
} else {
|
||||||
|
String::from(call.name.clone())
|
||||||
|
};
|
||||||
|
|
||||||
let ret_type = ret_type_kind.get_type(scope.type_values);
|
let ret_type = ret_type_kind.get_type(scope.type_values);
|
||||||
|
|
||||||
@ -1340,9 +1293,16 @@ impl mir::Expression {
|
|||||||
.map(|v| v.unwrap())
|
.map(|v| v.unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let location = if let Some(debug) = &scope.debug {
|
||||||
|
call.meta.into_debug(scope.tokens, debug.scope)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let val = if let Some(ty) = associated_type {
|
||||||
let assoc_key = AssociatedFunctionKey(ty.clone(), call.name.clone());
|
let assoc_key = AssociatedFunctionKey(ty.clone(), call.name.clone());
|
||||||
let intrinsic = get_intrinsic_assoc_func(&ty, &call.name);
|
let intrinsic_def = get_intrinsic_assoc_func(&ty, &call.name);
|
||||||
let intrinsic_owned = intrinsic.map(|func_def| {
|
let intrinsic = intrinsic_def.map(|func_def| {
|
||||||
let FunctionDefinitionKind::Intrinsic(intrinsic) = func_def.kind else {
|
let FunctionDefinitionKind::Intrinsic(intrinsic) = func_def.kind else {
|
||||||
panic!();
|
panic!();
|
||||||
};
|
};
|
||||||
@ -1351,18 +1311,21 @@ impl mir::Expression {
|
|||||||
let callee = scope
|
let callee = scope
|
||||||
.assoc_functions
|
.assoc_functions
|
||||||
.get(&assoc_key)
|
.get(&assoc_key)
|
||||||
.or(intrinsic_owned.as_ref())
|
.or(intrinsic.as_ref())
|
||||||
|
.expect(&format!("Function {} does not exist!", call_name));
|
||||||
|
callee
|
||||||
|
.codegen(&call_name, params.as_slice(), &call.return_type, location, scope)
|
||||||
|
.unwrap()
|
||||||
|
} else {
|
||||||
|
let callee = scope
|
||||||
|
.functions
|
||||||
|
.get(&call.name)
|
||||||
.expect(&format!("Function {} does not exist!", call_name));
|
.expect(&format!("Function {} does not exist!", call_name));
|
||||||
|
|
||||||
let location = if let Some(debug) = &scope.debug {
|
callee
|
||||||
call.meta.into_debug(scope.tokens, debug.scope)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let val = callee
|
|
||||||
.codegen(&call_name, params.as_slice(), &call.return_type, location, scope)
|
.codegen(&call_name, params.as_slice(), &call.return_type, location, scope)
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
let ptr = if ret_type_kind != TypeKind::Void {
|
let ptr = if ret_type_kind != TypeKind::Void {
|
||||||
let ptr = scope
|
let ptr = scope
|
||||||
@ -1379,7 +1342,7 @@ impl mir::Expression {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(ptr) = ptr {
|
Ok(if let Some(ptr) = ptr {
|
||||||
if state.should_load {
|
if state.should_load {
|
||||||
Some(StackValue(
|
Some(StackValue(
|
||||||
StackValueKind::Immutable(
|
StackValueKind::Immutable(
|
||||||
@ -1398,14 +1361,7 @@ impl mir::Expression {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
})
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Some(value) = &value {
|
|
||||||
value.instr().maybe_location(&mut scope.block, location);
|
|
||||||
}
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mir::IfExpression {
|
impl mir::IfExpression {
|
||||||
|
@ -143,3 +143,12 @@ fn array_short_compiles_well() {
|
|||||||
fn imported_type_compiles_well() {
|
fn imported_type_compiles_well() {
|
||||||
test(include_str!("../../examples/imported_type.reid"), "test", Some(0));
|
test(include_str!("../../examples/imported_type.reid"), "test", Some(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn associated_functions() {
|
||||||
|
test(
|
||||||
|
include_str!("../../examples/associated_functions.reid"),
|
||||||
|
"test",
|
||||||
|
Some(32),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user