mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-24 18:39:50 -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)) => {
|
(Shape::Hole(sym), other) | (other, Shape::Hole(sym)) => {
|
||||||
if symbol_table.contains_key(&sym.val) {
|
if symbol_table.contains_key(&sym.val) {
|
||||||
symbol_table.insert(sym.val.clone(), other.clone().with_pos(sym.pos.clone()));
|
symbol_table.insert(sym.val.clone(), other.clone().with_pos(sym.pos.clone()));
|
||||||
} else {
|
|
||||||
// TODO(jwall): Is this an error?
|
|
||||||
todo!();
|
|
||||||
}
|
}
|
||||||
other.clone()
|
other.clone()
|
||||||
},
|
},
|
||||||
|
@ -33,7 +33,7 @@ pub trait DeriveShape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DeriveShape for FuncDef {
|
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.
|
// 1. First set up our symbols.
|
||||||
let mut table = self
|
let mut table = self
|
||||||
.argdefs
|
.argdefs
|
||||||
@ -41,11 +41,11 @@ impl DeriveShape for FuncDef {
|
|||||||
.map(|sym| (sym.val.clone(), Shape::Hole(sym.clone())))
|
.map(|sym| (sym.val.clone(), Shape::Hole(sym.clone())))
|
||||||
.collect::<BTreeMap<Rc<str>, Shape>>();
|
.collect::<BTreeMap<Rc<str>, Shape>>();
|
||||||
// 2.Then determine the shapes of those symbols in our expression.
|
// 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.
|
// 3. Finally determine what the return shape can be.
|
||||||
Shape::Func(FuncShapeDef {
|
Shape::Func(FuncShapeDef {
|
||||||
args: table,
|
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]
|
#[test]
|
||||||
fn infer_symbol_type_test() {
|
fn infer_symbol_type_test() {
|
||||||
// foo should be determined to be int
|
// foo should be determined to be int
|
||||||
let expr = "1 + foo".into();
|
let foo = Into::<Rc<str>>::into("foo");
|
||||||
let symbol: Rc<str> = "foo".into();
|
let bar = Into::<Rc<str>>::into("bar");
|
||||||
let mut checker = Checker::new();
|
let table = vec![
|
||||||
checker
|
(
|
||||||
.symbol_table
|
"1 + foo",
|
||||||
.insert(symbol.clone(), Shape::Hole(PositionedItem::new(symbol.clone(), Position::new(0, 0, 0))));
|
vec![(
|
||||||
let tokens = tokenize(expr, None).unwrap();
|
foo.clone(),
|
||||||
let token_iter = SliceIter::new(&tokens);
|
Shape::Int(PositionedItem::new(1, Position::new(0, 0, 0))),
|
||||||
let expr = expression(token_iter);
|
)],
|
||||||
if let abortable_parser::Result::Complete(_, mut expr) = expr {
|
vec![Shape::Hole(PositionedItem::new(
|
||||||
checker.walk_expression(&mut expr);
|
foo.clone(),
|
||||||
dbg!(&checker.symbol_table);
|
Position::new(0, 0, 0),
|
||||||
assert_eq!(
|
))],
|
||||||
checker.symbol_table[&symbol],
|
),
|
||||||
Shape::Int(PositionedItem::new(1, 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