mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +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 | 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 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -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; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -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, ¶ms, ¶mcount)) { |     if (dst_seq_view(paramv, ¶ms, ¶mcount)) { | ||||||
|         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; | ||||||
|   | |||||||
| @@ -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, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 bakpakin
					bakpakin