diff --git a/schala-lang/language/src/symbol_table.rs b/schala-lang/language/src/symbol_table.rs index 86fdbc0..7ca1a16 100644 --- a/schala-lang/language/src/symbol_table.rs +++ b/schala-lang/language/src/symbol_table.rs @@ -4,6 +4,7 @@ use std::fmt; use std::fmt::Write; use crate::ast; +use crate::ast::Signature; use crate::typechecking::TypeName; //cf. p. 150 or so of Language Implementation Patterns @@ -65,28 +66,7 @@ impl SymbolTable { let statement = statement.node(); if let Statement::Declaration(decl) = statement { match decl { - FuncSig(signature) | FuncDecl(signature, _) => { - let mut ch: char = 'a'; - let mut types = vec![]; - for param in signature.params.iter() { - match param { - (_, Some(_ty)) => { - //TODO eventually handle this case different - types.push(Rc::new(format!("{}", ch))); - ch = ((ch as u8) + 1) as char; - }, - (_, None) => { - types.push(Rc::new(format!("{}", ch))); - ch = ((ch as u8) + 1) as char; - } - } - } - let spec = SymbolSpec::Func(types); - self.values.insert( - signature.name.clone(), - Symbol { name: signature.name.clone(), spec } - ); - }, + FuncSig(signature) | FuncDecl(signature, _) => self.add_function_signature(signature), //TODO figure out why _params isn't being used here TypeDecl { name: TypeSingletonName { name, params: _params}, body: TypeBody(variants), mutable: _mutable, } => { for (index, var) in variants.iter().enumerate() { @@ -129,4 +109,32 @@ impl SymbolTable { } output } + + fn add_function_signature(&mut self, signature: &Signature) { + let mut local_type_context = LocalTypeContext::new(); + let types = signature.params.iter().map(|param| match param { + (_, Some(type_identifier)) => Rc::new(format!("{:?}", type_identifier)), + (_, None) => local_type_context.new_universal_type() + }).collect(); + let spec = SymbolSpec::Func(types); + self.values.insert( + signature.name.clone(), + Symbol { name: signature.name.clone(), spec } + ); + } +} + +struct LocalTypeContext { + state: u8 +} +impl LocalTypeContext { + fn new() -> LocalTypeContext { + LocalTypeContext { state: 0 } + } + + fn new_universal_type(&mut self) -> TypeName { + let n = self.state; + self.state += 1; + Rc::new(format!("{}", (('a' as u8) + n) as char)) + } }