From 3d1edefedb5bcb577cce3c6398d451eefaa0c48a Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 5 Aug 2020 22:45:52 -0700 Subject: [PATCH] add definition parsing to typed. add tests --- ast/src/functions/function.rs | 2 +- ast/tests/serialization/expected_ast.json | 2 +- ast/tests/serialization/json.rs | 2 -- compiler/src/expression/circuit/circuit.rs | 2 +- .../src/expression/circuit/static_access.rs | 4 +-- .../src/statement/assign/circuit_field.rs | 2 +- compiler/src/value/value.rs | 2 +- compiler/tests/definition/import_fail.leo | 3 ++ compiler/tests/definition/mod.rs | 19 ++++++++++ compiler/tests/definition/out_of_order.leo | 5 +++ compiler/tests/definition/src/test_import.leo | 8 +++++ compiler/tests/mod.rs | 1 + typed/src/functions/function.rs | 20 +++++------ typed/src/program.rs | 36 +++++++++++-------- .../serialization/expected_typed_ast.json | 2 +- typed/tests/serialization/json.rs | 1 - 16 files changed, 75 insertions(+), 36 deletions(-) create mode 100644 compiler/tests/definition/import_fail.leo create mode 100644 compiler/tests/definition/mod.rs create mode 100644 compiler/tests/definition/out_of_order.leo create mode 100644 compiler/tests/definition/src/test_import.leo diff --git a/ast/src/functions/function.rs b/ast/src/functions/function.rs index d40c46b9cd..5b4e815c7a 100644 --- a/ast/src/functions/function.rs +++ b/ast/src/functions/function.rs @@ -7,7 +7,7 @@ use serde::Serialize; #[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::function))] pub struct Function<'ast> { - pub function_name: Identifier<'ast>, + pub identifier: Identifier<'ast>, pub parameters: Vec>, pub returns: Vec>, pub statements: Vec>, diff --git a/ast/tests/serialization/expected_ast.json b/ast/tests/serialization/expected_ast.json index 4da98dab1f..94665d51bd 100644 --- a/ast/tests/serialization/expected_ast.json +++ b/ast/tests/serialization/expected_ast.json @@ -3,7 +3,7 @@ "definitions": [ { "Function": { - "function_name": { + "identifier": { "value": "main", "span": { "input": "main", diff --git a/ast/tests/serialization/json.rs b/ast/tests/serialization/json.rs index 488ea9de0c..f4844121e4 100644 --- a/ast/tests/serialization/json.rs +++ b/ast/tests/serialization/json.rs @@ -19,7 +19,5 @@ fn test_serialize() { // Serializes the abstract syntax tree into JSON format. let serialized_ast = LeoAst::to_json_string(&ast).unwrap(); - // println!("{:#?}", serialized_ast); - assert_eq!(expected, serialized_ast); } diff --git a/compiler/src/expression/circuit/circuit.rs b/compiler/src/expression/circuit/circuit.rs index dd39deab72..698b37617f 100644 --- a/compiler/src/expression/circuit/circuit.rs +++ b/compiler/src/expression/circuit/circuit.rs @@ -61,7 +61,7 @@ impl> ConstrainedProgram { } } CircuitMember::CircuitFunction(_static, function) => { - let identifier = function.function_name.clone(); + let identifier = function.identifier.clone(); let mut constrained_function_value = ConstrainedValue::Function(Some(circuit_identifier.clone()), function); diff --git a/compiler/src/expression/circuit/static_access.rs b/compiler/src/expression/circuit/static_access.rs index 14d8317aa5..00708ae99f 100644 --- a/compiler/src/expression/circuit/static_access.rs +++ b/compiler/src/expression/circuit/static_access.rs @@ -33,7 +33,7 @@ impl> ConstrainedProgram { // Find static circuit function let matched_function = circuit.members.into_iter().find(|member| match member { - CircuitMember::CircuitFunction(_static, function) => function.function_name == circuit_member, + CircuitMember::CircuitFunction(_static, function) => function.identifier == circuit_member, _ => false, }); @@ -44,7 +44,7 @@ impl> ConstrainedProgram { function } else { return Err(ExpressionError::invalid_member_access( - function.function_name.to_string(), + function.identifier.to_string(), span, )); } diff --git a/compiler/src/statement/assign/circuit_field.rs b/compiler/src/statement/assign/circuit_field.rs index 450bfa7816..460deaac7d 100644 --- a/compiler/src/statement/assign/circuit_field.rs +++ b/compiler/src/statement/assign/circuit_field.rs @@ -32,7 +32,7 @@ impl> ConstrainedProgram { Some(object) => match &object.1 { ConstrainedValue::Function(_circuit_identifier, function) => { return Err(StatementError::immutable_circuit_function( - function.function_name.to_string(), + function.identifier.to_string(), span, )); } diff --git a/compiler/src/value/value.rs b/compiler/src/value/value.rs index a7753ca220..6132104c1e 100644 --- a/compiler/src/value/value.rs +++ b/compiler/src/value/value.rs @@ -302,7 +302,7 @@ impl> fmt::Display for ConstrainedValue write!(f, "circuit {{ {} }}", circuit.circuit_name), ConstrainedValue::Function(ref _circuit_option, ref function) => { - write!(f, "function {{ {}() }}", function.function_name) + write!(f, "function {{ {}() }}", function.identifier) } ConstrainedValue::Import(_, ref value) => write!(f, "{}", value), ConstrainedValue::Mutable(ref value) => write!(f, "mut {}", value), diff --git a/compiler/tests/definition/import_fail.leo b/compiler/tests/definition/import_fail.leo new file mode 100644 index 0000000000..6a92f3e376 --- /dev/null +++ b/compiler/tests/definition/import_fail.leo @@ -0,0 +1,3 @@ +function main() {} + +import test_import.foo; \ No newline at end of file diff --git a/compiler/tests/definition/mod.rs b/compiler/tests/definition/mod.rs new file mode 100644 index 0000000000..e0282c491a --- /dev/null +++ b/compiler/tests/definition/mod.rs @@ -0,0 +1,19 @@ +use crate::{assert_satisfied, parse_program}; + +#[test] +fn test_out_of_order() { + let program_bytes = include_bytes!("out_of_order.leo"); + + let program = parse_program(program_bytes).unwrap(); + + assert_satisfied(program); +} + +#[test] +fn test_import_fail() { + let program_bytes = include_bytes!("import_fail.leo"); + + let syntax_error = parse_program(program_bytes).is_err(); + + assert!(syntax_error); +} diff --git a/compiler/tests/definition/out_of_order.leo b/compiler/tests/definition/out_of_order.leo new file mode 100644 index 0000000000..bbb9b5a1dc --- /dev/null +++ b/compiler/tests/definition/out_of_order.leo @@ -0,0 +1,5 @@ +test function fake_test() {} + +function main() {} + +circuit Foo {} \ No newline at end of file diff --git a/compiler/tests/definition/src/test_import.leo b/compiler/tests/definition/src/test_import.leo new file mode 100644 index 0000000000..6dd3e2c88a --- /dev/null +++ b/compiler/tests/definition/src/test_import.leo @@ -0,0 +1,8 @@ +circuit Point { + x: u32 + y: u32 +} + +function foo() -> u32 { + return 1u32 +} \ No newline at end of file diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index bfea8242e1..4f1aa524dc 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -2,6 +2,7 @@ pub mod address; pub mod array; pub mod boolean; pub mod circuits; +pub mod definition; pub mod field; pub mod function; pub mod group; diff --git a/typed/src/functions/function.rs b/typed/src/functions/function.rs index 7c8b00fd8e..8d72e3de5e 100644 --- a/typed/src/functions/function.rs +++ b/typed/src/functions/function.rs @@ -6,7 +6,7 @@ use std::fmt; #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Function { - pub function_name: Identifier, + pub identifier: Identifier, pub input: Vec, pub returns: Vec, pub statements: Vec, @@ -14,41 +14,41 @@ pub struct Function { } impl<'ast> From> for Function { - fn from(function_definition: AstFunction<'ast>) -> Self { - let function_name = Identifier::from(function_definition.function_name); - let parameters = function_definition + fn from(function: AstFunction<'ast>) -> Self { + let function_name = Identifier::from(function.identifier); + let parameters = function .parameters .into_iter() .map(|parameter| InputVariable::from(parameter)) .collect(); - let returns = function_definition + let returns = function .returns .into_iter() .map(|return_type| Type::from(return_type)) .collect(); - let statements = function_definition + let statements = function .statements .into_iter() .map(|statement| Statement::from(statement)) .collect(); Function { - function_name, + identifier: function_name, input: parameters, returns, statements, - span: Span::from(function_definition.span), + span: Span::from(function.span), } } } impl Function { pub fn get_name(&self) -> String { - self.function_name.name.clone() + self.identifier.name.clone() } fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "function {}", self.function_name)?; + write!(f, "function {}", self.identifier)?; let parameters = self .input .iter() diff --git a/typed/src/program.rs b/typed/src/program.rs index 20848aecfa..0a246f1506 100644 --- a/typed/src/program.rs +++ b/typed/src/program.rs @@ -2,7 +2,7 @@ //! Each defined type consists of typed statements and expressions. use crate::{Circuit, Function, Identifier, Import, InputVariable, TestFunction}; -use leo_ast::files::File; +use leo_ast::{definitions::Definition, files::File}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -36,20 +36,26 @@ impl<'ast> Program { let mut tests = HashMap::new(); let mut expected_input = vec![]; - program_ast.circuits.to_owned().into_iter().for_each(|circuit| { - circuits.insert(Identifier::from(circuit.identifier.clone()), Circuit::from(circuit)); - }); - program_ast.functions.to_owned().into_iter().for_each(|function_def| { - let function = Function::from(function_def); - if function.function_name.name.eq(MAIN_FUNCTION_NAME) { - expected_input = function.input.clone(); - } - functions.insert(function.function_name.clone(), function); - }); - program_ast.tests.to_owned().into_iter().for_each(|test_def| { - let test = TestFunction::from(test_def); - tests.insert(test.0.function_name.clone(), test); - }); + program_ast + .definitions + .to_owned() + .into_iter() + .for_each(|definition| match definition { + Definition::Circuit(circuit) => { + circuits.insert(Identifier::from(circuit.identifier.clone()), Circuit::from(circuit)); + } + Definition::Function(function_def) => { + let function = Function::from(function_def); + if function.identifier.name.eq(MAIN_FUNCTION_NAME) { + expected_input = function.input.clone(); + } + functions.insert(function.identifier.clone(), function); + } + Definition::TestFunction(test_def) => { + let test = TestFunction::from(test_def); + tests.insert(test.0.identifier.clone(), test); + } + }); Self { name: program_name.to_string(), diff --git a/typed/tests/serialization/expected_typed_ast.json b/typed/tests/serialization/expected_typed_ast.json index 4955096120..28428a82f1 100644 --- a/typed/tests/serialization/expected_typed_ast.json +++ b/typed/tests/serialization/expected_typed_ast.json @@ -5,7 +5,7 @@ "circuits": {}, "functions": { "{\"name\":\"main\",\"span\":\"{\\\"text\\\":\\\" function main() {\\\",\\\"line\\\":1,\\\"start\\\":10,\\\"end\\\":14}\"}": { - "function_name": "{\"name\":\"main\",\"span\":\"{\\\"text\\\":\\\" function main() {\\\",\\\"line\\\":1,\\\"start\\\":10,\\\"end\\\":14}\"}", + "identifier": "{\"name\":\"main\",\"span\":\"{\\\"text\\\":\\\" function main() {\\\",\\\"line\\\":1,\\\"start\\\":10,\\\"end\\\":14}\"}", "input": [], "returns": [], "statements": [ diff --git a/typed/tests/serialization/json.rs b/typed/tests/serialization/json.rs index 20b860623c..bd985ae308 100644 --- a/typed/tests/serialization/json.rs +++ b/typed/tests/serialization/json.rs @@ -33,7 +33,6 @@ fn test_serialize() { // Load the expected typed syntax tree. let expected = include_str!("expected_typed_ast.json"); - println!("{}", serialized_typed_ast); assert_eq!(expected, serialized_typed_ast); }