From c9052e0a3bf970a5185bc912df5bf9722b7c8667 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 19 Sep 2019 01:34:21 -0700 Subject: [PATCH] QualifiedName with id --- schala-lang/language/src/ast.rs | 9 ++++-- schala-lang/language/src/parsing.rs | 6 ++-- schala-lang/language/src/parsing/test.rs | 33 +++++++++++++------- schala-lang/language/src/reduced_ast.rs | 18 +++++------ schala-lang/language/src/scope_resolution.rs | 2 +- schala-lang/language/src/typechecking.rs | 2 +- 6 files changed, 43 insertions(+), 27 deletions(-) diff --git a/schala-lang/language/src/ast.rs b/schala-lang/language/src/ast.rs index 0ce6743..3a9b1c5 100644 --- a/schala-lang/language/src/ast.rs +++ b/schala-lang/language/src/ast.rs @@ -101,8 +101,13 @@ pub enum StatementKind { pub type Block = Vec>; pub type ParamName = Rc; -#[derive(Debug, PartialEq, Clone)] -pub struct QualifiedName(pub Vec>); +#[derive(Debug, Derivative, Clone)] +#[derivative(PartialEq)] +pub struct QualifiedName { + #[derivative(PartialEq="ignore")] + pub id: ItemId, + pub components: Vec>, +} #[derive(Debug, PartialEq, Clone)] pub struct FormalParam { diff --git a/schala-lang/language/src/parsing.rs b/schala-lang/language/src/parsing.rs index 4e5aa84..79c6f44 100644 --- a/schala-lang/language/src/parsing.rs +++ b/schala-lang/language/src/parsing.rs @@ -775,17 +775,17 @@ impl Parser { #[recursive_descent_method] fn qualified_identifier(&mut self) -> ParseResult { - let mut vec = vec![self.identifier()?]; + let mut components = vec![self.identifier()?]; loop { match (self.token_handler.peek_kind(), self.token_handler.peek_kind_n(1)) { (Colon, Colon) => { self.token_handler.next(); self.token_handler.next(); - vec.push(self.identifier()?); + components.push(self.identifier()?); }, _ => break, } } - Ok(QualifiedName(vec)) + Ok(QualifiedName { id: self.id_store.fresh(), components }) } #[recursive_descent_method] diff --git a/schala-lang/language/src/parsing/test.rs b/schala-lang/language/src/parsing/test.rs index e961b11..2b438a0 100644 --- a/schala-lang/language/src/parsing/test.rs +++ b/schala-lang/language/src/parsing/test.rs @@ -30,8 +30,19 @@ macro_rules! parse_test_wrap_ast { macro_rules! parse_error { ($string:expr) => { assert!(parse($string).is_err()) } } +macro_rules! qname { + ( $( $component:expr),* ) => { + { + let mut components = vec![]; + $( + components.push(rc!($component)); + )* + QualifiedName { components, id: ItemIdStore::new_id() } + } + }; +} macro_rules! val { - ($var:expr) => { Value(Meta::new(QualifiedName(vec![Rc::new($var.to_string())]))) }; + ($var:expr) => { Value(Meta::new(QualifiedName { components: vec![Rc::new($var.to_string())], id: ItemIdStore::new_id() })) }; } macro_rules! ty { ($name:expr) => { Singleton(tys!($name)) } @@ -163,10 +174,10 @@ fn parsing_identifiers() { parse_test_wrap_ast!("None", exst!(val!("None"))); parse_test_wrap_ast!("Pandas { a: x + y }", - exst!(NamedStruct { name: Meta::new(QualifiedName(vec![rc!(Pandas)])), fields: vec![(rc!(a), ex!(m binexp!("+", val!("x"), val!("y"))))]}) + exst!(NamedStruct { name: Meta::new(qname!(Pandas)), fields: vec![(rc!(a), ex!(m binexp!("+", val!("x"), val!("y"))))]}) ); parse_test_wrap_ast! { "Pandas { a: n, b: q, }", - exst!(NamedStruct { name: Meta::new(QualifiedName(vec![rc!(Pandas)])), fields: + exst!(NamedStruct { name: Meta::new(qname!(Pandas)), fields: vec![(rc!(a), ex!(m val!("n"))), (rc!(b), ex!(m val!("q")))] } ) @@ -179,13 +190,13 @@ fn qualified_identifiers() { parse_test_wrap_ast! { "let q_q = Yolo::Swaggins", Meta::new(decl!(Binding { name: rc!(q_q), constant: true, type_anno: None, - expr: Meta::new(Expression::new(ItemIdStore::new_id(), Value(Meta::new(QualifiedName(vec![rc!(Yolo), rc!(Swaggins)]))))), + expr: Meta::new(Expression::new(ItemIdStore::new_id(), Value(Meta::new(qname!(Yolo, Swaggins))))), })) } parse_test_wrap_ast! { "thing::item::call()", - exst!(Call { f: bx![ex!(m Value(Meta::new(QualifiedName(vec![rc!(thing), rc!(item), rc!(call)]))))], arguments: vec![] }) + exst!(Call { f: bx![ex!(m Value(Meta::new(qname!(thing, item, call))))], arguments: vec![] }) } } @@ -609,8 +620,8 @@ fn patterns() { "if x is Some(a) then { 4 } else { 9 }", exst!( IfExpression { discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))), - body: bx!(IfExpressionBody::SimplePatternMatch(Pattern::TupleStruct(Meta::new(QualifiedName(vec![rc!(Some)])), - vec![Pattern::VarOrName(Meta::new(QualifiedName(vec![rc!(a)])))]), vec![exst!(s "4")], Some(vec![exst!(s "9")]))) } + body: bx!(IfExpressionBody::SimplePatternMatch(Pattern::TupleStruct(Meta::new(qname!(Some)), + vec![Pattern::VarOrName(Meta::new(qname!(a)))]), vec![exst!(s "4")], Some(vec![exst!(s "9")]))) } ) } @@ -618,8 +629,8 @@ fn patterns() { "if x is Some(a) then 4 else 9", exst!( IfExpression { discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))), - body: bx!(IfExpressionBody::SimplePatternMatch(Pattern::TupleStruct(Meta::new(QualifiedName(vec![rc!(Some)])), - vec![Pattern::VarOrName(Meta::new(QualifiedName(vec![rc!(a)])))]), vec![exst!(s "4")], Some(vec![exst!(s "9")]))) } + body: bx!(IfExpressionBody::SimplePatternMatch(Pattern::TupleStruct(Meta::new(qname!(Some)), + vec![Pattern::VarOrName(Meta::new(qname!(a)))]), vec![exst!(s "4")], Some(vec![exst!(s "9")]))) } ) } @@ -628,9 +639,9 @@ fn patterns() { IfExpression { discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))), body: bx!(IfExpressionBody::SimplePatternMatch( - Pattern::Record(Meta::new(QualifiedName(vec![rc!(Something)])), vec![ + Pattern::Record(Meta::new(qname!(Something)), vec![ (rc!(a),Pattern::Literal(PatternLiteral::StringPattern(rc!(a)))), - (rc!(b),Pattern::VarOrName(Meta::new(QualifiedName(vec![rc!(x)])))) + (rc!(b),Pattern::VarOrName(Meta::new(qname!(x)))) ]), vec![exst!(s "4")], Some(vec![exst!(s "9")]))) } diff --git a/schala-lang/language/src/reduced_ast.rs b/schala-lang/language/src/reduced_ast.rs index 16fef7c..c42d104 100644 --- a/schala-lang/language/src/reduced_ast.rs +++ b/schala-lang/language/src/reduced_ast.rs @@ -360,9 +360,9 @@ fn handle_symbol(symbol: Option<&Symbol>, inner_patterns: &Vec, symbol_ if symbol_exists { None } else { - let QualifiedName(name_elems) = meta_name.node(); - if name_elems.len() == 1 { - Some(name_elems[0].clone()) + let QualifiedName { components, .. } = meta_name.node(); + if components.len() == 1 { + Some(components[0].clone()) } else { panic!("Bad variable name in pattern"); } @@ -415,11 +415,11 @@ impl Pattern { fn to_subpattern(&self, symbol_table: &SymbolTable) -> Subpattern { use self::Pattern::*; match self { - TupleStruct( Meta { n: QualifiedName(vec), fqsn, .. }, inner_patterns) => { + TupleStruct( Meta { n: QualifiedName{ components, .. }, fqsn, .. }, inner_patterns) => { match fqsn.as_ref().and_then(|fqsn| symbol_table.lookup_by_fqsn(&fqsn)) { Some(symbol) => handle_symbol(Some(symbol), inner_patterns, symbol_table), None => { - panic!("Symbol {:?} not found", QualifiedName(vec.to_vec())); + panic!("Symbol {:?} not found", components); } } }, @@ -429,16 +429,16 @@ impl Pattern { }, Ignored => Subpattern { tag: None, subpatterns: vec![], guard: None, bound_vars: vec![] }, Literal(lit) => lit.to_subpattern(symbol_table), - VarOrName(Meta { n: QualifiedName(vec), fqsn, .. }) => { + VarOrName(Meta { n: QualifiedName { components, .. }, fqsn, .. }) => { // if fqsn is Some, treat this as a symbol pattern. If it's None, treat it // as a variable. - println!("Calling VarOrName reduction with : {:?}", vec); + println!("Calling VarOrName reduction with : {:?}", components); match fqsn.as_ref().and_then(|fqsn| symbol_table.lookup_by_fqsn(&fqsn)) { Some(symbol) => handle_symbol(Some(symbol), &vec![], symbol_table), None => { - let name = if vec.len() == 1 { - vec[0].clone() + let name = if components.len() == 1 { + components[0].clone() } else { panic!("check this line of code yo"); }; diff --git a/schala-lang/language/src/scope_resolution.rs b/schala-lang/language/src/scope_resolution.rs index 4043c37..64b2c0e 100644 --- a/schala-lang/language/src/scope_resolution.rs +++ b/schala-lang/language/src/scope_resolution.rs @@ -152,7 +152,7 @@ impl<'a> ScopeResolver<'a> { //TODO this is incomplete fn lookup_name_in_scope(sym_name: &QualifiedName) -> FullyQualifiedSymbolName { - let QualifiedName(vec) = sym_name; + let QualifiedName { components: vec, .. } = sym_name; let len = vec.len(); let new_vec: Vec = vec.iter().enumerate().map(|(i, name)| { let kind = if i == (len - 1) { diff --git a/schala-lang/language/src/typechecking.rs b/schala-lang/language/src/typechecking.rs index 52464dc..71f6cb4 100644 --- a/schala-lang/language/src/typechecking.rs +++ b/schala-lang/language/src/typechecking.rs @@ -414,7 +414,7 @@ impl<'a> TypeContext<'a> { } fn handle_value(&mut self, val: &QualifiedName) -> InferResult { - let QualifiedName(vec) = val; + let QualifiedName { components: vec, .. } = val; let var = &vec[0]; match self.variable_map.lookup(var) { Some(ty) => Ok(ty.clone()),