Skip to main content

ternlang_core/
ast.rs

1#[derive(Debug, Clone, PartialEq)]
2pub enum Expr {
3    TritLiteral(i8),
4    IntLiteral(i64),
5    FloatLiteral(f64),
6    StringLiteral(String),
7    Ident(String),
8    BinaryOp {
9        op: BinOp,
10        lhs: Box<Expr>,
11        rhs: Box<Expr>,
12    },
13    UnaryOp {
14        op: UnOp,
15        expr: Box<Expr>,
16    },
17    Call {
18        callee: String,
19        args: Vec<Expr>,
20    },
21    /// field access: `object.field`
22    FieldAccess {
23        object: Box<Expr>,
24        field: String,
25    },
26    /// cast(expr) — type coercion built-in
27    Cast {
28        expr: Box<Expr>,
29        ty: Type,
30    },
31    /// spawn AgentName — creates a local agent instance, evaluates to AgentRef
32    /// spawn remote "addr" AgentName — creates a remote agent instance (Phase 5.1)
33    Spawn {
34        agent_name: String,
35        /// None = local, Some("host:port") = remote node
36        node_addr: Option<String>,
37    },
38    /// await <agentref_expr> — receive result from agent mailbox
39    Await {
40        target: Box<Expr>,
41    },
42    /// tensor[row, col] indexing (Phase 4.1)
43    Index {
44        object: Box<Expr>,
45        row: Box<Expr>,
46        col: Box<Expr>,
47    },
48    /// nodeid — returns the current node's address (Phase 5.1)
49    NodeId,
50    /// expr? — ternary error propagation.
51    /// If the inner expression evaluates to -1 (conflict), the current function
52    /// returns -1 immediately.  Otherwise execution continues with the value.
53    Propagate {
54        expr: Box<Expr>,
55    },
56    /// [1, 0, -1]
57    TritTensorLiteral(Vec<i8>),
58    /// Struct initialization: `Name { field: value, ... }`
59    StructLiteral {
60        name: String,
61        fields: Vec<(String, Expr)>,
62    },
63}
64
65#[derive(Debug, Clone, Copy, PartialEq)]
66pub enum BinOp {
67    Add,
68    Sub,
69    Mul,
70    Div,
71    Mod,
72    Equal,
73    NotEqual,
74    Less,
75    Greater,
76    LessEqual,
77    GreaterEqual,
78    And,
79    Or,
80}
81
82#[derive(Debug, Clone, Copy, PartialEq)]
83pub enum UnOp {
84    Neg,
85}
86
87#[derive(Debug, Clone, PartialEq)]
88pub enum Stmt {
89    Let {
90        name: String,
91        ty: Type,
92        value: Expr,
93    },
94    IfTernary {
95        condition: Expr,
96        on_pos: Box<Stmt>,   // branch when +1
97        on_zero: Box<Stmt>,  // branch when  0
98        on_neg: Box<Stmt>,   // branch when -1
99    },
100    Match {
101        condition: Expr,
102        arms: Vec<(i64, Stmt)>,
103    },
104    /// for <var> in <iter_expr> { body }
105    ForIn {
106        var: String,
107        iter: Expr,
108        body: Box<Stmt>,
109    },
110    /// while <condition> ? { on_pos } else { on_zero } else { on_neg }
111    WhileTernary {
112        condition: Expr,
113        on_pos: Box<Stmt>,
114        on_zero: Box<Stmt>,
115        on_neg: Box<Stmt>,
116    },
117    /// loop { body } — infinite loop, exited via break
118    Loop {
119        body: Box<Stmt>,
120    },
121    Break,
122    Continue,
123    Block(Vec<Stmt>),
124    Return(Expr),
125    Expr(Expr),
126    Decorated {
127        directive: String,
128        stmt: Box<Stmt>,
129    },
130    /// use path::to::module;
131    Use {
132        path: Vec<String>,
133    },
134    /// from <source> import <names>;
135    FromImport {
136        spec: ImportSpec,
137    },
138    /// send <agentref_expr> <message_expr>;
139    Send {
140        target: Expr,
141        message: Expr,
142    },
143    /// instance.field = value;
144    FieldSet {
145        object: String,
146        field: String,
147        value: Expr,
148    },
149    /// tensor[row, col] = value;
150    IndexSet {
151        object: String,
152        row: Expr,
153        col: Expr,
154        value: Expr,
155    },
156    /// ident = value;
157    Set {
158        name: String,
159        value: Expr,
160    },
161}
162
163#[derive(Debug, Clone, PartialEq)]
164pub enum Type {
165    Trit,
166    TritTensor { dims: Vec<usize> },
167    Int,
168    Bool,
169    Float,
170    String,
171    /// User-defined struct type
172    Named(String),
173    /// Handle to a running agent instance
174    AgentRef,
175}
176
177#[derive(Debug, Clone, PartialEq)]
178pub struct Function {
179    pub name: String,
180    pub params: Vec<(String, Type)>,
181    pub return_type: Type,
182    pub body: Vec<Stmt>,
183    pub directive: Option<String>,
184}
185
186/// Top-level struct definition: `struct Name { field: type, ... }`
187#[derive(Debug, Clone, PartialEq)]
188pub struct StructDef {
189    pub name: String,
190    pub fields: Vec<(String, Type)>,
191}
192
193/// Top-level agent definition: `agent Name { fn handle(msg: trit) -> trit { ... } }`
194/// v0.1: agents have a single `handle` method that processes each incoming message.
195#[derive(Debug, Clone, PartialEq)]
196pub struct AgentDef {
197    pub name: String,
198    pub methods: Vec<Function>,
199}
200
201/// Source of a `from ... import` statement.
202#[derive(Debug, Clone, PartialEq)]
203pub enum ImportSource {
204    /// `from stdlib::net` — double-colon module path (stdlib or relative .tern)
205    Module(Vec<String>),
206    /// `from "path/to/file.tern"` — explicit file path (string literal)
207    File(String),
208}
209
210/// What to pull out of the import source.
211#[derive(Debug, Clone, PartialEq)]
212pub enum ImportNames {
213    /// `import *` — everything (same as legacy `use`)
214    Wildcard,
215    /// `import foo, bar` — only these named symbols
216    Named(Vec<String>),
217}
218
219/// A `from <source> import <names>` statement.
220#[derive(Debug, Clone, PartialEq)]
221pub struct ImportSpec {
222    pub source: ImportSource,
223    pub names: ImportNames,
224}
225
226#[derive(Debug, Clone, PartialEq)]
227pub struct Program {
228    /// Legacy `use std::trit;` paths (kept for backward compat)
229    pub imports: Vec<Vec<String>>,
230    /// New `from ... import ...` statements
231    pub import_specs: Vec<ImportSpec>,
232    pub structs: Vec<StructDef>,
233    pub agents: Vec<AgentDef>,
234    pub functions: Vec<Function>,
235}