implement python precedence in the parser, use derives in ast generation
This commit is contained in:
parent
97ac8da31b
commit
6f4501ba8a
5 changed files with 166 additions and 106 deletions
|
@ -500,21 +500,17 @@ impl<'ast> From<pest::ArrayInitializerExpression<'ast>> for absy::ExpressionNode
|
|||
}
|
||||
|
||||
impl<'ast> From<pest::UnaryExpression<'ast>> for absy::ExpressionNode<'ast> {
|
||||
fn from(unary: pest::UnaryExpression<'ast>) -> absy::ExpressionNode<'ast> {
|
||||
fn from(e: pest::UnaryExpression<'ast>) -> absy::ExpressionNode<'ast> {
|
||||
use crate::absy::NodeValue;
|
||||
|
||||
match unary.op {
|
||||
pest::UnaryOperator::Not(_) => {
|
||||
absy::Expression::Not(Box::new(absy::ExpressionNode::from(*unary.expression)))
|
||||
}
|
||||
pest::UnaryOperator::Neg(_) => {
|
||||
absy::Expression::Neg(Box::new(absy::ExpressionNode::from(*unary.expression)))
|
||||
}
|
||||
pest::UnaryOperator::Pos(_) => {
|
||||
absy::Expression::Pos(Box::new(absy::ExpressionNode::from(*unary.expression)))
|
||||
}
|
||||
let expression = Box::new(absy::ExpressionNode::from(*e.expression));
|
||||
|
||||
match e.op {
|
||||
pest::UnaryOperator::Not(..) => absy::Expression::Not(expression),
|
||||
pest::UnaryOperator::Neg(..) => absy::Expression::Neg(expression),
|
||||
pest::UnaryOperator::Pos(..) => absy::Expression::Pos(expression),
|
||||
}
|
||||
.span(unary.span)
|
||||
.span(e.span)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -203,6 +203,8 @@ fn check_with_arena<'ast, T: Field, E: Into<imports::Error>>(
|
|||
CompileErrors(errors.into_iter().map(|e| CompileError::from(e)).collect())
|
||||
})?;
|
||||
|
||||
println!("{}", typed_ast);
|
||||
|
||||
let abi = typed_ast.abi();
|
||||
|
||||
// analyse (unroll and constant propagation)
|
||||
|
|
|
@ -13,6 +13,8 @@ def main():
|
|||
|
||||
assert(0x00 ^ 0x00 == 0x00)
|
||||
|
||||
assert(0 - 2 ** 2 == -4)
|
||||
|
||||
//check if all statements have evalutated to true
|
||||
assert(a * b * c * d * e * f == 1)
|
||||
return
|
||||
|
|
|
@ -55,8 +55,10 @@ optionally_typed_assignee = { (ty ~ assignee) | (assignee) } // we don't use { t
|
|||
// Expressions
|
||||
expression_list = _{(expression ~ ("," ~ expression)*)?}
|
||||
|
||||
expression = { term ~ (op_binary ~ term)* }
|
||||
term = { ("(" ~ expression ~ ")") | inline_struct_expression | conditional_expression | postfix_expression | primary_expression | inline_array_expression | array_initializer_expression | unary_expression }
|
||||
expression = { unaried_term ~ (op_binary ~ unaried_term)* }
|
||||
unaried_term = { op_unary? ~ powered_term }
|
||||
powered_term = { term ~ (op_pow ~ exponent_expression)? }
|
||||
term = { ("(" ~ expression ~ ")") | inline_struct_expression | conditional_expression | postfix_expression | primary_expression | inline_array_expression | array_initializer_expression }
|
||||
spread = { "..." ~ expression }
|
||||
range = { from_expression? ~ ".." ~ to_expression? }
|
||||
from_expression = { expression }
|
||||
|
@ -84,7 +86,8 @@ spread_or_expression = { spread | expression }
|
|||
range_or_expression = { range | expression }
|
||||
array_initializer_expression = { "[" ~ expression ~ ";" ~ constant ~ "]" }
|
||||
|
||||
unary_expression = { op_unary ~ term }
|
||||
signeable_expression = { "(" ~ expression ~ ")" | primary_expression }
|
||||
exponent_expression = { "(" ~ expression ~ ")" | primary_expression }
|
||||
|
||||
// End Expressions
|
||||
|
||||
|
@ -121,9 +124,8 @@ op_neg = {"-"}
|
|||
op_pos = {"+"}
|
||||
op_left_shift = @{"<<"}
|
||||
op_right_shift = @{">>"}
|
||||
op_binary = _ { op_pow | op_or | op_and | op_bit_xor | op_bit_and | op_bit_or | op_left_shift | op_right_shift | op_equal | op_not_equal | op_lte | op_lt | op_gte | op_gt | op_add | op_sub | op_mul | op_div | op_rem }
|
||||
op_unary = { op_not | op_neg | op_pos }
|
||||
|
||||
op_binary = _ { op_or | op_and | op_bit_xor | op_bit_and | op_bit_or | op_left_shift | op_right_shift | op_equal | op_not_equal | op_lte | op_lt | op_gte | op_gt | op_add | op_sub | op_mul | op_div | op_rem }
|
||||
op_unary = { op_pos | op_neg | op_not }
|
||||
|
||||
WHITESPACE = _{ " " | "\t" | "\\" ~ NEWLINE}
|
||||
COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) }
|
||||
|
|
|
@ -12,7 +12,7 @@ pub use ast::{
|
|||
AssigneeAccess, BasicOrStructType, BasicType, BinaryExpression, BinaryOperator, CallAccess,
|
||||
ConstantExpression, DecimalNumberExpression, DefinitionStatement, Expression, FieldType, File,
|
||||
FromExpression, Function, IdentifierExpression, ImportDirective, ImportSource,
|
||||
InlineArrayExpression, InlineStructExpression, InlineStructMember, IterationStatement,
|
||||
InlineArrayExpression, InlineStructExpression, InlineStructMember, IterationStatement, Not,
|
||||
OptionallyTypedAssignee, Parameter, PostfixExpression, Range, RangeOrExpression,
|
||||
ReturnStatement, Span, Spread, SpreadOrExpression, Statement, StructDefinition, StructField,
|
||||
TernaryExpression, ToExpression, Type, UnaryExpression, UnaryOperator, Visibility,
|
||||
|
@ -52,7 +52,6 @@ mod ast {
|
|||
Operator::new(Rule::op_mul, Assoc::Left)
|
||||
| Operator::new(Rule::op_div, Assoc::Left)
|
||||
| Operator::new(Rule::op_rem, Assoc::Left),
|
||||
Operator::new(Rule::op_pow, Assoc::Left),
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -74,7 +73,6 @@ mod ast {
|
|||
Rule::op_mul => Expression::binary(BinaryOperator::Mul, lhs, rhs, span),
|
||||
Rule::op_div => Expression::binary(BinaryOperator::Div, lhs, rhs, span),
|
||||
Rule::op_rem => Expression::binary(BinaryOperator::Rem, lhs, rhs, span),
|
||||
Rule::op_pow => Expression::binary(BinaryOperator::Pow, lhs, rhs, span),
|
||||
Rule::op_equal => Expression::binary(BinaryOperator::Eq, lhs, rhs, span),
|
||||
Rule::op_not_equal => Expression::binary(BinaryOperator::NotEq, lhs, rhs, span),
|
||||
Rule::op_lte => Expression::binary(BinaryOperator::Lte, lhs, rhs, span),
|
||||
|
@ -97,74 +95,12 @@ mod ast {
|
|||
PREC_CLIMBER.climb(pair.into_inner(), build_factor, infix_rule)
|
||||
}
|
||||
|
||||
// Create an Expression from a `term`.
|
||||
// Precondition: `pair` MUST be a term
|
||||
// Create an Expression from a `signed_term`.
|
||||
// Precondition: `pair` MUST be a signed_term
|
||||
fn build_factor(pair: Pair<Rule>) -> Box<Expression> {
|
||||
Box::new(match pair.as_rule() {
|
||||
Rule::term => {
|
||||
// clone the pair to peek into what we should create
|
||||
let clone = pair.clone();
|
||||
// define the child pair
|
||||
let next = clone.into_inner().next().unwrap();
|
||||
match next.as_rule() {
|
||||
// this happens when we have an expression in parentheses: it needs to be processed as another sequence of terms and operators
|
||||
Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
Rule::conditional_expression => Expression::Ternary(
|
||||
TernaryExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
),
|
||||
Rule::primary_expression => {
|
||||
// maybe this could be simplified
|
||||
let next = next.into_inner().next().unwrap();
|
||||
match next.as_rule() {
|
||||
Rule::constant => Expression::Constant(
|
||||
ConstantExpression::from_pest(
|
||||
&mut pair.into_inner().next().unwrap().into_inner(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
Rule::identifier => Expression::Identifier(
|
||||
IdentifierExpression::from_pest(
|
||||
&mut pair.into_inner().next().unwrap().into_inner(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
r => unreachable!("`primary_expression` should contain one of [`constant`, `identifier`], found {:#?}", r),
|
||||
}
|
||||
}
|
||||
Rule::postfix_expression => Expression::Postfix(
|
||||
PostfixExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
),
|
||||
Rule::inline_struct_expression => Expression::InlineStruct(
|
||||
InlineStructExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
),
|
||||
Rule::inline_array_expression => Expression::InlineArray(
|
||||
InlineArrayExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
),
|
||||
Rule::array_initializer_expression => Expression::ArrayInitializer(
|
||||
ArrayInitializerExpression::from_pest(&mut pair.into_inner()).unwrap()
|
||||
),
|
||||
Rule::unary_expression => {
|
||||
let span = next.as_span();
|
||||
let mut inner = next.into_inner();
|
||||
let op = match inner.next().unwrap().as_rule() {
|
||||
Rule::op_unary => UnaryOperator::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
r => unreachable!("`unary_expression` should yield `op_unary`, found {:#?}", r)
|
||||
};
|
||||
let expression = build_factor(inner.next().unwrap());
|
||||
Expression::Unary(UnaryExpression {
|
||||
op,
|
||||
expression,
|
||||
span
|
||||
})
|
||||
},
|
||||
r => unreachable!("`term` should contain one of [`expression`, `conditional_expression`, `primary_expression`, `postfix_expression`, `inline_array_expression`, `unary_expression`, `array_initializer_expression`], found {:#?}", r)
|
||||
}
|
||||
}
|
||||
r => unreachable!(
|
||||
"`build_factor` can only be called on `term`, found {:#?}",
|
||||
r
|
||||
),
|
||||
})
|
||||
Box::new(Expression::from(
|
||||
UnariedTerm::from_pest(&mut Pairs::single(pair)).unwrap(),
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
|
@ -431,14 +367,6 @@ mod ast {
|
|||
Pow,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, FromPest, Clone)]
|
||||
#[pest_ast(rule(Rule::op_unary))]
|
||||
pub enum UnaryOperator<'ast> {
|
||||
Not(Not<'ast>),
|
||||
Neg(Neg<'ast>),
|
||||
Pos(Pos<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, FromPest, Clone)]
|
||||
#[pest_ast(rule(Rule::op_not))]
|
||||
pub struct Not<'ast> {
|
||||
|
@ -464,13 +392,145 @@ mod ast {
|
|||
pub enum Expression<'ast> {
|
||||
Ternary(TernaryExpression<'ast>),
|
||||
Binary(BinaryExpression<'ast>),
|
||||
Unary(UnaryExpression<'ast>),
|
||||
Postfix(PostfixExpression<'ast>),
|
||||
Identifier(IdentifierExpression<'ast>),
|
||||
Constant(ConstantExpression<'ast>),
|
||||
InlineArray(InlineArrayExpression<'ast>),
|
||||
InlineStruct(InlineStructExpression<'ast>),
|
||||
ArrayInitializer(ArrayInitializerExpression<'ast>),
|
||||
Unary(UnaryExpression<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::term))]
|
||||
pub enum Term<'ast> {
|
||||
Expression(Expression<'ast>),
|
||||
InlineStruct(InlineStructExpression<'ast>),
|
||||
Ternary(TernaryExpression<'ast>),
|
||||
Postfix(PostfixExpression<'ast>),
|
||||
Primary(PrimaryExpression<'ast>),
|
||||
InlineArray(InlineArrayExpression<'ast>),
|
||||
ArrayInitializer(ArrayInitializerExpression<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::powered_term))]
|
||||
struct PoweredTerm<'ast> {
|
||||
base: Term<'ast>,
|
||||
op: Option<PowOp>,
|
||||
exponent: Option<ExponentExpression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::op_pow))]
|
||||
struct PowOp;
|
||||
|
||||
impl<'ast> From<PoweredTerm<'ast>> for Expression<'ast> {
|
||||
fn from(t: PoweredTerm<'ast>) -> Self {
|
||||
let base = Expression::from(t.base);
|
||||
|
||||
match t.exponent {
|
||||
Some(exponent) => Expression::Binary(BinaryExpression {
|
||||
op: BinaryOperator::Pow,
|
||||
left: Box::new(base),
|
||||
right: Box::new(exponent.into()),
|
||||
span: t.span,
|
||||
}),
|
||||
None => base,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::unaried_term))]
|
||||
struct UnariedTerm<'ast> {
|
||||
op: Option<UnaryOperator>,
|
||||
expression: PoweredTerm<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> From<UnariedTerm<'ast>> for Expression<'ast> {
|
||||
fn from(t: UnariedTerm<'ast>) -> Self {
|
||||
let expression = Expression::from(t.expression);
|
||||
|
||||
match t.op {
|
||||
Some(sign) => Expression::Unary(UnaryExpression {
|
||||
op: sign.into(),
|
||||
expression: Box::new(expression),
|
||||
span: t.span,
|
||||
}),
|
||||
None => expression,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::op_unary))]
|
||||
pub enum UnaryOperator {
|
||||
Pos(PosOperator),
|
||||
Neg(NegOperator),
|
||||
Not(NotOperator),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::op_pos))]
|
||||
pub struct PosOperator;
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::op_neg))]
|
||||
pub struct NegOperator;
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::op_not))]
|
||||
pub struct NotOperator;
|
||||
|
||||
impl<'ast> From<Term<'ast>> for Expression<'ast> {
|
||||
fn from(t: Term<'ast>) -> Self {
|
||||
match t {
|
||||
Term::Expression(e) => e,
|
||||
Term::Ternary(e) => Expression::Ternary(e),
|
||||
Term::Postfix(e) => Expression::Postfix(e),
|
||||
Term::Primary(e) => e.into(),
|
||||
Term::InlineArray(e) => Expression::InlineArray(e),
|
||||
Term::InlineStruct(e) => Expression::InlineStruct(e),
|
||||
Term::ArrayInitializer(e) => Expression::ArrayInitializer(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::primary_expression))]
|
||||
pub enum PrimaryExpression<'ast> {
|
||||
Identifier(IdentifierExpression<'ast>),
|
||||
Constant(ConstantExpression<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> From<PrimaryExpression<'ast>> for Expression<'ast> {
|
||||
fn from(e: PrimaryExpression<'ast>) -> Self {
|
||||
match e {
|
||||
PrimaryExpression::Constant(c) => Expression::Constant(c),
|
||||
PrimaryExpression::Identifier(i) => Expression::Identifier(i),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::exponent_expression))]
|
||||
pub enum ExponentExpression<'ast> {
|
||||
Expression(Expression<'ast>),
|
||||
Primary(PrimaryExpression<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> From<ExponentExpression<'ast>> for Expression<'ast> {
|
||||
fn from(e: ExponentExpression<'ast>) -> Self {
|
||||
match e {
|
||||
ExponentExpression::Expression(e) => e,
|
||||
ExponentExpression::Primary(e) => e.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
|
@ -521,15 +581,6 @@ mod ast {
|
|||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::unary_expression))]
|
||||
pub struct UnaryExpression<'ast> {
|
||||
pub op: UnaryOperator<'ast>,
|
||||
pub expression: Box<Expression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::inline_array_expression))]
|
||||
pub struct InlineArrayExpression<'ast> {
|
||||
|
@ -621,6 +672,13 @@ mod ast {
|
|||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct UnaryExpression<'ast> {
|
||||
pub op: UnaryOperator,
|
||||
pub expression: Box<Expression<'ast>>,
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::conditional_expression))]
|
||||
pub struct TernaryExpression<'ast> {
|
||||
|
|
Loading…
Reference in a new issue