Fixed all broken tests

This commit is contained in:
greg 2019-09-10 03:31:23 -07:00
parent b65779fb93
commit 72944ded1b
5 changed files with 53 additions and 48 deletions

View File

@ -81,12 +81,12 @@ fn scopes() {
fn if_is_patterns() { fn if_is_patterns() {
let source = r#" let source = r#"
type Option<T> = Some(T) | None type Option<T> = 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"); test_in_fresh_env!(source, "9");
let source = r#" let source = r#"
type Option<T> = Some(T) | None type Option<T> = 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"); 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() { fn full_if_matching() {
let source = r#" let source = r#"
type Option<T> = Some(T) | None type Option<T> = Some(T) | None
let a = None let a = Option::None
if a { is Option::None -> 4, is Option::Some(x) -> x } if a { is Option::None -> 4, is Option::Some(x) -> x }
"#; "#;
test_in_fresh_env!(source, "4"); test_in_fresh_env!(source, "4");
let source = r#" let source = r#"
type Option<T> = Some(T) | None type Option<T> = Some(T) | None
let a = Some(99) let a = Option::Some(99)
if a { is None -> 4, is Some(x) -> x } if a { is Option::None -> 4, is Option::Some(x) -> x }
"#; "#;
test_in_fresh_env!(source, "99"); test_in_fresh_env!(source, "99");
@ -153,7 +153,7 @@ test_in_fresh_env!(source, "\"y\"");
fn ignore_pattern() { fn ignore_pattern() {
let source = r#" let source = r#"
type Option<T> = Some(T) | None type Option<T> = Some(T) | None
if Some(10) { if Option::Some(10) {
is _ -> "hella" is _ -> "hella"
} }
"#; "#;
@ -209,25 +209,25 @@ test_in_fresh_env!(source, 5);
fn prim_obj_pattern() { fn prim_obj_pattern() {
let source = r#" let source = r#"
type Stuff = Mulch(Nat) | Jugs(Nat, String) | Mardok type Stuff = Mulch(Nat) | Jugs(Nat, String) | Mardok
let a = Mulch(20) let a = Stuff::Mulch(20)
let b = Jugs(1, "haha") let b = Stuff::Jugs(1, "haha")
let c = Mardok let c = Stuff::Mardok
let x = if a { let x = if a {
is Mulch(20) -> "x", is Stuff::Mulch(20) -> "x",
is _ -> "ERR" is _ -> "ERR"
} }
let y = if b { let y = if b {
is Mulch(n) -> "ERR", is Stuff::Mulch(n) -> "ERR",
is Jugs(2, _) -> "ERR", is Stuff::Jugs(2, _) -> "ERR",
is Jugs(1, s) -> s, is Stuff::Jugs(1, s) -> s,
is _ -> "ERR", is _ -> "ERR",
} }
let z = if c { let z = if c {
is Jugs(_, _) -> "ERR", is Stuff::Jugs(_, _) -> "ERR",
is Mardok -> "NIGH", is Stuff::Mardok -> "NIGH",
is _ -> "ERR", is _ -> "ERR",
} }

View File

@ -5,8 +5,8 @@ type Ord = LT | EQ | GT
fn map(input: Option<T>, func: Func): Option<T> { fn map(input: Option<T>, func: Func): Option<T> {
if input { if input {
is Some(x) -> Some(func(x)), is Option::Some(x) -> Option::Some(func(x)),
is None -> None, is Option::None -> Option::None,
} }
} }

View File

@ -158,7 +158,7 @@ impl Meta<Expression> {
Value(qualified_name) => { Value(qualified_name) => {
let ref sym_name = match self.fqsn { let ref sym_name = match self.fqsn {
Some(ref fqsn) => 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 FullyQualifiedSymbolName(ref v) = sym_name;
let name = v.last().unwrap().name.clone(); let name = v.last().unwrap().name.clone();
@ -355,14 +355,13 @@ impl Pattern {
fn to_subpattern(&self, symbol_table: &SymbolTable) -> Subpattern { fn to_subpattern(&self, symbol_table: &SymbolTable) -> Subpattern {
use self::Pattern::*; use self::Pattern::*;
match self { match self {
TupleStruct( Meta { n: QualifiedName(vec), .. }, inner_patterns) => { TupleStruct( Meta { n: QualifiedName(vec), fqsn, .. }, inner_patterns) => {
let name = if vec.len() == 1 { match fqsn.as_ref().and_then(|fqsn| symbol_table.lookup_by_fqsn(&fqsn)) {
vec[0].clone() Some(symbol) => handle_symbol(Some(symbol), inner_patterns, symbol_table),
} else { None => {
panic!("check this line of code 2 yo"); panic!("Symbol {:?} not found", QualifiedName(vec.to_vec()));
}; }
let symbol = symbol_table.lookup_by_name(&name).expect(&format!("Symbol {} not found", name)); }
handle_symbol(Some(symbol), inner_patterns, symbol_table)
}, },
TuplePattern(inner_patterns) => handle_symbol(None, inner_patterns, symbol_table), TuplePattern(inner_patterns) => handle_symbol(None, inner_patterns, symbol_table),
Record(_name, _pairs) => { Record(_name, _pairs) => {
@ -371,25 +370,26 @@ impl Pattern {
Ignored => Subpattern { tag: None, subpatterns: vec![], guard: None, bound_vars: vec![] }, Ignored => Subpattern { tag: None, subpatterns: vec![], guard: None, bound_vars: vec![] },
Literal(lit) => lit.to_subpattern(symbol_table), Literal(lit) => lit.to_subpattern(symbol_table),
VarOrName(Meta { n: QualifiedName(vec), fqsn, .. }) => { VarOrName(Meta { n: QualifiedName(vec), fqsn, .. }) => {
// if fqsn is Some, then it should be a symbol pattern but isn't yet // if fqsn is Some, treat this as a symbol pattern. If it's None, treat it
// if it's None, then it's a variable. scope resolution makes this decision // as a variable.
println!("Calling VarOrName reduction with : {:?}", vec); println!("Calling VarOrName reduction with : {:?}", vec);
//TODO this name needs to be resolved from metadata with context
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 { let name = if vec.len() == 1 {
vec[0].clone() vec[0].clone()
} else { } else {
panic!("check this line of code yo"); panic!("check this line of code yo");
}; };
Subpattern {
match symbol_table.lookup_by_name(&name) {
Some(symbol) => handle_symbol(Some(symbol), &vec![], symbol_table),
None => Subpattern {
tag: None, tag: None,
subpatterns: vec![], subpatterns: vec![],
guard: None, guard: None,
bound_vars: vec![Some(name.clone())], bound_vars: vec![Some(name.clone())],
} }
} }
}
}, },
} }
} }

View File

@ -81,14 +81,19 @@ impl<'a> ScopeResolver<'a> {
}; };
match &mut **body { match &mut **body {
IfExpressionBody::SimplePatternMatch(ref mut pat, _, _) => { IfExpressionBody::SimplePatternMatch(ref mut pat, ref mut alt1, ref mut alt2) => {
self.pattern(pat)?; self.pattern(pat)?;
self.block(alt1)?;
if let Some(alt) = alt2.as_mut() {
self.block(alt)?;
}
}, },
IfExpressionBody::GuardList(guardarms) => { IfExpressionBody::GuardList(guardarms) => {
for arm in guardarms.iter_mut() { for arm in guardarms.iter_mut() {
if let Guard::Pat(ref mut pat) = arm.guard { if let Guard::Pat(ref mut pat) = arm.guard {
self.pattern(pat)?; self.pattern(pat)?;
} }
self.block(&mut arm.body)?;
} }
} }
_ => () _ => ()
@ -137,12 +142,11 @@ impl<'a> ScopeResolver<'a> {
Ok(()) Ok(())
} }
//TODO add symbol table reference to make this determination
/// this might be a variable or a pattern. if a variable, set to none /// 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<QualifiedName>, ) { fn qualified_name_in_pattern(&mut self, meta_qualified_name: &mut Meta<QualifiedName>, ) {
let inner_name = meta_qualified_name.node(); let inner_name = meta_qualified_name.node();
let fqsn = lookup_name_in_scope(inner_name); 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 };
} }
} }

View File

@ -241,8 +241,10 @@ impl SymbolTable {
use crate::ast::{TypeIdentifier, Variant}; use crate::ast::{TypeIdentifier, Variant};
let TypeBody(variants) = body; let TypeBody(variants) = body;
let ref type_name = type_name.name; let ref type_name = type_name.name;
//scope_name_stack.push(name.clone()); //TODO adding this makes variants scoped under their scope_name_stack.push(ScopeSegment{
//type name and breaks a lot of things - don't add it until importing names works name: type_name.clone(),
kind: ScopeSegmentKind::Type,
});
//TODO figure out why _params isn't being used here //TODO figure out why _params isn't being used here
for (index, var) in variants.iter().enumerate() { for (index, var) in variants.iter().enumerate() {
match var { match var {
@ -289,7 +291,7 @@ impl SymbolTable {
}, },
} }
} }
//scope_name_stack.pop(); scope_name_stack.pop();
Ok(()) Ok(())
} }
} }
@ -432,7 +434,6 @@ fn outer_func(x) {
let mut symbol_table = SymbolTable::new(); let mut symbol_table = SymbolTable::new();
let ast = quick_ast(source); let ast = quick_ast(source);
symbol_table.add_top_level_symbols(&ast).unwrap(); 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"; 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, "inner_func"; tr)).is_some());
assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; fn, "second_inner_func"; tr)).is_some()); assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; fn, "second_inner_func"; tr)).is_some());