1
0
Fork 0
mirror of synced 2025-09-23 04:08:33 +00:00

implement python precedence in the parser, use derives in ast generation

This commit is contained in:
schaeff 2021-03-23 12:24:35 +01:00
parent 97ac8da31b
commit 6f4501ba8a
5 changed files with 166 additions and 106 deletions

View file

@ -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)
}
}

View file

@ -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)

View file

@ -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

View file

@ -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)*) }

View file

@ -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> {