diff --git a/schala-lang/language/src/reduced_ir/mod.rs b/schala-lang/language/src/reduced_ir/mod.rs index 630f2c8..c8f60cb 100644 --- a/schala-lang/language/src/reduced_ir/mod.rs +++ b/schala-lang/language/src/reduced_ir/mod.rs @@ -148,8 +148,10 @@ impl<'a, 'b> Reducer<'a, 'b> { body: self.function_internal_block(body), }), NamedStruct { name, fields } => { - self.symbol_table.debug(); - let symbol = self.symbol_table.lookup_symbol(&name.id).unwrap(); + let symbol = match self.symbol_table.lookup_symbol(&name.id) { + Some(symbol) => symbol, + None => return Expression::ReductionError(format!("No symbol found for {:?}", name)), + }; let (tag, type_id) = match symbol.spec() { SymbolSpec::RecordConstructor { tag, type_id } => (tag, type_id), e => return Expression::ReductionError(format!("Bad symbol for NamedStruct: {:?}", e)), diff --git a/schala-lang/language/src/symbol_table/mod.rs b/schala-lang/language/src/symbol_table/mod.rs index 3605d78..6818cda 100644 --- a/schala-lang/language/src/symbol_table/mod.rs +++ b/schala-lang/language/src/symbol_table/mod.rs @@ -427,13 +427,16 @@ impl<'a> SymbolTableRunner<'a> { location: Location, scope_stack: &mut Vec, ) -> Vec { - let variants = match type_body { - TypeBody::Variants(variants) => variants.clone(), - TypeBody::ImmediateRecord(id, fields) => vec![Variant { - id: *id, - name: type_name.name.clone(), - kind: VariantKind::Record(fields.clone()), - }], + let (variants, immediate_variant) = match type_body { + TypeBody::Variants(variants) => (variants.clone(), false), + TypeBody::ImmediateRecord(id, fields) => ( + vec![Variant { + id: *id, + name: type_name.name.clone(), + kind: VariantKind::Record(fields.clone()), + }], + true, + ), }; let type_fqsn = Fqsn::from_scope_stack(scope_stack, type_name.name.clone()); @@ -520,6 +523,18 @@ impl<'a> SymbolTableRunner<'a> { self.table.add_symbol(id, fqsn, spec); } + if immediate_variant { + let variant = &type_definition.variants[0]; + let fqsn = Fqsn::from_scope_stack(scope_stack.as_ref(), Rc::new(variant.name.to_string())); + let id = fqsn_id_map.get(&fqsn).unwrap(); + let abbrev_fqsn = Fqsn::from_scope_stack( + scope_stack[0..scope_stack.len() - 1].as_ref(), + Rc::new(variant.name.to_string()), + ); + let spec = SymbolSpec::RecordConstructor { tag: 0, type_id }; + self.table.add_symbol(id, abbrev_fqsn, spec); + } + scope_stack.pop(); vec![] } diff --git a/schala-lang/language/src/symbol_table/resolver.rs b/schala-lang/language/src/symbol_table/resolver.rs index 3ea516c..0e12c9b 100644 --- a/schala-lang/language/src/symbol_table/resolver.rs +++ b/schala-lang/language/src/symbol_table/resolver.rs @@ -39,31 +39,6 @@ impl<'a> ScopeResolver<'a> { walk_ast(self, ast); } - /* - fn lookup_name_in_scope(&self, sym_name: &QualifiedName) -> Fqsn { - let QualifiedName { components, .. } = sym_name; - let first_component = &components[0]; - match self.name_scope_stack.lookup(first_component) { - None => Fqsn { - scopes: components - .iter() - .map(|name| Scope::Name(name.clone())) - .collect(), - }, - Some(fqsn_prefix) => { - let mut full_name = fqsn_prefix.clone(); - let rest_of_name: FqsnPrefix = components[1..] - .iter() - .map(|name| Scope::Name(name.clone())) - .collect(); - full_name.extend_from_slice(&rest_of_name); - - Fqsn { scopes: full_name } - } - } - } - */ - /// This method correctly modifies the id_to_symbol table (ItemId) to have the appropriate /// mappings. fn lookup_name_in_scope(&mut self, name: &QualifiedName) { diff --git a/schala-lang/language/src/tree_walk_eval/test.rs b/schala-lang/language/src/tree_walk_eval/test.rs index 069b0aa..af7b921 100644 --- a/schala-lang/language/src/tree_walk_eval/test.rs +++ b/schala-lang/language/src/tree_walk_eval/test.rs @@ -173,7 +173,7 @@ if x { } #[test] -fn record_patterns() { +fn record_patterns_1() { let source = r#" type Ara = Kueh { a: Int, b: String } | Morbuk @@ -183,7 +183,10 @@ if alpha { is _ then ("nooo", 8888) }"#; eval_assert(source, r#"("sanchez", 10)"#); +} +#[test] +fn record_patterns_2() { let source = r#" type Ara = Kueh { a: Int, b: String } | Morbuk @@ -193,11 +196,14 @@ if alpha { is _ then ("nooo", 8888) }"#; eval_assert(source, r#"("sanchez", 20)"#); +} +#[test] +fn record_patterns_3() { let source = r#" type Vstsavlobs = { tkveni: Int, b: Ia } type Ia = { sitqva: Int, ghmerts: String } -let b = Vstsavlobs::Vstsavlobs { tkveni: 3, b: Ia::Ia { sitqva: 5, ghmerts: "ooo" } } +let b = Vstsavlobs { tkveni: 3, b: Ia::Ia { sitqva: 5, ghmerts: "ooo" } } if b { is Vstsavlobs::Vstsavlobs { tkveni: _, b: Ia::Ia { sitqva, ghmerts } } then sitqva is _ then 5000