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-02-21 01:46:27 -08:00
|
|
|
use crate::typechecking::TypeData;
|
2019-09-02 14:13:53 -07:00
|
|
|
use crate::symbol_table::FullyQualifiedSymbolName;
|
2018-06-04 19:25:40 -07:00
|
|
|
|
2019-08-14 07:25:45 -07:00
|
|
|
mod operators;
|
|
|
|
pub use operators::*;
|
|
|
|
|
2019-09-18 01:51:23 -07:00
|
|
|
/// An abstract identifier for an AST node
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
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
|
|
|
|
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,
|
2019-09-03 03:20:17 -07:00
|
|
|
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-08-31 23:39:01 -07:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub struct QualifiedName(pub Vec<Rc<String>>);
|
|
|
|
|
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,
|
2019-02-20 22:44:45 -08:00
|
|
|
type_anno: Option<TypeIdentifier>,
|
2019-02-21 19:07:07 -08:00
|
|
|
expr: Meta<Expression>,
|
2018-06-04 19:25:40 -07:00
|
|
|
},
|
|
|
|
Impl {
|
2018-10-18 13:27:09 -07:00
|
|
|
type_name: TypeIdentifier,
|
2019-01-08 00:51:56 -08:00
|
|
|
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>,
|
2018-08-24 16:49:59 -07:00
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2019-07-10 18:52:25 -07:00
|
|
|
pub struct Expression {
|
|
|
|
pub kind: ExpressionKind,
|
|
|
|
pub type_anno: Option<TypeIdentifier>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Expression {
|
|
|
|
pub fn new(kind: ExpressionKind) -> Expression {
|
|
|
|
Expression { kind, type_anno: None }
|
|
|
|
}
|
2018-06-04 19:25:40 -07:00
|
|
|
|
2019-07-10 18:52:25 -07:00
|
|
|
pub fn with_anno(kind: ExpressionKind, type_anno: TypeIdentifier) -> Expression {
|
|
|
|
Expression { 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)]
|
2019-02-21 01:26:51 -08:00
|
|
|
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-06 10:03:50 -07:00
|
|
|
Value(Meta<QualifiedName>),
|
2018-06-04 19:25:40 -07:00
|
|
|
NamedStruct {
|
2019-09-06 17:19:41 -07:00
|
|
|
name: Meta<QualifiedName>,
|
2019-02-21 19:07:07 -08:00
|
|
|
fields: Vec<(Rc<String>, Meta<Expression>)>,
|
2018-06-04 19:25:40 -07:00
|
|
|
},
|
|
|
|
Call {
|
2019-02-21 19:07:07 -08:00
|
|
|
f: Box<Meta<Expression>>,
|
2019-09-02 14:41:09 -07:00
|
|
|
arguments: Vec<InvocationArgument>,
|
2018-06-04 19:25:40 -07:00
|
|
|
},
|
|
|
|
Index {
|
2019-02-21 19:07:07 -08:00
|
|
|
indexee: Box<Meta<Expression>>,
|
|
|
|
indexers: Vec<Meta<Expression>>,
|
2018-06-04 19:25:40 -07:00
|
|
|
},
|
2018-06-19 02:05:25 -07:00
|
|
|
IfExpression {
|
|
|
|
discriminator: Box<Discriminator>,
|
|
|
|
body: Box<IfExpressionBody>,
|
|
|
|
},
|
2018-06-04 19:25:40 -07:00
|
|
|
WhileExpression {
|
2019-02-21 19:07:07 -08:00
|
|
|
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,
|
|
|
|
},
|
2019-02-21 19:07:07 -08:00
|
|
|
ListLiteral(Vec<Meta<Expression>>),
|
2018-06-04 19:25:40 -07:00
|
|
|
}
|
2018-11-16 14:06:04 -08:00
|
|
|
|
2019-06-11 17:20:20 -07:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub enum InvocationArgument {
|
2019-09-02 14:13:53 -07:00
|
|
|
Positional(Meta<Expression>),
|
2019-06-11 17:20:20 -07:00
|
|
|
Keyword {
|
|
|
|
name: Rc<String>,
|
2019-09-02 14:13:53 -07:00
|
|
|
expr: Meta<Expression>,
|
2019-06-11 17:20:20 -07:00
|
|
|
},
|
|
|
|
Ignored
|
|
|
|
}
|
|
|
|
|
2018-06-19 02:05:25 -07:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub enum Discriminator {
|
2019-09-02 14:13:53 -07:00
|
|
|
Simple(Meta<Expression>),
|
|
|
|
BinOp(Meta<Expression>, BinOp)
|
2018-06-19 02:05:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[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>)
|
2018-06-19 02:05:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[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>,
|
2019-02-21 01:26:51 -08:00
|
|
|
pub expr: ExpressionKind,
|
2018-06-19 02:05:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[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-06 17:19:41 -07:00
|
|
|
TupleStruct(Meta<QualifiedName>, Vec<Pattern>),
|
|
|
|
Record(Meta<QualifiedName>, Vec<(Rc<String>, Pattern)>),
|
|
|
|
VarOrName(Meta<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,
|
2019-02-21 01:26:51 -08:00
|
|
|
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-19 02:05:25 -07:00
|
|
|
}
|
2018-06-04 19:25:40 -07:00
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub struct Enumerator {
|
|
|
|
pub id: Rc<String>,
|
2019-02-21 19:07:07 -08:00
|
|
|
pub generator: Meta<Expression>,
|
2018-06-04 19:25:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
pub enum ForBody {
|
2019-02-21 19:07:07 -08:00
|
|
|
MonadicReturn(Meta<Expression>),
|
2018-06-04 19:25:40 -07:00
|
|
|
StatementBlock(Block),
|
|
|
|
}
|