mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
tests: Expand our symbol inference test some more
This commit is contained in:
parent
a14caa77c8
commit
c7c26222fc
@ -303,9 +303,6 @@ impl Shape {
|
||||
(Shape::Hole(sym), other) | (other, Shape::Hole(sym)) => {
|
||||
if symbol_table.contains_key(&sym.val) {
|
||||
symbol_table.insert(sym.val.clone(), other.clone().with_pos(sym.pos.clone()));
|
||||
} else {
|
||||
// TODO(jwall): Is this an error?
|
||||
todo!();
|
||||
}
|
||||
other.clone()
|
||||
},
|
||||
|
@ -33,7 +33,7 @@ pub trait DeriveShape {
|
||||
}
|
||||
|
||||
impl DeriveShape for FuncDef {
|
||||
fn derive_shape(&self, _symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape {
|
||||
fn derive_shape(&self, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape {
|
||||
// 1. First set up our symbols.
|
||||
let mut table = self
|
||||
.argdefs
|
||||
@ -41,11 +41,11 @@ impl DeriveShape for FuncDef {
|
||||
.map(|sym| (sym.val.clone(), Shape::Hole(sym.clone())))
|
||||
.collect::<BTreeMap<Rc<str>, Shape>>();
|
||||
// 2.Then determine the shapes of those symbols in our expression.
|
||||
let _shape = self.fields.derive_shape(&mut table);
|
||||
let shape = self.fields.derive_shape(&mut table);
|
||||
// 3. Finally determine what the return shape can be.
|
||||
Shape::Func(FuncShapeDef {
|
||||
args: table,
|
||||
ret: todo!(),
|
||||
ret: shape.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -153,24 +153,101 @@ fn multiple_binary_typefail() {
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! infer_symbol_test {
|
||||
($e:expr, $sym_list:expr, $sym_init_list:expr) => {{
|
||||
let expr = $e.into();
|
||||
let mut checker = Checker::new();
|
||||
for (idx, shape) in $sym_init_list.iter().enumerate() {
|
||||
let symbol = $sym_list[idx].0.clone();
|
||||
checker
|
||||
.symbol_table
|
||||
.insert(symbol.clone(), shape.clone());
|
||||
}
|
||||
let tokens = tokenize(expr, None).unwrap();
|
||||
let token_iter = SliceIter::new(&tokens);
|
||||
let expr = expression(token_iter);
|
||||
if let abortable_parser::Result::Complete(_, mut expr) = expr {
|
||||
checker.walk_expression(&mut expr);
|
||||
dbg!(&checker.symbol_table);
|
||||
for (sym, shape) in $sym_list {
|
||||
assert_eq!(
|
||||
checker.symbol_table[&sym],
|
||||
shape,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
assert!(false, "Expression failed to parse");
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_symbol_type_test() {
|
||||
// foo should be determined to be int
|
||||
let expr = "1 + foo".into();
|
||||
let symbol: Rc<str> = "foo".into();
|
||||
let mut checker = Checker::new();
|
||||
checker
|
||||
.symbol_table
|
||||
.insert(symbol.clone(), Shape::Hole(PositionedItem::new(symbol.clone(), Position::new(0, 0, 0))));
|
||||
let tokens = tokenize(expr, None).unwrap();
|
||||
let token_iter = SliceIter::new(&tokens);
|
||||
let expr = expression(token_iter);
|
||||
if let abortable_parser::Result::Complete(_, mut expr) = expr {
|
||||
checker.walk_expression(&mut expr);
|
||||
dbg!(&checker.symbol_table);
|
||||
assert_eq!(
|
||||
checker.symbol_table[&symbol],
|
||||
Shape::Int(PositionedItem::new(1, Position::new(0, 0, 0)))
|
||||
);
|
||||
let foo = Into::<Rc<str>>::into("foo");
|
||||
let bar = Into::<Rc<str>>::into("bar");
|
||||
let table = vec![
|
||||
(
|
||||
"1 + foo",
|
||||
vec![(
|
||||
foo.clone(),
|
||||
Shape::Int(PositionedItem::new(1, Position::new(0, 0, 0))),
|
||||
)],
|
||||
vec![Shape::Hole(PositionedItem::new(
|
||||
foo.clone(),
|
||||
Position::new(0, 0, 0),
|
||||
))],
|
||||
),
|
||||
(
|
||||
"bar + foo",
|
||||
vec![
|
||||
(
|
||||
foo.clone(),
|
||||
Shape::Float(PositionedItem::new(1.0, Position::new(0, 0, 0))),
|
||||
),
|
||||
(
|
||||
bar.clone(),
|
||||
Shape::Float(PositionedItem::new(1.0, Position::new(0, 0, 0))),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
Shape::Hole(PositionedItem::new(foo.clone(), Position::new(0, 0, 0))),
|
||||
Shape::Float(PositionedItem::new(1.0, Position::new(0, 0, 0))),
|
||||
],
|
||||
),
|
||||
];
|
||||
for (expr, sym_list, sym_init_list) in table {
|
||||
infer_symbol_test!(expr, sym_list, sym_init_list)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_func_type_test() {
|
||||
let mut args = BTreeMap::new();
|
||||
args.insert(
|
||||
Into::<Rc<str>>::into("foo"),
|
||||
Shape::Int(PositionedItem {
|
||||
pos: Position {
|
||||
file: None,
|
||||
line: 1,
|
||||
column: 6,
|
||||
offset: 5,
|
||||
},
|
||||
val: 1,
|
||||
}),
|
||||
);
|
||||
let ret = Shape::Int(PositionedItem {
|
||||
pos: Position {
|
||||
file: None,
|
||||
line: 1,
|
||||
column: 20,
|
||||
offset: 19,
|
||||
},
|
||||
val: 1,
|
||||
})
|
||||
.into();
|
||||
assert_type_success!(
|
||||
"func(foo) => foo + 1;",
|
||||
Shape::Func(FuncShapeDef { args, ret })
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user