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