Skip to content

Commit

Permalink
Breaks
Browse files Browse the repository at this point in the history
  • Loading branch information
kuviman committed Nov 22, 2024
1 parent 1e27616 commit 683b0a6
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 10 deletions.
6 changes: 3 additions & 3 deletions examples/for-generator.ks
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ let generator = fn(()) {

for value in generator() {
print value;
#if value == "stop" {
#break;
#}
if value == "stop" then (
break;
);
};
3 changes: 0 additions & 3 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ impl ListCollector<'_> {
node = a;
if let Some(b) = b {
result.push(b);
} else {
break;
}
}
ast::Associativity::Right => {
Expand All @@ -72,7 +70,6 @@ impl ListCollector<'_> {
result.push(a);
} else {
node = a;
break;
}
}
}
Expand Down
35 changes: 33 additions & 2 deletions std/lib.ks
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,43 @@ const generator_handler = forall[T] {
(.handle = T -> () with ()) :: type
};

const loop_context = forall[T] {
(
.@"break" = T -> () with (), # TODO never
.@"continue" = () -> () with (),
) :: type
};

impl syntax @"syntax".for_loop = macro (.value_pattern, .generator, .body) => `(
with (.handle = $value_pattern => $body) :: generator_handler[_];
$generator
unwindable for_loop (
let handler = $value_pattern => (
const BodyResult = forall[T] { newtype :Break T | :Continue };
let body_result :: BodyResult[_] = unwindable body (
with (
.@"break" = () => unwind body (:Break ()),
.@"continue" = () => unwind body (:Continue),
) :: loop_context[()];
$body;
:Continue
);
match body_result (
| :Break value => unwind for_loop value
| :Continue => ()
);
);
with (.handle = handler) :: generator_handler[_];
$generator
)
);

impl syntax @"syntax".@"yield" = macro (.value) => `(
(current generator_handler[_]).handle $value
);

impl syntax @"syntax".break_without_value = macro _ => `(
break ()
);

impl syntax @"syntax".break_with_value = macro (.value) => `(
(current loop_context[_]).@"break" $value
);
4 changes: 2 additions & 2 deletions std/syntax.ks
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ syntax_module {
syntax @"builtin macro use" <- 1 = "use" namespace ".*";

# syntax return <- 2 = "return" value;
# syntax break_with_value <- 2 = "break" value;
# syntax break_without_value <- 2 = "break";
syntax break_with_value <- 2 = "break" value;
syntax break_without_value <- 2 = "break";
# syntax continue_impl <- 2 = "continue";
syntax yield <- 2 = "yield" value;

Expand Down

0 comments on commit 683b0a6

Please sign in to comment.