schala/schala-lang/language/src/ast/mod.rs

296 lines
7.5 KiB
Rust
Raw Normal View History

2021-10-19 22:24:27 -07:00
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::enum_variant_names)]
2018-11-16 14:06:04 -08:00
2021-10-28 02:00:37 -07:00
use std::{
convert::{AsRef, From},
fmt,
2021-10-28 02:00:37 -07:00
rc::Rc,
};
mod operators;
2021-10-28 02:00:37 -07:00
mod visitor;
mod visualize;
2021-10-28 02:00:37 -07:00
pub use operators::{BinOp, PrefixOp};
2021-10-26 11:37:43 -07:00
pub use visitor::*;
2021-10-28 02:00:37 -07:00
use crate::{
derivative::Derivative,
identifier::{define_id_kind, Id},
tokenizing::Location,
};
define_id_kind!(ASTItem);
2019-09-18 01:51:23 -07:00
pub type ItemId = Id<ASTItem>;
2019-09-18 09:56:11 -07:00
2019-09-18 02:15:45 -07:00
#[derive(Derivative, Debug)]
#[derivative(PartialEq)]
2019-09-11 19:06:00 -07:00
pub struct AST {
2021-10-28 02:00:37 -07:00
#[derivative(PartialEq = "ignore")]
pub id: ItemId,
pub statements: Block,
2019-09-11 19:06:00 -07:00
}
2018-06-04 19:25:40 -07:00
impl fmt::Display for AST {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", visualize::render_ast(self))
}
}
2019-09-18 10:07:20 -07:00
#[derive(Derivative, Debug, Clone)]
#[derivative(PartialEq)]
2019-09-17 02:25:11 -07:00
pub struct Statement {
2021-10-28 02:00:37 -07:00
#[derivative(PartialEq = "ignore")]
pub id: ItemId,
#[derivative(PartialEq = "ignore")]
pub location: Location,
pub kind: StatementKind,
2019-09-17 02:25:11 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub enum StatementKind {
2021-10-28 02:00:37 -07:00
Expression(Expression),
Declaration(Declaration),
Import(ImportSpecifier),
2021-11-01 00:14:15 -07:00
Flow(FlowControl),
}
#[derive(Debug, Clone, PartialEq)]
pub enum FlowControl {
Continue,
Break,
Return(Option<Expression>),
2018-06-04 19:25:40 -07:00
}
2021-10-26 14:05:27 -07:00
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Block {
2021-10-28 02:00:37 -07:00
pub statements: Vec<Statement>,
2021-10-26 14:05:27 -07:00
}
impl From<Vec<Statement>> for Block {
fn from(statements: Vec<Statement>) -> Self {
Self { statements }
}
}
impl From<Statement> for Block {
fn from(statement: Statement) -> Self {
Self { statements: vec![statement] }
}
}
impl AsRef<[Statement]> for Block {
fn as_ref(&self) -> &[Statement] {
self.statements.as_ref()
}
}
2018-06-04 19:25:40 -07:00
pub type ParamName = Rc<String>;
2019-06-16 14:56:52 -07:00
2019-09-19 01:34:21 -07:00
#[derive(Debug, Derivative, Clone)]
#[derivative(PartialEq)]
pub struct QualifiedName {
2021-10-28 02:00:37 -07:00
#[derivative(PartialEq = "ignore")]
pub id: ItemId,
pub components: Vec<Rc<String>>,
2019-09-19 01:34:21 -07:00
}
2019-08-31 23:39:01 -07:00
impl fmt::Display for QualifiedName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.components[..] {
[] => write!(f, "[<empty>]"),
[name] => write!(f, "{}", name),
[name, rest @ ..] => {
write!(f, "{}", name)?;
for c in rest {
write!(f, "::{}", c)?;
}
Ok(())
}
}
}
}
2019-06-16 14:56:52 -07:00
#[derive(Debug, PartialEq, Clone)]
pub struct FormalParam {
2021-10-28 02:00:37 -07:00
pub name: ParamName,
pub default: Option<Expression>,
pub anno: Option<TypeIdentifier>,
2019-06-16 14:56:52 -07:00
}
2018-06-04 19:25:40 -07:00
#[derive(Debug, PartialEq, Clone)]
pub enum Declaration {
2021-10-28 02:00:37 -07:00
FuncSig(Signature),
FuncDecl(Signature, Block),
TypeDecl { name: TypeSingletonName, body: TypeBody, mutable: bool },
//TODO TypeAlias `original` needs to be a more complex type definition
2021-10-28 02:00:37 -07:00
TypeAlias { alias: Rc<String>, original: Rc<String> },
Binding { name: Rc<String>, constant: bool, type_anno: Option<TypeIdentifier>, expr: Expression },
Impl { type_name: TypeIdentifier, interface_name: Option<TypeSingletonName>, block: Vec<Declaration> },
Interface { name: Rc<String>, signatures: Vec<Signature> },
2021-11-02 16:56:12 -07:00
//TODO need to limit the types of statements that can be annotated
Annotation { name: Rc<String>, arguments: Vec<Expression>, inner: Box<Statement> },
2021-11-02 18:34:15 -07:00
Module { name: Rc<String>, items: Block },
2018-06-04 19:25:40 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub struct Signature {
2021-10-28 02:00:37 -07:00
pub name: Rc<String>,
pub operator: bool,
pub params: Vec<FormalParam>,
pub type_anno: Option<TypeIdentifier>,
2018-06-04 19:25:40 -07:00
}
//TODO I can probably get rid of TypeBody
2018-06-04 19:25:40 -07:00
#[derive(Debug, PartialEq, Clone)]
2021-10-31 02:30:38 -07:00
pub enum TypeBody {
Variants(Vec<Variant>),
ImmediateRecord(ItemId, Vec<(Rc<String>, TypeIdentifier)>),
}
2018-06-04 19:25:40 -07:00
2021-10-21 20:00:26 -07:00
#[derive(Debug, Derivative, Clone)]
#[derivative(PartialEq)]
2021-10-21 19:53:50 -07:00
pub struct Variant {
2021-10-28 02:00:37 -07:00
#[derivative(PartialEq = "ignore")]
2021-10-21 20:00:26 -07:00
pub id: ItemId,
2021-10-21 19:53:50 -07:00
pub name: Rc<String>,
pub kind: VariantKind,
2021-10-28 02:00:37 -07:00
}
2021-10-21 19:53:50 -07:00
#[derive(Debug, PartialEq, Clone)]
pub enum VariantKind {
UnitStruct,
TupleStruct(Vec<TypeIdentifier>),
Record(Vec<(Rc<String>, TypeIdentifier)>),
2021-10-28 02:00:37 -07:00
}
2018-06-04 19:25:40 -07:00
2019-09-18 14:15:05 -07:00
#[derive(Debug, Derivative, Clone)]
#[derivative(PartialEq)]
pub struct Expression {
2021-10-28 02:00:37 -07:00
#[derivative(PartialEq = "ignore")]
pub id: ItemId,
pub kind: ExpressionKind,
//TODO this should only allow singletons, not tuples
2021-10-28 02:00:37 -07:00
pub type_anno: Option<TypeIdentifier>,
}
impl Expression {
2021-10-28 02:00:37 -07:00
pub fn new(id: ItemId, kind: ExpressionKind) -> Expression {
Expression { id, kind, type_anno: None }
}
}
2018-11-16 14:06:04 -08:00
2018-06-04 19:25:40 -07:00
#[derive(Debug, PartialEq, Clone)]
2018-10-18 13:27:09 -07:00
pub enum TypeIdentifier {
2021-10-28 02:00:37 -07:00
Tuple(Vec<TypeIdentifier>),
Singleton(TypeSingletonName),
2018-06-04 19:25:40 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub struct TypeSingletonName {
2021-10-28 02:00:37 -07:00
pub name: Rc<String>,
pub params: Vec<TypeIdentifier>,
2018-06-04 19:25:40 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub enum ExpressionKind {
2021-10-28 02:00:37 -07:00
NatLiteral(u64),
FloatLiteral(f64),
StringLiteral(Rc<String>),
BoolLiteral(bool),
BinExp(BinOp, Box<Expression>, Box<Expression>),
PrefixExp(PrefixOp, Box<Expression>),
TupleLiteral(Vec<Expression>),
Value(QualifiedName),
NamedStruct { name: QualifiedName, fields: Vec<(Rc<String>, Expression)> },
Call { f: Box<Expression>, arguments: Vec<InvocationArgument> },
Index { indexee: Box<Expression>, indexers: Vec<Expression> },
IfExpression { discriminator: Option<Box<Expression>>, body: Box<IfExpressionBody> },
WhileExpression { condition: Option<Box<Expression>>, body: Block },
ForExpression { enumerators: Vec<Enumerator>, body: Box<ForBody> },
Lambda { params: Vec<FormalParam>, type_anno: Option<TypeIdentifier>, body: Block },
Access { name: Rc<String>, expr: Box<Expression> },
2021-10-28 02:00:37 -07:00
ListLiteral(Vec<Expression>),
2018-06-04 19:25:40 -07:00
}
2018-11-16 14:06:04 -08:00
#[derive(Debug, PartialEq, Clone)]
pub enum InvocationArgument {
2021-10-28 02:00:37 -07:00
Positional(Expression),
Keyword { name: Rc<String>, expr: Expression },
Ignored,
}
#[derive(Debug, PartialEq, Clone)]
pub enum IfExpressionBody {
2021-10-28 02:00:37 -07:00
SimpleConditional { then_case: Block, else_case: Option<Block> },
SimplePatternMatch { pattern: Pattern, then_case: Block, else_case: Option<Block> },
CondList(Vec<ConditionArm>),
}
#[derive(Debug, PartialEq, Clone)]
pub struct ConditionArm {
2021-10-28 02:00:37 -07:00
pub condition: Condition,
pub guard: Option<Expression>,
pub body: Block,
2018-07-13 21:50:38 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub enum Condition {
2021-10-28 02:00:37 -07:00
Pattern(Pattern),
TruncatedOp(BinOp, Expression),
2021-11-04 21:11:19 -07:00
//Expression(Expression), //I'm pretty sure I don't actually want this
2021-10-28 02:00:37 -07:00
Else,
}
#[derive(Debug, PartialEq, Clone)]
2018-07-01 01:26:19 -07:00
pub enum Pattern {
2021-10-28 02:00:37 -07:00
Ignored,
TuplePattern(Vec<Pattern>),
Literal(PatternLiteral),
TupleStruct(QualifiedName, Vec<Pattern>),
Record(QualifiedName, Vec<(Rc<String>, Pattern)>),
VarOrName(QualifiedName),
2018-07-01 01:26:19 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub enum PatternLiteral {
2021-10-28 02:00:37 -07:00
NumPattern { neg: bool, num: ExpressionKind },
StringPattern(Rc<String>),
BoolPattern(bool),
}
2018-06-04 19:25:40 -07:00
#[derive(Debug, PartialEq, Clone)]
pub struct Enumerator {
2021-11-05 12:52:41 -07:00
pub id: Rc<String>, //TODO rename this field
2021-10-28 02:00:37 -07:00
pub generator: Expression,
2018-06-04 19:25:40 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub enum ForBody {
2021-10-28 02:00:37 -07:00
MonadicReturn(Expression),
StatementBlock(Block),
2018-06-04 19:25:40 -07:00
}
2019-09-21 02:30:28 -07:00
#[derive(Debug, Derivative, Clone)]
#[derivative(PartialEq)]
pub struct ImportSpecifier {
2021-10-28 02:00:37 -07:00
#[derivative(PartialEq = "ignore")]
pub id: ItemId,
pub path_components: Vec<Rc<String>>,
pub imported_names: ImportedNames,
2019-09-21 02:30:28 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub enum ImportedNames {
2021-10-28 02:00:37 -07:00
All,
LastOfPath,
List(Vec<Rc<String>>),
2019-09-21 02:30:28 -07:00
}
2019-10-22 03:15:14 -07:00
#[derive(Debug, PartialEq, Clone)]
pub struct ModuleSpecifier {
2021-10-28 02:00:37 -07:00
pub name: Rc<String>,
pub contents: Block,
2019-10-22 03:15:14 -07:00
}