1
0
mirror of https://github.com/janet-lang/janet synced 2024-09-28 07:08:14 +00:00

Add self reference in closures without having to use vars.

This commit is contained in:
bakpakin 2018-01-19 12:37:37 -05:00
parent 0531866954
commit acb706ca3a
5 changed files with 29 additions and 25 deletions

View File

@ -27,31 +27,17 @@ Byte code interpreter with an assembly interface
Proper tail calls for functional code Proper tail calls for functional code
Direct interop with C Direct interop with C
## Compiling and Running ## Compiling and Running
Clone the repository and run: To build the runtime and run test, run
```sh ```sh
make run make test
```
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
``` ```
You can also use the `--help` option to see more usage information for the vm. A repl can also be run with
```sh
## Running Tests make repl
```
Simply run `make test` to run the currently minimal test suite.
## Todo ## Todo

View File

@ -150,6 +150,7 @@ void dstc_scope(DstCompiler *c, int flags) {
scope.defs = NULL; scope.defs = NULL;
scope.slots = NULL; scope.slots = NULL;
scope.smax = -1; scope.smax = -1;
scope.selfconst = -1;
scope.bytecode_start = dst_v_count(c->buffer); scope.bytecode_start = dst_v_count(c->buffer);
scope.flags = flags; scope.flags = flags;
@ -224,7 +225,6 @@ DstSlot dstc_resolve(
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (scope->syms[i].sym == sym) { if (scope->syms[i].sym == sym) {
ret = scope->syms[i].slot; ret = scope->syms[i].slot;
ret.flags |= DST_SLOT_NAMED;
goto found; goto found;
} }
} }

View File

@ -91,6 +91,9 @@ struct DstScope {
* that corresponds to the direct parent's stack will always have value 0. */ * that corresponds to the direct parent's stack will always have value 0. */
int32_t *envs; int32_t *envs;
/* Where to add reference to self in constants */
int32_t selfconst;
int32_t bytecode_start; int32_t bytecode_start;
int flags; int flags;
}; };

View File

@ -416,6 +416,7 @@ DstSlot dstc_fn(DstFopts opts, DstAst *ast, int32_t argn, const Dst *argv) {
DstFopts subopts = dstc_fopts_default(c); DstFopts subopts = dstc_fopts_default(c);
const Dst *params; const Dst *params;
int varargs = 0; int varargs = 0;
int selfref = 0;
if (argn < 2) { if (argn < 2) {
dstc_cerror(c, ast, "expected at least 2 arguments to function literal"); 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 */ /* Read function parameters */
parami = 0; parami = 0;
arity = 0; arity = 0;
head = dst_ast_unwrap(argv[0]); head = dst_ast_unwrap1(argv[0]);
if (dst_checktype(head, DST_SYMBOL)) parami = 1; if (dst_checktype(head, DST_SYMBOL)) {
selfref = 1;
parami = 1;
}
if (parami >= argn) { if (parami >= argn) {
dstc_cerror(c, dst_ast_node(argv[0]), "expected function parameters"); dstc_cerror(c, dst_ast_node(argv[0]), "expected function parameters");
return dstc_cslot(dst_wrap_nil()); 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, &params, &paramcount)) { if (dst_seq_view(paramv, &params, &paramcount)) {
int32_t i; int32_t i;
for (i = 0; i < paramcount; 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)) { if (dst_checktype(param, DST_SYMBOL)) {
DstSlot slot; DstSlot slot;
/* Check for varargs */ /* 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()); 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 */ /* Compile function body */
for (argi = parami + 1; argi < argn; argi++) { for (argi = parami + 1; argi < argn; argi++) {
DstSlot s; DstSlot s;

View File

@ -69,8 +69,8 @@ enum DstOpCode {
DOP_LOAD_FALSE, DOP_LOAD_FALSE,
DOP_LOAD_INTEGER, DOP_LOAD_INTEGER,
DOP_LOAD_CONSTANT, DOP_LOAD_CONSTANT,
DOP_LOAD_SELF,
DOP_LOAD_UPVALUE, DOP_LOAD_UPVALUE,
DOP_LOAD_SELF,
DOP_SET_UPVALUE, DOP_SET_UPVALUE,
DOP_CLOSURE, DOP_CLOSURE,
DOP_PUSH, DOP_PUSH,