mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 07:33:01 +00:00 
			
		
		
		
	Begin implementing module system.
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -16,7 +16,7 @@ all: $(GST_TARGET) | |||||||
| ################################### | ################################### | ||||||
| GST_CORE_SOURCES=$(addprefix core/,\ | GST_CORE_SOURCES=$(addprefix core/,\ | ||||||
| 				 compile.c disasm.c parse.c stl.c strings.c \ | 				 compile.c disasm.c parse.c stl.c strings.c \ | ||||||
| 				 value.c vm.c ds.c gc.c thread.c serialize.c) | 				 value.c vm.c ds.c gc.c thread.c serialize.c capi.c) | ||||||
| GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES)) | GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES)) | ||||||
| $(GST_CORELIB): $(GST_CORE_OBJECTS) $(GST_HEADERS) | $(GST_CORELIB): $(GST_CORE_OBJECTS) $(GST_HEADERS) | ||||||
| 	ar rcs $(GST_CORELIB) $(GST_CORE_OBJECTS) | 	ar rcs $(GST_CORELIB) $(GST_CORE_OBJECTS) | ||||||
|   | |||||||
| @@ -16,10 +16,7 @@ void debug_repl(FILE *in, FILE *out) { | |||||||
|     GstCompiler c; |     GstCompiler c; | ||||||
|  |  | ||||||
|     gst_init(&vm); |     gst_init(&vm); | ||||||
|  |     gst_stl_load(&vm); | ||||||
|     vm.rootenv.type = GST_OBJECT; |  | ||||||
|     vm.rootenv.data.object = gst_object(&vm, 10); |  | ||||||
|     gst_object_put(&vm, vm.rootenv.data.object, gst_load_csymbol(&vm, "_ENV"), vm.rootenv); |  | ||||||
|  |  | ||||||
|     for (;;) { |     for (;;) { | ||||||
|  |  | ||||||
| @@ -61,9 +58,8 @@ void debug_repl(FILE *in, FILE *out) { | |||||||
|         /* Try to compile generated AST */ |         /* Try to compile generated AST */ | ||||||
|         gst_compiler(&c, &vm); |         gst_compiler(&c, &vm); | ||||||
|         func.type = GST_NIL; |         func.type = GST_NIL; | ||||||
|         gst_compiler_add_global(&c, "ans", func); |         gst_compiler_usemodule(&c, "std"); | ||||||
|         gst_stl_load(&c); |         gst_compiler_global(&c, "ans", gst_object_get(vm.rootenv, gst_load_csymbol(&vm, "ans"))); | ||||||
|         gst_compiler_env(&c, vm.rootenv); |  | ||||||
|         func.type = GST_FUNCTION; |         func.type = GST_FUNCTION; | ||||||
|         func.data.function = gst_compiler_compile(&c, p.value); |         func.data.function = gst_compiler_compile(&c, p.value); | ||||||
|  |  | ||||||
| @@ -98,7 +94,7 @@ void debug_repl(FILE *in, FILE *out) { | |||||||
|             continue; |             continue; | ||||||
|         } else if (out) { |         } else if (out) { | ||||||
|             fprintf(out, "%s\n", (char *)gst_to_string(&vm, vm.ret)); |             fprintf(out, "%s\n", (char *)gst_to_string(&vm, vm.ret)); | ||||||
|             gst_object_put(&vm, vm.rootenv.data.object, gst_load_csymbol(&vm, "ans"), vm.ret); |             gst_object_put(&vm, vm.rootenv, gst_load_csymbol(&vm, "ans"), vm.ret); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								core/capi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								core/capi.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | #include <gst/gst.h> | ||||||
|  |  | ||||||
|  | GstObject *gst_c_module(Gst *vm, const GstModuleItem *mod) { | ||||||
|  |     GstObject *module = gst_object(vm, 10); | ||||||
|  |     while (mod->name != NULL) { | ||||||
|  |         GstValue key = gst_load_csymbol(vm, mod->name); | ||||||
|  |         GstValue val; | ||||||
|  |         val.type = GST_CFUNCTION; | ||||||
|  |         val.data.cfunction = mod->data; | ||||||
|  |         gst_object_put(vm, module, key, val); | ||||||
|  |         mod++; | ||||||
|  |     } | ||||||
|  |     return module; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void gst_c_register(Gst *vm, const char *packagename, GstObject *mod) { | ||||||
|  |     GstValue modv; | ||||||
|  |     if (vm->rootenv == NULL) | ||||||
|  |         vm->rootenv = gst_object(vm, 10); | ||||||
|  |     modv.type = GST_OBJECT; | ||||||
|  |     modv.data.object = mod; | ||||||
|  |     gst_object_put(vm, vm->rootenv, gst_load_csymbol(vm, packagename), modv); | ||||||
|  | } | ||||||
| @@ -327,7 +327,8 @@ static uint16_t compiler_declare_symbol(GstCompiler *c, GstScope *scope, GstValu | |||||||
|  |  | ||||||
| /* Try to resolve a symbol. If the symbol can be resovled, return true and | /* Try to resolve a symbol. If the symbol can be resovled, return true and | ||||||
|  * pass back the level and index by reference. */ |  * pass back the level and index by reference. */ | ||||||
| static int symbol_resolve(GstScope *scope, GstValue x, uint16_t *level, uint16_t *index) { | static int symbol_resolve(GstCompiler *c, GstValue x, uint16_t *level, uint16_t *index) { | ||||||
|  |     GstScope *scope = c->tail; | ||||||
|     uint32_t currentLevel = scope->level; |     uint32_t currentLevel = scope->level; | ||||||
|     while (scope) { |     while (scope) { | ||||||
|         GstValue check = gst_object_get(scope->locals, x); |         GstValue check = gst_object_get(scope->locals, x); | ||||||
| @@ -336,6 +337,7 @@ static int symbol_resolve(GstScope *scope, GstValue x, uint16_t *level, uint16_t | |||||||
|             *index = (uint16_t) check.data.number; |             *index = (uint16_t) check.data.number; | ||||||
|             return 1; |             return 1; | ||||||
|         } |         } | ||||||
|  |          | ||||||
|         scope = scope->parent; |         scope = scope->parent; | ||||||
|     } |     } | ||||||
|     return 0; |     return 0; | ||||||
| @@ -409,13 +411,13 @@ static Slot compile_nonref_type(GstCompiler *c, FormOptions opts, GstValue x) { | |||||||
| /* Compile a symbol. Resolves any kind of symbol. */ | /* Compile a symbol. Resolves any kind of symbol. */ | ||||||
| static Slot compile_symbol(GstCompiler *c, FormOptions opts, GstValue sym) { | static Slot compile_symbol(GstCompiler *c, FormOptions opts, GstValue sym) { | ||||||
|     GstBuffer * buffer = c->buffer; |     GstBuffer * buffer = c->buffer; | ||||||
|     GstScope * scope = c->tail; |  | ||||||
|     uint16_t index = 0; |     uint16_t index = 0; | ||||||
|     uint16_t level = 0; |     uint16_t level = 0; | ||||||
|     Slot ret; |     Slot ret; | ||||||
|     if (opts.resultUnused) return nil_slot(); |     if (opts.resultUnused) return nil_slot(); | ||||||
|     if (!symbol_resolve(scope, sym, &level, &index)) |     if (!symbol_resolve(c, sym, &level, &index)) { | ||||||
|         c_error(c, "undefined symbol"); |         c_error(c, "undefined symbol"); | ||||||
|  |     } | ||||||
|     if (level > 0) { |     if (level > 0) { | ||||||
|         /* We have an upvalue */ |         /* We have an upvalue */ | ||||||
|         ret = compiler_get_target(c, opts); |         ret = compiler_get_target(c, opts); | ||||||
| @@ -452,7 +454,7 @@ static Slot compile_assign(GstCompiler *c, FormOptions opts, GstValue left, GstV | |||||||
|     Slot slot; |     Slot slot; | ||||||
|     subOpts.isTail = 0; |     subOpts.isTail = 0; | ||||||
|     subOpts.resultUnused = 0; |     subOpts.resultUnused = 0; | ||||||
|     if (symbol_resolve(scope, left, &level, &target)) { |     if (symbol_resolve(c, left, &level, &target)) { | ||||||
|         /* Check if we have an up value. Otherwise, it's just a normal |         /* Check if we have an up value. Otherwise, it's just a normal | ||||||
|          * local variable */ |          * local variable */ | ||||||
|         if (level != 0) { |         if (level != 0) { | ||||||
| @@ -1022,39 +1024,35 @@ void gst_compiler(GstCompiler *c, Gst *vm) { | |||||||
|     compiler_push_scope(c, 0); |     compiler_push_scope(c, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Add environment */ | /* Add a global variable */ | ||||||
| void gst_compiler_env(GstCompiler *c, GstValue env) { | void gst_compiler_global(GstCompiler *c, const char *name, GstValue x) { | ||||||
|  |     GstValue sym = gst_load_csymbol(c->vm, name); | ||||||
|  |     compiler_declare_symbol(c, c->tail, sym); | ||||||
|  |     gst_array_push(c->vm, c->env, x);                 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Add many global variables */ | ||||||
|  | void gst_compiler_globals(GstCompiler *c, GstObject *env) { | ||||||
|     uint32_t i; |     uint32_t i; | ||||||
|     GstBucket *bucket; |     GstBucket *bucket; | ||||||
|     /* Register everything in environment */ |     for (i = 0; i < env->capacity; ++i) { | ||||||
|     if (env.type == GST_OBJECT) { |         bucket = env->buckets[i]; | ||||||
|         for (i = 0; i < env.data.object->capacity; ++i) { |         while (bucket) { | ||||||
|             bucket = env.data.object->buckets[i]; |             if (bucket->key.type == GST_SYMBOL) { | ||||||
|             while (bucket) { |                 compiler_declare_symbol(c, c->tail, bucket->key); | ||||||
|                 if (bucket->key.type == GST_SYMBOL) { |                 gst_array_push(c->vm, c->env, bucket->value);                 | ||||||
|                     compiler_declare_symbol(c, c->tail, bucket->key); |  | ||||||
|                     gst_array_push(c->vm, c->env, bucket->value); |  | ||||||
|                 } |  | ||||||
|                 bucket = bucket->next; |  | ||||||
|             } |             } | ||||||
|  |             bucket = bucket->next; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Register a global for the compilation environment. */ | /* Use a module that was loaded into the vm */ | ||||||
| void gst_compiler_add_global(GstCompiler *c, const char *name, GstValue x) { | void gst_compiler_usemodule(GstCompiler *c, const char *modulename) { | ||||||
|     GstValue sym = gst_load_cstring(c->vm, name); |     GstValue mod = gst_object_get(c->vm->rootenv, gst_load_csymbol(c->vm, modulename)); | ||||||
|     sym.type = GST_SYMBOL; |     if (mod.type == GST_OBJECT) { | ||||||
|     compiler_declare_symbol(c, c->tail, sym); |         gst_compiler_globals(c, mod.data.object); | ||||||
|     gst_array_push(c->vm, c->env, x); |     } | ||||||
| } |  | ||||||
|  |  | ||||||
| /* Register a global c function for the compilation environment. */ |  | ||||||
| void gst_compiler_add_global_cfunction(GstCompiler *c, const char *name, GstCFunction f) { |  | ||||||
|     GstValue func; |  | ||||||
|     func.type = GST_CFUNCTION; |  | ||||||
|     func.data.cfunction = f; |  | ||||||
|     gst_compiler_add_global(c, name, func); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Compile interface. Returns a function that evaluates the | /* Compile interface. Returns a function that evaluates the | ||||||
|   | |||||||
| @@ -235,13 +235,15 @@ void gst_mem_tag(void *mem, uint32_t tags) { | |||||||
|  |  | ||||||
| /* Run garbage collection */ | /* Run garbage collection */ | ||||||
| void gst_collect(Gst *vm) { | void gst_collect(Gst *vm) { | ||||||
|  |     GstValueUnion renv; | ||||||
|     /* Thread can be null */ |     /* Thread can be null */ | ||||||
|     if (vm->thread) { |     if (vm->thread) { | ||||||
|         GstValueUnion t; |         GstValueUnion t; | ||||||
|         t.thread = vm->thread; |         t.thread = vm->thread; | ||||||
|         gst_mark(vm, t, GST_THREAD); |         gst_mark(vm, t, GST_THREAD); | ||||||
|     } |     } | ||||||
|     gst_mark_value(vm, vm->rootenv); |     renv.object = vm->rootenv; | ||||||
|  |     gst_mark(vm, renv, GST_OBJECT); | ||||||
|     gst_mark_value(vm, vm->ret); |     gst_mark_value(vm, vm->ret); | ||||||
|     gst_sweep(vm); |     gst_sweep(vm); | ||||||
|     vm->nextCollection = 0; |     vm->nextCollection = 0; | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								core/stl.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								core/stl.c
									
									
									
									
									
								
							| @@ -396,12 +396,7 @@ int gst_stl_serialize(Gst *vm) { | |||||||
| /* Bootstraping */ | /* Bootstraping */ | ||||||
| /****/ | /****/ | ||||||
|  |  | ||||||
| struct GstRegistryItem { | static const GstModuleItem const std_module[] = { | ||||||
|     const char *name; |  | ||||||
|     GstCFunction func; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const struct GstRegistryItem const registry[] = { |  | ||||||
|     {"+", gst_stl_add}, |     {"+", gst_stl_add}, | ||||||
|     {"*", gst_stl_mul}, |     {"*", gst_stl_mul}, | ||||||
|     {"-", gst_stl_sub}, |     {"-", gst_stl_sub}, | ||||||
| @@ -430,9 +425,7 @@ static const struct GstRegistryItem const registry[] = { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| /* Load all libraries */ | /* Load all libraries */ | ||||||
| void gst_stl_load(GstCompiler *c) { | void gst_stl_load(Gst *vm) { | ||||||
|     const struct GstRegistryItem *item; |     GstObject *module = gst_c_module(vm, std_module); | ||||||
|     for (item = registry; item->name; ++item) { |     gst_c_register(vm, "std", module); | ||||||
|         gst_compiler_add_global_cfunction(c, item->name, item->func); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -504,16 +504,17 @@ void gst_init(Gst *vm) { | |||||||
|     vm->black = 0; |     vm->black = 0; | ||||||
|     /* Add thread */ |     /* Add thread */ | ||||||
|     vm->thread = NULL; |     vm->thread = NULL; | ||||||
|     vm->rootenv.type = GST_NIL; |  | ||||||
|     /* Set up string cache */ |     /* Set up string cache */ | ||||||
|     gst_stringcache_init(vm, 128); |     gst_stringcache_init(vm, 128); | ||||||
|  |     /* Set up global env */ | ||||||
|  |     vm->rootenv = NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Clear all memory associated with the VM */ | /* Clear all memory associated with the VM */ | ||||||
| void gst_deinit(Gst *vm) { | void gst_deinit(Gst *vm) { | ||||||
|     gst_clear_memory(vm); |     gst_clear_memory(vm); | ||||||
|     vm->thread = NULL; |     vm->thread = NULL; | ||||||
|     vm->rootenv.type = GST_NIL; |     vm->rootenv = NULL; | ||||||
|     vm->ret.type = GST_NIL; |     vm->ret.type = GST_NIL; | ||||||
|     gst_stringcache_deinit(vm); |     gst_stringcache_deinit(vm); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,14 +20,14 @@ struct GstCompiler { | |||||||
| /* Initialize the Compiler */ | /* Initialize the Compiler */ | ||||||
| void gst_compiler(GstCompiler *c, Gst *vm); | void gst_compiler(GstCompiler *c, Gst *vm); | ||||||
|  |  | ||||||
| /* Register an environment for compilation */ | /* Add many globals */ | ||||||
| void gst_compiler_env(GstCompiler *c, GstValue env); | void gst_compiler_globals(GstCompiler *c, GstObject *env); | ||||||
|  |  | ||||||
| /* Register a global for the compilation environment. */ | /* Register a global for the compilation environment. */ | ||||||
| void gst_compiler_add_global(GstCompiler *c, const char *name, GstValue x); | void gst_compiler_global(GstCompiler *c, const char *name, GstValue x); | ||||||
|  |  | ||||||
| /* Register a global c function for the compilation environment. */ | /* Use a module */ | ||||||
| void gst_compiler_add_global_cfunction(GstCompiler *c, const char *name, GstCFunction f); | void gst_compiler_usemodule(GstCompiler *c, const char *modulename); | ||||||
|  |  | ||||||
| /* Compile a function that evaluates the given form. */ | /* Compile a function that evaluates the given form. */ | ||||||
| GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form); | GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form); | ||||||
|   | |||||||
| @@ -131,6 +131,15 @@ typedef union GstValueUnion GstValueUnion; | |||||||
| /* Definitely implementation details */ | /* Definitely implementation details */ | ||||||
| typedef struct GstBucket GstBucket; | typedef struct GstBucket GstBucket; | ||||||
|  |  | ||||||
|  | /* API Types */ | ||||||
|  | typedef struct GstModuleItem GstModuleItem; | ||||||
|  |  | ||||||
|  | /* C Api data types */ | ||||||
|  | struct GstModuleItem { | ||||||
|  |     const char *name; | ||||||
|  |     GstCFunction data; | ||||||
|  | }; | ||||||
|  |  | ||||||
| /* Union datatype */ | /* Union datatype */ | ||||||
| union GstValueUnion { | union GstValueUnion { | ||||||
|     GstBoolean boolean; |     GstBoolean boolean; | ||||||
| @@ -174,7 +183,7 @@ struct GstThread { | |||||||
|     } status; |     } status; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* A dynamic array type. Useful for implementing a stack. */ | /* A dynamic array type. */ | ||||||
| struct GstArray { | struct GstArray { | ||||||
|     uint32_t count; |     uint32_t count; | ||||||
|     uint32_t capacity; |     uint32_t capacity; | ||||||
| @@ -257,7 +266,7 @@ struct Gst { | |||||||
|     /* Thread */ |     /* Thread */ | ||||||
|     GstThread *thread; |     GstThread *thread; | ||||||
|     /* A GC root */ |     /* A GC root */ | ||||||
|     GstValue rootenv; |     GstObject *rootenv; | ||||||
|     /* Return state */ |     /* Return state */ | ||||||
|     const char *crash; |     const char *crash; | ||||||
|     GstValue ret; /* Returned value from gst_start. Also holds errors. */ |     GstValue ret; /* Returned value from gst_start. Also holds errors. */ | ||||||
| @@ -462,4 +471,11 @@ GstValue gst_arg(Gst *vm, uint16_t index); | |||||||
| void gst_set_arg(Gst *vm, uint16_t index, GstValue x); | void gst_set_arg(Gst *vm, uint16_t index, GstValue x); | ||||||
| uint16_t gst_count_args(Gst *vm); | uint16_t gst_count_args(Gst *vm); | ||||||
|  |  | ||||||
|  | /***/ | ||||||
|  | /* C Api */ | ||||||
|  | /***/ | ||||||
|  |  | ||||||
|  | GstObject *gst_c_module(Gst *vm, const GstModuleItem *mod); | ||||||
|  | void gst_c_register(Gst *vm, const char *packagename, GstObject *mod); | ||||||
|  |  | ||||||
| #endif // GST_H_defined | #endif // GST_H_defined | ||||||
|   | |||||||
| @@ -2,10 +2,9 @@ | |||||||
| #define stl_h_INCLUDED | #define stl_h_INCLUDED | ||||||
|  |  | ||||||
| #include <gst/gst.h> | #include <gst/gst.h> | ||||||
| #include <gst/compile.h> |  | ||||||
|  |  | ||||||
| /* Load the standard library */ | /* Load the standard library */ | ||||||
| void gst_stl_load(GstCompiler *c); | void gst_stl_load(Gst *vm); | ||||||
|  |  | ||||||
| #endif // stl_h_INCLUDED | #endif // stl_h_INCLUDED | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose