diff --git a/schala-lang/language/src/eval/test.rs b/schala-lang/language/src/eval/test.rs index 54aff6c..527f912 100644 --- a/schala-lang/language/src/eval/test.rs +++ b/schala-lang/language/src/eval/test.rs @@ -81,12 +81,12 @@ fn scopes() { fn if_is_patterns() { let source = r#" type Option = Some(T) | None -let x = Some(9); if x is Some(q) then { q } else { 0 }"#; +let x = Option::Some(9); if x is Option::Some(q) then { q } else { 0 }"#; test_in_fresh_env!(source, "9"); let source = r#" type Option = Some(T) | None -let x = None; if x is Some(q) then { q } else { 0 }"#; +let x = Option::None; if x is Option::Some(q) then { q } else { 0 }"#; test_in_fresh_env!(source, "0"); } @@ -94,15 +94,15 @@ let x = None; if x is Some(q) then { q } else { 0 }"#; fn full_if_matching() { let source = r#" type Option = Some(T) | None -let a = None +let a = Option::None if a { is Option::None -> 4, is Option::Some(x) -> x } "#; test_in_fresh_env!(source, "4"); let source = r#" type Option = Some(T) | None -let a = Some(99) -if a { is None -> 4, is Some(x) -> x } +let a = Option::Some(99) +if a { is Option::None -> 4, is Option::Some(x) -> x } "#; test_in_fresh_env!(source, "99"); @@ -153,7 +153,7 @@ test_in_fresh_env!(source, "\"y\""); fn ignore_pattern() { let source = r#" type Option = Some(T) | None -if Some(10) { +if Option::Some(10) { is _ -> "hella" } "#; @@ -209,25 +209,25 @@ test_in_fresh_env!(source, 5); fn prim_obj_pattern() { let source = r#" type Stuff = Mulch(Nat) | Jugs(Nat, String) | Mardok -let a = Mulch(20) -let b = Jugs(1, "haha") -let c = Mardok +let a = Stuff::Mulch(20) +let b = Stuff::Jugs(1, "haha") +let c = Stuff::Mardok let x = if a { - is Mulch(20) -> "x", + is Stuff::Mulch(20) -> "x", is _ -> "ERR" } let y = if b { - is Mulch(n) -> "ERR", - is Jugs(2, _) -> "ERR", - is Jugs(1, s) -> s, + is Stuff::Mulch(n) -> "ERR", + is Stuff::Jugs(2, _) -> "ERR", + is Stuff::Jugs(1, s) -> s, is _ -> "ERR", } let z = if c { - is Jugs(_, _) -> "ERR", - is Mardok -> "NIGH", + is Stuff::Jugs(_, _) -> "ERR", + is Stuff::Mardok -> "NIGH", is _ -> "ERR", } diff --git a/schala-lang/language/src/prelude.schala b/schala-lang/language/src/prelude.schala index 886c7bb..64f3243 100644 --- a/schala-lang/language/src/prelude.schala +++ b/schala-lang/language/src/prelude.schala @@ -5,8 +5,8 @@ type Ord = LT | EQ | GT fn map(input: Option, func: Func): Option { if input { - is Some(x) -> Some(func(x)), - is None -> None, + is Option::Some(x) -> Option::Some(func(x)), + is Option::None -> Option::None, } } diff --git a/schala-lang/language/src/reduced_ast.rs b/schala-lang/language/src/reduced_ast.rs index 786c0b1..25a749b 100644 --- a/schala-lang/language/src/reduced_ast.rs +++ b/schala-lang/language/src/reduced_ast.rs @@ -158,7 +158,7 @@ impl Meta { Value(qualified_name) => { let ref sym_name = match self.fqsn { Some(ref fqsn) => fqsn, - None => return Expr::ReductionError(format!("FQSN lookup for value A failed")), + None => return Expr::ReductionError(format!("FQSN lookup for Value {:?} failed", qualified_name)), }; let FullyQualifiedSymbolName(ref v) = sym_name; let name = v.last().unwrap().name.clone(); @@ -355,14 +355,13 @@ impl Pattern { fn to_subpattern(&self, symbol_table: &SymbolTable) -> Subpattern { use self::Pattern::*; match self { - TupleStruct( Meta { n: QualifiedName(vec), .. }, inner_patterns) => { - let name = if vec.len() == 1 { - vec[0].clone() - } else { - panic!("check this line of code 2 yo"); - }; - let symbol = symbol_table.lookup_by_name(&name).expect(&format!("Symbol {} not found", name)); - handle_symbol(Some(symbol), inner_patterns, symbol_table) + TupleStruct( Meta { n: QualifiedName(vec), 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())); + } + } }, TuplePattern(inner_patterns) => handle_symbol(None, inner_patterns, symbol_table), Record(_name, _pairs) => { @@ -371,23 +370,24 @@ 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, .. }) => { - // if fqsn is Some, then it should be a symbol pattern but isn't yet - // if it's None, then it's a variable. scope resolution makes this decision + // 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); - //TODO this name needs to be resolved from metadata with context - let name = if vec.len() == 1 { - vec[0].clone() - } else { - panic!("check this line of code yo"); - }; - - match symbol_table.lookup_by_name(&name) { + + match fqsn.as_ref().and_then(|fqsn| symbol_table.lookup_by_fqsn(&fqsn)) { Some(symbol) => handle_symbol(Some(symbol), &vec![], symbol_table), - None => Subpattern { - tag: None, - subpatterns: vec![], - guard: None, - bound_vars: vec![Some(name.clone())], + None => { + let name = if vec.len() == 1 { + vec[0].clone() + } else { + panic!("check this line of code yo"); + }; + Subpattern { + tag: None, + subpatterns: vec![], + guard: None, + bound_vars: vec![Some(name.clone())], + } } } }, diff --git a/schala-lang/language/src/scope_resolution.rs b/schala-lang/language/src/scope_resolution.rs index 8ec6abf..e4bebcb 100644 --- a/schala-lang/language/src/scope_resolution.rs +++ b/schala-lang/language/src/scope_resolution.rs @@ -81,14 +81,19 @@ impl<'a> ScopeResolver<'a> { }; match &mut **body { - IfExpressionBody::SimplePatternMatch(ref mut pat, _, _) => { + IfExpressionBody::SimplePatternMatch(ref mut pat, ref mut alt1, ref mut alt2) => { self.pattern(pat)?; + self.block(alt1)?; + if let Some(alt) = alt2.as_mut() { + self.block(alt)?; + } }, IfExpressionBody::GuardList(guardarms) => { for arm in guardarms.iter_mut() { if let Guard::Pat(ref mut pat) = arm.guard { self.pattern(pat)?; } + self.block(&mut arm.body)?; } } _ => () @@ -137,12 +142,11 @@ impl<'a> ScopeResolver<'a> { Ok(()) } - //TODO add symbol table reference to make this determination /// this might be a variable or a pattern. if a variable, set to none fn qualified_name_in_pattern(&mut self, meta_qualified_name: &mut Meta, ) { let inner_name = meta_qualified_name.node(); let fqsn = lookup_name_in_scope(inner_name); - meta_qualified_name.fqsn = Some(fqsn); + meta_qualified_name.fqsn = if self.symbol_table.lookup_by_fqsn(&fqsn).is_some() { Some(fqsn) } else { None }; } } diff --git a/schala-lang/language/src/symbol_table.rs b/schala-lang/language/src/symbol_table.rs index c82c5f1..46044bf 100644 --- a/schala-lang/language/src/symbol_table.rs +++ b/schala-lang/language/src/symbol_table.rs @@ -241,8 +241,10 @@ impl SymbolTable { use crate::ast::{TypeIdentifier, Variant}; let TypeBody(variants) = body; let ref type_name = type_name.name; - //scope_name_stack.push(name.clone()); //TODO adding this makes variants scoped under their - //type name and breaks a lot of things - don't add it until importing names works + scope_name_stack.push(ScopeSegment{ + name: type_name.clone(), + kind: ScopeSegmentKind::Type, + }); //TODO figure out why _params isn't being used here for (index, var) in variants.iter().enumerate() { match var { @@ -289,7 +291,7 @@ impl SymbolTable { }, } } - //scope_name_stack.pop(); + scope_name_stack.pop(); Ok(()) } } @@ -432,7 +434,6 @@ fn outer_func(x) { let mut symbol_table = SymbolTable::new(); let ast = quick_ast(source); symbol_table.add_top_level_symbols(&ast).unwrap(); - println!("{}", symbol_table.debug_symbol_table()); assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; tr)).is_some()); assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; fn, "inner_func"; tr)).is_some()); assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; fn, "second_inner_func"; tr)).is_some());