mirror of
https://github.com/janet-lang/janet
synced 2024-11-24 09:17:17 +00:00
Add self reference in closures without having to use vars.
This commit is contained in:
parent
0531866954
commit
acb706ca3a
26
README.md
26
README.md
@ -27,31 +27,17 @@ Byte code interpreter with an assembly interface
|
||||
Proper tail calls for functional code
|
||||
Direct interop with C
|
||||
|
||||
|
||||
|
||||
## Compiling and Running
|
||||
|
||||
Clone the repository and run:
|
||||
To build the runtime and run test, run
|
||||
```sh
|
||||
make run
|
||||
```
|
||||
To build the runtime and launch a repl.
|
||||
|
||||
## Basic programs
|
||||
|
||||
To run some basic programs, run the client with one argument, the name of the
|
||||
file to run. For example, the client that is built will be located in the
|
||||
client directory, so running a program `script.dst` from the project directory
|
||||
would be
|
||||
```bash
|
||||
client/dst script.dst
|
||||
make test
|
||||
```
|
||||
|
||||
You can also use the `--help` option to see more usage information for the vm.
|
||||
|
||||
## Running Tests
|
||||
|
||||
Simply run `make test` to run the currently minimal test suite.
|
||||
A repl can also be run with
|
||||
```sh
|
||||
make repl
|
||||
```
|
||||
|
||||
## Todo
|
||||
|
||||
|
@ -150,6 +150,7 @@ void dstc_scope(DstCompiler *c, int flags) {
|
||||
scope.defs = NULL;
|
||||
scope.slots = NULL;
|
||||
scope.smax = -1;
|
||||
scope.selfconst = -1;
|
||||
scope.bytecode_start = dst_v_count(c->buffer);
|
||||
scope.flags = flags;
|
||||
|
||||
@ -224,7 +225,6 @@ DstSlot dstc_resolve(
|
||||
for (i = 0; i < len; i++) {
|
||||
if (scope->syms[i].sym == sym) {
|
||||
ret = scope->syms[i].slot;
|
||||
ret.flags |= DST_SLOT_NAMED;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,9 @@ struct DstScope {
|
||||
* that corresponds to the direct parent's stack will always have value 0. */
|
||||
int32_t *envs;
|
||||
|
||||
/* Where to add reference to self in constants */
|
||||
int32_t selfconst;
|
||||
|
||||
int32_t bytecode_start;
|
||||
int flags;
|
||||
};
|
||||
|
@ -416,6 +416,7 @@ DstSlot dstc_fn(DstFopts opts, DstAst *ast, int32_t argn, const Dst *argv) {
|
||||
DstFopts subopts = dstc_fopts_default(c);
|
||||
const Dst *params;
|
||||
int varargs = 0;
|
||||
int selfref = 0;
|
||||
|
||||
if (argn < 2) {
|
||||
dstc_cerror(c, ast, "expected at least 2 arguments to function literal");
|
||||
@ -428,8 +429,11 @@ DstSlot dstc_fn(DstFopts opts, DstAst *ast, int32_t argn, const Dst *argv) {
|
||||
/* Read function parameters */
|
||||
parami = 0;
|
||||
arity = 0;
|
||||
head = dst_ast_unwrap(argv[0]);
|
||||
if (dst_checktype(head, DST_SYMBOL)) parami = 1;
|
||||
head = dst_ast_unwrap1(argv[0]);
|
||||
if (dst_checktype(head, DST_SYMBOL)) {
|
||||
selfref = 1;
|
||||
parami = 1;
|
||||
}
|
||||
if (parami >= argn) {
|
||||
dstc_cerror(c, dst_ast_node(argv[0]), "expected function parameters");
|
||||
return dstc_cslot(dst_wrap_nil());
|
||||
@ -438,7 +442,7 @@ DstSlot dstc_fn(DstFopts opts, DstAst *ast, int32_t argn, const Dst *argv) {
|
||||
if (dst_seq_view(paramv, ¶ms, ¶mcount)) {
|
||||
int32_t i;
|
||||
for (i = 0; i < paramcount; i++) {
|
||||
Dst param = dst_ast_unwrap(params[i]);
|
||||
Dst param = dst_ast_unwrap1(params[i]);
|
||||
if (dst_checktype(param, DST_SYMBOL)) {
|
||||
DstSlot slot;
|
||||
/* Check for varargs */
|
||||
@ -467,6 +471,17 @@ DstSlot dstc_fn(DstFopts opts, DstAst *ast, int32_t argn, const Dst *argv) {
|
||||
return dstc_cslot(dst_wrap_nil());
|
||||
}
|
||||
|
||||
/* Check for self ref */
|
||||
if (selfref) {
|
||||
DstSlot slot;
|
||||
slot.envindex = 0;
|
||||
slot.flags = DST_SLOT_NAMED | DST_FUNCTION;
|
||||
slot.constant = dst_wrap_nil();
|
||||
slot.index = dstc_lsloti(c);
|
||||
dstc_emit(c, ast, (slot.index << 8) | DOP_LOAD_SELF);
|
||||
dstc_nameslot(c, dst_unwrap_symbol(head), slot);
|
||||
}
|
||||
|
||||
/* Compile function body */
|
||||
for (argi = parami + 1; argi < argn; argi++) {
|
||||
DstSlot s;
|
||||
|
@ -69,8 +69,8 @@ enum DstOpCode {
|
||||
DOP_LOAD_FALSE,
|
||||
DOP_LOAD_INTEGER,
|
||||
DOP_LOAD_CONSTANT,
|
||||
DOP_LOAD_SELF,
|
||||
DOP_LOAD_UPVALUE,
|
||||
DOP_LOAD_SELF,
|
||||
DOP_SET_UPVALUE,
|
||||
DOP_CLOSURE,
|
||||
DOP_PUSH,
|
||||
|
Loading…
Reference in New Issue
Block a user