Skip to content

Commit

Permalink
Split up the parser/ast file into its own ast module.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivorforce committed Apr 28, 2024
1 parent 68cca82 commit c55b292
Show file tree
Hide file tree
Showing 29 changed files with 478 additions and 418 deletions.
24 changes: 24 additions & 0 deletions src/ast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
pub use array::{Array, ArrayArgument};
pub use block::Block;
pub use conformance::TraitConformanceDeclaration;
pub use decorated::Decorated;
pub use expression::Expression;
pub use function::{Function, FunctionInterface};
pub use statement::Statement;
pub use string::StringPart;
pub use struct_::{Struct, StructArgument};
pub use term::{IfThenElse, Term};
pub use trait_::TraitDefinition;

mod array;
mod block;
mod struct_;
mod trait_;
mod conformance;
mod statement;
mod expression;
mod term;
mod string;
mod decorated;
mod function;

38 changes: 38 additions & 0 deletions src/ast/array.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::fmt::{Display, Error, Formatter};

use crate::ast::Expression;
use crate::util::fmt::write_separated_display;
use crate::util::position::Positioned;

#[derive(Eq, PartialEq, Clone)]
pub struct Array { pub arguments: Vec<Box<Positioned<ArrayArgument>>> }

impl Array {
pub fn empty() -> Array {
Array { arguments: vec![] }
}
}

impl Display for Array {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "[")?;
write_separated_display(f, ", ", self.arguments.iter().map(|f| &f.value))?;
write!(f, "]")
}
}

#[derive(Eq, PartialEq, Clone)]
pub struct ArrayArgument {
pub key: Option<Expression>,
pub value: Expression,
pub type_declaration: Option<Expression>,
}

impl Display for ArrayArgument {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
if let Some(key) = &self.key {
write!(fmt, "{}: ", key)?;
}
write!(fmt, "{}", self.value)
}
}
17 changes: 17 additions & 0 deletions src/ast/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use std::fmt::{Display, Error, Formatter};

use crate::ast::decorated::Decorated;
use crate::ast::Statement;
use crate::util::fmt::write_separated_display;
use crate::util::position::Positioned;

#[derive(Eq, PartialEq, Clone)]
pub struct Block {
pub statements: Vec<Box<Decorated<Positioned<Statement>>>>
}

impl Display for Block {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
write_separated_display(fmt, "\n", self.statements.iter())
}
}
17 changes: 17 additions & 0 deletions src/ast/conformance.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use std::fmt::{Display, Formatter};

use crate::ast::Block;
use crate::ast::expression::Expression;

#[derive(Eq, PartialEq, Clone)]
pub struct TraitConformanceDeclaration {
pub declared_for: Expression,
pub declared: Expression,
pub block: Box<Block>,
}

impl Display for TraitConformanceDeclaration {
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
write!(fmt, "declare {} is {} {{}} :: {{\n{}}}", self.declared_for, self.declared, self.block)
}
}
56 changes: 56 additions & 0 deletions src/ast/decorated.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::fmt::{Display, Formatter};

use crate::ast::{Array, Expression};
use crate::error::{RResult, RuntimeError, TryCollectMany};

#[derive(PartialEq, Eq, Clone)]
pub struct Decorated<T> {
pub decorations: Array,
pub value: T,
}

impl<V> Decorated<V> {
pub fn with_value<N>(&self, n: N) -> Decorated<N> {
Decorated {
decorations: self.decorations.clone(),
value: n,
}
}

pub fn undecorated(t: V) -> Decorated<V> {
Decorated {
decorations: Array { arguments: vec![] },
value: t,
}
}

pub fn decorations_as_vec(&self) -> RResult<Vec<&Expression>> {
return self.decorations.arguments.iter().map(|d| {
if d.value.key.is_some() {
return Err(RuntimeError::error("Decorations cannot have keys.").to_array())
}
if d.value.type_declaration.is_some() {
return Err(RuntimeError::error("Decorations cannot have type declarations.").to_array())
}

Ok(&d.value.value)
}).try_collect_many()
}

pub fn no_decorations(&self) -> RResult<()> {
if !self.decorations.arguments.is_empty() {
return Err(RuntimeError::error("Decorations are not supported in this context.").to_array())
}

return Ok(())
}
}

impl<V: Display> Display for Decorated<V> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
if self.decorations.arguments.is_empty() {
return write!(fmt, "{}", self.value)
}
write!(fmt, "!{}\n{}", self.decorations, self.value)
}
}
47 changes: 47 additions & 0 deletions src/ast/expression.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use std::fmt::{Display, Formatter};
use std::ops::{Deref, DerefMut};

use crate::ast::term::Term;
use crate::error::{RResult, TryCollectMany};
use crate::util::fmt::write_separated_display;
use crate::util::position::Positioned;

#[derive(Eq, PartialEq, Clone)]
pub struct Expression(Vec<Box<Positioned<Term>>>);

impl Expression {
pub fn no_errors(&self) -> RResult<()> {
self.iter()
.map(|t| match &t.value {
Term::Error(e) => Err(e.clone().to_array()),
_ => Ok(())
})
.try_collect_many()
}
}

impl Deref for Expression {
type Target = Vec<Box<Positioned<Term>>>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl DerefMut for Expression {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl From<Vec<Box<Positioned<Term>>>> for Expression {
fn from(value: Vec<Box<Positioned<Term>>>) -> Self {
Expression(value)
}
}

impl Display for Expression {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write_separated_display(f, " ", self.0.iter().map(|b| &b.value))
}
}
38 changes: 38 additions & 0 deletions src/ast/function.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::fmt::{Display, Error, Formatter};

use crate::ast::expression::Expression;

#[derive(Eq, PartialEq, Clone)]
pub struct Function {
pub interface: FunctionInterface,
pub body: Option<Expression>,
}

impl Display for Function {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
write!(fmt, "def {}", self.interface)?;

if let Some(body) = &self.body {
write!(fmt, " :: {}", body)?;
}
return Ok(())
}
}

#[derive(Eq, PartialEq, Clone)]
pub struct FunctionInterface {
pub expression: Expression,
pub return_type: Option<Expression>,
}

impl Display for FunctionInterface {
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
write!(fmt, "{}", &self.expression)?;

if let Some(return_type) = &self.return_type {
write!(fmt, " -> {}", return_type)?;
}

Ok(())
}
}
50 changes: 50 additions & 0 deletions src/ast/statement.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use std::fmt::{Display, Error, Formatter};

use crate::ast::conformance::TraitConformanceDeclaration;
use crate::ast::expression::Expression;
use crate::ast::function::Function;
use crate::ast::trait_::TraitDefinition;
use crate::program::allocation::Mutability;

#[derive(Eq, PartialEq, Clone)]
pub enum Statement {
VariableDeclaration {
mutability: Mutability,
identifier: String,
type_declaration: Option<Box<Expression>>,
assignment: Option<Box<Expression>>
},
VariableUpdate { target: Box<Expression>, new_value: Box<Expression> },
Expression(Box<Expression>),
Return(Option<Box<Expression>>),
FunctionDeclaration(Box<Function>),
Trait(Box<TraitDefinition>),
Conformance(Box<TraitConformanceDeclaration>),
}

impl Display for Statement {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
match self {
Statement::VariableDeclaration { mutability, identifier, type_declaration, assignment} => {
let mutability_string = mutability.variable_declaration_keyword();
write!(fmt, "{} {}", mutability_string, identifier)?;
if let Some(type_declaration) = type_declaration {
write!(fmt, " '{}", type_declaration)?;
}
if let Some(assignment) = assignment {
write!(fmt, " = {}", assignment)?;
}
Ok(())
},
Statement::VariableUpdate { target, new_value } => {
write!(fmt, "upd {} = {}", target, new_value)
},
Statement::Return(Some(expression)) => write!(fmt, "return {}", expression),
Statement::Return(None) => write!(fmt, "return"),
Statement::Expression(ref expression) => write!(fmt, "{}", expression),
Statement::FunctionDeclaration(function) => write!(fmt, "{}", function),
Statement::Trait(trait_) => write!(fmt, "{}", trait_),
Statement::Conformance(conformance) => write!(fmt, "{}", conformance),
}
}
}
18 changes: 18 additions & 0 deletions src/ast/string.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use std::fmt::{Display, Formatter};

use crate::ast::Struct;

#[derive(PartialEq, Eq, Clone)]
pub enum StringPart {
Literal(String),
Object(Box<Struct>),
}

impl Display for StringPart {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
StringPart::Literal(s) => write!(f, "{}", s),
StringPart::Object(struct_) => write!(f, "{}", struct_),
}
}
}
36 changes: 36 additions & 0 deletions src/ast/struct_.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use std::fmt::{Display, Error, Formatter};

use crate::ast::Expression;
use crate::program::functions::ParameterKey;
use crate::util::fmt::write_separated_display;
use crate::util::position::Positioned;

#[derive(Eq, PartialEq, Clone)]
pub struct Struct { pub arguments: Vec<Box<Positioned<StructArgument>>> }

impl Struct {
pub fn empty() -> Struct {
Struct { arguments: vec![] }
}
}

impl Display for Struct {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "(")?;
write_separated_display(f, ", ", self.arguments.iter().map(|f| &f.value))?;
write!(f, ")")
}
}

#[derive(Eq, PartialEq, Clone)]
pub struct StructArgument {
pub key: ParameterKey,
pub value: Expression,
pub type_declaration: Option<Expression>,
}

impl Display for StructArgument {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
write!(fmt, "{}{}", self.key, self.value)
}
}
Loading

0 comments on commit c55b292

Please sign in to comment.