692 lines
14 KiB
Rust
692 lines
14 KiB
Rust
use crate::name_analysis::symbol::Symbol;
|
|
use pest::Parser;
|
|
use std::range::Range;
|
|
|
|
pub mod build;
|
|
pub mod named;
|
|
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, Clone)]
|
|
pub struct Identifier {
|
|
pub name: String,
|
|
pub file_id: usize,
|
|
pub range: Range<usize>,
|
|
scope_id: Option<usize>,
|
|
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,
|
|
symbol: None,
|
|
}
|
|
}
|
|
|
|
pub fn set_scope_id(&mut self, id: usize) {
|
|
self.scope_id = Some(id);
|
|
}
|
|
|
|
pub fn scope_id(&self) -> Option<usize> {
|
|
self.scope_id
|
|
}
|
|
|
|
pub fn set_symbol(&mut self, symbol: Symbol) {
|
|
self.symbol = Some(symbol);
|
|
}
|
|
|
|
pub fn symbol(&self) -> &Option<Symbol> {
|
|
&self.symbol
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct FullyQualifiedName {
|
|
pub identifiers: Vec<Identifier>,
|
|
pub file_id: usize,
|
|
pub range: Range<usize>,
|
|
scope_id: Option<usize>,
|
|
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,
|
|
symbol: None,
|
|
}
|
|
}
|
|
|
|
pub fn set_scope_id(&mut self, scope_id: usize) {
|
|
self.scope_id = Some(scope_id);
|
|
}
|
|
|
|
pub fn scope_id(&self) -> Option<usize> {
|
|
self.scope_id
|
|
}
|
|
|
|
pub fn set_symbol(&mut self, symbol: Symbol) {
|
|
self.symbol = Some(symbol);
|
|
}
|
|
|
|
pub fn symbol(&self) -> &Option<Symbol> {
|
|
&self.symbol
|
|
}
|
|
}
|
|
|
|
/* Type Use */
|
|
|
|
#[derive(Debug)]
|
|
pub enum TypeUse {
|
|
Void,
|
|
InterfaceOrClass(InterfaceOrClassTypeUse),
|
|
Tuple(TupleTypeUse),
|
|
Function(FunctionTypeUse),
|
|
}
|
|
|
|
#[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::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 namespace: Option<FullyQualifiedName>,
|
|
pub declarations: Vec<ModuleLevelDeclaration>,
|
|
}
|
|
|
|
// 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),
|
|
}
|
|
|
|
// 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 {
|
|
expression: Box<Expression>,
|
|
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,
|
|
}
|
|
}
|
|
}
|