Add many rules to build.rs.

This commit is contained in:
Jesse Brault 2025-05-14 19:24:28 -05:00
parent 9df681e07c
commit 487d0383c5
4 changed files with 340 additions and 30 deletions

View File

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

View File

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

View File

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

View File

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