From 3f59714eac3ee79e84a55b6b2b4b4c76fec189bb Mon Sep 17 00:00:00 2001 From: collin Date: Mon, 13 Apr 2020 12:37:30 -0700 Subject: [PATCH] pest function defs --- simple.program | 6 +- src/aleo_program/types_from.rs | 6 ++ src/ast.rs | 126 ++++++++++++++++++++++++++------- src/language.pest | 66 ++++++++++------- 4 files changed, 152 insertions(+), 52 deletions(-) diff --git a/simple.program b/simple.program index 3e56c3789f..0845b650c8 100644 --- a/simple.program +++ b/simple.program @@ -1,2 +1,6 @@ -field[1] f = [1; 3] +struct Bar { + field a +} +def foo() -> (field): + return 1 return 1 \ No newline at end of file diff --git a/src/aleo_program/types_from.rs b/src/aleo_program/types_from.rs index 0856409207..b9c9bf3c02 100644 --- a/src/aleo_program/types_from.rs +++ b/src/aleo_program/types_from.rs @@ -333,6 +333,12 @@ impl<'ast> From> for types::Statement { impl<'ast> From> for types::Program { fn from(file: ast::File<'ast>) -> Self { // 1. compile ast -> aleo program representation + file.structs + .into_iter() + .for_each(|struct_def| println!("{:#?}", struct_def)); + file.functions + .into_iter() + .for_each(|function_def| println!("{:#?}", function_def)); let statements: Vec = file .statements .into_iter() diff --git a/src/ast.rs b/src/ast.rs index 6a30d4e639..a8036ec70c 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -56,6 +56,12 @@ fn parse_term(pair: Pair) -> Box { 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 => { + println!("struct inline"); + Expression::StructInline( + StructInlineExpression::from_pest(&mut pair.into_inner()).unwrap(), + ) + }, Rule::expression_array_inline => { println!("array inline"); Expression::ArrayInline( @@ -162,15 +168,6 @@ fn binary_expression<'ast>( }) } -#[derive(Clone, Debug, FromPest, PartialEq)] -#[pest_ast(rule(Rule::file))] -pub struct File<'ast> { - pub statements: Vec>, - pub eoi: EOI, - #[pest_ast(outer())] - pub span: Span<'ast>, -} - // Types #[derive(Debug, FromPest, PartialEq, Clone)] @@ -187,14 +184,14 @@ pub struct FieldType<'ast> { pub span: Span<'ast>, } -// #[derive(Debug, FromPest, PartialEq, Clone)] -// #[pest_ast(rule(Rule::ty_struct))] -// pub struct StructType<'ast> { -// pub id: IdentifierExpression<'ast>, -// #[pest_ast(outer())] -// pub span: Span<'ast>, -// } -// +#[derive(Debug, FromPest, PartialEq, Clone)] +#[pest_ast(rule(Rule::ty_struct))] +pub struct StructType<'ast> { + pub variable: Variable<'ast>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + #[derive(Debug, FromPest, PartialEq, Clone)] #[pest_ast(rule(Rule::ty_basic))] pub enum BasicType<'ast> { @@ -202,12 +199,12 @@ pub enum BasicType<'ast> { Boolean(BooleanType<'ast>), } -// #[derive(Debug, FromPest, PartialEq, Clone)] -// #[pest_ast(rule(Rule::ty_basic_or_struct))] -// pub enum BasicOrStructType<'ast> { -// Struct(StructType<'ast>), -// Basic(BasicType<'ast>), -// } +#[derive(Debug, FromPest, PartialEq, Clone)] +#[pest_ast(rule(Rule::ty_basic_or_struct))] +pub enum BasicOrStructType<'ast> { + Struct(StructType<'ast>), + Basic(BasicType<'ast>), +} #[derive(Debug, FromPest, PartialEq, Clone)] #[pest_ast(rule(Rule::ty_array))] @@ -221,9 +218,9 @@ pub struct ArrayType<'ast> { #[derive(Debug, FromPest, PartialEq, Clone)] #[pest_ast(rule(Rule::ty))] pub enum Type<'ast> { - // Basic(BasicType<'ast>), + Basic(BasicType<'ast>), Array(ArrayType<'ast>), - // Struct(StructType<'ast>), + Struct(StructType<'ast>), } // Visibility @@ -475,6 +472,44 @@ pub struct ArrayInitializerExpression<'ast> { pub span: Span<'ast>, } +// Structs + +#[derive(Debug, FromPest, PartialEq, Clone)] +#[pest_ast(rule(Rule::struct_field))] +pub struct StructField<'ast> { + pub ty: Type<'ast>, + pub variable: Variable<'ast>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + +#[derive(Debug, FromPest, PartialEq, Clone)] +#[pest_ast(rule(Rule::struct_definition))] +pub struct Struct<'ast> { + pub variable: Variable<'ast>, + pub fields: Vec>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + +#[derive(Debug, FromPest, PartialEq, Clone)] +#[pest_ast(rule(Rule::inline_struct_member))] +pub struct InlineStructMember<'ast> { + pub variable: Variable<'ast>, + pub expression: Expression<'ast>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + +#[derive(Debug, FromPest, PartialEq, Clone)] +#[pest_ast(rule(Rule::expression_inline_struct))] +pub struct StructInlineExpression<'ast> { + pub variable: Variable<'ast>, + pub members: Vec>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + // Expressions #[derive(Clone, Debug, FromPest, PartialEq)] @@ -533,6 +568,7 @@ pub enum Expression<'ast> { Ternary(TernaryExpression<'ast>), ArrayInline(ArrayInlineExpression<'ast>), ArrayInitializer(ArrayInitializerExpression<'ast>), + StructInline(StructInlineExpression<'ast>), Postfix(PostfixExpression<'ast>), } @@ -576,6 +612,7 @@ impl<'ast> Expression<'ast> { Expression::Ternary(expression) => &expression.span, Expression::ArrayInline(expression) => &expression.span, Expression::ArrayInitializer(expression) => &expression.span, + Expression::StructInline(expression) => &expression.span, Expression::Postfix(expression) => &expression.span, } } @@ -609,6 +646,9 @@ impl<'ast> fmt::Display for Expression<'ast> { Expression::ArrayInitializer(ref expression) => { write!(f, "{} = {}", expression.value, expression.expression) } + Expression::StructInline(ref expression) => { + write!(f, "inline struct display not impl {}", expression.variable) + } Expression::Postfix(ref expression) => { write!(f, "Postfix display not impl {}", expression.variable) } @@ -705,6 +745,42 @@ impl<'ast> fmt::Display for Statement<'ast> { } } +// Functions + +#[derive(Debug, FromPest, PartialEq, Clone)] +#[pest_ast(rule(Rule::parameter))] +pub struct Parameter<'ast> { + pub visibility: Option, + pub ty: Type<'ast>, + pub variable: Variable<'ast>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + +#[derive(Debug, FromPest, PartialEq, Clone)] +#[pest_ast(rule(Rule::function_definition))] +pub struct Function<'ast> { + pub variable: Variable<'ast>, + pub parameters: Vec>, + pub returns: Vec>, + pub statements: Vec>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + +// File + +#[derive(Clone, Debug, FromPest, PartialEq)] +#[pest_ast(rule(Rule::file))] +pub struct File<'ast> { + pub structs: Vec>, + pub functions: Vec>, + pub statements: Vec>, + pub eoi: EOI, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + // Utilities #[derive(Debug, FromPest, PartialEq, Clone)] diff --git a/src/language.pest b/src/language.pest index 7a097cf593..f2202bb48b 100644 --- a/src/language.pest +++ b/src/language.pest @@ -1,8 +1,4 @@ -// file = { SOI ~ NEWLINE* ~ import_section* ~ NEWLINE* ~ ty_struct_definition* ~ NEWLINE* ~ function_definition* ~ EOI } // file = { SOI ~ NEWLINE* ~ import_section* ~ NEWLINE* ~ EOI } - -file = { SOI ~ NEWLINE* ~ statement* ~ NEWLINE* ~ EOI } - /// Visibility visibility_public = { "public" } @@ -56,16 +52,13 @@ operation_binary = _ { ty_field = {"field"} ty_bool = {"bool"} ty_basic = { ty_field | ty_bool } +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} +ty = {ty_array | ty_basic | ty_struct} +// ty = {ty_array} type_list = _{(ty ~ ("," ~ ty)*)?} -/// Structs - -ty_struct = { variable } - /// Values value_boolean = { "true" | "false" } @@ -91,8 +84,10 @@ to_expression = { expression } range = { from_expression? ~ ".." ~ to_expression } range_or_expression = { range | expression } access_array = { "[" ~ range_or_expression ~ "]" } -access = { access_array } -expression_postfix = { variable ~ access } +access_call = { "(" ~ expression_tuple ~ ")" } +access_member = { "." ~ variable } +access = { access_array | access_call | access_member } +expression_postfix = { variable ~ access+ } spread = { "..." ~ expression } spread_or_expression = { spread | expression } @@ -103,21 +98,28 @@ 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 } +struct_field_list = _{(struct_field ~ (NEWLINE+ ~ struct_field)*)? } +struct_definition = { "struct" ~ variable ~ "{" ~ NEWLINE* ~ struct_field_list ~ NEWLINE* ~ "}" ~ NEWLINE* } + +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"} -// conditional_if = { "if" } -// conditional_else = { "else" } -// -// conditional_for = { "for" } -// -// conditional = { conditional_if | conditional_else | conditional_for } /// Expressions // Consider structs, conditionals, postfix, primary, inline array, array initializer, and unary expression_term = { ("(" ~ expression ~ ")") + | expression_inline_struct | expression_conditional | expression_postfix | expression_primitive @@ -129,25 +131,37 @@ expression_term = { } expression = { expression_term ~ (operation_binary ~ expression_term)* } - - - - expression_tuple = _{ (expression ~ ("," ~ expression)*)? } /// Statements +statement_expression = { expression } statement_assign = { variable ~ "=" ~ expression } statement_definition = { ty ~ variable ~ "=" ~ expression } statement_return = { "return" ~ expression_tuple } +statement_iteration = { "for" ~ ty ~ variable ~ "in" ~ expression ~ ".." ~ expression ~ "do" ~ NEWLINE* ~ statement* ~ "endfor"} -statement = { (statement_return | (statement_assign | statement_definition) ~ NEWLINE) ~ NEWLINE* } +statement = { + (statement_return + | (statement_iteration + | statement_assign + | statement_definition + | statement_expression + ) ~ NEWLINE + ) ~ NEWLINE* +} + +/// Functions + +parameter = {visibility? ~ ty ~ variable} +parameter_list = _{(parameter ~ ("," ~ parameter)*)?} +function_definition = {"def" ~ variable ~ "(" ~ parameter_list ~ ")" ~ "->" ~ "(" ~ type_list ~ ")" ~ ":" ~ NEWLINE* ~ statement* } /// Utilities COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) } WHITESPACE = _{ " " | "\t" ~ NEWLINE } -// /// Helpers -// -// helper_range = { expression+ ~ ".." ~ expression+ } // Confirm that '+' is the correct repetition +/// Abstract Syntax Tree File + +file = { SOI ~ NEWLINE* ~ struct_definition* ~ NEWLINE* ~ function_definition* ~ NEWLINE* ~ statement* ~ NEWLINE* ~ EOI }