1
0
dust/dust-lang/src/abstract_tree.rs

211 lines
6.8 KiB
Rust
Raw Normal View History

2024-08-09 01:59:09 +00:00
//! In-memory representation of a Dust program.
use std::{
2024-08-07 15:38:08 +00:00
collections::{HashMap, VecDeque},
fmt::{self, Display, Formatter},
};
2024-08-05 03:11:04 +00:00
use serde::{Deserialize, Serialize};
use crate::{BuiltInFunction, Identifier, Span, Type, Value};
2024-08-09 01:59:09 +00:00
/// In-memory representation of a Dust program.
2024-08-07 15:38:08 +00:00
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct AbstractSyntaxTree {
pub nodes: VecDeque<Node<Statement>>,
2024-08-07 15:38:08 +00:00
}
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Node<T> {
pub inner: T,
pub position: Span,
2024-08-05 03:11:04 +00:00
}
impl<T> Node<T> {
pub fn new(inner: T, position: Span) -> Self {
Self { inner, position }
2024-08-05 03:11:04 +00:00
}
}
impl<T: Display> Display for Node<T> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.inner)
}
}
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Statement {
2024-08-05 03:11:04 +00:00
// Top-level statements
Assign(Box<Node<Statement>>, Box<Node<Statement>>),
// Math expressions
Add(Box<Node<Statement>>, Box<Node<Statement>>),
Subtract(Box<Node<Statement>>, Box<Node<Statement>>),
Multiply(Box<Node<Statement>>, Box<Node<Statement>>),
2024-08-05 03:11:04 +00:00
// Function calls
BuiltInFunctionCall {
function: BuiltInFunction,
type_arguments: Option<Vec<Node<Statement>>>,
value_arguments: Option<Vec<Node<Statement>>>,
},
FunctionCall {
function: Box<Node<Statement>>,
type_arguments: Option<Vec<Node<Statement>>>,
value_arguments: Option<Vec<Node<Statement>>>,
},
// Comparison expressions
Comparison(
Box<Node<Statement>>,
Node<ComparisonOperator>,
Box<Node<Statement>>,
),
// Property access
PropertyAccess(Box<Node<Statement>>, Box<Node<Statement>>),
// Value collections
List(Vec<Node<Statement>>),
2024-08-05 03:11:04 +00:00
// Hard-coded values
Constant(Value),
Identifier(Identifier),
}
impl Statement {
pub fn expected_type(&self, variables: &HashMap<Identifier, Value>) -> Option<Type> {
match self {
Statement::Add(left, _) => left.inner.expected_type(variables),
Statement::Assign(_, _) => None,
Statement::BuiltInFunctionCall { function, .. } => function.expected_type(),
Statement::Comparison(_, _, _) => Some(Type::Boolean),
Statement::Constant(value) => Some(value.r#type(variables)),
Statement::FunctionCall { function, .. } => function.inner.expected_type(variables),
Statement::Identifier(identifier) => variables
.get(identifier)
.map(|value| value.r#type(variables)),
Statement::List(nodes) => nodes
.first()
.map(|node| node.inner.expected_type(variables))
.flatten(),
Statement::Multiply(left, _) => left.inner.expected_type(variables),
Statement::PropertyAccess(_, _) => None,
Statement::Subtract(left, _) => left.inner.expected_type(variables),
}
}
}
impl Display for Statement {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
2024-08-07 14:41:27 +00:00
Statement::Assign(left, right) => write!(f, "{left} = {right}"),
Statement::Add(left, right) => write!(f, "{left} + {right}"),
Statement::BuiltInFunctionCall {
function,
type_arguments: type_parameters,
value_arguments: value_parameters,
} => {
write!(f, "{function}")?;
if let Some(type_parameters) = type_parameters {
write!(f, "<")?;
for (i, type_parameter) in type_parameters.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{type_parameter}")?;
}
write!(f, ">")?;
}
write!(f, "(")?;
if let Some(value_parameters) = value_parameters {
for (i, value_parameter) in value_parameters.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{value_parameter}")?;
}
}
write!(f, ")")
}
Statement::Comparison(left, operator, right) => write!(f, "{left} {operator} {right}"),
Statement::Constant(value) => write!(f, "{value}"),
Statement::FunctionCall {
function,
type_arguments: type_parameters,
value_arguments: value_parameters,
} => {
write!(f, "{function}")?;
if let Some(type_parameters) = type_parameters {
write!(f, "<")?;
for (i, type_parameter) in type_parameters.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{type_parameter}")?;
}
write!(f, ">")?;
}
write!(f, "(")?;
if let Some(value_parameters) = value_parameters {
for (i, value_parameter) in value_parameters.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{value_parameter}")?;
}
}
write!(f, ")")
}
Statement::Identifier(identifier) => write!(f, "{identifier}"),
Statement::List(nodes) => {
write!(f, "[")?;
for (i, node) in nodes.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
2024-08-07 14:41:27 +00:00
write!(f, "{node}")?;
}
write!(f, "]")
}
2024-08-07 14:41:27 +00:00
Statement::Multiply(left, right) => write!(f, "{left} * {right}"),
Statement::PropertyAccess(left, right) => write!(f, "{left}.{right}"),
Statement::Subtract(left, right) => write!(f, "{left} - {right}"),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum ComparisonOperator {
GreaterThan,
GreaterThanOrEqual,
LessThan,
LessThanOrEqual,
}
impl Display for ComparisonOperator {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
ComparisonOperator::GreaterThan => write!(f, ">"),
ComparisonOperator::GreaterThanOrEqual => write!(f, ">="),
ComparisonOperator::LessThan => write!(f, "<"),
ComparisonOperator::LessThanOrEqual => write!(f, "<="),
}
}
}