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