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

325 lines
6.6 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
use std::rc::Rc;
2021-10-26 14:05:27 -07:00
use std::convert::{AsRef, From};
2019-09-25 18:41:07 -07:00
mod visitor;
mod operators;
pub use operators::{PrefixOp, BinOp};
2021-10-26 11:37:43 -07:00
pub use visitor::*;
use crate::derivative::Derivative;
use crate::tokenizing::Location;
use crate::identifier::{Id, define_id_kind};
define_id_kind!(ASTItem);
2019-09-18 01:51:23 -07:00
/*
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
pub struct ASTItem;
impl IdKind for ASTItem {
fn tag() -> &'static str { "ASTItem" }
}
*/
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 {
2019-09-18 02:15:45 -07:00
#[derivative(PartialEq="ignore")]
pub id: ItemId,
2021-10-26 14:05:27 -07:00
pub statements: Block,
2019-09-11 19:06:00 -07:00
}
2018-06-04 19:25:40 -07:00
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 {
2019-09-18 10:07:20 -07:00
#[derivative(PartialEq="ignore")]
pub id: ItemId,
#[derivative(PartialEq="ignore")]
pub location: Location,
2019-09-17 02:25:11 -07:00
pub kind: StatementKind,
}
#[derive(Debug, PartialEq, Clone)]
pub enum StatementKind {
Expression(Expression),
2019-09-21 02:30:28 -07:00
Declaration(Declaration),
Import(ImportSpecifier),
2019-10-22 03:15:14 -07:00
Module(ModuleSpecifier),
2018-06-04 19:25:40 -07:00
}
2021-10-26 14:05:27 -07:00
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Block {
pub statements: Vec<Statement>
}
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 {
#[derivative(PartialEq="ignore")]
pub id: ItemId,
pub components: Vec<Rc<String>>,
}
2019-08-31 23:39:01 -07:00
2019-06-16 14:56:52 -07:00
#[derive(Debug, PartialEq, Clone)]
pub struct FormalParam {
pub name: ParamName,
pub default: Option<Expression>,
2019-06-16 14:56:52 -07:00
pub anno: Option<TypeIdentifier>
}
2018-06-04 19:25:40 -07:00
#[derive(Debug, PartialEq, Clone)]
pub enum Declaration {
FuncSig(Signature),
FuncDecl(Signature, Block),
2018-07-12 02:07:52 -07:00
TypeDecl {
name: TypeSingletonName,
body: TypeBody,
mutable: bool
},
2019-09-28 02:42:18 -07:00
//TODO this needs to be more sophisticated
TypeAlias {
alias: Rc<String>,
original: Rc<String>,
},
2018-06-04 19:25:40 -07:00
Binding {
name: Rc<String>,
constant: bool,
type_anno: Option<TypeIdentifier>,
expr: Expression,
2018-06-04 19:25:40 -07:00
},
Impl {
2018-10-18 13:27:09 -07:00
type_name: TypeIdentifier,
interface_name: Option<TypeSingletonName>,
2018-06-04 19:25:40 -07:00
block: Vec<Declaration>,
},
Interface {
name: Rc<String>,
signatures: Vec<Signature>
2021-10-21 11:32:14 -07:00
},
Annotation {
name: Rc<String>,
arguments: Vec<Expression>
2018-06-04 19:25:40 -07:00
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct Signature {
pub name: Rc<String>,
pub operator: bool,
2018-06-04 19:25:40 -07:00
pub params: Vec<FormalParam>,
2018-10-18 13:27:09 -07:00
pub type_anno: Option<TypeIdentifier>,
2018-06-04 19:25:40 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub struct TypeBody(pub Vec<Variant>);
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-21 20:00:26 -07:00
#[derivative(PartialEq="ignore")]
pub id: ItemId,
2021-10-21 19:53:50 -07:00
pub name: Rc<String>,
pub kind: VariantKind,
}
#[derive(Debug, PartialEq, Clone)]
pub enum VariantKind {
UnitStruct,
TupleStruct(Vec<TypeIdentifier>),
Record(Vec<(Rc<String>, TypeIdentifier)>),
}
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 {
2019-09-18 14:15:05 -07:00
#[derivative(PartialEq="ignore")]
pub id: ItemId,
pub kind: ExpressionKind,
pub type_anno: Option<TypeIdentifier>
}
impl Expression {
pub fn new(id: ItemId, kind: ExpressionKind) -> Expression {
Expression { id, kind, type_anno: None }
}
2018-06-04 19:25:40 -07:00
2021-10-13 23:45:54 -07:00
#[cfg(test)]
pub fn with_anno(id: ItemId, kind: ExpressionKind, type_anno: TypeIdentifier) -> Expression {
Expression { id, kind, type_anno: Some(type_anno) }
}
}
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 {
Tuple(Vec<TypeIdentifier>),
2018-06-04 19:25:40 -07:00
Singleton(TypeSingletonName)
}
#[derive(Debug, PartialEq, Clone)]
pub struct TypeSingletonName {
pub name: Rc<String>,
2018-10-18 13:27:09 -07:00
pub params: Vec<TypeIdentifier>,
2018-06-04 19:25:40 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub enum ExpressionKind {
2018-06-04 19:25:40 -07:00
NatLiteral(u64),
FloatLiteral(f64),
StringLiteral(Rc<String>),
BoolLiteral(bool),
BinExp(BinOp, Box<Expression>, Box<Expression>),
PrefixExp(PrefixOp, Box<Expression>),
TupleLiteral(Vec<Expression>),
2019-09-20 01:57:48 -07:00
Value(QualifiedName),
2018-06-04 19:25:40 -07:00
NamedStruct {
name: QualifiedName,
fields: Vec<(Rc<String>, Expression)>,
2018-06-04 19:25:40 -07:00
},
Call {
f: Box<Expression>,
arguments: Vec<InvocationArgument>,
2018-06-04 19:25:40 -07:00
},
Index {
indexee: Box<Expression>,
indexers: Vec<Expression>,
2018-06-04 19:25:40 -07:00
},
IfExpression {
discriminator: Option<Box<Expression>>,
2019-10-10 10:34:54 -07:00
body: Box<IfExpressionBody>,
},
2018-06-04 19:25:40 -07:00
WhileExpression {
condition: Option<Box<Expression>>,
2018-06-04 19:25:40 -07:00
body: Block,
},
ForExpression {
enumerators: Vec<Enumerator>,
body: Box<ForBody>,
},
Lambda {
params: Vec<FormalParam>,
2018-11-05 19:10:34 -08:00
type_anno: Option<TypeIdentifier>,
2018-06-04 19:25:40 -07:00
body: Block,
},
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 {
Positional(Expression),
Keyword {
name: Rc<String>,
expr: Expression,
},
Ignored
}
#[derive(Debug, PartialEq, Clone)]
pub enum IfExpressionBody {
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 {
pub condition: Condition,
pub guard: Option<Expression>,
2018-07-13 21:50:38 -07:00
pub body: Block,
}
#[derive(Debug, PartialEq, Clone)]
pub enum Condition {
Pattern(Pattern),
2019-10-10 10:34:54 -07:00
TruncatedOp(BinOp, Expression),
Expression(Expression),
Else,
}
#[derive(Debug, PartialEq, Clone)]
2018-07-01 01:26:19 -07:00
pub enum Pattern {
2018-07-10 03:43:14 -07:00
Ignored,
2018-07-01 01:26:19 -07:00
TuplePattern(Vec<Pattern>),
Literal(PatternLiteral),
2019-09-20 02:03:10 -07:00
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 {
2018-08-21 19:57:45 -07:00
NumPattern {
neg: bool,
num: ExpressionKind,
2018-08-21 19:57:45 -07:00
},
2018-07-01 01:26:19 -07:00
StringPattern(Rc<String>),
BoolPattern(bool),
}
2018-06-04 19:25:40 -07:00
#[derive(Debug, PartialEq, Clone)]
pub struct Enumerator {
pub id: Rc<String>,
2019-09-20 02:05:57 -07:00
pub generator: Expression,
2018-06-04 19:25:40 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub enum ForBody {
2019-09-20 02:05:57 -07:00
MonadicReturn(Expression),
2018-06-04 19:25:40 -07:00
StatementBlock(Block),
}
2019-09-21 02:30:28 -07:00
#[derive(Debug, Derivative, Clone)]
#[derivative(PartialEq)]
pub struct ImportSpecifier {
#[derivative(PartialEq="ignore")]
pub id: ItemId,
pub path_components: Vec<Rc<String>>,
pub imported_names: ImportedNames
}
#[derive(Debug, PartialEq, Clone)]
pub enum ImportedNames {
All,
LastOfPath,
List(Vec<Rc<String>>)
}
2019-10-22 03:15:14 -07:00
#[derive(Debug, PartialEq, Clone)]
pub struct ModuleSpecifier {
pub name: Rc<String>,
2021-10-26 14:05:27 -07:00
pub contents: Block,
2019-10-22 03:15:14 -07:00
}