Put single ImmediateStruct member into scope
This commit is contained in:
parent
8798650024
commit
acc99fa0ef
@ -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)),
|
||||
|
@ -427,13 +427,16 @@ impl<'a> SymbolTableRunner<'a> {
|
||||
location: Location,
|
||||
scope_stack: &mut Vec<Scope>,
|
||||
) -> Vec<SymbolError> {
|
||||
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![]
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user