Split ast into operations, types, and values

This commit is contained in:
howardwu 2020-06-07 00:41:13 -07:00
parent 3286eac221
commit 103a12f7ab
26 changed files with 583 additions and 406 deletions

View File

@ -1,4 +1,27 @@
//! Abstract syntax tree (ast) representation from leo.pest.
use crate::{
operations::{
AssignOperation,
BinaryOperation,
NotOperation,
},
types::{
ArrayType,
CircuitType,
DataType,
FieldType,
ForStatement,
GroupType,
Identifier,
IntegerType,
SelfType,
Visibility
},
values::{
NumberValue,
Value
}
};
use from_pest::{ConversionError, FromPest, Void};
use pest::{
@ -18,7 +41,7 @@ pub fn parse(input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
LanguageParser::parse(Rule::file, input)
}
fn span_into_string(span: Span) -> String {
pub(crate) fn span_into_string(span: Span) -> String {
span.as_str().to_string()
}
@ -26,196 +49,13 @@ lazy_static! {
static ref PRECEDENCE_CLIMBER: PrecClimber<Rule> = precedence_climber();
}
// Identifiers
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::identifier))]
pub struct Identifier<'ast> {
#[pest_ast(outer(with(span_into_string)))]
pub value: String,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
impl<'ast> fmt::Display for Identifier<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value)
}
}
// Visibility
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::visibility_public))]
pub struct Public {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::visibility_private))]
pub struct Private {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::visibility))]
pub enum Visibility {
Public(Public),
Private(Private),
}
// Unary Operations
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_pre_not))]
pub struct Not<'ast> {
#[pest_ast(outer())]
pub span: Span<'ast>,
}
// #[derive(Clone, Debug, FromPest, PartialEq)]
// #[pest_ast(rule(Rule::operation_post_increment))]
// pub struct Increment<'ast> {
// #[pest_ast(outer())]
// pub span: Span<'ast>,
// }
//
// #[derive(Clone, Debug, FromPest, PartialEq)]
// #[pest_ast(rule(Rule::operation_post_decrement))]
// pub struct Decrement<'ast> {
// #[pest_ast(outer())]
// pub span: Span<'ast>,
// }
// Binary Operations
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_binary))]
pub enum BinaryOperator {
Or,
And,
Eq,
Ne,
Ge,
Gt,
Le,
Lt,
Add,
Sub,
Mul,
Div,
Pow,
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::assign))]
pub struct Assign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_add_assign))]
pub struct AddAssign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_sub_assign))]
pub struct SubAssign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_mul_assign))]
pub struct MulAssign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_div_assign))]
pub struct DivAssign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_pow_assign))]
pub struct PowAssign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_assign))]
pub enum OperationAssign {
Assign(Assign),
AddAssign(AddAssign),
SubAssign(SubAssign),
MulAssign(MulAssign),
DivAssign(DivAssign),
PowAssign(PowAssign),
}
// Types
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_u8))]
pub struct U8Type {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_u16))]
pub struct U16Type {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_u32))]
pub struct U32Type {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_u64))]
pub struct U64Type {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_u128))]
pub struct U128Type {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_integer))]
pub enum IntegerType {
U8Type(U8Type),
U16Type(U16Type),
U32Type(U32Type),
U64Type(U64Type),
U128Type(U128Type),
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_field))]
pub struct FieldType {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_group))]
pub struct GroupType {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_bool))]
pub struct BooleanType {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_circuit))]
pub struct CircuitType<'ast> {
pub identifier: Identifier<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_self))]
pub struct SelfType {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_basic))]
pub enum BasicType {
Integer(IntegerType),
Field(FieldType),
Group(GroupType),
Boolean(BooleanType),
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_array))]
pub struct ArrayType<'ast> {
pub _type: BasicType,
pub dimensions: Vec<Value<'ast>>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::_type))]
pub enum Type<'ast> {
Basic(BasicType),
Basic(DataType),
Array(ArrayType<'ast>),
Circuit(CircuitType<'ast>),
SelfType(SelfType),
@ -233,70 +73,12 @@ impl<'ast> fmt::Display for Type<'ast> {
}
// 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_implicit))]
pub struct NumberImplicit<'ast> {
pub number: Number<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
impl<'ast> fmt::Display for NumberImplicit<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.number)
}
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::value_integer))]
pub struct Integer<'ast> {
pub number: Number<'ast>,
pub _type: IntegerType,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
impl<'ast> fmt::Display for Integer<'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 _type: FieldType,
#[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::group_tuple))]
pub struct GroupTuple<'ast> {
pub x: Number<'ast>,
pub y: Number<'ast>,
pub x: NumberValue<'ast>,
pub y: NumberValue<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
@ -310,7 +92,7 @@ impl<'ast> fmt::Display for GroupTuple<'ast> {
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::group_single_or_tuple))]
pub enum GroupValue<'ast> {
Single(Number<'ast>),
Single(NumberValue<'ast>),
Tuple(GroupTuple<'ast>),
}
@ -353,39 +135,7 @@ impl<'ast> fmt::Display for Boolean<'ast> {
}
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::value))]
pub enum Value<'ast> {
Integer(Integer<'ast>),
Field(Field<'ast>),
Group(Group<'ast>),
Boolean(Boolean<'ast>),
Implicit(NumberImplicit<'ast>),
}
impl<'ast> Value<'ast> {
pub fn span(&self) -> &Span<'ast> {
match self {
Value::Integer(value) => &value.span,
Value::Field(value) => &value.span,
Value::Group(value) => &value.span,
Value::Boolean(value) => &value.span,
Value::Implicit(value) => &value.span,
}
}
}
impl<'ast> fmt::Display for Value<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Value::Integer(ref value) => write!(f, "{}", value),
Value::Field(ref value) => write!(f, "{}", value),
Value::Group(ref value) => write!(f, "{}", value),
Value::Boolean(ref value) => write!(f, "{}", value),
Value::Implicit(ref value) => write!(f, "{}", value),
}
}
}
// Variables + Mutability
@ -667,7 +417,7 @@ pub struct CircuitInlineExpression<'ast> {
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::expression_not))]
pub struct NotExpression<'ast> {
pub operation: Not<'ast>,
pub operation: NotOperation<'ast>,
pub expression: Box<Expression<'ast>>,
#[pest_ast(outer())]
pub span: Span<'ast>,
@ -691,7 +441,7 @@ pub struct NotExpression<'ast> {
#[derive(Clone, Debug, PartialEq)]
pub struct BinaryExpression<'ast> {
pub operation: BinaryOperator,
pub operation: BinaryOperation,
pub left: Box<Expression<'ast>>,
pub right: Box<Expression<'ast>>,
pub span: Span<'ast>,
@ -724,7 +474,7 @@ pub enum Expression<'ast> {
impl<'ast> Expression<'ast> {
pub fn binary(
operation: BinaryOperator,
operation: BinaryOperation,
left: Box<Expression<'ast>>,
right: Box<Expression<'ast>>,
span: Span<'ast>,
@ -857,7 +607,7 @@ fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
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::operation_not => NotOperation::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());
@ -925,19 +675,19 @@ fn binary_expression<'ast>(
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_ne => Expression::binary(BinaryOperator::Ne, lhs, rhs, span),
Rule::operation_ge => Expression::binary(BinaryOperator::Ge, lhs, rhs, span),
Rule::operation_gt => Expression::binary(BinaryOperator::Gt, lhs, rhs, span),
Rule::operation_le => Expression::binary(BinaryOperator::Le, 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),
Rule::operation_or => Expression::binary(BinaryOperation::Or, lhs, rhs, span),
Rule::operation_and => Expression::binary(BinaryOperation::And, lhs, rhs, span),
Rule::operation_eq => Expression::binary(BinaryOperation::Eq, lhs, rhs, span),
Rule::operation_ne => Expression::binary(BinaryOperation::Ne, lhs, rhs, span),
Rule::operation_ge => Expression::binary(BinaryOperation::Ge, lhs, rhs, span),
Rule::operation_gt => Expression::binary(BinaryOperation::Gt, lhs, rhs, span),
Rule::operation_le => Expression::binary(BinaryOperation::Le, lhs, rhs, span),
Rule::operation_lt => Expression::binary(BinaryOperation::Lt, lhs, rhs, span),
Rule::operation_add => Expression::binary(BinaryOperation::Add, lhs, rhs, span),
Rule::operation_sub => Expression::binary(BinaryOperation::Sub, lhs, rhs, span),
Rule::operation_mul => Expression::binary(BinaryOperation::Mul, lhs, rhs, span),
Rule::operation_div => Expression::binary(BinaryOperation::Div, lhs, rhs, span),
Rule::operation_pow => Expression::binary(BinaryOperation::Pow, lhs, rhs, span),
_ => unreachable!(),
})
}
@ -987,16 +737,6 @@ pub struct ConditionalStatement<'ast> {
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::statement_for))]
pub struct ForStatement<'ast> {
pub index: Identifier<'ast>,
pub start: Expression<'ast>,
pub stop: Expression<'ast>,
pub statements: Vec<Statement<'ast>>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::statement_multiple_assignment))]
@ -1023,7 +763,7 @@ pub struct DefinitionStatement<'ast> {
#[pest_ast(rule(Rule::statement_assign))]
pub struct AssignStatement<'ast> {
pub assignee: Assignee<'ast>,
pub assign: OperationAssign,
pub assign: AssignOperation,
pub expression: Expression<'ast>,
pub line_end: LineEnd,
#[pest_ast(outer())]

View File

@ -1,37 +1,32 @@
/// Identifiers
protected_name = { visibility | "let" | "for"| "if" | "else" | "as" | "return" }
// Declared in types/identifier.rs
identifier = @{ ((!protected_name ~ ASCII_ALPHA) | (protected_name ~ (ASCII_ALPHANUMERIC | "_"))) ~ (ASCII_ALPHANUMERIC | "_")* }
protected_name = { visibility | "let" | "for"| "if" | "else" | "as" | "return" }
/// Visibility
// Declared in types/visibility.rs
visibility = { visibility_public | visibility_private }
visibility_public = { "public" }
visibility_private = { "private" }
visibility = { visibility_public | visibility_private }
/// Unary Operations
operation_pre_not = { "!" }
expression_not = { operation_pre_not ~ expression_term }
// expression_increment = { expression+ ~ "++" }
//
// expression_decrement = { expression ~ "--" }
// Declared in operations/not_operation.rs
operation_not = { "!" }
/// Binary Operations
// Declared in operations/binary_operation.rs
operation_and = { "&&" }
operation_or = { "||" }
operation_eq = { "==" }
operation_ne = { "!=" }
operation_ge = { ">=" }
operation_gt = { ">" }
operation_le = { "<=" }
operation_lt = { "<" }
operation_add = { "+" }
operation_sub = { "-" }
operation_mul = { "*" }
@ -43,12 +38,16 @@ operation_compare = _{
operation_ge | operation_gt |
operation_le | operation_lt
}
operation_binary = _{
operation_compare | operation_and | operation_or |
operation_add | operation_sub | operation_pow | operation_mul | operation_div
}
// Declared in operations/assign_operation.rs
operation_assign = {
assign | operation_add_assign | operation_sub_assign |
operation_mul_assign | operation_div_assign | operation_pow_assign
}
assign = { "=" }
operation_add_assign = { "+=" }
operation_sub_assign = { "-=" }
@ -56,18 +55,9 @@ operation_mul_assign = { "*=" }
operation_div_assign = { "/=" }
operation_pow_assign = { "**=" }
operation_assign = {
assign | operation_add_assign | operation_sub_assign |
operation_mul_assign | operation_div_assign | operation_pow_assign
}
/// Types
type_u8 = {"u8"}
type_u16 = {"u16"}
type_u32 = {"u32"}
type_u64 = {"u64"}
type_u128 = {"u128"}
// Declared in types/integer.rs
type_integer = {
type_u8
| type_u16
@ -75,22 +65,48 @@ type_integer = {
| type_u64
| type_u128
}
type_u8 = { "u8" }
type_u16 = { "u16" }
type_u32 = { "u32" }
type_u64 = { "u64" }
type_u128 = { "u128" }
type_field = {"field"}
type_group = {"group"}
type_bool = {"bool"}
type_self = {"Self"}
type_basic = { type_field | type_group | type_bool | type_integer }
// Declared in types/field_type.rs
type_field = { "field" }
// Declared in types/group_type.rs
type_group = { "group" }
// Declared in types/boolean_type.rs
type_boolean = { "bool" }
// Declared in types/data_type.rs
type_data = { type_field | type_group | type_boolean | type_integer }
// Declared in types/self_type.rs
type_self = { "Self" }
// Declared in types/self_type.rs
type_circuit = { identifier }
type_array = {type_basic ~ ("[" ~ value ~ "]")+ }
_type = {type_self | type_array | type_basic | type_circuit}
// Declared in types/array_type.rs
type_array = { type_data ~ ("[" ~ value ~ "]")+ }
_type = {type_self | type_array | type_data | type_circuit}
type_list = _{(_type ~ ("," ~ _type)*)?}
/// Values
// Declared in values/number_value.rs
value_number = @{ "0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* }
// Declared in values/number_implicit_value.rs
value_implicit = { value_number }
// Declared in values/integer_value.rs
value_integer = { value_number ~ type_integer }
// Declared in values/field_value.rs
value_field = { value_number ~ type_field }
group_tuple = {"(" ~ value_number ~ "," ~ value_number ~ ")"}
@ -167,6 +183,7 @@ expression_term = {
| expression_array_inline
| expression_array_initializer
}
expression_not = { operation_not ~ expression_term }
expression = { expression_term ~ (operation_binary ~ expression_term)* }
expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
@ -180,12 +197,17 @@ assert_eq = {"assert_eq!" ~ "(" ~ NEWLINE* ~ expression ~ "," ~ NEWLINE* ~ expre
conditional_nested_or_end = { statement_conditional | "{" ~ NEWLINE* ~ statement+ ~ "}"}
/// Statements
statement_return = { "return" ~ expression_tuple }
statement_definition = { "let" ~ variable ~ "=" ~ expression ~ LINE_END}
statement_assign = { assignee ~ operation_assign ~ expression ~ LINE_END}
statement_multiple_assignment = { "let" ~ "(" ~ variable_tuple ~ ")" ~ "=" ~ identifier ~ "(" ~ expression_tuple ~ ")" ~ LINE_END}
statement_conditional = {"if" ~ (expression | "(" ~ expression ~ ")") ~ "{" ~ NEWLINE* ~ statement+ ~ "}" ~ ("else" ~ conditional_nested_or_end)?}
// Declared in types/for_statement.rs
statement_for = { "for" ~ identifier ~ "in" ~ expression ~ ".." ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}"}
statement_assert = {
assert_eq
// | assert_true |

View File

@ -10,3 +10,12 @@ pub use ast::*;
pub mod errors;
pub use errors::*;
pub mod operations;
pub use operations::*;
pub mod values;
pub use values::*;
pub mod types;
pub use types::*;

View File

@ -0,0 +1,38 @@
use crate::ast::Rule;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_assign))]
pub enum AssignOperation {
Assign(Assign),
AddAssign(AddAssign),
SubAssign(SubAssign),
MulAssign(MulAssign),
DivAssign(DivAssign),
PowAssign(PowAssign),
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::assign))]
pub struct Assign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_add_assign))]
pub struct AddAssign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_sub_assign))]
pub struct SubAssign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_mul_assign))]
pub struct MulAssign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_div_assign))]
pub struct DivAssign {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_pow_assign))]
pub struct PowAssign {}

View File

@ -0,0 +1,21 @@
use crate::ast::Rule;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_binary))]
pub enum BinaryOperation {
Or,
And,
Eq,
Ne,
Ge,
Gt,
Le,
Lt,
Add,
Sub,
Mul,
Div,
Pow,
}

View File

@ -0,0 +1,8 @@
pub mod assign_operation;
pub use assign_operation::*;
pub mod binary_operation;
pub use binary_operation::*;
pub mod not_operation;
pub use not_operation::*;

View File

@ -0,0 +1,11 @@
use crate::ast::Rule;
use pest::Span;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::operation_not))]
pub struct NotOperation<'ast> {
#[pest_ast(outer())]
pub span: Span<'ast>,
}

View File

@ -0,0 +1,13 @@
use crate::{ast::Rule, types::DataType, values::Value};
use pest::Span;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_array))]
pub struct ArrayType<'ast> {
pub _type: DataType,
pub dimensions: Vec<Value<'ast>>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}

View File

@ -0,0 +1,7 @@
use crate::ast::Rule;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_boolean))]
pub struct BooleanType {}

View File

@ -0,0 +1,12 @@
use crate::{ast::Rule, types::Identifier};
use pest::Span;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_circuit))]
pub struct CircuitType<'ast> {
pub identifier: Identifier<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}

View File

@ -0,0 +1,12 @@
use crate::{ast::Rule, types::{IntegerType, FieldType, GroupType, BooleanType}};
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_data))]
pub enum DataType {
Integer(IntegerType),
Field(FieldType),
Group(GroupType),
Boolean(BooleanType),
}

View File

@ -0,0 +1,7 @@
use crate::ast::Rule;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_field))]
pub struct FieldType {}

View File

@ -1,3 +1,8 @@
use crate::{ast::{Expression, Statement, Rule}, types::Identifier};
use pest::Span;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::statement_for))]
pub struct ForStatement<'ast> {
@ -7,4 +12,4 @@ pub struct ForStatement<'ast> {
pub statements: Vec<Statement<'ast>>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
}

View File

@ -0,0 +1,7 @@
use crate::ast::Rule;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_group))]
pub struct GroupType {}

View File

@ -0,0 +1,20 @@
use crate::ast::{span_into_string, Rule};
use pest::Span;
use pest_ast::FromPest;
use std::fmt;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::identifier))]
pub struct Identifier<'ast> {
#[pest_ast(outer(with(span_into_string)))]
pub value: String,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
impl<'ast> fmt::Display for Identifier<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value)
}
}

View File

@ -0,0 +1,33 @@
use crate::ast::Rule;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_integer))]
pub enum IntegerType {
U8Type(U8Type),
U16Type(U16Type),
U32Type(U32Type),
U64Type(U64Type),
U128Type(U128Type),
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_u8))]
pub struct U8Type {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_u16))]
pub struct U16Type {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_u32))]
pub struct U32Type {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_u64))]
pub struct U64Type {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_u128))]
pub struct U128Type {}

32
ast/src/types/mod.rs Normal file
View File

@ -0,0 +1,32 @@
pub mod array_type;
pub use array_type::*;
pub mod boolean_type;
pub use boolean_type::*;
pub mod circuit_type;
pub use circuit_type::*;
pub mod data_type;
pub use data_type::*;
pub mod field_type;
pub use field_type::*;
pub mod group_type;
pub use group_type::*;
pub mod for_statement;
pub use for_statement::*;
pub mod identifier;
pub use identifier::*;
pub mod integer_type;
pub use integer_type::*;
pub mod self_type;
pub use self_type::*;
pub mod visibility;
pub use visibility::*;

View File

@ -0,0 +1,7 @@
use crate::ast::Rule;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_self))]
pub struct SelfType {}

View File

@ -0,0 +1,18 @@
use crate::ast::Rule;
use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::visibility))]
pub enum Visibility {
Public(Public),
Private(Private),
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::visibility_public))]
pub struct Public {}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::visibility_private))]
pub struct Private {}

View File

@ -0,0 +1,20 @@
use crate::{ast::Rule, types::FieldType, values::NumberValue,};
use pest::Span;
use pest_ast::FromPest;
use std::fmt;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::value_field))]
pub struct FieldValue<'ast> {
pub number: NumberValue<'ast>,
pub _type: FieldType,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
impl<'ast> fmt::Display for FieldValue<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.number)
}
}

View File

@ -0,0 +1,20 @@
use crate::{ast::Rule, types::IntegerType, values::NumberValue};
use pest::Span;
use pest_ast::FromPest;
use std::fmt;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::value_integer))]
pub struct IntegerValue<'ast> {
pub number: NumberValue<'ast>,
pub _type: IntegerType,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
impl<'ast> fmt::Display for IntegerValue<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.number)
}
}

14
ast/src/values/mod.rs Normal file
View File

@ -0,0 +1,14 @@
pub mod field_value;
pub use field_value::*;
pub mod integer_value;
pub use integer_value::*;
pub mod number_implicit_value;
pub use number_implicit_value::*;
pub mod number_value;
pub use number_value::*;
pub mod value;
pub use value::*;

View File

@ -0,0 +1,19 @@
use crate::{ast::Rule, values::NumberValue};
use pest::Span;
use pest_ast::FromPest;
use std::fmt;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::value_implicit))]
pub struct NumberImplicitValue<'ast> {
pub number: NumberValue<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
impl<'ast> fmt::Display for NumberImplicitValue<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.number)
}
}

View File

@ -0,0 +1,20 @@
use crate::ast::{Rule, span_into_string};
use pest::Span;
use pest_ast::FromPest;
use std::fmt;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::value_number))]
pub struct NumberValue<'ast> {
#[pest_ast(outer(with(span_into_string)))]
pub value: String,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
impl<'ast> fmt::Display for NumberValue<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value)
}
}

39
ast/src/values/value.rs Normal file
View File

@ -0,0 +1,39 @@
use crate::{ast::{Group, Boolean, Rule}, values::{IntegerValue, FieldValue, NumberImplicitValue}};
use pest::Span;
use pest_ast::FromPest;
use std::fmt;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::value))]
pub enum Value<'ast> {
Integer(IntegerValue<'ast>),
Field(FieldValue<'ast>),
Group(Group<'ast>),
Boolean(Boolean<'ast>),
Implicit(NumberImplicitValue<'ast>),
}
impl<'ast> Value<'ast> {
pub fn span(&self) -> &Span<'ast> {
match self {
Value::Integer(value) => &value.span,
Value::Field(value) => &value.span,
Value::Group(value) => &value.span,
Value::Boolean(value) => &value.span,
Value::Implicit(value) => &value.span,
}
}
}
impl<'ast> fmt::Display for Value<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Value::Integer(ref value) => write!(f, "{}", value),
Value::Field(ref value) => write!(f, "{}", value),
Value::Group(ref value) => write!(f, "{}", value),
Value::Boolean(ref value) => write!(f, "{}", value),
Value::Implicit(ref value) => write!(f, "{}", value),
}
}
}

View File

@ -1,7 +1,30 @@
//! Logic to convert from an abstract syntax tree (ast) representation to a Leo program.
use crate::{types, Import, ImportSymbol};
use leo_ast::ast;
use leo_ast::{
ast,
operations::{
AssignOperation,
BinaryOperation,
},
types::{
ArrayType,
CircuitType,
DataType,
ForStatement,
Identifier,
IntegerType,
Visibility,
Private,
},
values::{
FieldValue,
IntegerValue,
NumberValue,
NumberImplicitValue,
Value
}
};
use snarkos_models::gadgets::utilities::{
boolean::Boolean,
@ -11,14 +34,14 @@ use std::collections::HashMap;
/// pest ast -> types::Identifier
impl<'ast> From<ast::Identifier<'ast>> for types::Identifier {
fn from(identifier: ast::Identifier<'ast>) -> Self {
impl<'ast> From<Identifier<'ast>> for types::Identifier {
fn from(identifier: Identifier<'ast>) -> Self {
types::Identifier::new(identifier.value)
}
}
impl<'ast> From<ast::Identifier<'ast>> for types::Expression {
fn from(identifier: ast::Identifier<'ast>) -> Self {
impl<'ast> From<Identifier<'ast>> for types::Expression {
fn from(identifier: Identifier<'ast>) -> Self {
types::Expression::Identifier(types::Identifier::from(identifier))
}
}
@ -38,24 +61,24 @@ impl<'ast> From<ast::Variable<'ast>> for types::Variable {
/// pest ast - types::Integer
impl<'ast> types::Integer {
pub(crate) fn from(number: ast::Number<'ast>, _type: ast::IntegerType) -> Self {
pub(crate) fn from(number: NumberValue<'ast>, _type: IntegerType) -> Self {
match _type {
ast::IntegerType::U8Type(_u8) => types::Integer::U8(UInt8::constant(
IntegerType::U8Type(_u8) => types::Integer::U8(UInt8::constant(
number.value.parse::<u8>().expect("unable to parse u8"),
)),
ast::IntegerType::U16Type(_u16) => types::Integer::U16(UInt16::constant(
IntegerType::U16Type(_u16) => types::Integer::U16(UInt16::constant(
number.value.parse::<u16>().expect("unable to parse u16"),
)),
ast::IntegerType::U32Type(_u32) => types::Integer::U32(UInt32::constant(
IntegerType::U32Type(_u32) => types::Integer::U32(UInt32::constant(
number
.value
.parse::<u32>()
.expect("unable to parse integers.u32"),
)),
ast::IntegerType::U64Type(_u64) => types::Integer::U64(UInt64::constant(
IntegerType::U64Type(_u64) => types::Integer::U64(UInt64::constant(
number.value.parse::<u64>().expect("unable to parse u64"),
)),
ast::IntegerType::U128Type(_u128) => types::Integer::U128(UInt128::constant(
IntegerType::U128Type(_u128) => types::Integer::U128(UInt128::constant(
number.value.parse::<u128>().expect("unable to parse u128"),
)),
}
@ -68,8 +91,8 @@ impl<'ast> types::Integer {
}
}
impl<'ast> From<ast::Integer<'ast>> for types::Expression {
fn from(field: ast::Integer<'ast>) -> Self {
impl<'ast> From<IntegerValue<'ast>> for types::Expression {
fn from(field: IntegerValue<'ast>) -> Self {
types::Expression::Integer(types::Integer::from(field.number, field._type))
}
}
@ -108,8 +131,8 @@ impl<'ast> From<ast::RangeOrExpression<'ast>> for types::RangeOrExpression {
/// pest ast -> types::Field
impl<'ast> From<ast::Field<'ast>> for types::Expression {
fn from(field: ast::Field<'ast>) -> Self {
impl<'ast> From<FieldValue<'ast>> for types::Expression {
fn from(field: FieldValue<'ast>) -> Self {
types::Expression::Field(field.number.value)
}
}
@ -137,22 +160,22 @@ impl<'ast> From<ast::Boolean<'ast>> for types::Expression {
/// pest ast -> types::NumberImplicit
impl<'ast> From<ast::NumberImplicit<'ast>> for types::Expression {
fn from(number: ast::NumberImplicit<'ast>) -> Self {
impl<'ast> From<NumberImplicitValue<'ast>> for types::Expression {
fn from(number: NumberImplicitValue<'ast>) -> Self {
types::Expression::Implicit(number.number.value)
}
}
/// pest ast -> types::Expression
impl<'ast> From<ast::Value<'ast>> for types::Expression {
fn from(value: ast::Value<'ast>) -> Self {
impl<'ast> From<Value<'ast>> for types::Expression {
fn from(value: Value<'ast>) -> Self {
match value {
ast::Value::Integer(num) => types::Expression::from(num),
ast::Value::Field(field) => types::Expression::from(field),
ast::Value::Group(group) => types::Expression::from(group),
ast::Value::Boolean(bool) => types::Expression::from(bool),
ast::Value::Implicit(value) => types::Expression::from(value),
Value::Integer(num) => types::Expression::from(num),
Value::Field(field) => types::Expression::from(field),
Value::Group(group) => types::Expression::from(group),
Value::Boolean(bool) => types::Expression::from(bool),
Value::Implicit(value) => types::Expression::from(value),
}
}
}
@ -180,55 +203,55 @@ impl<'ast> From<ast::BinaryExpression<'ast>> for types::Expression {
fn from(expression: ast::BinaryExpression<'ast>) -> Self {
match expression.operation {
// Boolean operations
ast::BinaryOperator::Or => types::Expression::Or(
BinaryOperation::Or => types::Expression::Or(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
ast::BinaryOperator::And => types::Expression::And(
BinaryOperation::And => types::Expression::And(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
ast::BinaryOperator::Eq => types::Expression::Eq(
BinaryOperation::Eq => types::Expression::Eq(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
ast::BinaryOperator::Ne => {
BinaryOperation::Ne => {
types::Expression::Not(Box::new(types::Expression::from(expression)))
}
ast::BinaryOperator::Ge => types::Expression::Ge(
BinaryOperation::Ge => types::Expression::Ge(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
ast::BinaryOperator::Gt => types::Expression::Gt(
BinaryOperation::Gt => types::Expression::Gt(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
ast::BinaryOperator::Le => types::Expression::Le(
BinaryOperation::Le => types::Expression::Le(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
ast::BinaryOperator::Lt => types::Expression::Lt(
BinaryOperation::Lt => types::Expression::Lt(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
// Number operations
ast::BinaryOperator::Add => types::Expression::Add(
BinaryOperation::Add => types::Expression::Add(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
ast::BinaryOperator::Sub => types::Expression::Sub(
BinaryOperation::Sub => types::Expression::Sub(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
ast::BinaryOperator::Mul => types::Expression::Mul(
BinaryOperation::Mul => types::Expression::Mul(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
ast::BinaryOperator::Div => types::Expression::Div(
BinaryOperation::Div => types::Expression::Div(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
ast::BinaryOperator::Pow => types::Expression::Pow(
BinaryOperation::Pow => types::Expression::Pow(
Box::new(types::Expression::from(*expression.left)),
Box::new(types::Expression::from(*expression.right)),
),
@ -349,14 +372,14 @@ impl<'ast> From<ast::Expression<'ast>> for types::Expression {
}
impl<'ast> types::Expression {
fn get_count(count: ast::Value<'ast>) -> usize {
fn get_count(count: Value<'ast>) -> usize {
match count {
ast::Value::Integer(integer) => integer
Value::Integer(integer) => integer
.number
.value
.parse::<usize>()
.expect("Unable to read array size"),
ast::Value::Implicit(number) => number
Value::Implicit(number) => number
.number
.value
.parse::<usize>()
@ -392,8 +415,8 @@ impl<'ast> From<ast::Assignee<'ast>> for types::Expression {
/// pest ast -> types::Assignee
impl<'ast> From<ast::Identifier<'ast>> for types::Assignee {
fn from(variable: ast::Identifier<'ast>) -> Self {
impl<'ast> From<Identifier<'ast>> for types::Assignee {
fn from(variable: Identifier<'ast>) -> Self {
types::Assignee::Identifier(types::Identifier::from(variable))
}
}
@ -445,7 +468,7 @@ impl<'ast> From<ast::DefinitionStatement<'ast>> for types::Statement {
impl<'ast> From<ast::AssignStatement<'ast>> for types::Statement {
fn from(statement: ast::AssignStatement<'ast>) -> Self {
match statement.assign {
ast::OperationAssign::Assign(ref _assign) => types::Statement::Assign(
AssignOperation::Assign(ref _assign) => types::Statement::Assign(
types::Assignee::from(statement.assignee),
types::Expression::from(statement.expression),
),
@ -454,42 +477,42 @@ impl<'ast> From<ast::AssignStatement<'ast>> for types::Statement {
let converted = types::Expression::from(statement.assignee.clone());
match operation_assign {
ast::OperationAssign::AddAssign(ref _assign) => types::Statement::Assign(
AssignOperation::AddAssign(ref _assign) => types::Statement::Assign(
types::Assignee::from(statement.assignee),
types::Expression::Add(
Box::new(converted),
Box::new(types::Expression::from(statement.expression)),
),
),
ast::OperationAssign::SubAssign(ref _assign) => types::Statement::Assign(
AssignOperation::SubAssign(ref _assign) => types::Statement::Assign(
types::Assignee::from(statement.assignee),
types::Expression::Sub(
Box::new(converted),
Box::new(types::Expression::from(statement.expression)),
),
),
ast::OperationAssign::MulAssign(ref _assign) => types::Statement::Assign(
AssignOperation::MulAssign(ref _assign) => types::Statement::Assign(
types::Assignee::from(statement.assignee),
types::Expression::Mul(
Box::new(converted),
Box::new(types::Expression::from(statement.expression)),
),
),
ast::OperationAssign::DivAssign(ref _assign) => types::Statement::Assign(
AssignOperation::DivAssign(ref _assign) => types::Statement::Assign(
types::Assignee::from(statement.assignee),
types::Expression::Div(
Box::new(converted),
Box::new(types::Expression::from(statement.expression)),
),
),
ast::OperationAssign::PowAssign(ref _assign) => types::Statement::Assign(
AssignOperation::PowAssign(ref _assign) => types::Statement::Assign(
types::Assignee::from(statement.assignee),
types::Expression::Pow(
Box::new(converted),
Box::new(types::Expression::from(statement.expression)),
),
),
ast::OperationAssign::Assign(ref _assign) => {
AssignOperation::Assign(ref _assign) => {
unimplemented!("cannot assign twice to assign statement")
}
}
@ -553,8 +576,8 @@ impl<'ast> From<ast::ConditionalStatement<'ast>> for types::ConditionalStatement
}
}
impl<'ast> From<ast::ForStatement<'ast>> for types::Statement {
fn from(statement: ast::ForStatement<'ast>) -> Self {
impl<'ast> From<ForStatement<'ast>> for types::Statement {
fn from(statement: ForStatement<'ast>) -> Self {
let from = match types::Expression::from(statement.start) {
types::Expression::Integer(number) => number,
types::Expression::Implicit(string) => types::Integer::from_implicit(string),
@ -615,33 +638,33 @@ impl<'ast> From<ast::Statement<'ast>> for types::Statement {
/// pest ast -> Explicit types::Type for defining circuit members and function params
impl From<ast::IntegerType> for types::IntegerType {
fn from(integer_type: ast::IntegerType) -> Self {
impl From<IntegerType> for types::IntegerType {
fn from(integer_type: IntegerType) -> Self {
match integer_type {
ast::IntegerType::U8Type(_type) => types::IntegerType::U8,
ast::IntegerType::U16Type(_type) => types::IntegerType::U16,
ast::IntegerType::U32Type(_type) => types::IntegerType::U32,
ast::IntegerType::U64Type(_type) => types::IntegerType::U64,
ast::IntegerType::U128Type(_type) => types::IntegerType::U128,
IntegerType::U8Type(_type) => types::IntegerType::U8,
IntegerType::U16Type(_type) => types::IntegerType::U16,
IntegerType::U32Type(_type) => types::IntegerType::U32,
IntegerType::U64Type(_type) => types::IntegerType::U64,
IntegerType::U128Type(_type) => types::IntegerType::U128,
}
}
}
impl From<ast::BasicType> for types::Type {
fn from(basic_type: ast::BasicType) -> Self {
impl From<DataType> for types::Type {
fn from(basic_type: DataType) -> Self {
match basic_type {
ast::BasicType::Integer(_type) => {
DataType::Integer(_type) => {
types::Type::IntegerType(types::IntegerType::from(_type))
}
ast::BasicType::Field(_type) => types::Type::Field,
ast::BasicType::Group(_type) => types::Type::Group,
ast::BasicType::Boolean(_type) => types::Type::Boolean,
DataType::Field(_type) => types::Type::Field,
DataType::Group(_type) => types::Type::Group,
DataType::Boolean(_type) => types::Type::Boolean,
}
}
}
impl<'ast> From<ast::ArrayType<'ast>> for types::Type {
fn from(array_type: ast::ArrayType<'ast>) -> Self {
impl<'ast> From<ArrayType<'ast>> for types::Type {
fn from(array_type: ArrayType<'ast>) -> Self {
let element_type = Box::new(types::Type::from(array_type._type));
let dimensions = array_type
.dimensions
@ -653,8 +676,8 @@ impl<'ast> From<ast::ArrayType<'ast>> for types::Type {
}
}
impl<'ast> From<ast::CircuitType<'ast>> for types::Type {
fn from(circuit_type: ast::CircuitType<'ast>) -> Self {
impl<'ast> From<CircuitType<'ast>> for types::Type {
fn from(circuit_type: CircuitType<'ast>) -> Self {
types::Type::Circuit(types::Identifier::from(circuit_type.identifier))
}
}
@ -728,7 +751,7 @@ impl<'ast> From<ast::InputModel<'ast>> for types::InputModel {
mutable: parameter.mutable.is_some(),
// private by default
private: parameter.visibility.map_or(true, |visibility| {
visibility.eq(&ast::Visibility::Private(ast::Private {}))
visibility.eq(&Visibility::Private(Private {}))
}),
_type: types::Type::from(parameter._type),
}