forked from AbleScript/ablescript
Reimplement BF function declaration semantics
This commit is contained in:
parent
ae3a7b7c8a
commit
1a8f17339e
|
@ -208,16 +208,26 @@ impl ExecEnv {
|
||||||
args: _,
|
args: _,
|
||||||
body: _,
|
body: _,
|
||||||
} => todo!(),
|
} => todo!(),
|
||||||
StmtKind::BfFunctio { .. } => todo!(),
|
StmtKind::BfFunctio {
|
||||||
// This is missing from StmtKind after the interpreter
|
iden,
|
||||||
// rewrite; presumably, parsing is not yet implemented for
|
tape_len,
|
||||||
// it. ~~Alex
|
code,
|
||||||
// StmtKind::BfFDeclaration { iden, body } => {
|
} => {
|
||||||
// self.decl_var(
|
self.decl_var(
|
||||||
// &iden.0,
|
&iden.iden,
|
||||||
// Value::Functio(Functio::BfFunctio(body.as_bytes().into())),
|
Value::Functio(Functio::BfFunctio {
|
||||||
// );
|
instructions: code.to_owned(),
|
||||||
// }
|
tape_len: tape_len
|
||||||
|
.as_ref()
|
||||||
|
.map(|tape_len| {
|
||||||
|
self.eval_expr(tape_len)
|
||||||
|
.and_then(|v| v.to_i32(&stmt.span))
|
||||||
|
.map(|len| len as usize)
|
||||||
|
})
|
||||||
|
.unwrap_or(Ok(crate::brian::DEFAULT_TAPE_SIZE_LIMIT))?,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
StmtKind::If { cond, body } => {
|
StmtKind::If { cond, body } => {
|
||||||
if self.eval_expr(cond)?.to_bool() {
|
if self.eval_expr(cond)?.to_bool() {
|
||||||
return self.eval_stmts_hs(&body.block, true);
|
return self.eval_stmts_hs(&body.block, true);
|
||||||
|
@ -228,7 +238,10 @@ impl ExecEnv {
|
||||||
match func {
|
match func {
|
||||||
Value::Functio(func) => {
|
Value::Functio(func) => {
|
||||||
match func {
|
match func {
|
||||||
Functio::BfFunctio(body) => {
|
Functio::BfFunctio {
|
||||||
|
instructions,
|
||||||
|
tape_len,
|
||||||
|
} => {
|
||||||
let mut input: Vec<u8> = vec![];
|
let mut input: Vec<u8> = vec![];
|
||||||
for arg in args {
|
for arg in args {
|
||||||
self.eval_expr(arg)?.bf_write(&mut input);
|
self.eval_expr(arg)?.bf_write(&mut input);
|
||||||
|
@ -236,11 +249,16 @@ impl ExecEnv {
|
||||||
println!("input = {:?}", input);
|
println!("input = {:?}", input);
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
|
|
||||||
crate::brian::interpret_with_io(&body, &input as &[_], &mut output)
|
crate::brian::Interpreter::from_ascii_with_tape_limit(
|
||||||
.map_err(|e| Error {
|
&instructions,
|
||||||
kind: ErrorKind::BfInterpretError(e),
|
&input as &[_],
|
||||||
span: stmt.span.clone(),
|
tape_len,
|
||||||
})?;
|
)
|
||||||
|
.interpret_with_output(&mut output)
|
||||||
|
.map_err(|e| Error {
|
||||||
|
kind: ErrorKind::BfInterpretError(e),
|
||||||
|
span: stmt.span.clone(),
|
||||||
|
})?;
|
||||||
|
|
||||||
// I guess Brainfuck functions write
|
// I guess Brainfuck functions write
|
||||||
// output to stdout? It's not quite
|
// output to stdout? It's not quite
|
||||||
|
|
|
@ -36,7 +36,10 @@ impl From<Abool> for bool {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Functio {
|
pub enum Functio {
|
||||||
BfFunctio(Vec<u8>),
|
BfFunctio {
|
||||||
|
instructions: Vec<u8>,
|
||||||
|
tape_len: usize,
|
||||||
|
},
|
||||||
AbleFunctio(Vec<Stmt>),
|
AbleFunctio(Vec<Stmt>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,10 +97,17 @@ impl Value {
|
||||||
}])
|
}])
|
||||||
}),
|
}),
|
||||||
Value::Functio(f) => stream.write_all(&[5]).and_then(|_| match f {
|
Value::Functio(f) => stream.write_all(&[5]).and_then(|_| match f {
|
||||||
Functio::BfFunctio(f) => stream
|
Functio::BfFunctio {
|
||||||
.write_all(&[0])
|
instructions,
|
||||||
.and_then(|_| stream.write_all(&(f.len() as u32).to_le_bytes()))
|
tape_len: _,
|
||||||
.and_then(|_| stream.write_all(&f)),
|
} => {
|
||||||
|
// NOTE(Alex): Tape length should maybe be taken
|
||||||
|
// into account here.
|
||||||
|
stream
|
||||||
|
.write_all(&[0])
|
||||||
|
.and_then(|_| stream.write_all(&(instructions.len() as u32).to_le_bytes()))
|
||||||
|
.and_then(|_| stream.write_all(&instructions))
|
||||||
|
}
|
||||||
Functio::AbleFunctio(_) => {
|
Functio::AbleFunctio(_) => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -148,11 +158,12 @@ impl Display for Value {
|
||||||
Value::Bool(v) => write!(f, "{}", v),
|
Value::Bool(v) => write!(f, "{}", v),
|
||||||
Value::Abool(v) => write!(f, "{}", v),
|
Value::Abool(v) => write!(f, "{}", v),
|
||||||
Value::Functio(v) => match v {
|
Value::Functio(v) => match v {
|
||||||
Functio::BfFunctio(source) => {
|
Functio::BfFunctio { instructions, tape_len } => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"({}) {}",
|
||||||
String::from_utf8(source.to_owned())
|
tape_len,
|
||||||
|
String::from_utf8(instructions.to_owned())
|
||||||
.expect("Brainfuck functio source should be UTF-8")
|
.expect("Brainfuck functio source should be UTF-8")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue