Compare commits

..

15 Commits

Author SHA1 Message Date
Jesse Brault
9805a3aad5 Finish current version of pretty print. 2025-05-15 16:12:17 -05:00
Jesse Brault
58c66b437e More work on pretty print; add dmc p3 command. 2025-05-15 11:27:05 -05:00
Jesse Brault
1c2e5300ac Start on pretty_print.rs for pretty-printing ASTs. 2025-05-15 11:06:30 -05:00
Jesse Brault
68a2c22be7 Delete trie.rs. 2025-05-15 11:05:08 -05:00
Jesse Brault
a9457c1ab9 Successful work to compile, parse, and unparse basic Deimos. 2025-05-15 09:40:39 -05:00
Jesse Brault
a9fe5b473c Delete old compile sketch files. 2025-05-15 08:54:02 -05:00
Jesse Brault
c980eb8a72 Fix up unparse.rs. 2025-05-15 08:52:34 -05:00
Jesse Brault
e3dc46e023 Enough work to hopefully make hello world parse and build AST. 2025-05-15 08:13:34 -05:00
Jesse Brault
63dec99cb5 Add expression rules and basic left-recursive AST-expression building. 2025-05-14 20:07:44 -05:00
Jesse Brault
487d0383c5 Add many rules to build.rs. 2025-05-14 19:24:59 -05:00
Jesse Brault
9df681e07c Refactoring grammar to be easier to work with. 2025-05-14 17:24:57 -05:00
Jesse Brault
373120d34e Add class-level declarations and components. 2025-05-14 12:04:07 -05:00
Jesse Brault
9d843097bc Much work on build.rs and related. 2025-05-14 10:04:31 -05:00
Jesse Brault
16e180180b Work on grammar and reorganize src/ast/mod.rs. 2025-05-13 19:00:14 -05:00
Jesse Brault
e4c93f319d Fix formatting. 2025-05-13 10:42:08 -05:00
19 changed files with 3001 additions and 1451 deletions

View File

@ -0,0 +1,5 @@
fn main() {
println('Hello, World!');
let x = 'I greet you!';
println(x);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,15 @@
use pest::Parser;
pub mod build;
pub mod pretty_print;
pub mod unparse;
// Operators
#[derive(Debug)]
pub enum Operator {
Binary(BinaryOperator),
Unary(UnaryOperator),
PrefixUnary(PrefixUnaryOperator),
SuffixUnary(SuffixUnaryOperator),
}
#[derive(Debug)]
@ -31,16 +32,22 @@ pub enum BinaryOperator {
}
#[derive(Debug)]
pub enum UnaryOperator {
pub enum PrefixUnaryOperator {
Spread,
BorrowMut,
Borrow,
Mut,
Not,
Negative,
PlusPlus,
MinusMinus,
CallOp,
Spread,
}
// Names
#[derive(Debug)]
pub enum SuffixUnaryOperator {
PlusPlus,
MinusMinus,
}
/* Names */
#[derive(Debug, Clone)]
pub struct Identifier {
@ -48,51 +55,13 @@ pub struct Identifier {
}
#[derive(Debug)]
pub struct Fqn {
pub identifiers: Vec<Identifier>,
}
pub struct FullyQualifiedName(pub Vec<Identifier>);
// Generic parameters
#[derive(Debug)]
pub struct GenericParameters(pub Vec<GenericParameter>);
impl GenericParameters {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct GenericParameter(Identifier);
// Generic arguments
#[derive(Debug)]
pub struct GenericArguments(pub Vec<GenericArgument>);
impl GenericArguments {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct GenericArgument {
pub fqn: Fqn,
}
// Type-use and components
// #[derive(Debug)]
// pub struct TypeUse {
// pub fqn: Fqn,
// pub arguments: Option<TypeArguments>,
// pub inputs: Option<InputArguments>,
// }
/* Type Use */
#[derive(Debug)]
pub enum TypeUse {
Void,
InterfaceOrClass(InterfaceOrClassTypeUse),
Tuple(TupleTypeUse),
Function(FunctionTypeUse),
@ -100,135 +69,68 @@ pub enum TypeUse {
#[derive(Debug)]
pub struct InterfaceOrClassTypeUse {
pub fqn: Fqn,
pub borrow_count: usize,
pub is_mutable: bool,
pub fqn: FullyQualifiedName,
pub generics: GenericArguments,
}
#[derive(Debug)]
pub struct TupleTypeUse(pub Vec<TypeUse>);
pub struct TupleTypeUse {
pub borrow_count: usize,
pub is_mutable: bool,
pub arguments: TupleArguments,
}
#[derive(Debug)]
pub struct FunctionTypeUse {
pub function_modifier: Option<FunctionModifier>,
pub borrow_count: usize,
pub function_modifier: Option<FunctionTypeModifier>,
pub generics: GenericParameters,
pub parameters: TupleTypeUse,
pub inputs: InputArguments,
pub parameters: Parameters,
pub return_type: ReturnType,
}
#[derive(Debug)]
pub enum TypeArguments {
Generics(GenericArguments),
Tuple(TupleArguments),
Function(FunctionTypeArguments),
}
// Generic arguments
#[derive(Debug)]
pub struct TupleArguments(pub Vec<Fqn>);
pub struct GenericArguments(pub Vec<TypeUse>);
impl TupleArguments {
impl GenericArguments {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct FunctionTypeArguments {
pub parameters: TupleParameters,
pub return_type: Box<TypeUse>,
impl Default for GenericArguments {
fn default() -> Self {
GenericArguments(Vec::new())
}
}
// Function components
/* Generic parameters */
#[derive(Debug)]
pub struct Parameters(pub Vec<Parameter>);
pub struct GenericParameters(pub Vec<Identifier>);
impl Parameters {
impl GenericParameters {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct Parameter {
identifier: Identifier,
type_use: TypeUse,
}
#[derive(Debug)]
pub struct ReturnType {
pub declared_type: VoidOrTypeUse,
pub references: References,
}
#[derive(Debug)]
pub enum VoidOrTypeUse {
Void,
TypeUse(Box<TypeUse>),
}
#[derive(Debug)]
pub struct References(pub Vec<Reference>);
impl References {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
impl Default for GenericParameters {
fn default() -> Self {
GenericParameters(Vec::new())
}
}
#[derive(Debug)]
pub struct Reference(pub Identifier);
// Inputs
/* Tuple Arguments */
#[derive(Debug)]
pub enum DelegateOrIdentifier {
Delegate,
Identifier(Identifier),
}
pub struct TupleArguments(pub Vec<TypeUse>);
#[derive(Debug)]
pub struct InputParameters(pub Vec<DelegateOrIdentifier>);
impl InputParameters {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct InputArguments(pub Vec<InputArgument>);
impl InputArguments {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct InputArgument {
pub lhs: DelegateOrIdentifier,
pub rhs: Identifier,
}
// Where guards
#[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
/* Implements List */
#[derive(Debug)]
pub struct ImplementsList(pub Vec<TypeUse>);
@ -239,11 +141,84 @@ impl ImplementsList {
}
}
// Top-level construct
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 {
identifier: Identifier,
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<Fqn>,
pub namespace: Option<FullyQualifiedName>,
pub declarations: Vec<ModuleLevelDeclaration>,
}
@ -251,17 +226,15 @@ pub struct CompilationUnit {
#[derive(Debug)]
pub enum ModuleLevelDeclaration {
Type(TypeDeclaration),
Module(ModuleDeclaration),
Interface(InterfaceDeclaration),
Class(ClassDeclaration),
Function(FunctionDeclaration),
Function(FunctionDefinition),
PlatformFunction(PlatformFunctionDeclaration),
}
#[derive(Debug)]
pub enum InterfaceLevelDeclaration {
Type(TypeDeclaration),
Module(ModuleDeclaration),
Interface(InterfaceDeclaration),
Class(ClassDeclaration),
@ -271,27 +244,18 @@ pub enum InterfaceLevelDeclaration {
#[derive(Debug)]
pub enum ClassLevelDeclaration {
Type(TypeDeclaration),
Module(ModuleDeclaration),
Interface(InterfaceDeclaration),
Class(ClassDeclaration),
Function(FunctionDeclaration),
OperatorFunction(OperatorFunctionDeclaration),
Function(FunctionDefinition),
OperatorFunction(OperatorFunctionDefinition),
PlatformFunction(PlatformFunctionDeclaration),
Property(PropertyDeclaration),
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,
@ -304,9 +268,7 @@ 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>,
}
@ -316,14 +278,64 @@ pub struct ClassDeclaration {
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 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,
@ -335,77 +347,9 @@ pub enum FunctionModifier {
#[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,
Equals(Expression),
Block(BlockStatement),
Alias(Identifier),
}
// Class components
@ -414,8 +358,14 @@ pub struct FunctionTypeParameters {
pub struct ClassConstructor(pub Vec<ClassConstructorParameter>);
#[derive(Debug)]
pub struct ClassConstructorParameter {
pub is_field: bool,
pub enum ClassConstructorParameter {
Property(PropertyDeclaration),
Field(FieldDeclaration),
}
#[derive(Debug)]
pub struct PropertyDeclaration {
pub is_mutable: bool,
pub identifier: Identifier,
pub declared_type: TypeUse,
}
@ -430,14 +380,17 @@ pub struct FieldDeclaration {
// Statements
#[derive(Debug)]
pub struct BlockStatement(pub Vec<Statement>);
pub struct BlockStatement {
pub statements: Vec<Statement>,
pub expression: Option<Expression>,
}
#[derive(Debug)]
pub enum Statement {
BlockStatement(BlockStatement),
CallStatement(CallExpression),
VariableDeclarationStatement(VariableDeclarationStatement),
AssignStatement(AssignStatement),
CallStatement(CallStatement),
ReturnStatement(ReturnStatement),
IfStatement(IfStatement),
IfElseStatement(IfElseStatement),
@ -454,7 +407,13 @@ pub struct VariableDeclarationStatement {
}
#[derive(Debug)]
pub struct AssignStatement(pub AssignmentExpression);
pub struct AssignStatement {
pub lhs: Expression,
pub rhs: Expression,
}
#[derive(Debug)]
pub struct CallStatement(pub Expression);
#[derive(Debug)]
pub struct ReturnStatement(pub Option<Expression>);
@ -462,15 +421,15 @@ pub struct ReturnStatement(pub Option<Expression>);
#[derive(Debug)]
pub struct IfStatement {
pub condition: Expression,
pub then_branch: BlockStatement,
pub then_block: BlockStatement,
}
#[derive(Debug)]
pub struct IfElseStatement {
pub condition: Expression,
pub then_branch: BlockStatement,
pub then_block: BlockStatement,
pub else_ifs: ElseIfs,
pub else_branch: BlockStatement,
pub else_block: BlockStatement,
}
#[derive(Debug)]
@ -493,11 +452,22 @@ pub struct ForStatement {
#[derive(Debug)]
pub enum Expression {
Ternary(TernaryExpression),
Binary(BinaryExpression),
Unary(UnaryExpression),
Assignment(Box<AssignmentExpression>),
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)]
@ -508,23 +478,27 @@ pub struct BinaryExpression {
}
#[derive(Debug)]
pub struct UnaryExpression {
pub operator: UnaryOperator,
pub struct PrefixExpression {
pub operator: PrefixUnaryOperator,
pub expression: Box<Expression>,
}
#[derive(Debug)]
pub struct AssignmentExpression {
identifier: Identifier,
expression: Expression,
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>);
@ -532,11 +506,29 @@ pub struct CallArguments(pub Vec<CallArgument>);
pub struct CallArgument(pub Box<Expression>);
#[derive(Debug)]
pub enum Literal {
IntegerLiteral(i32),
LongLiteral(i64),
DoubleLiteral(f64),
USizeLiteral(usize),
StringLiteral(String),
BooleanLiteral(bool),
pub struct Closure {}
#[derive(Debug)]
pub struct ObjectAccess {
pub receiver: Box<Expression>,
pub navigations: ObjectNavigations,
}
#[derive(Debug)]
pub struct ObjectNavigations(pub Vec<ObjectNavigation>);
#[derive(Debug)]
pub enum ObjectNavigation {
Index(Box<Expression>),
Identifier(Box<Identifier>),
}
#[derive(Debug)]
pub enum Literal {
Integer(i32),
Long(i64),
Double(f64),
USize(usize),
String(String),
Boolean(bool),
}

883
src/ast/pretty_print.rs Normal file
View File

@ -0,0 +1,883 @@
use crate::ast::*;
use crate::util::indent_writer::IndentWriter;
use std::fmt::Debug;
pub trait PrettyPrint {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()>;
}
impl PrettyPrint for Operator {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use Operator::*;
match self {
Binary(o) => o.pretty_print(writer),
PrefixUnary(o) => o.pretty_print(writer),
SuffixUnary(o) => o.pretty_print(writer),
}
}
}
impl PrettyPrint for BinaryOperator {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
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(">>"),
}
}
}
impl PrettyPrint for PrefixUnaryOperator {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use PrefixUnaryOperator::*;
match self {
Spread => writer.write("..."),
BorrowMut => writer.write("&mut"),
Borrow => writer.write("&"),
Mut => writer.write("mut"),
Not => writer.write("!"),
Negative => writer.write("-"),
}
}
}
impl PrettyPrint for SuffixUnaryOperator {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use SuffixUnaryOperator::*;
match self {
PlusPlus => writer.write("++"),
MinusMinus => writer.write("--"),
}
}
}
impl PrettyPrint for Identifier {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!("Identifier({})", self.name))
}
}
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.0 {
identifier.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for TypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use TypeUse::*;
match self {
Void => {
writer.writeln_indented("TypeUse(Void)")?;
}
InterfaceOrClass(t) => {
writer.increase_indent();
t.pretty_print(writer)?;
writer.decrease_indent();
}
Tuple(t) => {
writer.increase_indent();
t.pretty_print(writer)?;
writer.decrease_indent();
}
Function(t) => {
writer.increase_indent();
t.pretty_print(writer)?;
writer.decrease_indent();
}
}
Ok(())
}
}
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
))?;
writer.increase_indent();
self.fqn.pretty_print(writer)?;
self.generics.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
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
))?;
writer.increase_indent();
self.arguments.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for FunctionTypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"FunctionTypeUse(borrow_count = {})",
self.borrow_count
))?;
writer.increase_indent();
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)?;
writer.decrease_indent();
Ok(())
}
}
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 {
type_use.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
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 {
identifier.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
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 {
type_use.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
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 {
type_use.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for FunctionTypeModifier {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use FunctionTypeModifier::*;
writer.writeln_indented(&format!(
"FunctionTypeModifier({})",
match self {
Cons => "cons",
MutRef => "mut ref",
Mut => "mut",
Ref => "ref",
}
))
}
}
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 {
parameter.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
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 {
identifier.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
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 {
writer.writeln_indented("Namespace")?;
writer.increase_indent();
namespace.pretty_print(writer)?;
writer.decrease_indent();
}
for declaration in &self.declarations {
declaration.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for ModuleLevelDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use ModuleLevelDeclaration::*;
match self {
Module(module) => module.pretty_print(writer),
Interface(interface) => interface.pretty_print(writer),
Class(class) => class.pretty_print(writer),
Function(function) => function.pretty_print(writer),
PlatformFunction(platform_function) => platform_function.pretty_print(writer),
}
}
}
impl PrettyPrint for InterfaceLevelDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use InterfaceLevelDeclaration::*;
match self {
Module(module) => module.pretty_print(writer),
Interface(interface) => interface.pretty_print(writer),
Class(class) => class.pretty_print(writer),
Function(function) => function.pretty_print(writer),
OperatorFunction(operator_function) => operator_function.pretty_print(writer),
}
}
}
impl PrettyPrint for ClassLevelDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use ClassLevelDeclaration::*;
match self {
Module(module) => module.pretty_print(writer),
Interface(interface) => interface.pretty_print(writer),
Class(class) => class.pretty_print(writer),
Function(function) => function.pretty_print(writer),
OperatorFunction(operator_function) => operator_function.pretty_print(writer),
PlatformFunction(platform_function) => platform_function.pretty_print(writer),
Property(property) => property.pretty_print(writer),
Field(field) => field.pretty_print(writer),
}
}
}
impl PrettyPrint for ModuleDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"ModuleDeclaration(is_public = {})",
self.is_public
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
for declaration in &self.declarations {
declaration.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for InterfaceDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"InterfaceDeclaration(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 {
declaration.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
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.increase_indent();
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 {
declaration.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for FunctionDefinition {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"FunctionDefinition(is_public = {})",
self.is_public
))?;
writer.increase_indent();
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)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for OperatorFunctionDefinition {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"OperatorFunctionDefinition(is_public = {})",
self.is_public
))?;
writer.increase_indent();
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)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for PlatformFunctionDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"PlatformFunctionDeclaration(is_public = {})",
self.is_public
))?;
writer.increase_indent();
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)?;
writer.decrease_indent();
Ok(())
}
}
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 {
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 {
body.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
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 {
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 {
body.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for FunctionModifier {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use FunctionModifier::*;
writer.writeln_indented(&format!(
"FunctionModifier({})",
match self {
Static => "static",
Cons => "cons",
Mut => "mut",
Ref => "ref",
MutRef => "mut ref",
}
))
}
}
impl PrettyPrint for FunctionBody {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use FunctionBody::*;
match self {
Equals(expression) => {
writer.writeln_indented("EqualsFunctionBody")?;
writer.increase_indent();
expression.pretty_print(writer)?;
writer.decrease_indent();
}
Block(block_statement) => {
writer.writeln_indented("BlockFunctionBody")?;
writer.increase_indent();
block_statement.pretty_print(writer)?;
writer.decrease_indent();
}
Alias(identifier) => {
writer.writeln_indented("AliasFunctionBody")?;
writer.increase_indent();
identifier.pretty_print(writer)?;
writer.decrease_indent();
}
}
Ok(())
}
}
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 {
constructor_parameter.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for ClassConstructorParameter {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use ClassConstructorParameter::*;
match self {
Property(property) => {
writer.writeln_indented("PropertyConstructorParameter")?;
writer.increase_indent();
property.pretty_print(writer)?;
writer.decrease_indent();
}
Field(field) => {
writer.writeln_indented("FieldConstructorParameter")?;
writer.increase_indent();
field.pretty_print(writer)?;
writer.decrease_indent();
}
}
Ok(())
}
}
impl PrettyPrint for PropertyDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"PropertyDeclaration(is_mutable = {})",
self.is_mutable
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
self.declared_type.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for FieldDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"FieldDeclaration(is_mutable = {})",
self.is_mutable
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
self.declared_type.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
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 {
statement.pretty_print(writer)?;
}
if let Some(expression) = &self.expression {
expression.pretty_print(writer)?;
}
Ok(())
}
}
impl PrettyPrint for Statement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use Statement::*;
match self {
BlockStatement(block_statement) => block_statement.pretty_print(writer),
VariableDeclarationStatement(s) => s.pretty_print(writer),
AssignStatement(s) => s.pretty_print(writer),
CallStatement(s) => s.pretty_print(writer),
ReturnStatement(s) => s.pretty_print(writer),
IfStatement(s) => s.pretty_print(writer),
IfElseStatement(s) => s.pretty_print(writer),
WhileStatement(s) => s.pretty_print(writer),
ForStatement(s) => s.pretty_print(writer),
}
}
}
impl PrettyPrint for VariableDeclarationStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented(&format!(
"VariableDeclarationStatement(is_mutable = {})",
self.is_mutable
))?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
if let Some(declared_type) = &self.declared_type {
declared_type.pretty_print(writer)?;
}
if let Some(initializer) = &self.initializer {
initializer.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for ReturnStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("ReturnStatement")?;
if let Some(expression) = &self.0 {
writer.increase_indent();
expression.pretty_print(writer)?;
writer.decrease_indent();
}
Ok(())
}
}
impl PrettyPrint for IfStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("IfStatement")?;
writer.increase_indent();
self.condition.pretty_print(writer)?;
self.then_block.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for IfElseStatement {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
writer.writeln_indented("IfElseStatement")?;
writer.increase_indent();
self.condition.pretty_print(writer)?;
self.then_block.pretty_print(writer)?;
for else_if in &self.else_ifs.0 {
else_if.condition.pretty_print(writer)?;
else_if.then_block.pretty_print(writer)?;
}
self.else_block.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for Expression {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use Expression::*;
match self {
Ternary(e) => e.pretty_print(writer),
Binary(e) => e.pretty_print(writer),
UnaryPrefix(e) => e.pretty_print(writer),
UnarySuffix(e) => e.pretty_print(writer),
Call(e) => e.pretty_print(writer),
ObjectAccess(o) => o.pretty_print(writer),
Literal(literial) => literial.pretty_print(writer),
FullyQualifiedName(fqn) => fqn.pretty_print(writer),
Closure(closure) => closure.pretty_print(writer),
}
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
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 {
turbo_fish.pretty_print(writer)?;
}
self.arguments.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
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 {
call_argument.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for Closure {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
todo!()
}
}
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)?;
writer.decrease_indent();
Ok(())
}
}
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 {
object_navigation.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for ObjectNavigation {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use ObjectNavigation::*;
match self {
Index(e) => {
writer.writeln_indented("Index")?;
writer.increase_indent();
e.pretty_print(writer)?;
writer.decrease_indent();
}
Identifier(identifier) => {
writer.writeln_indented("Property")?;
writer.increase_indent();
identifier.pretty_print(writer)?;
writer.decrease_indent();
}
}
Ok(())
}
}
impl PrettyPrint for Literal {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
use Literal::*;
match self {
Integer(i) => writer.writeln_indented(&format!("Integer({})", i)),
Long(l) => writer.writeln_indented(&format!("Long({})", l)),
Double(d) => writer.writeln_indented(&format!("Double({})", d)),
USize(u) => writer.writeln_indented(&format!("USize({})", u)),
String(s) => writer.writeln_indented(&format!("String({})", s)),
Boolean(b) => writer.writeln_indented(&format!("Boolean({})", b)),
}
}
}

View File

@ -1,4 +1,4 @@
use std::fmt::write;
use crate::ast::FunctionModifier::{Cons, Mut, MutRef, Ref, Static};
use crate::ast::*;
macro_rules! to_unparse_vec {
@ -80,7 +80,8 @@ impl Unparse for Operator {
use Operator::*;
match self {
Binary(op) => op.unparse(buf),
Unary(op) => op.unparse(buf),
PrefixUnary(op) => op.unparse(buf),
SuffixUnary(op) => op.unparse(buf),
}
}
}
@ -108,16 +109,26 @@ impl Unparse for BinaryOperator {
}
}
impl Unparse for UnaryOperator {
impl Unparse for PrefixUnaryOperator {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
use UnaryOperator::*;
use PrefixUnaryOperator::*;
match self {
Spread => write!(buf, "..."),
BorrowMut => write!(buf, "&mut"),
Borrow => write!(buf, "&"),
Mut => write!(buf, "mut"),
Not => write!(buf, "!"),
Negative => write!(buf, "-"),
}
}
}
impl Unparse for SuffixUnaryOperator {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
use SuffixUnaryOperator::*;
match self {
PlusPlus => write!(buf, "++"),
MinusMinus => write!(buf, "--"),
CallOp => write!(buf, "()"),
Spread => write!(buf, "..."),
}
}
}
@ -130,39 +141,85 @@ impl Unparse for Identifier {
}
}
impl ListUnparse for Fqn {
impl ListUnparse for FullyQualifiedName {
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 {
/* TypeUse and components */
impl Unparse for TypeUse {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.0.unparse(buf)
use TypeUse::*;
match self {
Void => write!(buf, "Void"),
InterfaceOrClass(interface_or_class_type_use) => {
interface_or_class_type_use.unparse(buf)
}
Tuple(tuple_type_use) => tuple_type_use.unparse(buf),
Function(function_type_use) => function_type_use.unparse(buf),
}
}
}
impl Unparse for InterfaceOrClassTypeUse {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
for _ in 0..self.borrow_count {
write!(buf, "&")?;
}
if self.is_mutable {
write!(buf, "mut")?;
}
if self.borrow_count > 0 || self.is_mutable {
write!(buf, " ")?;
}
self.fqn.unparse(buf)?;
self.generics.unparse(buf)?;
unparse_ok!()
}
}
impl Unparse for TupleTypeUse {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
for _ in 0..self.borrow_count {
write!(buf, "&")?;
}
if self.is_mutable {
write!(buf, "mut")?;
}
if self.borrow_count > 0 || self.is_mutable {
write!(buf, " ")?;
}
self.arguments.unparse(buf)?;
unparse_ok!()
}
}
impl Unparse for FunctionTypeUse {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
for _ in 0..self.borrow_count {
write!(buf, "&")?;
}
if let Some(function_type_modifier) = &self.function_modifier {
function_type_modifier.unparse(buf)?;
}
if self.borrow_count > 0 || self.function_modifier.is_some() {
write!(buf, " ")?;
}
write!(buf, "fn ")?;
if !self.generics.is_empty() {
self.generics.unparse(buf)?;
write!(buf, " ")?;
}
self.parameters.unparse(buf)?;
write!(buf, " ")?;
self.return_type.unparse(buf)?;
unparse_ok!()
}
}
@ -186,82 +243,27 @@ impl ListUnparse for GenericArguments {
}
}
impl Unparse for GenericArgument {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.fqn.unparse(buf)
}
}
/* Generic Parameters */
/* TypeUse and components */
impl Unparse for TypeUse {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
use TypeUse::*;
match self {
InterfaceOrClass(interface_or_class_type_use) => interface_or_class_type_use.unparse(buf),
Tuple(tuple_type_use) => tuple_type_use.unparse(buf),
Function(function_type_use) => function_type_use.unparse(buf),
}
}
}
impl Unparse for InterfaceOrClassTypeUse {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.fqn.unparse(buf)?;
self.generics.unparse(buf)?;
unparse_ok!()
}
}
impl ListUnparse for TupleTypeUse {
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 FunctionTypeUse {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
if let Some(function_modifier) = &self.function_modifier {
function_modifier.unparse(buf)?;
}
write!(buf, " fn ")?;
if !self.generics.is_empty() {
self.generics.unparse(buf)?;
write!(buf, " ")?;
}
self.parameters.unparse(buf)?;
write!(buf, " ")?;
if !self.inputs.is_empty() {
self.inputs.unparse(buf)?;
write!(buf, " ")?;
}
self.return_type.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),
}
}
}
/* Tuple Arguments */
impl ListUnparse for TupleArguments {
fn prefix() -> &'static str {
@ -281,16 +283,37 @@ impl ListUnparse for TupleArguments {
}
}
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!()
/* Implements List */
impl ListUnparse for ImplementsList {
fn prefix() -> &'static str {
": "
}
fn separator() -> &'static str {
" + "
}
fn inner(&self) -> Vec<&dyn Unparse> {
to_unparse_vec!(self.0)
}
}
/* Function components */
/* Function Type Modifier */
impl Unparse for FunctionTypeModifier {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
use FunctionTypeModifier::*;
match self {
Cons => write!(buf, "cons"),
MutRef => write!(buf, "mut ref"),
Mut => write!(buf, "mut"),
Ref => write!(buf, "ref"),
}
}
}
/* Parameters */
impl ListUnparse for Parameters {
fn prefix() -> &'static str {
@ -319,27 +342,20 @@ impl Unparse for Parameter {
}
}
/* Return Type */
impl Unparse for ReturnType {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
write!(buf, "-> ")?;
self.declared_type.unparse(buf)?;
if !self.references.is_empty() {
write!(buf, " ")?;
self.references.unparse(buf)?;
}
unparse_ok!()
}
}
impl Unparse for VoidOrTypeUse {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
use VoidOrTypeUse::*;
match self {
Void => write!(buf, "Void"),
TypeUse(type_use) => type_use.unparse(buf),
}
}
}
impl ListUnparse for References {
fn prefix() -> &'static str {
"ref "
@ -354,110 +370,6 @@ impl ListUnparse for References {
}
}
impl Unparse for Reference {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.0.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 {
@ -478,7 +390,6 @@ 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),
@ -494,7 +405,6 @@ 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),
@ -510,7 +420,6 @@ 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),
@ -521,6 +430,7 @@ impl Unparse for ClassLevelDeclaration {
PlatformFunction(platform_function_declaration) => {
platform_function_declaration.unparse(buf)
}
Property(property_declaration) => property_declaration.unparse(buf),
Field(field_declaration) => field_declaration.unparse(buf),
}
}
@ -528,25 +438,6 @@ impl Unparse for ClassLevelDeclaration {
/* 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 {
@ -570,18 +461,10 @@ impl Unparse for InterfaceDeclaration {
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!()
}
@ -605,14 +488,6 @@ impl Unparse for ClassDeclaration {
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!()
}
@ -620,37 +495,7 @@ impl Unparse for ClassDeclaration {
/* 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 {
impl Unparse for FunctionDefinition {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
if self.is_public {
write!(buf, "pub ")?;
@ -660,21 +505,21 @@ impl Unparse for FunctionDeclaration {
write!(buf, " ")?;
}
write!(buf, "fn ")?;
self.generics.unparse(buf)?;
write!(buf, " ")?;
if !self.generics.is_empty() {
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.return_type.unparse(buf)?;
write!(buf, " ")?;
self.body.unparse(buf)?;
unparse_ok!()
}
}
impl Unparse for OperatorFunctionDeclaration {
impl Unparse for OperatorFunctionDefinition {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
if self.is_public {
write!(buf, "pub ")?;
@ -687,10 +532,8 @@ impl Unparse for OperatorFunctionDeclaration {
write!(buf, " ")?;
self.parameters.unparse(buf)?;
write!(buf, " ")?;
if let Some(return_type) = &self.return_type {
return_type.unparse(buf)?;
write!(buf, " ")?;
}
self.return_type.unparse(buf)?;
write!(buf, " ")?;
self.body.unparse(buf)?;
unparse_ok!()
}
@ -728,6 +571,10 @@ impl Unparse for InterfaceFunctionDeclaration {
self.parameters.unparse(buf)?;
write!(buf, " ")?;
self.return_type.unparse(buf)?;
if let Some(body) = &self.body {
write!(buf, " ")?;
body.unparse(buf)?;
}
unparse_ok!()
}
}
@ -748,47 +595,45 @@ impl Unparse for InterfaceOperatorFunctionDeclaration {
self.parameters.unparse(buf)?;
write!(buf, " ")?;
self.return_type.unparse(buf)?;
if let Some(body) = &self.body {
write!(buf, " ")?;
body.unparse(buf)?;
}
unparse_ok!()
}
}
/* Type components */
/* Function Modifier */
impl Unparse for TypeParameters {
impl Unparse for FunctionModifier {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
use TypeParameters::*;
use FunctionModifier::*;
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),
Static => write!(buf, "static"),
Cons => write!(buf, "cons"),
Mut => write!(buf, "mut"),
Ref => write!(buf, "ref"),
MutRef => write!(buf, "mut ref"),
}
}
}
impl ListUnparse for TupleParameters {
fn prefix() -> &'static str {
"("
}
/* Function Body */
fn separator() -> &'static str {
", "
}
fn suffix() -> &'static str {
")"
}
fn inner(&self) -> Vec<&dyn Unparse> {
to_unparse_vec!(self.0)
}
}
impl Unparse for FunctionTypeParameters {
impl Unparse for FunctionBody {
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!()
use FunctionBody::*;
match self {
Equals(expression) => {
write!(buf, "= ")?;
expression.unparse(buf)
}
Block(body) => body.unparse(buf),
Alias(identifier) => {
write!(buf, "alias ")?;
identifier.unparse(buf)
}
}
}
}
@ -814,8 +659,18 @@ impl ListUnparse for ClassConstructor {
impl Unparse for ClassConstructorParameter {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
if self.is_field {
write!(buf, "fld ")?;
use ClassConstructorParameter::*;
match self {
Property(property) => property.unparse(buf),
Field(field) => field.unparse(buf),
}
}
}
impl Unparse for PropertyDeclaration {
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, ": ")?;
@ -829,6 +684,7 @@ impl Unparse for FieldDeclaration {
if self.is_mutable {
write!(buf, "mut ")?;
}
write!(buf, "fld ")?;
self.identifier.unparse(buf)?;
write!(buf, ": ")?;
self.declared_type.unparse(buf)?;
@ -838,21 +694,18 @@ impl Unparse for FieldDeclaration {
/* 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 BlockStatement {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
write!(buf, "{{\n")?;
for statement in &self.statements {
statement.unparse(buf)?;
}
if let Some(expression) = &self.expression {
expression.unparse(buf)?;
write!(buf, "\n")?;
}
write!(buf, "}}")?;
unparse_ok!()
}
}
@ -861,7 +714,7 @@ impl Unparse for Statement {
use Statement::*;
match self {
BlockStatement(statement) => statement.unparse(buf),
CallStatement(call_expression) => call_expression.unparse(buf),
CallStatement(call) => call.unparse(buf),
VariableDeclarationStatement(declaration) => declaration.unparse(buf),
AssignStatement(assign_statement) => assign_statement.unparse(buf),
ReturnStatement(return_expression) => return_expression.unparse(buf),
@ -870,7 +723,8 @@ impl Unparse for Statement {
WhileStatement(while_statement) => while_statement.unparse(buf),
ForStatement(for_statement) => for_statement.unparse(buf),
}?;
write!(buf, "\n")
write!(buf, ";\n")?;
unparse_ok!()
}
}
@ -895,7 +749,17 @@ impl Unparse for VariableDeclarationStatement {
impl Unparse for AssignStatement {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.0.unparse(buf)
self.lhs.unparse(buf)?;
write!(buf, " = ")?;
self.rhs.unparse(buf)?;
unparse_ok!()
}
}
impl Unparse for CallStatement {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.0.unparse(buf)?;
unparse_ok!()
}
}
@ -915,7 +779,7 @@ impl Unparse for IfStatement {
write!(buf, "if ")?;
self.condition.unparse(buf)?;
write!(buf, " {{\n")?;
self.then_branch.unparse(buf)?;
self.then_block.unparse(buf)?;
write!(buf, "\n}}")?;
unparse_ok!()
}
@ -926,11 +790,11 @@ impl Unparse for IfElseStatement {
write!(buf, "if ")?;
self.condition.unparse(buf)?;
write!(buf, " ")?;
self.then_branch.unparse(buf)?;
self.then_block.unparse(buf)?;
write!(buf, " ")?;
self.else_ifs.unparse(buf)?;
write!(buf, "else ")?;
self.else_branch.unparse(buf)?;
self.else_block.unparse(buf)?;
unparse_ok!()
}
}
@ -970,29 +834,85 @@ impl Unparse for ForStatement {
/* Expressions */
impl Unparse for AssignmentExpression {
impl Unparse for Expression {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.identifier.unparse(buf)?;
write!(buf, " = ")?;
use Expression::*;
match self {
Ternary(ternary) => ternary.unparse(buf),
Binary(binary) => binary.unparse(buf),
UnaryPrefix(prefix) => prefix.unparse(buf),
UnarySuffix(suffix) => suffix.unparse(buf),
Call(call) => call.unparse(buf),
ObjectAccess(object_access) => object_access.unparse(buf),
Literal(literal) => literal.unparse(buf),
FullyQualifiedName(fully_qualified_name) => fully_qualified_name.unparse(buf),
Closure(closure) => closure.unparse(buf),
}
}
}
impl Unparse for TernaryExpression {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.condition.unparse(buf)?;
write!(buf, " ? ")?;
self.true_expression.unparse(buf)?;
write!(buf, " : ")?;
self.false_expression.unparse(buf)?;
unparse_ok!()
}
}
impl Unparse for BinaryExpression {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.left.unparse(buf)?;
write!(buf, " ")?;
self.operator.unparse(buf)?;
write!(buf, " ")?;
self.right.unparse(buf)?;
unparse_ok!()
}
}
impl Unparse for PrefixExpression {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
use PrefixUnaryOperator::*;
match &self.operator {
BorrowMut => write!(buf, "&mut "),
Mut => write!(buf, "mut "),
other => other.unparse(buf),
}?;
self.expression.unparse(buf)?;
unparse_ok!()
}
}
impl Unparse for Expression {
impl Unparse for SuffixExpression {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
todo!()
self.expression.unparse(buf)?;
self.operator.unparse(buf)?;
unparse_ok!()
}
}
impl Unparse for CallExpression {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.callee.unparse(buf)?;
if let Some(turbo_fish) = &self.turbo_fish {
turbo_fish.unparse(buf)?;
}
self.arguments.unparse(buf)?;
unparse_ok!()
}
}
impl Unparse for TurboFish {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
write!(buf, "::")?;
self.0.unparse(buf)?;
unparse_ok!()
}
}
impl ListUnparse for CallArguments {
fn prefix() -> &'static str {
"("
@ -1016,3 +936,58 @@ impl Unparse for CallArgument {
self.0.unparse(buf)
}
}
impl Unparse for Closure {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
write!(buf, "{{ -> TODO }}")
}
}
impl Unparse for ObjectAccess {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
self.receiver.unparse(buf)?;
self.navigations.unparse(buf)?;
unparse_ok!()
}
}
impl Unparse for ObjectNavigations {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
for navigation in &self.0 {
navigation.unparse(buf)?;
}
unparse_ok!()
}
}
impl Unparse for ObjectNavigation {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
use ObjectNavigation::*;
match self {
Index(expression) => {
write!(buf, "[")?;
expression.unparse(buf)?;
write!(buf, "]")?;
}
Identifier(identifier) => {
write!(buf, ".")?;
identifier.unparse(buf)?;
}
}
unparse_ok!()
}
}
impl Unparse for Literal {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
use Literal::*;
match self {
Integer(i) => write!(buf, "{}", i),
Long(l) => write!(buf, "{}", l),
Double(d) => write!(buf, "{}", d),
USize(u) => write!(buf, "{}", u),
String(s) => write!(buf, "\"{}\"", s),
Boolean(b) => write!(buf, "{}", b),
}
}
}

View File

@ -1,9 +0,0 @@
use std::path::PathBuf;
use deimos::ast::build::build_ast;
pub fn dump_ast(path: &PathBuf) {
let src = std::fs::read_to_string(path).expect(&format!("Could not read {:?}", path));
let ast = build_ast(&src);
println!("{:?}", ast);
}

View File

@ -1,8 +1,10 @@
mod ast_dump;
mod p3;
mod unparse;
use std::path::PathBuf;
use ast_dump::dump_ast;
use crate::p3::pretty_print_parse;
use crate::unparse::unparse;
use clap::{Parser, Subcommand};
#[derive(Debug, Parser)]
@ -16,15 +18,25 @@ struct Cli {
#[derive(Debug, Subcommand)]
enum Commands {
#[command(arg_required_else_help = true)]
AstDump { paths: Vec<PathBuf> },
Unparse {
paths: Vec<PathBuf>,
},
P3 {
paths: Vec<PathBuf>,
},
}
fn main() {
let args = Cli::parse();
match args.command {
Commands::AstDump { paths } => {
Commands::Unparse { paths } => {
for path in paths {
dump_ast(&path);
unparse(&path);
}
}
Commands::P3 { paths } => {
for path in paths {
pretty_print_parse(&path)
}
}
}

24
src/bin/dmc/p3.rs Normal file
View File

@ -0,0 +1,24 @@
use deimos::ast::build::build_ast;
use deimos::ast::pretty_print::PrettyPrint;
use deimos::parser::{DeimosParser, Rule};
use deimos::util::indent_writer::IndentWriter;
use pest::Parser;
use std::path::PathBuf;
pub fn pretty_print_parse(path: &PathBuf) {
let src = std::fs::read_to_string(path).expect(&format!("Unable to read {:?}", path));
let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src);
match parse_result {
Ok(mut pairs) => {
let compilation_unit_pair = pairs.next().unwrap();
let compilation_unit = build_ast(compilation_unit_pair);
let mut indent_writer = IndentWriter::new(0, " ", Box::new(std::io::stdout()));
compilation_unit
.pretty_print(&mut indent_writer)
.expect("Unable to pretty-print.");
}
Err(e) => {
eprintln!("{}", e);
}
}
}

22
src/bin/dmc/unparse.rs Normal file
View File

@ -0,0 +1,22 @@
use std::path::PathBuf;
use pest::Parser;
use deimos::ast::build::build_ast;
use deimos::ast::unparse::Unparse;
use deimos::parser::{DeimosParser, Rule};
pub fn unparse(path: &PathBuf) {
let src = std::fs::read_to_string(path).expect(&format!("Could not read {:?}", path));
let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src);
match parse_result {
Ok(mut pairs) => {
let compilation_unit_pair = pairs.next().unwrap();
let compilation_unit = build_ast(compilation_unit_pair);
let mut out = String::new();
compilation_unit.unparse(&mut out).expect("Failed to write to string.");
println!("{}", out);
},
Err(e) => {
eprintln!("{}", e);
}
}
}

View File

@ -1,10 +0,0 @@
pub enum DeclaredType {
Function(FunctionType),
}
pub enum FunctionType {
StaticFunction,
ObjectFunction,
StaticPlatformFunction,
ObjectPlatformFunction,
}

View File

@ -1,164 +0,0 @@
use crate::ast::{
AssignExpression, BlockStatement, CallExpression, CompilationUnit, Expression, Fqn,
FunctionDeclaration, Identifier, LValue, ModuleLevelDeclaration, Statement,
};
use crate::object_file::{DvmObjectFile, DvmPath};
use crate::vm::function::DvmFunction;
use crate::vm::instruction::Instruction;
use declared_type::{DeclaredType, FunctionType};
use std::rc::Rc;
use symbol_table::SymbolTable;
mod declared_type;
mod symbol;
mod symbol_table;
struct CompilationState {
fqn_part_stack: Vec<Identifier>,
}
impl CompilationState {
fn push_fqn_identifier(&mut self, identifier: &Identifier) {
self.fqn_part_stack.push(identifier.clone());
}
fn pop_fqn_identifier(&mut self) {
self.fqn_part_stack.pop();
}
fn get_current_fqn(&self) -> Fqn {
Fqn::new(self.fqn_part_stack.clone())
}
}
struct CompilationContext {
source_file_name: String,
symbol_table: SymbolTable,
}
fn compile_call_expression(
context: &CompilationContext,
call_expression: &CallExpression,
instructions: &mut Vec<Instruction>,
) {
match call_expression.receiver() {
Expression::LValue(lvalue) => {
let lvalue = &**lvalue;
if let LValue::Fqn(fqn) = lvalue {
let symbol = context.symbol_table.resolve(fqn);
match symbol.declared_type() {
DeclaredType::Function(function_type) => match function_type {
FunctionType::StaticFunction => {
instructions.push(Instruction::InvokeStatic {
function_name: Rc::new(convert_fqn(&fqn)),
source_code_location: call_expression
.source_code_location()
.clone(),
});
}
_ => todo!(),
},
}
} else {
todo!()
}
}
_ => todo!(),
}
}
fn compile_assign_expression(
assign_expression: &AssignExpression,
instruction: &mut Vec<Instruction>,
) {
todo!()
}
fn convert_statement(
context: &CompilationContext,
statement: &Statement,
instructions: &mut Vec<Instruction>,
) {
match statement {
Statement::CallStatement(call_expression) => {
compile_call_expression(context, call_expression, instructions);
}
Statement::AssignStatement(assign_expression) => {
compile_assign_expression(assign_expression, instructions);
}
}
}
fn convert_block_statement(
context: &CompilationContext,
block_statement: &BlockStatement,
) -> Vec<Instruction> {
let mut instructions = vec![];
for statement in block_statement.statements() {
convert_statement(context, statement, &mut instructions);
}
instructions
}
fn convert_static_function(
compilation_state: &CompilationState,
context: &CompilationContext,
function_declaration: &FunctionDeclaration,
) -> DvmFunction {
let mut fqn = compilation_state.get_current_fqn();
fqn.push_identifier(function_declaration.identifier().clone());
let instructions = convert_block_statement(context, function_declaration.block_statement());
DvmFunction::new(
&convert_fqn(&fqn),
&instructions,
function_declaration.source_code_location().clone(),
)
}
fn convert_fqn(fqn: &Fqn) -> String {
let mut as_string = String::new();
let mut i = 0;
let identifiers = fqn.identifiers();
while i < identifiers.len() {
as_string.push_str(identifiers[i].name());
i += 1;
if i < identifiers.len() {
as_string.push_str("::");
}
}
as_string
}
fn make_path(file_name: &str, file_namespace: &Option<Fqn>) -> DvmPath {
if let Some(namespace) = file_namespace {
DvmPath::new(&convert_fqn(namespace), file_name)
} else {
DvmPath::new("", file_name)
}
}
pub fn convert(file_name: &str, ast: CompilationUnit) -> DvmObjectFile {
let path = make_path(file_name, ast.namespace());
let mut object_file = DvmObjectFile::new(path);
let mut state = CompilationState {
fqn_part_stack: Vec::new(),
};
let context = CompilationContext {
source_file_name: file_name.to_string(),
symbol_table: SymbolTable {},
};
for declaration in ast.declarations() {
match declaration {
ModuleLevelDeclaration::Function(function_declaration) => {
let function = convert_static_function(&state, &context, function_declaration);
object_file.add_function(function);
}
_ => todo!("Unimplemented declaration {:?}", declaration),
}
}
object_file
}

View File

@ -1,17 +0,0 @@
use crate::ast::Fqn;
use crate::compile::declared_type::DeclaredType;
pub struct Symbol {
fqn: Fqn,
declared_type: DeclaredType,
}
impl Symbol {
pub fn fqn(&self) -> &Fqn {
&self.fqn
}
pub fn declared_type(&self) -> &DeclaredType {
&self.declared_type
}
}

View File

@ -1,10 +0,0 @@
use crate::ast::Fqn;
use crate::compile::symbol::Symbol;
pub struct SymbolTable {}
impl SymbolTable {
pub fn resolve(&self, fqn: &Fqn) -> Symbol {
todo!()
}
}

View File

@ -1,6 +1,5 @@
#![allow(warnings)]
pub mod ast;
pub mod compile;
pub mod module;
pub mod object_file;
pub mod parser;

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ pub struct DeimosParser;
mod deimos_parser_tests {
use crate::parser::{DeimosParser, Rule};
use pest::iterators::Pair;
use pest::Parser;
use pest::{Parser};
macro_rules! fail_rule {
($pair: expr; $rule:path) => {{
@ -77,25 +77,7 @@ mod deimos_parser_tests {
#[test]
fn identifier_call_as_expression() {
let pair = parse(Rule::Expression, "foo()");
match_inner_rules!(pair; Rule::Expression, Rule::OrExpression, Rule::AndExpression, Rule::EqualityExpression, Rule::ComparisonExpression, Rule::AdditiveExpression, Rule::MultiplicativeExpression, Rule::UnaryExpression; |unary_expression: Pair<Rule>| {
let mut unary_pairs = unary_expression.into_inner();
let primary_expression = unary_pairs.next().unwrap();
match_rule!(primary_expression; Rule::PrimaryExpression);
let call = unary_pairs.next().unwrap();
match_rule!(call; Rule::Call);
});
}
#[test]
fn identifier_call_as_call_expression() {
let pair = parse(Rule::CallExpression, "foo()");
match_rule!(pair; Rule::CallExpression);
let mut call_expression_pairs = pair.into_inner();
let primary_expression = call_expression_pairs.next().unwrap();
match_rule!(primary_expression; Rule::PrimaryExpression);
let call = call_expression_pairs.next().unwrap();
match_rule!(call; Rule::Call);
parse(Rule::Expression, "foo()");
}
mod smoke_screen_tests {

42
src/util/indent_writer.rs Normal file
View File

@ -0,0 +1,42 @@
pub struct IndentWriter {
indent_level: usize,
indent_string: String,
out: Box<dyn std::io::Write>,
}
impl IndentWriter {
pub fn new(start_level: usize, indent_string: &str, out: Box<dyn std::io::Write>) -> IndentWriter {
IndentWriter {
indent_level: start_level,
indent_string: indent_string.to_string(),
out,
}
}
pub fn increase_indent(&mut self) {
self.indent_level += 1;
}
pub fn decrease_indent(&mut self) {
self.indent_level -= 1;
}
pub fn write(&mut self, s: &str) -> std::io::Result<()> {
write!(self.out, "{}", s)
}
pub fn writeln(&mut self, s: &str) -> std::io::Result<()> {
self.write(&format!("{}\n", s))
}
pub fn write_indented(&mut self, s: &str) -> std::io::Result<()> {
for _ in 0..self.indent_level {
write!(self.out, "{}", self.indent_string)?;
}
write!(self.out, "{}", s)
}
pub fn writeln_indented(&mut self, s: &str) -> std::io::Result<()> {
self.write_indented(&format!("{}\n", s))
}
}

View File

@ -1 +1 @@
pub mod trie;
pub mod indent_writer;

View File

@ -1,120 +0,0 @@
// use crate::util::trie::GetEdgeResult::{EdgeKeyIsPrefix, EqualKeys, KeyIsPrefix};
// use std::collections::HashMap;
// use std::rc::Rc;
//
// pub struct RadixTrie<T> {
// root: RadixTrieNode<T>,
// }
//
// struct RadixTrieNode<T> {
// edges: HashMap<String, RadixTrieNode<T>>,
// value: Option<Rc<T>>,
// }
//
// impl<T> RadixTrie<T> {
// pub fn new() -> Self {
// RadixTrie {
// root: Default::default(),
// }
// }
//
// pub fn insert(&mut self, key: &str, value: &Rc<T>) {
// self.root.insert_helper(key, value);
// }
//
// pub fn remove(&mut self, key: &str) {
// todo!()
// }
//
// pub fn find(&self, key: &str) -> Option<Rc<T>> {
// todo!()
// }
// }
//
// impl<T> Default for RadixTrieNode<T> {
// fn default() -> Self {
// RadixTrieNode::new()
// }
// }
//
// enum GetEdgeResult<'a, T> {
// EqualKeys,
// KeyIsPrefix(&'a str, &'a mut RadixTrieNode<T>), // common prefix and target node
// EdgeKeyIsPrefix(&'a str, &'a mut RadixTrieNode<T>), // non-common suffix and target node,
// None,
// }
//
// impl<T> RadixTrieNode<T> {
// fn new() -> Self {
// RadixTrieNode {
// edges: HashMap::new(),
// value: None,
// }
// }
//
// fn get_edge<'a>(&'a mut self, key: &'a str) -> GetEdgeResult<'a, T> {
// for (edge_key, edge_node) in self.edges.iter_mut() {
// // Case: edge_key == key: overwrite data
// if *key == *edge_key {
// return EqualKeys;
// }
//
// // Find how many common characters there are starting from the beginning and terminating
// // as soon as there is no match
// let mut i = 0;
// 'number_of_common_chars: for (key_char, edge_key_char) in
// key.chars().zip(edge_key.chars())
// {
// if key_char == edge_key_char {
// i += 1;
// } else {
// break 'number_of_common_chars;
// }
// }
//
// // Case: key's first char does not match at all: continue searching
// if i == 0 {
// continue;
// }
//
// // Case: key is prefix of edge_key
// if i < edge_key.len() {
// return KeyIsPrefix(key, edge_node);
// }
//
// if i == edge_key.len() {
// panic!(
// "Should not have gotten here: counted common chars equals edge_key's length."
// )
// }
//
// return EdgeKeyIsPrefix(&edge_key[i..], edge_node);
// }
// GetEdgeResult::None
// }
//
// fn insert_helper(&mut self, key: &str, value: &Rc<T>) {
// match self.get_edge(key) {
// EqualKeys => {
// let edge_node = self.edges.get_mut(key).unwrap();
// edge_node.value = Some(value.clone());
// }
// KeyIsPrefix(prefix, edge_node) => {
// // split like asparagus break
// let old_target_node = self.edges.remove(key).unwrap();
//
//
// let mut common_prefix_node: RadixTrieNode<T> = RadixTrieNode::new();
// }
// EdgeKeyIsPrefix(suffix, edge_node) => {
// // recursive on edge_node
// edge_node.insert_helper(suffix, value);
// }
// GetEdgeResult::None => {
// let mut new_edge_node = RadixTrieNode::new();
// new_edge_node.value = Some(value.clone());
// self.edges.insert(String::from(key), new_edge_node);
// }
// }
// }
// }