Skip to main content

ironwork_exec/machine/
le_services.rs

1//! A CALL that reaches a Language Environment callable service: `rt::callee` builds the argument
2//! addresses, the walker runs the CALL's phrases, and `rt::le` runs the service.
3
4use super::*;
5use crate::le::{self, LeHost};
6use std::rc::Rc;
7
8impl<'p> Machine<'p, '_, '_> {
9    pub(super) fn le_call(&mut self, c: &'p Call, name: &str) -> R<Flow> {
10        let mark = self.unit.mem.len();
11        let outcome = callee::addresses(self, &call_args(&c.using), c.pos).and_then(|args| {
12            self.parmcheck_set();
13            self.le_service(name, &args, c.pos).map(|()| args)
14        });
15        self.unit.release_temporaries(mark);
16        self.parmcheck_test(c, &outcome?, |_| name.to_owned())?;
17        match &c.not_on_exception {
18            Some(body) => self.run_block(body),
19            None => Ok(Flow::Next),
20        }
21    }
22
23    fn le_service(&mut self, name: &str, args: &[Option<usize>], pos: Pos) -> R<()> {
24        match le::service(name) {
25            Some(service) => le::call(self, service, args, pos),
26            None => Err(Abend::ironwork(format!("CALL {name}: not a service ironwork provides"), pos)),
27        }
28    }
29}
30
31impl<'w> LeHost<'w> for Machine<'_, '_, 'w> {
32    fn page(&self) -> &'static CodePage {
33        self.page
34    }
35
36    fn method_name(program: &Rc<Compiled>) -> Option<String> {
37        program.program.oo.as_deref().and_then(|o| o.method()).map(|m| format!("{}.{}", m.class, m.name))
38    }
39}