/// Representation of Tokens, function names, the like... pub type Id = String; /// Puck's fundamental types. #[derive(Clone, PartialEq)] pub enum Type { Void, Never, Any, Integer, Float, String, // char et al are defined later Func { // future: effects from: Vec, to: Vec }, Struct(Vec<(Id, Type)>), Tuple(Vec<(Option, Type)>), Union(Vec<(Id, Type)>), Interface(Vec), Array { size: usize, kind: Box }, List(Box), Slice(Box), // todo: plus ownership Reference(Box), Pointer(Box), Distinct(Box), // todo: not sure Mutable(Box), Static(Box), // parameters only Alias { // todo: this is wrong id: Id, generics: Vec } } /// Function signatures. #[derive(Clone, PartialEq)] pub struct Sig { pub id: Id, pub generics: Vec<(Id, Option)>, pub parameters: Vec, pub kind: 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<(Id, Expr)>), // field, value Tuple(Vec<(Option, Expr)>), // field, value List(Vec), // arrays, slices, lists } /// Expressions introduce a new binding or bindings. pub enum Binding { // todo: excessive use of Option Let { id: Pattern, // id: Pattern supports ex. `let (a, b) = ...` kind: Option, value: Box }, Var { id: Pattern, kind: Option, value: Option> // variable bindings can be delayed }, Const { public: bool, id: Pattern, kind: Option, value: Box }, Func { public: bool, id: Id, generics: Vec<(Id, Option)>, parameters: Vec<(Id, Type)>, kind: Type, body: Vec }, Macro { public: bool, id: Id, generics: Vec<(Id, Option)>, parameters: Vec<(Id, Option)>, kind: Option, body: Vec }, TypeDecl { id: Id, generics: Vec<(Id, Option)>, alias: Type }, Use { modules: Vec }, // todo: aliases? anything else fancy? Module { id: Id, body: Vec }, } /// Expressions related to control flow. pub enum Control { Call { id: Id, params: Vec }, // function calls, macro invocations, field access... If { branches: Vec, else_body: Vec }, Try { body: Vec, catches: Vec, finally: Vec }, Match { item: Pattern, branches: Vec }, Block { id: Option, body: Vec }, Static { body: Vec }, For { binding: Pattern, range: Box, body: Vec }, While { cond: Box, body: Vec }, Loop { body: Vec }, } pub struct CondBranch { pub cond: Expr, pub body: Vec } pub struct CatchBranch { pub exceptions: Vec<(Id, Option)>, pub body: Vec } pub struct MatchBranch { pub patterns: Vec, pub guard: Option, pub body: Vec } /// Expressions are either Patterns, Bindings, or Control flow constructs. pub enum Expr { Pattern(Pattern), Binding(Binding), Control(Control), } pub type Ast = Vec;