Skip to content

Commit

Permalink
implement range based for over iterables
Browse files Browse the repository at this point in the history
  • Loading branch information
NotAPenguin0 committed Jul 5, 2022
1 parent a252990 commit 23a58f8
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/pscript/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,20 @@ ps::value context::execute(peg::Ast const* node, block_scope* scope, std::string
}
// using for (let i : iterable) syntax
else if (iterable) {
ps::value iterable_val = evaluate_expression(iterable, scope);
if (iterable_val.get_type() != ps::type::list) {
report_error(iterable, fmt::format("In range-for expression: Iterated variable '{}' 'has type '{}', which is not iterable.",
iterable->token_to_string(), type_str(iterable_val.get_type())));
PLIB_UNREACHABLE();
}

ps::list& list = static_cast<ps::list&>(iterable_val);
for (std::size_t i = 0; i < list->size(); ++i) {
block_scope local_scope {};
local_scope.parent = scope;
ps::variable& it = create_variable(identifier->token_to_string(), ps::value::ref(list->get(i)), &local_scope);
execute(compound, &local_scope, namespace_prefix);
}
}
} else { // regular for loop
peg::Ast const* initializer = find_child_with_type(content, "declaration");
Expand Down
14 changes: 14 additions & 0 deletions tests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1032,4 +1032,18 @@ TEST_CASE("range-for") {
ps::script script(source, ctx);
ctx.execute(script);
}

SECTION("list iteration") {
std::string source = R"(
import std.io;
let l = [1, 2, 3, 4, 5];
for (let i : l) {
std.io.print(i);
}
)";

ps::script script(source, ctx);
ctx.execute(script);
}
}

0 comments on commit 23a58f8

Please sign in to comment.