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 struct Foo {
a = 1 + 1 field a
endfor bool b
}
return 1 return 1

View File

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

View File

@ -4,7 +4,9 @@
//! @author Collin Chin <collin@aleo.org> //! @author Collin Chin <collin@aleo.org>
//! @date 2020 //! @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; 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 { impl<'ast> From<ast::File<'ast>> for types::Program {
fn from(file: ast::File<'ast>) -> Self { fn from(file: ast::File<'ast>) -> Self {
// 1. compile ast -> aleo program representation // 1. compile ast -> aleo program representation
file.structs let structs = file
.structs
.into_iter() .into_iter()
.for_each(|struct_def| println!("{:#?}", struct_def)); .map(|struct_def| {
println!("{:#?}", struct_def);
types::Struct::from(struct_def)
})
.collect();
file.functions file.functions
.into_iter() .into_iter()
.for_each(|function_def| println!("{:#?}", function_def)); .for_each(|function_def| println!("{:#?}", function_def));
@ -355,6 +418,7 @@ impl<'ast> From<ast::File<'ast>> for types::Program {
types::Program { types::Program {
id: "main".into(), id: "main".into(),
structs,
statements, statements,
arguments: vec![], arguments: vec![],
returns: vec![], returns: vec![],

View File

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

View File

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