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

311 lines
6.5 KiB
Rust
Raw Normal View History

2018-06-04 19:25:40 -07:00
use std::rc::Rc;
2018-11-16 14:06:04 -08:00
use std::convert::From;
2019-09-18 02:15:45 -07:00
use crate::derivative::Derivative;
2019-09-02 14:13:53 -07:00
use crate::symbol_table::FullyQualifiedSymbolName;
2018-06-04 19:25:40 -07:00
mod operators;
pub use operators::*;
2019-09-18 01:51:23 -07:00
/// An abstract identifier for an AST node
2019-09-19 02:58:52 -07:00
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
2019-09-18 01:51:23 -07:00
pub struct ItemId {
idx: u32,
}
impl ItemId {
2019-09-18 09:56:11 -07:00
fn new(n: u32) -> ItemId {
2019-09-18 01:51:23 -07:00
ItemId { idx: n }
}
}
2019-09-18 09:56:11 -07:00
pub struct ItemIdStore {
last_idx: u32
}
impl ItemIdStore {
pub fn new() -> ItemIdStore {
ItemIdStore { last_idx: 0 }
}
/// Always returns an ItemId with internal value zero
2019-09-18 14:15:05 -07:00
#[cfg(test)]
2019-09-18 09:56:11 -07:00
pub fn new_id() -> ItemId {
ItemId { idx: 0 }
}
/// This limits the size of the AST to 2^32 tree elements
pub fn fresh(&mut self) -> ItemId {
let idx = self.last_idx;
self.last_idx += 1;
ItemId::new(idx)
}
}
2019-01-04 22:58:25 -08:00
#[derive(Clone, Debug, PartialEq)]
2019-02-21 01:49:15 -08:00
pub struct Meta<T> {
2019-09-07 19:08:50 -07:00
pub n: T,
pub fqsn: Option<FullyQualifiedSymbolName>
2018-11-20 03:21:10 -08:00
}
2019-02-21 01:49:15 -08:00
impl<T> Meta<T> {
pub fn new(n: T) -> Meta<T> {
2019-09-02 14:13:53 -07:00
Meta { n,
fqsn: None,
}
2019-01-04 22:58:25 -08:00
}
pub fn node(&self) -> &T {
2018-11-20 03:21:10 -08:00
&self.n
}
2019-09-03 02:19:37 -07:00
pub fn mut_node(&mut self) -> &mut T {
&mut self.n
}
2018-11-20 03:21:10 -08:00
}
2019-01-04 22:58:25 -08:00
//TODO this PartialEq is here to make tests work - find a way to make it not necessary
#[derive(Clone, Debug, Default, PartialEq)]
2019-01-05 15:35:51 -08:00
struct SourceMap {
2018-11-20 03:21:10 -08:00
}
2019-02-21 01:49:15 -08:00
impl From<Expression> for Meta<Expression> {
fn from(expr: Expression) -> Meta<Expression> {
2019-09-02 14:13:53 -07:00
Meta::new(expr)
2019-01-05 15:47:44 -08: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,
2019-09-11 19:06:00 -07:00
pub statements: Vec<Meta<Statement>>
}
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,
2019-09-17 02:25:11 -07:00
pub kind: StatementKind,
}
#[derive(Debug, PartialEq, Clone)]
pub enum StatementKind {
Expression(Meta<Expression>),
2019-09-03 02:19:37 -07:00
Declaration(Declaration), //TODO Declaration should also be Meta-wrapped; only Expression and Declaration are Meta-wrapped maybe?
2018-06-04 19:25:40 -07:00
}
2019-02-21 01:49:15 -08:00
pub type Block = Vec<Meta<Statement>>;
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,
2019-09-02 14:13:53 -07:00
pub default: Option<Meta<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
},
2018-06-04 19:25:40 -07:00
TypeAlias(Rc<String>, Rc<String>), //should have TypeSingletonName in it, or maybe just String, not sure
Binding {
name: Rc<String>,
constant: bool,
type_anno: Option<TypeIdentifier>,
expr: Meta<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>
}
}
#[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>);
#[derive(Debug, PartialEq, Clone)]
pub enum Variant {
UnitStruct(Rc<String>),
2018-10-18 13:27:09 -07:00
TupleStruct(Rc<String>, Vec<TypeIdentifier>),
2019-01-24 20:47:20 -08:00
Record {
name: Rc<String>,
members: 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
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),
2019-02-21 01:49:15 -08:00
BinExp(BinOp, Box<Meta<Expression>>, Box<Meta<Expression>>),
PrefixExp(PrefixOp, Box<Meta<Expression>>),
TupleLiteral(Vec<Meta<Expression>>),
2019-09-20 01:57:48 -07:00
Value(QualifiedName),
2018-06-04 19:25:40 -07:00
NamedStruct {
2019-09-06 17:19:41 -07:00
name: Meta<QualifiedName>,
fields: Vec<(Rc<String>, Meta<Expression>)>,
2018-06-04 19:25:40 -07:00
},
Call {
f: Box<Meta<Expression>>,
arguments: Vec<InvocationArgument>,
2018-06-04 19:25:40 -07:00
},
Index {
indexee: Box<Meta<Expression>>,
indexers: Vec<Meta<Expression>>,
2018-06-04 19:25:40 -07:00
},
IfExpression {
discriminator: Box<Discriminator>,
body: Box<IfExpressionBody>,
},
2018-06-04 19:25:40 -07:00
WhileExpression {
condition: Option<Box<Meta<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<Meta<Expression>>),
2018-06-04 19:25:40 -07:00
}
2018-11-16 14:06:04 -08:00
#[derive(Debug, PartialEq, Clone)]
pub enum InvocationArgument {
2019-09-02 14:13:53 -07:00
Positional(Meta<Expression>),
Keyword {
name: Rc<String>,
2019-09-02 14:13:53 -07:00
expr: Meta<Expression>,
},
Ignored
}
#[derive(Debug, PartialEq, Clone)]
pub enum Discriminator {
2019-09-02 14:13:53 -07:00
Simple(Meta<Expression>),
BinOp(Meta<Expression>, BinOp)
}
#[derive(Debug, PartialEq, Clone)]
pub enum IfExpressionBody {
SimpleConditional(Block, Option<Block>),
2018-06-20 02:07:11 -07:00
SimplePatternMatch(Pattern, Block, Option<Block>),
2018-07-13 21:50:38 -07:00
GuardList(Vec<GuardArm>)
}
#[derive(Debug, PartialEq, Clone)]
2018-07-13 21:50:38 -07:00
pub struct GuardArm {
pub guard: Guard,
pub body: Block,
}
#[derive(Debug, PartialEq, Clone)]
pub enum Guard {
Pat(Pattern),
HalfExpr(HalfExpr)
}
#[derive(Debug, PartialEq, Clone)]
pub struct HalfExpr {
pub op: Option<BinOp>,
pub expr: ExpressionKind,
}
#[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>,
pub generator: Meta<Expression>,
2018-06-04 19:25:40 -07:00
}
#[derive(Debug, PartialEq, Clone)]
pub enum ForBody {
MonadicReturn(Meta<Expression>),
2018-06-04 19:25:40 -07:00
StatementBlock(Block),
}