mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-27 02:24:15 +03:00
impl operator assign statements
This commit is contained in:
parent
48ab4747e0
commit
90658f362d
@ -1,9 +1,5 @@
|
||||
function test() -> (u32, u32[2]) {
|
||||
return 1, [2, 3]
|
||||
}
|
||||
|
||||
function main() -> (u32[3]) {
|
||||
a, b = test();
|
||||
// a, u32[2] b = test() <- explicit type also works
|
||||
return [a, ...b]
|
||||
function main() -> (u32) {
|
||||
a = 2;
|
||||
a /= 3;
|
||||
return a
|
||||
}
|
@ -512,7 +512,6 @@ pub struct NotExpression<'ast> {
|
||||
// #[pest_ast(rule(Rule::expression_increment))]
|
||||
// pub struct IncrementExpression<'ast> {
|
||||
// pub expression: Box<Expression<'ast>>,
|
||||
// pub operation: Increment<'ast>,
|
||||
// #[pest_ast(outer())]
|
||||
// pub span: Span<'ast>,
|
||||
// }
|
||||
@ -521,7 +520,6 @@ pub struct NotExpression<'ast> {
|
||||
// #[pest_ast(rule(Rule::expression_decrement))]
|
||||
// pub struct DecrementExpression<'ast> {
|
||||
// pub expression: Box<Expression<'ast>>,
|
||||
// pub operation: Decrement<'ast>,
|
||||
// #[pest_ast(outer())]
|
||||
// pub span: Span<'ast>,
|
||||
// }
|
||||
@ -700,25 +698,25 @@ fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
|
||||
},
|
||||
// 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 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 })
|
||||
// Expression::Increment(IncrementExpression { 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 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 })
|
||||
// Expression::Decrement(DecrementExpression { expression, span })
|
||||
// },
|
||||
Rule::expression_postfix => {
|
||||
Expression::Postfix(
|
||||
@ -853,10 +851,41 @@ pub struct DefinitionStatement<'ast> {
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[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_assign))]
|
||||
pub enum OperationAssign {
|
||||
Assign(Assign),
|
||||
AddAssign(AddAssign),
|
||||
SubAssign(SubAssign),
|
||||
MulAssign(MulAssign),
|
||||
DivAssign(DivAssign),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_assign))]
|
||||
pub struct AssignStatement<'ast> {
|
||||
pub assignee: Assignee<'ast>,
|
||||
pub assign: OperationAssign,
|
||||
pub expression: Expression<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
|
@ -9,11 +9,9 @@ visibility = { visibility_public | visibility_private }
|
||||
operation_pre_not = { "!" }
|
||||
expression_not = { operation_pre_not ~ expression_term }
|
||||
|
||||
// operation_post_increment = { "++" }
|
||||
// expression_increment = { operation_post_increment ~ expression_term }
|
||||
// expression_increment = { expression+ ~ "++" }
|
||||
//
|
||||
// operation_post_decrement = { "--" }
|
||||
// expression_decrement = { operation_post_decrement ~ expression_term }
|
||||
// expression_decrement = { expression ~ "--" }
|
||||
|
||||
/// Binary Operations
|
||||
|
||||
@ -34,17 +32,24 @@ operation_mul = { "*" }
|
||||
operation_div = { "/" }
|
||||
operation_pow = { "**" }
|
||||
|
||||
operation_binary = _ {
|
||||
operation_binary = _{
|
||||
operation_and | operation_or |
|
||||
operation_eq | operation_neq |
|
||||
operation_geq | operation_gt | operation_leq | operation_lt |
|
||||
operation_add | operation_sub | operation_pow | operation_mul | operation_div
|
||||
}
|
||||
|
||||
// operation_add_assign = { "+=" }
|
||||
// operation_sub_assign = { "-=" }
|
||||
// operation_mul_assign = { "*=" }
|
||||
// operation_div_assign = { "/=" }
|
||||
assign = { "=" }
|
||||
operation_add_assign = { "+=" }
|
||||
operation_sub_assign = { "-=" }
|
||||
operation_mul_assign = { "*=" }
|
||||
operation_div_assign = { "/=" }
|
||||
|
||||
operation_assign = {
|
||||
assign
|
||||
| operation_add_assign | operation_sub_assign
|
||||
| operation_mul_assign | operation_div_assign
|
||||
}
|
||||
|
||||
/// Types
|
||||
|
||||
@ -60,7 +65,7 @@ type_list = _{(ty ~ ("," ~ ty)*)?}
|
||||
|
||||
/// Values
|
||||
|
||||
value_number = @{ "-"? ~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*)}
|
||||
value_number = @{ "0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* }
|
||||
value_u32 = { value_number ~ ty_u32? }
|
||||
value_field = { value_number ~ ty_field }
|
||||
value_boolean = { "true" | "false" }
|
||||
@ -145,7 +150,7 @@ expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
|
||||
// statement_one_or_more = { (statement ~ NEWLINE*)* }
|
||||
statement_return = { "return" ~ expression_tuple }
|
||||
statement_definition = { ty ~ variable ~ "=" ~ expression }
|
||||
statement_assign = { assignee ~ "=" ~ expression }
|
||||
statement_assign = { assignee ~ operation_assign ~ expression }
|
||||
statement_multiple_assignment = { optionally_typed_variable_tuple ~ "=" ~ variable ~ "(" ~ expression_tuple ~ ")" }
|
||||
statement_conditional = {"if" ~ "(" ~ expression ~ ")" ~ "{" ~ NEWLINE* ~ statement+ ~ "}" ~ ("else" ~ conditional_nested_or_end)?}
|
||||
conditional_nested_or_end = { statement_conditional | "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
@ -183,8 +188,6 @@ import_symbol = { variable ~ ("as" ~ variable)? }
|
||||
import_symbol_tuple = _{ import_symbol ~ ("," ~ NEWLINE* ~ import_symbol)* }
|
||||
|
||||
import = { "from" ~ "\"" ~ import_source ~ "\"" ~ "import" ~ ("*" | ("{" ~ NEWLINE* ~ import_symbol_tuple ~ NEWLINE* ~ "}")) ~ LINE_END}
|
||||
// import = { main_import | from_import }
|
||||
// main_import = {"import" ~ "\"" ~ import_source ~ "\"" ~ ("as" ~ variable)? ~ NEWLINE+}
|
||||
|
||||
/// Program File
|
||||
|
||||
|
@ -79,7 +79,7 @@ pub enum Expression<F: Field + PrimeField> {
|
||||
|
||||
// Arrays
|
||||
Array(Vec<Box<SpreadOrExpression<F>>>),
|
||||
ArrayAccess(Box<Expression<F>>, Box<RangeOrExpression<F>>),
|
||||
ArrayAccess(Box<Expression<F>>, Box<RangeOrExpression<F>>), // (array name, range)
|
||||
|
||||
// Structs
|
||||
Struct(Variable<F>, Vec<StructMember<F>>),
|
||||
|
@ -303,6 +303,30 @@ impl<'ast, F: Field + PrimeField> types::Expression<F> {
|
||||
}
|
||||
}
|
||||
|
||||
// ast::Assignee -> types::Expression for operator assign statements
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Assignee<'ast>> for types::Expression<F> {
|
||||
fn from(assignee: ast::Assignee<'ast>) -> Self {
|
||||
let variable = types::Expression::Variable(types::Variable::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::Member(struct_member) => {
|
||||
types::Expression::StructMemberAccess(
|
||||
Box::new(acc),
|
||||
types::Variable::from(struct_member.variable),
|
||||
)
|
||||
}
|
||||
ast::AssigneeAccess::Array(array) => types::Expression::ArrayAccess(
|
||||
Box::new(acc),
|
||||
Box::new(types::RangeOrExpression::from(array.expression)),
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// pest ast -> types::Assignee
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Assignee<F> {
|
||||
@ -358,10 +382,50 @@ impl<'ast, F: Field + PrimeField> From<ast::DefinitionStatement<'ast>> for types
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::AssignStatement<'ast>) -> Self {
|
||||
types::Statement::Assign(
|
||||
types::Assignee::from(statement.assignee),
|
||||
types::Expression::from(statement.expression),
|
||||
)
|
||||
match statement.assign {
|
||||
ast::OperationAssign::Assign(ref _assign) => types::Statement::Assign(
|
||||
types::Assignee::from(statement.assignee),
|
||||
types::Expression::from(statement.expression),
|
||||
),
|
||||
operation_assign => {
|
||||
// convert assignee into postfix expression
|
||||
let converted = types::Expression::from(statement.assignee.clone());
|
||||
|
||||
match operation_assign {
|
||||
ast::OperationAssign::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(
|
||||
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(
|
||||
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(
|
||||
types::Assignee::from(statement.assignee),
|
||||
types::Expression::Div(
|
||||
Box::new(converted),
|
||||
Box::new(types::Expression::from(statement.expression)),
|
||||
),
|
||||
),
|
||||
ast::OperationAssign::Assign(ref _assign) => {
|
||||
unimplemented!("cannot assign twice to assign statement")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user