Add many rules to build.rs.
This commit is contained in:
parent
9df681e07c
commit
487d0383c5
291
src/ast/build.rs
291
src/ast/build.rs
@ -1,12 +1,15 @@
|
||||
use crate::ast::{
|
||||
ClassConstructor, ClassConstructorParameter, ClassDeclaration, ClassLevelDeclaration,
|
||||
CompilationUnit, FieldDeclaration, FullyQualifiedName, FunctionDefinition,
|
||||
FunctionTypeModifier, FunctionTypeUse, GenericArguments, GenericParameter, GenericParameters,
|
||||
Identifier, ImplementsList, InterfaceDeclaration, InterfaceFunctionDeclaration,
|
||||
InterfaceLevelDeclaration, InterfaceOperatorFunctionDeclaration, InterfaceOrClassTypeUse,
|
||||
ModuleDeclaration, ModuleLevelDeclaration, OperatorFunctionDefinition, Parameters,
|
||||
PlatformFunctionDeclaration, PropertyDeclaration, Reference, References, ReturnType,
|
||||
TupleArguments, TupleTypeUse, TypeUse,
|
||||
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::parser::Rule;
|
||||
use pest::iterators::Pair;
|
||||
@ -42,6 +45,7 @@ fn build_fqn(fqn_pair: Pair<Rule>) -> FullyQualifiedName {
|
||||
fn build_type_use(type_use_pair: Pair<Rule>) -> TypeUse {
|
||||
let inner_pair = type_use_pair.into_inner().next().unwrap();
|
||||
match inner_pair.as_rule() {
|
||||
Rule::Void => TypeUse::Void,
|
||||
Rule::InterfaceOrClassTypeUse => {
|
||||
TypeUse::InterfaceOrClass(build_interface_or_class_type_use(inner_pair))
|
||||
}
|
||||
@ -211,12 +215,23 @@ fn build_function_type_modifier(pair: Pair<Rule>) -> FunctionTypeModifier {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_parameters(pair: Pair<Rule>) -> Parameters {
|
||||
todo!()
|
||||
fn build_parameters(parameters_pair: Pair<Rule>) -> Parameters {
|
||||
Parameters(
|
||||
parameters_pair
|
||||
.into_inner()
|
||||
.map(|parameter_pair| expect_and_use(parameter_pair, Rule::Parameter, build_parameter))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
fn build_parameter(pair: Pair<Rule>) -> Parameters {
|
||||
todo!()
|
||||
fn build_parameter(parameter_pair: Pair<Rule>) -> Parameter {
|
||||
let mut inner = parameter_pair.into_inner();
|
||||
let identifier = expect_and_use(inner.next().unwrap(), Rule::Identifier, build_identifier);
|
||||
let type_use = expect_and_use(inner.next().unwrap(), Rule::TypeUse, build_type_use);
|
||||
Parameter {
|
||||
identifier,
|
||||
type_use,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_return_type(return_type_pair: Pair<Rule>) -> ReturnType {
|
||||
@ -289,7 +304,7 @@ fn build_module_level_declaration(pair: Pair<Rule>) -> ModuleLevelDeclaration {
|
||||
}
|
||||
Rule::Class => ModuleLevelDeclaration::Class(build_class_declaration(inner_pair)),
|
||||
Rule::FunctionDefinition => {
|
||||
ModuleLevelDeclaration::Function(build_function_declaration(inner_pair))
|
||||
ModuleLevelDeclaration::Function(build_function_definition(inner_pair))
|
||||
}
|
||||
Rule::PlatformFunction => ModuleLevelDeclaration::PlatformFunction(
|
||||
build_platform_function_declaration(inner_pair),
|
||||
@ -331,7 +346,7 @@ fn build_class_level_declaration(declaration_pair: Pair<Rule>) -> ClassLevelDecl
|
||||
}
|
||||
Rule::Class => ClassLevelDeclaration::Class(build_class_declaration(inner_pair)),
|
||||
Rule::FunctionDefinition => {
|
||||
ClassLevelDeclaration::Function(build_function_declaration(inner_pair))
|
||||
ClassLevelDeclaration::Function(build_function_definition(inner_pair))
|
||||
}
|
||||
Rule::OperatorFunctionDefinition => {
|
||||
ClassLevelDeclaration::OperatorFunction(build_operator_function_declaration(inner_pair))
|
||||
@ -454,8 +469,52 @@ fn build_class_declaration(class_pair: Pair<Rule>) -> ClassDeclaration {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_function_declaration(function_definition_pair: Pair<Rule>) -> FunctionDefinition {
|
||||
todo!()
|
||||
fn build_function_definition(function_definition_pair: Pair<Rule>) -> FunctionDefinition {
|
||||
let mut is_public = false;
|
||||
let mut modifier = None;
|
||||
let mut generics = None;
|
||||
let mut identifier = None;
|
||||
let mut parameters = None;
|
||||
let mut return_type = None;
|
||||
let mut body = None;
|
||||
|
||||
for inner_pair in function_definition_pair.into_inner() {
|
||||
match inner_pair.as_rule() {
|
||||
Rule::Pub => {
|
||||
is_public = true;
|
||||
}
|
||||
Rule::FunctionModifier => {
|
||||
modifier = Some(build_function_modifier(inner_pair));
|
||||
}
|
||||
Rule::Fn => {}
|
||||
Rule::GenericParameters => {
|
||||
generics = Some(build_generic_parameters(inner_pair));
|
||||
}
|
||||
Rule::Identifier => {
|
||||
identifier = Some(build_identifier(inner_pair));
|
||||
}
|
||||
Rule::Parameters => {
|
||||
parameters = Some(build_parameters(inner_pair));
|
||||
}
|
||||
Rule::ReturnType => {
|
||||
return_type = Some(build_return_type(inner_pair));
|
||||
}
|
||||
Rule::FunctionBody => {
|
||||
body = Some(build_function_body(inner_pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
FunctionDefinition {
|
||||
is_public,
|
||||
modifier,
|
||||
generics: generics.unwrap_or_else(GenericParameters::default),
|
||||
identifier: identifier.unwrap(),
|
||||
parameters: parameters.unwrap(),
|
||||
return_type: return_type.unwrap_or_else(ReturnType::void),
|
||||
body: body.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_operator_function_declaration(
|
||||
@ -510,6 +569,43 @@ fn build_class_constructor(class_constructor_pair: Pair<Rule>) -> ClassConstruct
|
||||
)
|
||||
}
|
||||
|
||||
fn build_function_modifier(modifier_pair: Pair<Rule>) -> FunctionModifier {
|
||||
let mut inner = modifier_pair.into_inner();
|
||||
if inner.len() == 2 {
|
||||
FunctionModifier::MutRef
|
||||
} else {
|
||||
match inner.next().unwrap().as_rule() {
|
||||
Rule::Static => FunctionModifier::Static,
|
||||
Rule::Cons => FunctionModifier::Cons,
|
||||
Rule::Mut => FunctionModifier::Mut,
|
||||
Rule::Ref => FunctionModifier::Ref,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn build_function_body(body_pair: Pair<Rule>) -> FunctionBody {
|
||||
let inner_pair = body_pair.into_inner().next().unwrap();
|
||||
match inner_pair.as_rule() {
|
||||
Rule::FunctionEqualsBody => FunctionBody::Equals(expect_and_use(
|
||||
inner_pair.into_inner().next().unwrap(),
|
||||
Rule::Expression,
|
||||
build_expression,
|
||||
)),
|
||||
Rule::BlockStatement => FunctionBody::Block(build_block_statement(inner_pair)),
|
||||
Rule::FunctionAliasBody => {
|
||||
let mut alias_body_pairs = inner_pair.into_inner();
|
||||
alias_body_pairs.next().unwrap(); // Alias
|
||||
FunctionBody::Alias(expect_and_use(
|
||||
alias_body_pairs.next().unwrap(),
|
||||
Rule::Identifier,
|
||||
build_identifier,
|
||||
))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_property_class_constructor_parameter(
|
||||
property_pair: Pair<Rule>,
|
||||
) -> ClassConstructorParameter {
|
||||
@ -574,3 +670,166 @@ fn build_field_declaration(field_pair: Pair<Rule>) -> FieldDeclaration {
|
||||
declared_type: declared_type.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_block_statement(block_statement_pair: Pair<Rule>) -> BlockStatement {
|
||||
let mut statements = vec![];
|
||||
let mut expression = None;
|
||||
|
||||
for inner_pair in block_statement_pair.into_inner() {
|
||||
match inner_pair.as_rule() {
|
||||
Rule::Statement => {
|
||||
statements.push(build_statement(inner_pair));
|
||||
}
|
||||
Rule::Expression => {
|
||||
expression = Some(build_expression(inner_pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
BlockStatement {
|
||||
statements,
|
||||
expression,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_statement(statement_pair: Pair<Rule>) -> Statement {
|
||||
let first = statement_pair.into_inner().next().unwrap();
|
||||
match first.as_rule() {
|
||||
Rule::BlockStatement => Statement::BlockStatement(build_block_statement(first)),
|
||||
Rule::VariableDeclaration => {
|
||||
Statement::VariableDeclarationStatement(build_variable_declaration(first))
|
||||
}
|
||||
Rule::AssignmentStatement => Statement::AssignStatement(build_assignment_statement(first)),
|
||||
Rule::CallStatement => Statement::CallStatement(build_call_statement(first)),
|
||||
Rule::ReturnStatement => Statement::ReturnStatement(build_return_statement(first)),
|
||||
Rule::IfStatement => Statement::IfStatement(build_if_statement(first)),
|
||||
Rule::IfElseStatement => Statement::IfElseStatement(build_if_else_statement(first)),
|
||||
Rule::WhileStatement => Statement::WhileStatement(build_while_statement(first)),
|
||||
Rule::ForStatement => Statement::ForStatement(build_for_statement(first)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_variable_declaration(
|
||||
variable_declaration_pair: Pair<Rule>,
|
||||
) -> VariableDeclarationStatement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_assignment_statement(assignment_pair: Pair<Rule>) -> AssignStatement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_call_statement(call_statement_pair: Pair<Rule>) -> CallStatement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_return_statement(return_statement_pair: Pair<Rule>) -> ReturnStatement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_if_statement(if_statement_pair: Pair<Rule>) -> IfStatement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_if_else_statement(if_else_statement_pair: Pair<Rule>) -> IfElseStatement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_while_statement(while_statement_pair: Pair<Rule>) -> WhileStatement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_for_statement(for_statement_pair: Pair<Rule>) -> ForStatement {
|
||||
todo!()
|
||||
}
|
||||
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_ternary_expression(ternary_pair: Pair<Rule>) -> TernaryExpression {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_or_expression(or_expression_pair: Pair<Rule>) -> Expression {
|
||||
let mut inner = or_expression_pair.into_inner();
|
||||
if inner.len() == 3 {
|
||||
let left = expect_and_use(
|
||||
inner.next().unwrap(),
|
||||
Rule::AndExpression,
|
||||
build_and_expression,
|
||||
);
|
||||
inner.next().unwrap(); // Or
|
||||
let right = expect_and_use(inner.next().unwrap(), Rule::Expression, build_expression);
|
||||
Expression::Binary(BinaryExpression {
|
||||
left: Box::new(left),
|
||||
operator: BinaryOperator::Or,
|
||||
right: Box::new(right),
|
||||
})
|
||||
} else {
|
||||
build_and_expression(inner.next().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
fn build_and_expression(and_expression_pair: Pair<Rule>) -> Expression {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_equality_expression(equality_pair: Pair<Rule>) -> Expression {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_comparison_expression(comparison_expression_pair: Pair<Rule>) -> Expression {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_shift_expression(shift_expression_pair: Pair<Rule>) -> Expression {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_additive_expression(add_expression_pair: Pair<Rule>) -> Expression {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_multiplicative_expression(multiplicative_expression_pair: Pair<Rule>) -> Expression {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_unary_expression(unary_expression_pair: Pair<Rule>) -> Expression {
|
||||
todo!()
|
||||
}
|
||||
|
||||
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() {
|
||||
Rule::Literal => Expression::Literal(build_literal(first_pair)),
|
||||
Rule::FullyQualifiedName => Expression::FullyQualifiedName(build_fqn(first_pair)),
|
||||
Rule::Closure => Expression::Closure(build_closure(first_pair)),
|
||||
Rule::ParenthesizedExpression => {
|
||||
let inner_expression = first_pair.into_inner().next().unwrap();
|
||||
expect_and_use(inner_expression, Rule::Expression, build_expression)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
if let Some(suffix_pair) = inner.next() {
|
||||
todo!()
|
||||
} else {
|
||||
expression
|
||||
}
|
||||
}
|
||||
|
||||
fn build_literal(literal_pair: Pair<Rule>) -> Literal {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn build_closure(closure_pair: Pair<Rule>) -> Closure {
|
||||
todo!()
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ pub struct FullyQualifiedName(pub Vec<Identifier>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TypeUse {
|
||||
Void,
|
||||
InterfaceOrClass(InterfaceOrClassTypeUse),
|
||||
Tuple(TupleTypeUse),
|
||||
Function(FunctionTypeUse),
|
||||
@ -189,6 +190,17 @@ pub struct ReturnType {
|
||||
pub references: References,
|
||||
}
|
||||
|
||||
impl ReturnType {
|
||||
pub fn void() -> Self {
|
||||
ReturnType {
|
||||
declared_type: Box::new(TypeUse::Void),
|
||||
references: References::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* References */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct References(pub Vec<Reference>);
|
||||
|
||||
@ -373,14 +385,17 @@ pub struct FieldDeclaration {
|
||||
// Statements
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BlockStatement(pub Vec<Statement>);
|
||||
pub struct BlockStatement {
|
||||
pub statements: Vec<Statement>,
|
||||
pub expression: Option<Expression>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Statement {
|
||||
BlockStatement(BlockStatement),
|
||||
VariableDeclarationStatement(VariableDeclarationStatement),
|
||||
AssignStatement(AssignStatement),
|
||||
CallStatement(CallExpression),
|
||||
CallStatement(CallStatement),
|
||||
ReturnStatement(ReturnStatement),
|
||||
IfStatement(IfStatement),
|
||||
IfElseStatement(IfElseStatement),
|
||||
@ -397,7 +412,16 @@ pub struct VariableDeclarationStatement {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssignStatement(pub AssignmentExpression);
|
||||
pub struct AssignStatement {
|
||||
pub lhs: Expression,
|
||||
pub rhs: Expression,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallStatement {
|
||||
pub callee: Expression,
|
||||
pub arguments: CallArguments
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReturnStatement(pub Option<Expression>);
|
||||
@ -439,8 +463,10 @@ pub enum Expression {
|
||||
Ternary(TernaryExpression),
|
||||
Binary(BinaryExpression),
|
||||
Unary(UnaryExpression),
|
||||
Assignment(Box<AssignmentExpression>),
|
||||
Call(CallExpression),
|
||||
FullyQualifiedName(FullyQualifiedName),
|
||||
Closure(Closure),
|
||||
ObjectAccess(ObjectAccess),
|
||||
Literal(Literal),
|
||||
}
|
||||
|
||||
@ -465,12 +491,6 @@ pub struct UnaryExpression {
|
||||
pub rhs_operators: Vec<SuffixUnaryOperator>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssignmentExpression {
|
||||
identifier: Identifier,
|
||||
expression: Expression,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallExpression {
|
||||
pub callee: Box<Expression>,
|
||||
@ -483,6 +503,26 @@ pub struct CallArguments(pub Vec<CallArgument>);
|
||||
#[derive(Debug)]
|
||||
pub struct CallArgument(pub Box<Expression>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Closure {
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectAccess {
|
||||
pub receiver: Box<Expression>,
|
||||
pub navigations: ObjectNavigations
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectNavigations(pub Vec<ObjectNavigation>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ObjectNavigation {
|
||||
Index(Box<Expression>),
|
||||
Identifier(Box<Identifier>)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Literal {
|
||||
IntegerLiteral(i32),
|
||||
|
@ -27,6 +27,7 @@ While = { "while" }
|
||||
For = { "for" }
|
||||
In = { "in" }
|
||||
Move = { "move" }
|
||||
Alias = { "alias" }
|
||||
|
||||
// Keywords as a rule (for preventing identifiers with keywords, etc.)
|
||||
Keyword = {
|
||||
@ -58,6 +59,7 @@ Keyword = {
|
||||
| For
|
||||
| In
|
||||
| Move
|
||||
| Alias
|
||||
}
|
||||
|
||||
// Symbols
|
||||
@ -168,7 +170,8 @@ ParenthesesOptionalTypeUseList = {
|
||||
// Parameters = declaration
|
||||
|
||||
TypeUse = {
|
||||
InterfaceOrClassTypeUse
|
||||
Void
|
||||
| InterfaceOrClassTypeUse
|
||||
| TupleTypeUse
|
||||
| FunctionTypeUse
|
||||
}
|
||||
@ -433,7 +436,7 @@ FunctionEqualsBody = {
|
||||
}
|
||||
|
||||
FunctionAliasBody = {
|
||||
"alias"
|
||||
Alias
|
||||
~ Identifier
|
||||
}
|
||||
|
||||
@ -504,7 +507,15 @@ AssignmentStatement = {
|
||||
~ Expression
|
||||
}
|
||||
|
||||
CallStatement = { PrimaryExpression }
|
||||
CallStatement = {
|
||||
(
|
||||
Literal
|
||||
| FullyQualifiedName
|
||||
| Closure
|
||||
| ParenthesizedExpression
|
||||
)
|
||||
~ ( ObjectAccess? ~ ParenthesesCall )+
|
||||
}
|
||||
|
||||
ReturnStatement = {
|
||||
Return
|
||||
|
@ -8,7 +8,7 @@ pub struct DeimosParser;
|
||||
mod deimos_parser_tests {
|
||||
use crate::parser::{DeimosParser, Rule};
|
||||
use pest::iterators::Pair;
|
||||
use pest::{parses_to, Parser};
|
||||
use pest::{Parser};
|
||||
|
||||
macro_rules! fail_rule {
|
||||
($pair: expr; $rule:path) => {{
|
||||
|
Loading…
Reference in New Issue
Block a user