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:
KtorZ 2022-12-08 14:45:26 +01:00 committed by rvcas
parent ea48747825
commit bc785673b2
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
5 changed files with 44 additions and 3 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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);
} }

View File

@ -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
}