1
0
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:
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
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

View File

@ -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;
}
}

View File

@ -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;
};

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);
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, &params, &paramcount)) {
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;

View File

@ -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,