diff --git a/schala-lang/language/src/symbol_table.rs b/schala-lang/language/src/symbol_table.rs index 7ca1a16..b845c17 100644 --- a/schala-lang/language/src/symbol_table.rs +++ b/schala-lang/language/src/symbol_table.rs @@ -4,7 +4,7 @@ use std::fmt; use std::fmt::Write; use crate::ast; -use crate::ast::Signature; +use crate::ast::{TypeBody, TypeSingletonName, Signature}; use crate::typechecking::TypeName; //cf. p. 150 or so of Language Implementation Patterns @@ -60,42 +60,14 @@ impl SymbolTable { /* note: this adds names for *forward reference* but doesn't actually create any types. solve that problem * later */ pub fn add_top_level_symbols(&mut self, ast: &ast::AST) -> Result<(), String> { - use self::ast::{Statement, TypeIdentifier, Variant, TypeSingletonName, TypeBody}; + use self::ast::Statement; use self::ast::Declaration::*; for statement in ast.0.iter() { let statement = statement.node(); if let Statement::Declaration(decl) = statement { match decl { - 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() { - match var { - Variant::UnitStruct(variant_name) => { - let spec = SymbolSpec::DataConstructor { - index, - type_name: name.clone(), - type_args: vec![], - }; - self.values.insert(variant_name.clone(), Symbol { name: variant_name.clone(), spec }); - }, - Variant::TupleStruct(variant_name, tuple_members) => { - let type_args = tuple_members.iter().map(|type_name| match type_name { - TypeIdentifier::Singleton(TypeSingletonName { name, ..}) => name.clone(), - TypeIdentifier::Tuple(_) => unimplemented!(), - }).collect(); - let spec = SymbolSpec::DataConstructor { - index, - type_name: name.clone(), - type_args - }; - let symbol = Symbol { name: variant_name.clone(), spec }; - self.values.insert(variant_name.clone(), symbol); - }, - e => return Err(format!("{:?} not supported in typing yet", e)), - } - } - }, + FuncSig(signature) | FuncDecl(signature, _) => self.add_function_signature(signature)?, + TypeDecl { name, body, mutable } => self.add_type_decl(name, body, mutable)?, _ => () } } @@ -110,7 +82,7 @@ impl SymbolTable { output } - fn add_function_signature(&mut self, signature: &Signature) { + fn add_function_signature(&mut self, signature: &Signature) -> Result<(), String> { let mut local_type_context = LocalTypeContext::new(); let types = signature.params.iter().map(|param| match param { (_, Some(type_identifier)) => Rc::new(format!("{:?}", type_identifier)), @@ -121,6 +93,41 @@ impl SymbolTable { signature.name.clone(), Symbol { name: signature.name.clone(), spec } ); + Ok(()) + } + + fn add_type_decl(&mut self, type_name: &TypeSingletonName, body: &TypeBody, _mutable: &bool) -> Result<(), String> { + use crate::ast::{TypeIdentifier, Variant}; + let TypeBody(variants) = body; + let TypeSingletonName { name, .. } = type_name; + //TODO figure out why _params isn't being used here + for (index, var) in variants.iter().enumerate() { + match var { + Variant::UnitStruct(variant_name) => { + let spec = SymbolSpec::DataConstructor { + index, + type_name: name.clone(), + type_args: vec![], + }; + self.values.insert(variant_name.clone(), Symbol { name: variant_name.clone(), spec }); + }, + Variant::TupleStruct(variant_name, tuple_members) => { + let type_args = tuple_members.iter().map(|type_name| match type_name { + TypeIdentifier::Singleton(TypeSingletonName { name, ..}) => name.clone(), + TypeIdentifier::Tuple(_) => unimplemented!(), + }).collect(); + let spec = SymbolSpec::DataConstructor { + index, + type_name: name.clone(), + type_args + }; + let symbol = Symbol { name: variant_name.clone(), spec }; + self.values.insert(variant_name.clone(), symbol); + }, + Variant::Record { .. } => return Err(format!("Record types not supported yet")), + } + } + Ok(()) } }