diff --git a/fine/src/semantics.rs b/fine/src/semantics.rs index afa2b2c7..214f44bd 100644 --- a/fine/src/semantics.rs +++ b/fine/src/semantics.rs @@ -607,12 +607,7 @@ impl<'a> Semantics<'a> { continue; }; - let declaration_type = if let Some(type_expression) = param.nth_tree(2) { - self.type_of(type_expression) - } else { - Type::Error - }; - + let declaration_type = self.type_of(*ct); environment.insert(param_name, declaration_type); } @@ -658,6 +653,7 @@ impl<'a> Semantics<'a> { TreeKind::FunctionDecl => self.type_of_function_decl(tree), TreeKind::ReturnType => self.type_of_return_type(tree), + TreeKind::Parameter => self.type_of_parameter(tree), _ => self.internal_compiler_error(Some(t), "asking for a nonsense type"), }; @@ -1007,12 +1003,7 @@ impl<'a> Semantics<'a> { let param_list = tree.child_tree_of_kind(self.syntax_tree, TreeKind::ParamList)?; let mut parameter_types = Vec::new(); for p in param_list.child_trees() { - let param = &self.syntax_tree[p]; - - // TODO: Shouldn't this just be type_of(param)? - // TODO: Missing type expression means it's a generic function. - let parameter_type = param.child_of_kind(self.syntax_tree, TreeKind::TypeExpression)?; - parameter_types.push(Box::new(self.type_of(parameter_type))); + parameter_types.push(Box::new(self.type_of(p))); } let return_type = match tree.child_of_kind(self.syntax_tree, TreeKind::ReturnType) { @@ -1023,6 +1014,17 @@ impl<'a> Semantics<'a> { Some(Type::Function(parameter_types, return_type)) } + fn type_of_parameter(&self, tree: &Tree) -> Option { + assert_eq!(tree.kind, TreeKind::Parameter); + match tree.child_of_kind(self.syntax_tree, TreeKind::TypeExpression) { + Some(t) => Some(self.type_of(t)), + None => { + self.report_error_tree(tree, "generic parameters not yet supported"); + Some(Type::Error) + } + } + } + fn type_of_return_type(&self, tree: &Tree) -> Option { assert_eq!(tree.kind, TreeKind::ReturnType); Some(self.type_of(tree.nth_tree(1)?)) // type expression diff --git a/fine/tests/expression/generic_function.fine b/fine/tests/expression/generic_function.fine new file mode 100644 index 00000000..77581b31 --- /dev/null +++ b/fine/tests/expression/generic_function.fine @@ -0,0 +1,11 @@ +fun generic_add(x, y) { + x + y +} + +fun test() { + generic_add(10, 10) +} + +// @ignore +// @no-errors +// @eval: 20 \ No newline at end of file