mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Add first class symbol type.
This commit is contained in:
		| @@ -319,7 +319,7 @@ static uint16_t compiler_add_literal(GstCompiler *c, GstScope *scope, GstValue x | ||||
| static uint16_t compiler_declare_symbol(GstCompiler *c, GstScope *scope, GstValue sym) { | ||||
|     GstValue x; | ||||
|     uint16_t target; | ||||
|     if (sym.type != GST_STRING) | ||||
|     if (sym.type != GST_SYMBOL) | ||||
|         c_error(c, "expected symbol"); | ||||
|     target = compiler_get_local(c, scope); | ||||
|     x.type = GST_NUMBER; | ||||
| @@ -750,7 +750,7 @@ static Slot compile_function(GstCompiler *c, FormOptions opts, GstValue *form) { | ||||
|     params = form[current++].data.array; | ||||
|     for (i = 0; i < params->count; ++i) { | ||||
|         GstValue param = params->data[i]; | ||||
|         if (param.type != GST_STRING) | ||||
|         if (param.type != GST_SYMBOL) | ||||
|             c_error(c, "function parameters should be symbols"); | ||||
|         /* The compiler puts the parameter locals | ||||
|          * in the right place by default - at the beginning | ||||
| @@ -876,7 +876,7 @@ static Slot compile_try(GstCompiler *c, FormOptions opts, GstValue *form) { | ||||
|     if (gst_tuple_length(form) < 3 || gst_tuple_length(form) > 4) | ||||
|         c_error(c, "try takes either 2 or 3 arguments"); | ||||
|     /* Check for symbol to bind error to */ | ||||
|     if (form[1].type != GST_STRING) | ||||
|     if (form[1].type != GST_SYMBOL) | ||||
|         c_error(c, "expected symbol at start of try"); | ||||
|     /* Add subscope for error variable */ | ||||
|     GstScope *subScope = compiler_push_scope(c, 1); | ||||
| @@ -1013,7 +1013,7 @@ typedef Slot (*SpecialFormHelper) (GstCompiler *c, FormOptions opts, GstValue *f | ||||
| /* Dispatch to a special form */ | ||||
| static SpecialFormHelper get_special(GstValue *form) { | ||||
|     uint8_t *name; | ||||
|     if (gst_tuple_length(form) < 1 || form[0].type != GST_STRING) | ||||
|     if (gst_tuple_length(form) < 1 || form[0].type != GST_SYMBOL) | ||||
|         return NULL; | ||||
|     name = form[0].data.string; | ||||
|     /* If we have a symbol with a zero length name, we have other | ||||
| @@ -1273,7 +1273,7 @@ static Slot compile_value(GstCompiler *c, FormOptions opts, GstValue x) { | ||||
|         case GST_BOOLEAN: | ||||
|         case GST_NUMBER: | ||||
|             return compile_nonref_type(c, opts, x); | ||||
|         case GST_STRING: | ||||
|         case GST_SYMBOL: | ||||
|             return compile_symbol(c, opts, x); | ||||
|         case GST_TUPLE: | ||||
|             return compile_form(c, opts, x.data.tuple); | ||||
| @@ -1305,7 +1305,7 @@ void gst_compiler_env(GstCompiler *c, GstValue env) { | ||||
|         for (i = 0; i < env.data.object->capacity; ++i) { | ||||
|             bucket = env.data.object->buckets[i]; | ||||
|             while (bucket) { | ||||
|                 if (bucket->key.type == GST_STRING) { | ||||
|                 if (bucket->key.type == GST_SYMBOL) { | ||||
|                     compiler_declare_symbol(c, c->tail, bucket->key); | ||||
|                     gst_array_push(c->vm, c->env, bucket->value); | ||||
|                 } | ||||
| @@ -1318,7 +1318,7 @@ void gst_compiler_env(GstCompiler *c, GstValue env) { | ||||
| /* 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_STRING; | ||||
|     sym.type = GST_SYMBOL; | ||||
|     compiler_declare_symbol(c, c->tail, sym); | ||||
|     gst_array_push(c->vm, c->env, x); | ||||
| } | ||||
|   | ||||
| @@ -72,7 +72,7 @@ static GstValue quote(GstParser *p, GstValue x) { | ||||
|     tuple = gst_tuple(p->vm, 2); | ||||
|     tuplev.type = GST_TUPLE; | ||||
|     tuplev.data.tuple = tuple; | ||||
|     tuple[0] = gst_load_cstring(p->vm, "quote"); | ||||
|     tuple[0] = gst_load_csymbol(p->vm, "quote"); | ||||
|     tuple[1] = x; | ||||
|     return tuplev; | ||||
| } | ||||
| @@ -242,7 +242,7 @@ static GstValue build_token(GstParser *p, GstBuffer *buf) { | ||||
|             p_error(p, "symbols cannot start with digits"); | ||||
|             x.type = GST_NIL; | ||||
|         } else { | ||||
|             x.type = GST_STRING; | ||||
|             x.type = GST_SYMBOL; | ||||
|             x.data.string = gst_buffer_to_string(p->vm, buf); | ||||
|         } | ||||
|     } | ||||
| @@ -288,12 +288,11 @@ static int string_state(GstParser *p, uint8_t c) { | ||||
|             if (c == '\\') { | ||||
|                 top->buf.string.state = STRING_STATE_ESCAPE; | ||||
|             } else if (c == '"') { | ||||
|                 /* Return quoted form */ | ||||
|                 GstValue x; | ||||
|                 x.type = GST_STRING; | ||||
|                 x.data.string = gst_buffer_to_string(p->vm, top->buf.string.buffer); | ||||
|                 parser_pop(p); | ||||
|                 parser_append(p, quote(p, x)); | ||||
|                 parser_append(p, x); | ||||
|             } else { | ||||
|                 gst_buffer_push(p->vm, top->buf.string.buffer, c); | ||||
|             } | ||||
|   | ||||
| @@ -16,7 +16,7 @@ void debug_repl(FILE *in, FILE *out) { | ||||
|  | ||||
|     vm.rootenv.type = GST_OBJECT; | ||||
|     vm.rootenv.data.object = gst_object(&vm, 10); | ||||
|     gst_object_put(&vm, vm.rootenv.data.object, gst_load_cstring(&vm, "_ENV"), vm.rootenv); | ||||
|     gst_object_put(&vm, vm.rootenv.data.object, gst_load_csymbol(&vm, "_ENV"), vm.rootenv); | ||||
|  | ||||
|     for (;;) { | ||||
|  | ||||
| @@ -75,10 +75,10 @@ void debug_repl(FILE *in, FILE *out) { | ||||
|         } | ||||
|  | ||||
|         /* Print asm */ | ||||
|         //if (out) { | ||||
|             //fprintf(out, "\n"); | ||||
|             //gst_dasm_function(out, func.data.function); | ||||
|         //} | ||||
|         /*if (out) { | ||||
|             fprintf(out, "\n"); | ||||
|             gst_dasm_function(out, func.data.function); | ||||
|         }*/ | ||||
|  | ||||
|         /* Execute function */ | ||||
|         if (gst_run(&vm, func)) { | ||||
| @@ -95,7 +95,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_cstring(&vm, "ans"), vm.ret); | ||||
|             gst_object_put(&vm, vm.rootenv.data.object, gst_load_csymbol(&vm, "ans"), vm.ret); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -16,21 +16,22 @@ | ||||
|  * Byte 203: False | ||||
|  * Byte 204: Number  - double format | ||||
|  * Byte 205: String  - [u32 length]*[u8... characters] | ||||
|  * Byte 206: Buffer  - [u32 length]*[u8... characters] | ||||
|  * Byte 207: Array   - [u32 length]*[value... elements] | ||||
|  * Byte 208: Tuple   - [u32 length]*[value... elements] | ||||
|  * Byte 209: Thread  - [u8 state][u32 frames]*[[value callee][value env] | ||||
|  * Byte 206: Symbol  - [u32 length]*[u8... characters] | ||||
|  * Byte 207: Buffer  - [u32 length]*[u8... characters] | ||||
|  * Byte 208: Array   - [u32 length]*[value... elements] | ||||
|  * Byte 209: Tuple   - [u32 length]*[value... elements] | ||||
|  * Byte 210: Thread  - [u8 state][u32 frames]*[[value callee][value env] | ||||
|  *  [u32 pcoffset][u32 erroffset][u16 ret][u16 errloc][u16 size]*[value ...stack] | ||||
|  * Byte 210: Object  - [value meta][u32 length]*2*[value... kvs] | ||||
|  * Byte 211: FuncDef - [u32 locals][u32 arity][u32 flags][u32 literallen]*[value... | ||||
|  * Byte 211: Object  - [value meta][u32 length]*2*[value... kvs] | ||||
|  * Byte 212: FuncDef - [u32 locals][u32 arity][u32 flags][u32 literallen]*[value... | ||||
|  *  literals][u32 bytecodelen]*[u16... bytecode] | ||||
|  * Byte 212: FunEnv  - [value thread][u32 length]*[value ...upvalues] | ||||
|  * Byte 213: FunEnv  - [value thread][u32 length]*[value ...upvalues] | ||||
|  *  (upvalues is not read if thread is a thread object) | ||||
|  * Byte 213: Func    - [value parent][value def][value env] | ||||
|  * Byte 214: Func    - [value parent][value def][value env] | ||||
|  *  (nil values indicate empty) | ||||
|  * Byte 214: LUdata  - [value meta][u32 length]*[u8... bytes] | ||||
|  * Byte 215: CFunc   - [u32 length]*[u8... idstring] | ||||
|  * Byte 216: Ref     - [u32 id] | ||||
|  * Byte 215: LUdata  - [value meta][u32 length]*[u8... bytes] | ||||
|  * Byte 216: CFunc   - [u32 length]*[u8... idstring] | ||||
|  * Byte 217: Ref     - [u32 id] | ||||
|  */ | ||||
|  | ||||
| /* Error at buffer end */ | ||||
| @@ -135,7 +136,8 @@ static GstValue gst_deserialize_impl( | ||||
|             return ret; | ||||
|  | ||||
|         case 205: /* String */ | ||||
|             ret.type = GST_STRING; | ||||
|         case 206: /* Symbol */ | ||||
|             ret.type = data[-1] == 205 ? GST_STRING : GST_SYMBOL; | ||||
|             length = read_u32(); data += 4; | ||||
|             data = deser_datacheck(length); | ||||
|             ret.data.string =  | ||||
| @@ -148,7 +150,7 @@ static GstValue gst_deserialize_impl( | ||||
|             gst_array_push(vm, visited, ret); | ||||
|             return ret; | ||||
|  | ||||
|         case 206: /* Buffer */ | ||||
|         case 207: /* Buffer */ | ||||
|             ret.type = GST_BUFFER; | ||||
|             length = read_u32(); data += 4; | ||||
|             data = deser_datacheck(length); | ||||
| @@ -161,7 +163,7 @@ static GstValue gst_deserialize_impl( | ||||
|             gst_array_push(vm, visited, ret); | ||||
|             return ret; | ||||
|  | ||||
|         case 207: /* Array */ | ||||
|         case 208: /* Array */ | ||||
|             ret.type = GST_ARRAY; | ||||
|             length = read_u32(); data += 4; | ||||
|             buffer = gst_alloc(vm, length * sizeof(GstValue)); | ||||
| @@ -175,7 +177,7 @@ static GstValue gst_deserialize_impl( | ||||
|             gst_array_push(vm, visited, ret); | ||||
|             return ret; | ||||
|  | ||||
|         case 208: /* Tuple */ | ||||
|         case 209: /* Tuple */ | ||||
|             ret.type = GST_TUPLE; | ||||
|             length = read_u32(); data += 4; | ||||
|             buffer = gst_alloc(vm, length * sizeof(GstValue) + 2 * sizeof(uint32_t)) | ||||
| @@ -189,7 +191,7 @@ static GstValue gst_deserialize_impl( | ||||
|             gst_array_push(vm, visited, ret); | ||||
|             return ret; | ||||
|  | ||||
|         case 209: /* Thread */ | ||||
|         case 210: /* Thread */ | ||||
|             { | ||||
|                 GstValue nil; | ||||
|                 GstThread *t; | ||||
| @@ -251,7 +253,7 @@ static GstValue gst_deserialize_impl( | ||||
|             } | ||||
|             return ret; | ||||
|  | ||||
|         case 210: /* Object */ | ||||
|         case 211: /* Object */ | ||||
|             { | ||||
|                 GstValue meta; | ||||
|                 ret.type = GST_OBJECT; | ||||
| @@ -272,7 +274,7 @@ static GstValue gst_deserialize_impl( | ||||
|             } | ||||
|             return ret; | ||||
|  | ||||
|         case 211: /* Funcdef */ | ||||
|         case 212: /* Funcdef */ | ||||
|             { | ||||
|                 GstFuncDef *def; | ||||
|                 uint32_t locals, arity, literalsLen, byteCodeLen, flags; | ||||
| @@ -306,7 +308,7 @@ static GstValue gst_deserialize_impl( | ||||
|             } | ||||
|             return ret; | ||||
|  | ||||
|         case 212: /* Funcenv */ | ||||
|         case 213: /* Funcenv */ | ||||
|             { | ||||
|                 GstValue thread = gst_deserialize_impl(vm, deata, &data, visited); | ||||
|                 length = read_u32(); data += 4; | ||||
| @@ -328,7 +330,7 @@ static GstValue gst_deserialize_impl( | ||||
|             } | ||||
|             return ret; | ||||
|  | ||||
|         case 213: /* Function */ | ||||
|         case 214: /* Function */ | ||||
|             { | ||||
|                 GstValue parent, def, env; | ||||
|                 parent = gst_deserialize_impl(vm, data, end, &data, visited); | ||||
| @@ -352,7 +354,7 @@ static GstValue gst_deserialize_impl( | ||||
|             } | ||||
|             return ret; | ||||
|  | ||||
|         case 214: /* LUdata */ | ||||
|         case 215: /* LUdata */ | ||||
|             { | ||||
|                 GstValue meta; | ||||
|                 ret.type = GST_USERDATA; | ||||
| @@ -367,11 +369,11 @@ static GstValue gst_deserialize_impl( | ||||
|             } | ||||
|             return ret; | ||||
|  | ||||
|         case 215: /* C function */ | ||||
|         case 216: /* C function */ | ||||
|  | ||||
|             return ret; | ||||
|  | ||||
|         case 216: /* Reference */ | ||||
|         case 217: /* Reference */ | ||||
|             length = read_u32(); data += 4; | ||||
|             deser_assert(visited->count > length, "invalid reference"); | ||||
|             *newData = data; | ||||
|   | ||||
| @@ -70,6 +70,7 @@ void gst_mark(Gst *vm, GstValue *x) { | ||||
|             break; | ||||
|  | ||||
|         case GST_STRING: | ||||
|         case GST_SYMBOL: | ||||
|             gc_header(gst_string_raw(x->data.string))->color = vm->black; | ||||
|             break; | ||||
|  | ||||
|   | ||||
							
								
								
									
										17
									
								
								core/value.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								core/value.c
									
									
									
									
									
								
							| @@ -26,6 +26,13 @@ GstValue gst_load_cstring(Gst *vm, const char *string) { | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| GstValue gst_load_csymbol(Gst *vm, const char *string) { | ||||
|     GstValue ret; | ||||
|     ret.type = GST_SYMBOL; | ||||
|     ret.data.string = load_cstring(vm, string, strlen(string)); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static uint8_t * number_to_string(Gst *vm, GstNumber x) { | ||||
|     static const uint32_t SIZE = 20; | ||||
|     uint8_t *data = gst_alloc(vm, SIZE + 1 + 2 * sizeof(uint32_t)); | ||||
| @@ -94,6 +101,8 @@ uint8_t *gst_to_string(Gst *vm, GstValue x) { | ||||
|             return string_description(vm, "object", 6, x.data.pointer); | ||||
|         case GST_STRING: | ||||
|             return x.data.string; | ||||
|         case GST_SYMBOL: | ||||
|             return string_description(vm, "symbol", 6, x.data.pointer); | ||||
|         case GST_BYTEBUFFER: | ||||
|             return string_description(vm, "buffer", 6, x.data.pointer); | ||||
|         case GST_CFUNCTION: | ||||
| @@ -155,6 +164,7 @@ int gst_equals(GstValue x, GstValue y) { | ||||
|                 /* Assume that when strings are created, equal strings | ||||
|                  * are set to the same string */ | ||||
|             case GST_STRING: | ||||
|             case GST_SYMBOL: | ||||
|                 if (x.data.string == y.data.string) { | ||||
|                     result = 1; | ||||
|                     break; | ||||
| @@ -222,6 +232,7 @@ uint32_t gst_hash(GstValue x) { | ||||
|             break; | ||||
|             /* String hashes */ | ||||
|         case GST_STRING: | ||||
|         case GST_SYMBOL: | ||||
|             /* Assume 0 is not hashed. */ | ||||
|             if (gst_string_hash(x.data.string)) | ||||
|                 hash = gst_string_hash(x.data.string); | ||||
| @@ -271,6 +282,7 @@ int gst_compare(GstValue x, GstValue y) { | ||||
|                     return x.data.number > y.data.number ? 1 : -1; | ||||
|                 } | ||||
|             case GST_STRING: | ||||
|             case GST_SYMBOL: | ||||
|                 if (x.data.string == y.data.string) { | ||||
|                     return 0; | ||||
|                 } else { | ||||
| @@ -282,9 +294,9 @@ int gst_compare(GstValue x, GstValue y) { | ||||
|                         if (x.data.string[i] == y.data.string[i]) { | ||||
|                             continue; | ||||
|                         } else if (x.data.string[i] < y.data.string[i]) { | ||||
|                             return 1; /* x is less then y */ | ||||
|                             return -1; /* x is less then y */ | ||||
|                         } else { | ||||
|                             return -1; /* y is less than x */ | ||||
|                             return 1; /* y is less than x */ | ||||
|                         } | ||||
|                     } | ||||
|                     if (xlen == ylen) { | ||||
| @@ -379,6 +391,7 @@ const char *gst_get(GstValue ds, GstValue key, GstValue *out) { | ||||
|         ret.data.number = ds.data.buffer->data[index]; | ||||
|         break; | ||||
|     case GST_STRING: | ||||
|     case GST_SYMBOL: | ||||
|         if (key.type != GST_NUMBER) return "expected numeric key"; | ||||
|         index = to_index(key.data.number, gst_string_length(ds.data.string)); | ||||
|         if (index == -1) return "invalid string access"; | ||||
|   | ||||
| @@ -372,6 +372,7 @@ static int gst_continue_size(Gst *vm, uint32_t stackBase) { | ||||
|                 arity = pc[offset - 1]; | ||||
|                 /* Push new frame */ | ||||
|                 stack = gst_thread_beginframe(vm, &thread, temp, arity); | ||||
|                 if (stack == NULL) gst_error(vm, "expected function"); | ||||
|                 oldStack = stack - GST_FRAME_SIZE - gst_frame_prevsize(stack); | ||||
|                 /* Write arguments */ | ||||
|                 size = gst_frame_size(stack); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose