From b92287ec1f87a91e52d568cb690a0c731a1e4814 Mon Sep 17 00:00:00 2001 From: John Doty Date: Tue, 16 Jan 2024 19:52:45 -0800 Subject: [PATCH] [fine] Starting to work on generic parameters (yikes) --- fine/src/compiler.rs | 2 ++ fine/src/semantics.rs | 24 +++++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fine/src/compiler.rs b/fine/src/compiler.rs index 9003796b..e262508b 100644 --- a/fine/src/compiler.rs +++ b/fine/src/compiler.rs @@ -478,7 +478,9 @@ fn compile_identifier_expression(c: &mut Compiler, t: TreeRef, tree: &Tree) -> O None => { let tree = &c.syntax[*declaration]; compiler_assert_eq!(c, t, tree.kind, TreeKind::FunctionDecl); + compile_function_declaration(c, t, tree, false)?; + *c.function_bindings .get(&key) .expect("did not compile the function!") diff --git a/fine/src/semantics.rs b/fine/src/semantics.rs index 214f44bd..57a74823 100644 --- a/fine/src/semantics.rs +++ b/fine/src/semantics.rs @@ -79,6 +79,8 @@ pub enum Type { String, Bool, + TypeArgument(TreeRef, Box), // An un-bound type argument + Function(Vec>, Box), } @@ -103,9 +105,19 @@ impl Type { (Type::Error, _) => true, (_, Type::Error) => true, + (Type::TypeArgument(a_id, ..), Type::TypeArgument(b_id, ..)) => a_id == b_id, + (_, _) => false, } } + + pub fn is_generic(&self) -> bool { + match self { + Type::TypeArgument(..) => true, + Type::Function(a, b) => a.iter().any(|t| t.is_generic()) || b.is_generic(), + _ => false, + } + } } impl fmt::Debug for Type { @@ -125,8 +137,9 @@ impl fmt::Display for Type { String => write!(f, "string"), Bool => write!(f, "bool"), MagicPrintGarbage => write!(f, "MagicPrintGarbage"), + TypeArgument(_, id) => write!(f, "{id}"), Function(args, ret) => { - write!(f, "(")?; + write!(f, "fun (")?; let mut first = true; for arg in args.iter() { if !first { @@ -653,7 +666,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), + TreeKind::Parameter => self.type_of_parameter(t, tree), _ => self.internal_compiler_error(Some(t), "asking for a nonsense type"), }; @@ -1014,13 +1027,14 @@ impl<'a> Semantics<'a> { Some(Type::Function(parameter_types, return_type)) } - fn type_of_parameter(&self, tree: &Tree) -> Option { + fn type_of_parameter(&self, t: TreeRef, 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) + // It must be a generic parameter! We'll name this one after the tree where it exists. + let name = tree.nth_token(0)?; + Some(Type::TypeArgument(t, format!("${}", name.as_str()).into())) } } }