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/,\ | ||||
| 				 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_CORELIB): $(GST_CORE_OBJECTS) $(GST_HEADERS) | ||||
| 	ar rcs $(GST_CORELIB) $(GST_CORE_OBJECTS) | ||||
|   | ||||
| @@ -16,10 +16,7 @@ void debug_repl(FILE *in, FILE *out) { | ||||
|     GstCompiler c; | ||||
|  | ||||
|     gst_init(&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); | ||||
|     gst_stl_load(&vm); | ||||
|  | ||||
|     for (;;) { | ||||
|  | ||||
| @@ -61,9 +58,8 @@ void debug_repl(FILE *in, FILE *out) { | ||||
|         /* Try to compile generated AST */ | ||||
|         gst_compiler(&c, &vm); | ||||
|         func.type = GST_NIL; | ||||
|         gst_compiler_add_global(&c, "ans", func); | ||||
|         gst_stl_load(&c); | ||||
|         gst_compiler_env(&c, vm.rootenv); | ||||
|         gst_compiler_usemodule(&c, "std"); | ||||
|         gst_compiler_global(&c, "ans", gst_object_get(vm.rootenv, gst_load_csymbol(&vm, "ans"))); | ||||
|         func.type = GST_FUNCTION; | ||||
|         func.data.function = gst_compiler_compile(&c, p.value); | ||||
|  | ||||
| @@ -98,7 +94,7 @@ void debug_repl(FILE *in, FILE *out) { | ||||
|             continue; | ||||
|         } else if (out) { | ||||
|             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 | ||||
|  * 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; | ||||
|     while (scope) { | ||||
|         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; | ||||
|             return 1; | ||||
|         } | ||||
|          | ||||
|         scope = scope->parent; | ||||
|     } | ||||
|     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. */ | ||||
| static Slot compile_symbol(GstCompiler *c, FormOptions opts, GstValue sym) { | ||||
|     GstBuffer * buffer = c->buffer; | ||||
|     GstScope * scope = c->tail; | ||||
|     uint16_t index = 0; | ||||
|     uint16_t level = 0; | ||||
|     Slot ret; | ||||
|     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"); | ||||
|     } | ||||
|     if (level > 0) { | ||||
|         /* We have an upvalue */ | ||||
|         ret = compiler_get_target(c, opts); | ||||
| @@ -452,7 +454,7 @@ static Slot compile_assign(GstCompiler *c, FormOptions opts, GstValue left, GstV | ||||
|     Slot slot; | ||||
|     subOpts.isTail = 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 | ||||
|          * local variable */ | ||||
|         if (level != 0) { | ||||
| @@ -1022,39 +1024,35 @@ void gst_compiler(GstCompiler *c, Gst *vm) { | ||||
|     compiler_push_scope(c, 0); | ||||
| } | ||||
|  | ||||
| /* Add environment */ | ||||
| void gst_compiler_env(GstCompiler *c, GstValue env) { | ||||
| /* Add a global variable */ | ||||
| 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; | ||||
|     GstBucket *bucket; | ||||
|     /* Register everything in environment */ | ||||
|     if (env.type == GST_OBJECT) { | ||||
|         for (i = 0; i < env.data.object->capacity; ++i) { | ||||
|             bucket = env.data.object->buckets[i]; | ||||
|             while (bucket) { | ||||
|                 if (bucket->key.type == GST_SYMBOL) { | ||||
|                     compiler_declare_symbol(c, c->tail, bucket->key); | ||||
|                     gst_array_push(c->vm, c->env, bucket->value); | ||||
|                 } | ||||
|                 bucket = bucket->next; | ||||
|     for (i = 0; i < env->capacity; ++i) { | ||||
|         bucket = env->buckets[i]; | ||||
|         while (bucket) { | ||||
|             if (bucket->key.type == GST_SYMBOL) { | ||||
|                 compiler_declare_symbol(c, c->tail, bucket->key); | ||||
|                 gst_array_push(c->vm, c->env, bucket->value);                 | ||||
|             } | ||||
|             bucket = bucket->next; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* Register a global for the compilation environment. */ | ||||
| void gst_compiler_add_global(GstCompiler *c, const char *name, GstValue x) { | ||||
|     GstValue sym = gst_load_cstring(c->vm, name); | ||||
|     sym.type = GST_SYMBOL; | ||||
|     compiler_declare_symbol(c, c->tail, sym); | ||||
|     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); | ||||
| /* Use a module that was loaded into the vm */ | ||||
| void gst_compiler_usemodule(GstCompiler *c, const char *modulename) { | ||||
|     GstValue mod = gst_object_get(c->vm->rootenv, gst_load_csymbol(c->vm, modulename)); | ||||
|     if (mod.type == GST_OBJECT) { | ||||
|         gst_compiler_globals(c, mod.data.object); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* Compile interface. Returns a function that evaluates the | ||||
|   | ||||
| @@ -235,13 +235,15 @@ void gst_mem_tag(void *mem, uint32_t tags) { | ||||
|  | ||||
| /* Run garbage collection */ | ||||
| void gst_collect(Gst *vm) { | ||||
|     GstValueUnion renv; | ||||
|     /* Thread can be null */ | ||||
|     if (vm->thread) { | ||||
|         GstValueUnion t; | ||||
|         t.thread = vm->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_sweep(vm); | ||||
|     vm->nextCollection = 0; | ||||
|   | ||||
							
								
								
									
										15
									
								
								core/stl.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								core/stl.c
									
									
									
									
									
								
							| @@ -396,12 +396,7 @@ int gst_stl_serialize(Gst *vm) { | ||||
| /* Bootstraping */ | ||||
| /****/ | ||||
|  | ||||
| struct GstRegistryItem { | ||||
|     const char *name; | ||||
|     GstCFunction func; | ||||
| }; | ||||
|  | ||||
| static const struct GstRegistryItem const registry[] = { | ||||
| static const GstModuleItem const std_module[] = { | ||||
|     {"+", gst_stl_add}, | ||||
|     {"*", gst_stl_mul}, | ||||
|     {"-", gst_stl_sub}, | ||||
| @@ -430,9 +425,7 @@ static const struct GstRegistryItem const registry[] = { | ||||
| }; | ||||
|  | ||||
| /* Load all libraries */ | ||||
| void gst_stl_load(GstCompiler *c) { | ||||
|     const struct GstRegistryItem *item; | ||||
|     for (item = registry; item->name; ++item) { | ||||
|         gst_compiler_add_global_cfunction(c, item->name, item->func); | ||||
|     } | ||||
| void gst_stl_load(Gst *vm) { | ||||
|     GstObject *module = gst_c_module(vm, std_module); | ||||
|     gst_c_register(vm, "std", module); | ||||
| } | ||||
|   | ||||
| @@ -504,16 +504,17 @@ void gst_init(Gst *vm) { | ||||
|     vm->black = 0; | ||||
|     /* Add thread */ | ||||
|     vm->thread = NULL; | ||||
|     vm->rootenv.type = GST_NIL; | ||||
|     /* Set up string cache */ | ||||
|     gst_stringcache_init(vm, 128); | ||||
|     /* Set up global env */ | ||||
|     vm->rootenv = NULL; | ||||
| } | ||||
|  | ||||
| /* Clear all memory associated with the VM */ | ||||
| void gst_deinit(Gst *vm) { | ||||
|     gst_clear_memory(vm); | ||||
|     vm->thread = NULL; | ||||
|     vm->rootenv.type = GST_NIL; | ||||
|     vm->rootenv = NULL; | ||||
|     vm->ret.type = GST_NIL; | ||||
|     gst_stringcache_deinit(vm); | ||||
| } | ||||
|   | ||||
| @@ -20,14 +20,14 @@ struct GstCompiler { | ||||
| /* Initialize the Compiler */ | ||||
| void gst_compiler(GstCompiler *c, Gst *vm); | ||||
|  | ||||
| /* Register an environment for compilation */ | ||||
| void gst_compiler_env(GstCompiler *c, GstValue env); | ||||
| /* Add many globals */ | ||||
| void gst_compiler_globals(GstCompiler *c, GstObject *env); | ||||
|  | ||||
| /* 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. */ | ||||
| void gst_compiler_add_global_cfunction(GstCompiler *c, const char *name, GstCFunction f); | ||||
| /* Use a module */ | ||||
| void gst_compiler_usemodule(GstCompiler *c, const char *modulename); | ||||
|  | ||||
| /* Compile a function that evaluates the given form. */ | ||||
| GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form); | ||||
|   | ||||
| @@ -131,6 +131,15 @@ typedef union GstValueUnion GstValueUnion; | ||||
| /* Definitely implementation details */ | ||||
| typedef struct GstBucket GstBucket; | ||||
|  | ||||
| /* API Types */ | ||||
| typedef struct GstModuleItem GstModuleItem; | ||||
|  | ||||
| /* C Api data types */ | ||||
| struct GstModuleItem { | ||||
|     const char *name; | ||||
|     GstCFunction data; | ||||
| }; | ||||
|  | ||||
| /* Union datatype */ | ||||
| union GstValueUnion { | ||||
|     GstBoolean boolean; | ||||
| @@ -174,7 +183,7 @@ struct GstThread { | ||||
|     } status; | ||||
| }; | ||||
|  | ||||
| /* A dynamic array type. Useful for implementing a stack. */ | ||||
| /* A dynamic array type. */ | ||||
| struct GstArray { | ||||
|     uint32_t count; | ||||
|     uint32_t capacity; | ||||
| @@ -257,7 +266,7 @@ struct Gst { | ||||
|     /* Thread */ | ||||
|     GstThread *thread; | ||||
|     /* A GC root */ | ||||
|     GstValue rootenv; | ||||
|     GstObject *rootenv; | ||||
|     /* Return state */ | ||||
|     const char *crash; | ||||
|     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); | ||||
| 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 | ||||
|   | ||||
| @@ -2,10 +2,9 @@ | ||||
| #define stl_h_INCLUDED | ||||
|  | ||||
| #include <gst/gst.h> | ||||
| #include <gst/compile.h> | ||||
|  | ||||
| /* Load the standard library */ | ||||
| void gst_stl_load(GstCompiler *c); | ||||
| void gst_stl_load(Gst *vm); | ||||
|  | ||||
| #endif // stl_h_INCLUDED | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose