Skip to content

Commit

Permalink
while - continue support
Browse files Browse the repository at this point in the history
  • Loading branch information
mdecimus committed Oct 4, 2023
1 parent 3039311 commit 0932d6a
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 1 deletion.
18 changes: 18 additions & 0 deletions src/compiler/grammar/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,24 @@ impl Compiler {
jz_pos: usize::MAX,
}));
}
Word::Continue => {
state.validate_argument(
0,
Capability::While.into(),
token_info.line_num,
token_info.line_pos,
)?;
match (&state.block.btype, state.block_stack.last()) {
(Word::While, Some(prev_block)) => {
state
.instructions
.push(Instruction::Jmp(prev_block.last_block_start));
}
_ => {
return Err(token_info.custom(ErrorType::ContinueOutsideLoop));
}
}
}

_ => {
if state.has_capability(&Capability::Ihave) {
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/lexer/word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ pub(crate) enum Word {
Local,
While,
Let,
Continue,
}

pub(crate) static WORDS: phf::Map<&'static str, Word> = phf_map! {
Expand Down Expand Up @@ -286,6 +287,7 @@ pub(crate) static WORDS: phf::Map<&'static str, Word> = phf_map! {
"local" => Word::Local,
"while" => Word::While,
"let" => Word::Let,
"continue" => Word::Continue,
};

impl Display for Word {
Expand Down Expand Up @@ -418,6 +420,7 @@ impl Display for Word {
Word::Local => f.write_str("local"),
Word::While => f.write_str("while"),
Word::Let => f.write_str("let"),
Word::Continue => f.write_str("continue"),
}
}
}
2 changes: 2 additions & 0 deletions src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pub enum ErrorType {
LabelAlreadyDefined(String),
LabelUndefined(String),
BreakOutsideLoop,
ContinueOutsideLoop,
UnsupportedComparator(String),
DuplicatedParameter,
UndeclaredCapability(Capability),
Expand Down Expand Up @@ -464,6 +465,7 @@ impl Display for CompileError {
ErrorType::LabelAlreadyDefined(value) => write!(f, "Label {value:?} already defined"),
ErrorType::LabelUndefined(value) => write!(f, "Label {value:?} does not exist"),
ErrorType::BreakOutsideLoop => write!(f, "Break used outside of foreverypart loop"),
ErrorType::ContinueOutsideLoop => write!(f, "Continue used outside of while loop"),
ErrorType::UnsupportedComparator(value) => {
write!(f, "Comparator {value:?} is not supported")
}
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ impl<'x> Variable<'x> {

pub fn to_string_array<'y: 'x>(&'y self) -> Vec<Cow<'x, str>> {
match self {
Variable::Array(l) => l.into_iter().map(|i| i.to_cow()).collect(),
Variable::Array(l) => l.iter().map(|i| i.to_cow()).collect(),
Variable::ArrayRef(l) => l.iter().map(|i| i.to_cow()).collect(),
v if !v.is_empty() => vec![v.to_cow()],
_ => vec![],
Expand Down
29 changes: 29 additions & 0 deletions tests/stalwart/while.svtest
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,32 @@ test "While - body variable" {
}
}


test "While - continue" {
let "i" "0";
let "j" "0";

while "i < 5" {
let "i" "i+1";
let "j" "j+1";
}

if eval "i != j" {
test_fail "i != j";
}

let "i" "0";
let "j" "0";

while "i < 5" {
let "i" "i+1";
continue;
let "j" "j+1";
}

if eval "j != 0 || i == 0" {
test_fail "while continue failed";
}

}

0 comments on commit 0932d6a

Please sign in to comment.