Create and implement AST structs/enums and Unparse traits.
This commit is contained in:
parent
1a365481ab
commit
e8aff842ed
16
sketching/april_2025/closure_inputs.dm
Normal file
16
sketching/april_2025/closure_inputs.dm
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
class Counter {
|
||||||
|
fld count: Int
|
||||||
|
|
||||||
|
mut getAndIncrement() -> Int {
|
||||||
|
let result = count
|
||||||
|
count++
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synthetic
|
||||||
|
class MyClosure(delegate: Counter) : MutClosure(Int, Int) -> Int |delegate| {
|
||||||
|
mut fn call(x: Int, y: Int) -> Int {
|
||||||
|
x + y + delegate.getAndIncrement()
|
||||||
|
}
|
||||||
|
}
|
14
sketching/april_2025/iterator.dm
Normal file
14
sketching/april_2025/iterator.dm
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
pub type Iterator<T> |backing: &Any| = mut fn () -> Option<&T ref backing>
|
||||||
|
|
||||||
|
pub int Iterable<T> {
|
||||||
|
ref fn iterator() -> Iterator<T>(&self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let nums: List<Int> = [1, 2, 3]
|
||||||
|
let iterator: Iterator<Int> |backing = nums| = nums.iterator()
|
||||||
|
let first: &Int ref nums = iterator().unwrap()
|
||||||
|
let second: &Int ref nums = iterator().unwrap()
|
||||||
|
let third: &Int ref nums = iterator().unwrap()
|
||||||
|
println "${*first}, ${*second}, ${*third}"
|
||||||
|
}
|
605
src/ast/mod.rs
605
src/ast/mod.rs
@ -1,256 +1,507 @@
|
|||||||
use crate::vm::source_code_location::SourceCodeLocation;
|
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
|
|
||||||
pub mod build;
|
pub mod build;
|
||||||
|
pub mod unparse;
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CompilationUnit {
|
pub enum Operator {
|
||||||
namespace: Option<Fqn>,
|
Binary(BinaryOperator),
|
||||||
declarations: Vec<Declaration>,
|
Unary(UnaryOperator),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompilationUnit {
|
#[derive(Debug)]
|
||||||
pub fn namespace(&self) -> &Option<Fqn> {
|
pub enum BinaryOperator {
|
||||||
&self.namespace
|
Or,
|
||||||
|
And,
|
||||||
|
EqualTo,
|
||||||
|
NotEqualTo,
|
||||||
|
Greater,
|
||||||
|
Less,
|
||||||
|
GreaterEqual,
|
||||||
|
LessEqual,
|
||||||
|
Add,
|
||||||
|
Subtract,
|
||||||
|
Multiply,
|
||||||
|
Divide,
|
||||||
|
Modulo,
|
||||||
|
LeftShift,
|
||||||
|
RightShift,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declarations(&self) -> &Vec<Declaration> {
|
#[derive(Debug)]
|
||||||
&self.declarations
|
pub enum UnaryOperator {
|
||||||
|
Not,
|
||||||
|
Negative,
|
||||||
|
PlusPlus,
|
||||||
|
MinusMinus,
|
||||||
|
CallOp,
|
||||||
|
Spread,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Names
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Identifier {
|
||||||
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Fqn {
|
pub struct Fqn {
|
||||||
identifiers: Vec<Identifier>,
|
pub identifiers: Vec<Identifier>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fqn {
|
// Generic parameters
|
||||||
pub fn new(identifiers: Vec<Identifier>) -> Self {
|
|
||||||
Fqn { identifiers }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn identifiers(&self) -> &Vec<Identifier> {
|
|
||||||
&self.identifiers
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push_identifier(&mut self, identifier: Identifier) {
|
|
||||||
self.identifiers.push(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pop_identifier(&mut self) {
|
|
||||||
self.identifiers.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Declaration {
|
pub struct GenericParameters(pub Vec<GenericParameter>);
|
||||||
Interface {
|
|
||||||
identifier: Identifier,
|
|
||||||
is_extern: bool,
|
|
||||||
is_public: bool,
|
|
||||||
type_declaration: TypeDeclaration,
|
|
||||||
},
|
|
||||||
Implementation {
|
|
||||||
identifier: Identifier,
|
|
||||||
is_extern: bool,
|
|
||||||
is_public: bool,
|
|
||||||
type_declaration: TypeDeclaration,
|
|
||||||
impl_ctor: Option<ClassConstructor>,
|
|
||||||
},
|
|
||||||
Module {
|
|
||||||
identifier: Identifier,
|
|
||||||
is_extern: bool,
|
|
||||||
is_public: bool,
|
|
||||||
declarations: Vec<Declaration>,
|
|
||||||
},
|
|
||||||
Function(FunctionDeclaration),
|
|
||||||
Prop(Prop),
|
|
||||||
Field(Field),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
impl GenericParameters {
|
||||||
pub struct FunctionDeclaration {
|
pub fn is_empty(&self) -> bool {
|
||||||
source_code_location: SourceCodeLocation,
|
self.0.is_empty()
|
||||||
identifier: Identifier,
|
|
||||||
is_extern: bool,
|
|
||||||
is_public: bool,
|
|
||||||
parameters: Vec<Parameter>,
|
|
||||||
declared_type: Option<TypeUse>,
|
|
||||||
block_statement: BlockStatement,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FunctionDeclaration {
|
|
||||||
pub fn source_code_location(&self) -> &SourceCodeLocation {
|
|
||||||
&self.source_code_location
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn identifier(&self) -> &Identifier {
|
|
||||||
&self.identifier
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn block_statement(&self) -> &BlockStatement {
|
|
||||||
&self.block_statement
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TypeDeclaration {
|
|
||||||
generics: Vec<GenericParameter>,
|
|
||||||
extends: Vec<TypeUse>,
|
|
||||||
declarations: Vec<Declaration>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypeDeclaration {
|
|
||||||
pub fn new(
|
|
||||||
generics: Vec<GenericParameter>,
|
|
||||||
extends: Vec<TypeUse>,
|
|
||||||
declarations: Vec<Declaration>,
|
|
||||||
) -> TypeDeclaration {
|
|
||||||
TypeDeclaration {
|
|
||||||
generics,
|
|
||||||
extends,
|
|
||||||
declarations,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Identifier {
|
|
||||||
name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Identifier {
|
|
||||||
pub fn name(&self) -> &str {
|
|
||||||
&self.name
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GenericParameter {
|
pub struct GenericParameter {
|
||||||
identifier: Identifier,
|
identifier: Identifier,
|
||||||
bound: Option<GenericBound>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generic arguments
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum GenericBound {
|
pub struct GenericArguments(pub Vec<GenericArgument>);
|
||||||
Extends { fqn: Fqn },
|
|
||||||
Super { fqn: Fqn },
|
impl GenericArguments {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GenericArgument {
|
pub struct GenericArgument {
|
||||||
fqn: Fqn,
|
pub fqn: Fqn,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type-use and components
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TypeUse {
|
pub struct TypeUse {
|
||||||
fqn: Fqn,
|
pub fqn: Fqn,
|
||||||
generics: Vec<GenericArgument>,
|
pub arguments: Option<TypeArguments>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ClassConstructor {
|
pub enum TypeArguments {
|
||||||
args: Vec<ClassMember>,
|
Generics(GenericArguments),
|
||||||
|
Tuple(TupleArguments),
|
||||||
|
Function(FunctionTypeArguments),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClassConstructor {
|
#[derive(Debug)]
|
||||||
pub fn new(args: Vec<ClassMember>) -> Self {
|
pub struct TupleArguments(pub Vec<Fqn>);
|
||||||
ClassConstructor { args }
|
|
||||||
|
impl TupleArguments {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ClassMember {
|
pub struct FunctionTypeArguments {
|
||||||
is_field: bool,
|
pub parameters: Parameters,
|
||||||
|
pub return_type: Box<TypeUse>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function components
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Parameters(pub Vec<Parameter>);
|
||||||
|
|
||||||
|
impl Parameters {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Parameter {
|
||||||
identifier: Identifier,
|
identifier: Identifier,
|
||||||
type_use: Option<TypeUse>
|
type_use: TypeUse,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClassMember {
|
#[derive(Debug)]
|
||||||
pub fn new(is_field: bool, identifier: Identifier, type_use: Option<TypeUse>) -> Self {
|
pub struct ReturnType {
|
||||||
ClassMember {
|
pub type_use: Box<TypeUse>,
|
||||||
is_field,
|
pub references: References,
|
||||||
identifier,
|
|
||||||
type_use
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct References(pub Vec<Reference>);
|
||||||
|
|
||||||
|
impl References {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ImplCtorArg {
|
pub struct Reference {
|
||||||
is_field: bool,
|
pub identifier: Identifier,
|
||||||
identifier: Identifier,
|
}
|
||||||
r#type: Option<TypeUse>,
|
|
||||||
|
// Inputs
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum DelegateOrIdentifier {
|
||||||
|
Delegate,
|
||||||
|
Identifier(Identifier),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Prop {
|
pub struct InputParameters(pub Vec<DelegateOrIdentifier>);
|
||||||
identifier: Identifier,
|
|
||||||
r#type: TypeUse,
|
impl InputParameters {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Field {
|
pub struct InputArguments(pub Vec<InputArgument>);
|
||||||
identifier: Identifier,
|
|
||||||
r#type: TypeUse,
|
impl InputArguments {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BlockStatement {
|
pub struct InputArgument {
|
||||||
statements: Vec<Statement>,
|
pub lhs: DelegateOrIdentifier,
|
||||||
|
pub rhs: Identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockStatement {
|
// Where guards
|
||||||
pub fn statements(&self) -> &Vec<Statement> {
|
|
||||||
&self.statements
|
#[derive(Debug)]
|
||||||
|
pub struct WhereGuards(pub Vec<WhereGuard>);
|
||||||
|
|
||||||
|
impl WhereGuards {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct WhereGuard {
|
||||||
|
pub identifier: Identifier,
|
||||||
|
pub implements: ImplementsList
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ImplementsList(pub Vec<TypeUse>);
|
||||||
|
|
||||||
|
impl ImplementsList {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top-level construct
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CompilationUnit {
|
||||||
|
pub namespace: Option<Fqn>,
|
||||||
|
pub declarations: Vec<ModuleLevelDeclaration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Declarations allowed in each level
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ModuleLevelDeclaration {
|
||||||
|
Type(TypeDeclaration),
|
||||||
|
Module(ModuleDeclaration),
|
||||||
|
Interface(InterfaceDeclaration),
|
||||||
|
Class(ClassDeclaration),
|
||||||
|
Function(FunctionDeclaration),
|
||||||
|
PlatformFunction(PlatformFunctionDeclaration),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum InterfaceLevelDeclaration {
|
||||||
|
Type(TypeDeclaration),
|
||||||
|
Module(ModuleDeclaration),
|
||||||
|
Interface(InterfaceDeclaration),
|
||||||
|
Class(ClassDeclaration),
|
||||||
|
Function(InterfaceFunctionDeclaration),
|
||||||
|
OperatorFunction(InterfaceOperatorFunctionDeclaration),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ClassLevelDeclaration {
|
||||||
|
Type(TypeDeclaration),
|
||||||
|
Module(ModuleDeclaration),
|
||||||
|
Interface(InterfaceDeclaration),
|
||||||
|
Class(ClassDeclaration),
|
||||||
|
Function(FunctionDeclaration),
|
||||||
|
OperatorFunction(OperatorFunctionDeclaration),
|
||||||
|
PlatformFunction(PlatformFunctionDeclaration),
|
||||||
|
Field(FieldDeclaration),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Declarations
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TypeDeclaration {
|
||||||
|
pub is_public: bool,
|
||||||
|
pub identifier: Identifier,
|
||||||
|
pub parameters: Option<TypeParameters>,
|
||||||
|
pub where_guards: WhereGuards,
|
||||||
|
pub rhs: TypeUse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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 inputs: InputParameters,
|
||||||
|
pub implements: ImplementsList,
|
||||||
|
pub where_guards: WhereGuards,
|
||||||
|
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 inputs: InputArguments,
|
||||||
|
pub implements: ImplementsList,
|
||||||
|
pub where_guards: WhereGuards,
|
||||||
|
pub declarations: Vec<ClassLevelDeclaration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function declarations and components
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum FunctionModifier {
|
||||||
|
Static,
|
||||||
|
Cons,
|
||||||
|
Mut,
|
||||||
|
Ref,
|
||||||
|
MutRef,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum FunctionBody {
|
||||||
|
EqualsBody(Expression),
|
||||||
|
BlockBody(BlockStatement),
|
||||||
|
AliasBody(Identifier),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FunctionDeclaration {
|
||||||
|
pub is_public: bool,
|
||||||
|
pub modifier: Option<FunctionModifier>,
|
||||||
|
pub generics: GenericParameters,
|
||||||
|
pub identifier: Identifier,
|
||||||
|
pub parameters: Parameters,
|
||||||
|
pub return_type: Option<ReturnType>,
|
||||||
|
pub body: FunctionBody,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct OperatorFunctionDeclaration {
|
||||||
|
pub is_public: bool,
|
||||||
|
pub modifier: Option<FunctionModifier>,
|
||||||
|
pub generics: GenericParameters,
|
||||||
|
pub operator: Operator,
|
||||||
|
pub parameters: Parameters,
|
||||||
|
pub return_type: Option<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: TypeUse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InterfaceFunctionDeclaration {
|
||||||
|
pub modifier: Option<FunctionModifier>,
|
||||||
|
pub generics: GenericParameters,
|
||||||
|
pub identifier: Identifier,
|
||||||
|
pub parameters: Parameters,
|
||||||
|
pub return_type: ReturnType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InterfaceOperatorFunctionDeclaration {
|
||||||
|
pub modifier: Option<FunctionModifier>,
|
||||||
|
pub generics: GenericParameters,
|
||||||
|
pub operator: Operator,
|
||||||
|
pub parameters: Parameters,
|
||||||
|
pub return_type: ReturnType,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type components
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum TypeParameters {
|
||||||
|
Generic(GenericParameters),
|
||||||
|
Tuple(TupleParameters),
|
||||||
|
Function(FunctionTypeParameters),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TupleParameters(pub Vec<Identifier>);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FunctionTypeParameters {
|
||||||
|
pub parameters: Parameters,
|
||||||
|
pub return_type: TypeUse,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class components
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ClassConstructor(pub Vec<ClassConstructorParameter>);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ClassConstructorParameter {
|
||||||
|
pub is_field: 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 Vec<Statement>);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
|
BlockStatement(BlockStatement),
|
||||||
CallStatement(CallExpression),
|
CallStatement(CallExpression),
|
||||||
AssignStatement(AssignExpression),
|
VariableDeclarationStatement(VariableDeclarationStatement),
|
||||||
|
AssignStatement(AssignStatement),
|
||||||
|
ReturnStatement(ReturnStatement),
|
||||||
|
IfStatement(IfStatement),
|
||||||
|
IfElseStatement(IfElseStatement),
|
||||||
|
WhileStatement(WhileStatement),
|
||||||
|
ForStatement(ForStatement),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct VariableDeclarationStatement {
|
||||||
|
is_mutable: bool,
|
||||||
|
identifier: Identifier,
|
||||||
|
declared_type: Option<TypeUse>,
|
||||||
|
initializer: Option<Expression>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AssignStatement(pub AssignmentExpression);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ReturnStatement(pub Option<Expression>);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct IfStatement {
|
||||||
|
pub condition: Expression,
|
||||||
|
pub then_branch: BlockStatement,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct IfElseStatement {
|
||||||
|
pub condition: Expression,
|
||||||
|
pub then_branch: BlockStatement,
|
||||||
|
pub else_ifs: ElseIfs,
|
||||||
|
pub else_branch: BlockStatement,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ElseIfs(pub Vec<IfStatement>);
|
||||||
|
|
||||||
|
#[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 {
|
||||||
|
Binary(BinaryExpression),
|
||||||
|
Unary(UnaryExpression),
|
||||||
|
Assignment(Box<AssignmentExpression>),
|
||||||
|
Call(CallExpression),
|
||||||
|
Literal(Literal)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BinaryExpression {
|
||||||
|
pub left: Box<Expression>,
|
||||||
|
pub operator: BinaryOperator,
|
||||||
|
pub right: Box<Expression>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct UnaryExpression {
|
||||||
|
pub operator: UnaryOperator,
|
||||||
|
pub expression: Box<Expression>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AssignmentExpression {
|
||||||
|
identifier: Identifier,
|
||||||
|
expression: Expression,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CallExpression {
|
pub struct CallExpression {
|
||||||
receiver: Expression,
|
pub callee: Box<Expression>,
|
||||||
actuals_list: Vec<Expression>,
|
pub arguments: CallArguments
|
||||||
source_code_location: SourceCodeLocation,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CallExpression {
|
|
||||||
pub fn receiver(&self) -> &Expression {
|
|
||||||
&self.receiver
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn actuals_list(&self) -> &Vec<Expression> {
|
|
||||||
&self.actuals_list
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn source_code_location(&self) -> &SourceCodeLocation {
|
|
||||||
&self.source_code_location
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AssignExpression {
|
pub struct CallArguments(pub Vec<CallArgument>);
|
||||||
left: LValue,
|
|
||||||
right: Expression,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Expression {
|
pub struct CallArgument(pub Box<Expression>);
|
||||||
CallExpression(Box<CallExpression>),
|
|
||||||
AssignExpression(Box<AssignExpression>),
|
|
||||||
LValue(Box<LValue>),
|
|
||||||
Literal(Box<Literal>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum LValue {
|
|
||||||
Fqn(Fqn),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Literal {
|
pub enum Literal {
|
||||||
@ -261,9 +512,3 @@ pub enum Literal {
|
|||||||
StringLiteral(String),
|
StringLiteral(String),
|
||||||
BooleanLiteral(bool),
|
BooleanLiteral(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Parameter {
|
|
||||||
identifier: Identifier,
|
|
||||||
declared_type: Option<TypeUse>,
|
|
||||||
}
|
|
||||||
|
959
src/ast/unparse.rs
Normal file
959
src/ast/unparse.rs
Normal file
@ -0,0 +1,959 @@
|
|||||||
|
use crate::ast::*;
|
||||||
|
|
||||||
|
macro_rules! to_unparse_vec {
|
||||||
|
( $nodes:expr ) => {
|
||||||
|
$nodes
|
||||||
|
.iter()
|
||||||
|
.map(|node| node as &dyn Unparse)
|
||||||
|
.collect::<Vec<&dyn Unparse>>()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! unparse_contained_declarations {
|
||||||
|
( $declarations:expr, $buf:expr ) => {
|
||||||
|
if !$declarations.is_empty() {
|
||||||
|
write!($buf, "{{\n")?;
|
||||||
|
unparse_list($buf, "\n\n", &to_unparse_vec!($declarations));
|
||||||
|
write!($buf, "\n}}")?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! unparse_ok {
|
||||||
|
() => {
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Unparse {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ListUnparse: Unparse {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str;
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ListUnparse> Unparse for T {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(buf, "{}", Self::prefix())?;
|
||||||
|
unparse_list(buf, Self::separator(), &self.inner())?;
|
||||||
|
write!(buf, "{}", Self::suffix())?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparse_list(
|
||||||
|
buf: &mut dyn std::fmt::Write,
|
||||||
|
sep: &str,
|
||||||
|
items: &[&dyn Unparse],
|
||||||
|
) -> std::fmt::Result {
|
||||||
|
for (i, item) in items.iter().enumerate() {
|
||||||
|
item.unparse(buf)?;
|
||||||
|
if i < items.len() - 1 {
|
||||||
|
write!(buf, "{}", sep)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparse_comma_list(buf: &mut dyn std::fmt::Write, items: &[&dyn Unparse]) -> std::fmt::Result {
|
||||||
|
unparse_list(buf, ", ", items)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementations */
|
||||||
|
|
||||||
|
/* Operators */
|
||||||
|
|
||||||
|
impl Unparse for Operator {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use Operator::*;
|
||||||
|
match self {
|
||||||
|
Binary(op) => op.unparse(buf),
|
||||||
|
Unary(op) => op.unparse(buf),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for BinaryOperator {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use BinaryOperator::*;
|
||||||
|
match self {
|
||||||
|
Or => write!(buf, "||"),
|
||||||
|
And => write!(buf, "&&"),
|
||||||
|
EqualTo => write!(buf, "=="),
|
||||||
|
NotEqualTo => write!(buf, "!="),
|
||||||
|
Greater => write!(buf, ">"),
|
||||||
|
Less => write!(buf, "<"),
|
||||||
|
GreaterEqual => write!(buf, ">="),
|
||||||
|
LessEqual => write!(buf, "<="),
|
||||||
|
Add => write!(buf, "+"),
|
||||||
|
Subtract => write!(buf, "-"),
|
||||||
|
Multiply => write!(buf, "*"),
|
||||||
|
Divide => write!(buf, "/"),
|
||||||
|
Modulo => write!(buf, "%"),
|
||||||
|
LeftShift => write!(buf, "<<"),
|
||||||
|
RightShift => write!(buf, ">>"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for UnaryOperator {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use UnaryOperator::*;
|
||||||
|
match self {
|
||||||
|
Not => write!(buf, "!"),
|
||||||
|
Negative => write!(buf, "-"),
|
||||||
|
PlusPlus => write!(buf, "++"),
|
||||||
|
MinusMinus => write!(buf, "--"),
|
||||||
|
CallOp => write!(buf, "()"),
|
||||||
|
Spread => write!(buf, "..."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Names */
|
||||||
|
|
||||||
|
impl Unparse for Identifier {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(buf, "{}", self.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListUnparse for Fqn {
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
"::"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.identifiers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic Parameters */
|
||||||
|
|
||||||
|
impl ListUnparse for GenericParameters {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"<"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
">"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for GenericParameter {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.identifier.unparse(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic arguments */
|
||||||
|
|
||||||
|
impl ListUnparse for GenericArguments {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"<"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
">"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for GenericArgument {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.fqn.unparse(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TypeUse and components */
|
||||||
|
|
||||||
|
impl Unparse for TypeUse {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.fqn.unparse(buf)?;
|
||||||
|
if let Some(type_arguments) = &self.arguments {
|
||||||
|
type_arguments.unparse(buf)?;
|
||||||
|
}
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for TypeArguments {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use TypeArguments::*;
|
||||||
|
match self {
|
||||||
|
Generics(generic_arguments) => generic_arguments.unparse(buf),
|
||||||
|
Tuple(tuple_arguments) => tuple_arguments.unparse(buf),
|
||||||
|
Function(function_type_arguments) => function_type_arguments.unparse(buf),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListUnparse for TupleArguments {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"("
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
")"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for FunctionTypeArguments {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.parameters.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.return_type.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function components */
|
||||||
|
|
||||||
|
impl ListUnparse for Parameters {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"("
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
")"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for Parameter {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
write!(buf, ": ")?;
|
||||||
|
self.type_use.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for ReturnType {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(buf, "-> ")?;
|
||||||
|
self.type_use.unparse(buf)?;
|
||||||
|
if !self.references.is_empty() {
|
||||||
|
self.references.unparse(buf)?;
|
||||||
|
}
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListUnparse for References {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"ref "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for Reference {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.identifier.unparse(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input parameters and arguments */
|
||||||
|
|
||||||
|
impl Unparse for DelegateOrIdentifier {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use DelegateOrIdentifier::*;
|
||||||
|
match self {
|
||||||
|
Delegate => write!(buf, "delegate"),
|
||||||
|
Identifier(identifier) => identifier.unparse(buf),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListUnparse for InputParameters {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"|"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
"|"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListUnparse for InputArguments {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"|"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
"|"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for InputArgument {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.lhs.unparse(buf)?;
|
||||||
|
write!(buf, " = ")?;
|
||||||
|
self.rhs.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Where guards */
|
||||||
|
|
||||||
|
impl ListUnparse for WhereGuards {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"where "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for WhereGuard {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
write!(buf, " : ")?;
|
||||||
|
self.implements.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implements */
|
||||||
|
|
||||||
|
impl ListUnparse for ImplementsList {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
": "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
" + "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Top-level construct */
|
||||||
|
|
||||||
|
impl Unparse for CompilationUnit {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if let Some(namespace) = &self.namespace {
|
||||||
|
write!(buf, "ns ")?;
|
||||||
|
namespace.unparse(buf)?;
|
||||||
|
write!(buf, "\n\n")?;
|
||||||
|
}
|
||||||
|
unparse_list(buf, "\n\n", &to_unparse_vec!(self.declarations))?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Declarations allowed in each level */
|
||||||
|
|
||||||
|
impl Unparse for ModuleLevelDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use ModuleLevelDeclaration::*;
|
||||||
|
match self {
|
||||||
|
Type(type_declaration) => type_declaration.unparse(buf),
|
||||||
|
Module(module_declaration) => module_declaration.unparse(buf),
|
||||||
|
Interface(interface_declaration) => interface_declaration.unparse(buf),
|
||||||
|
Class(class_declaration) => class_declaration.unparse(buf),
|
||||||
|
Function(function_declaration) => function_declaration.unparse(buf),
|
||||||
|
PlatformFunction(platform_function_declaration) => {
|
||||||
|
platform_function_declaration.unparse(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for InterfaceLevelDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use InterfaceLevelDeclaration::*;
|
||||||
|
match self {
|
||||||
|
Type(type_declaration) => type_declaration.unparse(buf),
|
||||||
|
Module(module_declaration) => module_declaration.unparse(buf),
|
||||||
|
Interface(interface_declaration) => interface_declaration.unparse(buf),
|
||||||
|
Class(class_declaration) => class_declaration.unparse(buf),
|
||||||
|
Function(interface_function_declaration) => interface_function_declaration.unparse(buf),
|
||||||
|
OperatorFunction(interface_operator_function_declaration) => {
|
||||||
|
interface_operator_function_declaration.unparse(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for ClassLevelDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use ClassLevelDeclaration::*;
|
||||||
|
match self {
|
||||||
|
Type(type_declaration) => type_declaration.unparse(buf),
|
||||||
|
Module(module_declaration) => module_declaration.unparse(buf),
|
||||||
|
Interface(interface_declaration) => interface_declaration.unparse(buf),
|
||||||
|
Class(class_declaration) => class_declaration.unparse(buf),
|
||||||
|
Function(function_declaration) => function_declaration.unparse(buf),
|
||||||
|
OperatorFunction(operator_function_declaration) => {
|
||||||
|
operator_function_declaration.unparse(buf)
|
||||||
|
}
|
||||||
|
PlatformFunction(platform_function_declaration) => {
|
||||||
|
platform_function_declaration.unparse(buf)
|
||||||
|
}
|
||||||
|
Field(field_declaration) => field_declaration.unparse(buf),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Declarations */
|
||||||
|
|
||||||
|
impl Unparse for TypeDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if self.is_public {
|
||||||
|
write!(buf, "pub ")?;
|
||||||
|
}
|
||||||
|
write!(buf, "type ")?;
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
if let Some(type_parameters) = &self.parameters {
|
||||||
|
type_parameters.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
self.where_guards.unparse(buf)?;
|
||||||
|
write!(buf, "= ")?;
|
||||||
|
self.rhs.unparse(buf)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for ModuleDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if self.is_public {
|
||||||
|
write!(buf, "pub ")?;
|
||||||
|
}
|
||||||
|
write!(buf, "mod ")?;
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
unparse_contained_declarations!(self.declarations, buf);
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for InterfaceDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if self.is_public {
|
||||||
|
write!(buf, "pub ")?;
|
||||||
|
}
|
||||||
|
write!(buf, "int ")?;
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
if !self.generics.is_empty() {
|
||||||
|
self.generics.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
if !self.inputs.is_empty() {
|
||||||
|
self.inputs.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
if !self.implements.is_empty() {
|
||||||
|
self.implements.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
if !self.where_guards.is_empty() {
|
||||||
|
self.where_guards.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
unparse_contained_declarations!(self.declarations, buf);
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for ClassDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if self.is_public {
|
||||||
|
write!(buf, "pub ")?;
|
||||||
|
}
|
||||||
|
write!(buf, "class ")?;
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
if !self.generics.is_empty() {
|
||||||
|
self.generics.unparse(buf)?;
|
||||||
|
}
|
||||||
|
if let Some(class_constructor) = &self.class_constructor {
|
||||||
|
class_constructor.unparse(buf)?;
|
||||||
|
}
|
||||||
|
write!(buf, " ")?;
|
||||||
|
if !self.implements.is_empty() {
|
||||||
|
self.implements.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
if !self.inputs.is_empty() {
|
||||||
|
self.inputs.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
if !self.where_guards.is_empty() {
|
||||||
|
self.where_guards.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
unparse_contained_declarations!(self.declarations, buf);
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function declarations and components */
|
||||||
|
|
||||||
|
impl Unparse for FunctionModifier {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use FunctionModifier::*;
|
||||||
|
match self {
|
||||||
|
Static => write!(buf, "static"),
|
||||||
|
Cons => write!(buf, "cons"),
|
||||||
|
Mut => write!(buf, "mut"),
|
||||||
|
Ref => write!(buf, "ref"),
|
||||||
|
MutRef => write!(buf, "mut ref"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for FunctionBody {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use FunctionBody::*;
|
||||||
|
match self {
|
||||||
|
EqualsBody(expression) => {
|
||||||
|
write!(buf, "= ")?;
|
||||||
|
expression.unparse(buf)
|
||||||
|
}
|
||||||
|
BlockBody(body) => body.unparse(buf),
|
||||||
|
AliasBody(identifier) => {
|
||||||
|
write!(buf, "alias ")?;
|
||||||
|
identifier.unparse(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for FunctionDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if self.is_public {
|
||||||
|
write!(buf, "pub ")?;
|
||||||
|
}
|
||||||
|
if let Some(modifier) = &self.modifier {
|
||||||
|
modifier.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
write!(buf, "fn ")?;
|
||||||
|
self.generics.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
self.parameters.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
if let Some(return_type) = &self.return_type {
|
||||||
|
return_type.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
self.body.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for OperatorFunctionDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if self.is_public {
|
||||||
|
write!(buf, "pub ")?;
|
||||||
|
}
|
||||||
|
if let Some(modifier) = &self.modifier {
|
||||||
|
modifier.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
self.operator.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.parameters.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
if let Some(return_type) = &self.return_type {
|
||||||
|
return_type.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
self.body.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for PlatformFunctionDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if self.is_public {
|
||||||
|
write!(buf, "pub ")?;
|
||||||
|
}
|
||||||
|
write!(buf, "platform fn ")?;
|
||||||
|
if !self.generics.is_empty() {
|
||||||
|
self.generics.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
self.parameters.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.return_type.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for InterfaceFunctionDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if let Some(modifier) = &self.modifier {
|
||||||
|
modifier.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
if !self.generics.is_empty() {
|
||||||
|
self.parameters.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
self.parameters.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.return_type.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for InterfaceOperatorFunctionDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if let Some(modifier) = &self.modifier {
|
||||||
|
modifier.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
write!(buf, "op ")?;
|
||||||
|
if !self.generics.is_empty() {
|
||||||
|
self.generics.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
self.operator.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.parameters.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.return_type.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Type components */
|
||||||
|
|
||||||
|
impl Unparse for TypeParameters {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use TypeParameters::*;
|
||||||
|
match self {
|
||||||
|
Generic(generic_parameters) => generic_parameters.unparse(buf),
|
||||||
|
Tuple(tuple_parameters) => tuple_parameters.unparse(buf),
|
||||||
|
Function(function_type_parameters) => function_type_parameters.unparse(buf),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListUnparse for TupleParameters {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"("
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
")"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for FunctionTypeParameters {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.parameters.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.return_type.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Class components */
|
||||||
|
|
||||||
|
impl ListUnparse for ClassConstructor {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"("
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
")"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for ClassConstructorParameter {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if self.is_field {
|
||||||
|
write!(buf, "fld ")?;
|
||||||
|
}
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
write!(buf, ": ")?;
|
||||||
|
self.declared_type.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for FieldDeclaration {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
if self.is_mutable {
|
||||||
|
write!(buf, "mut ")?;
|
||||||
|
}
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
write!(buf, ": ")?;
|
||||||
|
self.declared_type.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Statements */
|
||||||
|
|
||||||
|
impl ListUnparse for BlockStatement {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"{\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
"\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
"\n}"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for Statement {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
use Statement::*;
|
||||||
|
match self {
|
||||||
|
BlockStatement(statement) => statement.unparse(buf),
|
||||||
|
CallStatement(call_expression) => call_expression.unparse(buf),
|
||||||
|
VariableDeclarationStatement(declaration) => declaration.unparse(buf),
|
||||||
|
AssignStatement(assign_statement) => assign_statement.unparse(buf),
|
||||||
|
ReturnStatement(return_expression) => return_expression.unparse(buf),
|
||||||
|
IfStatement(if_statement) => if_statement.unparse(buf),
|
||||||
|
IfElseStatement(if_else_statement) => if_else_statement.unparse(buf),
|
||||||
|
WhileStatement(while_statement) => while_statement.unparse(buf),
|
||||||
|
ForStatement(for_statement) => for_statement.unparse(buf),
|
||||||
|
}?;
|
||||||
|
write!(buf, "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for VariableDeclarationStatement {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(buf, "let ")?;
|
||||||
|
if self.is_mutable {
|
||||||
|
write!(buf, "mut ")?;
|
||||||
|
}
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
if let Some(declared_type) = &self.declared_type {
|
||||||
|
write!(buf, ": ")?;
|
||||||
|
declared_type.unparse(buf)?;
|
||||||
|
}
|
||||||
|
if let Some(initializer) = &self.initializer {
|
||||||
|
write!(buf, " = ")?;
|
||||||
|
initializer.unparse(buf)?;
|
||||||
|
}
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for AssignStatement {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.0.unparse(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for ReturnStatement {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(buf, "return")?;
|
||||||
|
if let Some(expression) = &self.0 {
|
||||||
|
write!(buf, " ")?;
|
||||||
|
expression.unparse(buf)?;
|
||||||
|
}
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for IfStatement {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(buf, "if ")?;
|
||||||
|
self.condition.unparse(buf)?;
|
||||||
|
write!(buf, " {{\n")?;
|
||||||
|
self.then_branch.unparse(buf)?;
|
||||||
|
write!(buf, "\n}}")?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for IfElseStatement {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(buf, "if ")?;
|
||||||
|
self.condition.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.then_branch.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.else_ifs.unparse(buf)?;
|
||||||
|
write!(buf, "else ")?;
|
||||||
|
self.else_branch.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for ElseIfs {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
for if_statement in &self.0 {
|
||||||
|
write!(buf, " else ")?;
|
||||||
|
if_statement.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
}
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for WhileStatement {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(buf, "while ")?;
|
||||||
|
self.condition.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.body.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for ForStatement {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(buf, "for ")?;
|
||||||
|
self.variable.unparse(buf)?;
|
||||||
|
write!(buf, " in ")?;
|
||||||
|
self.iterator.unparse(buf)?;
|
||||||
|
write!(buf, " ")?;
|
||||||
|
self.body.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expressions */
|
||||||
|
|
||||||
|
impl Unparse for AssignmentExpression {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.identifier.unparse(buf)?;
|
||||||
|
write!(buf, " = ")?;
|
||||||
|
self.expression.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for Expression {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for CallExpression {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.callee.unparse(buf)?;
|
||||||
|
self.arguments.unparse(buf)?;
|
||||||
|
unparse_ok!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListUnparse for CallArguments {
|
||||||
|
fn prefix() -> &'static str {
|
||||||
|
"("
|
||||||
|
}
|
||||||
|
|
||||||
|
fn separator() -> &'static str {
|
||||||
|
", "
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix() -> &'static str {
|
||||||
|
")"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self) -> Vec<&dyn Unparse> {
|
||||||
|
to_unparse_vec!(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for CallArgument {
|
||||||
|
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
|
||||||
|
self.0.unparse(buf)
|
||||||
|
}
|
||||||
|
}
|
@ -1,78 +1,78 @@
|
|||||||
// Top-level constructs
|
// Keywords
|
||||||
CompilationUnit = { SOI ~ Namespace? ~ ModuleLevelDeclaration* ~ EOI }
|
Ns = { "ns" }
|
||||||
Namespace = { "ns" ~ FullyQualifiedName }
|
TypeKw = { "type" }
|
||||||
|
Mod = { "mod" }
|
||||||
|
Int = { "int" }
|
||||||
|
ClassKw = { "class" }
|
||||||
|
Platform = { "platform" }
|
||||||
|
Pub = { "pub" }
|
||||||
|
Fld = { "fld" }
|
||||||
|
Impl = { "impl" }
|
||||||
|
Mut = { "mut" }
|
||||||
|
Cons = { "cons" }
|
||||||
|
Static = { "static" }
|
||||||
|
Ref = { "ref" }
|
||||||
|
Def = { "def" }
|
||||||
|
Where = { "where" }
|
||||||
|
Infer = { "infer" }
|
||||||
|
Void = { "Void" }
|
||||||
|
Delegate = { "delegate" }
|
||||||
|
Let = { "let" }
|
||||||
|
Fn = { "fn" }
|
||||||
|
Op = { "op" }
|
||||||
|
|
||||||
CommonDeclaration = { Interface | Class | Module | Function | OperatorFunction }
|
// Keywords as a rule (for preventing identifiers with keywords, etc.)
|
||||||
ModuleLevelDeclaration = { Declare? ~ Public? ~ CommonDeclaration }
|
Keyword = {
|
||||||
InterfaceLevelDeclaration = { CommonDeclaration }
|
Ns
|
||||||
ClassLevelDeclaration = { Declare? ~ Public? ~ ( CommonDeclaration | ClassMember ) }
|
| TypeKw
|
||||||
|
| Mod
|
||||||
// Module
|
| Int
|
||||||
Module = { "mod" ~ Identifier ~ "{" ~ ModuleLevelDeclaration* ~ "}" }
|
| ClassKw
|
||||||
|
| Platform
|
||||||
// Interface
|
| Pub
|
||||||
Interface = { "int" ~ Identifier ~ GenericParameters? ~ ExtendsList? ~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )? }
|
| Fld
|
||||||
|
| Impl
|
||||||
// Class
|
| Mut
|
||||||
Class = { "class" ~ Identifier ~ GenericParameters? ~ ClassConstructor? ~ ExtendsList? ~ ( "{" ~ ClassLevelDeclaration* ~ "}" )? }
|
| Cons
|
||||||
ClassMember = { Field? ~ Identifier ~ TypeAnnotation? }
|
| Static
|
||||||
|
| Ref
|
||||||
// Class Constructor
|
| Def
|
||||||
ClassConstructor = { "(" ~ ClassMemberList? ~ ")" }
|
| Where
|
||||||
ClassMemberList = { ClassMember ~ ( "," ~ ClassMember )* }
|
| Infer
|
||||||
|
| Void
|
||||||
// Various Keywords
|
| Delegate
|
||||||
Declare = { "decl" }
|
| Let
|
||||||
Public = { "pub" }
|
| Fn
|
||||||
Field = { "fld" }
|
| Op
|
||||||
Implementation = { "impl" }
|
|
||||||
Mutable = { "mut" }
|
|
||||||
Consume = { "cons" }
|
|
||||||
Reference = { "ref" }
|
|
||||||
Define = { "def" }
|
|
||||||
|
|
||||||
// Fqn and identifier
|
|
||||||
FullyQualifiedName = { Identifier ~ ( "::" ~ Identifier )* }
|
|
||||||
|
|
||||||
Identifier = @{ IdentifierStartChar ~ IdentifierChar* }
|
|
||||||
IdentifierStartChar = { 'a'..'z' | 'A'..'Z' | "_" }
|
|
||||||
IdentifierChar = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" }
|
|
||||||
|
|
||||||
// Type constructs
|
|
||||||
ExtendsList = { ":" ~ TypeUse ~ ( "+" ~ TypeUse )* }
|
|
||||||
TypeAnnotation = { ":" ~ TypeUse }
|
|
||||||
TypeUse = { FullyQualifiedName ~ GenericArguments? }
|
|
||||||
|
|
||||||
// Generic arguments given to a TypeUse or function calls
|
|
||||||
GenericArguments = { "<" ~ FullyQualifiedName ~ ( "," ~ FullyQualifiedName )* ~ ">" }
|
|
||||||
|
|
||||||
// Generic parameters (for when types are declared)
|
|
||||||
GenericParameters = { "<" ~ Identifier ~ ( "," ~ Identifier )* ~ ">" }
|
|
||||||
|
|
||||||
// Function
|
|
||||||
Function = { ( Implementation | Define )?
|
|
||||||
~ ( Consume | Mutable )?
|
|
||||||
~ Reference?
|
|
||||||
~ "fn"
|
|
||||||
~ GenericParameters?
|
|
||||||
~ Identifier
|
|
||||||
~ "(" ~ Parameters? ~ ")"
|
|
||||||
~ ReturnType?
|
|
||||||
~ ( FunctionAlias | FunctionEqualsBody | BlockStatement )?
|
|
||||||
}
|
}
|
||||||
ReturnType = { "->" ~ Reference? ~ TypeUse }
|
|
||||||
FunctionAlias = { "alias" ~ FullyQualifiedName }
|
|
||||||
|
|
||||||
OperatorFunction = { ( Implementation | Define )?
|
// Symbols
|
||||||
~ ( Consume | Mutable )?
|
Ellipsis = { "..." }
|
||||||
~ Reference?
|
Underscore = { "_" }
|
||||||
~ "op"
|
|
||||||
~ Operator
|
// Operators
|
||||||
~ "(" ~ Parameters? ~ ")"
|
Or = { "||" }
|
||||||
~ ReturnType?
|
And = { "&&" }
|
||||||
~ ( FunctionAlias | FunctionEqualsBody | BlockStatement )?
|
EqualTo = { "==" }
|
||||||
}
|
NotEqualTo = { "!=" }
|
||||||
Operator = { Or
|
Greater = { ">" }
|
||||||
|
Less = { "<" }
|
||||||
|
GreaterEqual = { ">=" }
|
||||||
|
LessEqual = { "<=" }
|
||||||
|
Add = { "+" }
|
||||||
|
Subtract = { "-" }
|
||||||
|
Multiply = { "*" }
|
||||||
|
Divide = { "/" }
|
||||||
|
Modulo = { "%" }
|
||||||
|
Not = { "!" }
|
||||||
|
Negative = { "-" }
|
||||||
|
PlusPlus = { "++" }
|
||||||
|
MinusMinus = { "--" }
|
||||||
|
CallOp = { "()" }
|
||||||
|
Spread = { Ellipsis }
|
||||||
|
|
||||||
|
Operator = {
|
||||||
|
Or
|
||||||
| And
|
| And
|
||||||
| EqualTo
|
| EqualTo
|
||||||
| NotEqualTo
|
| NotEqualTo
|
||||||
@ -85,93 +85,691 @@ Operator = { Or
|
|||||||
| Multiply
|
| Multiply
|
||||||
| Divide
|
| Divide
|
||||||
| Modulo
|
| Modulo
|
||||||
|
| Not
|
||||||
|
| Negative
|
||||||
|
| PlusPlus
|
||||||
|
| MinusMinus
|
||||||
| CallOp
|
| CallOp
|
||||||
|
| Spread
|
||||||
}
|
}
|
||||||
|
|
||||||
CallOp = { "()" }
|
// Commonly shared constructs
|
||||||
|
|
||||||
Parameters = { Parameter ~ ( "," ~ Parameter )* }
|
FullyQualifiedName = {
|
||||||
Parameter = { Identifier ~ TypeAnnotation? }
|
Identifier
|
||||||
|
~ ( "::" ~ Identifier )*
|
||||||
|
}
|
||||||
|
|
||||||
FunctionEqualsBody = { "=" ~ Expression }
|
Identifier = @{
|
||||||
|
( Keyword ~ IdentifierChar | !Keyword ~ IdentifierStartChar )
|
||||||
|
~ IdentifierChar*
|
||||||
|
}
|
||||||
|
|
||||||
|
IdentifierStartChar = {
|
||||||
|
'a'..'z'
|
||||||
|
| 'A'..'Z'
|
||||||
|
| "_"
|
||||||
|
}
|
||||||
|
|
||||||
|
IdentifierChar = {
|
||||||
|
'a'..'z'
|
||||||
|
| 'A'..'Z'
|
||||||
|
| '0'..'9'
|
||||||
|
| "_"
|
||||||
|
}
|
||||||
|
|
||||||
|
// In general:
|
||||||
|
// Arguments = usage
|
||||||
|
// Parameters = declaration
|
||||||
|
|
||||||
|
TypeUse = {
|
||||||
|
FullyQualifiedName
|
||||||
|
~ (
|
||||||
|
GenericArguments ~ InputArguments?
|
||||||
|
| TupleGenericArguments
|
||||||
|
| FunctionGenericArguments ~ FunctionInputArguments?
|
||||||
|
| InputArguments
|
||||||
|
)?
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericArguments = {
|
||||||
|
"<"
|
||||||
|
~ FullyQualifiedName
|
||||||
|
~ ( "," ~ FullyQualifiedName )*
|
||||||
|
~ ">"
|
||||||
|
}
|
||||||
|
|
||||||
|
InputArguments = {
|
||||||
|
"|"
|
||||||
|
~ (
|
||||||
|
InputArgument
|
||||||
|
~ ( "," ~ InputArgument )*
|
||||||
|
)?
|
||||||
|
~ "|"
|
||||||
|
}
|
||||||
|
|
||||||
|
InputArgument = {
|
||||||
|
Identifier
|
||||||
|
~ ( "=" ~ Identifier )
|
||||||
|
}
|
||||||
|
|
||||||
|
TupleGenericArguments = {
|
||||||
|
"("
|
||||||
|
~ (
|
||||||
|
FullyQualifiedName
|
||||||
|
~ ( "," ~ FullyQualifiedName )*
|
||||||
|
)?
|
||||||
|
~ ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionGenericArguments = {
|
||||||
|
TupleGenericArguments
|
||||||
|
~ ReturnTypeGenericArgument
|
||||||
|
~ FunctionInputArguments?
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnTypeGenericArgument = {
|
||||||
|
"->"
|
||||||
|
~ ( Void | FullyQualifiedName )
|
||||||
|
~ RefList?
|
||||||
|
}
|
||||||
|
|
||||||
|
RefList = {
|
||||||
|
Ref
|
||||||
|
~ Identifier
|
||||||
|
~ ( "," ~ Identifier )*
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionInputArguments = {
|
||||||
|
"|"
|
||||||
|
~ (
|
||||||
|
FunctionInputArgument
|
||||||
|
~ ( "," ~ FunctionInputArgument )*
|
||||||
|
)?
|
||||||
|
~ "|"
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionInputArgument = {
|
||||||
|
( Delegate | Identifier )
|
||||||
|
~ ( "=" ~ Identifier )
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic Parameters
|
||||||
|
|
||||||
|
GenericParameters = {
|
||||||
|
"<"
|
||||||
|
~ Identifier
|
||||||
|
~ ( "," ~ Identifier )*
|
||||||
|
~ ">"
|
||||||
|
}
|
||||||
|
|
||||||
|
InputParameters = {
|
||||||
|
"|"
|
||||||
|
~ InputParameter
|
||||||
|
~ ( "," ~ InputParameter )*
|
||||||
|
~ "|"
|
||||||
|
}
|
||||||
|
|
||||||
|
InputParameter = {
|
||||||
|
Identifier
|
||||||
|
~ ":"
|
||||||
|
~ TypeUse
|
||||||
|
}
|
||||||
|
|
||||||
|
TupleGenericParameters = {
|
||||||
|
"("
|
||||||
|
~ (
|
||||||
|
Identifier
|
||||||
|
~ ( "," ~ Identifier )*
|
||||||
|
)?
|
||||||
|
~ ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionGenericParameters = {
|
||||||
|
TupleGenericParameters
|
||||||
|
~ FunctionGenericParameterReturnType
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionGenericParameterReturnType = {
|
||||||
|
"->"
|
||||||
|
~ ( Void | Identifier )
|
||||||
|
~ RefList?
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionInputParameters = {
|
||||||
|
"|"
|
||||||
|
~ FunctionInputParameter
|
||||||
|
~ ( "," ~ FunctionInputParameter )*
|
||||||
|
~ "|"
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionInputParameter = {
|
||||||
|
( Delegate | Identifier )
|
||||||
|
~ ":"
|
||||||
|
~ TypeUse
|
||||||
|
}
|
||||||
|
|
||||||
|
ImplementsList = {
|
||||||
|
":"
|
||||||
|
~ TypeUse
|
||||||
|
~ ( "+" ~ TypeUse )
|
||||||
|
}
|
||||||
|
|
||||||
|
WhereGuards = {
|
||||||
|
Where
|
||||||
|
~ WhereGuard
|
||||||
|
~ ( "," ~ WhereGuard )*
|
||||||
|
}
|
||||||
|
|
||||||
|
WhereGuard = {
|
||||||
|
Identifier
|
||||||
|
~ ImplementsList
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top-level constructs
|
||||||
|
|
||||||
|
CompilationUnit = {
|
||||||
|
SOI
|
||||||
|
~ Namespace?
|
||||||
|
~ ModuleLevelDeclaration*
|
||||||
|
~ EOI
|
||||||
|
}
|
||||||
|
|
||||||
|
Namespace = {
|
||||||
|
Ns
|
||||||
|
~ FullyQualifiedName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Organizational declarations
|
||||||
|
|
||||||
|
ModuleLevelDeclaration = {
|
||||||
|
Type
|
||||||
|
| Module
|
||||||
|
| Interface
|
||||||
|
| Class
|
||||||
|
| FunctionDefinition
|
||||||
|
| PlatformFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
InterfaceLevelDeclaration = {
|
||||||
|
Type
|
||||||
|
| Module
|
||||||
|
| Interface
|
||||||
|
| Class
|
||||||
|
| InterfaceFunction
|
||||||
|
| InterfaceDefaultFunction
|
||||||
|
| InterfaceOperatorFunction
|
||||||
|
| InterfaceDefaultOperatorFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassLevelDeclaration = {
|
||||||
|
Type
|
||||||
|
| Module
|
||||||
|
| Interface
|
||||||
|
| Class
|
||||||
|
| FunctionDefinition
|
||||||
|
| OperatorFunctionDefinition
|
||||||
|
| PlatformFunction
|
||||||
|
| Field
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main organizational constructs
|
||||||
|
|
||||||
|
Type = {
|
||||||
|
Pub?
|
||||||
|
~ TypeKw
|
||||||
|
~ Identifier
|
||||||
|
~ GenericParameters?
|
||||||
|
~ TypeWhereGuards?
|
||||||
|
~ "="
|
||||||
|
~ TypeUse
|
||||||
|
}
|
||||||
|
|
||||||
|
Module = {
|
||||||
|
Pub?
|
||||||
|
~ Mod
|
||||||
|
~ Identifier
|
||||||
|
~ "{" ~ ModuleLevelDeclaration* ~ "}"
|
||||||
|
}
|
||||||
|
|
||||||
|
Interface = {
|
||||||
|
Pub?
|
||||||
|
~ Int
|
||||||
|
~ Identifier
|
||||||
|
~ InterfaceGenericParametersAndInputs?
|
||||||
|
~ ImplementsList?
|
||||||
|
~ WhereGuards?
|
||||||
|
~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )?
|
||||||
|
}
|
||||||
|
|
||||||
|
Class = {
|
||||||
|
Pub?
|
||||||
|
~ ClassKw
|
||||||
|
~ Identifier
|
||||||
|
~ GenericParameters?
|
||||||
|
~ ClassConstructor?
|
||||||
|
~ ImplementsList?
|
||||||
|
~ InputArguments?
|
||||||
|
~ WhereGuards?
|
||||||
|
~ ( "{" ~ ClassLevelDeclaration* ~ "}" )?
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type
|
||||||
|
|
||||||
|
TypeWhereGuards = {
|
||||||
|
Where
|
||||||
|
~ TypeWhereGuard
|
||||||
|
~ ( "," ~ TypeWhereGuard )*
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeWhereGuard = {
|
||||||
|
Identifier
|
||||||
|
~ ":"
|
||||||
|
~ TypeTypeUse
|
||||||
|
~ ( "+" ~ TypeTypeUse )*
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeTypeUse = {
|
||||||
|
FullyQualifiedName
|
||||||
|
~ TypeTypeArguments?
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeTypeArguments = {
|
||||||
|
TypeGenericArguments
|
||||||
|
| TypeGenericFunctionArguments
|
||||||
|
| TypeGenericTupleArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeGenericArguments = {
|
||||||
|
"<"
|
||||||
|
~ TypeGenericArgument
|
||||||
|
~ ( "," ~ TypeGenericArgument )*
|
||||||
|
~ ">"
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeGenericArgument = {
|
||||||
|
Underscore
|
||||||
|
| FullyQualifiedName
|
||||||
|
| ( Infer ~ Identifier )
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeGenericTupleArguments = {
|
||||||
|
"("
|
||||||
|
~ (
|
||||||
|
TypeGenericTupleArgument
|
||||||
|
~ ( "," ~ TypeGenericTupleArgument )*
|
||||||
|
)?
|
||||||
|
~ ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeGenericTupleArgument = {
|
||||||
|
Underscore
|
||||||
|
| FullyQualifiedName
|
||||||
|
| ( Infer ~ Identifier )
|
||||||
|
| ( Ellipsis ~ Underscore )
|
||||||
|
| ( Ellipsis ~ Infer ~ Identifier )
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeGenericFunctionArguments = {
|
||||||
|
TypeGenericTupleArguments
|
||||||
|
~ TypeGenericArguments?
|
||||||
|
~ TypeFunctionReturnType
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeFunctionReturnType = {
|
||||||
|
"->"
|
||||||
|
~ ( Void | FullyQualifiedName )
|
||||||
|
~ RefList?
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface
|
||||||
|
|
||||||
|
InterfaceGenericParametersAndInputs = {
|
||||||
|
GenericParameters ~ InputParameters?
|
||||||
|
| TupleGenericParameters
|
||||||
|
| FunctionGenericParameters ~ FunctionInputParameters?
|
||||||
|
| InputParameters
|
||||||
|
}
|
||||||
|
|
||||||
|
InterfaceFunction = {
|
||||||
|
(
|
||||||
|
Static
|
||||||
|
| Cons
|
||||||
|
| ( Mut ~ Ref? )
|
||||||
|
)?
|
||||||
|
~ Fn
|
||||||
|
~ GenericParameters?
|
||||||
|
~ Identifier
|
||||||
|
~ Parameters
|
||||||
|
~ ReturnType
|
||||||
|
~ WhereGuards?
|
||||||
|
}
|
||||||
|
|
||||||
|
InterfaceDefaultFunction = {
|
||||||
|
Def
|
||||||
|
~ (
|
||||||
|
Static
|
||||||
|
| Cons
|
||||||
|
| ( Mut ~ Ref? )
|
||||||
|
)?
|
||||||
|
~ Fn
|
||||||
|
~ GenericParameters?
|
||||||
|
~ Identifier
|
||||||
|
~ Parameters
|
||||||
|
~ ReturnType
|
||||||
|
~ WhereGuards?
|
||||||
|
~ FunctionBody
|
||||||
|
}
|
||||||
|
|
||||||
|
InterfaceOperatorFunction = {
|
||||||
|
(
|
||||||
|
Cons
|
||||||
|
| ( Mut ~ Ref? )
|
||||||
|
)?
|
||||||
|
~ Op
|
||||||
|
~ Operator
|
||||||
|
~ Parameters
|
||||||
|
~ ReturnType
|
||||||
|
~ RefList?
|
||||||
|
~ WhereGuards? // TODO: decide if we want this for interface op functions
|
||||||
|
}
|
||||||
|
|
||||||
|
InterfaceDefaultOperatorFunction = {
|
||||||
|
Def
|
||||||
|
~ (
|
||||||
|
Cons
|
||||||
|
| ( Mut ~ Ref? )
|
||||||
|
)?
|
||||||
|
~ Op
|
||||||
|
~ Operator
|
||||||
|
~ Parameters
|
||||||
|
~ ReturnType
|
||||||
|
~ RefList?
|
||||||
|
~ WhereGuards?
|
||||||
|
~ FunctionBody
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class constructs
|
||||||
|
|
||||||
|
ClassConstructor = {
|
||||||
|
"("
|
||||||
|
~ DataMember
|
||||||
|
~ ( "," ~ DataMember )*
|
||||||
|
~ ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
DataMember = {
|
||||||
|
Property
|
||||||
|
| Field
|
||||||
|
}
|
||||||
|
|
||||||
|
Property = {
|
||||||
|
Mut?
|
||||||
|
~ Identifier
|
||||||
|
~ ":"
|
||||||
|
~ TypeUse
|
||||||
|
}
|
||||||
|
|
||||||
|
Field = {
|
||||||
|
Mut?
|
||||||
|
~ Fld
|
||||||
|
~ Identifier
|
||||||
|
~ ":"
|
||||||
|
~ TypeUse
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function constructs
|
||||||
|
FunctionModifier = {
|
||||||
|
Static
|
||||||
|
| Cons
|
||||||
|
| Mut? Ref?
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionDefinition = {
|
||||||
|
Pub?
|
||||||
|
~ FunctionModifier
|
||||||
|
~ Fn
|
||||||
|
~ GenericParameters?
|
||||||
|
~ Identifier
|
||||||
|
~ Parameters
|
||||||
|
~ ReturnType?
|
||||||
|
~ FunctionBody
|
||||||
|
}
|
||||||
|
|
||||||
|
OperatorFunctionDefinition = {
|
||||||
|
Pub?
|
||||||
|
~ FunctionModifier
|
||||||
|
~ Op
|
||||||
|
~ Operator
|
||||||
|
~ Parameters
|
||||||
|
~ ReturnType?
|
||||||
|
~ FunctionBody
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformFunction = {
|
||||||
|
Pub?
|
||||||
|
~ FunctionModifier
|
||||||
|
~ Platform
|
||||||
|
~ Fn
|
||||||
|
~ GenericParameters
|
||||||
|
~ Identifier
|
||||||
|
~ Parameters
|
||||||
|
~ ReturnType
|
||||||
|
}
|
||||||
|
|
||||||
|
Parameters = {
|
||||||
|
"("
|
||||||
|
~ (
|
||||||
|
Parameter
|
||||||
|
~ ( "," ~ Parameter )*
|
||||||
|
)?
|
||||||
|
~ ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
Parameter = {
|
||||||
|
Identifier
|
||||||
|
~ ":"
|
||||||
|
~ TypeUse
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnType = {
|
||||||
|
"->"
|
||||||
|
~ ( Void | TypeUse )
|
||||||
|
~ RefList?
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionBody = {
|
||||||
|
FunctionEqualsBody
|
||||||
|
| FunctionBlockBody
|
||||||
|
| FunctionAliasBody
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionEqualsBody = {
|
||||||
|
"="
|
||||||
|
~ Expression
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionBlockBody = {
|
||||||
|
"{"
|
||||||
|
~ Statement*
|
||||||
|
~ "}"
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionAliasBody = {
|
||||||
|
"alias"
|
||||||
|
~ Identifier
|
||||||
|
}
|
||||||
|
|
||||||
// Statements
|
// Statements
|
||||||
BlockStatement = { "{" ~ Statement* ~ "}" }
|
|
||||||
Statement = { VariableDeclaration | CallExpression | AssignmentExpression }
|
|
||||||
|
|
||||||
VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" ~ Expression )? }
|
BlockStatement = {
|
||||||
|
"{"
|
||||||
|
~ Statement*
|
||||||
|
~ "}"
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement = {
|
||||||
|
BlockStatement
|
||||||
|
| VariableDeclaration
|
||||||
|
| AssignmentExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
VariableDeclaration = {
|
||||||
|
Let
|
||||||
|
~ Mut?
|
||||||
|
~ Identifier
|
||||||
|
~ ( ":" ~ TypeUse )?
|
||||||
|
~ ( "=" ~ Expression )?
|
||||||
|
}
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
|
|
||||||
Expression = { OrExpression }
|
Expression = { OrExpression }
|
||||||
|
|
||||||
OrExpression = { AndExpression ~ ( Or ~ AndExpression )* }
|
OrExpression = {
|
||||||
AndExpression = { EqualityExpression ~ ( And ~ EqualityExpression )* }
|
AndExpression
|
||||||
Or = { "||" }
|
~ ( Or ~ Expression )*
|
||||||
And = { "&&" }
|
}
|
||||||
|
|
||||||
EqualityExpression = { ComparisonExpression ~ ( ( EqualTo | NotEqualTo ) ~ ComparisonExpression )* }
|
AndExpression = {
|
||||||
EqualTo = { "==" }
|
EqualityExpression
|
||||||
NotEqualTo = { "!=" }
|
~ ( And ~ Expression )*
|
||||||
|
}
|
||||||
|
|
||||||
ComparisonExpression = { AdditiveExpression ~ ( ( Greater | Less | GreaterEqual | LessEqual ) ~ AdditiveExpression )* }
|
EqualityExpression = {
|
||||||
Greater = { ">" }
|
ComparisonExpression
|
||||||
Less = { "<" }
|
~ (
|
||||||
GreaterEqual = { ">=" }
|
( EqualTo | NotEqualTo )
|
||||||
LessEqual = { "<=" }
|
~ Expression
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
AdditiveExpression = { MultiplicativeExpression ~ ( ( Add | Subtract ) ~ MultiplicativeExpression )* }
|
ComparisonExpression = {
|
||||||
Add = { "+" }
|
AdditiveExpression
|
||||||
Subtract = { "-" }
|
~ (
|
||||||
|
( Greater | Less | GreaterEqual | LessEqual )
|
||||||
|
~ Expression
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
MultiplicativeExpression = { UnaryExpression ~ ( ( Multiply | Divide | Modulo ) ~ UnaryExpression )* }
|
AdditiveExpression = {
|
||||||
Multiply = { "*" }
|
MultiplicativeExpression
|
||||||
Divide = { "/" }
|
~ (
|
||||||
Modulo = { "%" }
|
( Add | Subtract )
|
||||||
|
~ Expression
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
UnaryExpression = { ( Not | Negative )* ~ PrimaryExpression ~ ( Call | ( PlusPlus | MinusMinus ) )* }
|
MultiplicativeExpression = {
|
||||||
Not = { "!" }
|
SpreadExpression
|
||||||
Negative = { "-" }
|
~ (
|
||||||
PlusPlus = { "++" }
|
( Multiply | Divide | Modulo )
|
||||||
MinusMinus = { "--" }
|
~ Expression
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
PrimaryExpression = { Literal | ObjectAccess | ParenthesizedExpression }
|
SpreadExpression = {
|
||||||
ParenthesizedExpression = { "(" ~ Expression ~ ")" }
|
UnaryExpression
|
||||||
|
~ Spread
|
||||||
|
~ Expression
|
||||||
|
}
|
||||||
|
|
||||||
|
UnaryExpression = {
|
||||||
|
( Not | Negative )*
|
||||||
|
~ PrimaryExpression
|
||||||
|
~ ( ( NoParenthesesCall | ParenthesesCall )+ | ( PlusPlus | MinusMinus ) )?
|
||||||
|
}
|
||||||
|
|
||||||
// Call
|
PrimaryExpression = {
|
||||||
CallExpression = { PrimaryExpression ~ Call+ }
|
Literal
|
||||||
Call = { GenericArguments? ~ CallArguments }
|
| ObjectAccess
|
||||||
ExpressionList = { Expression ~ ( "," ~ Expression )* }
|
| ParenthesizedExpression
|
||||||
CallArguments = {
|
}
|
||||||
( "(" ~ ExpressionList? ~ ")" )
|
|
||||||
| ExpressionList
|
ParenthesizedExpression = {
|
||||||
|
"("
|
||||||
|
~ Expression
|
||||||
|
~ ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calls
|
||||||
|
|
||||||
|
ParenthesesCall = {
|
||||||
|
TurboFish?
|
||||||
|
~ "("
|
||||||
|
~ ExpressionList?
|
||||||
|
~ ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
NoParenthesesCall = {
|
||||||
|
TurboFish?
|
||||||
|
~ ExpressionList
|
||||||
|
}
|
||||||
|
|
||||||
|
TurboFish = {
|
||||||
|
"::"
|
||||||
|
~ GenericArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpressionList = {
|
||||||
|
Expression
|
||||||
|
~ ( "," ~ Expression )*
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment
|
// Assignment
|
||||||
AssignmentExpression = { ObjectAccess ~ "=" ~ Expression }
|
AssignmentExpression = {
|
||||||
|
ObjectAccess
|
||||||
|
~ "="
|
||||||
|
~ Expression
|
||||||
|
}
|
||||||
|
|
||||||
// Object
|
// Object
|
||||||
ObjectAccess = { FullyQualifiedName ~ ( "." ~ Identifier )* }
|
ObjectAccess = {
|
||||||
|
FullyQualifiedName
|
||||||
|
~ ( "." ~ Identifier )*
|
||||||
|
}
|
||||||
|
|
||||||
// Literals
|
// Literals
|
||||||
Literal = { NumberLiteral | StringLiteral | BooleanLiteral | NullLiteral }
|
Literal = {
|
||||||
|
NumberLiteral
|
||||||
|
| StringLiteral
|
||||||
|
| BooleanLiteral
|
||||||
|
}
|
||||||
|
|
||||||
NumberLiteral = { LongLiteral | IntLiteral }
|
NumberLiteral = {
|
||||||
|
LongLiteral
|
||||||
|
| IntLiteral
|
||||||
|
| DoubleLiteral
|
||||||
|
}
|
||||||
|
|
||||||
IntLiteral = { NumberBase }
|
IntLiteral = { NumberBase }
|
||||||
|
|
||||||
LongLiteral = ${ NumberBase ~ "L" }
|
LongLiteral = ${ NumberBase ~ "L" }
|
||||||
|
|
||||||
NumberBase = { DecimalBase | BinaryBase | HexadecimalBase }
|
DoubleLiteral = ${ DecimalBase ~ "." ~ Digit+ }
|
||||||
|
|
||||||
|
NumberBase = {
|
||||||
|
DecimalBase
|
||||||
|
| BinaryBase
|
||||||
|
| HexadecimalBase
|
||||||
|
}
|
||||||
|
|
||||||
DecimalBase = @{ DecimalStartDigit ~ Digit* }
|
DecimalBase = @{ DecimalStartDigit ~ Digit* }
|
||||||
|
|
||||||
BinaryBase = @{ "0b" ~ Digit* }
|
BinaryBase = @{ "0b" ~ Digit* }
|
||||||
|
|
||||||
DecimalStartDigit = { '1'..'9' }
|
DecimalStartDigit = { '1'..'9' }
|
||||||
|
|
||||||
Digit = { '0'..'9'+ }
|
Digit = { '0'..'9'+ }
|
||||||
|
|
||||||
HexadecimalBase = @{ "0x" ~ HexadecimalDigit+ }
|
HexadecimalBase = @{ "0x" ~ HexadecimalDigit+ }
|
||||||
|
|
||||||
HexadecimalDigit = { '0'..'9' | 'a'..'f' }
|
HexadecimalDigit = { '0'..'9' | 'a'..'f' }
|
||||||
|
|
||||||
StringLiteral = ${ "\"" ~ StringInner ~ "\"" }
|
StringLiteral = ${ "\"" ~ StringInner ~ "\"" }
|
||||||
|
|
||||||
StringInner = @{ StringChar* }
|
StringInner = @{ StringChar* }
|
||||||
|
|
||||||
StringChar = {
|
StringChar = {
|
||||||
!( "\"" | "\\" ) ~ ANY
|
!( "\"" | "\\" ) ~ ANY
|
||||||
| "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" )
|
| "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" )
|
||||||
@ -180,6 +778,4 @@ StringChar = {
|
|||||||
|
|
||||||
BooleanLiteral = { "true" | "false" }
|
BooleanLiteral = { "true" | "false" }
|
||||||
|
|
||||||
NullLiteral = { "null" }
|
|
||||||
|
|
||||||
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
|
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
|
||||||
|
Loading…
Reference in New Issue
Block a user