Put single ImmediateStruct member into scope

This commit is contained in:
Greg Shuflin 2021-11-01 19:03:06 -07:00
parent 8798650024
commit acc99fa0ef
4 changed files with 34 additions and 36 deletions

View File

@ -148,8 +148,10 @@ impl<'a, 'b> Reducer<'a, 'b> {
body: self.function_internal_block(body), body: self.function_internal_block(body),
}), }),
NamedStruct { name, fields } => { NamedStruct { name, fields } => {
self.symbol_table.debug(); let symbol = match self.symbol_table.lookup_symbol(&name.id) {
let symbol = self.symbol_table.lookup_symbol(&name.id).unwrap(); Some(symbol) => symbol,
None => return Expression::ReductionError(format!("No symbol found for {:?}", name)),
};
let (tag, type_id) = match symbol.spec() { let (tag, type_id) = match symbol.spec() {
SymbolSpec::RecordConstructor { tag, type_id } => (tag, type_id), SymbolSpec::RecordConstructor { tag, type_id } => (tag, type_id),
e => return Expression::ReductionError(format!("Bad symbol for NamedStruct: {:?}", e)), e => return Expression::ReductionError(format!("Bad symbol for NamedStruct: {:?}", e)),

View File

@ -427,13 +427,16 @@ impl<'a> SymbolTableRunner<'a> {
location: Location, location: Location,
scope_stack: &mut Vec<Scope>, scope_stack: &mut Vec<Scope>,
) -> Vec<SymbolError> { ) -> Vec<SymbolError> {
let variants = match type_body { let (variants, immediate_variant) = match type_body {
TypeBody::Variants(variants) => variants.clone(), TypeBody::Variants(variants) => (variants.clone(), false),
TypeBody::ImmediateRecord(id, fields) => vec![Variant { TypeBody::ImmediateRecord(id, fields) => (
id: *id, vec![Variant {
name: type_name.name.clone(), id: *id,
kind: VariantKind::Record(fields.clone()), name: type_name.name.clone(),
}], kind: VariantKind::Record(fields.clone()),
}],
true,
),
}; };
let type_fqsn = Fqsn::from_scope_stack(scope_stack, type_name.name.clone()); 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); 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(); scope_stack.pop();
vec![] vec![]
} }

View File

@ -39,31 +39,6 @@ impl<'a> ScopeResolver<'a> {
walk_ast(self, ast); 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 /// This method correctly modifies the id_to_symbol table (ItemId) to have the appropriate
/// mappings. /// mappings.
fn lookup_name_in_scope(&mut self, name: &QualifiedName) { fn lookup_name_in_scope(&mut self, name: &QualifiedName) {

View File

@ -173,7 +173,7 @@ if x {
} }
#[test] #[test]
fn record_patterns() { fn record_patterns_1() {
let source = r#" let source = r#"
type Ara = Kueh { a: Int, b: String } | Morbuk type Ara = Kueh { a: Int, b: String } | Morbuk
@ -183,7 +183,10 @@ if alpha {
is _ then ("nooo", 8888) is _ then ("nooo", 8888)
}"#; }"#;
eval_assert(source, r#"("sanchez", 10)"#); eval_assert(source, r#"("sanchez", 10)"#);
}
#[test]
fn record_patterns_2() {
let source = r#" let source = r#"
type Ara = Kueh { a: Int, b: String } | Morbuk type Ara = Kueh { a: Int, b: String } | Morbuk
@ -193,11 +196,14 @@ if alpha {
is _ then ("nooo", 8888) is _ then ("nooo", 8888)
}"#; }"#;
eval_assert(source, r#"("sanchez", 20)"#); eval_assert(source, r#"("sanchez", 20)"#);
}
#[test]
fn record_patterns_3() {
let source = r#" let source = r#"
type Vstsavlobs = { tkveni: Int, b: Ia } type Vstsavlobs = { tkveni: Int, b: Ia }
type Ia = { sitqva: Int, ghmerts: String } 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 { if b {
is Vstsavlobs::Vstsavlobs { tkveni: _, b: Ia::Ia { sitqva, ghmerts } } then sitqva is Vstsavlobs::Vstsavlobs { tkveni: _, b: Ia::Ia { sitqva, ghmerts } } then sitqva
is _ then 5000 is _ then 5000