Skip to main content

ternlang_core/
ast.rs

1#[derive(Debug, Clone, PartialEq)]
2pub enum Expr {
3    TritLiteral(i8),
4    IntLiteral(i64),
5    StringLiteral(String),
6    Ident(String),
7    BinaryOp {
8        op: BinOp,
9        lhs: Box<Expr>,
10        rhs: Box<Expr>,
11    },
12    UnaryOp {
13        op: UnOp,
14        expr: Box<Expr>,
15    },
16    Call {
17        callee: String,
18        args: Vec<Expr>,
19    },
20    /// field access: `object.field`
21    FieldAccess {
22        object: Box<Expr>,
23        field: String,
24    },
25    /// cast(expr) — type coercion built-in
26    Cast {
27        expr: Box<Expr>,
28        ty: Type,
29    },
30    /// spawn AgentName — creates a local agent instance, evaluates to AgentRef
31    /// spawn remote "addr" AgentName — creates a remote agent instance (Phase 5.1)
32    Spawn {
33        agent_name: String,
34        /// None = local, Some("host:port") = remote node
35        node_addr: Option<String>,
36    },
37    /// await <agentref_expr> — receive result from agent mailbox
38    Await {
39        target: Box<Expr>,
40    },
41    /// nodeid — returns the current node's address (Phase 5.1)
42    NodeId,
43}
44
45#[derive(Debug, Clone, Copy, PartialEq)]
46pub enum BinOp {
47    Add,
48    Sub,
49    Mul,
50    Equal,
51    NotEqual,
52    And,
53    Or,
54}
55
56#[derive(Debug, Clone, Copy, PartialEq)]
57pub enum UnOp {
58    Neg,
59}
60
61#[derive(Debug, Clone, PartialEq)]
62pub enum Stmt {
63    Let {
64        name: String,
65        ty: Type,
66        value: Expr,
67    },
68    IfTernary {
69        condition: Expr,
70        on_pos: Box<Stmt>,   // branch when +1
71        on_zero: Box<Stmt>,  // branch when  0
72        on_neg: Box<Stmt>,   // branch when -1
73    },
74    Match {
75        condition: Expr,
76        arms: Vec<(i8, Stmt)>,
77    },
78    /// for <var> in <iter_expr> { body }
79    ForIn {
80        var: String,
81        iter: Expr,
82        body: Box<Stmt>,
83    },
84    /// while <condition> ? { on_pos } else { on_zero } else { on_neg }
85    WhileTernary {
86        condition: Expr,
87        on_pos: Box<Stmt>,
88        on_zero: Box<Stmt>,
89        on_neg: Box<Stmt>,
90    },
91    /// loop { body } — infinite loop, exited via break
92    Loop {
93        body: Box<Stmt>,
94    },
95    Break,
96    Continue,
97    Block(Vec<Stmt>),
98    Return(Expr),
99    Expr(Expr),
100    Decorated {
101        directive: String,
102        stmt: Box<Stmt>,
103    },
104    /// use path::to::module;
105    Use {
106        path: Vec<String>,
107    },
108    /// send <agentref_expr> <message_expr>;
109    Send {
110        target: Expr,
111        message: Expr,
112    },
113    /// instance.field = value;
114    FieldSet {
115        object: String,
116        field: String,
117        value: Expr,
118    },
119}
120
121#[derive(Debug, Clone, PartialEq)]
122pub enum Type {
123    Trit,
124    TritTensor { dims: Vec<usize> },
125    Int,
126    Bool,
127    Float,
128    String,
129    /// User-defined struct type
130    Named(String),
131    /// Handle to a running agent instance
132    AgentRef,
133}
134
135#[derive(Debug, Clone, PartialEq)]
136pub struct Function {
137    pub name: String,
138    pub params: Vec<(String, Type)>,
139    pub return_type: Type,
140    pub body: Vec<Stmt>,
141}
142
143/// Top-level struct definition: `struct Name { field: type, ... }`
144#[derive(Debug, Clone, PartialEq)]
145pub struct StructDef {
146    pub name: String,
147    pub fields: Vec<(String, Type)>,
148}
149
150/// Top-level agent definition: `agent Name { fn handle(msg: trit) -> trit { ... } }`
151/// v0.1: agents have a single `handle` method that processes each incoming message.
152#[derive(Debug, Clone, PartialEq)]
153pub struct AgentDef {
154    pub name: String,
155    pub methods: Vec<Function>,
156}
157
158#[derive(Debug, Clone, PartialEq)]
159pub struct Program {
160    pub structs: Vec<StructDef>,
161    pub agents: Vec<AgentDef>,
162    pub functions: Vec<Function>,
163}