1use 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 pub function_names: IndexMap<String, u32>,
13 pub module_aliases: IndexMap<String, String>,
16 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 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 #[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}