Compare commits

...

4 Commits

35 changed files with 5112 additions and 2001 deletions

File diff suppressed because it is too large Load Diff

1057
src/ast/children.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,760 +1,6 @@
use crate::ast::named::Named;
use crate::name_analysis::symbol::Symbol;
use pest::Parser;
use std::borrow::Cow;
use std::cell::RefCell;
use std::range::Range;
use std::rc::Rc;
pub mod build;
pub mod named;
pub mod children;
pub mod node;
pub mod pretty_print;
pub mod unparse;
/* Operators */
#[derive(Debug)]
pub enum Operator {
Binary(BinaryOperator),
PrefixUnary(PrefixUnaryOperator),
SuffixUnary(SuffixUnaryOperator),
}
#[derive(Debug)]
pub enum BinaryOperator {
Or,
And,
EqualTo,
NotEqualTo,
Greater,
Less,
GreaterEqual,
LessEqual,
Add,
Subtract,
Multiply,
Divide,
Modulo,
LeftShift,
RightShift,
}
#[derive(Debug)]
pub enum PrefixUnaryOperator {
Spread,
BorrowMut,
Borrow,
Mut,
Not,
Negative,
}
#[derive(Debug)]
pub enum SuffixUnaryOperator {
PlusPlus,
MinusMinus,
}
/* Names */
#[derive(Debug)]
pub struct Identifier {
name: String,
file_id: usize,
range: Range<usize>,
scope_id: Option<usize>,
saved_symbol: Option<Symbol>,
}
impl Identifier {
pub fn new(name: &str, file_id: usize, range: Range<usize>) -> Self {
Identifier {
name: name.to_string(),
file_id,
range,
scope_id: None,
saved_symbol: None,
}
}
}
#[derive(Debug)]
pub struct FullyQualifiedName {
identifiers: Vec<Identifier>,
file_id: usize,
range: Range<usize>,
scope_id: Option<usize>,
saved_symbol: Option<Symbol>,
}
impl FullyQualifiedName {
pub fn new(identifiers: Vec<Identifier>, file_id: usize, range: Range<usize>) -> Self {
FullyQualifiedName {
identifiers,
range,
file_id,
scope_id: None,
saved_symbol: None,
}
}
pub fn last(&self) -> &Identifier {
&self.identifiers[self.identifiers.len() - 1]
}
pub fn last_mut(&mut self) -> &mut Identifier {
let last_index = self.identifiers.len() - 1;
&mut self.identifiers[last_index]
}
pub fn len(&self) -> usize {
self.identifiers.len()
}
pub fn is_single_identifier(&self) -> bool {
self.identifiers.len() == 1
}
}
/* Type Use */
#[derive(Debug)]
pub enum TypeUse {
Primitive(PrimitiveTypeUse),
InterfaceOrClass(InterfaceOrClassTypeUse),
Tuple(TupleTypeUse),
Function(FunctionTypeUse),
}
#[derive(Debug)]
pub enum PrimitiveTypeUse {
Byte,
Short,
Char,
Int,
Long,
Double,
Bool,
String,
Array(Option<Box<GenericArguments>>),
Any,
Void,
}
#[derive(Debug)]
pub struct InterfaceOrClassTypeUse {
pub borrow_count: usize,
pub is_mutable: bool,
pub fqn: FullyQualifiedName,
pub generics: GenericArguments,
}
#[derive(Debug)]
pub struct TupleTypeUse {
pub borrow_count: usize,
pub is_mutable: bool,
pub arguments: TupleArguments,
}
#[derive(Debug)]
pub struct FunctionTypeUse {
pub borrow_count: usize,
pub function_modifier: Option<FunctionTypeModifier>,
pub generics: GenericParameters,
pub parameters: Parameters,
pub return_type: ReturnType,
}
/* Generic arguments */
#[derive(Debug)]
pub struct GenericArguments(pub Vec<TypeUse>);
impl GenericArguments {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl Default for GenericArguments {
fn default() -> Self {
GenericArguments(Vec::new())
}
}
/* Generic parameters */
#[derive(Debug)]
pub struct GenericParameters(pub Vec<Identifier>);
impl GenericParameters {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl Default for GenericParameters {
fn default() -> Self {
GenericParameters(Vec::new())
}
}
/* Tuple Arguments */
#[derive(Debug)]
pub struct TupleArguments(pub Vec<TypeUse>);
/* Implements List */
#[derive(Debug)]
pub struct ImplementsList(pub Vec<TypeUse>);
impl ImplementsList {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl Default for ImplementsList {
fn default() -> Self {
ImplementsList(Vec::new())
}
}
/* Function Type Modifier */
#[derive(Debug)]
pub enum FunctionTypeModifier {
Cons,
MutRef,
Mut,
Ref,
}
/* Function Parameters */
#[derive(Debug)]
pub struct Parameters(pub Vec<Parameter>);
impl Parameters {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl Default for Parameters {
fn default() -> Self {
Parameters(Vec::new())
}
}
#[derive(Debug)]
pub struct Parameter {
pub identifier: Identifier,
pub type_use: TypeUse,
}
/* Return Type */
#[derive(Debug)]
pub struct ReturnType {
pub declared_type: Box<TypeUse>,
pub references: References,
}
impl ReturnType {
pub fn void() -> Self {
ReturnType {
declared_type: Box::new(TypeUse::Primitive(PrimitiveTypeUse::Void)),
references: References::default(),
}
}
}
/* References */
#[derive(Debug)]
pub struct References(pub Vec<Identifier>);
impl References {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl Default for References {
fn default() -> Self {
References(Vec::new())
}
}
/* Top-level construct */
#[derive(Debug)]
pub struct CompilationUnit {
pub file_name: String,
pub file_id: usize,
pub namespace: Option<FullyQualifiedName>,
pub use_statements: Vec<UseStatement>,
pub declarations: Vec<ModuleLevelDeclaration>,
}
/* Use Statement */
#[derive(Debug)]
pub struct UseStatement {
pub identifiers: Vec<Identifier>,
pub last: UseStatementLast,
pub file_id: usize,
pub range: Range<usize>,
}
impl UseStatement {
pub fn new(
identifiers: Vec<Identifier>,
last: UseStatementLast,
file_id: usize,
range: Range<usize>,
) -> Self {
UseStatement {
identifiers,
last,
file_id,
range,
}
}
pub fn base_name(&self) -> Cow<'_, str> {
use UseStatementLast::*;
if self.identifiers.is_empty() {
match &self.last {
Identifier(_) => Cow::from(""),
Star | Identifiers(_) => panic!(), // should never get here because of grammar
}
} else if self.identifiers.len() == 1 {
self.identifiers[0].name()
} else {
let mut acc = String::new();
for (i, identifier) in self.identifiers.iter().enumerate() {
acc.push_str(&identifier.name());
if i != self.identifiers.len() - 1 {
acc.push_str("::");
}
}
Cow::from(acc)
}
}
pub fn is_star(&self) -> bool {
match &self.last {
UseStatementLast::Star => true,
_ => false,
}
}
}
#[derive(Debug)]
pub enum UseStatementLast {
Identifier(Rc<RefCell<Identifier>>),
Identifiers(Vec<Rc<RefCell<Identifier>>>),
Star,
}
/* Declarations allowed in each level */
#[derive(Debug)]
pub enum ModuleLevelDeclaration {
Module(ModuleDeclaration),
Interface(InterfaceDeclaration),
Class(ClassDeclaration),
Function(FunctionDefinition),
PlatformFunction(PlatformFunctionDeclaration),
}
#[derive(Debug)]
pub enum InterfaceLevelDeclaration {
Module(ModuleDeclaration),
Interface(InterfaceDeclaration),
Class(ClassDeclaration),
Function(InterfaceFunctionDeclaration),
OperatorFunction(InterfaceOperatorFunctionDeclaration),
}
#[derive(Debug)]
pub enum ClassLevelDeclaration {
Module(ModuleDeclaration),
Interface(InterfaceDeclaration),
Class(ClassDeclaration),
Function(FunctionDefinition),
OperatorFunction(OperatorFunctionDefinition),
PlatformFunction(PlatformFunctionDeclaration),
Property(PropertyDeclaration),
Field(FieldDeclaration),
}
/* Main Declarations */
#[derive(Debug)]
pub struct ModuleDeclaration {
pub is_public: bool,
pub identifier: Identifier,
pub declarations: Vec<ModuleLevelDeclaration>,
}
#[derive(Debug)]
pub struct InterfaceDeclaration {
pub is_public: bool,
pub identifier: Identifier,
pub generics: GenericParameters,
pub implements: ImplementsList,
pub declarations: Vec<InterfaceLevelDeclaration>,
}
#[derive(Debug)]
pub struct ClassDeclaration {
pub is_public: bool,
pub identifier: Identifier,
pub generics: GenericParameters,
pub class_constructor: Option<ClassConstructor>,
pub implements: ImplementsList,
pub declarations: Vec<ClassLevelDeclaration>,
}
/* Function declarations and components */
#[derive(Debug)]
pub struct FunctionDefinition {
pub is_public: bool,
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub identifier: Identifier,
pub parameters: Parameters,
pub return_type: ReturnType,
pub body: FunctionBody,
}
#[derive(Debug)]
pub struct OperatorFunctionDefinition {
pub is_public: bool,
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub operator: Operator,
pub parameters: Parameters,
pub return_type: ReturnType,
pub body: FunctionBody,
}
#[derive(Debug)]
pub struct PlatformFunctionDeclaration {
pub is_public: bool,
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub identifier: Identifier,
pub parameters: Parameters,
pub return_type: ReturnType,
}
#[derive(Debug)]
pub struct InterfaceFunctionDeclaration {
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub identifier: Identifier,
pub parameters: Parameters,
pub return_type: ReturnType,
pub body: Option<FunctionBody>,
}
#[derive(Debug)]
pub struct InterfaceOperatorFunctionDeclaration {
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub operator: Operator,
pub parameters: Parameters,
pub return_type: ReturnType,
pub body: Option<FunctionBody>,
}
#[derive(Debug)]
pub enum FunctionModifier {
Static,
Cons,
Mut,
Ref,
MutRef,
}
#[derive(Debug)]
pub enum FunctionBody {
Equals(Expression),
Block(BlockStatement),
Alias(Identifier),
}
/* Class components */
#[derive(Debug)]
pub struct ClassConstructor(pub Vec<ClassConstructorParameter>);
#[derive(Debug)]
pub enum ClassConstructorParameter {
Property(PropertyDeclaration),
Field(FieldDeclaration),
}
#[derive(Debug)]
pub struct PropertyDeclaration {
pub is_mutable: bool,
pub identifier: Identifier,
pub declared_type: TypeUse,
}
#[derive(Debug)]
pub struct FieldDeclaration {
pub is_mutable: bool,
pub identifier: Identifier,
pub declared_type: TypeUse,
}
/* Statements */
#[derive(Debug)]
pub struct BlockStatement {
pub statements: Vec<Statement>,
pub expression: Option<Expression>,
}
#[derive(Debug)]
pub enum Statement {
BlockStatement(BlockStatement),
VariableDeclarationStatement(VariableDeclarationStatement),
AssignStatement(AssignStatement),
CallStatement(CallStatement),
ReturnStatement(ReturnStatement),
IfStatement(IfStatement),
IfElseStatement(IfElseStatement),
WhileStatement(WhileStatement),
ForStatement(ForStatement),
}
#[derive(Debug)]
pub struct VariableDeclarationStatement {
pub is_mutable: bool,
pub identifier: Identifier,
pub declared_type: Option<TypeUse>,
pub initializer: Option<Expression>,
}
#[derive(Debug)]
pub struct AssignStatement {
pub lhs: Expression,
pub rhs: Expression,
}
#[derive(Debug)]
pub struct CallStatement(pub Expression);
#[derive(Debug)]
pub struct ReturnStatement(pub Option<Expression>);
#[derive(Debug)]
pub struct IfStatement {
pub condition: Expression,
pub then_block: BlockStatement,
}
#[derive(Debug)]
pub struct IfElseStatement {
pub if_statement: IfStatement,
pub else_ifs: ElseIfs,
pub else_block: Option<ElseBlock>,
}
#[derive(Debug, Default)]
pub struct ElseIfs(pub Vec<IfStatement>);
#[derive(Debug)]
pub struct ElseBlock(pub BlockStatement);
#[derive(Debug)]
pub struct WhileStatement {
pub condition: Expression,
pub body: BlockStatement,
}
#[derive(Debug)]
pub struct ForStatement {
pub variable: Identifier,
pub iterator: Expression,
pub body: BlockStatement,
}
/* Expressions */
#[derive(Debug)]
pub enum Expression {
Ternary(TernaryExpression),
Binary(BinaryExpression),
UnaryPrefix(PrefixExpression),
UnarySuffix(SuffixExpression),
Call(CallExpression),
ObjectAccess(ObjectAccess),
Literal(Literal),
FullyQualifiedName(FullyQualifiedName),
Closure(Closure),
}
#[derive(Debug)]
pub struct TernaryExpression {
pub condition: Box<Expression>,
pub true_expression: Box<Expression>,
pub false_expression: Box<Expression>,
}
#[derive(Debug)]
pub struct BinaryExpression {
pub left: Box<Expression>,
pub operator: BinaryOperator,
pub right: Box<Expression>,
}
#[derive(Debug)]
pub struct PrefixExpression {
pub operator: PrefixUnaryOperator,
pub expression: Box<Expression>,
}
#[derive(Debug)]
pub struct SuffixExpression {
pub expression: Box<Expression>,
pub operator: SuffixUnaryOperator,
}
#[derive(Debug)]
pub struct CallExpression {
pub callee: Box<Expression>,
pub turbo_fish: Option<TurboFish>,
pub arguments: CallArguments,
}
#[derive(Debug)]
pub struct TurboFish(pub GenericArguments);
#[derive(Debug)]
pub struct CallArguments(pub Vec<CallArgument>);
#[derive(Debug)]
pub struct CallArgument(pub Box<Expression>);
#[derive(Debug)]
pub struct Closure {
pub modifier: Option<ClosureModifier>,
pub is_move: bool,
pub captures: ClosureCaptures,
pub parameters: ClosureParameters,
pub statements: Vec<Statement>,
pub expression: Option<Box<Expression>>,
}
#[derive(Debug)]
pub enum ClosureModifier {
Cons,
Mut,
}
#[derive(Debug, Default)]
pub struct ClosureCaptures(pub Vec<ClosureCapture>);
impl ClosureCaptures {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct ClosureCapture {
pub borrow_count: usize,
pub is_mutable: bool,
pub identifier: Box<Identifier>,
}
#[derive(Debug, Default)]
pub struct ClosureParameters(pub Vec<ClosureParameter>);
impl ClosureParameters {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct ClosureParameter {
pub identifier: Identifier,
pub type_use: Option<TypeUse>,
}
#[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 {
Integer(i32),
Long(i64),
Double(f64),
USize(usize),
String(String),
DString(DString),
BacktickString(DString),
Boolean(bool),
}
#[derive(Debug)]
pub struct DString(pub Vec<DStringPart>);
#[derive(Debug)]
pub enum DStringPart {
String(String),
Expression(Box<Expression>),
}
impl DStringPart {
pub fn from_string(s: &str) -> DStringPart {
DStringPart::String(String::from(s))
}
pub fn from_expression(e: Expression) -> DStringPart {
DStringPart::Expression(Box::new(e))
}
pub fn is_string(&self) -> bool {
match self {
DStringPart::String(_) => true,
_ => false,
}
}
pub fn unwrap_string(self) -> String {
match self {
DStringPart::String(s) => s,
_ => panic!(),
}
}
pub fn is_expression(&self) -> bool {
match self {
DStringPart::Expression(_) => true,
_ => false,
}
}
}
mod walk;

View File

@ -1,88 +0,0 @@
use crate::ast::{FullyQualifiedName, Identifier};
use crate::name_analysis::symbol::Symbol;
use std::borrow::Cow;
use std::range::Range;
pub trait Named {
fn name(&self) -> Cow<'_, str>;
fn file_id(&self) -> usize;
fn range(&self) -> Range<usize>;
fn set_scope_id(&mut self, scope_id: usize);
fn scope_id(&self) -> Option<usize>;
fn set_saved_symbol(&mut self, symbol: Symbol);
fn saved_symbol(&self) -> Option<Symbol>;
}
impl Named for Identifier {
fn name(&self) -> Cow<'_, str> {
Cow::Borrowed(&self.name)
}
fn file_id(&self) -> usize {
self.file_id
}
fn range(&self) -> Range<usize> {
self.range
}
fn set_scope_id(&mut self, id: usize) {
self.scope_id = Some(id);
}
fn scope_id(&self) -> Option<usize> {
self.scope_id
}
fn set_saved_symbol(&mut self, saved_symbol: Symbol) {
self.saved_symbol = Some(saved_symbol);
}
fn saved_symbol(&self) -> Option<Symbol> {
self.saved_symbol.clone()
}
}
impl Named for FullyQualifiedName {
fn name(&self) -> Cow<'_, str> {
if self.identifiers.len() == 1 {
self.identifiers[0].name()
} else {
let mut acc = String::new();
for (i, identifier) in self.identifiers.iter().enumerate() {
acc += &identifier.name();
if i < self.identifiers.len() - 1 {
acc += "::";
}
}
Cow::Owned(acc)
}
}
fn file_id(&self) -> usize {
self.file_id
}
fn range(&self) -> Range<usize> {
self.range
}
fn set_scope_id(&mut self, id: usize) {
self.scope_id = Some(id);
}
fn scope_id(&self) -> Option<usize> {
self.scope_id
}
fn set_saved_symbol(&mut self, symbol: Symbol) {
self.saved_symbol = Some(symbol);
}
fn saved_symbol(&self) -> Option<Symbol> {
self.saved_symbol.clone()
}
}

View File

@ -0,0 +1,106 @@
use crate::ast::node::expression::Expression;
use crate::ast::node::generics::GenericArguments;
#[derive(Debug)]
pub struct CallExpression {
callee: Box<Expression>,
turbo_fish: Option<Box<TurboFish>>,
arguments: Box<CallArguments>,
}
impl CallExpression {
pub fn new(
callee: Box<Expression>,
turbo_fish: Option<Box<TurboFish>>,
arguments: Box<CallArguments>,
) -> Self {
Self {
callee,
turbo_fish,
arguments,
}
}
pub fn callee(&self) -> &Expression {
&self.callee
}
pub fn callee_mut(&mut self) -> &mut Expression {
&mut self.callee
}
pub fn turbo_fish(&self) -> Option<&TurboFish> {
if let Some(turbo_fish) = &self.turbo_fish {
Some(turbo_fish.as_ref())
} else {
None
}
}
pub fn turbo_fish_mut(&mut self) -> Option<&mut TurboFish> {
if let Some(turbo_fish) = &mut self.turbo_fish {
Some(turbo_fish.as_mut())
} else {
None
}
}
pub fn arguments(&self) -> &CallArguments {
&self.arguments
}
pub fn arguments_mut(&mut self) -> &mut CallArguments {
&mut self.arguments
}
}
#[derive(Debug)]
pub struct TurboFish(Box<GenericArguments>);
impl TurboFish {
pub fn new(generics: Box<GenericArguments>) -> Self {
Self(generics)
}
pub fn generics(&self) -> &GenericArguments {
&self.0
}
pub fn generics_mut(&mut self) -> &mut GenericArguments {
&mut self.0
}
}
#[derive(Debug)]
pub struct CallArguments(Vec<Box<CallArgument>>);
impl CallArguments {
pub fn new(arguments: Vec<Box<CallArgument>>) -> Self {
Self(arguments)
}
pub fn arguments(&self) -> Vec<&CallArgument> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn arguments_mut(&mut self) -> Vec<&mut CallArgument> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}
#[derive(Debug)]
pub struct CallArgument(Box<Expression>);
impl CallArgument {
pub fn new(expression: Box<Expression>) -> Self {
Self(expression)
}
pub fn expression(&self) -> &Expression {
&self.0
}
pub fn expression_mut(&mut self) -> &mut Expression {
&mut self.0
}
}

184
src/ast/node/class.rs Normal file
View File

@ -0,0 +1,184 @@
use crate::ast::node::generics::GenericParameters;
use crate::ast::node::implements_list::ImplementsList;
use crate::ast::node::level::ClassLevelDeclaration;
use crate::ast::node::names::Identifier;
use crate::ast::node::type_use::TypeUse;
#[derive(Debug)]
pub struct ClassDeclaration {
is_public: bool,
identifier: Box<Identifier>,
generics: Box<GenericParameters>,
class_constructor: Option<Box<ClassConstructor>>,
implements: Box<ImplementsList>,
declarations: Vec<Box<ClassLevelDeclaration>>,
}
impl ClassDeclaration {
pub fn new(
is_public: bool,
identifier: Box<Identifier>,
generics: Box<GenericParameters>,
class_constructor: Option<Box<ClassConstructor>>,
implements: Box<ImplementsList>,
declarations: Vec<Box<ClassLevelDeclaration>>,
) -> Self {
Self {
is_public,
identifier,
generics,
class_constructor,
implements,
declarations,
}
}
pub fn is_public(&self) -> bool {
self.is_public
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn generics(&self) -> &GenericParameters {
&self.generics
}
pub fn generics_mut(&mut self) -> &mut GenericParameters {
&mut self.generics
}
pub fn class_constructor(&self) -> Option<&ClassConstructor> {
if let Some(class_constructor) = &self.class_constructor {
Some(class_constructor.as_ref())
} else {
None
}
}
pub fn class_constructor_mut(&mut self) -> Option<&mut ClassConstructor> {
if let Some(class_constructor) = &mut self.class_constructor {
Some(class_constructor.as_mut())
} else {
None
}
}
pub fn implements(&self) -> &ImplementsList {
&self.implements
}
pub fn implements_mut(&mut self) -> &mut ImplementsList {
&mut self.implements
}
pub fn declarations(&self) -> Vec<&ClassLevelDeclaration> {
self.declarations.iter().map(Box::as_ref).collect()
}
pub fn declarations_mut(&mut self) -> Vec<&mut ClassLevelDeclaration> {
self.declarations.iter_mut().map(Box::as_mut).collect()
}
}
#[derive(Debug)]
pub struct ClassConstructor(Vec<Box<ClassConstructorParameter>>);
impl ClassConstructor {
pub fn new(parameters: Vec<Box<ClassConstructorParameter>>) -> Self {
Self(parameters)
}
pub fn parameters(&self) -> Vec<&ClassConstructorParameter> {
self.0.iter().map(|p| p.as_ref()).collect()
}
pub fn parameters_mut(&mut self) -> Vec<&mut ClassConstructorParameter> {
self.0.iter_mut().map(|p| p.as_mut()).collect()
}
}
#[derive(Debug)]
pub enum ClassConstructorParameter {
Property(Box<PropertyDeclaration>),
Field(Box<FieldDeclaration>),
}
#[derive(Debug)]
pub struct PropertyDeclaration {
is_mutable: bool,
identifier: Box<Identifier>,
declared_type: Box<TypeUse>,
}
impl PropertyDeclaration {
pub fn new(is_mutable: bool, identifier: Box<Identifier>, declared_type: Box<TypeUse>) -> Self {
Self {
is_mutable,
identifier,
declared_type,
}
}
pub fn is_mutable(&self) -> bool {
self.is_mutable
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn declared_type(&self) -> &TypeUse {
&self.declared_type
}
pub fn declared_type_mut(&mut self) -> &mut TypeUse {
&mut self.declared_type
}
}
#[derive(Debug)]
pub struct FieldDeclaration {
is_mutable: bool,
identifier: Box<Identifier>,
declared_type: Box<TypeUse>,
}
impl FieldDeclaration {
pub fn new(is_mutable: bool, identifier: Box<Identifier>, declared_type: Box<TypeUse>) -> Self {
Self {
is_mutable,
identifier,
declared_type,
}
}
pub fn is_mutable(&self) -> bool {
self.is_mutable
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn declared_type(&self) -> &TypeUse {
&self.declared_type
}
pub fn declared_type_mut(&mut self) -> &mut TypeUse {
&mut self.declared_type
}
}

204
src/ast/node/closure.rs Normal file
View File

@ -0,0 +1,204 @@
use crate::ast::node::expression::Expression;
use crate::ast::node::names::Identifier;
use crate::ast::node::statement::Statement;
use crate::ast::node::type_use::TypeUse;
#[derive(Debug)]
pub struct Closure {
modifier: Option<ClosureModifier>,
is_move: bool,
captures: Box<ClosureCaptures>,
parameters: Box<ClosureParameters>,
statements: Vec<Box<Statement>>,
expression: Option<Box<Expression>>,
}
impl Closure {
pub fn new(
modifier: Option<ClosureModifier>,
is_move: bool,
captures: Box<ClosureCaptures>,
parameters: Box<ClosureParameters>,
statements: Vec<Box<Statement>>,
expression: Option<Box<Expression>>,
) -> Self {
Self {
modifier,
is_move,
captures,
parameters,
statements,
expression,
}
}
pub fn modifier(&self) -> Option<&ClosureModifier> {
self.modifier.as_ref()
}
pub fn is_move(&self) -> bool {
self.is_move
}
pub fn captures(&self) -> &ClosureCaptures {
&self.captures
}
pub fn captures_mut(&mut self) -> &mut ClosureCaptures {
&mut self.captures
}
pub fn parameters(&self) -> &ClosureParameters {
&self.parameters
}
pub fn parameters_mut(&mut self) -> &mut ClosureParameters {
&mut self.parameters
}
pub fn statements(&self) -> Vec<&Statement> {
self.statements.iter().map(Box::as_ref).collect()
}
pub fn statements_mut(&mut self) -> Vec<&mut Statement> {
self.statements.iter_mut().map(Box::as_mut).collect()
}
pub fn expression(&self) -> Option<&Expression> {
if let Some(expression) = &self.expression {
Some(expression)
} else {
None
}
}
pub fn expression_mut(&mut self) -> Option<&mut Expression> {
if let Some(expression) = &mut self.expression {
Some(expression)
} else {
None
}
}
}
#[derive(Debug)]
pub enum ClosureModifier {
Cons,
Mut,
}
#[derive(Debug, Default)]
pub struct ClosureCaptures(Vec<Box<ClosureCapture>>);
impl ClosureCaptures {
pub fn new(captures: Vec<Box<ClosureCapture>>) -> Self {
Self(captures)
}
pub fn captures(&self) -> Vec<&ClosureCapture> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn captures_mut(&mut self) -> Vec<&mut ClosureCapture> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}
impl ClosureCaptures {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct ClosureCapture {
borrow_count: usize,
is_mutable: bool,
identifier: Box<Identifier>,
}
impl ClosureCapture {
pub fn new(borrow_count: usize, is_mutable: bool, identifier: Box<Identifier>) -> Self {
Self {
borrow_count,
is_mutable,
identifier,
}
}
pub fn borrow_count(&self) -> usize {
self.borrow_count
}
pub fn is_mutable(&self) -> bool {
self.is_mutable
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
}
#[derive(Debug, Default)]
pub struct ClosureParameters(Vec<Box<ClosureParameter>>);
impl ClosureParameters {
pub fn new(parameters: Vec<Box<ClosureParameter>>) -> Self {
Self(parameters)
}
pub fn parameters(&self) -> Vec<&ClosureParameter> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn parameters_mut(&mut self) -> Vec<&mut ClosureParameter> {
self.0.iter_mut().map(Box::as_mut).collect()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct ClosureParameter {
identifier: Box<Identifier>,
type_use: Option<Box<TypeUse>>,
}
impl ClosureParameter {
pub fn new(identifier: Box<Identifier>, type_use: Option<Box<TypeUse>>) -> Self {
Self {
identifier,
type_use,
}
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn type_use(&self) -> Option<&TypeUse> {
if let Some(type_use) = &self.type_use {
Some(type_use)
} else {
None
}
}
pub fn type_use_mut(&mut self) -> Option<&mut TypeUse> {
if let Some(type_use) = &mut self.type_use {
Some(type_use.as_mut())
} else {
None
}
}
}

View File

@ -0,0 +1,63 @@
use crate::ast::node::level::ModuleLevelDeclaration;
use crate::ast::node::names::FullyQualifiedName;
use crate::ast::node::use_statement::UseStatement;
#[derive(Debug)]
pub struct CompilationUnit {
file_name: String,
file_id: usize,
namespace: Option<Box<FullyQualifiedName>>,
use_statements: Vec<Box<UseStatement>>,
declarations: Vec<Box<ModuleLevelDeclaration>>,
}
impl CompilationUnit {
pub fn new(
file_name: String,
file_id: usize,
namespace: Option<Box<FullyQualifiedName>>,
use_statements: Vec<Box<UseStatement>>,
declarations: Vec<Box<ModuleLevelDeclaration>>,
) -> Self {
Self {
file_name,
file_id,
namespace,
use_statements,
declarations,
}
}
pub fn file_name(&self) -> &str {
&self.file_name
}
pub fn file_id(&self) -> usize {
self.file_id
}
pub fn namespace(&self) -> Option<&FullyQualifiedName> {
// We have to use this non-map syntax because we need a reference like `&self.namespace`
if let Some(namespace) = &self.namespace {
Some(namespace.as_ref())
} else {
None
}
}
pub fn use_statements(&self) -> Vec<&UseStatement> {
self.use_statements.iter().map(Box::as_ref).collect()
}
pub fn use_statements_mut(&mut self) -> Vec<&mut UseStatement> {
self.use_statements.iter_mut().map(Box::as_mut).collect()
}
pub fn declarations(&self) -> Vec<&ModuleLevelDeclaration> {
self.declarations.iter().map(Box::as_ref).collect()
}
pub fn declarations_mut(&mut self) -> Vec<&mut ModuleLevelDeclaration> {
self.declarations.iter_mut().map(Box::as_mut).collect()
}
}

55
src/ast/node/d_string.rs Normal file
View File

@ -0,0 +1,55 @@
use crate::ast::node::expression::Expression;
#[derive(Debug)]
pub struct DString(Vec<Box<DStringPart>>);
impl DString {
pub fn new(parts: Vec<Box<DStringPart>>) -> Self {
Self(parts)
}
pub fn parts(&self) -> Vec<&DStringPart> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn parts_mut(&mut self) -> Vec<&mut DStringPart> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}
#[derive(Debug)]
pub enum DStringPart {
String(String),
Expression(Box<Expression>),
}
impl DStringPart {
pub fn from_string(s: &str) -> DStringPart {
DStringPart::String(String::from(s))
}
pub fn from_expression(e: Expression) -> DStringPart {
DStringPart::Expression(Box::new(e))
}
pub fn is_string(&self) -> bool {
match self {
DStringPart::String(_) => true,
_ => false,
}
}
pub fn unwrap_string(self) -> String {
match self {
DStringPart::String(s) => s,
_ => panic!(),
}
}
pub fn is_expression(&self) -> bool {
match self {
DStringPart::Expression(_) => true,
_ => false,
}
}
}

155
src/ast/node/expression.rs Normal file
View File

@ -0,0 +1,155 @@
use crate::ast::node::call_expression::CallExpression;
use crate::ast::node::closure::Closure;
use crate::ast::node::literal::Literal;
use crate::ast::node::names::FullyQualifiedName;
use crate::ast::node::object_access::ObjectAccess;
use crate::ast::node::operators::{BinaryOperator, PrefixUnaryOperator, SuffixUnaryOperator};
#[derive(Debug)]
pub enum Expression {
Ternary(Box<TernaryExpression>),
Binary(Box<BinaryExpression>),
UnaryPrefix(Box<PrefixExpression>),
UnarySuffix(Box<SuffixExpression>),
Call(Box<CallExpression>),
ObjectAccess(Box<ObjectAccess>),
Literal(Box<Literal>),
FullyQualifiedName(Box<FullyQualifiedName>),
Closure(Box<Closure>),
}
#[derive(Debug)]
pub struct TernaryExpression {
condition: Box<Expression>,
true_expression: Box<Expression>,
false_expression: Box<Expression>,
}
impl TernaryExpression {
pub fn new(
condition: Box<Expression>,
true_expression: Box<Expression>,
false_expression: Box<Expression>,
) -> Self {
Self {
condition,
true_expression,
false_expression,
}
}
pub fn condition(&self) -> &Expression {
&self.condition
}
pub fn condition_mut(&mut self) -> &mut Expression {
&mut self.condition
}
pub fn true_expression(&self) -> &Expression {
&self.true_expression
}
pub fn true_expression_mut(&mut self) -> &mut Expression {
&mut self.true_expression
}
pub fn false_expression(&self) -> &Expression {
&self.false_expression
}
pub fn false_expression_mut(&mut self) -> &mut Expression {
&mut self.false_expression
}
}
#[derive(Debug)]
pub struct BinaryExpression {
left: Box<Expression>,
operator: BinaryOperator,
right: Box<Expression>,
}
impl BinaryExpression {
pub fn new(left: Box<Expression>, operator: BinaryOperator, right: Box<Expression>) -> Self {
Self {
left,
operator,
right,
}
}
pub fn left(&self) -> &Expression {
&self.left
}
pub fn left_mut(&mut self) -> &mut Expression {
&mut self.left
}
pub fn operator(&self) -> &BinaryOperator {
&self.operator
}
pub fn right(&self) -> &Expression {
&self.right
}
pub fn right_mut(&mut self) -> &mut Expression {
&mut self.right
}
}
#[derive(Debug)]
pub struct PrefixExpression {
operator: PrefixUnaryOperator,
expression: Box<Expression>,
}
impl PrefixExpression {
pub fn new(operator: PrefixUnaryOperator, expression: Box<Expression>) -> Self {
Self {
operator,
expression,
}
}
pub fn operator(&self) -> &PrefixUnaryOperator {
&self.operator
}
pub fn expression(&self) -> &Expression {
&self.expression
}
pub fn expression_mut(&mut self) -> &mut Expression {
&mut self.expression
}
}
#[derive(Debug)]
pub struct SuffixExpression {
expression: Box<Expression>,
operator: SuffixUnaryOperator,
}
impl SuffixExpression {
pub fn new(expression: Box<Expression>, operator: SuffixUnaryOperator) -> Self {
Self {
expression,
operator,
}
}
pub fn expression(&self) -> &Expression {
&self.expression
}
pub fn expression_mut(&mut self) -> &mut Expression {
&mut self.expression
}
pub fn operator(&self) -> &SuffixUnaryOperator {
&self.operator
}
}

543
src/ast/node/function.rs Normal file
View File

@ -0,0 +1,543 @@
use crate::ast::node::expression::Expression;
use crate::ast::node::generics::GenericParameters;
use crate::ast::node::names::Identifier;
use crate::ast::node::operators::Operator;
use crate::ast::node::statement::BlockStatement;
use crate::ast::node::type_use::{PrimitiveTypeUse, TypeUse};
#[derive(Debug)]
pub enum FunctionTypeModifier {
Cons,
MutRef,
Mut,
Ref,
}
#[derive(Debug)]
pub struct Parameters(Vec<Box<Parameter>>);
impl Parameters {
pub fn new(parameters: Vec<Box<Parameter>>) -> Self {
Self(parameters)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn parameters(&self) -> Vec<&Parameter> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn parameters_mut(&mut self) -> Vec<&mut Parameter> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}
impl Default for Parameters {
fn default() -> Self {
Parameters(Vec::new())
}
}
#[derive(Debug)]
pub struct Parameter {
identifier: Box<Identifier>,
type_use: Box<TypeUse>,
}
impl Parameter {
pub fn new(identifier: Box<Identifier>, type_use: Box<TypeUse>) -> Self {
Self {
identifier,
type_use,
}
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn type_use(&self) -> &TypeUse {
&self.type_use
}
pub fn type_use_mut(&mut self) -> &mut TypeUse {
&mut self.type_use
}
}
#[derive(Debug)]
pub struct ReturnType {
declared_type: Box<TypeUse>,
references: Box<References>,
}
impl ReturnType {
pub fn new(declared_type: Box<TypeUse>, references: Box<References>) -> Self {
Self {
declared_type,
references,
}
}
pub fn void() -> Self {
ReturnType {
declared_type: Box::new(TypeUse::Primitive(Box::new(PrimitiveTypeUse::Void))),
references: Box::new(References::default()),
}
}
pub fn declared_type(&self) -> &TypeUse {
&self.declared_type
}
pub fn declared_type_mut(&mut self) -> &mut TypeUse {
&mut self.declared_type
}
pub fn references(&self) -> &References {
&self.references
}
pub fn references_mut(&mut self) -> &mut References {
&mut self.references
}
}
#[derive(Debug)]
pub struct References(Vec<Box<Identifier>>);
impl References {
pub fn new(identifiers: Vec<Box<Identifier>>) -> Self {
Self(identifiers)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn identifiers(&self) -> Vec<&Identifier> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}
impl Default for References {
fn default() -> Self {
References(Vec::new())
}
}
#[derive(Debug)]
pub struct FunctionDefinition {
is_public: bool,
modifier: Option<FunctionModifier>,
generics: Box<GenericParameters>,
identifier: Box<Identifier>,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
body: Box<FunctionBody>,
}
impl FunctionDefinition {
pub fn new(
is_public: bool,
modifier: Option<FunctionModifier>,
generics: Box<GenericParameters>,
identifier: Box<Identifier>,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
body: Box<FunctionBody>,
) -> Self {
Self {
is_public,
modifier,
generics,
identifier,
parameters,
return_type,
body,
}
}
pub fn is_public(&self) -> bool {
self.is_public
}
pub fn modifier(&self) -> Option<&FunctionModifier> {
self.modifier.as_ref()
}
pub fn generics(&self) -> &GenericParameters {
&self.generics
}
pub fn generics_mut(&mut self) -> &mut GenericParameters {
&mut self.generics
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn parameters(&self) -> &Parameters {
&self.parameters
}
pub fn parameters_mut(&mut self) -> &mut Parameters {
&mut self.parameters
}
pub fn return_type(&self) -> &ReturnType {
&self.return_type
}
pub fn return_type_mut(&mut self) -> &mut ReturnType {
&mut self.return_type
}
pub fn body(&self) -> &FunctionBody {
&self.body
}
pub fn body_mut(&mut self) -> &mut FunctionBody {
&mut self.body
}
}
#[derive(Debug)]
pub struct OperatorFunctionDefinition {
is_public: bool,
modifier: Option<FunctionModifier>,
generics: Box<GenericParameters>,
operator: Operator,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
body: Box<FunctionBody>,
}
impl OperatorFunctionDefinition {
pub fn new(
is_public: bool,
modifier: Option<FunctionModifier>,
generics: Box<GenericParameters>,
operator: Operator,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
body: Box<FunctionBody>,
) -> Self {
Self {
is_public,
modifier,
generics,
operator,
parameters,
return_type,
body,
}
}
pub fn is_public(&self) -> bool {
self.is_public
}
pub fn modifier(&self) -> Option<&FunctionModifier> {
self.modifier.as_ref()
}
pub fn generics(&self) -> &GenericParameters {
&self.generics
}
pub fn generics_mut(&mut self) -> &mut GenericParameters {
&mut self.generics
}
pub fn operator(&self) -> &Operator {
&self.operator
}
pub fn parameters(&self) -> &Parameters {
&self.parameters
}
pub fn parameters_mut(&mut self) -> &mut Parameters {
&mut self.parameters
}
pub fn return_type(&self) -> &ReturnType {
&self.return_type
}
pub fn return_type_mut(&mut self) -> &mut ReturnType {
&mut self.return_type
}
pub fn body(&self) -> &FunctionBody {
&self.body
}
pub fn body_mut(&mut self) -> &mut FunctionBody {
&mut self.body
}
}
#[derive(Debug)]
pub struct PlatformFunctionDeclaration {
is_public: bool,
modifier: Option<FunctionModifier>,
generics: Box<GenericParameters>,
identifier: Box<Identifier>,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
}
impl PlatformFunctionDeclaration {
pub fn new(
is_public: bool,
modifier: Option<FunctionModifier>,
generics: Box<GenericParameters>,
identifier: Box<Identifier>,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
) -> Self {
Self {
is_public,
modifier,
generics,
identifier,
parameters,
return_type,
}
}
pub fn is_public(&self) -> bool {
self.is_public
}
pub fn modifier(&self) -> Option<&FunctionModifier> {
self.modifier.as_ref()
}
pub fn generics(&self) -> &GenericParameters {
&self.generics
}
pub fn generics_mut(&mut self) -> &mut GenericParameters {
&mut self.generics
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn parameters(&self) -> &Parameters {
&self.parameters
}
pub fn parameters_mut(&mut self) -> &mut Parameters {
&mut self.parameters
}
pub fn return_type(&self) -> &ReturnType {
&self.return_type
}
pub fn return_type_mut(&mut self) -> &mut ReturnType {
&mut self.return_type
}
}
#[derive(Debug)]
pub struct InterfaceFunctionDeclaration {
modifier: Option<FunctionModifier>,
generics: Box<GenericParameters>,
identifier: Box<Identifier>,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
body: Option<Box<FunctionBody>>,
}
impl InterfaceFunctionDeclaration {
pub fn new(
modifier: Option<FunctionModifier>,
generics: Box<GenericParameters>,
identifier: Box<Identifier>,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
body: Option<Box<FunctionBody>>,
) -> Self {
Self {
modifier,
generics,
identifier,
parameters,
return_type,
body,
}
}
pub fn modifier(&self) -> Option<&FunctionModifier> {
self.modifier.as_ref()
}
pub fn generics(&self) -> &GenericParameters {
&self.generics
}
pub fn generics_mut(&mut self) -> &mut GenericParameters {
&mut self.generics
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn parameters(&self) -> &Parameters {
&self.parameters
}
pub fn parameters_mut(&mut self) -> &mut Parameters {
&mut self.parameters
}
pub fn return_type(&self) -> &ReturnType {
&self.return_type
}
pub fn return_type_mut(&mut self) -> &mut ReturnType {
&mut self.return_type
}
pub fn body(&self) -> Option<&FunctionBody> {
FunctionBody::unwrap_option(&self.body)
}
pub fn body_mut(&mut self) -> Option<&mut FunctionBody> {
FunctionBody::unwrap_option_mut(&mut self.body)
}
}
#[derive(Debug)]
pub struct InterfaceOperatorFunctionDeclaration {
modifier: Option<FunctionModifier>,
generics: Box<GenericParameters>,
operator: Operator,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
body: Option<Box<FunctionBody>>,
}
impl InterfaceOperatorFunctionDeclaration {
pub fn new(
modifier: Option<FunctionModifier>,
generics: Box<GenericParameters>,
operator: Operator,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
body: Option<Box<FunctionBody>>,
) -> Self {
Self {
modifier,
generics,
operator,
parameters,
return_type,
body,
}
}
pub fn modifier(&self) -> Option<&FunctionModifier> {
self.modifier.as_ref()
}
pub fn generics(&self) -> &GenericParameters {
&self.generics
}
pub fn generics_mut(&mut self) -> &mut GenericParameters {
&mut self.generics
}
pub fn operator(&self) -> &Operator {
&self.operator
}
pub fn parameters(&self) -> &Box<Parameters> {
&self.parameters
}
pub fn parameters_mut(&mut self) -> &mut Box<Parameters> {
&mut self.parameters
}
pub fn return_type(&self) -> &ReturnType {
&self.return_type
}
pub fn return_type_mut(&mut self) -> &mut ReturnType {
&mut self.return_type
}
pub fn body(&self) -> Option<&FunctionBody> {
FunctionBody::unwrap_option(&self.body)
}
pub fn body_mut(&mut self) -> Option<&mut FunctionBody> {
FunctionBody::unwrap_option_mut(&mut self.body)
}
}
#[derive(Debug)]
pub enum FunctionModifier {
Static,
Cons,
Mut,
Ref,
MutRef,
}
#[derive(Debug)]
pub enum FunctionBody {
Equals(Box<Expression>),
Block(Box<BlockStatement>),
Alias(Box<Identifier>),
}
impl FunctionBody {
fn unwrap_option(opt: &Option<Box<FunctionBody>>) -> Option<&FunctionBody> {
if let Some(body) = opt {
Some(body.as_ref())
} else {
None
}
}
fn unwrap_option_mut(opt: &mut Option<Box<FunctionBody>>) -> Option<&mut FunctionBody> {
if let Some(body) = opt {
Some(body.as_mut())
} else {
None
}
}
}

56
src/ast/node/generics.rs Normal file
View File

@ -0,0 +1,56 @@
use crate::ast::node::names::Identifier;
use crate::ast::node::type_use::TypeUse;
#[derive(Debug)]
pub struct GenericArguments(Vec<Box<TypeUse>>);
impl GenericArguments {
pub fn new(arguments: Vec<Box<TypeUse>>) -> Self {
Self(arguments)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn arguments(&self) -> Vec<&TypeUse> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn arguments_mut(&mut self) -> Vec<&mut TypeUse> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}
impl Default for GenericArguments {
fn default() -> Self {
GenericArguments(Vec::new())
}
}
#[derive(Debug)]
pub struct GenericParameters(Vec<Box<Identifier>>);
impl GenericParameters {
pub fn new(identifiers: Vec<Box<Identifier>>) -> Self {
Self(identifiers)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn identifiers(&self) -> Vec<&Identifier> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}
impl Default for GenericParameters {
fn default() -> Self {
GenericParameters(Vec::new())
}
}

View File

@ -0,0 +1,28 @@
use crate::ast::node::type_use::TypeUse;
#[derive(Debug)]
pub struct ImplementsList(Vec<Box<TypeUse>>);
impl ImplementsList {
pub fn new(type_uses: Vec<Box<TypeUse>>) -> Self {
Self(type_uses)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn type_uses(&self) -> Vec<&TypeUse> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn type_uses_mut(&mut self) -> Vec<&mut TypeUse> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}
impl Default for ImplementsList {
fn default() -> Self {
ImplementsList(Vec::new())
}
}

67
src/ast/node/interface.rs Normal file
View File

@ -0,0 +1,67 @@
use crate::ast::node::generics::GenericParameters;
use crate::ast::node::implements_list::ImplementsList;
use crate::ast::node::level::InterfaceLevelDeclaration;
use crate::ast::node::names::Identifier;
#[derive(Debug)]
pub struct InterfaceDeclaration {
is_public: bool,
identifier: Box<Identifier>,
generics: Box<GenericParameters>,
implements: Box<ImplementsList>,
declarations: Vec<Box<InterfaceLevelDeclaration>>,
}
impl InterfaceDeclaration {
pub fn new(
is_public: bool,
identifier: Box<Identifier>,
generics: Box<GenericParameters>,
implements: Box<ImplementsList>,
declarations: Vec<Box<InterfaceLevelDeclaration>>,
) -> Self {
Self {
is_public,
identifier,
generics,
implements,
declarations,
}
}
pub fn is_public(&self) -> bool {
self.is_public
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn generics(&self) -> &GenericParameters {
&self.generics
}
pub fn generics_mut(&mut self) -> &mut GenericParameters {
&mut self.generics
}
pub fn implements(&self) -> &ImplementsList {
&self.implements
}
pub fn implements_mut(&mut self) -> &mut ImplementsList {
&mut self.implements
}
pub fn declarations(&self) -> Vec<&InterfaceLevelDeclaration> {
self.declarations.iter().map(Box::as_ref).collect()
}
pub fn declarations_mut(&mut self) -> Vec<&mut InterfaceLevelDeclaration> {
self.declarations.iter_mut().map(Box::as_mut).collect()
}
}

37
src/ast/node/level.rs Normal file
View File

@ -0,0 +1,37 @@
use crate::ast::node::class::{ClassDeclaration, FieldDeclaration, PropertyDeclaration};
use crate::ast::node::function::{
FunctionDefinition, InterfaceFunctionDeclaration, InterfaceOperatorFunctionDeclaration,
OperatorFunctionDefinition, PlatformFunctionDeclaration,
};
use crate::ast::node::interface::InterfaceDeclaration;
use crate::ast::node::module::ModuleDeclaration;
#[derive(Debug)]
pub enum ModuleLevelDeclaration {
Module(Box<ModuleDeclaration>),
Interface(Box<InterfaceDeclaration>),
Class(Box<ClassDeclaration>),
Function(Box<FunctionDefinition>),
PlatformFunction(Box<PlatformFunctionDeclaration>),
}
#[derive(Debug)]
pub enum InterfaceLevelDeclaration {
Module(Box<ModuleDeclaration>),
Interface(Box<InterfaceDeclaration>),
Class(Box<ClassDeclaration>),
Function(Box<InterfaceFunctionDeclaration>),
OperatorFunction(Box<InterfaceOperatorFunctionDeclaration>),
}
#[derive(Debug)]
pub enum ClassLevelDeclaration {
Module(Box<ModuleDeclaration>),
Interface(Box<InterfaceDeclaration>),
Class(Box<ClassDeclaration>),
Function(Box<FunctionDefinition>),
OperatorFunction(Box<OperatorFunctionDefinition>),
PlatformFunction(Box<PlatformFunctionDeclaration>),
Property(Box<PropertyDeclaration>),
Field(Box<FieldDeclaration>),
}

13
src/ast/node/literal.rs Normal file
View File

@ -0,0 +1,13 @@
use crate::ast::node::d_string::DString;
#[derive(Debug)]
pub enum Literal {
Integer(i32),
Long(i64),
Double(f64),
USize(usize),
String(String),
DString(Box<DString>),
BacktickString(Box<DString>),
Boolean(bool),
}

21
src/ast/node/mod.rs Normal file
View File

@ -0,0 +1,21 @@
pub mod call_expression;
pub mod class;
pub mod closure;
pub mod compilation_unit;
pub mod d_string;
pub mod expression;
pub mod function;
pub mod generics;
pub mod implements_list;
pub mod interface;
pub mod level;
pub mod literal;
pub mod module;
pub mod named;
pub mod names;
pub mod object_access;
pub mod operators;
pub mod statement;
pub mod tuple_arguments;
pub mod type_use;
pub mod use_statement;

43
src/ast/node/module.rs Normal file
View File

@ -0,0 +1,43 @@
use crate::ast::node::level::ModuleLevelDeclaration;
use crate::ast::node::names::Identifier;
#[derive(Debug)]
pub struct ModuleDeclaration {
is_public: bool,
identifier: Box<Identifier>,
declarations: Vec<Box<ModuleLevelDeclaration>>,
}
impl ModuleDeclaration {
pub fn new(
is_public: bool,
identifier: Box<Identifier>,
declarations: Vec<Box<ModuleLevelDeclaration>>,
) -> Self {
Self {
is_public,
identifier,
declarations,
}
}
pub fn is_public(&self) -> bool {
self.is_public
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn declarations(&self) -> Vec<&ModuleLevelDeclaration> {
self.declarations.iter().map(Box::as_ref).collect()
}
pub fn declarations_mut(&mut self) -> Vec<&mut ModuleLevelDeclaration> {
self.declarations.iter_mut().map(Box::as_mut).collect()
}
}

16
src/ast/node/named.rs Normal file
View File

@ -0,0 +1,16 @@
use crate::name_analysis::symbol::Symbol;
use std::borrow::Cow;
use std::range::Range;
pub trait Named {
fn name(&self) -> Cow<'_, str>;
fn file_id(&self) -> usize;
fn range(&self) -> Range<usize>;
fn set_scope_id(&mut self, scope_id: usize);
fn scope_id(&self) -> Option<usize>;
fn set_saved_symbol(&mut self, symbol: Symbol);
fn saved_symbol(&self) -> Option<Symbol>;
}

146
src/ast/node/names.rs Normal file
View File

@ -0,0 +1,146 @@
use std::borrow::Cow;
use crate::name_analysis::symbol::Symbol;
use std::range::Range;
use crate::ast::node::named::Named;
#[derive(Debug)]
pub struct Identifier {
name: String,
file_id: usize,
range: Range<usize>,
scope_id: Option<usize>,
saved_symbol: Option<Symbol>,
}
impl Identifier {
pub fn new(name: &str, file_id: usize, range: Range<usize>) -> Self {
Self {
name: name.to_string(),
file_id,
range,
scope_id: None,
saved_symbol: None,
}
}
}
impl Named for Identifier {
fn name(&self) -> Cow<'_, str> {
Cow::Borrowed(&self.name)
}
fn file_id(&self) -> usize {
self.file_id
}
fn range(&self) -> Range<usize> {
self.range
}
fn set_scope_id(&mut self, id: usize) {
self.scope_id = Some(id);
}
fn scope_id(&self) -> Option<usize> {
self.scope_id
}
fn set_saved_symbol(&mut self, saved_symbol: Symbol) {
self.saved_symbol = Some(saved_symbol);
}
fn saved_symbol(&self) -> Option<Symbol> {
self.saved_symbol.clone()
}
}
#[derive(Debug)]
pub struct FullyQualifiedName {
identifiers: Vec<Box<Identifier>>,
file_id: usize,
range: Range<usize>,
scope_id: Option<usize>,
saved_symbol: Option<Symbol>,
}
impl FullyQualifiedName {
pub fn new(identifiers: Vec<Box<Identifier>>, file_id: usize, range: Range<usize>) -> Self {
Self {
identifiers,
range,
file_id,
scope_id: None,
saved_symbol: None,
}
}
pub fn identifiers(&self) -> Vec<&Identifier> {
self.identifiers.iter().map(Box::as_ref).collect()
}
pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> {
self.identifiers.iter_mut().map(Box::as_mut).collect()
}
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
pub fn last(&self) -> &Identifier {
&self.identifiers[self.identifiers.len() - 1]
}
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
pub fn last_mut(&mut self) -> &mut Identifier {
let last_index = self.identifiers.len() - 1;
&mut self.identifiers[last_index]
}
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
pub fn len(&self) -> usize {
self.identifiers.len()
}
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
pub fn is_single_identifier(&self) -> bool {
self.identifiers.len() == 1
}
}
impl Named for FullyQualifiedName {
fn name(&self) -> Cow<'_, str> {
if self.identifiers.len() == 1 {
self.identifiers[0].name()
} else {
let mut acc = String::new();
for (i, identifier) in self.identifiers.iter().enumerate() {
acc += &identifier.name();
if i < self.identifiers.len() - 1 {
acc += "::";
}
}
Cow::Owned(acc)
}
}
fn file_id(&self) -> usize {
self.file_id
}
fn range(&self) -> Range<usize> {
self.range
}
fn set_scope_id(&mut self, id: usize) {
self.scope_id = Some(id);
}
fn scope_id(&self) -> Option<usize> {
self.scope_id
}
fn set_saved_symbol(&mut self, symbol: Symbol) {
self.saved_symbol = Some(symbol);
}
fn saved_symbol(&self) -> Option<Symbol> {
self.saved_symbol.clone()
}
}

View File

@ -0,0 +1,56 @@
use crate::ast::node::expression::Expression;
use crate::ast::node::names::Identifier;
#[derive(Debug)]
pub struct ObjectAccess {
receiver: Box<Expression>,
navigations: Box<ObjectNavigations>,
}
impl ObjectAccess {
pub fn new(receiver: Box<Expression>, navigations: Box<ObjectNavigations>) -> Self {
Self {
receiver,
navigations,
}
}
pub fn receiver(&self) -> &Expression {
&self.receiver
}
pub fn receiver_mut(&mut self) -> &mut Expression {
&mut self.receiver
}
pub fn navigations(&self) -> &ObjectNavigations {
&self.navigations
}
pub fn navigations_mut(&mut self) -> &mut ObjectNavigations {
&mut self.navigations
}
}
#[derive(Debug)]
pub struct ObjectNavigations(Vec<Box<ObjectNavigation>>);
impl ObjectNavigations {
pub fn new(navigations: Vec<Box<ObjectNavigation>>) -> Self {
Self(navigations)
}
pub fn navigations(&self) -> Vec<&ObjectNavigation> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn navigations_mut(&mut self) -> Vec<&mut ObjectNavigation> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}
#[derive(Debug)]
pub enum ObjectNavigation {
Index(Box<Expression>),
Identifier(Box<Identifier>),
}

44
src/ast/node/operators.rs Normal file
View File

@ -0,0 +1,44 @@
#[derive(Debug)]
pub enum Operator {
Binary(BinaryOperator),
PrefixUnary(PrefixUnaryOperator),
SuffixUnary(SuffixUnaryOperator),
}
#[derive(Debug)]
pub enum BinaryOperator {
Or,
And,
EqualTo,
NotEqualTo,
Greater,
Less,
GreaterEqual,
LessEqual,
Add,
Subtract,
Multiply,
Divide,
Modulo,
LeftShift,
RightShift,
}
#[derive(Debug)]
pub enum PrefixUnaryOperator {
Spread,
BorrowMut,
Borrow,
Star,
Mut,
Not,
Negative,
}
#[derive(Debug)]
pub enum SuffixUnaryOperator {
PlusPlus,
MinusMinus,
Call,
Index,
}

384
src/ast/node/statement.rs Normal file
View File

@ -0,0 +1,384 @@
use crate::ast::node::expression::Expression;
use crate::ast::node::names::Identifier;
use crate::ast::node::type_use::TypeUse;
#[derive(Debug)]
pub struct BlockStatement {
statements: Vec<Box<Statement>>,
expression: Option<Box<Expression>>,
}
impl BlockStatement {
pub fn new(statements: Vec<Box<Statement>>, expression: Option<Box<Expression>>) -> Self {
Self {
statements,
expression,
}
}
pub fn statements(&self) -> Vec<&Statement> {
self.statements.iter().map(AsRef::as_ref).collect()
}
pub fn statements_mut(&mut self) -> Vec<&mut Statement> {
self.statements.iter_mut().map(AsMut::as_mut).collect()
}
pub fn expression(&self) -> Option<&Expression> {
if let Some(ref expression) = self.expression {
Some(expression.as_ref())
} else {
None
}
}
pub fn expression_mut(&mut self) -> Option<&mut Expression> {
if let Some(ref mut expression) = self.expression {
Some(expression.as_mut())
} else {
None
}
}
}
#[derive(Debug)]
pub enum Statement {
BlockStatement(Box<BlockStatement>),
VariableDeclarationStatement(Box<VariableDeclarationStatement>),
AssignStatement(Box<AssignStatement>),
CallStatement(Box<CallStatement>),
ReturnStatement(Box<ReturnStatement>),
IfStatement(Box<IfStatement>),
IfElseStatement(Box<IfElseStatement>),
WhileStatement(Box<WhileStatement>),
ForStatement(Box<ForStatement>),
}
#[derive(Debug)]
pub struct VariableDeclarationStatement {
is_mutable: bool,
identifier: Box<Identifier>,
declared_type: Option<Box<TypeUse>>,
initializer: Option<Box<Expression>>,
}
impl VariableDeclarationStatement {
pub fn new(
is_mutable: bool,
identifier: Box<Identifier>,
declared_type: Option<Box<TypeUse>>,
initializer: Option<Box<Expression>>,
) -> Self {
Self {
is_mutable,
identifier,
declared_type,
initializer,
}
}
pub fn is_mutable(&self) -> bool {
self.is_mutable
}
pub fn identifier(&self) -> &Identifier {
&self.identifier
}
pub fn identifier_mut(&mut self) -> &mut Identifier {
&mut self.identifier
}
pub fn declared_type(&self) -> Option<&TypeUse> {
if let Some(type_use) = &self.declared_type {
Some(type_use.as_ref())
} else {
None
}
}
pub fn declared_type_mut(&mut self) -> Option<&mut TypeUse> {
if let Some(type_use) = &mut self.declared_type {
Some(type_use.as_mut())
} else {
None
}
}
pub fn initializer(&self) -> Option<&Expression> {
if let Some(initializer) = &self.initializer {
Some(initializer.as_ref())
} else {
None
}
}
pub fn initializer_mut(&mut self) -> Option<&mut Expression> {
if let Some(initializer) = &mut self.initializer {
Some(initializer.as_mut())
} else {
None
}
}
}
#[derive(Debug)]
pub struct AssignStatement {
lhs: Box<Expression>,
rhs: Box<Expression>,
}
impl AssignStatement {
pub fn new(lhs: Box<Expression>, rhs: Box<Expression>) -> Self {
Self { lhs, rhs }
}
pub fn lhs(&self) -> &Expression {
&self.lhs
}
pub fn lhs_mut(&mut self) -> &mut Expression {
&mut self.lhs
}
pub fn rhs(&self) -> &Expression {
&self.rhs
}
pub fn rhs_mut(&mut self) -> &mut Expression {
&mut self.rhs
}
}
#[derive(Debug)]
pub struct CallStatement(Box<Expression>);
impl CallStatement {
pub fn new(call_expression: Box<Expression>) -> Self {
Self(call_expression)
}
pub fn expression(&self) -> &Expression {
&self.0
}
pub fn expression_mut(&mut self) -> &mut Expression {
&mut self.0
}
}
#[derive(Debug)]
pub struct ReturnStatement(Option<Box<Expression>>);
impl ReturnStatement {
pub fn new(expression: Option<Box<Expression>>) -> Self {
Self(expression)
}
pub fn expression(&self) -> Option<&Expression> {
if let Some(expression) = &self.0 {
Some(expression.as_ref())
} else {
None
}
}
pub fn expression_mut(&mut self) -> Option<&mut Expression> {
if let Some(expression) = &mut self.0 {
Some(expression.as_mut())
} else {
None
}
}
}
#[derive(Debug)]
pub struct IfStatement {
condition: Box<Expression>,
then_block: Box<BlockStatement>,
}
impl IfStatement {
pub fn new(condition: Box<Expression>, then_block: Box<BlockStatement>) -> Self {
Self {
condition,
then_block,
}
}
pub fn condition(&self) -> &Expression {
&self.condition
}
pub fn condition_mut(&mut self) -> &mut Expression {
&mut self.condition
}
pub fn then_block(&self) -> &BlockStatement {
&self.then_block
}
pub fn then_block_mut(&mut self) -> &mut BlockStatement {
&mut self.then_block
}
}
#[derive(Debug)]
pub struct IfElseStatement {
if_statement: Box<IfStatement>,
else_ifs: Box<ElseIfs>,
else_block: Option<Box<ElseBlock>>,
}
impl IfElseStatement {
pub fn new(
if_statement: Box<IfStatement>,
else_ifs: Box<ElseIfs>,
else_block: Option<Box<ElseBlock>>,
) -> Self {
Self {
if_statement,
else_ifs,
else_block,
}
}
pub fn if_statement(&self) -> &IfStatement {
&self.if_statement
}
pub fn if_statement_mut(&mut self) -> &mut IfStatement {
&mut self.if_statement
}
pub fn else_ifs(&self) -> &ElseIfs {
&self.else_ifs
}
pub fn else_ifs_mut(&mut self) -> &mut ElseIfs {
&mut self.else_ifs
}
pub fn else_block(&self) -> Option<&ElseBlock> {
if let Some(else_block) = &self.else_block {
Some(else_block.as_ref())
} else {
None
}
}
pub fn else_block_mut(&mut self) -> Option<&mut ElseBlock> {
if let Some(else_block) = &mut self.else_block {
Some(else_block.as_mut())
} else {
None
}
}
}
#[derive(Debug, Default)]
pub struct ElseIfs(Vec<Box<IfStatement>>);
impl ElseIfs {
pub fn new(if_statements: Vec<Box<IfStatement>>) -> Self {
Self(if_statements)
}
pub fn if_statements(&self) -> Vec<&IfStatement> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn if_statements_mut(&mut self) -> Vec<&mut IfStatement> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}
#[derive(Debug)]
pub struct ElseBlock(Box<BlockStatement>);
impl ElseBlock {
pub fn new(block: Box<BlockStatement>) -> Self {
Self(block)
}
pub fn block_statement(&self) -> &BlockStatement {
&self.0
}
pub fn block_statement_mut(&mut self) -> &mut BlockStatement {
&mut self.0
}
}
#[derive(Debug)]
pub struct WhileStatement {
condition: Box<Expression>,
body: Box<BlockStatement>,
}
impl WhileStatement {
pub fn new(condition: Box<Expression>, body: Box<BlockStatement>) -> Self {
Self { condition, body }
}
pub fn condition(&self) -> &Expression {
&self.condition
}
pub fn condition_mut(&mut self) -> &mut Expression {
&mut self.condition
}
pub fn body(&self) -> &BlockStatement {
&self.body
}
pub fn body_mut(&mut self) -> &mut BlockStatement {
&mut self.body
}
}
#[derive(Debug)]
pub struct ForStatement {
variable: Box<Identifier>,
iterator: Box<Expression>,
body: Box<BlockStatement>,
}
impl ForStatement {
pub fn new(
variable: Box<Identifier>,
iterator: Box<Expression>,
body: Box<BlockStatement>,
) -> Self {
Self {
variable,
iterator,
body,
}
}
pub fn variable(&self) -> &Identifier {
&self.variable
}
pub fn variable_mut(&mut self) -> &mut Identifier {
&mut self.variable
}
pub fn iterator(&self) -> &Expression {
&self.iterator
}
pub fn iterator_mut(&mut self) -> &mut Expression {
&mut self.iterator
}
pub fn body(&self) -> &BlockStatement {
&self.body
}
pub fn body_mut(&mut self) -> &mut BlockStatement {
&mut self.body
}
}

View File

@ -0,0 +1,22 @@
use crate::ast::node::type_use::TypeUse;
#[derive(Debug)]
pub struct TupleArguments(Vec<Box<TypeUse>>);
impl TupleArguments {
pub fn new(arguments: Vec<Box<TypeUse>>) -> Self {
Self(arguments)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn type_uses(&self) -> Vec<&TypeUse> {
self.0.iter().map(Box::as_ref).collect()
}
pub fn type_uses_mut(&mut self) -> Vec<&mut TypeUse> {
self.0.iter_mut().map(Box::as_mut).collect()
}
}

167
src/ast/node/type_use.rs Normal file
View File

@ -0,0 +1,167 @@
use crate::ast::node::function::{FunctionTypeModifier, Parameters, ReturnType};
use crate::ast::node::generics::{GenericArguments, GenericParameters};
use crate::ast::node::names::FullyQualifiedName;
use crate::ast::node::tuple_arguments::TupleArguments;
#[derive(Debug)]
pub enum TypeUse {
Primitive(Box<PrimitiveTypeUse>),
InterfaceOrClass(Box<InterfaceOrClassTypeUse>),
Tuple(Box<TupleTypeUse>),
Function(Box<FunctionTypeUse>),
}
#[derive(Debug)]
pub enum PrimitiveTypeUse {
Byte,
Short,
Char,
Int,
Long,
Double,
Bool,
String,
Array(Option<Box<GenericArguments>>),
Any,
Void,
}
#[derive(Debug)]
pub struct InterfaceOrClassTypeUse {
borrow_count: usize,
is_mutable: bool,
fqn: Box<FullyQualifiedName>,
generics: Box<GenericArguments>,
}
impl InterfaceOrClassTypeUse {
pub fn new(
borrow_count: usize,
is_mutable: bool,
fqn: Box<FullyQualifiedName>,
generics: Box<GenericArguments>,
) -> Self {
Self {
borrow_count,
is_mutable,
fqn,
generics,
}
}
pub fn borrow_count(&self) -> usize {
self.borrow_count
}
pub fn is_mutable(&self) -> bool {
self.is_mutable
}
pub fn fqn(&self) -> &FullyQualifiedName {
&self.fqn
}
pub fn fqn_mut(&mut self) -> &mut FullyQualifiedName {
&mut self.fqn
}
pub fn generics(&self) -> &GenericArguments {
&self.generics
}
pub fn generics_mut(&mut self) -> &mut GenericArguments {
&mut self.generics
}
}
#[derive(Debug)]
pub struct TupleTypeUse {
borrow_count: usize,
is_mutable: bool,
arguments: Box<TupleArguments>,
}
impl TupleTypeUse {
pub fn new(borrow_count: usize, is_mutable: bool, arguments: Box<TupleArguments>) -> Self {
Self {
borrow_count,
is_mutable,
arguments,
}
}
pub fn borrow_count(&self) -> usize {
self.borrow_count
}
pub fn is_mutable(&self) -> bool {
self.is_mutable
}
pub fn arguments(&self) -> &TupleArguments {
&self.arguments
}
pub fn arguments_mut(&mut self) -> &mut TupleArguments {
&mut self.arguments
}
}
#[derive(Debug)]
pub struct FunctionTypeUse {
borrow_count: usize,
function_modifier: Option<FunctionTypeModifier>,
generics: Box<GenericParameters>,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
}
impl FunctionTypeUse {
pub fn new(
borrow_count: usize,
function_modifier: Option<FunctionTypeModifier>,
generics: Box<GenericParameters>,
parameters: Box<Parameters>,
return_type: Box<ReturnType>,
) -> Self {
Self {
borrow_count,
function_modifier,
generics,
parameters,
return_type,
}
}
pub fn borrow_count(&self) -> usize {
self.borrow_count
}
pub fn function_modifier(&self) -> Option<&FunctionTypeModifier> {
self.function_modifier.as_ref()
}
pub fn generics(&self) -> &GenericParameters {
&self.generics
}
pub fn generics_mut(&mut self) -> &mut GenericParameters {
&mut self.generics
}
pub fn parameters(&self) -> &Box<Parameters> {
&self.parameters
}
pub fn parameters_mut(&mut self) -> &mut Box<Parameters> {
&mut self.parameters
}
pub fn return_type(&self) -> &ReturnType {
&self.return_type
}
pub fn return_type_mut(&mut self) -> &mut ReturnType {
&mut self.return_type
}
}

View File

@ -0,0 +1,87 @@
use crate::ast::node::named::Named;
use crate::ast::node::names::Identifier;
use std::borrow::Cow;
use std::range::Range;
#[derive(Debug)]
pub struct UseStatement {
identifiers: Vec<Box<Identifier>>,
last: Box<UseStatementLast>,
file_id: usize,
range: Range<usize>,
}
impl UseStatement {
pub fn new(
identifiers: Vec<Box<Identifier>>,
last: Box<UseStatementLast>,
file_id: usize,
range: Range<usize>,
) -> Self {
UseStatement {
identifiers,
last,
file_id,
range,
}
}
pub fn base_name(&self) -> Cow<'_, str> {
use UseStatementLast::*;
if self.identifiers.is_empty() {
match self.last.as_ref() {
Identifier(_) => Cow::from(""),
Star | Identifiers(_) => panic!(), // should never get here because of grammar
}
} else if self.identifiers.len() == 1 {
self.identifiers[0].name()
} else {
let mut acc = String::new();
for (i, identifier) in self.identifiers.iter().enumerate() {
acc.push_str(&identifier.name());
if i != self.identifiers.len() - 1 {
acc.push_str("::");
}
}
Cow::from(acc)
}
}
pub fn is_star(&self) -> bool {
match self.last.as_ref() {
UseStatementLast::Star => true,
_ => false,
}
}
pub fn identifiers(&self) -> Vec<&Identifier> {
self.identifiers.iter().map(Box::as_ref).collect()
}
pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> {
self.identifiers.iter_mut().map(Box::as_mut).collect()
}
pub fn last(&self) -> &UseStatementLast {
&self.last
}
pub fn last_mut(&mut self) -> &mut UseStatementLast {
&mut self.last
}
pub fn file_id(&self) -> usize {
self.file_id
}
pub fn range(&self) -> Range<usize> {
self.range
}
}
#[derive(Debug)]
pub enum UseStatementLast {
Identifier(Box<Identifier>),
Identifiers(Vec<Box<Identifier>>),
Star,
}

View File

@ -1,4 +1,25 @@
use crate::ast::*;
use crate::ast::node::call_expression::*;
use crate::ast::node::class::*;
use crate::ast::node::closure::*;
use crate::ast::node::compilation_unit::*;
use crate::ast::node::d_string::*;
use crate::ast::node::expression::*;
use crate::ast::node::function::*;
use crate::ast::node::generics::*;
use crate::ast::node::implements_list::*;
use crate::ast::node::interface::*;
use crate::ast::node::level::*;
use crate::ast::node::literal::*;
use crate::ast::node::module::*;
use crate::ast::node::named::Named;
use crate::ast::node::names::*;
use crate::ast::node::object_access::*;
use crate::ast::node::operators::*;
use crate::ast::node::statement::*;
use crate::ast::node::tuple_arguments::*;
use crate::ast::node::type_use::*;
use crate::ast::node::use_statement::*;
use crate::ast::unparse::Unparse;
use crate::util::indent_writer::IndentWriter;
use std::fmt::Debug;
@ -8,7 +29,7 @@ pub trait PrettyPrint {
impl PrettyPrint for Operator {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use Operator::*;
use crate::ast::node::operators::Operator::*;
match self {
Binary(o) => o.pretty_print(writer),
PrefixUnary(o) => o.pretty_print(writer),
@ -20,24 +41,7 @@ impl PrettyPrint for Operator {
impl PrettyPrint for BinaryOperator {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.write_indented("BinaryOperator(")?;
use BinaryOperator::*;
match self {
Or => writer.write("||"),
And => writer.write("&&"),
EqualTo => writer.write("=="),
NotEqualTo => writer.write("!="),
Greater => writer.write(">"),
Less => writer.write("<"),
GreaterEqual => writer.write(">="),
LessEqual => writer.write("<="),
Add => writer.write("+"),
Subtract => writer.write("-"),
Multiply => writer.write("*"),
Divide => writer.write("/"),
Modulo => writer.write("%"),
LeftShift => writer.write("<<"),
RightShift => writer.write(">>"),
}?;
self.unparse(writer)?;
writer.writeln(")")?;
Ok(())
}
@ -46,15 +50,7 @@ impl PrettyPrint for BinaryOperator {
impl PrettyPrint for PrefixUnaryOperator {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.write_indented("PrefixUnaryOperator(")?;
use PrefixUnaryOperator::*;
match self {
Spread => writer.write("..."),
BorrowMut => writer.write("&mut"),
Borrow => writer.write("&"),
Mut => writer.write("mut"),
Not => writer.write("!"),
Negative => writer.write("-"),
}?;
self.unparse(writer)?;
writer.writeln(")")?;
Ok(())
}
@ -63,11 +59,7 @@ impl PrettyPrint for PrefixUnaryOperator {
impl PrettyPrint for SuffixUnaryOperator {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.write_indented("SuffixUnaryOperator(")?;
use SuffixUnaryOperator::*;
match self {
PlusPlus => writer.write("++"),
MinusMinus => writer.write("--"),
}?;
self.unparse(writer)?;
writer.write(")")?;
Ok(())
}
@ -75,7 +67,7 @@ impl PrettyPrint for SuffixUnaryOperator {
impl PrettyPrint for Identifier {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!("Identifier({})", self.name))
writer.writeln_indented(&format!("Identifier({})", self.name()))
}
}
@ -83,7 +75,7 @@ impl PrettyPrint for FullyQualifiedName {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("FullyQualifiedName")?;
writer.increase_indent();
for identifier in &self.identifiers {
for identifier in self.identifiers() {
identifier.pretty_print(writer)?;
}
writer.decrease_indent();
@ -93,22 +85,28 @@ impl PrettyPrint for FullyQualifiedName {
impl PrettyPrint for TypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use TypeUse::*;
use crate::ast::node::type_use::TypeUse::*;
match self {
Void => {
writer.writeln_indented("TypeUse(Void)")?;
Primitive(primitive_type_use) => {
writer.writeln_indented("PrimitiveTypeUse")?;
writer.increase_indent();
primitive_type_use.pretty_print(writer)?;
writer.decrease_indent()
}
InterfaceOrClass(t) => {
writer.writeln_indented("InterfaceOrClassTypeUse")?;
writer.increase_indent();
t.pretty_print(writer)?;
writer.decrease_indent();
}
Tuple(t) => {
writer.writeln_indented("TupleTypeUse")?;
writer.increase_indent();
t.pretty_print(writer)?;
writer.decrease_indent();
}
Function(t) => {
writer.writeln_indented("FunctionTypeUse")?;
writer.increase_indent();
t.pretty_print(writer)?;
writer.decrease_indent();
@ -118,15 +116,43 @@ impl PrettyPrint for TypeUse {
}
}
impl PrettyPrint for PrimitiveTypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use crate::ast::node::type_use::PrimitiveTypeUse::*;
match self {
Byte => writer.writeln_indented("Byte"),
Short => writer.writeln_indented("Short"),
Char => writer.writeln_indented("Char"),
Int => writer.writeln_indented("Int"),
Long => writer.writeln_indented("Long"),
Double => writer.writeln_indented("Double"),
Bool => writer.writeln_indented("Bool"),
String => writer.writeln_indented("String"),
Array(generics) => {
writer.writeln_indented("Array")?;
if let Some(generics) = generics {
writer.increase_indent();
generics.pretty_print(writer)?;
writer.decrease_indent();
}
Ok(())
}
Any => writer.writeln_indented("Any"),
Void => writer.writeln_indented("Void"),
}
}
}
impl PrettyPrint for InterfaceOrClassTypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"InterfaceOrClassTypeUse(borrow_count = {}, is_mutable = {})",
self.borrow_count, self.is_mutable
self.borrow_count(),
self.is_mutable()
))?;
writer.increase_indent();
self.fqn.pretty_print(writer)?;
self.generics.pretty_print(writer)?;
self.fqn().pretty_print(writer)?;
self.generics().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -136,10 +162,11 @@ impl PrettyPrint for TupleTypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"TupleTypeUse(borrow_count = {}, is_mutable = {})",
self.borrow_count, self.is_mutable
self.borrow_count(),
self.is_mutable()
))?;
writer.increase_indent();
self.arguments.pretty_print(writer)?;
self.arguments().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -149,15 +176,15 @@ impl PrettyPrint for FunctionTypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"FunctionTypeUse(borrow_count = {})",
self.borrow_count
self.borrow_count()
))?;
writer.increase_indent();
if let Some(function_type_modifier) = &self.function_modifier {
if let Some(function_type_modifier) = self.function_modifier() {
function_type_modifier.pretty_print(writer)?;
}
self.generics.pretty_print(writer)?;
self.parameters.pretty_print(writer)?;
self.return_type.pretty_print(writer)?;
self.generics().pretty_print(writer)?;
self.parameters().pretty_print(writer)?;
self.return_type().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -167,7 +194,7 @@ impl PrettyPrint for GenericArguments {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("GenericArguments")?;
writer.increase_indent();
for type_use in &self.0 {
for type_use in self.arguments() {
type_use.pretty_print(writer)?;
}
writer.decrease_indent();
@ -179,7 +206,7 @@ impl PrettyPrint for GenericParameters {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("GenericParameters")?;
writer.increase_indent();
for identifier in &self.0 {
for identifier in self.identifiers() {
identifier.pretty_print(writer)?;
}
writer.decrease_indent();
@ -191,7 +218,7 @@ impl PrettyPrint for TupleArguments {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("TupleArguments")?;
writer.increase_indent();
for type_use in &self.0 {
for type_use in self.type_uses() {
type_use.pretty_print(writer)?;
}
writer.decrease_indent();
@ -203,7 +230,7 @@ impl PrettyPrint for ImplementsList {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ImplementsList")?;
writer.increase_indent();
for type_use in &self.0 {
for type_use in self.type_uses() {
type_use.pretty_print(writer)?;
}
writer.decrease_indent();
@ -213,7 +240,7 @@ impl PrettyPrint for ImplementsList {
impl PrettyPrint for FunctionTypeModifier {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use FunctionTypeModifier::*;
use crate::ast::node::function::FunctionTypeModifier::*;
writer.writeln_indented(&format!(
"FunctionTypeModifier({})",
match self {
@ -230,7 +257,7 @@ impl PrettyPrint for Parameters {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("Parameters")?;
writer.increase_indent();
for parameter in &self.0 {
for parameter in self.parameters() {
parameter.pretty_print(writer)?;
}
writer.decrease_indent();
@ -242,8 +269,8 @@ impl PrettyPrint for Parameter {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("Parameter")?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
self.type_use.pretty_print(writer)?;
self.identifier().pretty_print(writer)?;
self.type_use().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -253,8 +280,8 @@ impl PrettyPrint for ReturnType {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ReturnType")?;
writer.increase_indent();
self.declared_type.pretty_print(writer)?;
self.references.pretty_print(writer)?;
self.declared_type().pretty_print(writer)?;
self.references().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -264,7 +291,7 @@ impl PrettyPrint for References {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("References")?;
writer.increase_indent();
for identifier in &self.0 {
for identifier in self.identifiers() {
identifier.pretty_print(writer)?;
}
writer.decrease_indent();
@ -276,16 +303,16 @@ impl PrettyPrint for CompilationUnit {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("CompilationUnit")?;
writer.increase_indent();
if let Some(namespace) = &self.namespace {
if let Some(namespace) = self.namespace() {
writer.writeln_indented("Namespace")?;
writer.increase_indent();
namespace.pretty_print(writer)?;
writer.decrease_indent();
}
for use_statement in &self.use_statements {
for use_statement in self.use_statements() {
use_statement.pretty_print(writer)?;
}
for declaration in &self.declarations {
for declaration in self.declarations() {
declaration.pretty_print(writer)?;
}
writer.decrease_indent();
@ -295,7 +322,7 @@ impl PrettyPrint for CompilationUnit {
impl PrettyPrint for ModuleLevelDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use ModuleLevelDeclaration::*;
use crate::ast::node::level::ModuleLevelDeclaration::*;
match self {
Module(module) => module.pretty_print(writer),
Interface(interface) => interface.pretty_print(writer),
@ -308,7 +335,7 @@ impl PrettyPrint for ModuleLevelDeclaration {
impl PrettyPrint for InterfaceLevelDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use InterfaceLevelDeclaration::*;
use crate::ast::node::level::InterfaceLevelDeclaration::*;
match self {
Module(module) => module.pretty_print(writer),
Interface(interface) => interface.pretty_print(writer),
@ -321,7 +348,7 @@ impl PrettyPrint for InterfaceLevelDeclaration {
impl PrettyPrint for ClassLevelDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use ClassLevelDeclaration::*;
use crate::ast::node::level::ClassLevelDeclaration::*;
match self {
Module(module) => module.pretty_print(writer),
Interface(interface) => interface.pretty_print(writer),
@ -339,11 +366,11 @@ impl PrettyPrint for ModuleDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"ModuleDeclaration(is_public = {})",
self.is_public
self.is_public()
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
for declaration in &self.declarations {
self.identifier().pretty_print(writer)?;
for declaration in self.declarations() {
declaration.pretty_print(writer)?;
}
writer.decrease_indent();
@ -355,13 +382,13 @@ impl PrettyPrint for InterfaceDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"InterfaceDeclaration(is_public = {})",
self.is_public
self.is_public()
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
self.generics.pretty_print(writer)?;
self.implements.pretty_print(writer)?;
for declaration in &self.declarations {
self.identifier().pretty_print(writer)?;
self.generics().pretty_print(writer)?;
self.implements().pretty_print(writer)?;
for declaration in self.declarations() {
declaration.pretty_print(writer)?;
}
writer.decrease_indent();
@ -371,15 +398,18 @@ impl PrettyPrint for InterfaceDeclaration {
impl PrettyPrint for ClassDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!("ClassDeclaration(is_public = {})", self.is_public))?;
writer.writeln_indented(&format!(
"ClassDeclaration(is_public = {})",
self.is_public()
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
self.generics.pretty_print(writer)?;
if let Some(class_constructor) = &self.class_constructor {
self.identifier().pretty_print(writer)?;
self.generics().pretty_print(writer)?;
if let Some(class_constructor) = self.class_constructor() {
class_constructor.pretty_print(writer)?;
}
self.implements.pretty_print(writer)?;
for declaration in &self.declarations {
self.implements().pretty_print(writer)?;
for declaration in self.declarations() {
declaration.pretty_print(writer)?;
}
writer.decrease_indent();
@ -391,17 +421,17 @@ impl PrettyPrint for FunctionDefinition {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"FunctionDefinition(is_public = {})",
self.is_public
self.is_public()
))?;
writer.increase_indent();
if let Some(modifier) = &self.modifier {
if let Some(modifier) = self.modifier() {
modifier.pretty_print(writer)?;
}
self.generics.pretty_print(writer)?;
self.identifier.pretty_print(writer)?;
self.parameters.pretty_print(writer)?;
self.return_type.pretty_print(writer)?;
self.body.pretty_print(writer)?;
self.generics().pretty_print(writer)?;
self.identifier().pretty_print(writer)?;
self.parameters().pretty_print(writer)?;
self.return_type().pretty_print(writer)?;
self.body().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -411,17 +441,17 @@ impl PrettyPrint for OperatorFunctionDefinition {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"OperatorFunctionDefinition(is_public = {})",
self.is_public
self.is_public()
))?;
writer.increase_indent();
if let Some(modifier) = &self.modifier {
if let Some(modifier) = self.modifier() {
modifier.pretty_print(writer)?;
}
self.generics.pretty_print(writer)?;
self.operator.pretty_print(writer)?;
self.parameters.pretty_print(writer)?;
self.return_type.pretty_print(writer)?;
self.body.pretty_print(writer)?;
self.generics().pretty_print(writer)?;
self.operator().pretty_print(writer)?;
self.parameters().pretty_print(writer)?;
self.return_type().pretty_print(writer)?;
self.body().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -431,16 +461,16 @@ impl PrettyPrint for PlatformFunctionDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"PlatformFunctionDeclaration(is_public = {})",
self.is_public
self.is_public()
))?;
writer.increase_indent();
if let Some(modifier) = &self.modifier {
if let Some(modifier) = self.modifier() {
modifier.pretty_print(writer)?;
}
self.generics.pretty_print(writer)?;
self.identifier.pretty_print(writer)?;
self.parameters.pretty_print(writer)?;
self.return_type.pretty_print(writer)?;
self.generics().pretty_print(writer)?;
self.identifier().pretty_print(writer)?;
self.parameters().pretty_print(writer)?;
self.return_type().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -450,14 +480,14 @@ impl PrettyPrint for InterfaceFunctionDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("InterfaceFunctionDeclaration")?;
writer.increase_indent();
if let Some(modifier) = &self.modifier {
if let Some(modifier) = self.modifier() {
modifier.pretty_print(writer)?;
}
self.generics.pretty_print(writer)?;
self.identifier.pretty_print(writer)?;
self.parameters.pretty_print(writer)?;
self.return_type.pretty_print(writer)?;
if let Some(body) = &self.body {
self.generics().pretty_print(writer)?;
self.identifier().pretty_print(writer)?;
self.parameters().pretty_print(writer)?;
self.return_type().pretty_print(writer)?;
if let Some(body) = self.body() {
body.pretty_print(writer)?;
}
writer.decrease_indent();
@ -469,14 +499,14 @@ impl PrettyPrint for InterfaceOperatorFunctionDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("InterfaceOperatorFunctionDeclaration")?;
writer.increase_indent();
if let Some(modifier) = &self.modifier {
if let Some(modifier) = self.modifier() {
modifier.pretty_print(writer)?;
}
self.generics.pretty_print(writer)?;
self.operator.pretty_print(writer)?;
self.parameters.pretty_print(writer)?;
self.return_type.pretty_print(writer)?;
if let Some(body) = &self.body {
self.generics().pretty_print(writer)?;
self.operator().pretty_print(writer)?;
self.parameters().pretty_print(writer)?;
self.return_type().pretty_print(writer)?;
if let Some(body) = self.body() {
body.pretty_print(writer)?;
}
writer.decrease_indent();
@ -486,7 +516,7 @@ impl PrettyPrint for InterfaceOperatorFunctionDeclaration {
impl PrettyPrint for FunctionModifier {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use FunctionModifier::*;
use crate::ast::node::function::FunctionModifier::*;
writer.writeln_indented(&format!(
"FunctionModifier({})",
match self {
@ -502,7 +532,7 @@ impl PrettyPrint for FunctionModifier {
impl PrettyPrint for FunctionBody {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use FunctionBody::*;
use crate::ast::node::function::FunctionBody::*;
match self {
Equals(expression) => {
writer.writeln_indented("EqualsFunctionBody")?;
@ -531,7 +561,7 @@ impl PrettyPrint for ClassConstructor {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ClassConstructor")?;
writer.increase_indent();
for constructor_parameter in &self.0 {
for constructor_parameter in self.parameters() {
constructor_parameter.pretty_print(writer)?;
}
writer.decrease_indent();
@ -541,7 +571,7 @@ impl PrettyPrint for ClassConstructor {
impl PrettyPrint for ClassConstructorParameter {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use ClassConstructorParameter::*;
use crate::ast::node::class::ClassConstructorParameter::*;
match self {
Property(property) => {
writer.writeln_indented("PropertyConstructorParameter")?;
@ -564,11 +594,11 @@ impl PrettyPrint for PropertyDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"PropertyDeclaration(is_mutable = {})",
self.is_mutable
self.is_mutable()
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
self.declared_type.pretty_print(writer)?;
self.identifier().pretty_print(writer)?;
self.declared_type().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -578,11 +608,11 @@ impl PrettyPrint for FieldDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"FieldDeclaration(is_mutable = {})",
self.is_mutable
self.is_mutable()
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
self.declared_type.pretty_print(writer)?;
self.identifier().pretty_print(writer)?;
self.declared_type().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -592,10 +622,10 @@ impl PrettyPrint for UseStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("UseStatement")?;
writer.increase_indent();
for identifier in &self.identifiers {
for identifier in self.identifiers() {
identifier.pretty_print(writer)?;
}
self.last.pretty_print(writer)?;
self.last().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -606,12 +636,12 @@ impl PrettyPrint for UseStatementLast {
writer.writeln_indented("UseStatementLast")?;
writer.increase_indent();
match self {
UseStatementLast::Identifier(i) => i.borrow().pretty_print(writer)?,
UseStatementLast::Identifier(i) => i.pretty_print(writer)?,
UseStatementLast::Identifiers(is) => {
for i in is {
i.borrow().pretty_print(writer)?;
i.pretty_print(writer)?;
}
}
},
UseStatementLast::Star => {
writer.writeln_indented("Star")?;
}
@ -625,10 +655,10 @@ impl PrettyPrint for BlockStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("BlockStatement")?;
writer.increase_indent();
for statement in &self.statements {
for statement in self.statements() {
statement.pretty_print(writer)?;
}
if let Some(expression) = &self.expression {
if let Some(expression) = self.expression() {
expression.pretty_print(writer)?;
}
Ok(())
@ -637,7 +667,7 @@ impl PrettyPrint for BlockStatement {
impl PrettyPrint for Statement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use Statement::*;
use crate::ast::node::statement::Statement::*;
match self {
BlockStatement(block_statement) => block_statement.pretty_print(writer),
VariableDeclarationStatement(s) => s.pretty_print(writer),
@ -656,14 +686,14 @@ impl PrettyPrint for VariableDeclarationStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"VariableDeclarationStatement(is_mutable = {})",
self.is_mutable
self.is_mutable()
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
if let Some(declared_type) = &self.declared_type {
self.identifier().pretty_print(writer)?;
if let Some(declared_type) = self.declared_type() {
declared_type.pretty_print(writer)?;
}
if let Some(initializer) = &self.initializer {
if let Some(initializer) = self.initializer() {
initializer.pretty_print(writer)?;
}
writer.decrease_indent();
@ -675,8 +705,8 @@ impl PrettyPrint for AssignStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("AssignStatement")?;
writer.increase_indent();
self.lhs.pretty_print(writer)?;
self.rhs.pretty_print(writer)?;
self.lhs().pretty_print(writer)?;
self.rhs().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -686,7 +716,7 @@ impl PrettyPrint for CallStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("CallStatement")?;
writer.increase_indent();
self.0.pretty_print(writer)?;
self.expression().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -695,7 +725,7 @@ impl PrettyPrint for CallStatement {
impl PrettyPrint for ReturnStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ReturnStatement")?;
if let Some(expression) = &self.0 {
if let Some(expression) = self.expression() {
writer.increase_indent();
expression.pretty_print(writer)?;
writer.decrease_indent();
@ -709,8 +739,8 @@ impl PrettyPrint for IfStatement {
writer.writeln_indented("IfStatement")?;
writer.increase_indent();
writer.increase_indent();
self.condition.pretty_print(writer)?;
self.then_block.pretty_print(writer)?;
self.condition().pretty_print(writer)?;
self.then_block().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -720,9 +750,9 @@ impl PrettyPrint for IfElseStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("IfElseStatement")?;
writer.increase_indent();
self.if_statement.pretty_print(writer)?;
self.else_ifs.pretty_print(writer)?;
if let Some(else_block) = &self.else_block {
self.if_statement().pretty_print(writer)?;
self.else_ifs().pretty_print(writer)?;
if let Some(else_block) = self.else_block() {
else_block.pretty_print(writer)?;
}
writer.decrease_indent();
@ -734,7 +764,7 @@ impl PrettyPrint for ElseIfs {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ElseIfs")?;
writer.increase_indent();
for if_statement in &self.0 {
for if_statement in self.if_statements() {
if_statement.pretty_print(writer)?;
}
writer.decrease_indent();
@ -746,7 +776,7 @@ impl PrettyPrint for ElseBlock {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ElseBlock")?;
writer.increase_indent();
self.0.pretty_print(writer)?;
self.block_statement().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -756,8 +786,8 @@ impl PrettyPrint for WhileStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("WhileStatement")?;
writer.increase_indent();
self.condition.pretty_print(writer)?;
self.body.pretty_print(writer)?;
self.condition().pretty_print(writer)?;
self.body().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -767,9 +797,9 @@ impl PrettyPrint for ForStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ForStatement")?;
writer.increase_indent();
self.variable.pretty_print(writer)?;
self.iterator.pretty_print(writer)?;
self.body.pretty_print(writer)?;
self.variable().pretty_print(writer)?;
self.iterator().pretty_print(writer)?;
self.body().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -777,7 +807,7 @@ impl PrettyPrint for ForStatement {
impl PrettyPrint for Expression {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use Expression::*;
use crate::ast::node::expression::Expression::*;
match self {
Ternary(e) => e.pretty_print(writer),
Binary(e) => e.pretty_print(writer),
@ -785,7 +815,7 @@ impl PrettyPrint for Expression {
UnarySuffix(e) => e.pretty_print(writer),
Call(e) => e.pretty_print(writer),
ObjectAccess(o) => o.pretty_print(writer),
Literal(literial) => literial.pretty_print(writer),
Literal(literal) => literal.pretty_print(writer),
FullyQualifiedName(fqn) => fqn.pretty_print(writer),
Closure(closure) => closure.pretty_print(writer),
}
@ -796,9 +826,9 @@ impl PrettyPrint for TernaryExpression {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("TernaryExpression")?;
writer.increase_indent();
self.condition.pretty_print(writer)?;
self.true_expression.pretty_print(writer)?;
self.false_expression.pretty_print(writer)?;
self.condition().pretty_print(writer)?;
self.true_expression().pretty_print(writer)?;
self.false_expression().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -808,9 +838,9 @@ impl PrettyPrint for BinaryExpression {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("BinaryExpression")?;
writer.increase_indent();
self.left.pretty_print(writer)?;
self.operator.pretty_print(writer)?;
self.right.pretty_print(writer)?;
self.left().pretty_print(writer)?;
self.operator().pretty_print(writer)?;
self.right().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -820,8 +850,8 @@ impl PrettyPrint for PrefixExpression {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("PrefixExpression")?;
writer.increase_indent();
self.operator.pretty_print(writer)?;
self.expression.pretty_print(writer)?;
self.operator().pretty_print(writer)?;
self.expression().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -831,8 +861,8 @@ impl PrettyPrint for SuffixExpression {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("SuffixExpression")?;
writer.increase_indent();
self.expression.pretty_print(writer)?;
self.operator.pretty_print(writer)?;
self.expression().pretty_print(writer)?;
self.operator().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -842,11 +872,11 @@ impl PrettyPrint for CallExpression {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("CallExpression")?;
writer.increase_indent();
self.callee.pretty_print(writer)?;
if let Some(turbo_fish) = &self.turbo_fish {
self.callee().pretty_print(writer)?;
if let Some(turbo_fish) = self.turbo_fish() {
turbo_fish.pretty_print(writer)?;
}
self.arguments.pretty_print(writer)?;
self.arguments().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -856,7 +886,7 @@ impl PrettyPrint for TurboFish {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("TurboFish")?;
writer.increase_indent();
self.0.pretty_print(writer)?;
self.generics().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -866,7 +896,7 @@ impl PrettyPrint for CallArguments {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("CallArguments")?;
writer.increase_indent();
for call_argument in &self.0 {
for call_argument in self.arguments() {
call_argument.pretty_print(writer)?;
}
writer.decrease_indent();
@ -878,7 +908,7 @@ impl PrettyPrint for CallArgument {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("CallArgument")?;
writer.increase_indent();
self.0.pretty_print(writer)?;
self.expression().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -886,22 +916,22 @@ impl PrettyPrint for CallArgument {
impl PrettyPrint for Closure {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!("Closure(is_move = {})", self.is_move))?;
writer.writeln_indented(&format!("Closure(is_move = {})", self.is_move()))?;
writer.increase_indent();
if let Some(modifier) = &self.modifier {
if let Some(modifier) = self.modifier() {
modifier.pretty_print(writer)?;
}
self.captures.pretty_print(writer)?;
self.parameters.pretty_print(writer)?;
if !self.statements.is_empty() {
self.captures().pretty_print(writer)?;
self.parameters().pretty_print(writer)?;
if !self.statements().is_empty() {
writer.writeln_indented("ClosureStatements")?;
writer.increase_indent();
for statement in &self.statements {
for statement in self.statements() {
statement.pretty_print(writer)?;
}
writer.decrease_indent();
}
if let Some(expression) = &self.expression {
if let Some(expression) = self.expression() {
expression.pretty_print(writer)?;
}
writer.decrease_indent();
@ -925,7 +955,7 @@ impl PrettyPrint for ClosureCaptures {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ClosureCaptures")?;
writer.increase_indent();
for capture in &self.0 {
for capture in self.captures() {
capture.pretty_print(writer)?;
}
writer.decrease_indent();
@ -937,10 +967,11 @@ impl PrettyPrint for ClosureCapture {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"ClosureCapture(borrow_count = {}, is_mutable = {})",
self.borrow_count, self.is_mutable
self.borrow_count(),
self.is_mutable()
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
self.identifier().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -950,7 +981,7 @@ impl PrettyPrint for ClosureParameters {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ClosureParameters")?;
writer.increase_indent();
for parameter in &self.0 {
for parameter in self.parameters() {
parameter.pretty_print(writer)?;
}
writer.decrease_indent();
@ -962,8 +993,8 @@ impl PrettyPrint for ClosureParameter {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ClosureParameter")?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
if let Some(type_use) = &self.type_use {
self.identifier().pretty_print(writer)?;
if let Some(type_use) = self.type_use() {
type_use.pretty_print(writer)?;
}
writer.decrease_indent();
@ -975,8 +1006,8 @@ impl PrettyPrint for ObjectAccess {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ObjectAccess")?;
writer.increase_indent();
self.receiver.pretty_print(writer)?;
self.navigations.pretty_print(writer)?;
self.receiver().pretty_print(writer)?;
self.navigations().pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
@ -986,7 +1017,7 @@ impl PrettyPrint for ObjectNavigations {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ObjectNavigations")?;
writer.increase_indent();
for object_navigation in &self.0 {
for object_navigation in self.navigations() {
object_navigation.pretty_print(writer)?;
}
writer.decrease_indent();
@ -996,7 +1027,7 @@ impl PrettyPrint for ObjectNavigations {
impl PrettyPrint for ObjectNavigation {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use ObjectNavigation::*;
use crate::ast::node::object_access::ObjectNavigation::*;
match self {
Index(e) => {
writer.writeln_indented("Index")?;
@ -1017,7 +1048,7 @@ impl PrettyPrint for ObjectNavigation {
impl PrettyPrint for Literal {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use Literal::*;
use crate::ast::node::literal::Literal::*;
match self {
Integer(i) => writer.writeln_indented(&format!("Integer({})", i)),
Long(l) => writer.writeln_indented(&format!("Long({})", l)),
@ -1035,7 +1066,7 @@ impl PrettyPrint for DString {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("DString")?;
writer.increase_indent();
for part in &self.0 {
for part in self.parts() {
part.pretty_print(writer)?;
}
Ok(())

File diff suppressed because it is too large Load Diff

145
src/ast/walk.rs Normal file
View File

@ -0,0 +1,145 @@
use crate::ast::children::{NodeInner, NodeRef};
pub fn walk_depth_first<F>(node: &dyn NodeInner, f: &mut F)
where
F: FnMut(NodeRef),
{
use NodeRef::*;
for child in node.children() {
match child {
Identifier(identifier) => walk_depth_first(identifier, f),
FullyQualifiedName(fqn) => {
walk_depth_first(fqn, f);
}
TypeUse(type_use) => walk_depth_first(type_use, f),
PrimitiveTypeUse(primitive_type_use) => walk_depth_first(primitive_type_use, f),
InterfaceOrClassTypeUse(interface_or_class_type_use) => {
walk_depth_first(interface_or_class_type_use, f)
}
TupleTypeUse(tuple_type_use) => walk_depth_first(tuple_type_use, f),
FunctionTypeUse(function_type_use) => walk_depth_first(function_type_use, f),
GenericArguments(generic_arguments) => walk_depth_first(generic_arguments, f),
GenericParameters(generic_parameters) => walk_depth_first(generic_parameters, f),
TupleArguments(tuple_arguments) => walk_depth_first(tuple_arguments, f),
ImplementsList(implements) => walk_depth_first(implements, f),
Parameters(parameters) => walk_depth_first(parameters, f),
Parameter(parameter) => walk_depth_first(parameter, f),
ReturnType(return_type) => walk_depth_first(return_type, f),
References(references) => walk_depth_first(references, f),
UseStatement(use_statement) => walk_depth_first(use_statement, f),
CompilationUnit(compilation_unit) => walk_depth_first(compilation_unit, f),
ModuleLevelDeclaration(module_level_declaration) => {
walk_depth_first(module_level_declaration, f)
}
InterfaceLevelDeclaration(interface_level_declaration) => {
walk_depth_first(interface_level_declaration, f)
}
ClassLevelDeclaration(class_level_declaration) => {
walk_depth_first(class_level_declaration, f)
}
ModuleDeclaration(module_declaration) => walk_depth_first(module_declaration, f),
InterfaceDeclaration(interface_declaration) => {
walk_depth_first(interface_declaration, f)
}
ClassDeclaration(class_declaration) => walk_depth_first(class_declaration, f),
FunctionDefinition(function_definition) => walk_depth_first(function_definition, f),
OperatorFunctionDefinition(operator_function_definition) => {
walk_depth_first(operator_function_definition, f)
}
PlatformFunctionDeclaration(platform_function_declaration) => {
walk_depth_first(platform_function_declaration, f)
}
InterfaceFunctionDeclaration(interface_function_declaration) => {
walk_depth_first(interface_function_declaration, f)
}
InterfaceOperatorFunctionDeclaration(interface_operator_function_declaration) => {
walk_depth_first(interface_operator_function_declaration, f)
}
FunctionBody(function_body) => walk_depth_first(function_body, f),
ClassConstructor(class_constructor) => walk_depth_first(class_constructor, f),
ClassConstructorParameter(class_constructor_parameter) => {
walk_depth_first(class_constructor_parameter, f)
}
PropertyDeclaration(property_declaration) => walk_depth_first(property_declaration, f),
FieldDeclaration(field_declaration) => walk_depth_first(field_declaration, f),
BlockStatement(block) => walk_depth_first(block, f),
Statement(statement) => walk_depth_first(statement, f),
VariableDeclarationStatement(variable_declaration) => {
walk_depth_first(variable_declaration, f)
}
AssignStatement(assign_statement) => walk_depth_first(assign_statement, f),
CallStatement(call_statement) => walk_depth_first(call_statement, f),
ReturnStatement(return_statement) => walk_depth_first(return_statement, f),
IfStatement(if_statement) => walk_depth_first(if_statement, f),
IfElseStatement(if_else_statement) => walk_depth_first(if_else_statement, f),
ElseIfs(else_ifs) => walk_depth_first(else_ifs, f),
ElseBlock(else_block) => walk_depth_first(else_block, f),
WhileStatement(while_statement) => walk_depth_first(while_statement, f),
ForStatement(for_statement) => walk_depth_first(for_statement, f),
Expression(expression) => walk_depth_first(expression, f),
TernaryExpression(ternary_expression) => walk_depth_first(ternary_expression, f),
BinaryExpression(binary_expression) => walk_depth_first(binary_expression, f),
PrefixExpression(prefix_expression) => walk_depth_first(prefix_expression, f),
SuffixExpression(suffix_expression) => walk_depth_first(suffix_expression, f),
CallExpression(call_expression) => walk_depth_first(call_expression, f),
TurboFish(turbo_fish) => walk_depth_first(turbo_fish, f),
CallArguments(call_arguments) => walk_depth_first(call_arguments, f),
CallArgument(call_argument) => walk_depth_first(call_argument, f),
Closure(closure) => walk_depth_first(closure, f),
ClosureCaptures(closure_captures) => walk_depth_first(closure_captures, f),
ClosureCapture(closure_capture) => walk_depth_first(closure_capture, f),
ClosureParameters(closure_parameters) => walk_depth_first(closure_parameters, f),
ClosureParameter(closure_parameter) => walk_depth_first(closure_parameter, f),
ObjectAccess(object_access) => walk_depth_first(object_access, f),
ObjectNavigations(object_navigations) => walk_depth_first(object_navigations, f),
ObjectNavigation(object_navigations) => walk_depth_first(object_navigations, f),
Literal(literal) => walk_depth_first(literal, f),
DString(d_string) => walk_depth_first(d_string, f),
DStringPart(d_string_part) => walk_depth_first(d_string_part, f),
}
}
f(node.as_node_ref());
}
#[cfg(test)]
mod tests {
use crate::ast::build::build_ast;
use crate::ast::children::NodeRef;
use crate::ast::walk::walk_depth_first;
use crate::parser::{DeimosParser, Rule};
use indoc::indoc;
use pest::Parser;
#[test]
fn collect_identifiers() {
let parse_result = DeimosParser::parse(
Rule::CompilationUnit,
indoc! {"
ns greeter;
class Greeter {}
fn main() {
let greeter = Greeter();
}
"},
);
match parse_result {
Ok(cu_pairs) => {
let cu = build_ast("greeter.dm", 0, cu_pairs.into_iter().next().unwrap());
let mut identifier_count = 0;
walk_depth_first(&cu, &mut |node_ref| match node_ref {
NodeRef::Identifier(identifier) => {
dbg!(identifier);
identifier_count += 1;
}
_ => {}
});
assert_eq!(identifier_count, 5);
}
Err(err) => {
panic!("{}", err);
}
}
}
}

View File

@ -1,5 +1,7 @@
#![feature(new_range_api)]
#![allow(warnings)]
extern crate core;
pub mod ast;
pub mod diagnostic;
pub mod module;

View File

@ -1,11 +1,27 @@
use crate::ast::named::Named;
use crate::ast::*;
use crate::ast::node::call_expression::*;
use crate::ast::node::class::*;
use crate::ast::node::closure::*;
use crate::ast::node::compilation_unit::*;
use crate::ast::node::d_string::*;
use crate::ast::node::expression::*;
use crate::ast::node::function::*;
use crate::ast::node::generics::*;
use crate::ast::node::implements_list::*;
use crate::ast::node::interface::*;
use crate::ast::node::level::*;
use crate::ast::node::literal::*;
use crate::ast::node::module::*;
use crate::ast::node::named::Named;
use crate::ast::node::names::*;
use crate::ast::node::object_access::*;
use crate::ast::node::statement::*;
use crate::ast::node::type_use::*;
use crate::ast::node::use_statement::*;
use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::fqn_context::FqnContext;
use crate::name_analysis::symbol::*;
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
use codespan_reporting::diagnostic::{Diagnostic, Label};
use std::cell::RefCell;
use std::ops::DerefMut;
use std::range::Range;
use std::rc::Rc;
@ -106,9 +122,9 @@ fn gather_interface_or_class_type_use(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_fully_qualified_name(&mut interface_or_class_type_use.fqn, symbol_table);
gather_fully_qualified_name(interface_or_class_type_use.fqn_mut(), symbol_table);
gather_generic_arguments(
&mut interface_or_class_type_use.generics,
interface_or_class_type_use.generics_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -121,7 +137,7 @@ fn gather_tuple_type_use(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for generic_argument in &mut tuple_type_use.arguments.0 {
for generic_argument in tuple_type_use.arguments_mut().type_uses_mut() {
gather_type_use(generic_argument, symbol_table, fqn_context, diagnostics);
}
}
@ -133,15 +149,15 @@ fn gather_function_type_use(
diagnostics: &mut Vec<DmDiagnostic>,
) {
symbol_table.push_scope("FunctionTypeUseScope");
gather_generic_parameters(&mut function_type_use.generics, symbol_table, diagnostics);
gather_generic_parameters(function_type_use.generics_mut(), symbol_table, diagnostics);
gather_parameters(
&mut function_type_use.parameters,
function_type_use.parameters_mut(),
symbol_table,
fqn_context,
diagnostics,
);
gather_return_type(
&mut function_type_use.return_type,
function_type_use.return_type_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -157,7 +173,7 @@ fn gather_generic_arguments(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for argument in &mut generic_arguments.0 {
for argument in generic_arguments.arguments_mut() {
gather_type_use(argument, symbol_table, fqn_context, diagnostics);
}
}
@ -169,7 +185,7 @@ fn gather_generic_parameters(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for identifier in &mut generic_parameters.0 {
for identifier in generic_parameters.identifiers_mut() {
let insert_result =
symbol_table.insert_type_symbol(TypeSymbol::Generic(GenericTypeSymbol::new(
&identifier.name(),
@ -199,7 +215,7 @@ fn gather_implements_list(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for type_use in &mut implements_list.0 {
for type_use in implements_list.type_uses_mut() {
gather_type_use(type_use, symbol_table, fqn_context, diagnostics);
}
}
@ -213,7 +229,7 @@ fn gather_parameters(
diagnostics: &mut Vec<DmDiagnostic>,
) -> Option<Vec<Rc<ParameterSymbol>>> {
parameters
.0
.parameters_mut()
.iter_mut()
.map(|parameter| gather_parameter(parameter, symbol_table, fqn_context, diagnostics))
.collect()
@ -225,21 +241,21 @@ fn gather_parameter(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) -> Option<Rc<ParameterSymbol>> {
let parameter_name = parameter.identifier.name();
let parameter_name = parameter.identifier().name();
let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new(
&parameter_name,
Some(&parameter.identifier),
Some(&parameter.identifier()),
));
match insert_result {
Ok(parameter_symbol) => {
parameter
.identifier
.identifier_mut()
.set_scope_id(symbol_table.current_scope_id());
gather_type_use(
&mut parameter.type_use,
parameter.type_use_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -250,8 +266,8 @@ fn gather_parameter(
handle_insert_error(
err,
&parameter_name,
parameter.identifier.file_id(),
parameter.identifier.range(),
parameter.identifier().file_id(),
parameter.identifier().range(),
"function/variable",
diagnostics,
);
@ -269,18 +285,18 @@ fn gather_return_type(
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_type_use(
&mut return_type.declared_type,
return_type.declared_type_mut(),
symbol_table,
fqn_context,
diagnostics,
);
gather_references(&mut return_type.references, symbol_table);
gather_references(return_type.references_mut(), symbol_table);
}
/* References */
fn gather_references(references: &mut References, symbol_table: &mut SymbolTable) {
for identifier in &mut references.0 {
for identifier in references.identifiers_mut() {
gather_identifier(identifier, symbol_table);
}
}
@ -293,15 +309,15 @@ pub(super) fn gather_compilation_unit(
diagnostics: &mut Vec<DmDiagnostic>,
) {
let mut fqn_context = FqnContext::new();
if let Some(namespace) = &compilation_unit.namespace {
if let Some(namespace) = compilation_unit.namespace() {
fqn_context.push(&namespace.name());
}
symbol_table.push_scope(&format!("FileScope({})", compilation_unit.file_name));
for use_statement in &mut compilation_unit.use_statements {
symbol_table.push_scope(&format!("FileScope({})", compilation_unit.file_name()));
for use_statement in compilation_unit.use_statements_mut() {
gather_use_statement(use_statement, symbol_table, &mut fqn_context, diagnostics)
}
for declaration in &mut compilation_unit.declarations {
for declaration in compilation_unit.declarations_mut() {
gather_module_level_declaration(declaration, symbol_table, &mut fqn_context, diagnostics);
}
symbol_table.pop_scope();
@ -313,34 +329,28 @@ pub(super) fn gather_compilation_unit(
fn handle_use_statement_import(
symbol_table: &mut SymbolTable,
base_name: &str,
identifier: Rc<RefCell<Identifier>>,
identifier: &mut Identifier,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let borrowed_identifier = identifier.borrow();
let declared_name = borrowed_identifier.name().to_string();
let declared_name = identifier.name().to_string();
let insert_result = symbol_table.insert_use_statement_symbol(UseStatementSymbol::new(
&format!("{}::{}", base_name, &declared_name),
&declared_name,
Some(identifier.clone()),
Some(identifier),
));
match insert_result {
Ok(use_statement_symbol) => {
drop(borrowed_identifier);
gather_identifier(identifier, symbol_table);
let mut mutable_borrowed_identifier = identifier.borrow_mut();
gather_identifier(mutable_borrowed_identifier.deref_mut(), symbol_table);
mutable_borrowed_identifier
.set_saved_symbol(Symbol::UseStatement(use_statement_symbol));
identifier.set_saved_symbol(Symbol::UseStatement(use_statement_symbol));
}
Err(err) => {
handle_insert_error(
err,
&declared_name,
borrowed_identifier.file_id(),
borrowed_identifier.range(),
identifier.file_id(),
identifier.range(),
"Use statement",
diagnostics,
);
@ -358,18 +368,13 @@ fn gather_use_statement(
todo!()
}
let base_name = use_statement.base_name().to_string();
match &mut use_statement.last {
match use_statement.last_mut() {
UseStatementLast::Identifier(identifier) => {
handle_use_statement_import(symbol_table, &base_name, identifier.clone(), diagnostics)
handle_use_statement_import(symbol_table, &base_name, identifier, diagnostics)
}
UseStatementLast::Identifiers(identifiers) => {
for identifier in identifiers {
handle_use_statement_import(
symbol_table,
&base_name,
identifier.clone(),
diagnostics,
)
handle_use_statement_import(symbol_table, &base_name, identifier, diagnostics)
}
}
UseStatementLast::Star => panic!(),
@ -384,7 +389,7 @@ fn gather_module_level_declaration(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use ModuleLevelDeclaration::*;
use crate::ast::node::level::ModuleLevelDeclaration::*;
match declaration {
Module(module_declaration) => {
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
@ -420,7 +425,7 @@ fn gather_interface_level_declaration(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use InterfaceLevelDeclaration::*;
use crate::ast::node::level::InterfaceLevelDeclaration::*;
match declaration {
Module(module_declaration) => {
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
@ -461,7 +466,7 @@ fn gather_class_level_declaration(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use ClassLevelDeclaration::*;
use crate::ast::node::level::ClassLevelDeclaration::*;
match declaration {
Module(module_declaration) => {
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
@ -525,13 +530,13 @@ fn gather_module_declaration(
// 5. Pop scope
// 6. Pop fqn_context
let module_name = declaration.identifier.name();
let module_name = declaration.identifier().name();
let insert_result = symbol_table.insert_module_symbol(ModuleSymbol::new(
&fqn_context.resolve(&module_name),
&module_name,
declaration.is_public,
Some(&declaration.identifier),
declaration.is_public(),
Some(declaration.identifier()),
));
match insert_result {
@ -539,7 +544,7 @@ fn gather_module_declaration(
fqn_context.push(&module_name);
symbol_table.push_scope(&format!("ModuleScope({})", module_name));
for inner_declaration in &mut declaration.declarations {
for inner_declaration in declaration.declarations_mut() {
gather_module_level_declaration(
inner_declaration,
symbol_table,
@ -554,8 +559,8 @@ fn gather_module_declaration(
Err(insert_error) => handle_insert_error(
insert_error,
&module_name,
declaration.identifier.file_id(),
declaration.identifier.range(),
declaration.identifier().file_id(),
declaration.identifier().range(),
"Module",
diagnostics,
),
@ -568,14 +573,14 @@ fn gather_interface_declaration(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let interface_name = declaration.identifier.name();
let interface_name = declaration.identifier().name();
let insert_result =
symbol_table.insert_type_symbol(TypeSymbol::Concrete(ConcreteTypeSymbol::new(
&fqn_context.resolve(&interface_name),
&interface_name,
declaration.is_public,
Some(&declaration.identifier),
declaration.is_public(),
Some(declaration.identifier()),
)));
match insert_result {
@ -583,7 +588,7 @@ fn gather_interface_declaration(
fqn_context.push(&interface_name);
symbol_table.push_scope(&format!("InterfaceScope({})", interface_name));
for inner_declaration in &mut declaration.declarations {
for inner_declaration in declaration.declarations_mut() {
gather_interface_level_declaration(
inner_declaration,
symbol_table,
@ -599,8 +604,8 @@ fn gather_interface_declaration(
handle_insert_error(
insert_error,
&interface_name,
declaration.identifier.file_id(),
declaration.identifier.range(),
declaration.identifier().file_id(),
declaration.identifier().range(),
"Interface",
diagnostics,
);
@ -614,21 +619,21 @@ fn gather_class_declaration(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let class_name = class_declaration.identifier.name();
let class_name = class_declaration.identifier().name().to_string();
let insert_result =
symbol_table.insert_type_symbol(TypeSymbol::Concrete(ConcreteTypeSymbol::new(
&fqn_context.resolve(&class_name),
&class_name,
class_declaration.is_public,
Some(&class_declaration.identifier),
class_declaration.is_public(),
Some(class_declaration.identifier()),
)));
match insert_result {
Ok(_) => {
// Do this first so we can't implement generic parameters!
gather_implements_list(
&mut class_declaration.implements,
class_declaration.implements_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -637,13 +642,13 @@ fn gather_class_declaration(
fqn_context.push(&class_name);
symbol_table.push_scope(&format!("ClassScope({})", class_name));
gather_generic_parameters(&mut class_declaration.generics, symbol_table, diagnostics);
gather_generic_parameters(class_declaration.generics_mut(), symbol_table, diagnostics);
if let Some(class_constructor) = &mut class_declaration.class_constructor {
if let Some(class_constructor) = class_declaration.class_constructor_mut() {
gather_class_constructor(class_constructor, symbol_table, fqn_context, diagnostics);
}
for inner_declaration in &mut class_declaration.declarations {
for inner_declaration in class_declaration.declarations_mut() {
gather_class_level_declaration(
inner_declaration,
symbol_table,
@ -659,8 +664,8 @@ fn gather_class_declaration(
handle_insert_error(
insert_error,
&class_name,
class_declaration.identifier.file_id(),
class_declaration.identifier.range(),
class_declaration.identifier().file_id(),
class_declaration.identifier().range(),
"interface/class",
diagnostics,
);
@ -676,27 +681,27 @@ fn gather_function_definition(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let declared_name = function.identifier.name();
let declared_name = function.identifier().name();
let resolved_name = fqn_context.resolve(&declared_name);
let insert_result = symbol_table.insert_function_symbol(FunctionSymbol::new(
&resolved_name,
&declared_name,
function.is_public,
function.is_public(),
false,
Some(&function.identifier),
Some(function.identifier()),
));
match insert_result {
Ok(function_symbol) => {
function
.identifier
.identifier_mut()
.set_scope_id(symbol_table.current_scope_id());
symbol_table.push_scope(&format!("FunctionParameterScope({})", resolved_name));
let parameters_result = gather_parameters(
&mut function.parameters,
function.parameters_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -712,7 +717,7 @@ fn gather_function_definition(
}
gather_return_type(
&mut function.return_type,
function.return_type_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -720,7 +725,7 @@ fn gather_function_definition(
symbol_table.push_scope(&format!("FunctionBodyScope({})", resolved_name));
gather_function_body(&mut function.body, symbol_table, fqn_context, diagnostics);
gather_function_body(function.body_mut(), symbol_table, fqn_context, diagnostics);
symbol_table.pop_scope(); // body
symbol_table.pop_scope(); // parameters
@ -729,8 +734,8 @@ fn gather_function_definition(
handle_insert_error(
err,
&declared_name,
function.identifier.file_id(),
function.identifier.range(),
function.identifier().file_id(),
function.identifier().range(),
"function/variable",
diagnostics,
);
@ -753,24 +758,26 @@ fn gather_platform_function_definition(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let declared_name = platform_function_declaration.identifier.name();
let declared_name = platform_function_declaration.identifier().name();
let fully_qualified_name = fqn_context.resolve(&declared_name);
let insert_result = symbol_table.insert_function_symbol(FunctionSymbol::new(
&fully_qualified_name,
&declared_name,
platform_function_declaration.is_public,
platform_function_declaration.is_public(),
true,
Some(&platform_function_declaration.identifier),
Some(platform_function_declaration.identifier()),
));
match insert_result {
Ok(function_symbol) => {
let declared_name_as_string =
platform_function_declaration.identifier.name().to_string();
let declared_name_as_string = platform_function_declaration
.identifier()
.name()
.to_string();
platform_function_declaration
.identifier
.identifier_mut()
.set_scope_id(symbol_table.current_scope_id());
symbol_table.push_scope(&format!(
@ -779,7 +786,7 @@ fn gather_platform_function_definition(
));
let parameter_symbols_result = gather_parameters(
&mut platform_function_declaration.parameters,
platform_function_declaration.parameters_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -795,7 +802,7 @@ fn gather_platform_function_definition(
}
gather_return_type(
&mut platform_function_declaration.return_type,
platform_function_declaration.return_type_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -807,8 +814,8 @@ fn gather_platform_function_definition(
handle_insert_error(
err,
&declared_name,
platform_function_declaration.identifier.file_id(),
platform_function_declaration.identifier.range(),
platform_function_declaration.identifier().file_id(),
platform_function_declaration.identifier().range(),
"(Platform-) Function",
diagnostics,
);
@ -822,23 +829,23 @@ fn gather_interface_function_declaration(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let name = declaration.identifier.name();
let name = declaration.identifier().name();
let insert_result = symbol_table.insert_function_symbol(FunctionSymbol::new(
&fqn_context.resolve(&name),
&name,
true,
false,
Some(&declaration.identifier),
Some(declaration.identifier()),
));
match insert_result {
Ok(function_symbol) => {
symbol_table.push_scope(&format!("FunctionParameterScope({})", &name));
gather_generic_parameters(&mut declaration.generics, symbol_table, diagnostics);
gather_generic_parameters(declaration.generics_mut(), symbol_table, diagnostics);
let parameters = gather_parameters(
&mut declaration.parameters,
declaration.parameters_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -850,13 +857,13 @@ fn gather_interface_function_declaration(
}
gather_return_type(
&mut declaration.return_type,
declaration.return_type_mut(),
symbol_table,
fqn_context,
diagnostics,
);
if let Some(body) = &mut declaration.body {
if let Some(body) = declaration.body_mut() {
gather_function_body(body, symbol_table, fqn_context, diagnostics);
}
@ -866,8 +873,8 @@ fn gather_interface_function_declaration(
handle_insert_error(
insert_error,
&name,
declaration.identifier.file_id(),
declaration.identifier.range(),
declaration.identifier().file_id(),
declaration.identifier().range(),
"Interface Function",
diagnostics,
);
@ -890,7 +897,7 @@ fn gather_function_body(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::FunctionBody::*;
use crate::ast::node::function::FunctionBody::*;
match function_body {
Equals(expression) => gather_expression(expression, symbol_table, diagnostics),
Block(block) => gather_block_statement_inner(block, symbol_table, fqn_context, diagnostics),
@ -906,13 +913,18 @@ fn gather_class_constructor(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for parameter in &mut class_constructor.0 {
for parameter in class_constructor.parameters_mut() {
match parameter {
ClassConstructorParameter::Property(property) => {
gather_property_declaration(property, symbol_table, fqn_context, diagnostics);
gather_property_declaration(
property.deref_mut(),
symbol_table,
fqn_context,
diagnostics,
);
}
ClassConstructorParameter::Field(field) => {
gather_field_declaration(field, symbol_table, fqn_context, diagnostics);
gather_field_declaration(field.deref_mut(), symbol_table, fqn_context, diagnostics);
}
}
}
@ -924,19 +936,18 @@ fn gather_property_declaration(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let insert_result = symbol_table.insert_class_member_symbol(
ClassMemberSymbol::new(
&property_declaration.identifier.name(),
let identifier = property_declaration.identifier();
let insert_result = symbol_table.insert_class_member_symbol(ClassMemberSymbol::new(
&identifier.name(),
false,
Some(SourceDefinition::from_identifier(&property_declaration.identifier))
)
);
Some(SourceDefinition::from_identifier(identifier)),
));
if let Err(insert_error) = insert_result {
handle_insert_error(
insert_error,
&property_declaration.identifier.name(),
property_declaration.identifier.file_id(),
property_declaration.identifier.range(),
&identifier.name(),
identifier.file_id(),
identifier.range(),
"Data Member",
diagnostics,
);
@ -949,19 +960,18 @@ fn gather_field_declaration(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let insert_result = symbol_table.insert_class_member_symbol(
ClassMemberSymbol::new(
&field_declaration.identifier.name(),
let identifier = field_declaration.identifier();
let insert_result = symbol_table.insert_class_member_symbol(ClassMemberSymbol::new(
&identifier.name(),
true,
Some(SourceDefinition::from_identifier(&field_declaration.identifier))
)
);
Some(SourceDefinition::from_identifier(identifier)),
));
if let Err(insert_error) = insert_result {
handle_insert_error(
insert_error,
&field_declaration.identifier.name(),
field_declaration.identifier.file_id(),
field_declaration.identifier.range(),
&identifier.name(),
identifier.file_id(),
identifier.range(),
"Data Member",
diagnostics,
);
@ -987,10 +997,10 @@ fn gather_block_statement_inner(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for statement in &mut block.statements {
for statement in block.statements_mut() {
gather_statement(statement, symbol_table, fqn_context, diagnostics);
}
if let Some(expression) = &mut block.expression {
if let Some(expression) = block.expression_mut() {
gather_expression(expression, symbol_table, diagnostics);
}
}
@ -1001,7 +1011,7 @@ fn gather_statement(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::Statement::*;
use crate::ast::node::statement::Statement::*;
match statement {
BlockStatement(block) => {
gather_block_statement(block, symbol_table, fqn_context, diagnostics)
@ -1024,30 +1034,31 @@ fn gather_variable_declaration(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let variable_name = variable_declaration.identifier.name();
let identifier = variable_declaration.identifier();
let variable_name = identifier.name();
let insert_result = symbol_table.insert_variable_symbol(VariableSymbol::new(
&variable_name,
variable_declaration.is_mutable,
Some(&variable_declaration.identifier),
variable_declaration.is_mutable(),
Some(identifier),
));
if let Err(err) = insert_result {
handle_insert_error(
err,
&variable_name,
variable_declaration.identifier.file_id(),
variable_declaration.identifier.range(),
identifier.file_id(),
identifier.range(),
"function/variable",
diagnostics,
)
}
variable_declaration
.identifier
.identifier_mut()
.set_scope_id(symbol_table.current_scope_id());
if let Some(initializer) = &mut variable_declaration.initializer {
if let Some(initializer) = variable_declaration.initializer_mut() {
gather_expression(initializer, symbol_table, diagnostics);
}
}
@ -1058,8 +1069,8 @@ fn gather_assign_statement(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut assign_statement.lhs, symbol_table, diagnostics);
gather_expression(&mut assign_statement.rhs, symbol_table, diagnostics);
gather_expression(assign_statement.lhs_mut(), symbol_table, diagnostics);
gather_expression(assign_statement.rhs_mut(), symbol_table, diagnostics);
}
fn gather_call_statement(
@ -1067,16 +1078,15 @@ fn gather_call_statement(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut call_statement.0, symbol_table, diagnostics);
gather_expression(call_statement.expression_mut(), symbol_table, diagnostics);
}
fn gather_return_statement(
return_statement: &mut ReturnStatement,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
if let Some(expression) = &mut return_statement.0 {
if let Some(expression) = return_statement.expression_mut() {
gather_expression(expression, symbol_table, diagnostics);
}
}
@ -1087,9 +1097,9 @@ fn gather_if_statement(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut if_statement.condition, symbol_table, diagnostics);
gather_expression(if_statement.condition_mut(), symbol_table, diagnostics);
gather_block_statement(
&mut if_statement.then_block,
if_statement.then_block_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -1103,16 +1113,21 @@ fn gather_if_else_statement(
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_if_statement(
&mut if_else_statement.if_statement,
if_else_statement.if_statement_mut(),
symbol_table,
fqn_context,
diagnostics,
);
for if_statement in &mut if_else_statement.else_ifs.0 {
for if_statement in if_else_statement.else_ifs_mut().if_statements_mut() {
gather_if_statement(if_statement, symbol_table, fqn_context, diagnostics);
}
if let Some(else_block) = &mut if_else_statement.else_block {
gather_block_statement(&mut else_block.0, symbol_table, fqn_context, diagnostics);
if let Some(else_block) = if_else_statement.else_block_mut() {
gather_block_statement(
else_block.block_statement_mut(),
symbol_table,
fqn_context,
diagnostics,
);
}
}
@ -1122,9 +1137,9 @@ fn gather_while_statement(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut while_statement.condition, symbol_table, diagnostics);
gather_expression(while_statement.condition_mut(), symbol_table, diagnostics);
gather_block_statement(
&mut while_statement.body,
while_statement.body_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -1137,9 +1152,9 @@ fn gather_for_statement(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut for_statement.iterator, symbol_table, diagnostics);
gather_expression(for_statement.iterator_mut(), symbol_table, diagnostics);
symbol_table.push_scope("ForStatementScope");
let variable_identifier = &mut for_statement.variable;
let variable_identifier = for_statement.variable_mut();
let insert_result = symbol_table.insert_variable_symbol(VariableSymbol::new(
&variable_identifier.name(),
false,
@ -1149,7 +1164,7 @@ fn gather_for_statement(
match insert_result {
Ok(_) => {
gather_block_statement_inner(
&mut for_statement.body,
for_statement.body_mut(),
symbol_table,
fqn_context,
diagnostics,
@ -1177,7 +1192,7 @@ fn gather_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::Expression::*;
use crate::ast::node::expression::Expression::*;
match expression {
Ternary(ternary_expression) => {
gather_ternary_expression(ternary_expression, symbol_table, diagnostics);
@ -1214,14 +1229,18 @@ fn gather_ternary_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut ternary_expression.condition, symbol_table, diagnostics);
gather_expression(
&mut ternary_expression.true_expression,
ternary_expression.condition_mut(),
symbol_table,
diagnostics,
);
gather_expression(
&mut ternary_expression.false_expression,
ternary_expression.true_expression_mut(),
symbol_table,
diagnostics,
);
gather_expression(
ternary_expression.false_expression_mut(),
symbol_table,
diagnostics,
);
@ -1232,8 +1251,8 @@ fn gather_binary_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut binary_expression.left, symbol_table, diagnostics);
gather_expression(&mut binary_expression.right, symbol_table, diagnostics);
gather_expression(binary_expression.left_mut(), symbol_table, diagnostics);
gather_expression(binary_expression.right_mut(), symbol_table, diagnostics);
}
fn gather_prefix_expression(
@ -1241,7 +1260,11 @@ fn gather_prefix_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut prefix_expression.expression, symbol_table, diagnostics);
gather_expression(
prefix_expression.expression_mut(),
symbol_table,
diagnostics,
);
}
fn gather_suffix_expression(
@ -1249,7 +1272,11 @@ fn gather_suffix_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut suffix_expression.expression, symbol_table, diagnostics);
gather_expression(
suffix_expression.expression_mut(),
symbol_table,
diagnostics,
);
}
fn gather_call_expression(
@ -1257,12 +1284,12 @@ fn gather_call_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut call_expression.callee, symbol_table, diagnostics);
if let Some(turbo_fish) = &mut call_expression.turbo_fish {
gather_expression(call_expression.callee_mut(), symbol_table, diagnostics);
if let Some(turbo_fish) = call_expression.turbo_fish_mut() {
gather_turbo_fish(turbo_fish, symbol_table, diagnostics);
}
for call_argument in &mut call_expression.arguments.0 {
gather_expression(&mut call_argument.0, symbol_table, diagnostics);
for call_argument in call_expression.arguments_mut().arguments_mut() {
gather_expression(call_argument.expression_mut(), symbol_table, diagnostics);
}
}
@ -1287,8 +1314,8 @@ fn gather_object_access(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_expression(&mut object_access.receiver, symbol_table, diagnostics);
for object_navigation in &mut object_access.navigations.0 {
gather_expression(object_access.receiver_mut(), symbol_table, diagnostics);
for object_navigation in object_access.navigations_mut().navigations_mut() {
match object_navigation {
ObjectNavigation::Index(index_expression) => {
gather_expression(index_expression, symbol_table, diagnostics);

View File

@ -5,7 +5,7 @@ There are two phases in name analysis.
## 1. Gather
The gather phases has three responsibilities:
The gather phase has three responsibilities:
1. Add all declared symbols to the symbol table.
2. Set the `scope_id` property of all identifiers and fully-qualified-names.
@ -19,8 +19,8 @@ The resolve phase has one main responsibility: resolve all references based on t
`scope_id` property.
*/
use crate::ast::named::Named;
use crate::ast::CompilationUnit;
use crate::ast::node::compilation_unit::CompilationUnit;
use crate::ast::node::named::Named;
use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::gather::gather_compilation_unit;
use crate::name_analysis::resolve::resolve_compilation_unit;
@ -206,7 +206,7 @@ mod tests {
use greeter::Greeter;
class Greeter {}
"}
"},
),
(
"greeter.dm",
@ -214,8 +214,8 @@ mod tests {
ns greeter;
class Greeter {}
"}
)
"},
),
]);
assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
}

View File

@ -1,13 +1,29 @@
use crate::ast::named::Named;
use crate::ast::*;
use crate::ast::node::call_expression::*;
use crate::ast::node::class::*;
use crate::ast::node::closure::*;
use crate::ast::node::compilation_unit::*;
use crate::ast::node::d_string::*;
use crate::ast::node::expression::*;
use crate::ast::node::function::*;
use crate::ast::node::generics::*;
use crate::ast::node::implements_list::*;
use crate::ast::node::interface::*;
use crate::ast::node::level::*;
use crate::ast::node::literal::*;
use crate::ast::node::module::*;
use crate::ast::node::names::*;
use crate::ast::node::object_access::*;
use crate::ast::node::statement::*;
use crate::ast::node::tuple_arguments::*;
use crate::ast::node::type_use::*;
use crate::ast::node::use_statement::*;
use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::symbol::Symbol;
use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable};
use codespan_reporting::diagnostic::{Diagnostic, Label};
use std::cell::RefCell;
use std::ops::DerefMut;
use std::range::Range;
use std::rc::Rc;
use crate::ast::node::named::Named;
/* Type Use */
fn resolve_type_use(
@ -56,7 +72,7 @@ fn resolve_interface_or_class_type_use(
diagnostics: &mut Vec<DmDiagnostic>,
) {
// 1. handle main name
let fqn = &mut interface_or_class_type_use.fqn;
let fqn = interface_or_class_type_use.fqn_mut();
let lookup_result = if fqn.is_single_identifier() {
let identifier = fqn.last();
symbol_table.lookup_type_by_declared_name(
@ -86,7 +102,7 @@ fn resolve_interface_or_class_type_use(
// 2. generics
resolve_generic_arguments(
&mut interface_or_class_type_use.generics,
interface_or_class_type_use.generics_mut(),
symbol_table,
diagnostics,
);
@ -97,7 +113,7 @@ fn resolve_tuple_type_use(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_tuple_arguments(&mut tuple_type_use.arguments, symbol_table, diagnostics);
resolve_tuple_arguments(tuple_type_use.arguments_mut(), symbol_table, diagnostics);
}
fn resolve_function_type_use(
@ -105,9 +121,13 @@ fn resolve_function_type_use(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_parameters(&mut function_type_use.parameters, symbol_table, diagnostics);
resolve_parameters(
function_type_use.parameters_mut(),
symbol_table,
diagnostics,
);
resolve_return_type(
&mut function_type_use.return_type,
function_type_use.return_type_mut(),
symbol_table,
diagnostics,
);
@ -120,7 +140,7 @@ fn resolve_generic_arguments(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for generic_argument in &mut generic_arguments.0 {
for generic_argument in generic_arguments.arguments_mut() {
resolve_type_use(generic_argument, symbol_table, diagnostics);
}
}
@ -134,7 +154,7 @@ fn resolve_tuple_arguments(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for type_use in &mut tuple_type_use.0 {
for type_use in tuple_type_use.type_uses_mut() {
resolve_type_use(type_use, symbol_table, diagnostics);
}
}
@ -146,7 +166,7 @@ fn resolve_implements_list(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for type_use in &mut implements_list.0 {
for type_use in implements_list.type_uses_mut() {
resolve_type_use(type_use, symbol_table, diagnostics);
}
}
@ -158,8 +178,8 @@ fn resolve_parameters(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for parameter in &mut parameters.0 {
resolve_type_use(&mut parameter.type_use, symbol_table, diagnostics);
for parameter in parameters.parameters_mut() {
resolve_type_use(parameter.type_use_mut(), symbol_table, diagnostics);
}
}
@ -170,8 +190,8 @@ fn resolve_return_type(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_type_use(&mut return_type.declared_type, symbol_table, diagnostics);
resolve_references(&mut return_type.references, symbol_table, diagnostics);
resolve_type_use(return_type.declared_type_mut(), symbol_table, diagnostics);
resolve_references(return_type.references_mut(), symbol_table, diagnostics);
}
/* References */
@ -181,7 +201,7 @@ fn resolve_references(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for reference in &mut references.0 {
for reference in references.identifiers_mut() {
todo!()
}
}
@ -193,10 +213,10 @@ pub(super) fn resolve_compilation_unit(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for use_statement in &mut compilation_unit.use_statements {
for use_statement in compilation_unit.use_statements_mut() {
resolve_use_statement(use_statement, symbol_table, diagnostics);
}
for declaration in &mut compilation_unit.declarations {
for declaration in compilation_unit.declarations_mut() {
resolve_module_level_declaration(declaration, symbol_table, diagnostics);
}
}
@ -204,22 +224,20 @@ pub(super) fn resolve_compilation_unit(
/* Use Statement */
fn handle_use_statement_identifier(
identifier: Rc<RefCell<Identifier>>,
identifier: &mut Identifier,
base_name: &str,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
file_id: usize,
error_range: Range<usize>,
) {
let borrowed_identifier = identifier.borrow();
let declared_name = borrowed_identifier.name().to_string();
let declared_name = identifier.name().to_string();
let fqn = format!("{}::{}", base_name, &declared_name);
let lookup_result =
symbol_table.lookup_usable_by_fqn(&fqn, borrowed_identifier.scope_id().unwrap());
let lookup_result = symbol_table.lookup_usable_by_fqn(&fqn, identifier.scope_id().unwrap());
match lookup_result {
Ok(referenced_symbol) => {
let saved_symbol = borrowed_identifier
let saved_symbol = identifier
.saved_symbol()
.expect("Identifier's saved_symbol is not set.");
let use_statement_symbol = saved_symbol.unwrap_use_statement_symbol();
@ -242,28 +260,31 @@ fn resolve_use_statement(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let file_id = use_statement.file_id();
let use_statement_range = use_statement.range();
let base_name = use_statement.base_name().to_string();
match &use_statement.last {
match use_statement.last_mut() {
UseStatementLast::Identifier(identifier) => {
handle_use_statement_identifier(
identifier.clone(),
identifier.deref_mut(),
&base_name,
symbol_table,
diagnostics,
use_statement.file_id,
use_statement.range,
file_id,
use_statement_range,
);
}
UseStatementLast::Identifiers(identifiers) => {
for identifier in identifiers {
let identifier_range = identifier.range();
handle_use_statement_identifier(
identifier.clone(),
identifier.deref_mut(),
&base_name,
symbol_table,
diagnostics,
use_statement.file_id,
identifier.borrow().range(),
file_id,
identifier_range,
)
}
}
@ -278,7 +299,7 @@ fn resolve_module_level_declaration(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::ModuleLevelDeclaration::*;
use crate::ast::node::level::ModuleLevelDeclaration::*;
match declaration {
Module(module_declaration) => {
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
@ -305,7 +326,7 @@ fn resolve_interface_level_declaration(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::InterfaceLevelDeclaration::*;
use crate::ast::node::level::InterfaceLevelDeclaration::*;
match declaration {
Module(module_declaration) => {
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
@ -338,7 +359,7 @@ fn resolve_class_level_declaration(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::ClassLevelDeclaration::*;
use crate::ast::node::level::ClassLevelDeclaration::*;
match declaration {
Module(module_declaration) => {
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
@ -382,7 +403,7 @@ fn resolve_module_declaration(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for declaration in &mut module_declaration.declarations {
for declaration in module_declaration.declarations_mut() {
resolve_module_level_declaration(declaration, symbol_table, diagnostics);
}
}
@ -393,11 +414,11 @@ fn resolve_interface_declaration(
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_implements_list(
&mut interface_declaration.implements,
interface_declaration.implements_mut(),
symbol_table,
diagnostics,
);
for declaration in &mut interface_declaration.declarations {
for declaration in interface_declaration.declarations_mut() {
resolve_interface_level_declaration(declaration, symbol_table, diagnostics);
}
}
@ -407,11 +428,15 @@ fn resolve_class_declaration(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
if let Some(class_constructor) = &mut class_declaration.class_constructor {
if let Some(class_constructor) = class_declaration.class_constructor_mut() {
resolve_class_constructor(class_constructor, symbol_table, diagnostics);
}
resolve_implements_list(&mut class_declaration.implements, symbol_table, diagnostics);
for declaration in &mut class_declaration.declarations {
resolve_implements_list(
class_declaration.implements_mut(),
symbol_table,
diagnostics,
);
for declaration in class_declaration.declarations_mut() {
resolve_class_level_declaration(declaration, symbol_table, diagnostics);
}
}
@ -424,16 +449,16 @@ fn resolve_function_definition(
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_parameters(
&mut function_definition.parameters,
function_definition.parameters_mut(),
symbol_table,
diagnostics,
);
resolve_return_type(
&mut function_definition.return_type,
function_definition.return_type_mut(),
symbol_table,
diagnostics,
);
resolve_function_body(&mut function_definition.body, symbol_table, diagnostics);
resolve_function_body(function_definition.body_mut(), symbol_table, diagnostics);
}
fn resolve_operator_function_definition(
@ -450,12 +475,12 @@ fn resolve_platform_function_declaration(
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_parameters(
&mut platform_function_declaration.parameters,
platform_function_declaration.parameters_mut(),
symbol_table,
diagnostics,
);
resolve_return_type(
&mut platform_function_declaration.return_type,
platform_function_declaration.return_type_mut(),
symbol_table,
diagnostics,
);
@ -467,16 +492,16 @@ fn resolve_interface_function_declaration(
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_parameters(
&mut interface_function_declaration.parameters,
interface_function_declaration.parameters_mut(),
symbol_table,
diagnostics,
);
resolve_return_type(
&mut interface_function_declaration.return_type,
interface_function_declaration.return_type_mut(),
symbol_table,
diagnostics,
);
if let Some(body) = &mut interface_function_declaration.body {
if let Some(body) = interface_function_declaration.body_mut() {
resolve_function_body(body, symbol_table, diagnostics);
}
}
@ -494,7 +519,7 @@ fn resolve_function_body(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::FunctionBody::*;
use crate::ast::node::function::FunctionBody::*;
match function_body {
Equals(expression) => resolve_expression(expression, symbol_table, diagnostics),
Block(block) => resolve_block_statement(block, symbol_table, diagnostics),
@ -517,8 +542,8 @@ fn resolve_class_constructor(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::ClassConstructorParameter::*;
for parameter in &mut class_constructor.0 {
use crate::ast::node::class::ClassConstructorParameter::*;
for parameter in class_constructor.parameters_mut() {
match parameter {
Property(property) => resolve_property_declaration(property, symbol_table, diagnostics),
Field(field) => resolve_field_declaration(field, symbol_table, diagnostics),
@ -532,7 +557,7 @@ fn resolve_property_declaration(
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_type_use(
&mut property_declaration.declared_type,
property_declaration.declared_type_mut(),
symbol_table,
diagnostics,
);
@ -544,7 +569,7 @@ fn resolve_field_declaration(
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_type_use(
&mut field_declaration.declared_type,
field_declaration.declared_type_mut(),
symbol_table,
diagnostics,
);
@ -557,10 +582,10 @@ fn resolve_block_statement(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for statement in block_statement.statements.iter_mut() {
for statement in block_statement.statements_mut() {
resolve_statement(statement, symbol_table, diagnostics);
}
if let Some(expression) = block_statement.expression.as_mut() {
if let Some(expression) = block_statement.expression_mut() {
resolve_expression(expression, symbol_table, diagnostics);
}
}
@ -570,7 +595,7 @@ fn resolve_statement(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::Statement::*;
use crate::ast::node::statement::Statement::*;
match statement {
BlockStatement(block) => resolve_block_statement(block, symbol_table, diagnostics),
VariableDeclarationStatement(variable_declaration) => {
@ -591,7 +616,7 @@ fn resolve_variable_declaration(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
if let Some(initializer) = &mut variable_declaration.initializer {
if let Some(initializer) = variable_declaration.initializer_mut() {
resolve_expression(initializer, symbol_table, diagnostics)
}
}
@ -601,8 +626,8 @@ fn resolve_assign_statement(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(&mut assign_statement.lhs, symbol_table, diagnostics);
resolve_expression(&mut assign_statement.rhs, symbol_table, diagnostics);
resolve_expression(assign_statement.lhs_mut(), symbol_table, diagnostics);
resolve_expression(assign_statement.rhs_mut(), symbol_table, diagnostics);
}
fn resolve_call_statement(
@ -610,7 +635,7 @@ fn resolve_call_statement(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(&mut call_statement.0, symbol_table, diagnostics)
resolve_expression(call_statement.expression_mut(), symbol_table, diagnostics)
}
fn resolve_return_statement(
@ -618,7 +643,7 @@ fn resolve_return_statement(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
if let Some(expression) = &mut return_statement.0 {
if let Some(expression) = return_statement.expression_mut() {
resolve_expression(expression, symbol_table, diagnostics);
}
}
@ -654,7 +679,7 @@ fn resolve_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::Expression::*;
use crate::ast::node::expression::Expression::*;
match expression {
Ternary(ternary_expression) => {
resolve_ternary_expression(ternary_expression, symbol_table, diagnostics);
@ -737,14 +762,18 @@ fn resolve_ternary_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(&mut ternary_expression.condition, symbol_table, diagnostics);
resolve_expression(
&mut ternary_expression.true_expression,
ternary_expression.condition_mut(),
symbol_table,
diagnostics,
);
resolve_expression(
&mut ternary_expression.false_expression,
ternary_expression.true_expression_mut(),
symbol_table,
diagnostics,
);
resolve_expression(
ternary_expression.false_expression_mut(),
symbol_table,
diagnostics,
);
@ -755,8 +784,8 @@ fn resolve_binary_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(&mut binary_expression.left, symbol_table, diagnostics);
resolve_expression(&mut binary_expression.right, symbol_table, diagnostics);
resolve_expression(binary_expression.left_mut(), symbol_table, diagnostics);
resolve_expression(binary_expression.right_mut(), symbol_table, diagnostics);
}
fn resolve_prefix_expression(
@ -764,7 +793,11 @@ fn resolve_prefix_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(&mut prefix_expression.expression, symbol_table, diagnostics);
resolve_expression(
prefix_expression.expression_mut(),
symbol_table,
diagnostics,
);
}
fn resolve_suffix_expression(
@ -772,7 +805,11 @@ fn resolve_suffix_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(&mut suffix_expression.expression, symbol_table, diagnostics);
resolve_expression(
suffix_expression.expression_mut(),
symbol_table,
diagnostics,
);
}
fn resolve_call_expression(
@ -780,11 +817,11 @@ fn resolve_call_expression(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(&mut call_expression.callee, symbol_table, diagnostics);
if let Some(turbo_fish) = &mut call_expression.turbo_fish {
resolve_expression(call_expression.callee_mut(), symbol_table, diagnostics);
if let Some(turbo_fish) = call_expression.turbo_fish_mut() {
resolve_turbo_fish(turbo_fish, symbol_table, diagnostics);
}
resolve_call_arguments(&mut call_expression.arguments, symbol_table, diagnostics);
resolve_call_arguments(call_expression.arguments_mut(), symbol_table, diagnostics);
}
fn resolve_turbo_fish(
@ -792,7 +829,7 @@ fn resolve_turbo_fish(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_generic_arguments(&mut turbo_fish.0, symbol_table, diagnostics);
resolve_generic_arguments(turbo_fish.generics_mut(), symbol_table, diagnostics);
}
fn resolve_call_arguments(
@ -800,7 +837,7 @@ fn resolve_call_arguments(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for argument in &mut call_arguments.0 {
for argument in call_arguments.arguments_mut() {
resolve_call_argument(argument, symbol_table, diagnostics);
}
}
@ -810,7 +847,7 @@ fn resolve_call_argument(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(&mut call_argument.0, symbol_table, diagnostics);
resolve_expression(call_argument.expression_mut(), symbol_table, diagnostics);
}
fn resolve_closure(

View File

@ -1,5 +1,6 @@
use crate::ast::named::Named;
use crate::ast::{Identifier, UseStatement};
use crate::ast::node::named::Named;
use crate::ast::node::names::Identifier;
use crate::ast::node::use_statement::UseStatement;
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter};
use std::ops::Deref;
@ -31,8 +32,8 @@ impl SourceDefinition {
#[deprecated(note = "Use identifier instead.")]
pub fn from_use_statement(use_statement: &UseStatement) -> Self {
SourceDefinition {
file_id: use_statement.file_id,
range: use_statement.range,
file_id: use_statement.file_id(),
range: use_statement.range(),
}
}
@ -97,15 +98,11 @@ pub struct UseStatementSymbol {
}
impl UseStatementSymbol {
pub fn new(
fqn: &str,
declared_name: &str,
identifier: Option<Rc<RefCell<Identifier>>>,
) -> Self {
pub fn new(fqn: &str, declared_name: &str, identifier: Option<&Identifier>) -> Self {
UseStatementSymbol {
fqn: fqn.to_string(),
declared_name: declared_name.to_string(),
definition: identifier.map(SourceDefinition::from_identifier_rc),
definition: identifier.map(SourceDefinition::from_identifier),
referenced_symbol: None,
}
}

View File

@ -120,6 +120,7 @@ Star = { "*" }
LeftShift = { "<<" }
RightShift = { ">>" }
Index = { "[]" }
BorrowMut = { Borrow ~ Mut }
Operator = {
Or
@ -135,16 +136,19 @@ Operator = {
| Multiply
| Divide
| Modulo
| LeftShift
| RightShift
// unary prefix
| Spread
| BorrowMut
| Borrow
| Star
| Not
| Negative
// unary suffix
| PlusPlus
| MinusMinus
| CallOp
| Spread
| Borrow
| Star
| LeftShift
| RightShift
| Index
}
@ -457,10 +461,10 @@ InterfaceDefaultOperatorFunction = {
Def
~ FunctionModifier?
~ Op
~ GenericParameters?
~ Operator
~ Parameters
~ ReturnType
~ RefList?
~ FunctionBody
}
@ -698,10 +702,6 @@ PrefixExpression = {
~ SuffixExpression
}
BorrowMut = {
Borrow ~ Mut
}
SuffixExpression = {
PrimaryExpression
~ (