program structs

This commit is contained in:
collin 2020-04-13 17:21:09 -07:00
parent 940806ec50
commit 1903858e7a
6 changed files with 172 additions and 62 deletions

View File

@ -1,4 +1,5 @@
for field i in 0..4 do
a = 1 + 1
endfor
struct Foo {
field a
bool b
}
return 1

View File

@ -89,10 +89,31 @@ pub enum Statement {
Return(Vec<Expression>),
}
#[derive(Clone, Debug)]
pub enum Type {
FieldElement,
Boolean,
Array(Box<Type>, usize),
Struct(Variable),
}
#[derive(Clone)]
pub struct StructField {
pub variable: Variable,
pub ty: Type,
}
#[derive(Clone)]
pub struct Struct {
pub variable: Variable,
pub fields: Vec<StructField>,
}
/// A simple program with statement expressions, program arguments and program returns.
#[derive(Debug, Clone)]
pub struct Program {
pub id: String,
pub structs: Vec<Struct>,
pub statements: Vec<Statement>,
pub arguments: Vec<Variable>,
pub returns: Vec<Variable>,
@ -150,21 +171,21 @@ mod tests {
//
// println!("{:#?}", program);
// }
#[test]
fn test_basic_prog() {
// return 1 == 1
let prog = Program {
id: "main".into(),
statements: vec![Statement::Return(vec![Expression::Boolean(
BooleanExpression::FieldEq(
Box::new(FieldExpression::Number(1)),
Box::new(FieldExpression::Number(1)),
),
)])],
arguments: vec![],
returns: vec![],
};
println!("{:#?}", prog);
}
// #[test]
// fn test_basic_prog() {
// // return 1 == 1
// let prog = Program {
// id: "main".into(),
// statements: vec![Statement::Return(vec![Expression::Boolean(
// BooleanExpression::FieldEq(
// Box::new(FieldExpression::Number(1)),
// Box::new(FieldExpression::Number(1)),
// ),
// )])],
// arguments: vec![],
// returns: vec![],
// };
//
// println!("{:#?}", prog);
// }
}

View File

@ -4,7 +4,9 @@
//! @author Collin Chin <collin@aleo.org>
//! @date 2020
use crate::aleo_program::{BooleanExpression, Expression, FieldExpression, Statement, Variable};
use crate::aleo_program::{
BooleanExpression, Expression, FieldExpression, Statement, Struct, StructField, Type, Variable,
};
use std::fmt;
@ -91,3 +93,30 @@ impl fmt::Debug for Statement {
}
}
}
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
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 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} : {}", self.ty, self.variable)
}
}
impl fmt::Debug for Struct {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "struct {} {{ \n", self.variable)?;
for field in self.fields.iter() {
write!(f, " {}\n", field)?;
}
write!(f, "}}")
}
}

View File

@ -338,12 +338,75 @@ impl<'ast> From<ast::Statement<'ast>> for types::Statement {
}
}
impl<'ast> From<ast::BasicType<'ast>> for types::Type {
fn from(basic_type: ast::BasicType<'ast>) -> Self {
match basic_type {
ast::BasicType::Field(ty) => types::Type::FieldElement,
ast::BasicType::Boolean(ty) => types::Type::Boolean,
}
}
}
impl<'ast> From<ast::ArrayType<'ast>> for types::Type {
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"),
_ => unimplemented!("Array size should be an integer"),
};
types::Type::Array(element_type, count)
}
}
impl<'ast> From<ast::StructType<'ast>> for types::Type {
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 {
fn from(ty: ast::Type<'ast>) -> Self {
match ty {
ast::Type::Basic(ty) => types::Type::from(ty),
ast::Type::Array(ty) => types::Type::from(ty),
ast::Type::Struct(ty) => types::Type::from(ty),
}
}
}
impl<'ast> From<ast::StructField<'ast>> for types::StructField {
fn from(struct_field: ast::StructField<'ast>) -> Self {
types::StructField {
variable: types::Variable::from(struct_field.variable),
ty: types::Type::from(struct_field.ty),
}
}
}
impl<'ast> From<ast::Struct<'ast>> for types::Struct {
fn from(struct_definition: ast::Struct<'ast>) -> Self {
let variable = types::Variable::from(struct_definition.variable);
let fields = struct_definition
.fields
.into_iter()
.map(|struct_field| types::StructField::from(struct_field))
.collect();
types::Struct { variable, fields }
}
}
impl<'ast> From<ast::File<'ast>> for types::Program {
fn from(file: ast::File<'ast>) -> Self {
// 1. compile ast -> aleo program representation
file.structs
let structs = file
.structs
.into_iter()
.for_each(|struct_def| println!("{:#?}", struct_def));
.map(|struct_def| {
println!("{:#?}", struct_def);
types::Struct::from(struct_def)
})
.collect();
file.functions
.into_iter()
.for_each(|function_def| println!("{:#?}", function_def));
@ -355,6 +418,7 @@ impl<'ast> From<ast::File<'ast>> for types::Program {
types::Program {
id: "main".into(),
structs,
statements,
arguments: vec![],
returns: vec![],

View File

@ -170,21 +170,21 @@ fn binary_expression<'ast>(
// Types
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::ty_bool))]
pub struct BooleanType<'ast> {
#[pest_ast(outer())]
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::ty_field))]
pub struct FieldType<'ast> {
#[pest_ast(outer())]
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::ty_struct))]
pub struct StructType<'ast> {
pub variable: Variable<'ast>,
@ -192,30 +192,30 @@ pub struct StructType<'ast> {
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::ty_basic))]
pub enum BasicType<'ast> {
Field(FieldType<'ast>),
Boolean(BooleanType<'ast>),
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::ty_basic_or_struct))]
pub enum BasicOrStructType<'ast> {
Struct(StructType<'ast>),
Basic(BasicType<'ast>),
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::ty_array))]
pub struct ArrayType<'ast> {
pub ty: BasicType<'ast>,
pub dimensions: Vec<Expression<'ast>>,
pub count: Value<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::ty))]
pub enum Type<'ast> {
Basic(BasicType<'ast>),
@ -275,7 +275,7 @@ pub struct Decrement<'ast> {
// Binary Operations
#[derive(Debug, PartialEq, Clone)]
#[derive(Clone, Debug, PartialEq)]
pub enum BinaryOperator {
Or,
And,
@ -368,15 +368,15 @@ impl<'ast> fmt::Display for Variable<'ast> {
// Access
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::from_expression))]
pub struct FromExpression<'ast>(pub Expression<'ast>);
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::to_expression))]
pub struct ToExpression<'ast>(pub Expression<'ast>);
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::range))]
pub struct Range<'ast> {
pub from: Option<FromExpression<'ast>>,
@ -385,14 +385,14 @@ pub struct Range<'ast> {
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::range_or_expression))]
pub enum RangeOrExpression<'ast> {
Range(Range<'ast>),
Expression(Expression<'ast>),
}
// #[derive(Debug, FromPest, PartialEq, Clone)]
// #[derive(Clone, Debug, FromPest, PartialEq)]
// #[pest_ast(rule(Rule::call_access))]
// pub struct CallAccess<'ast> {
// pub expressions: Vec<Expression<'ast>>,
@ -400,7 +400,7 @@ pub enum RangeOrExpression<'ast> {
// pub span: Span<'ast>,
// }
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::access_array))]
pub struct ArrayAccess<'ast> {
pub expression: RangeOrExpression<'ast>,
@ -408,7 +408,7 @@ pub struct ArrayAccess<'ast> {
pub span: Span<'ast>,
}
// #[derive(Debug, FromPest, PartialEq, Clone)]
// #[derive(Clone, Debug, FromPest, PartialEq)]
// #[pest_ast(rule(Rule::member_access))]
// pub struct MemberAccess<'ast> {
// pub id: IdentifierExpression<'ast>,
@ -416,7 +416,7 @@ pub struct ArrayAccess<'ast> {
// pub span: Span<'ast>,
// }
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::access))]
pub enum Access<'ast> {
// Call(CallAccess<'ast>),
@ -424,7 +424,7 @@ pub enum Access<'ast> {
// Member(MemberAccess<'ast>),
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::expression_postfix))]
pub struct PostfixExpression<'ast> {
pub variable: Variable<'ast>,
@ -433,7 +433,7 @@ pub struct PostfixExpression<'ast> {
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::spread))]
pub struct Spread<'ast> {
pub expression: Expression<'ast>,
@ -447,7 +447,7 @@ impl<'ast> fmt::Display for Spread<'ast> {
}
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::spread_or_expression))]
pub enum SpreadOrExpression<'ast> {
Spread(Spread<'ast>),
@ -465,7 +465,7 @@ impl<'ast> fmt::Display for SpreadOrExpression<'ast> {
// Arrays
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::expression_array_inline))]
pub struct ArrayInlineExpression<'ast> {
pub expressions: Vec<SpreadOrExpression<'ast>>,
@ -473,18 +473,18 @@ pub struct ArrayInlineExpression<'ast> {
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::expression_array_initializer))]
pub struct ArrayInitializerExpression<'ast> {
pub expression: Box<Expression<'ast>>,
pub value: Value<'ast>,
pub count: Value<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
// Structs
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::struct_field))]
pub struct StructField<'ast> {
pub ty: Type<'ast>,
@ -493,7 +493,7 @@ pub struct StructField<'ast> {
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::struct_definition))]
pub struct Struct<'ast> {
pub variable: Variable<'ast>,
@ -502,7 +502,7 @@ pub struct Struct<'ast> {
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::inline_struct_member))]
pub struct InlineStructMember<'ast> {
pub variable: Variable<'ast>,
@ -511,7 +511,7 @@ pub struct InlineStructMember<'ast> {
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::expression_inline_struct))]
pub struct StructInlineExpression<'ast> {
pub variable: Variable<'ast>,
@ -654,7 +654,7 @@ impl<'ast> fmt::Display for Expression<'ast> {
write!(f, "")
}
Expression::ArrayInitializer(ref expression) => {
write!(f, "{} = {}", expression.value, expression.expression)
write!(f, "[{} ; {}]", expression.expression, expression.count)
}
Expression::StructInline(ref expression) => {
write!(f, "inline struct display not impl {}", expression.variable)
@ -686,7 +686,7 @@ impl<'ast> FromPest<'ast> for Expression<'ast> {
// Statements
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::statement_assign))]
pub struct AssignStatement<'ast> {
pub variable: Variable<'ast>,
@ -717,7 +717,7 @@ pub struct IterationStatement<'ast> {
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::statement_return))]
pub struct ReturnStatement<'ast> {
pub expressions: Vec<Expression<'ast>>,
@ -781,7 +781,7 @@ impl<'ast> fmt::Display for Statement<'ast> {
// Functions
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::parameter))]
pub struct Parameter<'ast> {
pub visibility: Option<Visibility>,
@ -791,7 +791,7 @@ pub struct Parameter<'ast> {
pub span: Span<'ast>,
}
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::function_definition))]
pub struct Function<'ast> {
pub variable: Variable<'ast>,
@ -817,6 +817,6 @@ pub struct File<'ast> {
// Utilities
#[derive(Debug, FromPest, PartialEq, Clone)]
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::EOI))]
pub struct EOI;

View File

@ -56,7 +56,6 @@ ty_struct = { variable }
ty_basic_or_struct = {ty_basic | ty_struct }
ty_array = {ty_basic ~ ("[" ~ expression ~ "]")+ }
ty = {ty_array | ty_basic | ty_struct}
// ty = {ty_array}
type_list = _{(ty ~ ("," ~ ty)*)?}
/// Values
@ -87,7 +86,7 @@ access_array = { "[" ~ range_or_expression ~ "]" }
access_call = { "(" ~ expression_tuple ~ ")" }
access_member = { "." ~ variable }
access = { access_array | access_call | access_member }
expression_postfix = { variable ~ access+ }
expression_postfix = { variable ~ access+ } // add ++ and -- operators
spread = { "..." ~ expression }
spread_or_expression = { spread | expression }
@ -98,7 +97,6 @@ inline_array_inner = _{(spread_or_expression ~ ("," ~ NEWLINE* ~ spread_or_expre
expression_array_inline = { "[" ~ NEWLINE* ~ inline_array_inner ~ NEWLINE* ~ "]"}
expression_array_initializer = { "[" ~ expression ~ ";" ~ value ~ "]" }
/// Structs
struct_field = { ty ~ variable }
@ -109,7 +107,6 @@ inline_struct_member = { variable ~ ":" ~ expression }
inline_struct_member_list = _{(inline_struct_member ~ ("," ~ NEWLINE* ~ inline_struct_member)*)? ~ ","? }
expression_inline_struct = { variable ~ "{" ~ NEWLINE* ~ inline_struct_member_list ~ NEWLINE* ~ "}" }
/// Conditionals
expression_conditional = { "if" ~ expression ~ "then" ~ expression ~ "else" ~ expression ~ "fi"}
@ -135,7 +132,6 @@ expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
/// Statements
// statement_expression = { expression }
statement_assign = { variable ~ "=" ~ expression }
statement_definition = { ty ~ variable ~ "=" ~ expression }
statement_return = { "return" ~ expression_tuple }
@ -146,7 +142,6 @@ statement = {
| (statement_iteration
| statement_assign
| statement_definition
// | statement_expression
) ~ NEWLINE
) ~ NEWLINE*
}