Skip to main content

lex_bytecode/
program.rs

1//! Compiled program: a set of functions plus a constant pool.
2
3use crate::op::*;
4use indexmap::IndexMap;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
8pub struct Program {
9    pub constants: Vec<Const>,
10    pub functions: Vec<Function>,
11    /// Global function names โ†’ function index in `functions`.
12    pub function_names: IndexMap<String, u32>,
13    /// Imported module aliases โ†’ module name (e.g., `io` โ†’ `io`).
14    /// Used by the compiler/runtime to dispatch `alias.op(...)` calls.
15    pub module_aliases: IndexMap<String, String>,
16    /// Entry function (for `lex run`, set to whatever function the user
17    /// chose to invoke). Optional.
18    pub entry: Option<u32>,
19}
20
21impl Program {
22    pub fn lookup(&self, name: &str) -> Option<u32> {
23        self.function_names.get(name).copied()
24    }
25
26    /// Walk every function's declared effects and collect the union of
27    /// effect kinds (with their args).
28    pub fn declared_effects(&self) -> Vec<DeclaredEffect> {
29        let mut out: Vec<DeclaredEffect> = Vec::new();
30        for f in &self.functions {
31            for e in &f.effects {
32                if !out.iter().any(|x| x == e) {
33                    out.push(e.clone());
34                }
35            }
36        }
37        out
38    }
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
42pub struct Function {
43    pub name: String,
44    pub arity: u16,
45    pub locals_count: u16,
46    pub code: Vec<Op>,
47    /// Declared effects on this function's signature (spec ยง7).
48    #[serde(default)]
49    pub effects: Vec<DeclaredEffect>,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
53pub struct DeclaredEffect {
54    pub kind: String,
55    #[serde(default, skip_serializing_if = "Option::is_none")]
56    pub arg: Option<EffectArg>,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
60pub enum EffectArg {
61    Str(String),
62    Int(i64),
63    Ident(String),
64}