Fix compilation errors for the newly introduce test & add type inference.
Tests are basically functions for which the return type should unify with bool. In principle, the type checker could also check that a test function has no arguments but, a test function with arguments wouldn't parse in the first place; feels a bit hacky but it works when considering the pipeline as a whole. Note that the code generation is still to be done.
This commit is contained in:
parent
ea48747825
commit
bc785673b2
|
@ -279,7 +279,7 @@ pub fn test_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = Parse
|
||||||
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
||||||
)
|
)
|
||||||
.map_with_span(|((name, span_end), body), span| {
|
.map_with_span(|((name, span_end), body), span| {
|
||||||
ast::UntypedDefinition::Fn(ast::Function {
|
ast::UntypedDefinition::Test(ast::Function {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: body.unwrap_or(expr::UntypedExpr::Todo {
|
body: body.unwrap_or(expr::UntypedExpr::Todo {
|
||||||
kind: TodoKind::EmptyFunction,
|
kind: TodoKind::EmptyFunction,
|
||||||
|
|
|
@ -255,6 +255,7 @@ impl<'a> Environment<'a> {
|
||||||
definition @ (Definition::TypeAlias { .. }
|
definition @ (Definition::TypeAlias { .. }
|
||||||
| Definition::DataType { .. }
|
| Definition::DataType { .. }
|
||||||
| Definition::Use { .. }
|
| Definition::Use { .. }
|
||||||
|
| Definition::Test { .. }
|
||||||
| Definition::ModuleConstant { .. }) => definition,
|
| Definition::ModuleConstant { .. }) => definition,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -911,7 +912,10 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Definition::Fn { .. } | Definition::Use { .. } | Definition::ModuleConstant { .. } => {}
|
Definition::Fn { .. }
|
||||||
|
| Definition::Test { .. }
|
||||||
|
| Definition::Use { .. }
|
||||||
|
| Definition::ModuleConstant { .. } => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -990,6 +994,24 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Definition::Test(Function { name, location, .. }) => {
|
||||||
|
hydrators.insert(name.clone(), Hydrator::new());
|
||||||
|
let arg_types = vec![];
|
||||||
|
let return_type = builtins::bool();
|
||||||
|
self.insert_variable(
|
||||||
|
name.clone(),
|
||||||
|
ValueConstructorVariant::ModuleFn {
|
||||||
|
name: name.clone(),
|
||||||
|
field_map: None,
|
||||||
|
module: module_name.to_owned(),
|
||||||
|
arity: 0,
|
||||||
|
location: *location,
|
||||||
|
builtin: None,
|
||||||
|
},
|
||||||
|
function(arg_types, return_type),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Definition::DataType(DataType {
|
Definition::DataType(DataType {
|
||||||
location,
|
location,
|
||||||
public,
|
public,
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
RecordConstructorArg, TypeAlias, TypedDefinition, TypedModule, UntypedDefinition,
|
RecordConstructorArg, TypeAlias, TypedDefinition, TypedModule, UntypedDefinition,
|
||||||
UntypedModule, Use,
|
UntypedModule, Use,
|
||||||
},
|
},
|
||||||
|
builtins,
|
||||||
builtins::function,
|
builtins::function,
|
||||||
parser::token::Token,
|
parser::token::Token,
|
||||||
IdGenerator,
|
IdGenerator,
|
||||||
|
@ -66,8 +67,8 @@ impl UntypedModule {
|
||||||
for def in self.definitions().cloned() {
|
for def in self.definitions().cloned() {
|
||||||
match def {
|
match def {
|
||||||
Definition::ModuleConstant { .. } => consts.push(def),
|
Definition::ModuleConstant { .. } => consts.push(def),
|
||||||
|
|
||||||
Definition::Fn { .. }
|
Definition::Fn { .. }
|
||||||
|
| Definition::Test { .. }
|
||||||
| Definition::TypeAlias { .. }
|
| Definition::TypeAlias { .. }
|
||||||
| Definition::DataType { .. }
|
| Definition::DataType { .. }
|
||||||
| Definition::Use { .. } => not_consts.push(def),
|
| Definition::Use { .. } => not_consts.push(def),
|
||||||
|
@ -233,6 +234,17 @@ fn infer_definition(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Definition::Test(f) => {
|
||||||
|
if let Definition::Fn(f) =
|
||||||
|
infer_definition(Definition::Fn(f), module_name, hydrators, environment)?
|
||||||
|
{
|
||||||
|
environment.unify(f.return_type.clone(), builtins::bool(), f.location)?;
|
||||||
|
Ok(Definition::Test(f))
|
||||||
|
} else {
|
||||||
|
unreachable!("test defintion inferred as something else than a function?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Definition::TypeAlias(TypeAlias {
|
Definition::TypeAlias(TypeAlias {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
|
|
|
@ -336,6 +336,9 @@ impl Project {
|
||||||
func,
|
func,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Definition::Test(_) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
Definition::TypeAlias(ta) => {
|
Definition::TypeAlias(ta) => {
|
||||||
type_aliases.insert((module.name.clone(), ta.alias.clone()), ta);
|
type_aliases.insert((module.name.clone(), ta.alias.clone()), ta);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,3 +11,7 @@ pub fn spend(datum: sample.Datum, rdmr: sample.Redeemer, _ctx: Nil) -> Bool {
|
||||||
|
|
||||||
z == #(#[222], #[222])
|
z == #(#[222], #[222])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test foo() {
|
||||||
|
1 + 1 == 2
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue