Well, Able and Eval functios can now change loops flow!
This commit is contained in:
parent
472b41cf16
commit
e883010580
|
@ -282,8 +282,7 @@ impl ExecEnv {
|
|||
}
|
||||
Stmt::Call { expr, args } => {
|
||||
let func = self.eval_expr(expr)?.into_functio();
|
||||
|
||||
self.fn_call(func, args, &stmt.span)?;
|
||||
return self.fn_call(func, args, &stmt.span);
|
||||
}
|
||||
Stmt::Loop { body } => loop {
|
||||
let res = self.eval_stmts_hs(body, true)?;
|
||||
|
@ -396,7 +395,7 @@ impl ExecEnv {
|
|||
func: Functio,
|
||||
args: &[Spanned<Expr>],
|
||||
span: &Range<usize>,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<HaltStatus, Error> {
|
||||
// Arguments that are ExprKind::Variable are pass by
|
||||
// reference; all other expressions are pass by value.
|
||||
let args = args
|
||||
|
@ -419,7 +418,7 @@ impl ExecEnv {
|
|||
func: Functio,
|
||||
args: &[ValueRef],
|
||||
span: &Range<usize>,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<HaltStatus, Error> {
|
||||
match func {
|
||||
Functio::Bf {
|
||||
instructions,
|
||||
|
@ -446,6 +445,8 @@ impl ExecEnv {
|
|||
stdout()
|
||||
.write_all(&output)
|
||||
.expect("Failed to write to stdout");
|
||||
|
||||
Ok(HaltStatus::Finished)
|
||||
}
|
||||
Functio::Able { params, body } => {
|
||||
self.stack.push(Default::default());
|
||||
|
@ -457,34 +458,46 @@ impl ExecEnv {
|
|||
let res = self.eval_stmts_hs(&body, false);
|
||||
|
||||
self.stack.pop();
|
||||
res?;
|
||||
res
|
||||
}
|
||||
Functio::Builtin(b) => {
|
||||
b.call(args).map_err(|e| Error::new(e, span.clone()))?;
|
||||
Ok(HaltStatus::Finished)
|
||||
}
|
||||
Functio::Builtin(b) => b.call(args).map_err(|e| Error::new(e, span.clone()))?,
|
||||
Functio::Chain { functios, kind } => {
|
||||
use crate::value::functio::FunctioChainKind;
|
||||
let (left_functio, right_functio) = *functios;
|
||||
match kind {
|
||||
Ok(
|
||||
match match kind {
|
||||
FunctioChainKind::Equal => {
|
||||
let (l, r) = args.split_at(args.len() / 2);
|
||||
|
||||
self.fn_call_with_values(left_functio, l, span)?;
|
||||
self.fn_call_with_values(right_functio, r, span)?;
|
||||
(
|
||||
self.fn_call_with_values(left_functio, l, span)?,
|
||||
self.fn_call_with_values(right_functio, r, span)?,
|
||||
)
|
||||
}
|
||||
FunctioChainKind::ByArity => {
|
||||
let (l, r) =
|
||||
Self::deinterlace(args, (left_functio.arity(), right_functio.arity()));
|
||||
let (l, r) = Self::deinterlace(
|
||||
args,
|
||||
(left_functio.arity(), right_functio.arity()),
|
||||
);
|
||||
|
||||
self.fn_call_with_values(left_functio, &l, span)?;
|
||||
self.fn_call_with_values(right_functio, &r, span)?;
|
||||
(
|
||||
self.fn_call_with_values(left_functio, &l, span)?,
|
||||
self.fn_call_with_values(right_functio, &r, span)?,
|
||||
)
|
||||
}
|
||||
};
|
||||
} {
|
||||
(s, HaltStatus::Finished) => s,
|
||||
(HaltStatus::Finished, s) => s,
|
||||
(_, r) => r,
|
||||
},
|
||||
)
|
||||
}
|
||||
Functio::Eval(code) => {
|
||||
self.eval_stmts_hs(&crate::parser::parse(&code)?, false)?;
|
||||
Functio::Eval(code) => self.eval_stmts_hs(&crate::parser::parse(&code)?, false),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deinterlace(args: &[ValueRef], arities: (usize, usize)) -> (Vec<ValueRef>, Vec<ValueRef>) {
|
||||
let n_alternations = usize::min(arities.0, arities.1);
|
||||
|
|
Loading…
Reference in a new issue