add definition parsing to typed. add tests

This commit is contained in:
collin 2020-08-05 22:45:52 -07:00
parent 4550573213
commit 3d1edefedb
16 changed files with 75 additions and 36 deletions

View File

@ -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<Input<'ast>>,
pub returns: Vec<Type<'ast>>,
pub statements: Vec<Statement<'ast>>,

View File

@ -3,7 +3,7 @@
"definitions": [
{
"Function": {
"function_name": {
"identifier": {
"value": "main",
"span": {
"input": "main",

View File

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

View File

@ -61,7 +61,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
}
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);

View File

@ -33,7 +33,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// 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<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
function
} else {
return Err(ExpressionError::invalid_member_access(
function.function_name.to_string(),
function.identifier.to_string(),
span,
));
}

View File

@ -32,7 +32,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
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,
));
}

View File

@ -302,7 +302,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F
}
ConstrainedValue::CircuitDefinition(ref circuit) => 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),

View File

@ -0,0 +1,3 @@
function main() {}
import test_import.foo;

View File

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

View File

@ -0,0 +1,5 @@
test function fake_test() {}
function main() {}
circuit Foo {}

View File

@ -0,0 +1,8 @@
circuit Point {
x: u32
y: u32
}
function foo() -> u32 {
return 1u32
}

View File

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

View File

@ -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<InputVariable>,
pub returns: Vec<Type>,
pub statements: Vec<Statement>,
@ -14,41 +14,41 @@ pub struct Function {
}
impl<'ast> From<AstFunction<'ast>> 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()

View File

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

View File

@ -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": [

View File

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