mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 10:41:57 +03:00
add and constrain explict type for u32
This commit is contained in:
parent
dbbf816645
commit
1bbe71d726
@ -1,4 +1,5 @@
|
||||
from "./simple_import" import foo
|
||||
from "./simple_import" import Point
|
||||
|
||||
def main() -> (field):
|
||||
return foo()
|
||||
def main() -> (Point):
|
||||
Point p = Point { x: 1u32, y: 2u32}
|
||||
return p
|
@ -1,3 +1,4 @@
|
||||
def foo() -> (field):
|
||||
// return myGlobal <- not allowed
|
||||
return 42
|
||||
struct Point {
|
||||
u32 x
|
||||
u32 y
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,146 +1,192 @@
|
||||
//! A zokrates_program consists of nodes that keep track of position and wrap zokrates_program types.
|
||||
//! A typed program in aleo consists of import, struct, and function definitions.
|
||||
//! Each defined type consists of typed statements and expressions.
|
||||
//!
|
||||
//! @file types.rs
|
||||
//! @author Collin Chin <collin@aleo.org>
|
||||
//! @date 2020
|
||||
|
||||
use crate::aleo_program::Import;
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
/// A variable in a constraint system.
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Variable(pub String);
|
||||
|
||||
/// Spread operator
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FieldSpread(pub FieldExpression);
|
||||
|
||||
/// Spread or field expression enum
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FieldSpreadOrExpression {
|
||||
Spread(FieldSpread),
|
||||
FieldExpression(FieldExpression),
|
||||
pub struct Variable<F: Field + PrimeField> {
|
||||
pub name: String,
|
||||
pub(crate) _field: PhantomData<F>,
|
||||
}
|
||||
|
||||
/// Range or field expression enum
|
||||
/// An integer type enum wrapping the integer value
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FieldRangeOrExpression {
|
||||
Range(Option<FieldExpression>, Option<FieldExpression>),
|
||||
FieldExpression(FieldExpression),
|
||||
pub enum Integer {
|
||||
// U8(u8),
|
||||
U32(u32),
|
||||
// U64(u64),
|
||||
}
|
||||
|
||||
/// Spread operator or u32 expression enum
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum IntegerSpreadOrExpression<F: Field + PrimeField> {
|
||||
Spread(IntegerExpression<F>),
|
||||
Expression(IntegerExpression<F>),
|
||||
}
|
||||
|
||||
/// Range or integer expression enum
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum IntegerRangeOrExpression<F: Field + PrimeField> {
|
||||
Range(Option<IntegerExpression<F>>, Option<IntegerExpression<F>>),
|
||||
Expression(IntegerExpression<F>),
|
||||
}
|
||||
|
||||
/// Expression that evaluates to a u32 value
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum IntegerExpression<F: Field + PrimeField> {
|
||||
Variable(Variable<F>),
|
||||
Number(Integer),
|
||||
// Operators
|
||||
Add(Box<IntegerExpression<F>>, Box<IntegerExpression<F>>),
|
||||
Sub(Box<IntegerExpression<F>>, Box<IntegerExpression<F>>),
|
||||
Mul(Box<IntegerExpression<F>>, Box<IntegerExpression<F>>),
|
||||
Div(Box<IntegerExpression<F>>, Box<IntegerExpression<F>>),
|
||||
Pow(Box<IntegerExpression<F>>, Box<IntegerExpression<F>>),
|
||||
// Conditionals
|
||||
IfElse(
|
||||
Box<BooleanExpression<F>>,
|
||||
Box<IntegerExpression<F>>,
|
||||
Box<IntegerExpression<F>>,
|
||||
),
|
||||
// Arrays
|
||||
Array(Vec<Box<IntegerSpreadOrExpression<F>>>),
|
||||
}
|
||||
|
||||
// /// Spread or field expression enum
|
||||
// #[derive(Debug, Clone)]
|
||||
// pub enum FieldSpreadOrExpression<F: Field + PrimeField> {
|
||||
// Spread(FieldExpression<F>),
|
||||
// Expression(FieldExpression<F>),
|
||||
// }
|
||||
|
||||
/// Expression that evaluates to a field value
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FieldExpression {
|
||||
Variable(Variable),
|
||||
Number(u32),
|
||||
// Operators
|
||||
Add(Box<FieldExpression>, Box<FieldExpression>),
|
||||
Sub(Box<FieldExpression>, Box<FieldExpression>),
|
||||
Mul(Box<FieldExpression>, Box<FieldExpression>),
|
||||
Div(Box<FieldExpression>, Box<FieldExpression>),
|
||||
Pow(Box<FieldExpression>, Box<FieldExpression>),
|
||||
// Conditionals
|
||||
IfElse(
|
||||
Box<BooleanExpression>,
|
||||
Box<FieldExpression>,
|
||||
Box<FieldExpression>,
|
||||
),
|
||||
// Arrays
|
||||
Array(Vec<Box<FieldSpreadOrExpression>>),
|
||||
pub enum FieldExpression<F: Field + PrimeField> {
|
||||
Variable(Variable<F>),
|
||||
Number(F),
|
||||
// // Operators
|
||||
// Add(Box<FieldExpression<F>>, Box<FieldExpression<F>>),
|
||||
// Sub(Box<FieldExpression<F>>, Box<FieldExpression<F>>),
|
||||
// Mul(Box<FieldExpression<F>>, Box<FieldExpression<F>>),
|
||||
// Div(Box<FieldExpression<F>>, Box<FieldExpression<F>>),
|
||||
// Pow(Box<FieldExpression<F>>, Box<FieldExpression<F>>),
|
||||
// // Conditionals
|
||||
// IfElse(
|
||||
// Box<BooleanExpression>,
|
||||
// Box<FieldExpression<F>>,
|
||||
// Box<FieldExpression<F>>,
|
||||
// ),
|
||||
// // Arrays
|
||||
// Array(Vec<Box<FieldSpreadOrExpression<F>>>),
|
||||
}
|
||||
|
||||
/// Spread operator
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BooleanSpread(pub BooleanExpression);
|
||||
|
||||
/// Spread or field expression enum
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum BooleanSpreadOrExpression {
|
||||
Spread(BooleanSpread),
|
||||
BooleanExpression(BooleanExpression),
|
||||
pub enum BooleanSpreadOrExpression<F: Field + PrimeField> {
|
||||
Spread(BooleanExpression<F>),
|
||||
Expression(BooleanExpression<F>),
|
||||
}
|
||||
|
||||
/// Expression that evaluates to a boolean value
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum BooleanExpression {
|
||||
Variable(Variable),
|
||||
pub enum BooleanExpression<F: Field + PrimeField> {
|
||||
Variable(Variable<F>),
|
||||
Value(bool),
|
||||
// Boolean operators
|
||||
Not(Box<BooleanExpression>),
|
||||
Or(Box<BooleanExpression>, Box<BooleanExpression>),
|
||||
And(Box<BooleanExpression>, Box<BooleanExpression>),
|
||||
BoolEq(Box<BooleanExpression>, Box<BooleanExpression>),
|
||||
Not(Box<BooleanExpression<F>>),
|
||||
Or(Box<BooleanExpression<F>>, Box<BooleanExpression<F>>),
|
||||
And(Box<BooleanExpression<F>>, Box<BooleanExpression<F>>),
|
||||
BoolEq(Box<BooleanExpression<F>>, Box<BooleanExpression<F>>),
|
||||
// Field operators
|
||||
FieldEq(Box<FieldExpression>, Box<FieldExpression>),
|
||||
Geq(Box<FieldExpression>, Box<FieldExpression>),
|
||||
Gt(Box<FieldExpression>, Box<FieldExpression>),
|
||||
Leq(Box<FieldExpression>, Box<FieldExpression>),
|
||||
Lt(Box<FieldExpression>, Box<FieldExpression>),
|
||||
FieldEq(Box<IntegerExpression<F>>, Box<IntegerExpression<F>>),
|
||||
Geq(Box<IntegerExpression<F>>, Box<IntegerExpression<F>>),
|
||||
Gt(Box<IntegerExpression<F>>, Box<IntegerExpression<F>>),
|
||||
Leq(Box<IntegerExpression<F>>, Box<IntegerExpression<F>>),
|
||||
Lt(Box<IntegerExpression<F>>, Box<IntegerExpression<F>>),
|
||||
// Conditionals
|
||||
IfElse(
|
||||
Box<BooleanExpression>,
|
||||
Box<BooleanExpression>,
|
||||
Box<BooleanExpression>,
|
||||
Box<BooleanExpression<F>>,
|
||||
Box<BooleanExpression<F>>,
|
||||
Box<BooleanExpression<F>>,
|
||||
),
|
||||
// Arrays
|
||||
Array(Vec<Box<BooleanSpreadOrExpression>>),
|
||||
Array(Vec<Box<BooleanSpreadOrExpression<F>>>),
|
||||
}
|
||||
|
||||
/// Expression that evaluates to a value
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Expression {
|
||||
Boolean(BooleanExpression),
|
||||
FieldElement(FieldExpression),
|
||||
Variable(Variable),
|
||||
Struct(Variable, Vec<StructMember>),
|
||||
ArrayAccess(Box<Expression>, FieldRangeOrExpression),
|
||||
StructMemberAccess(Box<Expression>, Variable), // (struct name, struct member name)
|
||||
FunctionCall(Box<Expression>, Vec<Expression>),
|
||||
pub enum Expression<F: Field + PrimeField> {
|
||||
Integer(IntegerExpression<F>),
|
||||
FieldElement(FieldExpression<F>),
|
||||
Boolean(BooleanExpression<F>),
|
||||
Variable(Variable<F>),
|
||||
Struct(Variable<F>, Vec<StructMember<F>>),
|
||||
ArrayAccess(Box<Expression<F>>, IntegerRangeOrExpression<F>),
|
||||
StructMemberAccess(Box<Expression<F>>, Variable<F>), // (struct name, struct member name)
|
||||
FunctionCall(Box<Expression<F>>, Vec<Expression<F>>),
|
||||
}
|
||||
|
||||
/// Definition assignee: v, arr[0..2], Point p.x
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Assignee {
|
||||
Variable(Variable),
|
||||
Array(Box<Assignee>, FieldRangeOrExpression),
|
||||
StructMember(Box<Assignee>, Variable),
|
||||
pub enum Assignee<F: Field + PrimeField> {
|
||||
Variable(Variable<F>),
|
||||
Array(Box<Assignee<F>>, IntegerRangeOrExpression<F>),
|
||||
StructMember(Box<Assignee<F>>, Variable<F>),
|
||||
}
|
||||
|
||||
/// Program statement that defines some action (or expression) to be carried out.
|
||||
#[derive(Clone)]
|
||||
pub enum Statement {
|
||||
pub enum Statement<F: Field + PrimeField> {
|
||||
// Declaration(Variable),
|
||||
Definition(Assignee, Expression),
|
||||
For(Variable, FieldExpression, FieldExpression, Vec<Statement>),
|
||||
Return(Vec<Expression>),
|
||||
Definition(Assignee<F>, Expression<F>),
|
||||
For(
|
||||
Variable<F>,
|
||||
IntegerExpression<F>,
|
||||
IntegerExpression<F>,
|
||||
Vec<Statement<F>>,
|
||||
),
|
||||
Return(Vec<Expression<F>>),
|
||||
}
|
||||
|
||||
/// Explicit type used for defining struct members and function parameters
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Type {
|
||||
Boolean,
|
||||
pub enum Type<F: Field + PrimeField> {
|
||||
U32,
|
||||
FieldElement,
|
||||
Array(Box<Type>, usize),
|
||||
Struct(Variable),
|
||||
Boolean,
|
||||
Array(Box<Type<F>>, usize),
|
||||
Struct(Variable<F>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct StructMember {
|
||||
pub variable: Variable,
|
||||
pub expression: Expression,
|
||||
pub struct StructMember<F: Field + PrimeField> {
|
||||
pub variable: Variable<F>,
|
||||
pub expression: Expression<F>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct StructField {
|
||||
pub variable: Variable,
|
||||
pub ty: Type,
|
||||
pub struct StructField<F: Field + PrimeField> {
|
||||
pub variable: Variable<F>,
|
||||
pub ty: Type<F>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Struct {
|
||||
pub variable: Variable,
|
||||
pub fields: Vec<StructField>,
|
||||
pub struct Struct<F: Field + PrimeField> {
|
||||
pub variable: Variable<F>,
|
||||
pub fields: Vec<StructField<F>>,
|
||||
}
|
||||
|
||||
/// Function parameters
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Visibility {
|
||||
Public,
|
||||
@ -148,10 +194,10 @@ pub enum Visibility {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Parameter {
|
||||
pub struct Parameter<F: Field + PrimeField> {
|
||||
pub visibility: Option<Visibility>,
|
||||
pub ty: Type,
|
||||
pub variable: Variable,
|
||||
pub ty: Type<F>,
|
||||
pub variable: Variable<F>,
|
||||
}
|
||||
|
||||
/// The given name for a defined function in the program.
|
||||
@ -159,14 +205,14 @@ pub struct Parameter {
|
||||
pub struct FunctionName(pub String);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Function {
|
||||
pub struct Function<F: Field + PrimeField> {
|
||||
pub function_name: FunctionName,
|
||||
pub parameters: Vec<Parameter>,
|
||||
pub returns: Vec<Type>,
|
||||
pub statements: Vec<Statement>,
|
||||
pub parameters: Vec<Parameter<F>>,
|
||||
pub returns: Vec<Type<F>>,
|
||||
pub statements: Vec<Statement<F>>,
|
||||
}
|
||||
|
||||
impl Function {
|
||||
impl<F: Field + PrimeField> Function<F> {
|
||||
pub fn get_name(&self) -> String {
|
||||
self.function_name.0.clone()
|
||||
}
|
||||
@ -174,28 +220,19 @@ impl Function {
|
||||
|
||||
/// A simple program with statement expressions, program arguments and program returns.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Program<'ast> {
|
||||
pub name: Variable,
|
||||
pub struct Program<'ast, F: Field + PrimeField> {
|
||||
pub name: Variable<F>,
|
||||
pub imports: Vec<Import<'ast>>,
|
||||
pub structs: HashMap<Variable, Struct>,
|
||||
pub functions: HashMap<FunctionName, Function>,
|
||||
pub structs: HashMap<Variable<F>, Struct<F>>,
|
||||
pub functions: HashMap<FunctionName, Function<F>>,
|
||||
}
|
||||
|
||||
impl<'ast> Program<'ast> {
|
||||
impl<'ast, F: Field + PrimeField> Program<'ast, F> {
|
||||
pub fn name(mut self, name: String) -> Self {
|
||||
self.name = Variable(name);
|
||||
self.name = Variable {
|
||||
name,
|
||||
_field: PhantomData::<F>,
|
||||
};
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_variable() {
|
||||
let variable = Variable("1".into());
|
||||
|
||||
println!("{:#?}", variable);
|
||||
}
|
||||
}
|
||||
|
@ -5,53 +5,56 @@
|
||||
//! @date 2020
|
||||
|
||||
use crate::aleo_program::{
|
||||
Assignee, BooleanExpression, BooleanSpread, BooleanSpreadOrExpression, Expression,
|
||||
FieldExpression, FieldRangeOrExpression, FieldSpread, FieldSpreadOrExpression, Function,
|
||||
FunctionName, Parameter, Statement, Struct, StructField, Type, Variable,
|
||||
Assignee, BooleanExpression, BooleanSpreadOrExpression, Expression, Function, FunctionName,
|
||||
Integer, IntegerExpression, IntegerRangeOrExpression, IntegerSpreadOrExpression, Parameter,
|
||||
Statement, Struct, StructField, Type, Variable,
|
||||
};
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use std::fmt;
|
||||
|
||||
impl fmt::Display for Variable {
|
||||
impl<F: Field + PrimeField> fmt::Display for Variable<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
impl fmt::Debug for Variable {
|
||||
impl<F: Field + PrimeField> fmt::Debug for Variable<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FieldSpread {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "...{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FieldSpreadOrExpression {
|
||||
impl fmt::Display for Integer {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
FieldSpreadOrExpression::Spread(ref spread) => write!(f, "{}", spread),
|
||||
FieldSpreadOrExpression::FieldExpression(ref expression) => write!(f, "{}", expression),
|
||||
Integer::U32(ref num) => write!(f, "{}", num),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for FieldExpression {
|
||||
impl<F: Field + PrimeField> fmt::Display for IntegerSpreadOrExpression<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
FieldExpression::Variable(ref variable) => write!(f, "{}", variable),
|
||||
FieldExpression::Number(ref number) => write!(f, "{}", number),
|
||||
FieldExpression::Add(ref lhs, ref rhs) => write!(f, "{} + {}", lhs, rhs),
|
||||
FieldExpression::Sub(ref lhs, ref rhs) => write!(f, "{} - {}", lhs, rhs),
|
||||
FieldExpression::Mul(ref lhs, ref rhs) => write!(f, "{} * {}", lhs, rhs),
|
||||
FieldExpression::Div(ref lhs, ref rhs) => write!(f, "{} / {}", lhs, rhs),
|
||||
FieldExpression::Pow(ref lhs, ref rhs) => write!(f, "{} ** {}", lhs, rhs),
|
||||
FieldExpression::IfElse(ref a, ref b, ref c) => {
|
||||
IntegerSpreadOrExpression::Spread(ref spread) => write!(f, "...{}", spread),
|
||||
IntegerSpreadOrExpression::Expression(ref expression) => write!(f, "{}", expression),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> fmt::Display for IntegerExpression<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
IntegerExpression::Variable(ref variable) => write!(f, "{}", variable),
|
||||
IntegerExpression::Number(ref number) => write!(f, "{}", number),
|
||||
IntegerExpression::Add(ref lhs, ref rhs) => write!(f, "{} + {}", lhs, rhs),
|
||||
IntegerExpression::Sub(ref lhs, ref rhs) => write!(f, "{} - {}", lhs, rhs),
|
||||
IntegerExpression::Mul(ref lhs, ref rhs) => write!(f, "{} * {}", lhs, rhs),
|
||||
IntegerExpression::Div(ref lhs, ref rhs) => write!(f, "{} / {}", lhs, rhs),
|
||||
IntegerExpression::Pow(ref lhs, ref rhs) => write!(f, "{} ** {}", lhs, rhs),
|
||||
IntegerExpression::IfElse(ref a, ref b, ref c) => {
|
||||
write!(f, "if {} then {} else {} fi", a, b, c)
|
||||
}
|
||||
FieldExpression::Array(ref array) => {
|
||||
IntegerExpression::Array(ref array) => {
|
||||
write!(f, "[")?;
|
||||
for (i, e) in array.iter().enumerate() {
|
||||
write!(f, "{}", e)?;
|
||||
@ -65,24 +68,16 @@ impl<'ast> fmt::Display for FieldExpression {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BooleanSpread {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "...{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BooleanSpreadOrExpression {
|
||||
impl<F: Field + PrimeField> fmt::Display for BooleanSpreadOrExpression<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
BooleanSpreadOrExpression::Spread(ref spread) => write!(f, "{}", spread),
|
||||
BooleanSpreadOrExpression::BooleanExpression(ref expression) => {
|
||||
write!(f, "{}", expression)
|
||||
}
|
||||
BooleanSpreadOrExpression::Spread(ref spread) => write!(f, "...{}", spread),
|
||||
BooleanSpreadOrExpression::Expression(ref expression) => write!(f, "{}", expression),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for BooleanExpression {
|
||||
impl<'ast, F: Field + PrimeField> fmt::Display for BooleanExpression<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
BooleanExpression::Variable(ref variable) => write!(f, "{}", variable),
|
||||
@ -114,10 +109,10 @@ impl<'ast> fmt::Display for BooleanExpression {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for FieldRangeOrExpression {
|
||||
impl<'ast, F: Field + PrimeField> fmt::Display for IntegerRangeOrExpression<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
FieldRangeOrExpression::Range(ref from, ref to) => write!(
|
||||
IntegerRangeOrExpression::Range(ref from, ref to) => write!(
|
||||
f,
|
||||
"{}..{}",
|
||||
from.as_ref()
|
||||
@ -125,16 +120,19 @@ impl<'ast> fmt::Display for FieldRangeOrExpression {
|
||||
.unwrap_or("".to_string()),
|
||||
to.as_ref().map(|e| e.to_string()).unwrap_or("".to_string())
|
||||
),
|
||||
FieldRangeOrExpression::FieldExpression(ref e) => write!(f, "{}", e),
|
||||
IntegerRangeOrExpression::Expression(ref e) => write!(f, "{}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Expression {
|
||||
impl<'ast, F: Field + PrimeField> fmt::Display for Expression<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Expression::Integer(ref integer_expression) => write!(f, "{}", integer_expression),
|
||||
Expression::FieldElement(ref _field_expression) => {
|
||||
unimplemented!("field elem not impl ")
|
||||
}
|
||||
Expression::Boolean(ref boolean_expression) => write!(f, "{}", boolean_expression),
|
||||
Expression::FieldElement(ref field_expression) => write!(f, "{}", field_expression),
|
||||
Expression::Variable(ref variable) => write!(f, "{}", variable),
|
||||
Expression::Struct(ref var, ref members) => {
|
||||
write!(f, "{} {{", var)?;
|
||||
@ -164,7 +162,7 @@ impl<'ast> fmt::Display for Expression {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Assignee {
|
||||
impl<F: Field + PrimeField> fmt::Display for Assignee<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Assignee::Variable(ref variable) => write!(f, "{}", variable),
|
||||
@ -176,7 +174,7 @@ impl fmt::Display for Assignee {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Statement {
|
||||
impl<F: Field + PrimeField> fmt::Display for Statement<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Statement::Definition(ref variable, ref statement) => {
|
||||
@ -199,7 +197,7 @@ impl fmt::Display for Statement {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Statement {
|
||||
impl<F: Field + PrimeField> fmt::Debug for Statement<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Statement::Definition(ref variable, ref statement) => {
|
||||
@ -222,24 +220,25 @@ impl fmt::Debug for Statement {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Type {
|
||||
impl<F: Field + PrimeField> fmt::Display for Type<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Type::FieldElement => unimplemented!("field type unimpl"),
|
||||
Type::U32 => write!(f, "field"),
|
||||
Type::Boolean => write!(f, "bool"),
|
||||
Type::FieldElement => write!(f, "field"),
|
||||
Type::Struct(ref variable) => write!(f, "{}", variable),
|
||||
Type::Array(ref array, ref count) => write!(f, "[{}; {}]", array, count),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for StructField {
|
||||
impl<F: Field + PrimeField> fmt::Display for StructField<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} : {}", self.ty, self.variable)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Struct {
|
||||
impl<F: Field + PrimeField> fmt::Debug for Struct<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "struct {} {{ \n", self.variable)?;
|
||||
for field in self.fields.iter() {
|
||||
@ -249,7 +248,7 @@ impl fmt::Debug for Struct {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Parameter {
|
||||
impl<F: Field + PrimeField> fmt::Display for Parameter<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// let visibility = if self.private { "private " } else { "" };
|
||||
write!(
|
||||
@ -262,7 +261,7 @@ impl fmt::Display for Parameter {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Parameter {
|
||||
impl<F: Field + PrimeField> fmt::Debug for Parameter<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Parameter(variable: {:?})", self.ty)
|
||||
}
|
||||
@ -274,7 +273,7 @@ impl fmt::Debug for FunctionName {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Function {
|
||||
impl<F: Field + PrimeField> fmt::Display for Function<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
@ -293,7 +292,7 @@ impl fmt::Display for Function {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Function {
|
||||
impl<F: Field + PrimeField> fmt::Debug for Function<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
|
@ -1,78 +1,170 @@
|
||||
//! Logic to convert from an abstract syntax tree (ast) representation to a typed zokrates_program.
|
||||
//! Logic to convert from an abstract syntax tree (ast) representation to a typed aleo program.
|
||||
//!
|
||||
//! @file zokrates_program.rs
|
||||
//! @file types_from.rs
|
||||
//! @author Collin Chin <collin@aleo.org>
|
||||
//! @date 2020
|
||||
|
||||
use crate::aleo_program::{types, Import, PathString};
|
||||
use crate::ast;
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use std::path::Path;
|
||||
|
||||
impl<'ast> From<ast::Field<'ast>> for types::FieldExpression {
|
||||
fn from(field: ast::Field<'ast>) -> Self {
|
||||
let number = field.value.parse::<u32>().expect("unable to unwrap field");
|
||||
types::FieldExpression::Number(number)
|
||||
/// pest ast -> types::Variable
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Variable<F> {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::Variable {
|
||||
name: variable.value,
|
||||
_field: PhantomData::<F>,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Boolean<'ast>> for types::BooleanExpression {
|
||||
/// pest ast - types::Integer
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Variable<'ast>> for types::IntegerExpression<F> {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::IntegerExpression::Variable(types::Variable::from(variable))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::U32<'ast>> for types::IntegerExpression<F> {
|
||||
fn from(field: ast::U32<'ast>) -> Self {
|
||||
types::IntegerExpression::Number(types::Integer::U32(
|
||||
field
|
||||
.number
|
||||
.value
|
||||
.parse::<u32>()
|
||||
.expect("unable to unwrap u32"),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>> for types::IntegerExpression<F> {
|
||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||
match types::Expression::from(expression) {
|
||||
types::Expression::Integer(integer_expression) => integer_expression,
|
||||
types::Expression::Variable(variable) => types::IntegerExpression::Variable(variable),
|
||||
_ => unimplemented!("expected field in field expression"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>>
|
||||
for types::IntegerSpreadOrExpression<F>
|
||||
{
|
||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||
match types::Expression::from(expression) {
|
||||
types::Expression::Integer(expression) => {
|
||||
types::IntegerSpreadOrExpression::Expression(expression)
|
||||
}
|
||||
_ => unimplemented!("cannot create field expression from boolean type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::SpreadOrExpression<'ast>>
|
||||
for types::IntegerSpreadOrExpression<F>
|
||||
{
|
||||
fn from(s_or_e: ast::SpreadOrExpression<'ast>) -> Self {
|
||||
match s_or_e {
|
||||
ast::SpreadOrExpression::Spread(spread) => {
|
||||
types::IntegerSpreadOrExpression::from(spread.expression)
|
||||
}
|
||||
ast::SpreadOrExpression::Expression(expression) => {
|
||||
types::IntegerSpreadOrExpression::from(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::RangeOrExpression<'ast>>
|
||||
for types::IntegerRangeOrExpression<F>
|
||||
{
|
||||
fn from(range_or_expression: ast::RangeOrExpression<'ast>) -> Self {
|
||||
match range_or_expression {
|
||||
ast::RangeOrExpression::Range(range) => {
|
||||
let from = range
|
||||
.from
|
||||
.map(|from| match types::Expression::from(from.0) {
|
||||
types::Expression::Integer(field) => field,
|
||||
expression => {
|
||||
unimplemented!("Range bounds should be numbers, found {}", expression)
|
||||
}
|
||||
});
|
||||
let to = range.to.map(|to| match types::Expression::from(to.0) {
|
||||
types::Expression::Integer(field) => field,
|
||||
expression => {
|
||||
unimplemented!("Range bounds should be numbers, found {}", expression)
|
||||
}
|
||||
});
|
||||
|
||||
types::IntegerRangeOrExpression::Range(from, to)
|
||||
}
|
||||
ast::RangeOrExpression::Expression(expression) => {
|
||||
match types::Expression::from(expression) {
|
||||
types::Expression::Integer(field_expression) => {
|
||||
types::IntegerRangeOrExpression::Expression(field_expression)
|
||||
}
|
||||
// types::Expression::ArrayAccess(expression, field), // recursive array access
|
||||
expression => unimplemented!("expression must be field, found {}", expression),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// pest ast -> types::Boolean
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>>
|
||||
for types::BooleanSpreadOrExpression<F>
|
||||
{
|
||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||
match types::Expression::from(expression) {
|
||||
types::Expression::Boolean(expression) => {
|
||||
types::BooleanSpreadOrExpression::Expression(expression)
|
||||
}
|
||||
_ => unimplemented!("cannot create boolean expression from field type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::SpreadOrExpression<'ast>>
|
||||
for types::BooleanSpreadOrExpression<F>
|
||||
{
|
||||
fn from(s_or_e: ast::SpreadOrExpression<'ast>) -> Self {
|
||||
match s_or_e {
|
||||
ast::SpreadOrExpression::Spread(spread) => {
|
||||
types::BooleanSpreadOrExpression::from(spread.expression)
|
||||
}
|
||||
ast::SpreadOrExpression::Expression(expression) => {
|
||||
types::BooleanSpreadOrExpression::from(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Variable<'ast>> for types::BooleanExpression<F> {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::BooleanExpression::Variable(types::Variable::from(variable))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Boolean<'ast>> for types::BooleanExpression<F> {
|
||||
fn from(boolean: ast::Boolean<'ast>) -> Self {
|
||||
let boolean = boolean
|
||||
types::BooleanExpression::Value(
|
||||
boolean
|
||||
.value
|
||||
.parse::<bool>()
|
||||
.expect("unable to unwrap boolean");
|
||||
types::BooleanExpression::Value(boolean)
|
||||
.expect("unable to unwrap boolean"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Value<'ast>> for types::Expression {
|
||||
fn from(value: ast::Value<'ast>) -> Self {
|
||||
match value {
|
||||
ast::Value::Boolean(value) => {
|
||||
types::Expression::Boolean(types::BooleanExpression::from(value))
|
||||
}
|
||||
ast::Value::Field(value) => {
|
||||
types::Expression::FieldElement(types::FieldExpression::from(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Variable<'ast>> for types::Variable {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::Variable(variable.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Variable<'ast>> for types::FieldExpression {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::FieldExpression::Variable(types::Variable(variable.value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Variable<'ast>> for types::BooleanExpression {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::BooleanExpression::Variable(types::Variable(variable.value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Variable<'ast>> for types::Expression {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::Expression::Variable(types::Variable(variable.value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::NotExpression<'ast>> for types::Expression {
|
||||
fn from(expression: ast::NotExpression<'ast>) -> Self {
|
||||
types::Expression::Boolean(types::BooleanExpression::Not(Box::new(
|
||||
types::BooleanExpression::from(*expression.expression),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Expression<'ast>> for types::BooleanExpression {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>> for types::BooleanExpression<F> {
|
||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||
match types::Expression::from(expression) {
|
||||
types::Expression::Boolean(boolean_expression) => boolean_expression,
|
||||
@ -82,17 +174,37 @@ impl<'ast> From<ast::Expression<'ast>> for types::BooleanExpression {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Expression<'ast>> for types::FieldExpression {
|
||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||
match types::Expression::from(expression) {
|
||||
types::Expression::FieldElement(field_expression) => field_expression,
|
||||
types::Expression::Variable(variable) => types::FieldExpression::Variable(variable),
|
||||
_ => unimplemented!("expected field in field expression"),
|
||||
/// pest ast -> types::Expression
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Value<'ast>> for types::Expression<F> {
|
||||
fn from(value: ast::Value<'ast>) -> Self {
|
||||
match value {
|
||||
ast::Value::U32(value) => {
|
||||
types::Expression::Integer(types::IntegerExpression::from(value))
|
||||
}
|
||||
ast::Value::Field(_field) => unimplemented!("cannot declare field values yet"),
|
||||
ast::Value::Boolean(value) => {
|
||||
types::Expression::Boolean(types::BooleanExpression::from(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> types::BooleanExpression {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Expression<F> {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::Expression::Variable(types::Variable::from(variable))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::NotExpression<'ast>> for types::Expression<F> {
|
||||
fn from(expression: ast::NotExpression<'ast>) -> Self {
|
||||
types::Expression::Boolean(types::BooleanExpression::Not(Box::new(
|
||||
types::BooleanExpression::from(*expression.expression),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> types::BooleanExpression<F> {
|
||||
/// Find out which types we are comparing and output the corresponding expression.
|
||||
fn from_eq(expression: ast::BinaryExpression<'ast>) -> Self {
|
||||
let left = types::Expression::from(*expression.left);
|
||||
@ -117,18 +229,18 @@ impl<'ast> types::BooleanExpression {
|
||||
)
|
||||
} //TODO: check case for two variables?
|
||||
// Field equality
|
||||
(types::Expression::FieldElement(lhs), types::Expression::FieldElement(rhs)) => {
|
||||
(types::Expression::Integer(lhs), types::Expression::Integer(rhs)) => {
|
||||
types::BooleanExpression::FieldEq(Box::new(lhs), Box::new(rhs))
|
||||
}
|
||||
(types::Expression::FieldElement(lhs), types::Expression::Variable(rhs)) => {
|
||||
(types::Expression::Integer(lhs), types::Expression::Variable(rhs)) => {
|
||||
types::BooleanExpression::FieldEq(
|
||||
Box::new(lhs),
|
||||
Box::new(types::FieldExpression::Variable(rhs)),
|
||||
Box::new(types::IntegerExpression::Variable(rhs)),
|
||||
)
|
||||
}
|
||||
(types::Expression::Variable(lhs), types::Expression::FieldElement(rhs)) => {
|
||||
(types::Expression::Variable(lhs), types::Expression::Integer(rhs)) => {
|
||||
types::BooleanExpression::FieldEq(
|
||||
Box::new(types::FieldExpression::Variable(lhs)),
|
||||
Box::new(types::IntegerExpression::Variable(lhs)),
|
||||
Box::new(rhs),
|
||||
)
|
||||
}
|
||||
@ -142,7 +254,7 @@ impl<'ast> types::BooleanExpression {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::BinaryExpression<'ast>> for types::Expression {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::BinaryExpression<'ast>> for types::Expression<F> {
|
||||
fn from(expression: ast::BinaryExpression<'ast>) -> Self {
|
||||
match expression.operation {
|
||||
// Boolean operations
|
||||
@ -161,57 +273,47 @@ impl<'ast> From<ast::BinaryExpression<'ast>> for types::Expression {
|
||||
types::Expression::Boolean(types::BooleanExpression::from_neq(expression))
|
||||
}
|
||||
ast::BinaryOperator::Geq => types::Expression::Boolean(types::BooleanExpression::Geq(
|
||||
Box::new(types::FieldExpression::from(*expression.left)),
|
||||
Box::new(types::FieldExpression::from(*expression.right)),
|
||||
Box::new(types::IntegerExpression::from(*expression.left)),
|
||||
Box::new(types::IntegerExpression::from(*expression.right)),
|
||||
)),
|
||||
ast::BinaryOperator::Gt => types::Expression::Boolean(types::BooleanExpression::Gt(
|
||||
Box::new(types::FieldExpression::from(*expression.left)),
|
||||
Box::new(types::FieldExpression::from(*expression.right)),
|
||||
Box::new(types::IntegerExpression::from(*expression.left)),
|
||||
Box::new(types::IntegerExpression::from(*expression.right)),
|
||||
)),
|
||||
ast::BinaryOperator::Leq => types::Expression::Boolean(types::BooleanExpression::Leq(
|
||||
Box::new(types::FieldExpression::from(*expression.left)),
|
||||
Box::new(types::FieldExpression::from(*expression.right)),
|
||||
Box::new(types::IntegerExpression::from(*expression.left)),
|
||||
Box::new(types::IntegerExpression::from(*expression.right)),
|
||||
)),
|
||||
ast::BinaryOperator::Lt => types::Expression::Boolean(types::BooleanExpression::Lt(
|
||||
Box::new(types::FieldExpression::from(*expression.left)),
|
||||
Box::new(types::FieldExpression::from(*expression.right)),
|
||||
Box::new(types::IntegerExpression::from(*expression.left)),
|
||||
Box::new(types::IntegerExpression::from(*expression.right)),
|
||||
)),
|
||||
// Field operations
|
||||
ast::BinaryOperator::Add => {
|
||||
types::Expression::FieldElement(types::FieldExpression::Add(
|
||||
Box::new(types::FieldExpression::from(*expression.left)),
|
||||
Box::new(types::FieldExpression::from(*expression.right)),
|
||||
))
|
||||
}
|
||||
ast::BinaryOperator::Sub => {
|
||||
types::Expression::FieldElement(types::FieldExpression::Sub(
|
||||
Box::new(types::FieldExpression::from(*expression.left)),
|
||||
Box::new(types::FieldExpression::from(*expression.right)),
|
||||
))
|
||||
}
|
||||
ast::BinaryOperator::Mul => {
|
||||
types::Expression::FieldElement(types::FieldExpression::Mul(
|
||||
Box::new(types::FieldExpression::from(*expression.left)),
|
||||
Box::new(types::FieldExpression::from(*expression.right)),
|
||||
))
|
||||
}
|
||||
ast::BinaryOperator::Div => {
|
||||
types::Expression::FieldElement(types::FieldExpression::Div(
|
||||
Box::new(types::FieldExpression::from(*expression.left)),
|
||||
Box::new(types::FieldExpression::from(*expression.right)),
|
||||
))
|
||||
}
|
||||
ast::BinaryOperator::Pow => {
|
||||
types::Expression::FieldElement(types::FieldExpression::Pow(
|
||||
Box::new(types::FieldExpression::from(*expression.left)),
|
||||
Box::new(types::FieldExpression::from(*expression.right)),
|
||||
))
|
||||
}
|
||||
ast::BinaryOperator::Add => types::Expression::Integer(types::IntegerExpression::Add(
|
||||
Box::new(types::IntegerExpression::from(*expression.left)),
|
||||
Box::new(types::IntegerExpression::from(*expression.right)),
|
||||
)),
|
||||
ast::BinaryOperator::Sub => types::Expression::Integer(types::IntegerExpression::Sub(
|
||||
Box::new(types::IntegerExpression::from(*expression.left)),
|
||||
Box::new(types::IntegerExpression::from(*expression.right)),
|
||||
)),
|
||||
ast::BinaryOperator::Mul => types::Expression::Integer(types::IntegerExpression::Mul(
|
||||
Box::new(types::IntegerExpression::from(*expression.left)),
|
||||
Box::new(types::IntegerExpression::from(*expression.right)),
|
||||
)),
|
||||
ast::BinaryOperator::Div => types::Expression::Integer(types::IntegerExpression::Div(
|
||||
Box::new(types::IntegerExpression::from(*expression.left)),
|
||||
Box::new(types::IntegerExpression::from(*expression.right)),
|
||||
)),
|
||||
ast::BinaryOperator::Pow => types::Expression::Integer(types::IntegerExpression::Pow(
|
||||
Box::new(types::IntegerExpression::from(*expression.left)),
|
||||
Box::new(types::IntegerExpression::from(*expression.right)),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::TernaryExpression<'ast>> for types::Expression {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::TernaryExpression<'ast>> for types::Expression<F> {
|
||||
fn from(expression: ast::TernaryExpression<'ast>) -> Self {
|
||||
// Evaluate expressions to find out result type
|
||||
let first = types::BooleanExpression::from(*expression.first);
|
||||
@ -242,24 +344,24 @@ impl<'ast> From<ast::TernaryExpression<'ast>> for types::Expression {
|
||||
))
|
||||
}
|
||||
// Field Result
|
||||
(types::Expression::FieldElement(second), types::Expression::FieldElement(third)) => {
|
||||
types::Expression::FieldElement(types::FieldExpression::IfElse(
|
||||
(types::Expression::Integer(second), types::Expression::Integer(third)) => {
|
||||
types::Expression::Integer(types::IntegerExpression::IfElse(
|
||||
Box::new(first),
|
||||
Box::new(second),
|
||||
Box::new(third),
|
||||
))
|
||||
}
|
||||
(types::Expression::FieldElement(second), types::Expression::Variable(third)) => {
|
||||
types::Expression::FieldElement(types::FieldExpression::IfElse(
|
||||
(types::Expression::Integer(second), types::Expression::Variable(third)) => {
|
||||
types::Expression::Integer(types::IntegerExpression::IfElse(
|
||||
Box::new(first),
|
||||
Box::new(second),
|
||||
Box::new(types::FieldExpression::Variable(third)),
|
||||
Box::new(types::IntegerExpression::Variable(third)),
|
||||
))
|
||||
}
|
||||
(types::Expression::Variable(second), types::Expression::FieldElement(third)) => {
|
||||
types::Expression::FieldElement(types::FieldExpression::IfElse(
|
||||
(types::Expression::Variable(second), types::Expression::Integer(third)) => {
|
||||
types::Expression::Integer(types::IntegerExpression::IfElse(
|
||||
Box::new(first),
|
||||
Box::new(types::FieldExpression::Variable(second)),
|
||||
Box::new(types::IntegerExpression::Variable(second)),
|
||||
Box::new(third),
|
||||
))
|
||||
}
|
||||
@ -274,41 +376,7 @@ impl<'ast> From<ast::TernaryExpression<'ast>> for types::Expression {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::RangeOrExpression<'ast>> for types::FieldRangeOrExpression {
|
||||
fn from(range_or_expression: ast::RangeOrExpression<'ast>) -> Self {
|
||||
match range_or_expression {
|
||||
ast::RangeOrExpression::Range(range) => {
|
||||
let from = range
|
||||
.from
|
||||
.map(|from| match types::Expression::from(from.0) {
|
||||
types::Expression::FieldElement(field) => field,
|
||||
expression => {
|
||||
unimplemented!("Range bounds should be numbers, found {}", expression)
|
||||
}
|
||||
});
|
||||
let to = range.to.map(|to| match types::Expression::from(to.0) {
|
||||
types::Expression::FieldElement(field) => field,
|
||||
expression => {
|
||||
unimplemented!("Range bounds should be numbers, found {}", expression)
|
||||
}
|
||||
});
|
||||
|
||||
types::FieldRangeOrExpression::Range(from, to)
|
||||
}
|
||||
ast::RangeOrExpression::Expression(expression) => {
|
||||
match types::Expression::from(expression) {
|
||||
types::Expression::FieldElement(field_expression) => {
|
||||
types::FieldRangeOrExpression::FieldExpression(field_expression)
|
||||
}
|
||||
// types::Expression::ArrayAccess(expression, field), // recursive array access
|
||||
expression => unimplemented!("expression must be field, found {}", expression),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::PostfixExpression<'ast>> for types::Expression {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::PostfixExpression<'ast>> for types::Expression<F> {
|
||||
fn from(expression: ast::PostfixExpression<'ast>) -> Self {
|
||||
let variable = types::Expression::Variable(types::Variable::from(expression.variable));
|
||||
|
||||
@ -339,13 +407,13 @@ impl<'ast> From<ast::PostfixExpression<'ast>> for types::Expression {
|
||||
),
|
||||
ast::Access::Array(array) => types::Expression::ArrayAccess(
|
||||
Box::new(acc),
|
||||
types::FieldRangeOrExpression::from(array.expression),
|
||||
types::IntegerRangeOrExpression::from(array.expression),
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Expression<'ast>> for types::Expression {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>> for types::Expression<F> {
|
||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||
match expression {
|
||||
ast::Expression::Value(value) => types::Expression::from(value),
|
||||
@ -359,147 +427,53 @@ impl<'ast> From<ast::Expression<'ast>> for types::Expression {
|
||||
ast::Expression::ArrayInitializer(_expression) => {
|
||||
unimplemented!("unknown type for array initializer expression")
|
||||
}
|
||||
ast::Expression::StructInline(_expression) => {
|
||||
unimplemented!("unknown type for inline struct expression")
|
||||
}
|
||||
ast::Expression::Postfix(expression) => types::Expression::from(expression),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Variable<'ast>> for types::Assignee {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::Assignee::Variable(types::Variable::from(variable))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Assignee<'ast>> for types::Assignee {
|
||||
fn from(assignee: ast::Assignee<'ast>) -> Self {
|
||||
let variable = types::Assignee::from(assignee.variable);
|
||||
|
||||
// we start with the id, and we fold the array of accesses by wrapping the current value
|
||||
assignee
|
||||
.accesses
|
||||
.into_iter()
|
||||
.fold(variable, |acc, access| match access {
|
||||
ast::AssigneeAccess::Array(array) => types::Assignee::Array(
|
||||
Box::new(acc),
|
||||
types::FieldRangeOrExpression::from(array.expression),
|
||||
),
|
||||
ast::AssigneeAccess::Member(struct_member) => types::Assignee::StructMember(
|
||||
Box::new(acc),
|
||||
types::Variable::from(struct_member.variable),
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::AssignStatement<'ast>> for types::Statement {
|
||||
fn from(statement: ast::AssignStatement<'ast>) -> Self {
|
||||
types::Statement::Definition(
|
||||
types::Assignee::from(statement.assignee),
|
||||
types::Expression::from(statement.expression),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Spread<'ast>> for types::BooleanSpread {
|
||||
fn from(spread: ast::Spread<'ast>) -> Self {
|
||||
let boolean_expression = types::Expression::from(spread.expression);
|
||||
match boolean_expression {
|
||||
types::Expression::Boolean(expression) => types::BooleanSpread(expression),
|
||||
types::Expression::Variable(variable) => {
|
||||
types::BooleanSpread(types::BooleanExpression::Variable(variable))
|
||||
}
|
||||
_ => unimplemented!("cannot create boolean spread from field type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Expression<'ast>> for types::BooleanSpreadOrExpression {
|
||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||
match types::Expression::from(expression) {
|
||||
types::Expression::Boolean(expression) => {
|
||||
types::BooleanSpreadOrExpression::BooleanExpression(expression)
|
||||
}
|
||||
_ => unimplemented!("cannot create boolean expression from field type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::SpreadOrExpression<'ast>> for types::BooleanSpreadOrExpression {
|
||||
fn from(s_or_e: ast::SpreadOrExpression<'ast>) -> Self {
|
||||
match s_or_e {
|
||||
ast::SpreadOrExpression::Spread(spread) => {
|
||||
types::BooleanSpreadOrExpression::Spread(types::BooleanSpread::from(spread))
|
||||
}
|
||||
ast::SpreadOrExpression::Expression(expression) => {
|
||||
match types::Expression::from(expression) {
|
||||
types::Expression::Boolean(expression) => {
|
||||
types::BooleanSpreadOrExpression::BooleanExpression(expression)
|
||||
}
|
||||
_ => unimplemented!("cannot create boolean expression from field type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Spread<'ast>> for types::FieldSpread {
|
||||
fn from(spread: ast::Spread<'ast>) -> Self {
|
||||
match types::Expression::from(spread.expression) {
|
||||
types::Expression::FieldElement(expression) => types::FieldSpread(expression),
|
||||
types::Expression::Variable(variable) => {
|
||||
types::FieldSpread(types::FieldExpression::Variable(variable))
|
||||
}
|
||||
expression => unimplemented!(
|
||||
"cannot create field spread from boolean type {}",
|
||||
expression
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Expression<'ast>> for types::FieldSpreadOrExpression {
|
||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||
match types::Expression::from(expression) {
|
||||
types::Expression::FieldElement(expression) => {
|
||||
types::FieldSpreadOrExpression::FieldExpression(expression)
|
||||
}
|
||||
_ => unimplemented!("cannot create field expression from boolean type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::SpreadOrExpression<'ast>> for types::FieldSpreadOrExpression {
|
||||
fn from(s_or_e: ast::SpreadOrExpression<'ast>) -> Self {
|
||||
match s_or_e {
|
||||
ast::SpreadOrExpression::Spread(spread) => {
|
||||
types::FieldSpreadOrExpression::Spread(types::FieldSpread::from(spread))
|
||||
}
|
||||
ast::SpreadOrExpression::Expression(expression) => {
|
||||
types::FieldSpreadOrExpression::from(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::InlineStructMember<'ast>> for types::StructMember {
|
||||
fn from(member: ast::InlineStructMember<'ast>) -> Self {
|
||||
types::StructMember {
|
||||
variable: types::Variable::from(member.variable),
|
||||
expression: types::Expression::from(member.expression),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> types::Expression {
|
||||
/// pest ast -> typed types::Expression
|
||||
/// For defined types (ex: u32[4]) we manually construct the expression instead of implementing the From trait.
|
||||
/// This saves us from having to resolve things at a later point in time.
|
||||
impl<'ast, F: Field + PrimeField> types::Expression<F> {
|
||||
fn from_basic(_ty: ast::BasicType<'ast>, _expression: ast::Expression<'ast>) -> Self {
|
||||
unimplemented!("from basic not impl");
|
||||
}
|
||||
|
||||
fn from_array(ty: ast::ArrayType<'ast>, expression: ast::Expression<'ast>) -> Self {
|
||||
match ty.ty {
|
||||
ast::BasicType::U32(_ty) => {
|
||||
let elements: Vec<Box<types::IntegerSpreadOrExpression<F>>> = match expression {
|
||||
ast::Expression::ArrayInline(array) => array
|
||||
.expressions
|
||||
.into_iter()
|
||||
.map(|s_or_e| Box::new(types::IntegerSpreadOrExpression::from(s_or_e)))
|
||||
.collect(),
|
||||
ast::Expression::ArrayInitializer(array) => {
|
||||
let count = match array.count {
|
||||
ast::Value::U32(f) => f
|
||||
.number
|
||||
.value
|
||||
.parse::<usize>()
|
||||
.expect("Unable to read array size"),
|
||||
_ => unimplemented!("Array size should be an integer"),
|
||||
};
|
||||
let expression =
|
||||
Box::new(types::IntegerSpreadOrExpression::from(*array.expression));
|
||||
|
||||
vec![expression; count]
|
||||
}
|
||||
_ => unimplemented!("expected array after array type"),
|
||||
};
|
||||
types::Expression::Integer(types::IntegerExpression::Array(elements))
|
||||
}
|
||||
ast::BasicType::Field(_ty) => unimplemented!("from array field basic types unimpl"),
|
||||
ast::BasicType::Boolean(_ty) => {
|
||||
let elements: Vec<Box<types::BooleanSpreadOrExpression>> = match expression {
|
||||
let elements: Vec<Box<types::BooleanSpreadOrExpression<F>>> = match expression {
|
||||
ast::Expression::ArrayInline(array) => array
|
||||
.expressions
|
||||
.into_iter()
|
||||
@ -507,9 +481,11 @@ impl<'ast> types::Expression {
|
||||
.collect(),
|
||||
ast::Expression::ArrayInitializer(array) => {
|
||||
let count = match array.count {
|
||||
ast::Value::Field(f) => {
|
||||
f.value.parse::<usize>().expect("Unable to read array size")
|
||||
}
|
||||
ast::Value::U32(f) => f
|
||||
.number
|
||||
.value
|
||||
.parse::<usize>()
|
||||
.expect("Unable to read array size"),
|
||||
_ => unimplemented!("Array size should be an integer"),
|
||||
};
|
||||
let expression =
|
||||
@ -521,29 +497,6 @@ impl<'ast> types::Expression {
|
||||
};
|
||||
types::Expression::Boolean(types::BooleanExpression::Array(elements))
|
||||
}
|
||||
ast::BasicType::Field(_ty) => {
|
||||
let elements: Vec<Box<types::FieldSpreadOrExpression>> = match expression {
|
||||
ast::Expression::ArrayInline(array) => array
|
||||
.expressions
|
||||
.into_iter()
|
||||
.map(|s_or_e| Box::new(types::FieldSpreadOrExpression::from(s_or_e)))
|
||||
.collect(),
|
||||
ast::Expression::ArrayInitializer(array) => {
|
||||
let count = match array.count {
|
||||
ast::Value::Field(f) => {
|
||||
f.value.parse::<usize>().expect("Unable to read array size")
|
||||
}
|
||||
_ => unimplemented!("Array size should be an integer"),
|
||||
};
|
||||
let expression =
|
||||
Box::new(types::FieldSpreadOrExpression::from(*array.expression));
|
||||
|
||||
vec![expression; count]
|
||||
}
|
||||
_ => unimplemented!("expected array after array type"),
|
||||
};
|
||||
types::Expression::FieldElement(types::FieldExpression::Array(elements))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -559,7 +512,7 @@ impl<'ast> types::Expression {
|
||||
.members
|
||||
.into_iter()
|
||||
.map(|member| types::StructMember::from(member))
|
||||
.collect::<Vec<types::StructMember>>();
|
||||
.collect::<Vec<types::StructMember<F>>>();
|
||||
|
||||
types::Expression::Struct(variable, members)
|
||||
}
|
||||
@ -576,7 +529,47 @@ impl<'ast> types::Expression {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::DefinitionStatement<'ast>> for types::Statement {
|
||||
/// pest ast -> types::Assignee
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Assignee<F> {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::Assignee::Variable(types::Variable::from(variable))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Assignee<'ast>> for types::Assignee<F> {
|
||||
fn from(assignee: ast::Assignee<'ast>) -> Self {
|
||||
let variable = types::Assignee::from(assignee.variable);
|
||||
|
||||
// we start with the id, and we fold the array of accesses by wrapping the current value
|
||||
assignee
|
||||
.accesses
|
||||
.into_iter()
|
||||
.fold(variable, |acc, access| match access {
|
||||
ast::AssigneeAccess::Array(array) => types::Assignee::Array(
|
||||
Box::new(acc),
|
||||
types::IntegerRangeOrExpression::from(array.expression),
|
||||
),
|
||||
ast::AssigneeAccess::Member(struct_member) => types::Assignee::StructMember(
|
||||
Box::new(acc),
|
||||
types::Variable::from(struct_member.variable),
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// pest ast -> types::Statement
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::AssignStatement<'ast>) -> Self {
|
||||
types::Statement::Definition(
|
||||
types::Assignee::from(statement.assignee),
|
||||
types::Expression::from(statement.expression),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::DefinitionStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::DefinitionStatement<'ast>) -> Self {
|
||||
types::Statement::Definition(
|
||||
types::Assignee::from(statement.variable),
|
||||
@ -585,7 +578,7 @@ impl<'ast> From<ast::DefinitionStatement<'ast>> for types::Statement {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::ReturnStatement<'ast>> for types::Statement {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ReturnStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::ReturnStatement<'ast>) -> Self {
|
||||
types::Statement::Return(
|
||||
statement
|
||||
@ -597,12 +590,12 @@ impl<'ast> From<ast::ReturnStatement<'ast>> for types::Statement {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::ForStatement<'ast>> for types::Statement {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ForStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::ForStatement<'ast>) -> Self {
|
||||
types::Statement::For(
|
||||
types::Variable::from(statement.index),
|
||||
types::FieldExpression::from(statement.start),
|
||||
types::FieldExpression::from(statement.stop),
|
||||
types::IntegerExpression::from(statement.start),
|
||||
types::IntegerExpression::from(statement.stop),
|
||||
statement
|
||||
.statements
|
||||
.into_iter()
|
||||
@ -612,7 +605,7 @@ impl<'ast> From<ast::ForStatement<'ast>> for types::Statement {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Statement<'ast>> for types::Statement {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Statement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::Statement<'ast>) -> Self {
|
||||
match statement {
|
||||
ast::Statement::Assign(statement) => types::Statement::from(statement),
|
||||
@ -623,33 +616,40 @@ impl<'ast> From<ast::Statement<'ast>> for types::Statement {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::BasicType<'ast>> for types::Type {
|
||||
/// pest ast -> Explicit types::Type for defining struct members and function params
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::BasicType<'ast>> for types::Type<F> {
|
||||
fn from(basic_type: ast::BasicType<'ast>) -> Self {
|
||||
match basic_type {
|
||||
ast::BasicType::Field(_ty) => types::Type::FieldElement,
|
||||
ast::BasicType::U32(_ty) => types::Type::U32,
|
||||
ast::BasicType::Field(_ty) => types::Type::U32,
|
||||
ast::BasicType::Boolean(_ty) => types::Type::Boolean,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::ArrayType<'ast>> for types::Type {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ArrayType<'ast>> for types::Type<F> {
|
||||
fn from(array_type: ast::ArrayType<'ast>) -> Self {
|
||||
let element_type = Box::new(types::Type::from(array_type.ty));
|
||||
let count = match array_type.count {
|
||||
ast::Value::Field(f) => f.value.parse::<usize>().expect("Unable to read array size"),
|
||||
ast::Value::Field(f) => f
|
||||
.number
|
||||
.value
|
||||
.parse::<usize>()
|
||||
.expect("Unable to read array size"),
|
||||
_ => unimplemented!("Array size should be an integer"),
|
||||
};
|
||||
types::Type::Array(element_type, count)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::StructType<'ast>> for types::Type {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::StructType<'ast>> for types::Type<F> {
|
||||
fn from(struct_type: ast::StructType<'ast>) -> Self {
|
||||
types::Type::Struct(types::Variable::from(struct_type.variable))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Type<'ast>> for types::Type {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Type<'ast>> for types::Type<F> {
|
||||
fn from(ty: ast::Type<'ast>) -> Self {
|
||||
match ty {
|
||||
ast::Type::Basic(ty) => types::Type::from(ty),
|
||||
@ -659,7 +659,18 @@ impl<'ast> From<ast::Type<'ast>> for types::Type {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::StructField<'ast>> for types::StructField {
|
||||
/// pest ast -> types::Struct
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::InlineStructMember<'ast>> for types::StructMember<F> {
|
||||
fn from(member: ast::InlineStructMember<'ast>) -> Self {
|
||||
types::StructMember {
|
||||
variable: types::Variable::from(member.variable),
|
||||
expression: types::Expression::from(member.expression),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::StructField<'ast>> for types::StructField<F> {
|
||||
fn from(struct_field: ast::StructField<'ast>) -> Self {
|
||||
types::StructField {
|
||||
variable: types::Variable::from(struct_field.variable),
|
||||
@ -668,7 +679,7 @@ impl<'ast> From<ast::StructField<'ast>> for types::StructField {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Struct<'ast>> for types::Struct {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Struct<'ast>> for types::Struct<F> {
|
||||
fn from(struct_definition: ast::Struct<'ast>) -> Self {
|
||||
let variable = types::Variable::from(struct_definition.variable);
|
||||
let fields = struct_definition
|
||||
@ -681,6 +692,8 @@ impl<'ast> From<ast::Struct<'ast>> for types::Struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// pest ast -> function types::Parameters
|
||||
|
||||
impl From<ast::Visibility> for types::Visibility {
|
||||
fn from(visibility: ast::Visibility) -> Self {
|
||||
match visibility {
|
||||
@ -690,7 +703,7 @@ impl From<ast::Visibility> for types::Visibility {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Parameter<'ast>> for types::Parameter {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Parameter<'ast>> for types::Parameter<F> {
|
||||
fn from(parameter: ast::Parameter<'ast>) -> Self {
|
||||
let ty = types::Type::from(parameter.ty);
|
||||
let variable = types::Variable::from(parameter.variable);
|
||||
@ -712,13 +725,15 @@ impl<'ast> From<ast::Parameter<'ast>> for types::Parameter {
|
||||
}
|
||||
}
|
||||
|
||||
/// pest ast -> types::Function
|
||||
|
||||
impl<'ast> From<ast::FunctionName<'ast>> for types::FunctionName {
|
||||
fn from(name: ast::FunctionName<'ast>) -> Self {
|
||||
types::FunctionName(name.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::Function<'ast>> for types::Function {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Function<'ast>> for types::Function<F> {
|
||||
fn from(function_definition: ast::Function<'ast>) -> Self {
|
||||
let function_name = types::FunctionName::from(function_definition.function_name);
|
||||
let parameters = function_definition
|
||||
@ -746,6 +761,8 @@ impl<'ast> From<ast::Function<'ast>> for types::Function {
|
||||
}
|
||||
}
|
||||
|
||||
/// pest ast -> Import
|
||||
|
||||
impl<'ast> From<ast::Variable<'ast>> for PathString<'ast> {
|
||||
fn from(import: ast::Variable<'ast>) -> Self {
|
||||
import.span.as_str()
|
||||
@ -766,7 +783,9 @@ impl<'ast> From<ast::Import<'ast>> for Import<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ast::File<'ast>> for types::Program<'ast> {
|
||||
/// pest ast -> types::Program
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::File<'ast>> for types::Program<'ast, F> {
|
||||
fn from(file: ast::File<'ast>) -> Self {
|
||||
// Compiled ast -> aleo program representation
|
||||
let imports = file
|
||||
@ -792,7 +811,10 @@ impl<'ast> From<ast::File<'ast>> for types::Program<'ast> {
|
||||
});
|
||||
|
||||
types::Program {
|
||||
name: types::Variable("".into()),
|
||||
name: types::Variable {
|
||||
name: "".into(),
|
||||
_field: PhantomData::<F>,
|
||||
},
|
||||
imports,
|
||||
structs,
|
||||
functions,
|
||||
|
512
src/ast.rs
512
src/ast.rs
@ -30,203 +30,6 @@ lazy_static! {
|
||||
static ref PRECEDENCE_CLIMBER: PrecClimber<Rule> = precedence_climber();
|
||||
}
|
||||
|
||||
fn precedence_climber() -> PrecClimber<Rule> {
|
||||
PrecClimber::new(vec![
|
||||
Operator::new(Rule::operation_or, Assoc::Left),
|
||||
Operator::new(Rule::operation_and, Assoc::Left),
|
||||
Operator::new(Rule::operation_eq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_neq, Assoc::Left),
|
||||
Operator::new(Rule::operation_geq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_gt, Assoc::Left)
|
||||
| Operator::new(Rule::operation_leq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_lt, Assoc::Left),
|
||||
Operator::new(Rule::operation_add, Assoc::Left)
|
||||
| Operator::new(Rule::operation_sub, Assoc::Left),
|
||||
Operator::new(Rule::operation_mul, Assoc::Left)
|
||||
| Operator::new(Rule::operation_div, Assoc::Left),
|
||||
Operator::new(Rule::operation_pow, Assoc::Left),
|
||||
])
|
||||
}
|
||||
|
||||
fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
|
||||
Box::new(match pair.as_rule() {
|
||||
Rule::expression_term => {
|
||||
let clone = pair.clone();
|
||||
let next = clone.into_inner().next().unwrap();
|
||||
match next.as_rule() {
|
||||
Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(), // Parenthesis case
|
||||
Rule::expression_inline_struct => {
|
||||
Expression::StructInline(
|
||||
StructInlineExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
},
|
||||
Rule::expression_array_inline => {
|
||||
Expression::ArrayInline(
|
||||
ArrayInlineExpression::from_pest(&mut pair.into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Rule::expression_array_initializer => {
|
||||
Expression::ArrayInitializer(
|
||||
ArrayInitializerExpression::from_pest(&mut pair.into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Rule::expression_conditional => {
|
||||
Expression::Ternary(
|
||||
TernaryExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
},
|
||||
Rule::expression_not => {
|
||||
let span = next.as_span();
|
||||
let mut inner = next.into_inner();
|
||||
let operation = match inner.next().unwrap().as_rule() {
|
||||
Rule::operation_pre_not => Not::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
rule => unreachable!("`expression_not` should yield `operation_pre_not`, found {:#?}", rule)
|
||||
};
|
||||
let expression = parse_term(inner.next().unwrap());
|
||||
Expression::Not(NotExpression { operation, expression, span })
|
||||
},
|
||||
Rule::expression_increment => {
|
||||
println!("expression increment");
|
||||
let span = next.as_span();
|
||||
let mut inner = next.into_inner();
|
||||
let expression = parse_term(inner.next().unwrap());
|
||||
let operation = match inner.next().unwrap().as_rule() {
|
||||
Rule::operation_post_increment => Increment::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
rule => unreachable!("`expression_increment` should yield `operation_post_increment`, found {:#?}", rule)
|
||||
};
|
||||
Expression::Increment(IncrementExpression { operation, expression, span })
|
||||
},
|
||||
Rule::expression_decrement => {
|
||||
println!("expression decrement");
|
||||
let span = next.as_span();
|
||||
let mut inner = next.into_inner();
|
||||
let expression = parse_term(inner.next().unwrap());
|
||||
let operation = match inner.next().unwrap().as_rule() {
|
||||
Rule::operation_post_decrement => Decrement::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
rule => unreachable!("`expression_decrement` should yield `operation_post_decrement`, found {:#?}", rule)
|
||||
};
|
||||
Expression::Decrement(DecrementExpression { operation, expression, span })
|
||||
},
|
||||
Rule::expression_postfix => {
|
||||
Expression::Postfix(
|
||||
PostfixExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
}
|
||||
Rule::expression_primitive => {
|
||||
let next = next.into_inner().next().unwrap();
|
||||
match next.as_rule() {
|
||||
Rule::value => Expression::Value(
|
||||
Value::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
|
||||
),
|
||||
Rule::variable => Expression::Variable(
|
||||
Variable::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
),
|
||||
rule => unreachable!("`expression_primitive` should contain one of [`value`, `variable`], found {:#?}", rule)
|
||||
}
|
||||
},
|
||||
|
||||
rule => unreachable!("`term` should contain one of ['value', 'variable', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}", rule)
|
||||
}
|
||||
}
|
||||
rule => unreachable!(
|
||||
"`parse_expression_term` should be invoked on `Rule::expression_term`, found {:#?}",
|
||||
rule
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
fn binary_expression<'ast>(
|
||||
lhs: Box<Expression<'ast>>,
|
||||
pair: Pair<'ast, Rule>,
|
||||
rhs: Box<Expression<'ast>>,
|
||||
) -> Box<Expression<'ast>> {
|
||||
let (start, _) = lhs.span().clone().split();
|
||||
let (_, end) = rhs.span().clone().split();
|
||||
let span = start.span(&end);
|
||||
|
||||
Box::new(match pair.as_rule() {
|
||||
Rule::operation_or => Expression::binary(BinaryOperator::Or, lhs, rhs, span),
|
||||
Rule::operation_and => Expression::binary(BinaryOperator::And, lhs, rhs, span),
|
||||
Rule::operation_eq => Expression::binary(BinaryOperator::Eq, lhs, rhs, span),
|
||||
Rule::operation_neq => Expression::binary(BinaryOperator::Neq, lhs, rhs, span),
|
||||
Rule::operation_geq => Expression::binary(BinaryOperator::Geq, lhs, rhs, span),
|
||||
Rule::operation_gt => Expression::binary(BinaryOperator::Gt, lhs, rhs, span),
|
||||
Rule::operation_leq => Expression::binary(BinaryOperator::Leq, lhs, rhs, span),
|
||||
Rule::operation_lt => Expression::binary(BinaryOperator::Lt, lhs, rhs, span),
|
||||
Rule::operation_add => Expression::binary(BinaryOperator::Add, lhs, rhs, span),
|
||||
Rule::operation_sub => Expression::binary(BinaryOperator::Sub, lhs, rhs, span),
|
||||
Rule::operation_mul => Expression::binary(BinaryOperator::Mul, lhs, rhs, span),
|
||||
Rule::operation_div => Expression::binary(BinaryOperator::Div, lhs, rhs, span),
|
||||
Rule::operation_pow => Expression::binary(BinaryOperator::Pow, lhs, rhs, span),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
|
||||
// Types
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_bool))]
|
||||
pub struct BooleanType<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_field))]
|
||||
pub struct FieldType<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_struct))]
|
||||
pub struct StructType<'ast> {
|
||||
pub variable: Variable<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_basic))]
|
||||
pub enum BasicType<'ast> {
|
||||
Field(FieldType<'ast>),
|
||||
Boolean(BooleanType<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_basic_or_struct))]
|
||||
pub enum BasicOrStructType<'ast> {
|
||||
Struct(StructType<'ast>),
|
||||
Basic(BasicType<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_array))]
|
||||
pub struct ArrayType<'ast> {
|
||||
pub ty: BasicType<'ast>,
|
||||
pub count: Value<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty))]
|
||||
pub enum Type<'ast> {
|
||||
Basic(BasicType<'ast>),
|
||||
Array(ArrayType<'ast>),
|
||||
Struct(StructType<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Type<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Type::Basic(ref _ty) => write!(f, "basic"),
|
||||
Type::Array(ref _ty) => write!(f, "array"),
|
||||
Type::Struct(ref _ty) => write!(f, "struct"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Visibility
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
@ -286,7 +89,124 @@ pub enum BinaryOperator {
|
||||
Pow,
|
||||
}
|
||||
|
||||
// Types
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_u32))]
|
||||
pub struct U32Type<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_bool))]
|
||||
pub struct BooleanType<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_field))]
|
||||
pub struct FieldType<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_struct))]
|
||||
pub struct StructType<'ast> {
|
||||
pub variable: Variable<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_basic))]
|
||||
pub enum BasicType<'ast> {
|
||||
U32(U32Type<'ast>),
|
||||
Field(FieldType<'ast>),
|
||||
Boolean(BooleanType<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_basic_or_struct))]
|
||||
pub enum BasicOrStructType<'ast> {
|
||||
Struct(StructType<'ast>),
|
||||
Basic(BasicType<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty_array))]
|
||||
pub struct ArrayType<'ast> {
|
||||
pub ty: BasicType<'ast>,
|
||||
pub count: Value<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::ty))]
|
||||
pub enum Type<'ast> {
|
||||
Basic(BasicType<'ast>),
|
||||
Array(ArrayType<'ast>),
|
||||
Struct(StructType<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Type<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Type::Basic(ref _ty) => write!(f, "basic"),
|
||||
Type::Array(ref _ty) => write!(f, "array"),
|
||||
Type::Struct(ref _ty) => write!(f, "struct"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Values
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_number))]
|
||||
pub struct Number<'ast> {
|
||||
#[pest_ast(outer(with(span_into_string)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Number<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_u32))]
|
||||
pub struct U32<'ast> {
|
||||
pub number: Number<'ast>,
|
||||
pub ty: U32Type<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for U32<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.number)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_field))]
|
||||
pub struct Field<'ast> {
|
||||
pub number: Number<'ast>,
|
||||
pub ty: U32Type<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Field<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.number)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_boolean))]
|
||||
@ -303,33 +223,20 @@ impl<'ast> fmt::Display for Boolean<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_field))]
|
||||
pub struct Field<'ast> {
|
||||
#[pest_ast(outer(with(span_into_string)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Field<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value))]
|
||||
pub enum Value<'ast> {
|
||||
Boolean(Boolean<'ast>),
|
||||
U32(U32<'ast>),
|
||||
Field(Field<'ast>),
|
||||
Boolean(Boolean<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> Value<'ast> {
|
||||
pub fn span(&self) -> &Span<'ast> {
|
||||
match self {
|
||||
Value::Boolean(value) => &value.span,
|
||||
Value::U32(value) => &value.span,
|
||||
Value::Field(value) => &value.span,
|
||||
Value::Boolean(value) => &value.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -337,8 +244,9 @@ impl<'ast> Value<'ast> {
|
||||
impl<'ast> fmt::Display for Value<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Value::Boolean(ref value) => write!(f, "{}", value),
|
||||
Value::U32(ref value) => write!(f, "{}", value),
|
||||
Value::Field(ref value) => write!(f, "{}", value),
|
||||
Value::Boolean(ref value) => write!(f, "{}", value),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -720,6 +628,140 @@ impl<'ast> fmt::Display for Expression<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
fn precedence_climber() -> PrecClimber<Rule> {
|
||||
PrecClimber::new(vec![
|
||||
Operator::new(Rule::operation_or, Assoc::Left),
|
||||
Operator::new(Rule::operation_and, Assoc::Left),
|
||||
Operator::new(Rule::operation_eq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_neq, Assoc::Left),
|
||||
Operator::new(Rule::operation_geq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_gt, Assoc::Left)
|
||||
| Operator::new(Rule::operation_leq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_lt, Assoc::Left),
|
||||
Operator::new(Rule::operation_add, Assoc::Left)
|
||||
| Operator::new(Rule::operation_sub, Assoc::Left),
|
||||
Operator::new(Rule::operation_mul, Assoc::Left)
|
||||
| Operator::new(Rule::operation_div, Assoc::Left),
|
||||
Operator::new(Rule::operation_pow, Assoc::Left),
|
||||
])
|
||||
}
|
||||
|
||||
fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
|
||||
Box::new(match pair.as_rule() {
|
||||
Rule::expression_term => {
|
||||
let clone = pair.clone();
|
||||
let next = clone.into_inner().next().unwrap();
|
||||
match next.as_rule() {
|
||||
Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(), // Parenthesis case
|
||||
Rule::expression_inline_struct => {
|
||||
Expression::StructInline(
|
||||
StructInlineExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
},
|
||||
Rule::expression_array_inline => {
|
||||
Expression::ArrayInline(
|
||||
ArrayInlineExpression::from_pest(&mut pair.into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Rule::expression_array_initializer => {
|
||||
Expression::ArrayInitializer(
|
||||
ArrayInitializerExpression::from_pest(&mut pair.into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Rule::expression_conditional => {
|
||||
Expression::Ternary(
|
||||
TernaryExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
},
|
||||
Rule::expression_not => {
|
||||
let span = next.as_span();
|
||||
let mut inner = next.into_inner();
|
||||
let operation = match inner.next().unwrap().as_rule() {
|
||||
Rule::operation_pre_not => Not::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
rule => unreachable!("`expression_not` should yield `operation_pre_not`, found {:#?}", rule)
|
||||
};
|
||||
let expression = parse_term(inner.next().unwrap());
|
||||
Expression::Not(NotExpression { operation, expression, span })
|
||||
},
|
||||
Rule::expression_increment => {
|
||||
println!("expression increment");
|
||||
let span = next.as_span();
|
||||
let mut inner = next.into_inner();
|
||||
let expression = parse_term(inner.next().unwrap());
|
||||
let operation = match inner.next().unwrap().as_rule() {
|
||||
Rule::operation_post_increment => Increment::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
rule => unreachable!("`expression_increment` should yield `operation_post_increment`, found {:#?}", rule)
|
||||
};
|
||||
Expression::Increment(IncrementExpression { operation, expression, span })
|
||||
},
|
||||
Rule::expression_decrement => {
|
||||
println!("expression decrement");
|
||||
let span = next.as_span();
|
||||
let mut inner = next.into_inner();
|
||||
let expression = parse_term(inner.next().unwrap());
|
||||
let operation = match inner.next().unwrap().as_rule() {
|
||||
Rule::operation_post_decrement => Decrement::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
rule => unreachable!("`expression_decrement` should yield `operation_post_decrement`, found {:#?}", rule)
|
||||
};
|
||||
Expression::Decrement(DecrementExpression { operation, expression, span })
|
||||
},
|
||||
Rule::expression_postfix => {
|
||||
Expression::Postfix(
|
||||
PostfixExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
}
|
||||
Rule::expression_primitive => {
|
||||
let next = next.into_inner().next().unwrap();
|
||||
match next.as_rule() {
|
||||
Rule::value => {
|
||||
Expression::Value(
|
||||
Value::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Rule::variable => Expression::Variable(
|
||||
Variable::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
),
|
||||
rule => unreachable!("`expression_primitive` should contain one of [`value`, `variable`], found {:#?}", rule)
|
||||
}
|
||||
},
|
||||
|
||||
rule => unreachable!("`term` should contain one of ['value', 'variable', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}", rule)
|
||||
}
|
||||
}
|
||||
rule => unreachable!(
|
||||
"`parse_expression_term` should be invoked on `Rule::expression_term`, found {:#?}",
|
||||
rule
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
fn binary_expression<'ast>(
|
||||
lhs: Box<Expression<'ast>>,
|
||||
pair: Pair<'ast, Rule>,
|
||||
rhs: Box<Expression<'ast>>,
|
||||
) -> Box<Expression<'ast>> {
|
||||
let (start, _) = lhs.span().clone().split();
|
||||
let (_, end) = rhs.span().clone().split();
|
||||
let span = start.span(&end);
|
||||
|
||||
Box::new(match pair.as_rule() {
|
||||
Rule::operation_or => Expression::binary(BinaryOperator::Or, lhs, rhs, span),
|
||||
Rule::operation_and => Expression::binary(BinaryOperator::And, lhs, rhs, span),
|
||||
Rule::operation_eq => Expression::binary(BinaryOperator::Eq, lhs, rhs, span),
|
||||
Rule::operation_neq => Expression::binary(BinaryOperator::Neq, lhs, rhs, span),
|
||||
Rule::operation_geq => Expression::binary(BinaryOperator::Geq, lhs, rhs, span),
|
||||
Rule::operation_gt => Expression::binary(BinaryOperator::Gt, lhs, rhs, span),
|
||||
Rule::operation_leq => Expression::binary(BinaryOperator::Leq, lhs, rhs, span),
|
||||
Rule::operation_lt => Expression::binary(BinaryOperator::Lt, lhs, rhs, span),
|
||||
Rule::operation_add => Expression::binary(BinaryOperator::Add, lhs, rhs, span),
|
||||
Rule::operation_sub => Expression::binary(BinaryOperator::Sub, lhs, rhs, span),
|
||||
Rule::operation_mul => Expression::binary(BinaryOperator::Mul, lhs, rhs, span),
|
||||
Rule::operation_div => Expression::binary(BinaryOperator::Div, lhs, rhs, span),
|
||||
Rule::operation_pow => Expression::binary(BinaryOperator::Pow, lhs, rhs, span),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
|
||||
impl<'ast> FromPest<'ast> for Expression<'ast> {
|
||||
type Rule = Rule;
|
||||
type FatalError = Void;
|
||||
@ -759,6 +801,14 @@ pub struct DefinitionStatement<'ast> {
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_return))]
|
||||
pub struct ReturnStatement<'ast> {
|
||||
pub expressions: Vec<Expression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_for))]
|
||||
pub struct ForStatement<'ast> {
|
||||
@ -770,21 +820,13 @@ pub struct ForStatement<'ast> {
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_return))]
|
||||
pub struct ReturnStatement<'ast> {
|
||||
pub expressions: Vec<Expression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement))]
|
||||
pub enum Statement<'ast> {
|
||||
Assign(AssignStatement<'ast>),
|
||||
Definition(DefinitionStatement<'ast>),
|
||||
Iteration(ForStatement<'ast>),
|
||||
Return(ReturnStatement<'ast>),
|
||||
Iteration(ForStatement<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for AssignStatement<'ast> {
|
||||
@ -799,16 +841,6 @@ impl<'ast> fmt::Display for DefinitionStatement<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ForStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"for {} in {}..{} do {:#?} endfor",
|
||||
self.index, self.start, self.stop, self.statements
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ReturnStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (i, expression) in self.expressions.iter().enumerate() {
|
||||
@ -821,13 +853,23 @@ impl<'ast> fmt::Display for ReturnStatement<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ForStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"for {} in {}..{} do {:#?} endfor",
|
||||
self.index, self.start, self.stop, self.statements
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Statement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Statement::Assign(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Definition(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Iteration(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Return(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Iteration(ref statement) => write!(f, "{}", statement),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,10 +48,10 @@ operation_binary = _ {
|
||||
// operation_div_assign = { "/=" }
|
||||
|
||||
/// Types
|
||||
|
||||
ty_u32 = {"u32"}
|
||||
ty_field = {"field"}
|
||||
ty_bool = {"bool"}
|
||||
ty_basic = { ty_field | ty_bool }
|
||||
ty_basic = { ty_u32 | ty_field | ty_bool }
|
||||
ty_struct = { variable }
|
||||
ty_basic_or_struct = {ty_basic | ty_struct }
|
||||
ty_array = {ty_basic ~ ("[" ~ value ~ "]")+ }
|
||||
@ -59,10 +59,11 @@ ty = {ty_array | ty_basic | ty_struct}
|
||||
type_list = _{(ty ~ ("," ~ ty)*)?}
|
||||
|
||||
/// Values
|
||||
|
||||
value_number = @{ "-"? ~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*)}
|
||||
value_u32 = { value_number ~ ty_u32}
|
||||
value_field = { value_number ~ ty_field }
|
||||
value_boolean = { "true" | "false" }
|
||||
value_field = @{ "-"? ~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*) }
|
||||
value = { value_boolean | value_field }
|
||||
value = { value_u32 | value_field | value_boolean }
|
||||
|
||||
/// Variables
|
||||
|
||||
@ -88,8 +89,8 @@ access_member = { "." ~ variable }
|
||||
access = { access_array | access_call | access_member }
|
||||
expression_postfix = { variable ~ access+ }
|
||||
|
||||
assignee = { variable ~ assignee_access* }
|
||||
assignee_access = { access_array | access_member }
|
||||
assignee = { variable ~ assignee_access* }
|
||||
|
||||
spread = { "..." ~ expression }
|
||||
spread_or_expression = { spread | expression }
|
||||
|
@ -47,7 +47,7 @@ impl<F: Field + PrimeField> ConstraintSynthesizer<F> for Benchmark<F> {
|
||||
let syntax_tree = ast::File::from_pest(&mut file).expect("infallible");
|
||||
// println!("{:#?}", syntax_tree);
|
||||
|
||||
let program = aleo_program::Program::from(syntax_tree);
|
||||
let program = aleo_program::Program::<'_, F>::from(syntax_tree);
|
||||
println!(" compiled: {:#?}", program);
|
||||
|
||||
let program = program.name("simple".into());
|
||||
|
Loading…
Reference in New Issue
Block a user