Add type for talking about symbol paths
to symbol table
This commit is contained in:
parent
0bcd7e6f41
commit
7694afc9e2
@ -7,9 +7,15 @@ use crate::ast;
|
|||||||
use crate::ast::{TypeBody, TypeSingletonName, Signature};
|
use crate::ast::{TypeBody, TypeSingletonName, Signature};
|
||||||
use crate::typechecking::TypeName;
|
use crate::typechecking::TypeName;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Hash, Debug)]
|
||||||
|
struct SymbolPath {
|
||||||
|
name: Rc<String>,
|
||||||
|
enclosing_scopes: Vec<Rc<String>>
|
||||||
|
}
|
||||||
|
|
||||||
//cf. p. 150 or so of Language Implementation Patterns
|
//cf. p. 150 or so of Language Implementation Patterns
|
||||||
pub struct SymbolTable {
|
pub struct SymbolTable {
|
||||||
pub values: HashMap<Rc<String>, Symbol> //TODO this will eventually have real type information
|
values: HashMap<SymbolPath, Symbol> //TODO this will eventually have real type information
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO add various types of lookups here, maybe multiple hash tables internally? also make values
|
//TODO add various types of lookups here, maybe multiple hash tables internally? also make values
|
||||||
@ -19,8 +25,20 @@ impl SymbolTable {
|
|||||||
SymbolTable { values: HashMap::new() }
|
SymbolTable { values: HashMap::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_new_symbol(&mut self, path: &Rc<String>, symbol: Symbol) {
|
||||||
|
let symbol_path = SymbolPath {
|
||||||
|
name: path.clone(),
|
||||||
|
enclosing_scopes: vec![]
|
||||||
|
};
|
||||||
|
self.values.insert(symbol_path, symbol);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn lookup_by_name(&self, name: &Rc<String>) -> Option<&Symbol> {
|
pub fn lookup_by_name(&self, name: &Rc<String>) -> Option<&Symbol> {
|
||||||
self.values.get(name)
|
let symbol_path = SymbolPath {
|
||||||
|
name: name.clone(),
|
||||||
|
enclosing_scopes: vec![]
|
||||||
|
};
|
||||||
|
self.values.get(&symbol_path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +99,7 @@ impl SymbolTable {
|
|||||||
pub fn debug_symbol_table(&self) -> String {
|
pub fn debug_symbol_table(&self) -> String {
|
||||||
let mut output = format!("Symbol table\n");
|
let mut output = format!("Symbol table\n");
|
||||||
for (name, sym) in &self.values {
|
for (name, sym) in &self.values {
|
||||||
write!(output, "{} -> {}\n", name, sym).unwrap();
|
write!(output, "{:?} -> {}\n", name, sym).unwrap();
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
@ -93,8 +111,8 @@ impl SymbolTable {
|
|||||||
(_, None) => local_type_context.new_universal_type()
|
(_, None) => local_type_context.new_universal_type()
|
||||||
}).collect();
|
}).collect();
|
||||||
let spec = SymbolSpec::Func(types);
|
let spec = SymbolSpec::Func(types);
|
||||||
self.values.insert(
|
self.add_new_symbol(
|
||||||
signature.name.clone(),
|
&signature.name,
|
||||||
Symbol { name: signature.name.clone(), spec }
|
Symbol { name: signature.name.clone(), spec }
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -113,7 +131,7 @@ impl SymbolTable {
|
|||||||
type_name: name.clone(),
|
type_name: name.clone(),
|
||||||
type_args: vec![],
|
type_args: vec![],
|
||||||
};
|
};
|
||||||
self.values.insert(variant_name.clone(), Symbol { name: variant_name.clone(), spec });
|
self.add_new_symbol(variant_name, Symbol { name: variant_name.clone(), spec });
|
||||||
},
|
},
|
||||||
Variant::TupleStruct(variant_name, tuple_members) => {
|
Variant::TupleStruct(variant_name, tuple_members) => {
|
||||||
let type_args = tuple_members.iter().map(|type_name| match type_name {
|
let type_args = tuple_members.iter().map(|type_name| match type_name {
|
||||||
@ -126,7 +144,7 @@ impl SymbolTable {
|
|||||||
type_args
|
type_args
|
||||||
};
|
};
|
||||||
let symbol = Symbol { name: variant_name.clone(), spec };
|
let symbol = Symbol { name: variant_name.clone(), spec };
|
||||||
self.values.insert(variant_name.clone(), symbol);
|
self.add_new_symbol(variant_name, symbol);
|
||||||
},
|
},
|
||||||
//TODO if there is only one variant, and it is a record, it doesn't need to have an
|
//TODO if there is only one variant, and it is a record, it doesn't need to have an
|
||||||
//explicit name
|
//explicit name
|
||||||
@ -134,7 +152,7 @@ impl SymbolTable {
|
|||||||
let fields = HashMap::new();
|
let fields = HashMap::new();
|
||||||
let spec = SymbolSpec::RecordConstructor { fields };
|
let spec = SymbolSpec::RecordConstructor { fields };
|
||||||
let symbol = Symbol { name: name.clone(), spec };
|
let symbol = Symbol { name: name.clone(), spec };
|
||||||
self.values.insert(name.clone(), symbol);
|
self.add_new_symbol(name, symbol);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user