Skip to main content

aver/
ast.rs

1#[derive(Debug, Clone, PartialEq)]
2pub enum Literal {
3    Int(i64),
4    Float(f64),
5    Str(String),
6    Bool(bool),
7}
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum BinOp {
11    Add,
12    Sub,
13    Mul,
14    Div,
15    Eq,
16    Neq,
17    Lt,
18    Gt,
19    Lte,
20    Gte,
21}
22
23#[derive(Debug, Clone, PartialEq)]
24pub struct MatchArm {
25    pub pattern: Pattern,
26    pub body: Box<Expr>,
27}
28
29#[derive(Debug, Clone, PartialEq)]
30pub enum Pattern {
31    Wildcard,
32    Literal(Literal),
33    Ident(String),
34    /// Empty list pattern: `[]`
35    EmptyList,
36    /// Cons-like list pattern: `[head, ..tail]`
37    Cons(String, String),
38    /// Tuple pattern: `(a, b)` / `(_, x)` / nested tuples.
39    Tuple(Vec<Pattern>),
40    /// Constructor pattern: name + list of binding names.
41    /// Built-ins: Ok(x), Err(x), Some(x), None → vec!["x"] or vec![]
42    /// User-defined: Circle(r), Rect(w, h), Point → vec!["r"], vec!["w","h"], vec![]
43    Constructor(String, Vec<String>),
44}
45
46#[derive(Debug, Clone, PartialEq)]
47pub enum StrPart {
48    Literal(String),
49    Parsed(Box<Expr>),
50}
51
52#[derive(Debug, Clone, PartialEq)]
53pub enum Expr {
54    Literal(Literal),
55    Ident(String),
56    Attr(Box<Expr>, String),
57    FnCall(Box<Expr>, Vec<Expr>),
58    BinOp(BinOp, Box<Expr>, Box<Expr>),
59    Match {
60        subject: Box<Expr>,
61        arms: Vec<MatchArm>,
62        line: usize,
63    },
64    Constructor(String, Option<Box<Expr>>),
65    ErrorProp(Box<Expr>),
66    InterpolatedStr(Vec<StrPart>),
67    List(Vec<Expr>),
68    Tuple(Vec<Expr>),
69    /// Map literal: `{"a" => 1, "b" => 2}`
70    MapLiteral(Vec<(Expr, Expr)>),
71    /// Record creation: `User(name = "Alice", age = 30)`
72    RecordCreate {
73        type_name: String,
74        fields: Vec<(String, Expr)>,
75    },
76    /// Record update: `User.update(base, field = newVal, ...)`
77    RecordUpdate {
78        type_name: String,
79        base: Box<Expr>,
80        updates: Vec<(String, Expr)>,
81    },
82    /// Tail-position call to a function in the same SCC (self or mutual recursion).
83    /// Produced by the TCO transform pass before type-checking.
84    /// Boxed to keep Expr enum at its original size (48 bytes).
85    TailCall(Box<(String, Vec<Expr>)>),
86    /// Compiled variable lookup: `env[last][slot]` — O(1) instead of HashMap scan.
87    /// Produced by the resolver pass for locals inside function bodies.
88    Resolved(u16),
89}
90
91#[derive(Debug, Clone, PartialEq)]
92pub enum Stmt {
93    Binding(String, Option<String>, Expr),
94    Expr(Expr),
95}
96
97#[derive(Debug, Clone, PartialEq)]
98pub enum FnBody {
99    Expr(Expr),
100    Block(Vec<Stmt>),
101}
102
103/// Compile-time resolution metadata for a function body.
104/// Produced by `resolver::resolve_fn` — maps local variable names to slot indices
105/// so the interpreter can use `Vec<Rc<Value>>` instead of `HashMap` lookups.
106#[derive(Debug, Clone, PartialEq)]
107pub struct FnResolution {
108    /// Total number of local slots needed (params + bindings in body).
109    pub local_count: u16,
110    /// Map from local variable name → slot index in the local `Slots` frame.
111    pub local_slots: std::collections::HashMap<String, u16>,
112}
113
114#[derive(Debug, Clone, PartialEq)]
115pub struct FnDef {
116    pub name: String,
117    pub line: usize,
118    pub params: Vec<(String, String)>,
119    pub return_type: String,
120    pub effects: Vec<String>,
121    pub desc: Option<String>,
122    pub body: std::rc::Rc<FnBody>,
123    /// `None` for unresolved (REPL, module sub-interpreters).
124    pub resolution: Option<FnResolution>,
125}
126
127#[derive(Debug, Clone, PartialEq)]
128pub struct Module {
129    pub name: String,
130    pub line: usize,
131    pub depends: Vec<String>,
132    pub exposes: Vec<String>,
133    pub intent: String,
134}
135
136#[derive(Debug, Clone, PartialEq)]
137pub enum VerifyGivenDomain {
138    /// Integer range domain in verify law: `1..50` (inclusive).
139    IntRange { start: i64, end: i64 },
140    /// Explicit domain values in verify law: `[v1, v2, ...]`.
141    Explicit(Vec<Expr>),
142}
143
144#[derive(Debug, Clone, PartialEq)]
145pub struct VerifyGiven {
146    pub name: String,
147    pub type_name: String,
148    pub domain: VerifyGivenDomain,
149}
150
151#[derive(Debug, Clone, PartialEq)]
152pub struct VerifyLaw {
153    pub name: String,
154    pub givens: Vec<VerifyGiven>,
155    /// Template assertion from source before given-domain expansion.
156    pub lhs: Expr,
157    pub rhs: Expr,
158}
159
160#[derive(Debug, Clone, PartialEq)]
161pub enum VerifyKind {
162    Cases,
163    Law(VerifyLaw),
164}
165
166#[derive(Debug, Clone, PartialEq)]
167pub struct VerifyBlock {
168    pub fn_name: String,
169    pub line: usize,
170    pub cases: Vec<(Expr, Expr)>,
171    pub kind: VerifyKind,
172}
173
174#[derive(Debug, Clone, PartialEq)]
175pub struct DecisionBlock {
176    pub name: String,
177    pub line: usize,
178    pub date: String,
179    pub reason: String,
180    pub chosen: DecisionImpact,
181    pub rejected: Vec<DecisionImpact>,
182    pub impacts: Vec<DecisionImpact>,
183    pub author: Option<String>,
184}
185
186#[derive(Debug, Clone, PartialEq, Eq, Hash)]
187pub enum DecisionImpact {
188    Symbol(String),
189    Semantic(String),
190}
191
192impl DecisionImpact {
193    pub fn text(&self) -> &str {
194        match self {
195            DecisionImpact::Symbol(s) | DecisionImpact::Semantic(s) => s,
196        }
197    }
198
199    pub fn as_context_string(&self) -> String {
200        match self {
201            DecisionImpact::Symbol(s) => s.clone(),
202            DecisionImpact::Semantic(s) => format!("\"{}\"", s),
203        }
204    }
205}
206
207/// A variant in a sum type definition.
208/// e.g. `Circle(Float)` → `TypeVariant { name: "Circle", fields: ["Float"] }`
209#[derive(Debug, Clone, PartialEq)]
210pub struct TypeVariant {
211    pub name: String,
212    pub fields: Vec<String>, // type annotations (e.g. "Float", "String")
213}
214
215/// A user-defined type definition.
216#[derive(Debug, Clone, PartialEq)]
217pub enum TypeDef {
218    /// `type Shape` with variants Circle(Float), Rect(Float, Float), Point
219    Sum {
220        name: String,
221        variants: Vec<TypeVariant>,
222        line: usize,
223    },
224    /// `record User` with fields name: String, age: Int
225    Product {
226        name: String,
227        fields: Vec<(String, String)>,
228        line: usize,
229    },
230}
231
232#[derive(Debug, Clone, PartialEq)]
233pub enum TopLevel {
234    Module(Module),
235    FnDef(FnDef),
236    Verify(VerifyBlock),
237    Decision(DecisionBlock),
238    Stmt(Stmt),
239    TypeDef(TypeDef),
240    /// `effects AppIO = [Console, Disk]` — named effect set (alias)
241    EffectSet {
242        name: String,
243        effects: Vec<String>,
244        line: usize,
245    },
246}