Skip to content

Commit 75e44f9

Browse files
Add DRETURN
1 parent d0a7d76 commit 75e44f9

File tree

5 files changed

+36
-0
lines changed

5 files changed

+36
-0
lines changed

SPECIFICATION.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ Program termination is exposed via `EXIT`. `EXIT()` or `EXIT(code)` requests imm
9595

9696
Memory-management and function-return behavior are also exposed via operators. `DEL(x)` deletes the variable `x` from the current environment, freeing its memory; any subsequent reference to `x` is an error unless `x` is re-assigned. `RETURN(a)`, when executed inside a function body, immediately terminates that function and returns the value of `a` to the caller. Executing `RETURN` outside of a function is a runtime error.
9797

98+
`DRETURN(x)` is a convenience operator combining `RETURN` and `DEL`: when executed inside a function body it retrieves the current value of the identifier `x`, deletes the binding `x` from the environment (so subsequent references are an error), and returns the retrieved value to the caller. Using `DRETURN` outside of a function is a runtime error. If `x` is frozen or undefined, `DRETURN(x)` raises the same runtime errors as `DEL(x)` or a reference to `x` would.
99+
98100

99101
## 5. Statements and Control Flow
100102

asmln.exe

196 KB
Binary file not shown.

interpreter.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
Parser,
3535
Program,
3636
ReturnStatement,
37+
DReturnStatement,
3738
SourceLocation,
3839
Statement,
3940
TensorLiteral,
@@ -1801,6 +1802,26 @@ def _execute_statement(self, statement: Statement, env: Environment) -> None:
18011802
closure=env,
18021803
)
18031804
return
1805+
if isinstance(statement, DReturnStatement):
1806+
frame: Frame = self.call_stack[-1]
1807+
if frame.name == "<top-level>":
1808+
raise ASMRuntimeError("DRETURN outside of function", location=statement.location, rewrite_rule="DRETURN")
1809+
# Expect identifier expression to delete a symbol
1810+
expr = statement.expression
1811+
if not isinstance(expr, Identifier):
1812+
raise ASMRuntimeError("DRETURN expects identifier", location=statement.location, rewrite_rule="DRETURN")
1813+
name = expr.name
1814+
try:
1815+
value = env.get(name)
1816+
except ASMRuntimeError as err:
1817+
err.location = statement.location
1818+
raise
1819+
try:
1820+
env.delete(name)
1821+
except ASMRuntimeError as err:
1822+
err.location = statement.location
1823+
raise
1824+
raise ReturnSignal(value)
18041825
if isinstance(statement, ReturnStatement):
18051826
frame: Frame = self.call_stack[-1]
18061827
if frame.name == "<top-level>":

lexer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class Token:
2727
"FOR",
2828
"FUNC",
2929
"RETURN",
30+
"DRETURN",
3031
"BREAK",
3132
"CONTINUE",
3233
"GOTO",

parser.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ class ReturnStatement(Statement):
9191
expression: Optional["Expression"]
9292

9393

94+
@dataclass
95+
class DReturnStatement(Statement):
96+
expression: "Expression"
97+
98+
9499
@dataclass
95100
class BreakStatement(Statement):
96101
expression: "Expression"
@@ -192,6 +197,8 @@ def _parse_statement(self) -> Statement:
192197
return self._parse_for()
193198
if token.type == "RETURN":
194199
return self._parse_return()
200+
if token.type == "DRETURN":
201+
return self._parse_dreturn()
195202
if token.type == "BREAK":
196203
return self._parse_break()
197204
if token.type == "CONTINUE":
@@ -290,6 +297,11 @@ def _parse_return(self) -> ReturnStatement:
290297
expression: Expression = self._parse_parenthesized_expression()
291298
return ReturnStatement(location=self._location_from_token(keyword), expression=expression)
292299

300+
def _parse_dreturn(self) -> DReturnStatement:
301+
keyword = self._consume("DRETURN")
302+
expression: Expression = self._parse_parenthesized_expression()
303+
return DReturnStatement(location=self._location_from_token(keyword), expression=expression)
304+
293305
def _parse_break(self) -> BreakStatement:
294306
keyword = self._consume("BREAK")
295307
expression: Expression = self._parse_parenthesized_expression()

0 commit comments

Comments
 (0)