Skip to main content

yulang_vm/vm/
mod.rs

1use std::collections::{BTreeMap, HashMap};
2use std::fmt;
3use std::path::PathBuf;
4use std::rc::Rc;
5
6use yulang_runtime_ir::{
7    EffectIdRef, EffectIdVar, FinalizedBinding as Binding, FinalizedExpr as Expr,
8    FinalizedExprKind as ExprKind, FinalizedHandleArm as HandleArm, FinalizedMatchArm as MatchArm,
9    FinalizedModule as Module, FinalizedPattern as Pattern,
10    FinalizedRecordExprField as RecordExprField, FinalizedRecordSpreadExpr as RecordSpreadExpr,
11    FinalizedStmt as Stmt, RuntimeType as Type,
12};
13use yulang_runtime_types::RuntimeError;
14use yulang_runtime_types::types::effect_is_empty;
15use yulang_typed_ir as typed_ir;
16
17use crate::runtime::bytes_tree::BytesTree;
18use crate::runtime::list_tree::{ListTree, ListView};
19use crate::runtime::string_tree::StringTree;
20
21pub struct VmModule {
22    module: Module,
23}
24
25impl VmModule {
26    pub fn module(&self) -> &Module {
27        &self.module
28    }
29
30    pub fn eval_root_expr(&self, index: usize) -> Result<VmResult, VmError> {
31        VmInterpreter::new(&self.module).eval_root_expr(index)
32    }
33
34    pub fn eval_root_expr_profiled(&self, index: usize) -> Result<(VmResult, VmProfile), VmError> {
35        let mut interpreter = VmInterpreter::new(&self.module);
36        let result = interpreter.eval_root_expr(index)?;
37        Ok((result, interpreter.profile()))
38    }
39
40    pub fn eval_roots(&self) -> Result<Vec<VmResult>, VmError> {
41        Ok(self.eval_roots_profiled()?.0)
42    }
43
44    pub fn eval_roots_profiled(&self) -> Result<(Vec<VmResult>, VmProfile), VmError> {
45        let mut interpreter = VmInterpreter::new(&self.module);
46        let results = (0..self.module.root_exprs.len())
47            .map(|index| interpreter.eval_root_expr(index))
48            .collect::<Result<Vec<_>, _>>()?;
49        Ok((results, interpreter.profile()))
50    }
51
52    pub fn resume_request(&self, request: VmRequest, value: VmValue) -> Result<VmResult, VmError> {
53        VmInterpreter::new(&self.module).resume(request.continuation, value)
54    }
55
56    pub fn force_value_profiled(&self, value: VmValue) -> Result<(VmResult, VmProfile), VmError> {
57        let mut interpreter = VmInterpreter::new(&self.module);
58        let result = interpreter.bind_here(value)?;
59        Ok((result, interpreter.profile()))
60    }
61
62    pub fn resume_request_profiled(
63        &self,
64        request: VmRequest,
65        value: VmValue,
66    ) -> Result<(VmResult, VmProfile), VmError> {
67        let mut interpreter = VmInterpreter::new(&self.module);
68        let result = interpreter.resume(request.continuation, value)?;
69        Ok((result, interpreter.profile()))
70    }
71}
72
73pub trait IntoVmModule {
74    fn into_vm_module(self) -> Module;
75}
76
77impl IntoVmModule for Module {
78    fn into_vm_module(self) -> Module {
79        self
80    }
81}
82
83pub fn compile_vm_module<M: IntoVmModule>(module: M) -> Result<VmModule, VmError> {
84    let module = module.into_vm_module();
85    let effects = EffectPathResolver::collect(&module);
86    let module = erase_module(module, &effects)?;
87    Ok(VmModule { module })
88}
89
90#[derive(Debug, Clone, PartialEq)]
91pub enum VmError {
92    Runtime(RuntimeError),
93    ResidualPolymorphicBinding {
94        path: typed_ir::Path,
95        vars: Vec<typed_ir::TypeVar>,
96    },
97    MissingRootExpr(usize),
98    UnboundVariable(typed_ir::Path),
99    PatternMismatch,
100    ExpectedBool(VmValue),
101    ExpectedInt(VmValue),
102    ExpectedFloat(VmValue),
103    ExpectedString(VmValue),
104    ExpectedChar(VmValue),
105    ExpectedBytes(VmValue),
106    ExpectedPath(VmValue),
107    ExpectedList(VmValue),
108    ExpectedRecord(VmValue),
109    ExpectedVariant(VmValue),
110    ExpectedClosure(VmValue),
111    ExpectedThunk(VmValue),
112    ExpectedEffectId(VmValue),
113    YadaYada,
114    InvalidPrimitiveArity {
115        expected: usize,
116        actual: usize,
117    },
118    UnsupportedPrimitive(typed_ir::PrimitiveOp),
119    UnsupportedEffectIdVar(usize),
120    UnsupportedFindId,
121    UnexpectedRequest(typed_ir::Path),
122    HostIo(String),
123}
124
125impl fmt::Display for VmError {
126    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127        write!(f, "{self:?}")
128    }
129}
130
131impl std::error::Error for VmError {}
132
133mod continuation;
134mod control;
135mod erase;
136mod guard;
137mod interpreter;
138mod model;
139pub mod primitive;
140mod value;
141
142use erase::*;
143use guard::*;
144use interpreter::*;
145pub(crate) use model::VmFileHandleState;
146use model::*;
147pub use model::{
148    VmContinuation, VmFileHandle, VmPrimitive, VmProfile, VmRequest, VmResult, VmValue,
149};
150use primitive::*;
151use value::*;
152
153pub use control::{CONTROL_VM_ARTIFACT_VERSION, ControlVmModule, compile_control_vm_module};
154
155#[cfg(test)]
156mod tests;