[fine] Starting to work on generic parameters (yikes)

This commit is contained in:
John Doty 2024-01-16 19:52:45 -08:00
parent aaa88717f5
commit b92287ec1f
2 changed files with 21 additions and 5 deletions

View file

@ -478,7 +478,9 @@ fn compile_identifier_expression(c: &mut Compiler, t: TreeRef, tree: &Tree) -> O
None => { None => {
let tree = &c.syntax[*declaration]; let tree = &c.syntax[*declaration];
compiler_assert_eq!(c, t, tree.kind, TreeKind::FunctionDecl); compiler_assert_eq!(c, t, tree.kind, TreeKind::FunctionDecl);
compile_function_declaration(c, t, tree, false)?; compile_function_declaration(c, t, tree, false)?;
*c.function_bindings *c.function_bindings
.get(&key) .get(&key)
.expect("did not compile the function!") .expect("did not compile the function!")

View file

@ -79,6 +79,8 @@ pub enum Type {
String, String,
Bool, Bool,
TypeArgument(TreeRef, Box<str>), // An un-bound type argument
Function(Vec<Box<Type>>, Box<Type>), Function(Vec<Box<Type>>, Box<Type>),
} }
@ -103,9 +105,19 @@ impl Type {
(Type::Error, _) => true, (Type::Error, _) => true,
(_, Type::Error) => true, (_, Type::Error) => true,
(Type::TypeArgument(a_id, ..), Type::TypeArgument(b_id, ..)) => a_id == b_id,
(_, _) => false, (_, _) => 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 { impl fmt::Debug for Type {
@ -125,8 +137,9 @@ impl fmt::Display for Type {
String => write!(f, "string"), String => write!(f, "string"),
Bool => write!(f, "bool"), Bool => write!(f, "bool"),
MagicPrintGarbage => write!(f, "MagicPrintGarbage"), MagicPrintGarbage => write!(f, "MagicPrintGarbage"),
TypeArgument(_, id) => write!(f, "{id}"),
Function(args, ret) => { Function(args, ret) => {
write!(f, "(")?; write!(f, "fun (")?;
let mut first = true; let mut first = true;
for arg in args.iter() { for arg in args.iter() {
if !first { if !first {
@ -653,7 +666,7 @@ impl<'a> Semantics<'a> {
TreeKind::FunctionDecl => self.type_of_function_decl(tree), TreeKind::FunctionDecl => self.type_of_function_decl(tree),
TreeKind::ReturnType => self.type_of_return_type(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"), _ => 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)) Some(Type::Function(parameter_types, return_type))
} }
fn type_of_parameter(&self, tree: &Tree) -> Option<Type> { fn type_of_parameter(&self, t: TreeRef, tree: &Tree) -> Option<Type> {
assert_eq!(tree.kind, TreeKind::Parameter); assert_eq!(tree.kind, TreeKind::Parameter);
match tree.child_of_kind(self.syntax_tree, TreeKind::TypeExpression) { match tree.child_of_kind(self.syntax_tree, TreeKind::TypeExpression) {
Some(t) => Some(self.type_of(t)), Some(t) => Some(self.type_of(t)),
None => { None => {
self.report_error_tree(tree, "generic parameters not yet supported"); // It must be a generic parameter! We'll name this one after the tree where it exists.
Some(Type::Error) let name = tree.nth_token(0)?;
Some(Type::TypeArgument(t, format!("${}", name.as_str()).into()))
} }
} }
} }