forked from defunkt/ReefVM
update docs
This commit is contained in:
parent
17d846b999
commit
8d9510e9ae
34
CLAUDE.md
34
CLAUDE.md
|
|
@ -222,6 +222,40 @@ HALT
|
|||
HALT
|
||||
```
|
||||
|
||||
### Function Definition Patterns
|
||||
|
||||
When defining functions, you MUST prevent the PC from falling through into function bodies. Two patterns:
|
||||
|
||||
**Pattern 1: JUMP over function bodies (Recommended)**
|
||||
```
|
||||
MAKE_FUNCTION (params) .body
|
||||
STORE function_name
|
||||
JUMP .end ; Skip over function body
|
||||
.body:
|
||||
<function code>
|
||||
RETURN
|
||||
.end:
|
||||
<continue with program>
|
||||
```
|
||||
|
||||
**Pattern 2: Function bodies after HALT**
|
||||
```
|
||||
MAKE_FUNCTION (params) .body
|
||||
STORE function_name
|
||||
<use the function>
|
||||
HALT ; Stop before function bodies
|
||||
.body:
|
||||
<function code>
|
||||
RETURN
|
||||
```
|
||||
|
||||
Pattern 1 is required for:
|
||||
- Defining multiple functions before using them
|
||||
- REPL mode
|
||||
- Any case where execution continues after defining a function
|
||||
|
||||
Pattern 2 only works if you HALT before reaching function bodies.
|
||||
|
||||
### REPL Mode (Incremental Execution)
|
||||
|
||||
For building REPLs (like the Shrimp REPL), use `vm.continue()` and `vm.appendBytecode()`:
|
||||
|
|
|
|||
60
GUIDE.md
60
GUIDE.md
|
|
@ -241,6 +241,40 @@ CALL
|
|||
|
||||
## Compiler Patterns
|
||||
|
||||
### Function Definitions
|
||||
|
||||
When defining functions, you must prevent the PC from "falling through" into the function body during sequential execution. There are two standard patterns:
|
||||
|
||||
**Pattern 1: JUMP over function bodies (Recommended)**
|
||||
```
|
||||
MAKE_FUNCTION (params) .body
|
||||
STORE function_name
|
||||
JUMP .end ; Skip over function body
|
||||
.body:
|
||||
<function code>
|
||||
RETURN
|
||||
.end:
|
||||
<continue with program>
|
||||
```
|
||||
|
||||
**Pattern 2: Function bodies after HALT**
|
||||
```
|
||||
MAKE_FUNCTION (params) .body
|
||||
STORE function_name
|
||||
<use the function>
|
||||
HALT ; Stop execution before function bodies
|
||||
.body:
|
||||
<function code>
|
||||
RETURN
|
||||
```
|
||||
|
||||
**Important**: Pattern 2 only works if you HALT before reaching function bodies. Pattern 1 is more flexible and required for:
|
||||
- Defining multiple functions before using them
|
||||
- REPL mode (incremental execution)
|
||||
- Any case where execution continues after defining a function
|
||||
|
||||
**Why?** `MAKE_FUNCTION` creates a function value but doesn't jump to the body—it just stores the body's address. Without JUMP or HALT, the PC increments into the function body and executes it as top-level code.
|
||||
|
||||
### If-Else
|
||||
```
|
||||
<condition>
|
||||
|
|
@ -362,7 +396,8 @@ Functions automatically capture current scope:
|
|||
PUSH 0
|
||||
STORE counter
|
||||
MAKE_FUNCTION () .increment
|
||||
RETURN
|
||||
STORE increment_fn
|
||||
JUMP .main
|
||||
|
||||
.increment:
|
||||
LOAD counter ; Captured variable
|
||||
|
|
@ -371,6 +406,18 @@ RETURN
|
|||
STORE counter
|
||||
LOAD counter
|
||||
RETURN
|
||||
|
||||
.main:
|
||||
LOAD increment_fn
|
||||
PUSH 0
|
||||
PUSH 0
|
||||
CALL ; Returns 1
|
||||
POP
|
||||
LOAD increment_fn
|
||||
PUSH 0
|
||||
PUSH 0
|
||||
CALL ; Returns 2 (counter persists!)
|
||||
HALT
|
||||
```
|
||||
|
||||
### Tail Recursion
|
||||
|
|
@ -378,7 +425,7 @@ Use TAIL_CALL instead of CALL for last call:
|
|||
```
|
||||
MAKE_FUNCTION (n acc) .factorial
|
||||
STORE factorial
|
||||
<...>
|
||||
JUMP .main
|
||||
|
||||
.factorial:
|
||||
LOAD n
|
||||
|
|
@ -398,6 +445,15 @@ STORE factorial
|
|||
PUSH 2
|
||||
PUSH 0
|
||||
TAIL_CALL ; Reuses stack frame
|
||||
|
||||
.main:
|
||||
LOAD factorial
|
||||
PUSH 5
|
||||
PUSH 1
|
||||
PUSH 2
|
||||
PUSH 0
|
||||
CALL ; factorial(5, 1) = 120
|
||||
HALT
|
||||
```
|
||||
|
||||
### Optional Function Calls (TRY_CALL)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user