Reimplement BF function declaration semantics

This commit is contained in:
Alex Bethel 2021-06-12 09:26:21 -05:00
parent ae3a7b7c8a
commit 1a8f17339e
2 changed files with 53 additions and 24 deletions

View file

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

View file

@ -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")
) )
} }