Skip to content

Commit

Permalink
Merge pull request #145 from Vardan2009/master
Browse files Browse the repository at this point in the history
Added `fallout` statement
  • Loading branch information
Almas-Ali authored May 27, 2024
2 parents 3f0114b + ed2fae2 commit c24d8de
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 0 deletions.
12 changes: 12 additions & 0 deletions core/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@ def visit_SwitchNode(self, node: SwitchNode, context: Context) -> RTResult[Value
assert subject is not None

should_continue = False
fallout = False
for expr, body in node.cases:
if not should_continue:
value = res.register(self.visit(expr, context))
Expand All @@ -814,6 +815,14 @@ def visit_SwitchNode(self, node: SwitchNode, context: Context) -> RTResult[Value
if res.should_return():
return res

if res.should_fallout:
should_continue = True
fallout = True
continue

if fallout:
continue

if res.should_fallthrough:
should_continue = True
continue
Expand All @@ -830,6 +839,9 @@ def visit_SwitchNode(self, node: SwitchNode, context: Context) -> RTResult[Value
def visit_FallthroughNode(self, node: FallthroughNode, context: Context) -> RTResult[Value]:
return RTResult[Value]().success(Null.null()).fallthrough()

def visit_FalloutNode(self, node: FalloutNode, context: Context) -> RTResult[Value]:
return RTResult[Value]().success(Null.null()).fallout()

def visit_AttrAccessNode(self, node: AttrAccessNode, context: Context) -> RTResult[Value]:
res = RTResult[Value]()
value = res.register(self.visit(node.node_to_access, context))
Expand Down
6 changes: 6 additions & 0 deletions core/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ class FallthroughNode:
pos_end: Position


@dataclass
class FalloutNode:
pos_start: Position
pos_end: Position


@dataclass
class TryNode:
try_block: Node
Expand Down
19 changes: 19 additions & 0 deletions core/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,18 @@ def statement(self) -> ParseResult[Optional[Node]] | ParseResult[Node]:
return res.success(UnitRaiseNode(call, call.pos_start, call.pos_end))
return res.success(RaiseNode(call, call.pos_start, call.pos_end))

if self.current_tok.matches(TT_KEYWORD, "fallout"):
if not self.in_case:
return res.failure(
InvalidSyntaxError(
self.current_tok.pos_start,
self.current_tok.pos_end,
"Fallout statement must be inside a switch-case statement",
)
)
self.advance(res)
return res.success(FalloutNode(pos_start, self.current_tok.pos_start.copy()))

if self.current_tok.matches(TT_KEYWORD, "return"):
if not self.in_func:
return res.failure(
Expand Down Expand Up @@ -1501,6 +1513,7 @@ class RTResult(Generic[T]):
loop_should_break: bool
should_exit: bool
should_fallthrough: bool
should_fallout: bool

def __init__(self) -> None:
self.reset()
Expand All @@ -1513,6 +1526,7 @@ def reset(self) -> None:
self.loop_should_break = False
self.should_exit = False
self.should_fallthrough = False
self.should_fallout = False

U = TypeVar("U")

Expand All @@ -1523,6 +1537,7 @@ def register(self, res: RTResult[U]) -> Optional[U]:
self.loop_should_break = res.loop_should_break
self.should_exit = res.should_exit
self.should_fallthrough = res.should_fallthrough
self.should_fallout = res.should_fallout
return res.value

def success(self, value: T) -> RTResult[T]:
Expand Down Expand Up @@ -1559,6 +1574,10 @@ def fallthrough(self) -> RTResult[T]:
self.should_fallthrough = True
return self

def fallout(self) -> RTResult[T]:
self.should_fallout = True
return self

def failure(self, error: Error) -> RTResult[T]:
self.reset()
self.error = error
Expand Down
1 change: 1 addition & 0 deletions core/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ def copy(self) -> Position:
"default",
"fallthrough",
"raise",
"fallout",
]

TokenValue: TypeAlias = Optional[str | int | float]
Expand Down
10 changes: 10 additions & 0 deletions tests/fallout.rn
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
switch 44 {
case 42 -> print("42")
case 43 -> print("43")
case 44 -> fallout
case 45 -> print("45")
case 46 -> print("46")
case 47 -> print("47")
case 48 -> print("48")
default -> print("default")
}
1 change: 1 addition & 0 deletions tests/fallout.rn.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"code": 0, "stdout": "45\n46\n47\n48\ndefault\n", "stderr": ""}

0 comments on commit c24d8de

Please sign in to comment.