diff options
author | JJ | 2023-10-31 09:49:41 +0000 |
---|---|---|
committer | JJ | 2023-10-31 09:50:21 +0000 |
commit | 1c14500ed698f1dc21b4b634a174af89b6318b07 (patch) | |
tree | 9dad300eec0585e6ee0d41cd0f8740da2e269a28 /src/frontend/ast.rs | |
parent | 87d74952a614daa7075aeecef462ff51c4dc46e0 (diff) |
compiler: restructure codebase
Diffstat (limited to 'src/frontend/ast.rs')
-rw-r--r-- | src/frontend/ast.rs | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/frontend/ast.rs b/src/frontend/ast.rs new file mode 100644 index 0000000..6c7963e --- /dev/null +++ b/src/frontend/ast.rs @@ -0,0 +1,116 @@ +/// Representation of Tokens, function names, the like... +pub type Id = String; + +/// Puck's fundamental types. +pub enum Type { + Void, Never, + Integer, Float, String, // char et al are defined later + Func{from: Box<Type>, to: Box<Type>}, // todo: multiple params, effects + Struct(Vec<(Id, Box<Type>)>), + Tuple(Vec<(Option<String>, Box<Type>)>), + Union(Vec<(Id, Box<Type>)>), + Interface { + funcs: Vec<Sig>, + for_type: Option<Box<Type>>, + }, + Array{size: usize, kind: Box<Type>}, + List(Box<Type>), + Slice(Box<Type>), // todo: plus ownership + Reference(Box<Type>), + Mutable(Box<Type>), // parameters only + Static(Box<Type>), // parameters only + Alias{ id: Id, params: Vec<Type> }, // todo: this is wrong +} + +/// Function signatures. +pub struct Sig { + effect: Option<Id>, + id: Id, + generics: Vec<(Id, Option<Type>)>, + params: Vec<Type>, + result: Option<Type> +} + +/// Patterns are recognizable given zero context. +/// This is why there is a generic Number term and no Bool term. +/// Also can be considered to be a Term/Value. +pub enum Pattern { + Ident(Id), // type aliases, union variants, calls... + Number(i64), Float(f64), + Char(char), String(String), + Struct(Vec<StructPattern>), + Tuple(Vec<TuplePattern>), + List(Vec<Expr>), // arrays, slices, lists +} + +pub struct StructPattern { field: Id, value: Expr } +pub struct TuplePattern { field: Option<Id>, value: Expr } + +/// Expressions introduce a new binding or bindings, in some regard. +pub enum Binding { + Let { + id: Pattern, // id: Pattern supports ex. `let (a, b) = ...` + kind: Option<Type>, + value: Box<Expr> + }, + Var { + id: Pattern, + kind: Option<Type>, + value: Option<Box<Expr>> // variable bindings can be delayed + }, + Const { + public: bool, + id: Pattern, + kind: Option<Type>, + value: Box<Expr> + }, + FuncDecl { + public: bool, + effect: Option<Id>, + id: Id, + generics: Vec<GenericDecl>, + params: Vec<ParamDecl>, + kind: Type, + body: Vec<Expr> + }, + TypeDecl { id: Id, generics: Vec<Id>, alias: Type }, + Import { from: Option<Id>, imports: Vec<Id>, alias: Option<Id> }, + Module { id: Id, body: Vec<Expr> }, +} + +pub struct GenericDecl { id: Id, kind: Option<Type> } +pub struct ParamDecl { id: Id, kind: Type } + +/// Expressions related to control flow. +pub enum Control { + Call { id: Id, params: Vec<Expr> }, // function calls, macro invocations, field access... + If { + branches: Vec<CondBranch>, + else_body: Option<Vec<Expr>> + }, + Try { + body: Vec<Expr>, + catches: Vec<CatchBranch>, + finally: Option<Vec<Expr>> + }, + Match { + item: Pattern, + branches: Vec<MatchBranch> + }, + Block { id: Option<Id>, body: Vec<Expr> }, + Static { body: Vec<Expr> }, + For { binding: Pattern, range: Box<Expr>, body: Vec<Expr> }, + While { cond: Box<Expr>, body: Vec<Expr> }, + Loop { body: Vec<Expr> }, +} + +pub struct CondBranch { cond: Expr, body: Vec<Expr> } +pub struct CatchBranch { exceptions: Vec<Id>, binding: Option<Id>, body: Vec<Expr> } +pub struct MatchBranch { pattern: Pattern, guard: Option<Expr>, body: Vec<Expr> } + +/// Expressions are either Patterns, Bindings, or Control flow constructs. +pub enum Expr { + Pattern(Pattern), + Binding(Binding), + Control(Control), +} |