Add expression rules and basic left-recursive AST-expression building.
This commit is contained in:
parent
487d0383c5
commit
63dec99cb5
125
src/ast/build.rs
125
src/ast/build.rs
@ -1,16 +1,4 @@
|
||||
use crate::ast::{
|
||||
AssignStatement, BinaryExpression, BinaryOperator, BlockStatement, CallStatement,
|
||||
ClassConstructor, ClassConstructorParameter, ClassDeclaration, ClassLevelDeclaration, Closure,
|
||||
CompilationUnit, Expression, FieldDeclaration, ForStatement, FullyQualifiedName, FunctionBody,
|
||||
FunctionDefinition, FunctionModifier, FunctionTypeModifier, FunctionTypeUse, GenericArguments,
|
||||
GenericParameter, GenericParameters, Identifier, IfElseStatement, IfStatement, ImplementsList,
|
||||
InterfaceDeclaration, InterfaceFunctionDeclaration, InterfaceLevelDeclaration,
|
||||
InterfaceOperatorFunctionDeclaration, InterfaceOrClassTypeUse, Literal, ModuleDeclaration,
|
||||
ModuleLevelDeclaration, OperatorFunctionDefinition, Parameter, Parameters,
|
||||
PlatformFunctionDeclaration, PropertyDeclaration, Reference, References, ReturnStatement,
|
||||
ReturnType, Statement, TernaryExpression, TupleArguments, TupleTypeUse, TypeUse,
|
||||
VariableDeclarationStatement, WhileStatement,
|
||||
};
|
||||
use crate::ast::{AssignStatement, BinaryExpression, BinaryOperator, BlockStatement, CallArgument, CallArguments, CallExpression, CallStatement, ClassConstructor, ClassConstructorParameter, ClassDeclaration, ClassLevelDeclaration, Closure, CompilationUnit, Expression, FieldDeclaration, ForStatement, FullyQualifiedName, FunctionBody, FunctionDefinition, FunctionModifier, FunctionTypeModifier, FunctionTypeUse, GenericArguments, GenericParameter, GenericParameters, Identifier, IfElseStatement, IfStatement, ImplementsList, InterfaceDeclaration, InterfaceFunctionDeclaration, InterfaceLevelDeclaration, InterfaceOperatorFunctionDeclaration, InterfaceOrClassTypeUse, Literal, ModuleDeclaration, ModuleLevelDeclaration, ObjectAccess, ObjectNavigation, ObjectNavigations, OperatorFunctionDefinition, Parameter, Parameters, PlatformFunctionDeclaration, PropertyDeclaration, Reference, References, ReturnStatement, ReturnType, Statement, SuffixExpression, SuffixUnaryOperator, TernaryExpression, TupleArguments, TupleTypeUse, TurboFish, TypeUse, UnarySuffixExpression, VariableDeclarationStatement, WhileStatement};
|
||||
use crate::parser::Rule;
|
||||
use pest::iterators::Pair;
|
||||
|
||||
@ -749,7 +737,6 @@ fn build_expression(expression_pair: Pair<Rule>) -> Expression {
|
||||
let inner_pair = expression_pair.into_inner().next().unwrap();
|
||||
match inner_pair.as_rule() {
|
||||
Rule::TernaryExpression => Expression::Ternary(build_ternary_expression(inner_pair)),
|
||||
Rule::OrExpression => build_or_expression(inner_pair),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@ -802,14 +789,93 @@ fn build_multiplicative_expression(multiplicative_expression_pair: Pair<Rule>) -
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_unary_expression(unary_expression_pair: Pair<Rule>) -> Expression {
|
||||
fn build_prefix_expression(prefix_pair: Pair<Rule>) -> Expression {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_suffix_expression(suffix_pair: Pair<Rule>) -> Expression {
|
||||
let mut inner = suffix_pair.into_inner();
|
||||
let mut result = expect_and_use(
|
||||
inner.next().unwrap(),
|
||||
Rule::PrimaryExpression,
|
||||
build_primary_expression,
|
||||
);
|
||||
while let Some(suffix_pair) = inner.next() {
|
||||
match suffix_pair.as_rule() {
|
||||
Rule::ObjectAccess => {
|
||||
result = Expression::Suffix(SuffixExpression::ObjectAccess(build_object_access(
|
||||
result,
|
||||
suffix_pair,
|
||||
)))
|
||||
}
|
||||
Rule::ParenthesesCall => {
|
||||
result = Expression::Suffix(SuffixExpression::Call(build_call_expression(
|
||||
result,
|
||||
suffix_pair,
|
||||
)))
|
||||
}
|
||||
Rule::PlusPlus => {
|
||||
result = Expression::Suffix(SuffixExpression::Unary(UnarySuffixExpression {
|
||||
expression: Box::new(result),
|
||||
operator: SuffixUnaryOperator::PlusPlus,
|
||||
}))
|
||||
}
|
||||
Rule::MinusMinus => {
|
||||
result = Expression::Suffix(SuffixExpression::Unary(UnarySuffixExpression {
|
||||
expression: Box::new(result),
|
||||
operator: SuffixUnaryOperator::MinusMinus,
|
||||
}))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn build_call_expression(callee: Expression, parentheses_call_pair: Pair<Rule>) -> CallExpression {
|
||||
let mut turbo_fish = None;
|
||||
let mut arguments = vec![];
|
||||
|
||||
for inner_pair in parentheses_call_pair.into_inner() {
|
||||
match inner_pair.as_rule() {
|
||||
Rule::TurboFish => {
|
||||
turbo_fish = Some(build_turbo_fish(inner_pair));
|
||||
}
|
||||
Rule::ExpressionList => {
|
||||
for expression_pair in inner_pair.into_inner() {
|
||||
arguments.push(expect_and_use(
|
||||
expression_pair,
|
||||
Rule::Expression,
|
||||
build_expression,
|
||||
));
|
||||
}
|
||||
}
|
||||
Rule::Closure => {
|
||||
arguments.push(Expression::Closure(build_closure(inner_pair)));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
CallExpression {
|
||||
callee: Box::new(callee),
|
||||
turbo_fish,
|
||||
arguments: CallArguments(
|
||||
arguments
|
||||
.into_iter()
|
||||
.map(|argument| CallArgument(Box::new(argument)))
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_turbo_fish(turbo_fish_pair: Pair<Rule>) -> TurboFish {
|
||||
TurboFish(build_generic_arguments(turbo_fish_pair.into_inner().next().unwrap()))
|
||||
}
|
||||
|
||||
fn build_primary_expression(primary_expression_pair: Pair<Rule>) -> Expression {
|
||||
let mut inner = primary_expression_pair.into_inner();
|
||||
let first_pair = inner.next().unwrap();
|
||||
let expression = match first_pair.as_rule() {
|
||||
let first_pair = primary_expression_pair.into_inner().next().unwrap();
|
||||
match first_pair.as_rule() {
|
||||
Rule::Literal => Expression::Literal(build_literal(first_pair)),
|
||||
Rule::FullyQualifiedName => Expression::FullyQualifiedName(build_fqn(first_pair)),
|
||||
Rule::Closure => Expression::Closure(build_closure(first_pair)),
|
||||
@ -818,11 +884,24 @@ fn build_primary_expression(primary_expression_pair: Pair<Rule>) -> Expression {
|
||||
expect_and_use(inner_expression, Rule::Expression, build_expression)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
if let Some(suffix_pair) = inner.next() {
|
||||
todo!()
|
||||
} else {
|
||||
expression
|
||||
}
|
||||
}
|
||||
|
||||
fn build_object_access(receiver: Expression, navigations_pair: Pair<Rule>) -> ObjectAccess {
|
||||
ObjectAccess {
|
||||
receiver: Box::new(receiver),
|
||||
navigations: ObjectNavigations(
|
||||
navigations_pair
|
||||
.into_inner()
|
||||
.map(|identifier_pair| {
|
||||
ObjectNavigation::Identifier(Box::new(expect_and_use(
|
||||
identifier_pair,
|
||||
Rule::Identifier,
|
||||
build_identifier,
|
||||
)))
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ impl ReturnType {
|
||||
pub fn void() -> Self {
|
||||
ReturnType {
|
||||
declared_type: Box::new(TypeUse::Void),
|
||||
references: References::default()
|
||||
references: References::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -420,7 +420,7 @@ pub struct AssignStatement {
|
||||
#[derive(Debug)]
|
||||
pub struct CallStatement {
|
||||
pub callee: Expression,
|
||||
pub arguments: CallArguments
|
||||
pub arguments: CallArguments,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -462,12 +462,11 @@ pub struct ForStatement {
|
||||
pub enum Expression {
|
||||
Ternary(TernaryExpression),
|
||||
Binary(BinaryExpression),
|
||||
Unary(UnaryExpression),
|
||||
Call(CallExpression),
|
||||
UnaryPrefix(PrefixExpression),
|
||||
Suffix(SuffixExpression),
|
||||
Literal(Literal),
|
||||
FullyQualifiedName(FullyQualifiedName),
|
||||
Closure(Closure),
|
||||
ObjectAccess(ObjectAccess),
|
||||
Literal(Literal),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -485,18 +484,34 @@ pub struct BinaryExpression {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnaryExpression {
|
||||
pub lhs_operators: Vec<PrefixUnaryOperator>,
|
||||
pub struct PrefixExpression {
|
||||
pub operator: PrefixUnaryOperator,
|
||||
pub expression: Box<Expression>,
|
||||
pub rhs_operators: Vec<SuffixUnaryOperator>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SuffixExpression {
|
||||
Call(CallExpression),
|
||||
ObjectAccess(ObjectAccess),
|
||||
Unary(UnarySuffixExpression),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallExpression {
|
||||
pub callee: Box<Expression>,
|
||||
pub turbo_fish: Option<TurboFish>,
|
||||
pub arguments: CallArguments,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnarySuffixExpression {
|
||||
expression: Box<Expression>,
|
||||
operator: SuffixUnaryOperator,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TurboFish(pub GenericArguments);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallArguments(pub Vec<CallArgument>);
|
||||
|
||||
@ -504,14 +519,12 @@ pub struct CallArguments(pub Vec<CallArgument>);
|
||||
pub struct CallArgument(pub Box<Expression>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Closure {
|
||||
|
||||
}
|
||||
pub struct Closure {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectAccess {
|
||||
pub receiver: Box<Expression>,
|
||||
pub navigations: ObjectNavigations
|
||||
pub navigations: ObjectNavigations,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -520,7 +533,7 @@ pub struct ObjectNavigations(pub Vec<ObjectNavigation>);
|
||||
#[derive(Debug)]
|
||||
pub enum ObjectNavigation {
|
||||
Index(Box<Expression>),
|
||||
Identifier(Box<Identifier>)
|
||||
Identifier(Box<Identifier>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -508,13 +508,15 @@ AssignmentStatement = {
|
||||
}
|
||||
|
||||
CallStatement = {
|
||||
(
|
||||
Literal
|
||||
| FullyQualifiedName
|
||||
| Closure
|
||||
| ParenthesizedExpression
|
||||
)
|
||||
~ ( ObjectAccess? ~ ParenthesesCall )+
|
||||
PrimaryExpression
|
||||
~ ObjectAccess?
|
||||
~ ParenthesesCall
|
||||
~ (
|
||||
ObjectAccess
|
||||
| ParenthesesCall
|
||||
| PlusPlus
|
||||
| MinusMinus
|
||||
)*
|
||||
}
|
||||
|
||||
ReturnStatement = {
|
||||
@ -554,16 +556,17 @@ ForStatement = {
|
||||
// Expressions
|
||||
|
||||
Expression = {
|
||||
TernaryExpression
|
||||
| OrExpression
|
||||
TernaryExpression
|
||||
}
|
||||
|
||||
TernaryExpression = {
|
||||
( OrExpression | ParenthesizedExpression )
|
||||
~ "?"
|
||||
~ Expression
|
||||
~ ":"
|
||||
~ Expression
|
||||
OrExpression
|
||||
~ (
|
||||
"?"
|
||||
~ Expression
|
||||
~ ":"
|
||||
~ Expression
|
||||
)?
|
||||
}
|
||||
|
||||
OrExpression = {
|
||||
@ -572,19 +575,14 @@ OrExpression = {
|
||||
}
|
||||
|
||||
AndExpression = {
|
||||
EqualityExpression
|
||||
~ ( And ~ Expression )?
|
||||
}
|
||||
|
||||
EqualityExpression = {
|
||||
ComparisonExpression
|
||||
~ ( ( EqualTo | NotEqualTo ) ~ Expression )?
|
||||
~ ( And ~ Expression )?
|
||||
}
|
||||
|
||||
ComparisonExpression = {
|
||||
AdditiveExpression
|
||||
~ (
|
||||
( Greater | Less | GreaterEqual | LessEqual )
|
||||
( Greater | Less | GreaterEqual | LessEqual | EqualTo | NotEqualTo )
|
||||
~ Expression
|
||||
)?
|
||||
}
|
||||
@ -603,14 +601,14 @@ AdditiveExpression = {
|
||||
}
|
||||
|
||||
MultiplicativeExpression = {
|
||||
UnaryExpression
|
||||
PrefixExpression
|
||||
~ (
|
||||
( Multiply | Divide | Modulo )
|
||||
~ Expression
|
||||
)?
|
||||
}
|
||||
|
||||
UnaryExpression = {
|
||||
PrefixExpression = {
|
||||
(
|
||||
Spread
|
||||
| ( Borrow ~ Mut )
|
||||
@ -619,18 +617,24 @@ UnaryExpression = {
|
||||
| Not
|
||||
| Negative
|
||||
)*
|
||||
~ PrimaryExpression
|
||||
~ ( PlusPlus | MinusMinus )*
|
||||
~ SuffixExpression
|
||||
}
|
||||
|
||||
SuffixExpression = {
|
||||
PrimaryExpression
|
||||
~ (
|
||||
ObjectAccess
|
||||
| ParenthesesCall
|
||||
| PlusPlus
|
||||
| MinusMinus
|
||||
)*
|
||||
}
|
||||
|
||||
PrimaryExpression = {
|
||||
(
|
||||
Literal
|
||||
| FullyQualifiedName
|
||||
| Closure
|
||||
| ParenthesizedExpression
|
||||
)
|
||||
~ ExpressionSuffix?
|
||||
Literal
|
||||
| FullyQualifiedName
|
||||
| Closure
|
||||
| ParenthesizedExpression
|
||||
}
|
||||
|
||||
ParenthesizedExpression = {
|
||||
@ -639,12 +643,6 @@ ParenthesizedExpression = {
|
||||
~ ")"
|
||||
}
|
||||
|
||||
ExpressionSuffix = {
|
||||
ObjectAccess
|
||||
~ ( ParenthesesCall ~ ObjectAccess? )*
|
||||
| ( ParenthesesCall ~ ObjectAccess? )+
|
||||
}
|
||||
|
||||
ObjectAccess = {
|
||||
"."
|
||||
~ Identifier
|
||||
|
Loading…
Reference in New Issue
Block a user