Allow any expression as constants

This is only a start. It compiles, but with a few TODOs left open. In particular, it doesn't currently handle constants depending on other constants or functions; nor does it hoist constants.
This commit is contained in:
KtorZ
2024-08-02 17:23:14 +02:00
parent 79cf0b8d97
commit cd0a9440e8
17 changed files with 192 additions and 282 deletions

View File

@@ -1,8 +1,6 @@
use crate::{github::repo::LatestRelease, package_name::PackageName, paths, Error};
use aiken_lang::{
ast::{
Annotation, ByteArrayFormatPreference, Constant, ModuleConstant, Span, UntypedDefinition,
},
ast::{Annotation, ByteArrayFormatPreference, ModuleConstant, Span, UntypedDefinition},
expr::UntypedExpr,
parser::token::Base,
};
@@ -78,24 +76,14 @@ impl SimpleExpr {
let (value, annotation) = match self {
SimpleExpr::Bool(..) => todo!("requires https://github.com/aiken-lang/aiken/pull/992"),
SimpleExpr::Int(i) => (
SimpleExpr::Int(_) => (
// TODO: Replace with 'self.as_untyped_expr()' after https://github.com/aiken-lang/aiken/pull/992
Constant::Int {
location,
value: format!("{i}"),
base: Base::Decimal {
numeric_underscore: false,
},
},
self.as_untyped_expr(),
Some(Annotation::int(location)),
),
SimpleExpr::ByteArray(bs, preferred_format) => (
SimpleExpr::ByteArray(_, _) => (
// TODO: Replace with 'self.as_untyped_expr()' after https://github.com/aiken-lang/aiken/pull/992
Constant::ByteArray {
location,
bytes: bs.to_vec(),
preferred_format: *preferred_format,
},
self.as_untyped_expr(),
Some(Annotation::bytearray(location)),
),
SimpleExpr::List(..) => todo!("requires https://github.com/aiken-lang/aiken/pull/992"),
@@ -107,8 +95,7 @@ impl SimpleExpr {
public: true,
name: identifier.to_string(),
annotation,
value: Box::new(value),
tipo: (),
value,
})
}
}

View File

@@ -36,7 +36,7 @@ use aiken_lang::{
TypedFunction, UntypedDefinition,
},
builtins,
expr::UntypedExpr,
expr::{TypedExpr, UntypedExpr},
format::{Formatter, MAX_COLUMNS},
gen_uplc::CodeGenerator,
line_numbers::LineNumbers,
@@ -98,6 +98,7 @@ where
checks_count: Option<usize>,
event_listener: T,
functions: IndexMap<FunctionAccessKey, TypedFunction>,
constants: IndexMap<FunctionAccessKey, TypedExpr>,
data_types: IndexMap<DataTypeKey, TypedDataType>,
module_sources: HashMap<String, (String, LineNumbers)>,
}
@@ -149,6 +150,7 @@ where
checks_count: None,
event_listener,
functions,
constants: IndexMap::new(),
data_types,
module_sources: HashMap::new(),
}
@@ -158,6 +160,7 @@ where
CodeGenerator::new(
self.config.plutus,
utils::indexmap::as_ref_values(&self.functions),
utils::indexmap::as_ref_values(&self.constants),
utils::indexmap::as_ref_values(&self.data_types),
utils::indexmap::as_str_ref_values(&self.module_types),
utils::indexmap::as_str_ref_values(&self.module_sources),
@@ -805,6 +808,7 @@ where
&mut self.module_sources,
&mut self.module_types,
&mut self.functions,
&mut self.constants,
&mut self.data_types,
)?;

View File

@@ -5,6 +5,7 @@ use aiken_lang::{
Tracing, TypedDataType, TypedFunction, TypedModule, TypedValidator, UntypedModule,
Validator,
},
expr::TypedExpr,
line_numbers::LineNumbers,
parser::extra::{comments_before, Comment, ModuleExtra},
tipo::TypeInfo,
@@ -49,6 +50,7 @@ impl ParsedModule {
module_sources: &mut HashMap<String, (String, LineNumbers)>,
module_types: &mut HashMap<String, TypeInfo>,
functions: &mut IndexMap<FunctionAccessKey, TypedFunction>,
constants: &mut IndexMap<FunctionAccessKey, TypedExpr>,
data_types: &mut IndexMap<DataTypeKey, TypedDataType>,
) -> Result<(CheckedModule, Vec<Warning>), Error> {
let mut warnings = Vec::new();
@@ -92,7 +94,7 @@ impl ParsedModule {
module_types.insert(self.name.clone(), ast.type_info.clone());
// Register function definitions & data-types for easier access later.
ast.register_definitions(functions, data_types);
ast.register_definitions(functions, constants, data_types);
Ok((
CheckedModule {

View File

@@ -62,7 +62,8 @@ mod test {
let mut functions = builtins::prelude_functions(&id_gen, &module_types);
let mut data_types = builtins::prelude_data_types(&id_gen);
ast.register_definitions(&mut functions, &mut data_types);
let mut constants = IndexMap::new();
ast.register_definitions(&mut functions, &mut constants, &mut data_types);
let mut module_sources = HashMap::new();
module_sources.insert(
@@ -87,6 +88,7 @@ mod test {
let mut generator = CodeGenerator::new(
PlutusVersion::default(),
utils::indexmap::as_ref_values(&functions),
utils::indexmap::as_ref_values(&constants),
utils::indexmap::as_ref_values(&data_types),
utils::indexmap::as_str_ref_values(&module_types),
utils::indexmap::as_str_ref_values(&module_sources),
@@ -240,13 +242,14 @@ mod test {
}
"#});
assert!(prop
.run::<()>(
assert!(
prop.run::<()>(
42,
PropertyTest::DEFAULT_MAX_SUCCESS,
&PlutusVersion::default()
)
.is_success());
.is_success()
);
}
#[test]

View File

@@ -9,6 +9,7 @@ use aiken_lang::{
DataTypeKey, FunctionAccessKey, ModuleKind, TraceLevel, Tracing, TypedDataType,
TypedFunction,
},
expr::TypedExpr,
gen_uplc::CodeGenerator,
line_numbers::LineNumbers,
parser,
@@ -28,6 +29,7 @@ pub struct TestProject {
pub package: PackageName,
pub id_gen: IdGenerator,
pub functions: IndexMap<FunctionAccessKey, TypedFunction>,
pub constants: IndexMap<FunctionAccessKey, TypedExpr>,
pub data_types: IndexMap<DataTypeKey, TypedDataType>,
pub module_types: HashMap<String, TypeInfo>,
pub module_sources: HashMap<String, (String, LineNumbers)>,
@@ -48,12 +50,14 @@ impl TestProject {
let functions = builtins::prelude_functions(&id_gen, &module_types);
let data_types = builtins::prelude_data_types(&id_gen);
let constants = IndexMap::new();
TestProject {
package,
id_gen,
module_types,
functions,
constants,
data_types,
module_sources: HashMap::new(),
}
@@ -63,6 +67,7 @@ impl TestProject {
CodeGenerator::new(
PlutusVersion::default(),
utils::indexmap::as_ref_values(&self.functions),
utils::indexmap::as_ref_values(&self.constants),
utils::indexmap::as_ref_values(&self.data_types),
utils::indexmap::as_str_ref_values(&self.module_types),
utils::indexmap::as_str_ref_values(&self.module_sources),
@@ -104,7 +109,11 @@ impl TestProject {
.expect("Failed to type-check module");
// Register function definitions & data-types for easier access later.
ast.register_definitions(&mut self.functions, &mut self.data_types);
ast.register_definitions(
&mut self.functions,
&mut self.constants,
&mut self.data_types,
);
// Register module sources for an easier access later.
self.module_sources.insert(