/// Representation of Tokens, function names, the like... pub type Id = String; /// Puck's fundamental types. #[derive(Clone, PartialEq)] pub enum Type { Void, Never, Integer, Float, String, // char et al are defined later Func { // todo: multiple params, effects from: Box, to: Box }, Struct(Vec<(Id, Box)>), Tuple(Vec<(Option, Box)>), Union(Vec<(Id, Box)>), 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), // parameters only Static(Box), // parameters only Alias { // todo: this is wrong id: Id, generics: Vec } } /// Function signatures. #[derive(Clone, PartialEq)] pub struct Sig { pub effect: Option, pub id: Id, pub generics: Vec<(Id, Option)>, pub parameters: Vec, pub kind: Option } /// 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, in some regard. pub enum Binding { 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, effect: Option, id: Id, generics: Vec<(Id, Option)>, // id, kind parameters: Vec<(Id, Type)>, // id, kind kind: Type, body: Vec }, Macro { public: bool, id: Id, generics: Vec<(Id, Option)>, // id, kind parameters: Vec<(Id, Option)>, // id, kind kind: Option, body: Vec }, TypeDecl { id: Id, generics: Vec<(Id, Option)>, alias: Type }, Import { from: Option, imports: Vec, alias: Option }, 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: Option> }, Try { body: Vec, catches: Vec, finally: Option> }, 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), }