Well, Able and Eval functios can now change loops flow!

This commit is contained in:
Erin 2022-07-01 23:12:59 +02:00 committed by ondra05
parent a7c75e2303
commit 2de2eb8914

View file

@ -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);