Compare commits
3 Commits
0a90ac4497
...
2f56f148cb
Author | SHA1 | Date | |
---|---|---|---|
2f56f148cb | |||
8bbee5eb41 | |||
ef427f5e58 |
@ -385,10 +385,12 @@ impl Builder {
|
|||||||
}
|
}
|
||||||
Instr::FunctionCall(fun, params) => {
|
Instr::FunctionCall(fun, params) => {
|
||||||
let param_types = self.function_data(&fun).params;
|
let param_types = self.function_data(&fun).params;
|
||||||
|
dbg!(¶ms, ¶m_types);
|
||||||
if param_types.len() != params.len() {
|
if param_types.len() != params.len() {
|
||||||
return Err(()); // TODO error: invalid amount of params
|
return Err(()); // TODO error: invalid amount of params
|
||||||
}
|
}
|
||||||
for (a, b) in param_types.iter().zip(params) {
|
for (a, b) in param_types.iter().zip(params) {
|
||||||
|
dbg!(b.get_type(&self)?);
|
||||||
if *a != b.get_type(&self)? {
|
if *a != b.get_type(&self)? {
|
||||||
return Err(()); // TODO error: params do not match
|
return Err(()); // TODO error: params do not match
|
||||||
}
|
}
|
||||||
|
@ -542,7 +542,7 @@ pub fn pick_return<T>(lhs: (ReturnKind, T), rhs: (ReturnKind, T)) -> (ReturnKind
|
|||||||
impl TypeKind {
|
impl TypeKind {
|
||||||
/// Assert that a type is already known and not vague. Return said type or
|
/// Assert that a type is already known and not vague. Return said type or
|
||||||
/// error.
|
/// error.
|
||||||
pub fn assert_known(&self) -> Result<TypeKind, ErrorKind> {
|
pub fn assert_unvague(&self) -> Result<TypeKind, ErrorKind> {
|
||||||
self.known().map_err(ErrorKind::TypeIsVague)
|
self.known().map_err(ErrorKind::TypeIsVague)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ impl<'t> Pass for TypeCheck<'t> {
|
|||||||
name,
|
name,
|
||||||
kind,
|
kind,
|
||||||
meta,
|
meta,
|
||||||
source_module,
|
source_module: _,
|
||||||
} = &typedef;
|
} = &typedef;
|
||||||
|
|
||||||
match kind {
|
match kind {
|
||||||
@ -162,12 +162,12 @@ fn check_typedefs_for_recursion<'a, 'b>(
|
|||||||
impl FunctionDefinition {
|
impl FunctionDefinition {
|
||||||
fn typecheck(
|
fn typecheck(
|
||||||
&mut self,
|
&mut self,
|
||||||
hints: &TypeRefs,
|
typerefs: &TypeRefs,
|
||||||
state: &mut TypecheckPassState,
|
state: &mut TypecheckPassState,
|
||||||
) -> Result<TypeKind, ErrorKind> {
|
) -> Result<TypeKind, ErrorKind> {
|
||||||
for param in &self.parameters {
|
for param in &self.parameters {
|
||||||
let param_t = state.or_else(
|
let param_t = state.or_else(
|
||||||
param.1.assert_known(),
|
param.1.assert_known(typerefs, state),
|
||||||
TypeKind::Vague(Vague::Unknown),
|
TypeKind::Vague(Vague::Unknown),
|
||||||
self.signature(),
|
self.signature(),
|
||||||
);
|
);
|
||||||
@ -185,11 +185,11 @@ impl FunctionDefinition {
|
|||||||
state.ok(res, self.signature());
|
state.ok(res, self.signature());
|
||||||
}
|
}
|
||||||
|
|
||||||
let return_type = self.return_type.clone();
|
let return_type = self.return_type.clone().assert_known(typerefs, state)?;
|
||||||
let inferred = match &mut self.kind {
|
let inferred = match &mut self.kind {
|
||||||
FunctionDefinitionKind::Local(block, _) => {
|
FunctionDefinitionKind::Local(block, _) => {
|
||||||
state.scope.return_type_hint = Some(self.return_type.clone());
|
state.scope.return_type_hint = Some(self.return_type.clone());
|
||||||
block.typecheck(&mut state.inner(), &hints, Some(&return_type))
|
block.typecheck(&mut state.inner(), &typerefs, Some(&return_type))
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern(_) => {
|
FunctionDefinitionKind::Extern(_) => {
|
||||||
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))
|
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))
|
||||||
@ -408,7 +408,7 @@ impl Expression {
|
|||||||
ExprKind::BinOp(op, lhs, rhs) => {
|
ExprKind::BinOp(op, lhs, rhs) => {
|
||||||
// TODO make sure lhs and rhs can actually do this binary
|
// TODO make sure lhs and rhs can actually do this binary
|
||||||
// operation once relevant
|
// operation once relevant
|
||||||
let lhs_res = lhs.typecheck(state, &typerefs, None);
|
let lhs_res = lhs.typecheck(state, &typerefs, hint_t);
|
||||||
let lhs_type = state.or_else(lhs_res, TypeKind::Vague(Vague::Unknown), lhs.1);
|
let lhs_type = state.or_else(lhs_res, TypeKind::Vague(Vague::Unknown), lhs.1);
|
||||||
let rhs_res = rhs.typecheck(state, &typerefs, Some(&lhs_type));
|
let rhs_res = rhs.typecheck(state, &typerefs, Some(&lhs_type));
|
||||||
let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1);
|
let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1);
|
||||||
@ -755,3 +755,33 @@ impl Literal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TypeKind {
|
||||||
|
fn assert_known(
|
||||||
|
&self,
|
||||||
|
refs: &TypeRefs,
|
||||||
|
state: &TypecheckPassState,
|
||||||
|
) -> Result<TypeKind, ErrorKind> {
|
||||||
|
self.is_known(refs, state).map(|_| self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_known(&self, refs: &TypeRefs, state: &TypecheckPassState) -> Result<(), ErrorKind> {
|
||||||
|
match &self {
|
||||||
|
TypeKind::Array(type_kind, _) => type_kind.as_ref().is_known(refs, state),
|
||||||
|
TypeKind::CustomType(custom_type_key) => state
|
||||||
|
.scope
|
||||||
|
.types
|
||||||
|
.get(custom_type_key)
|
||||||
|
.map(|_| ())
|
||||||
|
.ok_or(ErrorKind::NoSuchType(
|
||||||
|
custom_type_key.0.clone(),
|
||||||
|
state.module_id.unwrap(),
|
||||||
|
)),
|
||||||
|
TypeKind::Borrow(type_kind, _) => type_kind.is_known(refs, state),
|
||||||
|
TypeKind::UserPtr(type_kind) => type_kind.is_known(refs, state),
|
||||||
|
TypeKind::CodegenPtr(type_kind) => type_kind.is_known(refs, state),
|
||||||
|
TypeKind::Vague(vague_type) => Err(ErrorKind::TypeIsVague(*vague_type)),
|
||||||
|
_ => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -49,7 +49,7 @@ impl FunctionDefinition {
|
|||||||
) -> Result<(), ErrorKind> {
|
) -> Result<(), ErrorKind> {
|
||||||
let scope_hints = ScopeTypeRefs::from(type_refs);
|
let scope_hints = ScopeTypeRefs::from(type_refs);
|
||||||
for param in &self.parameters {
|
for param in &self.parameters {
|
||||||
let param_t = state.or_else(param.1.assert_known(), Vague(Unknown), self.signature());
|
let param_t = state.or_else(param.1.assert_unvague(), Vague(Unknown), self.signature());
|
||||||
let res = scope_hints
|
let res = scope_hints
|
||||||
.new_var(param.0.clone(), false, ¶m_t)
|
.new_var(param.0.clone(), false, ¶m_t)
|
||||||
.or(Err(ErrorKind::VariableAlreadyDefined(param.0.clone())));
|
.or(Err(ErrorKind::VariableAlreadyDefined(param.0.clone())));
|
||||||
|
12
reid_src/test.reid
Normal file
12
reid_src/test.reid
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
fn vec_sub(l: [f32; 3], r: [f32; 3]) -> [f32; 3] {
|
||||||
|
return [l[0]-r[0], l[1]-r[1], l[2]-r[2]];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(x: f32) {
|
||||||
|
let a = [x, x, 0.0];
|
||||||
|
let b = [x, x, x]; // works
|
||||||
|
// let b = [x * 0.5, x * 0.5, x]; // does not work
|
||||||
|
vec_sub(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue
Block a user