1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

remove strings from absy and replace with references to the input source

This commit is contained in:
schaeff 2019-06-04 15:42:17 +02:00
parent 5f040f484e
commit 6877f1a589
9 changed files with 201 additions and 188 deletions

View file

@ -4,7 +4,7 @@ use types::Type;
use zokrates_field::field::Field;
use zokrates_pest_ast as pest;
impl<'ast, T: Field> From<pest::File<'ast>> for absy::Prog<T> {
impl<'ast, T: Field> From<pest::File<'ast>> for absy::Prog<'ast, T> {
fn from(prog: pest::File<'ast>) -> absy::Prog<T> {
absy::Prog {
functions: prog
@ -32,7 +32,7 @@ impl<'ast> From<pest::ImportDirective<'ast>> for absy::ImportNode {
}
}
impl<'ast, T: Field> From<pest::Function<'ast>> for absy::FunctionNode<T> {
impl<'ast, T: Field> From<pest::Function<'ast>> for absy::FunctionNode<'ast, T> {
fn from(function: pest::Function<'ast>) -> absy::FunctionNode<T> {
use absy::NodeValue;
@ -57,7 +57,7 @@ impl<'ast, T: Field> From<pest::Function<'ast>> for absy::FunctionNode<T> {
);
absy::Function::<T> {
id: function.id.value,
id: function.id.span.as_str(),
arguments: function
.parameters
.into_iter()
@ -74,7 +74,7 @@ impl<'ast, T: Field> From<pest::Function<'ast>> for absy::FunctionNode<T> {
}
}
impl<'ast> From<pest::Parameter<'ast>> for absy::ParameterNode {
impl<'ast> From<pest::Parameter<'ast>> for absy::ParameterNode<'ast> {
fn from(param: pest::Parameter<'ast>) -> absy::ParameterNode {
use absy::NodeValue;
@ -87,7 +87,7 @@ impl<'ast> From<pest::Parameter<'ast>> for absy::ParameterNode {
.unwrap_or(false);
let variable =
absy::Variable::new(param.id.value, Type::from(param.ty)).span(param.id.span);
absy::Variable::new(param.id.span.as_str(), Type::from(param.ty)).span(param.id.span);
absy::Parameter::new(variable, private).span(param.span)
}
@ -118,7 +118,7 @@ fn statements_from_multi_assignment<'ast, T: Field>(
.filter(|i| i.ty.is_some())
.map(|i| {
absy::Statement::Declaration(
absy::Variable::new(i.id.clone().value, Type::from(i.ty.unwrap())).span(i.id.span),
absy::Variable::new(i.id.span.as_str(), Type::from(i.ty.unwrap())).span(i.id.span),
)
.span(i.span)
});
@ -126,7 +126,7 @@ fn statements_from_multi_assignment<'ast, T: Field>(
let lhs = assignment
.lhs
.into_iter()
.map(|i| absy::Assignee::Identifier(i.id.value).span(i.id.span))
.map(|i| absy::Assignee::Identifier(i.id.span.as_str()).span(i.id.span))
.collect();
let multi_def = absy::Statement::MultipleDefinition(
@ -153,7 +153,7 @@ fn statements_from_definition<'ast, T: Field>(
vec![
absy::Statement::Declaration(
absy::Variable::new(definition.id.clone().value, Type::from(definition.ty))
absy::Variable::new(definition.id.span.as_str(), Type::from(definition.ty))
.span(definition.id.span.clone()),
)
.span(definition.span.clone()),
@ -165,7 +165,7 @@ fn statements_from_definition<'ast, T: Field>(
]
}
impl<'ast, T: Field> From<pest::ReturnStatement<'ast>> for absy::StatementNode<T> {
impl<'ast, T: Field> From<pest::ReturnStatement<'ast>> for absy::StatementNode<'ast, T> {
fn from(statement: pest::ReturnStatement<'ast>) -> absy::StatementNode<T> {
use absy::NodeValue;
@ -183,7 +183,7 @@ impl<'ast, T: Field> From<pest::ReturnStatement<'ast>> for absy::StatementNode<T
}
}
impl<'ast, T: Field> From<pest::AssertionStatement<'ast>> for absy::StatementNode<T> {
impl<'ast, T: Field> From<pest::AssertionStatement<'ast>> for absy::StatementNode<'ast, T> {
fn from(statement: pest::AssertionStatement<'ast>) -> absy::StatementNode<T> {
use absy::NodeValue;
@ -207,12 +207,12 @@ impl<'ast, T: Field> From<pest::AssertionStatement<'ast>> for absy::StatementNod
}
}
impl<'ast, T: Field> From<pest::IterationStatement<'ast>> for absy::StatementNode<T> {
impl<'ast, T: Field> From<pest::IterationStatement<'ast>> for absy::StatementNode<'ast, T> {
fn from(statement: pest::IterationStatement<'ast>) -> absy::StatementNode<T> {
use absy::NodeValue;
let from = absy::ExpressionNode::from(statement.from);
let to = absy::ExpressionNode::from(statement.to);
let index = statement.index.value;
let index = statement.index.span.as_str();
let ty = Type::from(statement.ty);
let statements: Vec<absy::StatementNode<T>> = statement
.statements
@ -236,7 +236,7 @@ impl<'ast, T: Field> From<pest::IterationStatement<'ast>> for absy::StatementNod
}
}
impl<'ast, T: Field> From<pest::AssignmentStatement<'ast>> for absy::StatementNode<T> {
impl<'ast, T: Field> From<pest::AssignmentStatement<'ast>> for absy::StatementNode<'ast, T> {
fn from(statement: pest::AssignmentStatement<'ast>) -> absy::StatementNode<T> {
use absy::NodeValue;
@ -248,8 +248,8 @@ impl<'ast, T: Field> From<pest::AssignmentStatement<'ast>> for absy::StatementNo
}
}
impl<'ast, T: Field> From<pest::Expression<'ast>> for absy::ExpressionNode<T> {
fn from(expression: pest::Expression<'ast>) -> absy::ExpressionNode<T> {
impl<'ast, T: Field> From<pest::Expression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::Expression<'ast>) -> absy::ExpressionNode<'ast, T> {
match expression {
pest::Expression::Binary(e) => absy::ExpressionNode::from(e),
pest::Expression::Ternary(e) => absy::ExpressionNode::from(e),
@ -262,8 +262,8 @@ impl<'ast, T: Field> From<pest::Expression<'ast>> for absy::ExpressionNode<T> {
}
}
impl<'ast, T: Field> From<pest::BinaryExpression<'ast>> for absy::ExpressionNode<T> {
fn from(expression: pest::BinaryExpression<'ast>) -> absy::ExpressionNode<T> {
impl<'ast, T: Field> From<pest::BinaryExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::BinaryExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
use absy::NodeValue;
match expression.op {
pest::BinaryOperator::Add => absy::Expression::Add(
@ -320,8 +320,8 @@ impl<'ast, T: Field> From<pest::BinaryExpression<'ast>> for absy::ExpressionNode
}
}
impl<'ast, T: Field> From<pest::TernaryExpression<'ast>> for absy::ExpressionNode<T> {
fn from(expression: pest::TernaryExpression<'ast>) -> absy::ExpressionNode<T> {
impl<'ast, T: Field> From<pest::TernaryExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::TernaryExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
use absy::NodeValue;
absy::Expression::IfElse(
box absy::ExpressionNode::from(*expression.first),
@ -332,8 +332,8 @@ impl<'ast, T: Field> From<pest::TernaryExpression<'ast>> for absy::ExpressionNod
}
}
impl<'ast, T: Field> From<pest::InlineArrayExpression<'ast>> for absy::ExpressionNode<T> {
fn from(array: pest::InlineArrayExpression<'ast>) -> absy::ExpressionNode<T> {
impl<'ast, T: Field> From<pest::InlineArrayExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(array: pest::InlineArrayExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
use absy::NodeValue;
absy::Expression::InlineArray(
array
@ -346,8 +346,8 @@ impl<'ast, T: Field> From<pest::InlineArrayExpression<'ast>> for absy::Expressio
}
}
impl<'ast, T: Field> From<pest::UnaryExpression<'ast>> for absy::ExpressionNode<T> {
fn from(unary: pest::UnaryExpression<'ast>) -> absy::ExpressionNode<T> {
impl<'ast, T: Field> From<pest::UnaryExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(unary: pest::UnaryExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
use absy::NodeValue;
match unary.op {
@ -359,8 +359,8 @@ impl<'ast, T: Field> From<pest::UnaryExpression<'ast>> for absy::ExpressionNode<
}
}
impl<'ast, T: Field> From<pest::PostfixExpression<'ast>> for absy::ExpressionNode<T> {
fn from(expression: pest::PostfixExpression<'ast>) -> absy::ExpressionNode<T> {
impl<'ast, T: Field> From<pest::PostfixExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::PostfixExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
use absy::NodeValue;
assert!(expression.access.len() == 1); // we only allow a single access: function call or array access
@ -382,30 +382,30 @@ impl<'ast, T: Field> From<pest::PostfixExpression<'ast>> for absy::ExpressionNod
}
}
impl<'ast, T: Field> From<pest::ConstantExpression<'ast>> for absy::ExpressionNode<T> {
fn from(expression: pest::ConstantExpression<'ast>) -> absy::ExpressionNode<T> {
impl<'ast, T: Field> From<pest::ConstantExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::ConstantExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
use absy::NodeValue;
absy::Expression::Number(T::try_from_dec_str(&expression.value).unwrap())
.span(expression.span)
}
}
impl<'ast, T: Field> From<pest::IdentifierExpression<'ast>> for absy::ExpressionNode<T> {
fn from(expression: pest::IdentifierExpression<'ast>) -> absy::ExpressionNode<T> {
impl<'ast, T: Field> From<pest::IdentifierExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::IdentifierExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
use absy::NodeValue;
absy::Expression::Identifier(expression.value).span(expression.span)
absy::Expression::Identifier(expression.span.as_str()).span(expression.span)
}
}
impl<'ast, T: Field> From<pest::IdentifierExpression<'ast>> for absy::AssigneeNode<T> {
impl<'ast, T: Field> From<pest::IdentifierExpression<'ast>> for absy::AssigneeNode<'ast, T> {
fn from(expression: pest::IdentifierExpression<'ast>) -> absy::AssigneeNode<T> {
use absy::NodeValue;
absy::Assignee::Identifier(expression.value).span(expression.span)
absy::Assignee::Identifier(expression.span.as_str()).span(expression.span)
}
}
impl<'ast, T: Field> From<pest::Assignee<'ast>> for absy::AssigneeNode<T> {
impl<'ast, T: Field> From<pest::Assignee<'ast>> for absy::AssigneeNode<'ast, T> {
fn from(assignee: pest::Assignee<'ast>) -> absy::AssigneeNode<T> {
use absy::NodeValue;
@ -460,7 +460,7 @@ mod tests {
let ast = pest::generate_ast(&source).unwrap();
let expected: absy::Prog<FieldPrime> = absy::Prog {
functions: vec![absy::Function {
id: String::from("main"),
id: &source[4..8],
arguments: vec![],
statements: vec![absy::Statement::Return(
absy::ExpressionList {
@ -488,14 +488,11 @@ mod tests {
let expected: absy::Prog<FieldPrime> = absy::Prog {
functions: vec![absy::Function {
id: String::from("main"),
id: &source[4..8],
arguments: vec![
absy::Parameter::private(
absy::Variable::field_element(String::from("a")).into(),
)
.into(),
absy::Parameter::public(absy::Variable::boolean(String::from("b")).into())
absy::Parameter::private(absy::Variable::field_element(&source[23..24]).into())
.into(),
absy::Parameter::public(absy::Variable::boolean(&source[31..32]).into()).into(),
],
statements: vec![absy::Statement::Return(
absy::ExpressionList {

View file

@ -20,15 +20,17 @@ use crate::imports::ImportNode;
use std::fmt;
use zokrates_field::field::Field;
pub type Identifier<'ast> = &'ast str;
#[derive(Clone, PartialEq)]
pub struct Prog<T: Field> {
pub struct Prog<'ast, T: Field> {
/// Functions of the program
pub functions: Vec<FunctionNode<T>>,
pub functions: Vec<FunctionNode<'ast, T>>,
pub imports: Vec<ImportNode>,
pub imported_functions: Vec<FlatFunction<T>>,
}
impl<T: Field> fmt::Display for Prog<T> {
impl<'ast, T: Field> fmt::Display for Prog<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut res = vec![];
res.extend(
@ -53,7 +55,7 @@ impl<T: Field> fmt::Display for Prog<T> {
}
}
impl<T: Field> fmt::Debug for Prog<T> {
impl<'ast, T: Field> fmt::Debug for Prog<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
@ -78,20 +80,20 @@ impl<T: Field> fmt::Debug for Prog<T> {
}
#[derive(Clone, PartialEq)]
pub struct Function<T: Field> {
pub struct Function<'ast, T: Field> {
/// Name of the program
pub id: String,
pub id: Identifier<'ast>,
/// Arguments of the function
pub arguments: Vec<ParameterNode>,
pub arguments: Vec<ParameterNode<'ast>>,
/// Vector of statements that are executed when running the function
pub statements: Vec<StatementNode<T>>,
pub statements: Vec<StatementNode<'ast, T>>,
/// function signature
pub signature: Signature,
}
pub type FunctionNode<T> = Node<Function<T>>;
pub type FunctionNode<'ast, T> = Node<Function<'ast, T>>;
impl<T: Field> fmt::Display for Function<T> {
impl<'ast, T: Field> fmt::Display for Function<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
@ -111,7 +113,7 @@ impl<T: Field> fmt::Display for Function<T> {
}
}
impl<T: Field> fmt::Debug for Function<T> {
impl<'ast, T: Field> fmt::Debug for Function<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
@ -128,14 +130,14 @@ impl<T: Field> fmt::Debug for Function<T> {
}
#[derive(Clone, PartialEq)]
pub enum Assignee<T: Field> {
Identifier(String),
ArrayElement(Box<AssigneeNode<T>>, Box<ExpressionNode<T>>),
pub enum Assignee<'ast, T: Field> {
Identifier(Identifier<'ast>),
ArrayElement(Box<AssigneeNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
}
pub type AssigneeNode<T> = Node<Assignee<T>>;
pub type AssigneeNode<'ast, T> = Node<Assignee<'ast, T>>;
impl<T: Field> fmt::Debug for Assignee<T> {
impl<'ast, T: Field> fmt::Debug for Assignee<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Assignee::Identifier(ref s) => write!(f, "{}", s),
@ -144,48 +146,48 @@ impl<T: Field> fmt::Debug for Assignee<T> {
}
}
impl<T: Field> fmt::Display for Assignee<T> {
impl<'ast, T: Field> fmt::Display for Assignee<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl<T: Field> From<ExpressionNode<T>> for AssigneeNode<T> {
fn from(e: ExpressionNode<T>) -> Self {
match e.value {
Expression::Select(box e1, box e2) => match e1 {
ExpressionNode {
value: Expression::Identifier(id),
start,
end,
} => Node::new(
e.start,
e.end,
Assignee::ArrayElement(
box Node::new(start, end, Assignee::Identifier(id)),
box e2,
),
),
_ => panic!("only use expression to assignee for elements like foo[bar]"),
},
_ => panic!("only use expression to assignee for elements like foo[bar]"),
}
}
}
// impl<'ast, T: Field> From<ExpressionNode<'ast, T>> for AssigneeNode<T> {
// fn from(e: ExpressionNode<'ast, T>) -> Self {
// match e.value {
// Expression::Select(box e1, box e2) => match e1 {
// ExpressionNode {
// value: Expression::Identifier(id),
// start,
// end,
// } => Node::new(
// e.start,
// e.end,
// Assignee::ArrayElement(
// box Node::new(start, end, Assignee::Identifier(id)),
// box e2,
// ),
// ),
// _ => panic!("only use expression to assignee for elements like foo[bar]"),
// },
// _ => panic!("only use expression to assignee for elements like foo[bar]"),
// }
// }
// }
#[derive(Clone, PartialEq)]
pub enum Statement<T: Field> {
Return(ExpressionListNode<T>),
Declaration(VariableNode),
Definition(AssigneeNode<T>, ExpressionNode<T>),
Condition(ExpressionNode<T>, ExpressionNode<T>),
For(VariableNode, T, T, Vec<StatementNode<T>>),
MultipleDefinition(Vec<AssigneeNode<T>>, ExpressionNode<T>),
pub enum Statement<'ast, T: Field> {
Return(ExpressionListNode<'ast, T>),
Declaration(VariableNode<'ast>),
Definition(AssigneeNode<'ast, T>, ExpressionNode<'ast, T>),
Condition(ExpressionNode<'ast, T>, ExpressionNode<'ast, T>),
For(VariableNode<'ast>, T, T, Vec<StatementNode<'ast, T>>),
MultipleDefinition(Vec<AssigneeNode<'ast, T>>, ExpressionNode<'ast, T>),
}
pub type StatementNode<T> = Node<Statement<T>>;
pub type StatementNode<'ast, T> = Node<Statement<'ast, T>>;
impl<T: Field> fmt::Display for Statement<T> {
impl<'ast, T: Field> fmt::Display for Statement<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Statement::Return(ref expr) => write!(f, "return {}", expr),
@ -212,7 +214,7 @@ impl<T: Field> fmt::Display for Statement<T> {
}
}
impl<T: Field> fmt::Debug for Statement<T> {
impl<'ast, T: Field> fmt::Debug for Statement<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Statement::Return(ref expr) => write!(f, "Return({:?})", expr),
@ -235,36 +237,36 @@ impl<T: Field> fmt::Debug for Statement<T> {
}
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub enum Expression<T: Field> {
#[derive(Clone, PartialEq)]
pub enum Expression<'ast, T: Field> {
Number(T),
Identifier(String),
Add(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Sub(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Mult(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Div(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Pow(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Identifier(Identifier<'ast>),
Add(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Sub(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Mult(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Div(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Pow(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
IfElse(
Box<ExpressionNode<T>>,
Box<ExpressionNode<T>>,
Box<ExpressionNode<T>>,
Box<ExpressionNode<'ast, T>>,
Box<ExpressionNode<'ast, T>>,
Box<ExpressionNode<'ast, T>>,
),
FunctionCall(String, Vec<ExpressionNode<T>>),
Lt(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Le(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Eq(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Ge(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Gt(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
And(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Not(Box<ExpressionNode<T>>),
InlineArray(Vec<ExpressionNode<T>>),
Select(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
Or(Box<ExpressionNode<T>>, Box<ExpressionNode<T>>),
FunctionCall(String, Vec<ExpressionNode<'ast, T>>),
Lt(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Le(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Eq(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Ge(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Gt(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
And(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Not(Box<ExpressionNode<'ast, T>>),
InlineArray(Vec<ExpressionNode<'ast, T>>),
Select(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Or(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
}
pub type ExpressionNode<T> = Node<Expression<T>>;
pub type ExpressionNode<'ast, T> = Node<Expression<'ast, T>>;
impl<T: Field> fmt::Display for Expression<T> {
impl<'ast, T: Field> fmt::Display for Expression<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expression::Number(ref i) => write!(f, "{}", i),
@ -312,7 +314,7 @@ impl<T: Field> fmt::Display for Expression<T> {
}
}
impl<T: Field> fmt::Debug for Expression<T> {
impl<'ast, T: Field> fmt::Debug for Expression<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expression::Number(ref i) => write!(f, "Num({})", i),
@ -350,22 +352,22 @@ impl<T: Field> fmt::Debug for Expression<T> {
}
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct ExpressionList<T: Field> {
pub expressions: Vec<ExpressionNode<T>>,
#[derive(Clone, PartialEq)]
pub struct ExpressionList<'ast, T: Field> {
pub expressions: Vec<ExpressionNode<'ast, T>>,
}
pub type ExpressionListNode<T> = Node<ExpressionList<T>>;
pub type ExpressionListNode<'ast, T> = Node<ExpressionList<'ast, T>>;
impl<T: Field> ExpressionList<T> {
pub fn new() -> ExpressionList<T> {
impl<'ast, T: Field> ExpressionList<'ast, T> {
pub fn new() -> ExpressionList<'ast, T> {
ExpressionList {
expressions: vec![],
}
}
}
impl<T: Field> fmt::Display for ExpressionList<T> {
impl<'ast, T: Field> fmt::Display for ExpressionList<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (i, param) in self.expressions.iter().enumerate() {
r#try!(write!(f, "{}", param));
@ -377,7 +379,7 @@ impl<T: Field> fmt::Display for ExpressionList<T> {
}
}
impl<T: Field> fmt::Debug for ExpressionList<T> {
impl<'ast, T: Field> fmt::Debug for ExpressionList<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ExpressionList({:?})", self.expressions)
}

View file

@ -62,14 +62,14 @@ use crate::absy::*;
use crate::imports::*;
use zokrates_field::field::Field;
impl<T: Field> NodeValue for Expression<T> {}
impl<T: Field> NodeValue for ExpressionList<T> {}
impl<T: Field> NodeValue for Assignee<T> {}
impl<T: Field> NodeValue for Statement<T> {}
impl<T: Field> NodeValue for Function<T> {}
impl<T: Field> NodeValue for Prog<T> {}
impl NodeValue for Variable {}
impl NodeValue for Parameter {}
impl<'ast, T: Field> NodeValue for Expression<'ast, T> {}
impl<'ast, T: Field> NodeValue for ExpressionList<'ast, T> {}
impl<'ast, T: Field> NodeValue for Assignee<'ast, T> {}
impl<'ast, T: Field> NodeValue for Statement<'ast, T> {}
impl<'ast, T: Field> NodeValue for Function<'ast, T> {}
impl<'ast, T: Field> NodeValue for Prog<'ast, T> {}
impl<'ast> NodeValue for Variable<'ast> {}
impl<'ast> NodeValue for Parameter<'ast> {}
impl NodeValue for Import {}
impl<T: NodeValue> std::cmp::PartialEq for Node<T> {

View file

@ -1,25 +1,25 @@
use crate::absy::{Node, VariableNode};
use std::fmt;
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct Parameter {
pub id: VariableNode,
#[derive(Clone, PartialEq)]
pub struct Parameter<'ast> {
pub id: VariableNode<'ast>,
pub private: bool,
}
impl Parameter {
pub fn new(v: VariableNode, private: bool) -> Self {
impl<'ast> Parameter<'ast> {
pub fn new(v: VariableNode<'ast>, private: bool) -> Self {
Parameter { id: v, private }
}
pub fn public(v: VariableNode) -> Self {
pub fn public(v: VariableNode<'ast>) -> Self {
Parameter {
id: v,
private: false,
}
}
pub fn private(v: VariableNode) -> Self {
pub fn private(v: VariableNode<'ast>) -> Self {
Parameter {
id: v,
private: true,
@ -27,9 +27,9 @@ impl Parameter {
}
}
pub type ParameterNode = Node<Parameter>;
pub type ParameterNode<'ast> = Node<Parameter<'ast>>;
impl fmt::Display for Parameter {
impl<'ast> fmt::Display for Parameter<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let visibility = if self.private { "private " } else { "" };
write!(
@ -42,7 +42,7 @@ impl fmt::Display for Parameter {
}
}
impl fmt::Debug for Parameter {
impl<'ast> fmt::Debug for Parameter<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,

View file

@ -2,37 +2,39 @@ use crate::absy::Node;
use crate::types::Type;
use std::fmt;
#[derive(Serialize, Deserialize, Clone, PartialEq, Hash, Eq)]
pub struct Variable {
pub id: String,
use crate::absy::Identifier;
#[derive(Clone, PartialEq, Hash, Eq)]
pub struct Variable<'ast> {
pub id: Identifier<'ast>,
pub _type: Type,
}
pub type VariableNode = Node<Variable>;
pub type VariableNode<'ast> = Node<Variable<'ast>>;
impl Variable {
pub fn new<S: Into<String>>(id: S, t: Type) -> Variable {
impl<'ast> Variable<'ast> {
pub fn new<S: Into<&'ast str>>(id: S, t: Type) -> Variable<'ast> {
Variable {
id: id.into(),
_type: t,
}
}
pub fn field_element<S: Into<String>>(id: S) -> Variable {
pub fn field_element<S: Into<&'ast str>>(id: S) -> Variable<'ast> {
Variable {
id: id.into(),
_type: Type::FieldElement,
}
}
pub fn boolean<S: Into<String>>(id: S) -> Variable {
pub fn boolean<S: Into<&'ast str>>(id: S) -> Variable<'ast> {
Variable {
id: id.into(),
_type: Type::Boolean,
}
}
pub fn field_array<S: Into<String>>(id: S, size: usize) -> Variable {
pub fn field_array<S: Into<&'ast str>>(id: S, size: usize) -> Variable<'ast> {
Variable {
id: id.into(),
_type: Type::FieldElementArray(size),
@ -44,13 +46,13 @@ impl Variable {
}
}
impl fmt::Display for Variable {
impl<'ast> fmt::Display for Variable<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self._type, self.id,)
}
}
impl fmt::Debug for Variable {
impl<'ast> fmt::Debug for Variable<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Variable(type: {:?}, id: {:?})", self._type, self.id,)
}

View file

@ -132,12 +132,17 @@ impl Importer {
Importer {}
}
pub fn apply_imports<T: Field, S: BufRead, E: Into<Error>>(
// Inject dependencies declared for `destination`
// The lifetime of the Program before injection outlives the lifetime after
pub fn apply_imports<'before, 'after, T: Field, S: BufRead, E: Into<Error>>(
&self,
destination: Prog<T>,
destination: Prog<'before, T>,
location: Option<String>,
resolve_option: Option<fn(&Option<String>, &String) -> Result<(S, String, String), E>>,
) -> Result<Prog<T>, CompileErrors> {
) -> Result<Prog<'after, T>, CompileErrors>
where
'before: 'after,
{
let mut origins: Vec<CompiledImport<T>> = vec![];
for import in destination.imports.iter() {

View file

@ -10,6 +10,7 @@ use crate::absy::variable::Variable;
use crate::absy::*;
use crate::typed_absy::*;
use crate::types::Signature;
use absy::Identifier;
use std::collections::HashSet;
use std::fmt;
use zokrates_field::field::Field;
@ -36,13 +37,13 @@ impl fmt::Display for Error {
}
}
pub struct FunctionQuery {
id: String,
pub struct FunctionQuery<'ast> {
id: Identifier<'ast>,
inputs: Vec<Type>,
outputs: Vec<Option<Type>>,
}
impl fmt::Display for FunctionQuery {
impl<'ast> fmt::Display for FunctionQuery<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
r#try!(write!(f, "("));
for (i, t) in self.inputs.iter().enumerate() {
@ -65,8 +66,12 @@ impl fmt::Display for FunctionQuery {
}
}
impl FunctionQuery {
fn new(id: String, inputs: &Vec<Type>, outputs: &Vec<Option<Type>>) -> FunctionQuery {
impl<'ast> FunctionQuery<'ast> {
fn new(
id: Identifier<'ast>,
inputs: &Vec<Type>,
outputs: &Vec<Option<Type>>,
) -> FunctionQuery<'ast> {
FunctionQuery {
id,
inputs: inputs.clone(),
@ -95,23 +100,23 @@ impl FunctionQuery {
#[derive(Clone, Debug)]
pub struct ScopedVariable {
id: Variable,
pub struct ScopedVariable<'ast> {
id: Variable<'ast>,
level: usize,
}
impl Hash for ScopedVariable {
impl<'ast> Hash for ScopedVariable<'ast> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.id.hash(state);
}
}
impl PartialEq for ScopedVariable {
impl<'ast> PartialEq for ScopedVariable<'ast> {
fn eq(&self, other: &ScopedVariable) -> bool {
self.id.id == other.id.id
}
}
impl Eq for ScopedVariable {}
impl<'ast> Eq for ScopedVariable<'ast> {}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct FunctionDeclaration {
@ -120,14 +125,14 @@ pub struct FunctionDeclaration {
}
// Checker, checks the semantics of a program.
pub struct Checker {
scope: HashSet<ScopedVariable>,
pub struct Checker<'ast> {
scope: HashSet<ScopedVariable<'ast>>,
functions: HashSet<FunctionDeclaration>,
level: usize,
}
impl Checker {
pub fn new() -> Checker {
impl<'ast> Checker<'ast> {
pub fn new() -> Checker<'ast> {
Checker {
scope: HashSet::new(),
functions: HashSet::new(),
@ -135,10 +140,13 @@ impl Checker {
}
}
pub fn check_program<T: Field>(&mut self, prog: Prog<T>) -> Result<TypedProg<T>, Vec<Error>> {
pub fn check_program<T: 'ast + Field>(
&mut self,
prog: Prog<'ast, T>,
) -> Result<TypedProg<T>, Vec<Error>> {
for func in &prog.imported_functions {
self.functions.insert(FunctionDeclaration {
id: func.id.clone(),
id: func.id.to_string(),
signature: func.signature.clone(),
});
}
@ -150,7 +158,7 @@ impl Checker {
self.enter_scope();
let dec = FunctionDeclaration {
id: func.value.id.clone(),
id: func.value.id.to_string(),
signature: func.value.signature.clone(),
};
@ -208,7 +216,7 @@ impl Checker {
fn check_function<T: Field>(
&mut self,
funct_node: FunctionNode<T>,
funct_node: FunctionNode<'ast, T>,
) -> Result<TypedFunction<T>, Vec<Error>> {
let mut errors = vec![];
let pos = funct_node.pos();
@ -266,7 +274,7 @@ impl Checker {
}
Ok(TypedFunction {
id: funct.id.clone(),
id: funct.id.to_string(),
arguments: funct
.arguments
.iter()
@ -279,7 +287,7 @@ impl Checker {
fn check_statement<T: Field>(
&mut self,
stat: &StatementNode<T>,
stat: &StatementNode<'ast, T>,
header_return_types: &Vec<Type>,
) -> Result<TypedStatement<T>, Error> {
match stat.value {
@ -425,8 +433,7 @@ impl Checker {
let arguments_types =
arguments_checked.iter().map(|a| a.get_type()).collect();
let query =
FunctionQuery::new(fun_id.to_string(), &arguments_types, &vars_types);
let query = FunctionQuery::new(&fun_id, &arguments_types, &vars_types);
let candidates = self.find_candidates(&query).clone();
match candidates.len() {
@ -435,7 +442,7 @@ impl Checker {
let f = &candidates[0];
let lhs = var_names.iter().enumerate().map(|(index, name)|
Variable::new(name.to_string(), f.signature.outputs[index].clone())
Variable::new(**name, f.signature.outputs[index].clone())
);
// we can infer the left hand side to be typed as the return values
@ -443,7 +450,7 @@ impl Checker {
self.insert_scope(var);
}
Ok(TypedStatement::MultipleDefinition(lhs.map(|v| v.into()).collect(), TypedExpressionList::FunctionCall(f.id.clone(), arguments_checked, f.signature.outputs.clone())))
Ok(TypedStatement::MultipleDefinition(lhs.map(|v| v.into()).collect(), TypedExpressionList::FunctionCall(f.id.to_string(), arguments_checked, f.signature.outputs.clone())))
},
0 => Err(Error { pos: Some(stat.pos()),
message: format!("Function definition for function {} with signature {} not found.", fun_id, query) }),
@ -667,7 +674,7 @@ impl Checker {
// outside of multidef, function calls must have a single return value
// we use type inference to determine the type of the return, so we don't specify it
let query = FunctionQuery::new(fun_id.to_string(), &arguments_types, &vec![None]);
let query = FunctionQuery::new(&fun_id, &arguments_types, &vec![None]);
let candidates = self.find_candidates(&query);
@ -679,14 +686,14 @@ impl Checker {
match f.signature.outputs.len() {
1 => match f.signature.outputs[0] {
Type::FieldElement => Ok(FieldElementExpression::FunctionCall(
f.id.clone(),
f.id.to_string(),
arguments_checked,
)
.into()),
Type::FieldElementArray(size) => {
Ok(FieldElementArrayExpression::FunctionCall(
size,
f.id.clone(),
f.id.to_string(),
arguments_checked,
)
.into())
@ -921,21 +928,21 @@ impl Checker {
}
}
fn get_scope(&self, variable_name: &String) -> Option<&ScopedVariable> {
fn get_scope(&self, variable_name: &'ast str) -> Option<&ScopedVariable> {
self.scope.get(&ScopedVariable {
id: Variable::new(variable_name.clone(), Type::FieldElement),
level: 0,
})
}
fn insert_scope(&mut self, v: Variable) -> bool {
fn insert_scope(&mut self, v: Variable<'ast>) -> bool {
self.scope.insert(ScopedVariable {
id: v,
level: self.level,
})
}
fn find_candidates(&self, query: &FunctionQuery) -> Vec<FunctionDeclaration> {
fn find_candidates(&self, query: &FunctionQuery<'ast>) -> Vec<FunctionDeclaration> {
query.match_funcs(&self.functions)
}

View file

@ -31,8 +31,8 @@ impl fmt::Debug for Parameter {
}
}
impl From<absy::Parameter> for Parameter {
fn from(p: absy::Parameter) -> Parameter {
impl<'ast> From<absy::Parameter<'ast>> for Parameter {
fn from(p: absy::Parameter<'ast>) -> Parameter {
Parameter {
private: p.private,
id: p.id.value.into(),

View file

@ -47,10 +47,10 @@ impl fmt::Debug for Variable {
}
}
impl From<absy::Variable> for Variable {
impl<'ast> From<absy::Variable<'ast>> for Variable {
fn from(v: absy::Variable) -> Variable {
Variable {
id: v.id,
id: v.id.to_string(),
_type: v._type,
}
}