diff --git a/typed/src/annotation.rs b/typed/src/annotation.rs new file mode 100644 index 0000000000..761dea19e3 --- /dev/null +++ b/typed/src/annotation.rs @@ -0,0 +1,58 @@ +use crate::{Circuit, Function, Identifier, Import, InputVariable, TestFunction}; +use leo_ast::{ + annotations::{Annotation, AnnotationArguments, AnnotationName}, + definitions::{AnnotatedDefinition, Definition}, +}; + +use std::collections::HashMap; + +pub fn load_annotation( + annotated_definition: AnnotatedDefinition, + _imports: &mut Vec, + _circuits: &mut HashMap, + _functions: &mut HashMap, + tests: &mut HashMap, + _expected: &mut Vec, +) { + let ast_annotation = annotated_definition.annotation; + let ast_definition = *annotated_definition.definition; + + match ast_definition { + Definition::Import(_) => unimplemented!("annotated imports are not supported yet"), + Definition::Circuit(_) => unimplemented!("annotated circuits are not supported yet"), + Definition::Function(_) => unimplemented!("annotated functions are not supported yet"), + Definition::TestFunction(ast_test) => { + let test = TestFunction::from(ast_test); + load_annotated_test(test, ast_annotation, tests) + } + Definition::Annotated(_) => unimplemented!("nested annotations are not supported yet"), + } +} + +pub fn load_annotated_test(test: TestFunction, annotation: Annotation, tests: &mut HashMap) { + let name = annotation.name; + let ast_arguments = annotation.arguments; + + match name { + AnnotationName::Context(_) => load_annotated_test_context(test, ast_arguments, tests), + } +} + +pub fn load_annotated_test_context( + mut test: TestFunction, + ast_arguments: AnnotationArguments, + tests: &mut HashMap, +) { + let arguments = ast_arguments.arguments; + + if arguments.len() != 1 { + panic!("text context annotation must have one argument identifier") + } + + let ast_input_file = arguments[0].to_owned(); + let input_file = Identifier::from(ast_input_file); + + test.input_file = Some(input_file); + + tests.insert(test.function.identifier.clone(), test); +} diff --git a/typed/src/functions/test_function.rs b/typed/src/functions/test_function.rs index cc20c13ad7..f82344afc2 100644 --- a/typed/src/functions/test_function.rs +++ b/typed/src/functions/test_function.rs @@ -1,13 +1,19 @@ -use crate::Function; +use crate::{Function, Identifier}; use leo_ast::functions::TestFunction as AstTestFunction; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct TestFunction(pub Function); +pub struct TestFunction { + pub function: Function, + pub input_file: Option, +} impl<'ast> From> for TestFunction { fn from(test: AstTestFunction) -> Self { - TestFunction(Function::from(test.function)) + TestFunction { + function: Function::from(test.function), + input_file: None, // pass custom input file with `@context` annotation + } } } diff --git a/typed/src/lib.rs b/typed/src/lib.rs index c1d90de64c..e52df4e8cb 100644 --- a/typed/src/lib.rs +++ b/typed/src/lib.rs @@ -1,6 +1,9 @@ //! A typed syntax tree is represented as a `Program` and consists of import, circuit, and function definitions. //! Each defined type consists of typed statements and expressions. +pub mod annotation; +pub use self::annotation::*; + pub mod circuits; pub use self::circuits::*; diff --git a/typed/src/program.rs b/typed/src/program.rs index c4964ffd10..abe5cb8bf0 100644 --- a/typed/src/program.rs +++ b/typed/src/program.rs @@ -1,7 +1,7 @@ //! A typed Leo program consists of import, circuit, and function definitions. //! Each defined type consists of typed statements and expressions. -use crate::{Circuit, Function, Identifier, Import, InputVariable, TestFunction}; +use crate::{load_annotation, Circuit, Function, Identifier, Import, InputVariable, TestFunction}; use leo_ast::{definitions::Definition, files::File}; use serde::{Deserialize, Serialize}; @@ -47,7 +47,17 @@ impl<'ast> Program { } Definition::TestFunction(test_def) => { let test = TestFunction::from(test_def); - tests.insert(test.0.identifier.clone(), test); + tests.insert(test.function.identifier.clone(), test); + } + Definition::Annotated(annotated_definition) => { + load_annotation( + annotated_definition, + &mut imports, + &mut circuits, + &mut functions, + &mut tests, + &mut expected_input, + ); } });