mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-30 23:23:07 +00:00 
			
		
		
		
	Add self reference in closures without having to use vars.
This commit is contained in:
		
							
								
								
									
										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, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 bakpakin
					bakpakin