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