Replaced `break` with `enough` (credits: Evrey#6086)

trunk
ondra05 2022-05-06 23:52:43 +02:00
parent cda63c733c
commit ad2839d497
5 changed files with 18 additions and 17 deletions

View File

@ -110,7 +110,7 @@ pub enum Stmt {
Loop { Loop {
body: Block, body: Block,
}, },
Break, Enough,
HopBack, HopBack,
Dim { Dim {

View File

@ -13,7 +13,7 @@ pub enum ErrorKind {
UnexpectedToken(Token), UnexpectedToken(Token),
UnknownVariable(String), UnknownVariable(String),
MeloVariable(String), MeloVariable(String),
TopLevelBreak, TopLevelEnough,
MissingLhs, MissingLhs,
Brian(InterpretError), Brian(InterpretError),
Io(io::Error), Io(io::Error),
@ -50,7 +50,7 @@ impl Display for ErrorKind {
ErrorKind::UnexpectedToken(token) => write!(f, "unexpected token {:?}", token), ErrorKind::UnexpectedToken(token) => write!(f, "unexpected token {:?}", token),
ErrorKind::UnknownVariable(name) => write!(f, "unknown identifier \"{}\"", name), ErrorKind::UnknownVariable(name) => write!(f, "unknown identifier \"{}\"", name),
ErrorKind::MeloVariable(name) => write!(f, "banned variable \"{}\"", name), ErrorKind::MeloVariable(name) => write!(f, "banned variable \"{}\"", name),
ErrorKind::TopLevelBreak => write!(f, "can only `break` out of a loop"), ErrorKind::TopLevelEnough => write!(f, "can only `enough` out of a loop"),
ErrorKind::Brian(err) => write!(f, "brainfuck error: {}", err), ErrorKind::Brian(err) => write!(f, "brainfuck error: {}", err),
// TODO: give concrete numbers here. // TODO: give concrete numbers here.
ErrorKind::MissingLhs => write!(f, "missing expression before binary operation"), ErrorKind::MissingLhs => write!(f, "missing expression before binary operation"),

View File

@ -68,9 +68,9 @@ enum HaltStatus {
/// We ran out of statements to execute. /// We ran out of statements to execute.
Finished, Finished,
/// A `break` statement occurred at the given span, and was not /// An `enough` statement occurred at the given span, and was not
/// caught by a `loop` statement up to this point. /// caught by a `loop` statement up to this point.
Break(Range<usize>), Enough(Range<usize>),
/// A `hopback` statement occurred at the given span, and was not /// A `hopback` statement occurred at the given span, and was not
/// caught by a `loop` statement up to this point. /// caught by a `loop` statement up to this point.
@ -105,20 +105,20 @@ impl ExecEnv {
/// Execute a set of Statements in the root stack frame. Return an /// Execute a set of Statements in the root stack frame. Return an
/// error if one or more of the Stmts failed to evaluate, or if a /// error if one or more of the Stmts failed to evaluate, or if a
/// `break` or `hopback` statement occurred at the top level. /// `enough` or `hopback` statement occurred at the top level.
pub fn eval_stmts(&mut self, stmts: &[Spanned<Stmt>]) -> Result<(), Error> { pub fn eval_stmts(&mut self, stmts: &[Spanned<Stmt>]) -> Result<(), Error> {
match self.eval_stmts_hs(stmts, false)? { match self.eval_stmts_hs(stmts, false)? {
HaltStatus::Finished => Ok(()), HaltStatus::Finished => Ok(()),
HaltStatus::Break(span) | HaltStatus::Hopback(span) => Err(Error { HaltStatus::Enough(span) | HaltStatus::Hopback(span) => Err(Error {
// It's an error to issue a `break` outside of a // It's an error to issue a `enough` outside of a
// `loop` statement. // `loop` statement.
kind: ErrorKind::TopLevelBreak, kind: ErrorKind::TopLevelEnough,
span, span,
}), }),
} }
} }
/// The same as `eval_stmts`, but report "break" and "hopback" /// The same as `eval_stmts`, but report "enough" and "hopback"
/// exit codes as normal conditions in a HaltStatus enum, and /// exit codes as normal conditions in a HaltStatus enum, and
/// create a new stack frame if `stackframe` is true. /// create a new stack frame if `stackframe` is true.
/// ///
@ -279,15 +279,15 @@ impl ExecEnv {
let res = self.eval_stmts_hs(body, true)?; let res = self.eval_stmts_hs(body, true)?;
match res { match res {
HaltStatus::Finished => (), HaltStatus::Finished => (),
HaltStatus::Break(_) => break, HaltStatus::Enough(_) => break,
HaltStatus::Hopback(_) => continue, HaltStatus::Hopback(_) => continue,
} }
}, },
Stmt::Assign { assignable, value } => { Stmt::Assign { assignable, value } => {
self.assign(assignable, self.eval_expr(value)?)?; self.assign(assignable, self.eval_expr(value)?)?;
} }
Stmt::Break => { Stmt::Enough => {
return Ok(HaltStatus::Break(stmt.span.clone())); return Ok(HaltStatus::Enough(stmt.span.clone()));
} }
Stmt::HopBack => { Stmt::HopBack => {
return Ok(HaltStatus::Hopback(stmt.span.clone())); return Ok(HaltStatus::Hopback(stmt.span.clone()));

View File

@ -93,8 +93,9 @@ pub enum Token {
#[token("loop")] #[token("loop")]
Loop, Loop,
#[token("break")] /// Break out of the loop
Break, #[token("enough")]
Enough,
/// HopBack hops on the back of loop - like `continue` /// HopBack hops on the back of loop - like `continue`
#[token("hopback")] #[token("hopback")]

View File

@ -84,8 +84,8 @@ impl<'source> Parser<'source> {
self.loop_flow()?, self.loop_flow()?,
start..self.lexer.span().end, start..self.lexer.span().end,
)), )),
Token::Break => Ok(Spanned::new( Token::Enough => Ok(Spanned::new(
self.semicolon_terminated(Stmt::Break)?, self.semicolon_terminated(Stmt::Enough)?,
start..self.lexer.span().end, start..self.lexer.span().end,
)), )),
Token::HopBack => Ok(Spanned::new( Token::HopBack => Ok(Spanned::new(