Browse Source

Sol Part 5: Kid Tested, Mother Approved!

Graham Northup 6 years ago
parent
commit
1ffe68b513
15 changed files with 4793 additions and 3523 deletions
  1. 1
    1
      ast.h
  2. 8
    0
      astprint.c
  3. 281
    10
      builtins.c
  4. 4
    7
      dsdebug.gdb
  5. 106
    96
      lex.yy.c
  6. 108
    65
      object.c
  7. 3665
    2842
      parser.output
  8. 392
    356
      parser.tab.c
  9. 13
    11
      parser.tab.h
  10. 24
    5
      parser.y
  11. 60
    26
      runtime.c
  12. 39
    6
      sol.h
  13. 68
    93
      state.c
  14. 20
    5
      test.sol
  15. 4
    0
      tokenizer.lex

+ 1
- 1
ast.h View File

@@ -21,7 +21,7 @@ typedef struct {
21 21
 	};
22 22
 } lit_node;
23 23
 
24
-typedef enum {OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_POW, OP_BAND, OP_BOR, OP_BXOR, OP_LAND, OP_LOR, OP_EQUAL, OP_LESS, OP_GREATER, OP_LESSEQ, OP_GREATEREQ} binop_t;
24
+typedef enum {OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_POW, OP_BAND, OP_BOR, OP_BXOR, OP_LAND, OP_LOR, OP_EQUAL, OP_LESS, OP_GREATER, OP_LESSEQ, OP_GREATEREQ, OP_LSHIFT, OP_RSHIFT} binop_t;
25 25
 typedef struct {
26 26
 	binop_t type;
27 27
 	expr_node *left;

+ 8
- 0
astprint.c View File

@@ -198,6 +198,14 @@ void prex(expr_node *node, int lev) {
198 198
 				case OP_GREATEREQ:
199 199
 					prlev(lev, "Op: >=");
200 200
 					break;
201
+					
202
+				case OP_LSHIFT:
203
+					prlev(lev, "Op: <<");
204
+					break;
205
+					
206
+				case OP_RSHIFT:
207
+					prlev(lev, "Op: >>");
208
+					break;
201 209
 			}
202 210
 			prlev(lev, "Left:");
203 211
 			prex(node->binop->left, lev+1);

+ 281
- 10
builtins.c View File

@@ -70,20 +70,20 @@ sol_object_t *sol_f_try(sol_state_t *state, sol_object_t *args) {
70 70
 		sol_obj_free(res);
71 71
 		sol_obj_free(one);
72 72
 		sol_clear_error(state);
73
-		sol_list_insert(state, &ls, 0, err);
73
+		sol_list_insert(state, ls, 0, err);
74 74
 		sol_obj_free(err);
75
-		sol_list_insert(state, &ls, 0, zero);
75
+		sol_list_insert(state, ls, 0, zero);
76 76
 		sol_obj_free(zero);
77 77
 		return ls;
78 78
 	}
79
-	sol_list_insert(state, &ls, 0, res);
79
+	sol_list_insert(state, ls, 0, res);
80 80
 	sol_obj_free(res);
81
-	sol_list_insert(state, &ls, 0, one);
81
+	sol_list_insert(state, ls, 0, one);
82 82
 	sol_obj_free(one);
83 83
 	return ls;
84 84
 }
85 85
 
86
-static char *sol_TypeNames[] = {"singlet", "integer", "float", "string", "list", "map", "function", "cfunction", "cdata"};
86
+static char *sol_TypeNames[] = {"singlet", "integer", "float", "string", "list", "listcell", "map", "mapcell", "function", "cfunction", "cdata"};
87 87
 
88 88
 sol_object_t *sol_f_type(sol_state_t *state, sol_object_t *args) {
89 89
     sol_object_t *obj = sol_list_get_index(state, args, 0);
@@ -92,8 +92,21 @@ sol_object_t *sol_f_type(sol_state_t *state, sol_object_t *args) {
92 92
     return res;
93 93
 }
94 94
 
95
+sol_object_t *p_seen[1024] = {0};
96
+
95 97
 void ob_print(sol_object_t *obj) {
96 98
     sol_object_t *cur;
99
+	int i;
100
+	for(i=0; i<1024; i++) {
101
+		if(!p_seen[i]) {
102
+			p_seen[i] = obj;
103
+			break;
104
+		}
105
+		if(p_seen[i] == obj) {
106
+			printf("... (%p)", obj);
107
+			return;
108
+		}
109
+	}
97 110
     switch(obj->type) {
98 111
         case SOL_SINGLET:
99 112
             printf("<Singlet>");
@@ -110,6 +123,10 @@ void ob_print(sol_object_t *obj) {
110 123
         case SOL_STRING:
111 124
             printf("\"%s\"", obj->str);
112 125
             break;
126
+			
127
+		case SOL_LCELL:
128
+			printf("<<");
129
+			/* fall through */
113 130
 
114 131
         case SOL_LIST:
115 132
             printf("[");
@@ -125,6 +142,10 @@ void ob_print(sol_object_t *obj) {
125 142
             }
126 143
             printf("]");
127 144
             break;
145
+			
146
+		case SOL_MCELL:
147
+			printf("<<");
148
+			/* fall through */
128 149
 
129 150
         case SOL_MAP:
130 151
             printf("{");
@@ -161,13 +182,170 @@ void ob_print(sol_object_t *obj) {
161 182
 }
162 183
 
163 184
 sol_object_t *sol_f_prepr(sol_state_t *state, sol_object_t *args) {
164
-    sol_object_t *obj = sol_list_get_index(state, args, 0);
165
-    ob_print(obj);
166
-    printf("\n");
167
-    sol_obj_free(obj);
185
+	int i, sz = sol_list_len(state, args);
186
+    sol_object_t *obj;
187
+	for(i=0; i<1024; i++) p_seen[i] = NULL;
188
+	for(i=0; i<sz; i++) {
189
+		obj = sol_list_get_index(state, args, i);
190
+		ob_print(obj);
191
+		printf(" ");
192
+		sol_obj_free(obj);
193
+	}
194
+	printf("\n");
195
+    return sol_incref(state->None);
196
+}
197
+
198
+sol_object_t *sol_f_print(sol_state_t *state, sol_object_t *args) {
199
+	int i, sz = sol_list_len(state, args);
200
+    sol_object_t *obj;
201
+	for(i=0; i<1024; i++) p_seen[i] = NULL;
202
+	for(i=0; i<sz; i++) {
203
+		obj = sol_list_get_index(state, args, i);
204
+		if(sol_is_string(obj)) {
205
+			printf("%s", obj->str);
206
+		} else {
207
+			ob_print(obj);
208
+		}
209
+		printf(" ");
210
+		sol_obj_free(obj);
211
+	}
212
+	printf("\n");
168 213
     return sol_incref(state->None);
169 214
 }
170 215
 
216
+sol_object_t *sol_f_rawget(sol_state_t *state, sol_object_t *args) {
217
+	sol_object_t *obj = sol_list_get_index(state, args, 0), *key, *res;
218
+	if(!sol_is_map(obj)) return sol_set_error_string(state, "Rawset of non-map");
219
+	key = sol_list_get_index(state, args, 1);
220
+	res = sol_map_get(state, obj, key);
221
+	sol_obj_free(key);
222
+	sol_obj_free(obj);
223
+	return sol_incref(state->None);
224
+}
225
+
226
+
227
+sol_object_t *sol_f_rawset(sol_state_t *state, sol_object_t *args) {
228
+	sol_object_t *obj = sol_list_get_index(state, args, 0), *key, *val;
229
+	if(!sol_is_map(obj)) return sol_set_error_string(state, "Rawset of non-map");
230
+	key = sol_list_get_index(state, args, 1);
231
+	val = sol_list_get_index(state, args, 2);
232
+	sol_map_set(state, obj, key, val);
233
+	sol_obj_free(val);
234
+	sol_obj_free(key);
235
+	sol_obj_free(obj);
236
+	return sol_incref(state->None);
237
+}
238
+
239
+sol_object_t *sol_f_range(sol_state_t *state, sol_object_t *args) {
240
+	sol_object_t *res = sol_new_list(state), *bound = sol_cast_int(state, sol_list_get_index(state, args, 0));
241
+	int i;
242
+	for(i=0; i<bound->ival; i++) {
243
+		sol_list_insert(state, res, sol_list_len(state, res), sol_new_int(state, i));
244
+	}
245
+	sol_obj_free(bound);
246
+	return res;
247
+}
248
+
249
+sol_object_t *sol_f_debug_getref(sol_state_t *state, sol_object_t *args) {
250
+	sol_object_t *obj = sol_list_get_index(state, args, 0);
251
+	sol_object_t *res = sol_new_int(state, obj->refcnt - 2); // NB: We grabbed a reference, and there's one in the arglist, so account for them.
252
+	sol_obj_free(obj);
253
+	return res;
254
+}
255
+
256
+sol_object_t *sol_f_debug_setref(sol_state_t *state, sol_object_t *args) {
257
+	sol_object_t *obj = sol_list_get_index(state, args, 0), *cnt = sol_list_get_index(state, args, 1);
258
+	obj->refcnt = sol_cast_int(state, cnt)->ival + 2; // NB: As above.
259
+	sol_obj_free(cnt);
260
+	sol_obj_free(obj);
261
+	return sol_incref(state->None);
262
+}
263
+
264
+sol_object_t *sol_f_debug_closure(sol_state_t *state, sol_object_t *args) {
265
+	sol_object_t *func = sol_list_get_index(state, args, 0);
266
+	sol_object_t *res = sol_incref(func->closure);
267
+	sol_obj_free(func);
268
+	return res;
269
+}
270
+
271
+sol_object_t *sol_f_debug_globals(sol_state_t *state, sol_object_t *args) {
272
+	return sol_list_get_index(state, state->scopes, sol_list_len(state, state->scopes)-1);
273
+}
274
+
275
+sol_object_t *sol_f_debug_locals(sol_state_t *state, sol_object_t *args) {
276
+	return sol_list_get_index(state, state->scopes, 0);
277
+}
278
+
279
+sol_object_t *sol_f_iter_str(sol_state_t *state, sol_object_t *args) {
280
+	sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
281
+	sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
282
+	char temp[2] = {0, 0};
283
+	if(sol_is_none(state, index)) {
284
+		sol_obj_free(index);
285
+		index = sol_new_int(state, 0);
286
+		sol_map_set_name(state, local, "idx", index);
287
+	}
288
+	if(index->ival >= strlen(obj->str)) {
289
+		sol_obj_free(index);
290
+		sol_obj_free(obj);
291
+		sol_obj_free(local);
292
+		return sol_incref(state->StopIteration);
293
+	}
294
+	temp[0] = obj->str[index->ival];
295
+	res = sol_new_string(state, temp);
296
+	index->ival++;
297
+	sol_obj_free(index);
298
+	sol_obj_free(local);
299
+	sol_obj_free(obj);
300
+	return res;
301
+}
302
+
303
+sol_object_t *sol_f_iter_list(sol_state_t *state, sol_object_t *args) {
304
+	sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
305
+	sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
306
+	if(sol_is_none(state, index)) {
307
+		sol_obj_free(index);
308
+		index = sol_new_int(state, 0);
309
+		sol_map_set_name(state, local, "idx", index);
310
+	}
311
+	if(index->ival >= sol_list_len(state, obj)) {
312
+		sol_obj_free(index);
313
+		sol_obj_free(obj);
314
+		sol_obj_free(local);
315
+		return sol_incref(state->StopIteration);
316
+	}
317
+	res = sol_list_get_index(state, obj, index->ival);
318
+	index->ival++;
319
+	sol_obj_free(index);
320
+	sol_obj_free(local);
321
+	sol_obj_free(obj);
322
+	return res;
323
+}
324
+
325
+sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) {
326
+	sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
327
+	sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
328
+	if(sol_is_none(state, index)) {
329
+		sol_obj_free(index);
330
+		index = obj;
331
+		sol_map_set_name(state, local, "idx", index);
332
+	}
333
+	while(index && !index->mkey) index = index->mnext;
334
+	if(!index || !index->mnext) {
335
+		sol_obj_free(index);
336
+		sol_obj_free(obj);
337
+		sol_obj_free(local);
338
+		return sol_incref(state->StopIteration);
339
+	}
340
+	res = sol_incref(index->mkey);
341
+	index = index->mnext;
342
+	sol_map_set_name(state, local, "idx", index);
343
+	sol_obj_free(index);
344
+	sol_obj_free(local);
345
+	sol_obj_free(obj);
346
+	return res;
347
+}
348
+
171 349
 sol_object_t *sol_f_int_add(sol_state_t *state, sol_object_t *args) {
172 350
 	sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
173 351
 	sol_object_t *res = sol_new_int(state, a->ival + b->ival);
@@ -240,6 +418,24 @@ sol_object_t *sol_f_int_bxor(sol_state_t *state, sol_object_t *args) {
240 418
 	return res;
241 419
 }
242 420
 
421
+sol_object_t *sol_f_int_blsh(sol_state_t *state, sol_object_t *args) {
422
+	sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
423
+	sol_object_t *res = sol_new_int(state, a->ival << b->ival);
424
+	sol_obj_free(a);
425
+	sol_obj_free(b);
426
+	if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
427
+	return res;
428
+}
429
+
430
+sol_object_t *sol_f_int_brsh(sol_state_t *state, sol_object_t *args) {
431
+	sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
432
+	sol_object_t *res = sol_new_int(state, a->ival >> b->ival);
433
+	sol_obj_free(a);
434
+	sol_obj_free(b);
435
+	if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
436
+	return res;
437
+}
438
+
243 439
 sol_object_t *sol_f_int_bnot(sol_state_t *state, sol_object_t *args) {
244 440
 	sol_object_t *a = sol_list_get_index(state, args, 0);
245 441
 	sol_object_t *res = sol_new_int(state, ~a->ival);
@@ -390,6 +586,10 @@ sol_object_t *sol_f_str_len(sol_state_t *state, sol_object_t *args) {
390 586
 	return res;
391 587
 }
392 588
 
589
+sol_object_t *sol_f_str_iter(sol_state_t *state, sol_object_t *args) {
590
+	return sol_new_cfunc(state, sol_f_iter_str);
591
+}
592
+
393 593
 sol_object_t *sol_f_str_toint(sol_state_t *state, sol_object_t *args) {
394 594
 	sol_object_t *a = sol_list_get_index(state, args, 0);
395 595
 	sol_object_t *res = sol_new_int(state, atoi(a->str));
@@ -467,6 +667,10 @@ sol_object_t *sol_f_list_len(sol_state_t *state, sol_object_t *args) {
467 667
 	return res;
468 668
 }
469 669
 
670
+sol_object_t *sol_f_list_iter(sol_state_t *state, sol_object_t *args) {
671
+	return sol_new_cfunc(state, sol_f_iter_list);
672
+}
673
+
470 674
 sol_object_t *sol_f_list_tostring(sol_state_t *state, sol_object_t *args) {
471 675
 	return sol_new_string(state, "<List>");
472 676
 }
@@ -487,7 +691,21 @@ sol_object_t *sol_f_map_add(sol_state_t *state, sol_object_t *args) {
487 691
 
488 692
 sol_object_t *sol_f_map_index(sol_state_t *state, sol_object_t *args) {
489 693
 	sol_object_t *map = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
490
-	sol_object_t *res = sol_map_get(state, map, b);
694
+	sol_object_t *indexf = sol_map_get_name(state, map, "__index");
695
+	sol_object_t *res = NULL, *newls;
696
+	if(!sol_is_none(state, indexf)) {
697
+		if(indexf->ops->call && indexf->ops->call != sol_f_not_impl) {
698
+			newls = sol_new_list(state);
699
+			sol_list_insert(state, newls, 0, indexf);
700
+			sol_list_append(state, newls, args);
701
+			res = indexf->ops->call(state, newls);
702
+			sol_obj_free(newls);
703
+		} else if(indexf->ops->index && indexf->ops->index != sol_f_not_impl) {
704
+			res = indexf->ops->index(state, args);
705
+		}
706
+	}
707
+	if(!res) res = sol_map_get(state, map, b);
708
+	sol_obj_free(indexf);
491 709
 	sol_obj_free(map);
492 710
 	sol_obj_free(b);
493 711
 	return res;
@@ -496,6 +714,21 @@ sol_object_t *sol_f_map_index(sol_state_t *state, sol_object_t *args) {
496 714
 sol_object_t *sol_f_map_setindex(sol_state_t *state, sol_object_t *args) {
497 715
 	sol_object_t *map = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
498 716
 	sol_object_t *val = sol_list_get_index(state, args, 2);
717
+	sol_object_t *setindexf = sol_map_get_name(state, map, "__setindex"), *newls;
718
+	if(!sol_is_none(state, setindexf)) {
719
+		if(setindexf->ops->call && setindexf->ops->call != sol_f_not_impl) {
720
+			newls = sol_new_list(state);
721
+			sol_list_insert(state, newls, 0, setindexf);
722
+			sol_list_append(state, newls, args);
723
+			sol_obj_free(setindexf->ops->call(state, newls));
724
+			sol_obj_free(newls);
725
+			return sol_incref(state->None);
726
+		} else if(setindexf->ops->setindex && setindexf->ops->setindex != sol_f_not_impl) {
727
+			setindexf->ops->setindex(state, args);
728
+			return sol_incref(state->None);
729
+		}
730
+	}
731
+	sol_obj_free(setindexf);
499 732
 	sol_map_set(state, map, b, val);
500 733
 	sol_obj_free(map);
501 734
 	sol_obj_free(b);
@@ -503,6 +736,23 @@ sol_object_t *sol_f_map_setindex(sol_state_t *state, sol_object_t *args) {
503 736
 	return sol_incref(state->None);
504 737
 }
505 738
 
739
+sol_object_t *sol_f_map_call(sol_state_t *state, sol_object_t *args) {
740
+	sol_object_t *map = sol_list_get_index(state, args, 0), *fargs = sol_list_sublist(state, args, 1);
741
+	sol_object_t *callf = sol_map_get_name(state, map, "__call"), *res = NULL;
742
+	if(!sol_is_none(state, callf)) {
743
+		if(callf->ops->call) {
744
+			sol_list_insert(state, fargs, 0, callf);
745
+			sol_list_insert(state, fargs, 1, map);
746
+			res = callf->ops->call(state, fargs);
747
+		}
748
+	}
749
+	sol_obj_free(map);
750
+	sol_obj_free(fargs);
751
+	sol_obj_free(callf);
752
+	if(res) return res;
753
+	return sol_set_error_string(state, "Call map without call method");
754
+}
755
+
506 756
 sol_object_t *sol_f_map_len(sol_state_t *state, sol_object_t *args) {
507 757
 	sol_object_t *map = sol_list_get_index(state, args, 0);
508 758
 	sol_object_t *res = sol_new_int(state, sol_map_len(state, map));
@@ -510,10 +760,31 @@ sol_object_t *sol_f_map_len(sol_state_t *state, sol_object_t *args) {
510 760
 	return res;
511 761
 }
512 762
 
763
+sol_object_t *sol_f_map_iter(sol_state_t *state, sol_object_t *args) {
764
+	return sol_new_cfunc(state, sol_f_iter_map);
765
+}
766
+
513 767
 sol_object_t *sol_f_map_tostring(sol_state_t *state, sol_object_t *args) {
514 768
 	return sol_new_string(state, "<Map>");
515 769
 }
516 770
 
771
+sol_object_t *sol_f_func_index(sol_state_t *state, sol_object_t *args) {
772
+	sol_object_t *func = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *res;
773
+	res = sol_map_get(state, func->closure, key);
774
+	sol_obj_free(func);
775
+	sol_obj_free(key);
776
+	return res;
777
+}
778
+
779
+sol_object_t *sol_f_func_setindex(sol_state_t *state, sol_object_t *args) {
780
+	sol_object_t *func = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *val = sol_list_get_index(state, args, 2);
781
+	sol_map_set(state, func->closure, key, val);
782
+	sol_obj_free(func);
783
+	sol_obj_free(key);
784
+	sol_obj_free(val);
785
+	return sol_incref(state->None);
786
+}
787
+
517 788
 sol_object_t *sol_f_func_tostring(sol_state_t *state, sol_object_t *args) {
518 789
 	return sol_new_string(state, "<Function>");
519 790
 }

+ 4
- 7
dsdebug.gdb View File

@@ -1,7 +1,4 @@
1
-break object.c:265
2
-  condition $bpnum sol_validate_list(state, *list)
3
-break object.c:294
4
-  condition $bpnum sol_validate_list(state, *list)
5
-break object.c:183
6
-  condition $bpnum sol_validate_list(state, list)
7
-watch state->error
1
+break object.c:277
2
+  condition $bpnum sol_validate_list(list)
3
+break object.c:304
4
+  condition $bpnum sol_validate_list(list)

+ 106
- 96
lex.yy.c View File

@@ -368,8 +368,8 @@ static void yy_fatal_error (yyconst char msg[]  );
368 368
 	*yy_cp = '\0'; \
369 369
 	(yy_c_buf_p) = yy_cp;
370 370
 
371
-#define YY_NUM_RULES 58
372
-#define YY_END_OF_BUFFER 59
371
+#define YY_NUM_RULES 60
372
+#define YY_END_OF_BUFFER 61
373 373
 /* This struct is not used in this scanner,
374 374
    but its presence is necessary. */
375 375
 struct yy_trans_info
@@ -377,20 +377,20 @@ struct yy_trans_info
377 377
 	flex_int32_t yy_verify;
378 378
 	flex_int32_t yy_nxt;
379 379
 	};
380
-static yyconst flex_int16_t yy_accept[109] =
380
+static yyconst flex_int16_t yy_accept[111] =
381 381
     {   0,
382
-        0,    0,   59,   58,   57,   29,   58,   54,   23,   58,
383
-       48,   49,   20,   18,   53,   19,   50,   21,    2,   51,
384
-       52,   40,   30,   41,   55,   55,   46,   47,   25,   55,
385
-       55,   55,   55,   55,   55,   55,   55,   55,   44,   24,
386
-       45,   26,   57,    0,    3,   27,   36,    0,    4,   22,
387
-       33,   31,    0,   32,   34,    1,    2,   42,   39,   43,
388
-       55,   55,   38,   55,   55,   11,   55,   55,   55,   55,
389
-        5,   10,   55,   55,   55,   37,   28,   35,    0,   56,
390
-        1,   55,   55,   55,   55,   16,    9,   55,   55,   55,
391
-       55,   17,   55,   55,    7,   12,   55,    6,   55,   14,
392
-
393
-       55,   55,    8,   55,   13,   55,   15,    0
382
+        0,    0,   61,   60,   59,   29,   60,   56,   23,   60,
383
+       50,   51,   20,   18,   55,   19,   52,   21,    2,   53,
384
+       54,   40,   30,   41,   57,   57,   48,   49,   25,   57,
385
+       57,   57,   57,   57,   57,   57,   57,   57,   46,   24,
386
+       47,   26,   59,    0,    3,   27,   36,    0,    4,   22,
387
+       33,   31,    0,   32,   34,    1,    2,   45,   42,   39,
388
+       43,   44,   57,   57,   38,   57,   57,   11,   57,   57,
389
+       57,   57,    5,   10,   57,   57,   57,   37,   28,   35,
390
+        0,   58,    1,   57,   57,   57,   57,   16,    9,   57,
391
+       57,   57,   57,   17,   57,   57,    7,   12,   57,    6,
392
+
393
+       57,   14,   57,   57,    8,   57,   13,   57,   15,    0
394 394
     } ;
395 395
 
396 396
 static yyconst flex_int32_t yy_ec[256] =
@@ -434,84 +434,84 @@ static yyconst flex_int32_t yy_meta[49] =
434 434
         2,    2,    2,    2,    1,    1,    1,    1
435 435
     } ;
436 436
 
437
-static yyconst flex_int16_t yy_base[113] =
437
+static yyconst flex_int16_t yy_base[115] =
438 438
     {   0,
439
-        0,    0,  126,  127,   47,  127,  120,  127,   44,  116,
440
-      127,  127,   41,  102,  127,   39,  127,  101,   39,  127,
441
-      127,  100,   99,   98,    0,   79,  127,  127,   96,   76,
442
-       76,   75,   20,   16,   28,   81,   78,   77,  127,   42,
443
-      127,  127,   65,  105,  127,  127,  127,  101,  127,   87,
444
-      127,  127,  104,  127,  127,   89,   54,  127,  127,  127,
445
-        0,   67,  127,   72,   65,    0,   61,   70,   60,   61,
446
-        0,    0,   56,   65,   61,  127,  127,  127,   92,  127,
447
-       70,   54,   57,   42,   51,    0,    0,   52,   38,   42,
448
-       42,    0,   42,   42,    0,    0,   36,    0,   43,    0,
449
-
450
-       36,   35,    0,   29,    0,   38,    0,  127,   88,   90,
451
-       62,   92
439
+        0,    0,  128,  129,   47,  129,  122,  129,   44,  118,
440
+      129,  129,   41,  104,  129,   39,  129,  103,   39,  129,
441
+      129,   37,  102,   42,    0,   83,  129,  129,  100,   80,
442
+       80,   79,   29,   16,   35,   85,   82,   81,  129,   40,
443
+      129,  129,   67,  109,  129,  129,  129,  105,  129,   91,
444
+      129,  129,  108,  129,  129,   93,   57,  129,  129,  129,
445
+      129,  129,    0,   71,  129,   76,   69,    0,   65,   74,
446
+       64,   65,    0,    0,   60,   69,   65,  129,  129,  129,
447
+       96,  129,   81,   65,   68,   53,   62,    0,    0,   63,
448
+       42,   46,   46,    0,   46,   46,    0,    0,   40,    0,
449
+
450
+       47,    0,   40,   39,    0,   33,    0,   43,    0,  129,
451
+       86,   88,   69,   90
452 452
     } ;
453 453
 
454
-static yyconst flex_int16_t yy_def[113] =
454
+static yyconst flex_int16_t yy_def[115] =
455 455
     {   0,
456
-      108,    1,  108,  108,  108,  108,  109,  108,  108,  110,
457
-      108,  108,  108,  108,  108,  108,  108,  108,  108,  108,
458
-      108,  108,  108,  108,  111,  111,  108,  108,  108,  111,
459
-      111,  111,  111,  111,  111,  111,  111,  111,  108,  108,
460
-      108,  108,  108,  109,  108,  108,  108,  110,  108,  108,
461
-      108,  108,  112,  108,  108,  108,  108,  108,  108,  108,
462
-      111,  111,  108,  111,  111,  111,  111,  111,  111,  111,
463
-      111,  111,  111,  111,  111,  108,  108,  108,  112,  108,
464
-      108,  111,  111,  111,  111,  111,  111,  111,  111,  111,
465
-      111,  111,  111,  111,  111,  111,  111,  111,  111,  111,
466
-
467
-      111,  111,  111,  111,  111,  111,  111,    0,  108,  108,
468
-      108,  108
456
+      110,    1,  110,  110,  110,  110,  111,  110,  110,  112,
457
+      110,  110,  110,  110,  110,  110,  110,  110,  110,  110,
458
+      110,  110,  110,  110,  113,  113,  110,  110,  110,  113,
459
+      113,  113,  113,  113,  113,  113,  113,  113,  110,  110,
460
+      110,  110,  110,  111,  110,  110,  110,  112,  110,  110,
461
+      110,  110,  114,  110,  110,  110,  110,  110,  110,  110,
462
+      110,  110,  113,  113,  110,  113,  113,  113,  113,  113,
463
+      113,  113,  113,  113,  113,  113,  113,  110,  110,  110,
464
+      114,  110,  110,  113,  113,  113,  113,  113,  113,  113,
465
+      113,  113,  113,  113,  113,  113,  113,  113,  113,  113,
466
+
467
+      113,  113,  113,  113,  113,  113,  113,  113,  113,    0,
468
+      110,  110,  110,  110
469 469
     } ;
470 470
 
471
-static yyconst flex_int16_t yy_nxt[176] =
471
+static yyconst flex_int16_t yy_nxt[178] =
472 472
     {   0,
473 473
         4,    5,    5,    6,    7,    8,    9,   10,   11,   12,
474 474
        13,   14,   15,   16,   17,   18,   19,   20,   21,   22,
475 475
        23,   24,   25,   26,   27,   28,   29,   25,   30,   31,
476 476
        32,   33,   34,   25,   35,   25,   25,   25,   25,   36,
477 477
        25,   37,   25,   38,   39,   40,   41,   42,   43,   43,
478
-       46,   50,   53,   56,   69,   57,   67,   68,   70,   54,
479
-       71,   51,   76,   61,   47,   72,   43,   43,   56,  107,
480
-       57,  106,  105,  104,  103,  102,  101,  100,   99,   98,
481
-       97,   96,   95,   94,   93,   92,   81,   77,   44,   44,
482
-       48,   48,   79,   79,   80,   91,   90,   89,   88,   87,
483
-
484
-       86,   85,   84,   83,   82,   81,   80,   78,   49,   45,
485
-       75,   74,   73,   66,   65,   64,   63,   62,   60,   59,
486
-       58,   55,   52,   49,   45,  108,    3,  108,  108,  108,
487
-      108,  108,  108,  108,  108,  108,  108,  108,  108,  108,
488
-      108,  108,  108,  108,  108,  108,  108,  108,  108,  108,
489
-      108,  108,  108,  108,  108,  108,  108,  108,  108,  108,
490
-      108,  108,  108,  108,  108,  108,  108,  108,  108,  108,
491
-      108,  108,  108,  108,  108
478
+       46,   50,   53,   56,   71,   57,   58,   59,   72,   54,
479
+       78,   51,   61,   62,   47,   69,   70,   73,   43,   43,
480
+       63,   56,   74,   57,  109,  108,  107,  106,  105,  104,
481
+      103,  102,  101,  100,   99,   79,   44,   44,   48,   48,
482
+       81,   81,   98,   97,   96,   95,   94,   83,   82,   93,
483
+
484
+       92,   91,   90,   89,   88,   87,   86,   85,   84,   83,
485
+       82,   80,   49,   45,   77,   76,   75,   68,   67,   66,
486
+       65,   64,   60,   55,   52,   49,   45,  110,    3,  110,
487
+      110,  110,  110,  110,  110,  110,  110,  110,  110,  110,
488
+      110,  110,  110,  110,  110,  110,  110,  110,  110,  110,
489
+      110,  110,  110,  110,  110,  110,  110,  110,  110,  110,
490
+      110,  110,  110,  110,  110,  110,  110,  110,  110,  110,
491
+      110,  110,  110,  110,  110,  110,  110
492 492
     } ;
493 493
 
494
-static yyconst flex_int16_t yy_chk[176] =
494
+static yyconst flex_int16_t yy_chk[178] =
495 495
     {   0,
496 496
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
497 497
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
498 498
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
499 499
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
500 500
         1,    1,    1,    1,    1,    1,    1,    1,    5,    5,
501
-        9,   13,   16,   19,   34,   19,   33,   33,   34,   16,
502
-       35,   13,   40,  111,    9,   35,   43,   43,   57,  106,
503
-       57,  104,  102,  101,   99,   97,   94,   93,   91,   90,
504
-       89,   88,   85,   84,   83,   82,   81,   40,  109,  109,
505
-      110,  110,  112,  112,   79,   75,   74,   73,   70,   69,
506
-
507
-       68,   67,   65,   64,   62,   56,   53,   50,   48,   44,
508
-       38,   37,   36,   32,   31,   30,   29,   26,   24,   23,
509
-       22,   18,   14,   10,    7,    3,  108,  108,  108,  108,
510
-      108,  108,  108,  108,  108,  108,  108,  108,  108,  108,
511
-      108,  108,  108,  108,  108,  108,  108,  108,  108,  108,
512
-      108,  108,  108,  108,  108,  108,  108,  108,  108,  108,
513
-      108,  108,  108,  108,  108,  108,  108,  108,  108,  108,
514
-      108,  108,  108,  108,  108
501
+        9,   13,   16,   19,   34,   19,   22,   22,   34,   16,
502
+       40,   13,   24,   24,    9,   33,   33,   35,   43,   43,
503
+      113,   57,   35,   57,  108,  106,  104,  103,  101,   99,
504
+       96,   95,   93,   92,   91,   40,  111,  111,  112,  112,
505
+      114,  114,   90,   87,   86,   85,   84,   83,   81,   77,
506
+
507
+       76,   75,   72,   71,   70,   69,   67,   66,   64,   56,
508
+       53,   50,   48,   44,   38,   37,   36,   32,   31,   30,
509
+       29,   26,   23,   18,   14,   10,    7,    3,  110,  110,
510
+      110,  110,  110,  110,  110,  110,  110,  110,  110,  110,
511
+      110,  110,  110,  110,  110,  110,  110,  110,  110,  110,
512
+      110,  110,  110,  110,  110,  110,  110,  110,  110,  110,
513
+      110,  110,  110,  110,  110,  110,  110,  110,  110,  110,
514
+      110,  110,  110,  110,  110,  110,  110
515 515
     } ;
516 516
 
517 517
 static yy_state_type yy_last_accepting_state;
@@ -820,13 +820,13 @@ yy_match:
820 820
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
821 821
 				{
822 822
 				yy_current_state = (int) yy_def[yy_current_state];
823
-				if ( yy_current_state >= 109 )
823
+				if ( yy_current_state >= 111 )
824 824
 					yy_c = yy_meta[(unsigned int) yy_c];
825 825
 				}
826 826
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
827 827
 			++yy_cp;
828 828
 			}
829
-		while ( yy_base[yy_current_state] != 127 );
829
+		while ( yy_base[yy_current_state] != 129 );
830 830
 
831 831
 yy_find_action:
832 832
 		yy_act = yy_accept[yy_current_state];
@@ -1070,81 +1070,91 @@ YY_RULE_SETUP
1070 1070
 case 44:
1071 1071
 YY_RULE_SETUP
1072 1072
 #line 145 "tokenizer.lex"
1073
-{ return LBRACE; }
1073
+{ return RSHIFT; }
1074 1074
 	YY_BREAK
1075 1075
 case 45:
1076 1076
 YY_RULE_SETUP
1077 1077
 #line 147 "tokenizer.lex"
1078
-{ return RBRACE; }
1078
+{ return LSHIFT; }
1079 1079
 	YY_BREAK
1080 1080
 case 46:
1081 1081
 YY_RULE_SETUP
1082 1082
 #line 149 "tokenizer.lex"
1083
-{ return LBRACKET; }
1083
+{ return LBRACE; }
1084 1084
 	YY_BREAK
1085 1085
 case 47:
1086 1086
 YY_RULE_SETUP
1087 1087
 #line 151 "tokenizer.lex"
1088
-{ return RBRACKET; }
1088
+{ return RBRACE; }
1089 1089
 	YY_BREAK
1090 1090
 case 48:
1091 1091
 YY_RULE_SETUP
1092 1092
 #line 153 "tokenizer.lex"
1093
-{ return LPAREN; }
1093
+{ return LBRACKET; }
1094 1094
 	YY_BREAK
1095 1095
 case 49:
1096 1096
 YY_RULE_SETUP
1097 1097
 #line 155 "tokenizer.lex"
1098
-{ return RPAREN; }
1098
+{ return RBRACKET; }
1099 1099
 	YY_BREAK
1100 1100
 case 50:
1101 1101
 YY_RULE_SETUP
1102 1102
 #line 157 "tokenizer.lex"
1103
-{ return DOT; }
1103
+{ return LPAREN; }
1104 1104
 	YY_BREAK
1105 1105
 case 51:
1106 1106
 YY_RULE_SETUP
1107 1107
 #line 159 "tokenizer.lex"
1108
-{ return COLON; }
1108
+{ return RPAREN; }
1109 1109
 	YY_BREAK
1110 1110
 case 52:
1111 1111
 YY_RULE_SETUP
1112 1112
 #line 161 "tokenizer.lex"
1113
-{ return SEMICOLON; }
1113
+{ return DOT; }
1114 1114
 	YY_BREAK
1115 1115
 case 53:
1116 1116
 YY_RULE_SETUP
1117 1117
 #line 163 "tokenizer.lex"
1118
-{ return COMMA; }
1118
+{ return COLON; }
1119 1119
 	YY_BREAK
1120 1120
 case 54:
1121 1121
 YY_RULE_SETUP
1122 1122
 #line 165 "tokenizer.lex"
1123
-{ return POUND; }
1123
+{ return SEMICOLON; }
1124 1124
 	YY_BREAK
1125 1125
 case 55:
1126 1126
 YY_RULE_SETUP
1127 1127
 #line 167 "tokenizer.lex"
1128
-{ yylval = strdup(yytext); return IDENT; }
1128
+{ return COMMA; }
1129 1129
 	YY_BREAK
1130 1130
 case 56:
1131
-/* rule 56 can match eol */
1132 1131
 YY_RULE_SETUP
1133 1132
 #line 169 "tokenizer.lex"
1134
-/* Skip comments */
1133
+{ return POUND; }
1135 1134
 	YY_BREAK
1136 1135
 case 57:
1137
-/* rule 57 can match eol */
1138 1136
 YY_RULE_SETUP
1139 1137
 #line 171 "tokenizer.lex"
1140
-/* Skip whitespace */
1138
+{ yylval = strdup(yytext); return IDENT; }
1141 1139
 	YY_BREAK
1142 1140
 case 58:
1141
+/* rule 58 can match eol */
1143 1142
 YY_RULE_SETUP
1144 1143
 #line 173 "tokenizer.lex"
1144
+/* Skip comments */
1145
+	YY_BREAK
1146
+case 59:
1147
+/* rule 59 can match eol */
1148
+YY_RULE_SETUP
1149
+#line 175 "tokenizer.lex"
1150
+/* Skip whitespace */
1151
+	YY_BREAK
1152
+case 60:
1153
+YY_RULE_SETUP
1154
+#line 177 "tokenizer.lex"
1145 1155
 ECHO;
1146 1156
 	YY_BREAK
1147
-#line 1148 "lex.yy.c"
1157
+#line 1158 "lex.yy.c"
1148 1158
 case YY_STATE_EOF(INITIAL):
1149 1159
 	yyterminate();
1150 1160
 
@@ -1436,7 +1446,7 @@ static int yy_get_next_buffer (void)
1436 1446
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1437 1447
 			{
1438 1448
 			yy_current_state = (int) yy_def[yy_current_state];
1439
-			if ( yy_current_state >= 109 )
1449
+			if ( yy_current_state >= 111 )
1440 1450
 				yy_c = yy_meta[(unsigned int) yy_c];
1441 1451
 			}
1442 1452
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1464,11 +1474,11 @@ static int yy_get_next_buffer (void)
1464 1474
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1465 1475
 		{
1466 1476
 		yy_current_state = (int) yy_def[yy_current_state];
1467
-		if ( yy_current_state >= 109 )
1477
+		if ( yy_current_state >= 111 )
1468 1478
 			yy_c = yy_meta[(unsigned int) yy_c];
1469 1479
 		}
1470 1480
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1471
-	yy_is_jam = (yy_current_state == 108);
1481
+	yy_is_jam = (yy_current_state == 110);
1472 1482
 
1473 1483
 	return yy_is_jam ? 0 : yy_current_state;
1474 1484
 }
@@ -2142,7 +2152,7 @@ void yyfree (void * ptr )
2142 2152
 
2143 2153
 #define YYTABLES_NAME "yytables"
2144 2154
 
2145
-#line 173 "tokenizer.lex"
2155
+#line 177 "tokenizer.lex"
2146 2156
 
2147 2157
 
2148 2158
 

+ 108
- 65
object.c View File

@@ -3,12 +3,13 @@
3 3
 #include <stdlib.h>
4 4
 #include <string.h>
5 5
 #include <stdio.h>
6
+#include <assert.h>
6 7
 
7 8
 sol_object_t *sol_cast_int(sol_state_t *state, sol_object_t *obj) {
8 9
 	sol_object_t *res, *ls;
9 10
 	if(sol_is_int(obj)) return obj;
10 11
 	ls = sol_new_list(state);
11
-	sol_list_insert(state, &ls, 0, obj);
12
+	sol_list_insert(state, ls, 0, obj);
12 13
 	res = obj->ops->toint(state, ls);
13 14
 	sol_obj_free(ls);
14 15
 	sol_obj_free(obj);
@@ -19,7 +20,7 @@ sol_object_t *sol_cast_float(sol_state_t *state, sol_object_t *obj) {
19 20
 	sol_object_t *res, *ls;
20 21
 	if(sol_is_float(obj)) return obj;
21 22
 	ls = sol_new_list(state);
22
-	sol_list_insert(state, &ls, 0, obj);
23
+	sol_list_insert(state, ls, 0, obj);
23 24
 	res = obj->ops->tofloat(state, ls);
24 25
 	sol_obj_free(ls);
25 26
 	sol_obj_free(obj);
@@ -30,7 +31,7 @@ sol_object_t *sol_cast_string(sol_state_t *state, sol_object_t *obj) {
30 31
 	sol_object_t *res, *ls;
31 32
 	if(sol_is_string(obj)) return obj;
32 33
 	ls = sol_new_list(state);
33
-	sol_list_insert(state, &ls, 0, obj);
34
+	sol_list_insert(state, ls, 0, obj);
34 35
 	res = obj->ops->tostring(state, ls);
35 36
 	sol_obj_free(ls);
36 37
 	sol_obj_free(obj);
@@ -67,8 +68,16 @@ void sol_init_object(sol_state_t *state, sol_object_t *obj) {
67 68
 }
68 69
 
69 70
 void sol_obj_free(sol_object_t *obj) {
71
+	if(!obj) {
72
+		printf("WARNING: Attempt to free NULL\n");
73
+		return;
74
+	}
70 75
 	if(sol_decref(obj) <= 0) {
71
-		sol_obj_release(obj);
76
+		if(obj->refcnt < 0) {
77
+			printf("WARNING: Encountered refcnt < 0!\nObject %p type %d ref %d\n", obj, obj->type, obj->refcnt);
78
+		} else {
79
+			sol_obj_release(obj);
80
+		}
72 81
 	}
73 82
 }
74 83
 
@@ -147,8 +156,8 @@ int sol_list_len(sol_state_t *state, sol_object_t *list) {
147 156
 		sol_obj_free(sol_set_error_string(state, "Compute length of non-list"));
148 157
 		return -1;
149 158
 	}
150
-	while(cur && cur->lvalue) {
151
-		i++;
159
+	while(cur) {
160
+		if(cur->lvalue) i++;
152 161
 		cur = cur->lnext;
153 162
 	}
154 163
 	return i;
@@ -173,8 +182,8 @@ sol_object_t *sol_list_sublist(sol_state_t *state, sol_object_t *list, int idx)
173 182
 			if(cur->lnext) {
174 183
 				copy->lnext = sol_alloc_object(state);
175 184
 				copy = copy->lnext;
176
-				copy->type = SOL_LIST;
177
-				copy->ops = &(state->ListOps);
185
+				copy->type = SOL_LCELL;
186
+				copy->ops = &(state->LCellOps);
178 187
 				copy->lnext = NULL;
179 188
 				copy->lvalue = NULL;
180 189
 			}
@@ -193,11 +202,12 @@ sol_object_t *sol_list_get_index(sol_state_t *state, sol_object_t *list, int idx
193 202
 	if(idx < 0) {
194 203
 		return sol_set_error_string(state, "Get negative index");
195 204
 	}
196
-	while(cur && cur->lvalue && i < idx) {
197
-		i++;
205
+	while(cur && i < idx) {
206
+		if(cur->lvalue) i++;
198 207
 		cur = cur->lnext;
199 208
 	}
200
-	if(cur && cur->lvalue) {
209
+	while(cur && !cur->lvalue) cur = cur->lnext;
210
+	if(cur) {
201 211
 		return sol_incref(cur->lvalue);
202 212
 	} else {
203 213
 		return sol_set_error_string(state, "Get out-of-bounds index");
@@ -205,7 +215,7 @@ sol_object_t *sol_list_get_index(sol_state_t *state, sol_object_t *list, int idx
205 215
 }
206 216
 
207 217
 void sol_list_set_index(sol_state_t *state, sol_object_t *list, int idx, sol_object_t *obj) {
208
-	sol_object_t *cur = list;
218
+	sol_object_t *cur = list, *temp;
209 219
 	int i = 0;
210 220
 	if(!sol_is_list(list)) {
211 221
 		sol_obj_free(sol_set_error_string(state, "Set index of non-list"));
@@ -215,24 +225,25 @@ void sol_list_set_index(sol_state_t *state, sol_object_t *list, int idx, sol_obj
215 225
 		sol_obj_free(sol_set_error_string(state, "Set negative index"));
216 226
 		return;
217 227
 	}
218
-	while(cur && cur->lvalue && i < idx) {
219
-		i++;
228
+	while(cur && i < idx) {
229
+		if(cur->lvalue) i++;
220 230
 		cur = cur->lnext;
221 231
 	}
222 232
 	if(cur) {
223
-		sol_obj_free(cur->lvalue);
233
+		temp = cur->lvalue;
224 234
 		cur->lvalue = sol_incref(obj);
235
+		sol_obj_free(temp);
225 236
 	} else {
226 237
 		sol_obj_free(sol_set_error_string(state, "Set out-of-bounds index"));
227 238
 		return;
228 239
 	}
229 240
 }
230 241
 
231
-void sol_list_insert(sol_state_t *state, sol_object_t **list, int idx, sol_object_t *obj) {
232
-	sol_object_t *next = *list, *prev = NULL, *temp = sol_alloc_object(state);
242
+void sol_list_insert(sol_state_t *state, sol_object_t *list, int idx, sol_object_t *obj) {
243
+	sol_object_t *next = list, *prev = NULL, *temp = sol_alloc_object(state);
233 244
 	int i = 0;
234 245
 	if(sol_has_error(state)) return;
235
-	if(!sol_is_list(*list)) {
246
+	if(!sol_is_list(list)) {
236 247
 		sol_obj_free(sol_set_error_string(state, "Insert into non-list"));
237 248
 		return;
238 249
 	}
@@ -240,8 +251,8 @@ void sol_list_insert(sol_state_t *state, sol_object_t **list, int idx, sol_objec
240 251
 		sol_obj_free(sol_set_error_string(state, "Insert at negative index"));
241 252
 		return;
242 253
 	}
243
-	temp->type = SOL_LIST;
244
-	temp->ops = &(state->ListOps);
254
+	temp->type = SOL_LCELL;
255
+	temp->ops = &(state->LCellOps);
245 256
 	temp->lvalue = sol_incref(obj);
246 257
 	while(next && i < idx) {
247 258
 		if(next->lvalue) i++;
@@ -249,12 +260,18 @@ void sol_list_insert(sol_state_t *state, sol_object_t **list, int idx, sol_objec
249 260
 		next = next->lnext;
250 261
 	}
251 262
 	if(next) {
252
-		temp->lnext = next;
253 263
 		if(prev) {
254 264
 			prev->lnext = temp;
255
-		} else {
256
-			*list = temp;
257 265
 			temp->lnext = next;
266
+		} else {
267
+			assert(next == list);
268
+			temp->lnext = sol_alloc_object(state);
269
+			temp->lnext->type = SOL_LCELL;
270
+			temp->lnext->ops = &(state->LCellOps);
271
+			temp->lnext->lvalue = list->lvalue;
272
+			temp->lnext->lnext = list->lnext;
273
+			list->lnext = temp;
274
+			list->lvalue = NULL;
258 275
 		}
259 276
 	} else {
260 277
         if(prev) {
@@ -267,10 +284,11 @@ void sol_list_insert(sol_state_t *state, sol_object_t **list, int idx, sol_objec
267 284
             return;
268 285
         }
269 286
 	}
287
+	assert(!sol_validate_list(state, list));
270 288
 }
271 289
 
272
-sol_object_t *sol_list_remove(sol_state_t *state, sol_object_t **list, int idx) {
273
-	sol_object_t *next = *list, *prev = NULL, *res, *temp;
290
+sol_object_t *sol_list_remove(sol_state_t *state, sol_object_t *list, int idx) {
291
+	sol_object_t *next = list, *prev = NULL, *res, *temp;
274 292
 	int i = 0;
275 293
 	if(sol_has_error(state)) return sol_incref(state->None);
276 294
 	if(idx < 0) {
@@ -285,13 +303,12 @@ sol_object_t *sol_list_remove(sol_state_t *state, sol_object_t **list, int idx)
285 303
 		if(prev) {
286 304
             res = next->lvalue;
287 305
 			prev->lnext = next->lnext;
288
-			free(next);
306
+			sol_obj_free(next);
289 307
 		} else {
290
-            res = (*list)->lvalue;
291
-			temp = *list;
292
-			*list = (*list)->lnext;
293
-			free(temp);
308
+            res = list->lvalue;
309
+			list->lvalue = NULL;
294 310
 		}
311
+		assert(!sol_validate_list(state, list));
295 312
 		return res;
296 313
 	} else {
297 314
 		return sol_set_error_string(state, "Out-of-bounds remove");
@@ -307,8 +324,8 @@ sol_object_t *sol_list_copy(sol_state_t *state, sol_object_t *list) {
307 324
 			newls->lnext = sol_alloc_object(state);
308 325
 			if(sol_has_error(state)) return sol_incref(state->None);
309 326
 			newls = newls->lnext;
310
-			newls->type = SOL_LIST;
311
-			newls->ops = &(state->ListOps);
327
+			newls->type = SOL_LCELL;
328
+			newls->ops = &(state->LCellOps);
312 329
 		}
313 330
 		cur = cur->lnext;
314 331
 	}
@@ -318,13 +335,17 @@ sol_object_t *sol_list_copy(sol_state_t *state, sol_object_t *list) {
318 335
 void sol_list_append(sol_state_t *state, sol_object_t *dest, sol_object_t *src) {
319 336
     sol_object_t *curd = dest, *curs = src;
320 337
     while(curd->lnext) curd = curd->lnext;
321
-    while(curs && curs->lvalue) {
322
-        curd->lnext = sol_alloc_object(state);
323
-        if(sol_has_error(state)) return;
324
-        curd = curd->lnext;
325
-        curd->type = SOL_LIST;
326
-        curd->ops = &(state->ListOps);
327
-        curd->lvalue = sol_incref(curs->lvalue);
338
+    while(curs) {
339
+		if(curs->lvalue) {
340
+			curd->lvalue = sol_incref(curs->lvalue);
341
+			curd->lnext = sol_alloc_object(state);
342
+			if(sol_has_error(state)) return;
343
+			curd = curd->lnext;
344
+			curd->type = SOL_LCELL;
345
+			curd->ops = &(state->LCellOps);
346
+			curd->lnext = NULL;
347
+			curd->lvalue = NULL;
348
+		}
328 349
         curs = curs->lnext;
329 350
     }
330 351
 }
@@ -332,11 +353,16 @@ void sol_list_append(sol_state_t *state, sol_object_t *dest, sol_object_t *src)
332 353
 sol_object_t *sol_f_list_free(sol_state_t *state, sol_object_t *list) {
333 354
     sol_object_t *cur = list, *prev;
334 355
     while(cur) {
335
-        if(cur->lvalue) sol_obj_free(cur->lvalue);
336 356
         prev = cur;
337 357
         cur = cur->lnext;
338
-        if(prev!=list) free(prev);
358
+        if(prev!=list) sol_obj_free(prev);
339 359
     }
360
+    return list;
361
+}
362
+
363
+sol_object_t *sol_f_lcell_free(sol_state_t *state, sol_object_t *lcell) {
364
+	if(lcell->lvalue) sol_obj_free(lcell->lvalue);
365
+	return lcell;
340 366
 }
341 367
 
342 368
 int sol_test_cycle(sol_state_t *state, sol_object_t *seq) {
@@ -365,20 +391,20 @@ int sol_validate_list(sol_state_t *state, sol_object_t *list) {
365 391
 	while(cur) {
366 392
 		if(!sol_is_list(cur)) {
367 393
 			snprintf(msg, 128, "Node at index %d not a list node", i);
368
-			//sol_obj_free(sol_set_error_string(state, msg));
394
+			sol_obj_free(sol_set_error_string(state, msg));
369 395
 			return 1;
370 396
 		}
371
-		if(cur->lnext && !cur->lvalue) {
397
+		/*if(cur->lnext && !cur->lvalue) {
372 398
 			snprintf(msg, 128, "Node at index %d has a next node but NULL value", i);
373
-			//sol_obj_free(sol_set_error_string(state, msg));
399
+			sol_obj_free(sol_set_error_string(state, msg));
374 400
 			return 1;
375
-		}
401
+		}*/
376 402
 		cur = cur->lnext;
377 403
 		i++;
378 404
 	}
379 405
 	if(sol_test_cycle(state, list)) {
380 406
 		snprintf(msg, 128, "Cycle detected");
381
-		//sol_obj_free(sol_set_error_string(state, msg));
407
+		sol_obj_free(sol_set_error_string(state, msg));
382 408
 		return 1;
383 409
 	}
384 410
 	return 0;
@@ -406,12 +432,12 @@ int sol_map_len(sol_state_t *state, sol_object_t *map) {
406 432
 
407 433
 sol_object_t *sol_map_submap(sol_state_t *state, sol_object_t *map, sol_object_t *key) {
408 434
     sol_object_t *list = sol_new_list(state), *res = NULL, *cur = map, *cmp;
409
-    sol_list_insert(state, &list, 0, key);
435
+    sol_list_insert(state, list, 0, key);
410 436
     while(cur) {
411 437
         if(cur->mkey) {
412
-            sol_list_insert(state, &list, 1, cur->mkey);
438
+            sol_list_insert(state, list, 1, cur->mkey);
413 439
             cmp = sol_cast_int(state, key->ops->cmp(state, list));
414
-            sol_list_remove(state, &list, 1);
440
+            sol_list_remove(state, list, 1);
415 441
             if(cmp->ival == 0) {
416 442
                 res = cur;
417 443
                 break;
@@ -437,23 +463,29 @@ sol_object_t *sol_map_get(sol_state_t *state, sol_object_t *map, sol_object_t *k
437 463
     }
438 464
 }
439 465
 
466
+sol_object_t *sol_map_get_name(sol_state_t *state, sol_object_t *map, char *name) {
467
+	sol_object_t *key = sol_new_string(state, name);
468
+	sol_object_t *res = sol_map_get(state, map, key);
469
+	sol_obj_free(key);
470
+	return res;
471
+}
472
+
440 473
 void sol_map_set(sol_state_t *state, sol_object_t *map, sol_object_t *key, sol_object_t *val) {
441 474
     sol_object_t *cur = map, *prev = NULL, *list = sol_new_list(state), *cmp;
442
-    sol_list_insert(state, &list, 0, key);
475
+    sol_list_insert(state, list, 0, key);
443 476
     while(cur) {
444 477
         if(cur->mkey) {
445
-            sol_list_insert(state, &list, 1, cur->mkey);
478
+            sol_list_insert(state, list, 1, cur->mkey);
446 479
             cmp = sol_cast_int(state, key->ops->cmp(state, list));
447
-            sol_list_remove(state, &list, 1);
480
+            sol_list_remove(state, list, 1);
448 481
             if(cmp->ival == 0) {
449
-                sol_obj_free(cur->mval);
450 482
                 if(sol_is_none(state, val)) {
451 483
                     if(prev) {
452 484
                         prev->mnext = cur->mnext;
453
-                        sol_obj_free(cur->mkey);
454
-                        free(cur);
485
+                        sol_obj_free(cur);
455 486
                     } else {
456 487
                         sol_obj_free(cur->mkey);
488
+						sol_obj_free(cur->mval);
457 489
                         cur->mkey = NULL;
458 490
                         cur->mval = NULL;
459 491
                     }
@@ -470,30 +502,35 @@ void sol_map_set(sol_state_t *state, sol_object_t *map, sol_object_t *key, sol_o
470 502
     prev->mnext = sol_alloc_object(state);
471 503
     if(sol_has_error(state)) return;
472 504
     cur = prev->mnext;
473
-    cur->type = SOL_MAP;
474
-    cur->ops = &(state->MapOps);
505
+    cur->type = SOL_MCELL;
506
+    cur->ops = &(state->MCellOps);
475 507
     cur->mkey = sol_incref(key);
476 508
     cur->mval = sol_incref(val);
477 509
     cur->mnext = NULL;
478 510
 }
479 511
 
512
+void sol_map_set_name(sol_state_t *state, sol_object_t *map, char *name, sol_object_t *val) {
513
+	sol_object_t *key = sol_new_string(state, name);
514
+	sol_map_set(state, map, key, val);
515
+	sol_obj_free(key);
516
+}
517
+
480 518
 void sol_map_set_existing(sol_state_t *state, sol_object_t *map, sol_object_t *key, sol_object_t *val) {
481 519
     sol_object_t *cur = map, *prev = NULL, *list = sol_new_list(state), *cmp;
482
-    sol_list_insert(state, &list, 0, key);
520
+    sol_list_insert(state, list, 0, key);
483 521
     while(cur) {
484 522
         if(cur->mkey) {
485
-            sol_list_insert(state, &list, 1, cur->mkey);
523
+            sol_list_insert(state, list, 1, cur->mkey);
486 524
             cmp = sol_cast_int(state, key->ops->cmp(state, list));
487
-            sol_obj_free(sol_list_remove(state, &list, 1));
525
+            sol_obj_free(sol_list_remove(state, list, 1));
488 526
             if(cmp->ival == 0) {
489
-                sol_obj_free(cur->mval);
490 527
                 if(sol_is_none(state, val)) {
491 528
                     if(prev) {
492 529
                         prev->mnext = cur->mnext;
493
-                        sol_obj_free(cur->mkey);
494
-                        free(cur);
530
+                        sol_obj_free(cur);
495 531
                     } else {
496 532
                         sol_obj_free(cur->mkey);
533
+						sol_obj_free(cur->mval);
497 534
                         cur->mkey = NULL;
498 535
                         cur->mval = NULL;
499 536
                     }
@@ -516,8 +553,8 @@ sol_object_t *sol_map_copy(sol_state_t *state, sol_object_t *map) {
516 553
             newcur->mval = sol_incref(cur->mval);
517 554
             newcur->mnext = sol_alloc_object(state);
518 555
             newcur = newcur->mnext;
519
-            newcur->type = SOL_MAP;
520
-            newcur->ops = &(state->MapOps);
556
+            newcur->type = SOL_MCELL;
557
+            newcur->ops = &(state->MCellOps);
521 558
             newcur->mkey = NULL;
522 559
             newcur->mval = NULL;
523 560
             newcur->mnext = NULL;
@@ -561,6 +598,12 @@ sol_object_t *sol_f_map_free(sol_state_t *state, sol_object_t *map) {
561 598
     return map;
562 599
 }
563 600
 
601
+sol_object_t *sol_f_mcell_free(sol_state_t *state, sol_object_t *mcell) {
602
+	if(mcell->mkey) sol_obj_free(mcell->mkey);
603
+	if(mcell->mval) sol_obj_free(mcell->mval);
604
+	return mcell;
605
+}
606
+
564 607
 int sol_validate_map(sol_state_t *state, sol_object_t *map) {
565 608
 	sol_object_t *cur = map;
566 609
 	int i = 0;

+ 3665
- 2842
parser.output
File diff suppressed because it is too large
View File


+ 392
- 356
parser.tab.c
File diff suppressed because it is too large
View File


+ 13
- 11
parser.tab.h View File

@@ -89,17 +89,19 @@ extern int yydebug;
89 89
      GREATER = 298,
90 90
      LESSEQ = 299,
91 91
      GREATEREQ = 300,
92
-     LBRACE = 301,
93
-     RBRACE = 302,
94
-     LPAREN = 303,
95
-     RPAREN = 304,
96
-     LBRACKET = 305,
97
-     RBRACKET = 306,
98
-     DOT = 307,
99
-     COLON = 308,
100
-     SEMICOLON = 309,
101
-     COMMA = 310,
102
-     POUND = 311
92
+     RSHIFT = 301,
93
+     LSHIFT = 302,
94
+     LBRACE = 303,
95
+     RBRACE = 304,
96
+     LPAREN = 305,
97
+     RPAREN = 306,
98
+     LBRACKET = 307,
99
+     RBRACKET = 308,
100
+     DOT = 309,
101
+     COLON = 310,
102
+     SEMICOLON = 311,
103
+     COMMA = 312,
104
+     POUND = 313
103 105
    };
104 106
 #endif
105 107
 

+ 24
- 5
parser.y View File

@@ -18,7 +18,7 @@
18 18
 %token INT FLOAT STRING
19 19
 %token PLUS MINUS STAR SLASH DSTAR BAND BOR BXOR BNOT LAND LOR LNOT
20 20
 %token ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNSTAR ASSIGNSLASH ASSIGNDSTAR ASSIGNBAND ASSIGNBOR ASSIGNBXOR
21
-%token EQUAL LESS GREATER LESSEQ GREATEREQ
21
+%token EQUAL LESS GREATER LESSEQ GREATEREQ RSHIFT LSHIFT
22 22
 %token LBRACE RBRACE LPAREN RPAREN LBRACKET RBRACKET DOT COLON SEMICOLON COMMA POUND
23 23
 
24 24
 %parse-param {stmt_node **program}
@@ -36,7 +36,7 @@ stmt:
36 36
 | IF expr THEN stmt END { $$ = NEW_ST(); AS_ST($$)->type = ST_IFELSE; AS_ST($$)->ifelse = NEW(ifelse_node); AS_ST($$)->ifelse->cond = $2; AS_ST($$)->ifelse->iftrue = $4; AS_ST($$)->ifelse->iffalse = NULL; }
37 37
 | IF expr THEN stmt ELSE stmt END { $$ = NEW_ST(); AS_ST($$)->type = ST_IFELSE; AS_ST($$)->ifelse = NEW(ifelse_node); AS_ST($$)->ifelse->cond = $2; AS_ST($$)->ifelse->iftrue = $4; AS_ST($$)->ifelse->iffalse = $6; }
38 38
 | WHILE expr DO stmt END { $$ = NEW_ST(); AS_ST($$)->type = ST_LOOP; AS_ST($$)->loop = NEW(loop_node); AS_ST($$)->loop->cond = $2; AS_ST($$)->loop->loop = $4; }
39
-| FOR IDENT IN expr DO stmt END { $$ = NEW_ST(); AS_ST($$)->type = ST_ITER; AS_ST($$)->iter = NEW(iter_node); AS_ST($$)->iter->var = strdup($2); AS_ST($$)->iter->iter = $4; AS_ST($$)->iter->loop = $6; }
39
+| FOR IDENT IN expr DO stmt END { $$ = NEW_ST(); AS_ST($$)->type = ST_ITER; AS_ST($$)->iter = NEW(iter_node); AS_ST($$)->iter->var = $2; AS_ST($$)->iter->iter = $4; AS_ST($$)->iter->loop = $6; }
40 40
 | RETURN expr { $$ = NEW_ST(); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = $2; }
41 41
 | RETURN { $$ = NEW_ST(); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = NULL; }
42 42
 | BREAK { $$ = NEW_ST(); AS_ST($$)->type = ST_BREAK; }
@@ -282,9 +282,11 @@ power_expr:
282 282
 ;
283 283
 
284 284
 binary_expr:
285
-  ubinary_expr BAND ubinary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_BAND; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
286
-| ubinary_expr BOR ubinary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_BOR; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
287
-| ubinary_expr BXOR ubinary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_BXOR; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
285
+  binary_expr BAND binary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_BAND; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
286
+| binary_expr BOR binary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_BOR; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
287
+| binary_expr BXOR binary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_BXOR; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
288
+| binary_expr LSHIFT binary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_LSHIFT; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
289
+| binary_expr RSHIFT binary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_RSHIFT; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
288 290
 | ubinary_expr { $$ = $1; }
289 291
 ;
290 292
 
@@ -300,6 +302,23 @@ ulen_expr:
300 302
 
301 303
 call_expr:
302 304
   call_expr LPAREN expr_list RPAREN { $$ = NEW_EX(); AS_EX($$)->type = EX_CALL; AS_EX($$)->call = NEW(call_node); AS_EX($$)->call->expr = $1; AS_EX($$)->call->args = $3; }
305
+| call_expr COLON IDENT LPAREN expr_list RPAREN {
306
+	$$ = NEW_EX();
307
+	AS_EX($$)->type = EX_CALL;
308
+	AS_EX($$)->call = NEW(call_node);
309
+	AS_EX($$)->call->expr = NEW_EX();
310
+	AS_EX($$)->call->expr->type = EX_INDEX;
311
+	AS_EX($$)->call->expr->index = NEW(index_node);
312
+	AS_EX($$)->call->expr->index->expr = $1;
313
+	AS_EX($$)->call->expr->index->index = NEW_EX();
314
+	AS_EX($$)->call->expr->index->index->type = EX_LIT;
315
+	AS_EX($$)->call->expr->index->index->lit = NEW(lit_node);
316
+	AS_EX($$)->call->expr->index->index->lit->type = LIT_STRING;
317
+	AS_EX($$)->call->expr->index->index->lit->str = $3;
318
+	AS_EX($$)->call->args = NEW(exprlist_node);
319
+	AS_EX($$)->call->args->expr = $1;
320
+	AS_EX($$)->call->args->next = $5;
321
+}
303 322
 | funcdecl_expr { $$ = $1; }
304 323
 ;
305 324
 

+ 60
- 26
runtime.c View File

@@ -190,7 +190,7 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
190 190
             res = sol_new_list(state);
191 191
             cure = expr->listgen->list;
192 192
             while(cure) {
193
-                if(cure->expr) sol_list_insert(state, &res, sol_list_len(state, res), sol_eval(state, cure->expr));
193
+                if(cure->expr) sol_list_insert(state, res, sol_list_len(state, res), sol_eval(state, cure->expr));
194 194
                 cure = cure->next;
195 195
             }
196 196
             return res;
@@ -210,8 +210,8 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
210 210
             list = sol_new_list(state);
211 211
             left = sol_eval(state, expr->binop->left);
212 212
             right = sol_eval(state, expr->binop->right);
213
-            sol_list_insert(state, &list, 0, left);
214
-            sol_list_insert(state, &list, 1, right);
213
+            sol_list_insert(state, list, 0, left);
214
+            sol_list_insert(state, list, 1, right);
215 215
             switch(expr->binop->type) {
216 216
                 case OP_ADD:
217 217
                     res = left->ops->add(state, list);
@@ -238,7 +238,7 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
238 238
                     break;
239 239
 
240 240
                 case OP_BOR:
241
-                    res = left->ops->bor(state, list);
241
+                    res = left->ops->bor(state, list);			printf("BINOP\n"); ob_print(list); printf("\n");
242 242
                     break;
243 243
 
244 244
                 case OP_BXOR:
@@ -249,16 +249,16 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
249 249
                     lint = sol_cast_int(state, left);
250 250
                     rint = sol_cast_int(state, right);
251 251
                     res = sol_new_int(state, BOOL_TO_INT(lint && rint));
252
-                    sol_obj_free(lint);
253
-                    sol_obj_free(rint);
252
+                    if(lint != left) sol_obj_free(lint);
253
+                    if(rint != right) sol_obj_free(rint);
254 254
                     break;
255 255
 
256 256
                 case OP_LOR:
257 257
                     lint = sol_cast_int(state, left);
258 258
                     rint = sol_cast_int(state, right);
259 259
                     res = sol_new_int(state, BOOL_TO_INT(lint || rint));
260
-                    sol_obj_free(lint);
261
-                    sol_obj_free(rint);
260
+                    if(lint != left) sol_obj_free(lint);
261
+                    if(rint != right) sol_obj_free(rint);
262 262
                     break;
263 263
 
264 264
                 case OP_EQUAL:
@@ -280,21 +280,29 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
280 280
                 case OP_GREATEREQ:
281 281
                     res = sol_new_int(state, BOOL_TO_INT(sol_cast_int(state, left->ops->cmp(state, list))->ival>=0));
282 282
                     break;
283
+					
284
+				case OP_LSHIFT:
285
+					res = left->ops->blsh(state, list);
286
+					break;
287
+					
288
+				case OP_RSHIFT:
289
+					res = left->ops->brsh(state, list);
290
+					break;
283 291
             }
292
+            sol_obj_free(list);
284 293
             sol_obj_free(left);
285 294
             sol_obj_free(right);
286
-            sol_obj_free(list);
287 295
             return res;
288 296
             break;
289 297
 
290 298
         case EX_UNOP:
291 299
             left = sol_eval(state, expr->unop->expr);
292 300
             list = sol_new_list(state);
293
-            sol_list_insert(state, &list, 0, left);
301
+            sol_list_insert(state, list, 0, left);
294 302
             switch(expr->unop->type) {
295 303
                 case OP_NEG:
296 304
                     right = sol_new_int(state, -1);
297
-                    sol_list_insert(state, &list, 1, right);
305
+                    sol_list_insert(state, list, 1, right);
298 306
                     res = left->ops->mul(state, list);
299 307
                     sol_obj_free(right);
300 308
                     break;
@@ -322,8 +330,8 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
322 330
             left = sol_eval(state, expr->index->expr);
323 331
             right = sol_eval(state, expr->index->index);
324 332
             list = sol_new_list(state);
325
-            sol_list_insert(state, &list, 0, left);
326
-            sol_list_insert(state, &list, 1, right);
333
+            sol_list_insert(state, list, 0, left);
334
+            sol_list_insert(state, list, 1, right);
327 335
             res = left->ops->index(state, list);
328 336
             sol_obj_free(left);
329 337
             sol_obj_free(right);
@@ -336,9 +344,9 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
336 344
             right = sol_eval(state, expr->setindex->index);
337 345
             value = sol_eval(state, expr->setindex->value);
338 346
             list = sol_new_list(state);
339
-            sol_list_insert(state, &list, 0, left);
340
-            sol_list_insert(state, &list, 1, right);
341
-            sol_list_insert(state, &list, 2, value);
347
+            sol_list_insert(state, list, 0, left);
348
+            sol_list_insert(state, list, 1, right);
349
+            sol_list_insert(state, list, 2, value);
342 350
             res = left->ops->setindex(state, list);
343 351
             sol_obj_free(left);
344 352
             sol_obj_free(right);
@@ -360,10 +368,10 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
360 368
         case EX_CALL:
361 369
             value = sol_eval(state, expr->call->expr);
362 370
             list = sol_new_list(state);
363
-            sol_list_insert(state, &list, 0, value);
371
+            sol_list_insert(state, list, 0, value);
364 372
             cure = expr->call->args;
365 373
             while(cure) {
366
-                if(cure->expr) sol_list_insert(state, &list, sol_list_len(state, list), sol_eval(state, cure->expr));
374
+                if(cure->expr) sol_list_insert(state, list, sol_list_len(state, list), sol_eval(state, cure->expr));
367 375
                 cure = cure->next;
368 376
             }
369 377
             res = value->ops->call(state, list);
@@ -383,7 +391,7 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
383 391
 }
384 392
 
385 393
 void sol_exec(sol_state_t *state, stmt_node *stmt) {
386
-    sol_object_t *value, *vint;
394
+    sol_object_t *value, *vint, *list, *iter, *item;
387 395
     stmtlist_node *curs;
388 396
     if(!stmt) {
389 397
         sol_obj_free(sol_set_error_string(state, "Execute NULL statement"));
@@ -410,7 +418,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
410 418
             value = sol_eval(state, stmt->loop->cond);
411 419
             vint = sol_cast_int(state, value);
412 420
             while(vint->ival) {
413
-                sol_obj_free(value);
421
+                if(value != vint) sol_obj_free(value);
414 422
                 sol_obj_free(vint);
415 423
                 sol_exec(state, stmt->loop->loop);
416 424
                 if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) break;
@@ -418,18 +426,40 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
418 426
                 vint = sol_cast_int(state, value);
419 427
             }
420 428
             state->sflag = SF_NORMAL;
429
+			if(vint != value) sol_obj_free(value);
430
+			if(vint) sol_obj_free(vint);
421 431
             break;
422 432
 
423 433
         case ST_ITER:
424 434
             value = sol_eval(state, stmt->iter->iter);
425
-            while(value != state->StopIteration) {
426
-                sol_state_assign_l_name(state, stmt->iter->var, value);
427
-                sol_obj_free(value);
428
-                sol_exec(state, stmt->loop->loop);
435
+			if(value->ops->iter && value->ops->iter != sol_f_not_impl) {
436
+				list = sol_new_list(state);
437
+				sol_list_insert(state, list, 0, value);
438
+				iter = value->ops->iter(state, list);
439
+				sol_obj_free(list);
440
+			} else {
441
+				iter = value;
442
+			}
443
+			if(!iter->ops->call || iter->ops->call==sol_f_not_impl) {
444
+				sol_obj_free(sol_set_error_string(state, "Iterate over non-iterable"));
445
+				return;
446
+			}
447
+			list = sol_new_list(state);
448
+			sol_list_insert(state, list, 0, iter);
449
+			sol_list_insert(state, list, 1, value);
450
+			sol_list_insert(state, list, 2, sol_new_map(state));
451
+			item = iter->ops->call(state, list);
452
+            while(item != state->StopIteration) {
453
+                sol_state_assign_l_name(state, stmt->iter->var, item);
454
+                sol_exec(state, stmt->iter->loop);
455
+				sol_obj_free(item);
429 456
                 if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) break;
430
-                value = sol_eval(state, stmt->iter->iter);
457
+                item = iter->ops->call(state, list);
431 458
             }
432 459
             state->sflag = SF_NORMAL;
460
+			sol_obj_free(list);
461
+			sol_obj_free(iter);
462
+			sol_obj_free(value);
433 463
             break;
434 464
 
435 465
         case ST_LIST:
@@ -461,9 +491,12 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
461 491
 sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
462 492
     sol_object_t *res, *scope, *value, *curo = args, *key;
463 493
     identlist_node *curi;
494
+	while(curo && !curo->lvalue) curo = curo->lnext;
495
+	if(!curo) return sol_incref(state->None);
464 496
     value = curo->lvalue;
465
-	if(!value->func) return sol_incref(state->None);
497
+	if(!value || !value->func) return sol_incref(state->None);
466 498
     curo = curo->lnext;
499
+	while(curo && !curo->lvalue) curo = curo->lnext;
467 500
     scope = sol_map_copy(state, value->closure);
468 501
     curi = AS(value->args, identlist_node);
469 502
     while(curi) {
@@ -474,6 +507,7 @@ sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
474 507
             } else {
475 508
                 sol_map_set(state, scope, key, curo->lvalue);
476 509
                 curo = curo->lnext;
510
+				while(curo && !curo->lvalue) curo = curo->lnext;
477 511
             }
478 512
             sol_obj_free(key);
479 513
             curi = curi->next;

+ 39
- 6
sol.h View File

@@ -23,12 +23,15 @@ typedef struct {
23 23
 	sol_cfunc_t band;
24 24
 	sol_cfunc_t bor;
25 25
 	sol_cfunc_t bxor;
26
+	sol_cfunc_t blsh;
27
+	sol_cfunc_t brsh;
26 28
 	sol_cfunc_t bnot;
27 29
 	sol_cfunc_t cmp;
28 30
 	sol_cfunc_t call;
29 31
 	sol_cfunc_t index;
30 32
 	sol_cfunc_t setindex;
31 33
 	sol_cfunc_t len;
34
+	sol_cfunc_t iter;
32 35
 	sol_cfunc_t toint;
33 36
 	sol_cfunc_t tofloat;
34 37
 	sol_cfunc_t tostring;
@@ -42,7 +45,9 @@ typedef enum {
42 45
 	SOL_FLOAT,
43 46
 	SOL_STRING,
44 47
 	SOL_LIST,
48
+	SOL_LCELL,
45 49
 	SOL_MAP,
50
+	SOL_MCELL,
46 51
 	SOL_FUNCTION,
47 52
 	SOL_CFUNCTION,
48 53
 	SOL_CDATA
@@ -96,7 +101,9 @@ typedef struct sol_tag_state_t {
96 101
 	sol_ops_t FloatOps;
97 102
 	sol_ops_t StringOps;
98 103
 	sol_ops_t ListOps;
104
+	sol_ops_t LCellOps;
99 105
 	sol_ops_t MapOps;
106
+	sol_ops_t MCellOps;
100 107
 	sol_ops_t FuncOps;
101 108
 	sol_ops_t CFuncOps;
102 109
 } sol_state_t;
@@ -133,6 +140,20 @@ sol_object_t *sol_f_tostring(sol_state_t *, sol_object_t *);
133 140
 sol_object_t *sol_f_try(sol_state_t *, sol_object_t *);
134 141
 sol_object_t *sol_f_type(sol_state_t *, sol_object_t *);
135 142
 sol_object_t *sol_f_prepr(sol_state_t *, sol_object_t *);
143
+sol_object_t *sol_f_print(sol_state_t *, sol_object_t *);
144
+sol_object_t *sol_f_rawget(sol_state_t *, sol_object_t *);
145
+sol_object_t *sol_f_rawset(sol_state_t *, sol_object_t *);
146
+sol_object_t *sol_f_range(sol_state_t *, sol_object_t *);
147
+
148
+sol_object_t *sol_f_debug_getref(sol_state_t *, sol_object_t *);
149
+sol_object_t *sol_f_debug_setref(sol_state_t *, sol_object_t *);
150
+sol_object_t *sol_f_debug_closure(sol_state_t *, sol_object_t *);
151
+sol_object_t *sol_f_debug_globals(sol_state_t *, sol_object_t *);
152
+sol_object_t *sol_f_debug_locals(sol_state_t *, sol_object_t *);
153
+
154
+sol_object_t *sol_f_iter_str(sol_state_t *, sol_object_t *);
155
+sol_object_t *sol_f_iter_list(sol_state_t *, sol_object_t *);
156
+sol_object_t *sol_f_iter_map(sol_state_t *, sol_object_t *);
136 157
 
137 158
 sol_object_t *sol_f_int_add(sol_state_t *, sol_object_t *);
138 159
 sol_object_t *sol_f_int_sub(sol_state_t *, sol_object_t *);
@@ -142,6 +163,8 @@ sol_object_t *sol_f_int_pow(sol_state_t *, sol_object_t *);
142 163
 sol_object_t *sol_f_int_band(sol_state_t *, sol_object_t *);
143 164
 sol_object_t *sol_f_int_bor(sol_state_t *, sol_object_t *);
144 165
 sol_object_t *sol_f_int_bxor(sol_state_t *, sol_object_t *);
166
+sol_object_t *sol_f_int_blsh(sol_state_t *, sol_object_t *);
167
+sol_object_t *sol_f_int_brsh(sol_state_t *, sol_object_t *);
145 168
 sol_object_t *sol_f_int_bnot(sol_state_t *, sol_object_t *);
146 169
 sol_object_t *sol_f_int_cmp(sol_state_t *, sol_object_t *);
147 170
 sol_object_t *sol_f_int_toint(sol_state_t *, sol_object_t *);
@@ -161,6 +184,7 @@ sol_object_t *sol_f_float_tostring(sol_state_t *, sol_object_t *);
161 184
 sol_object_t *sol_f_str_add(sol_state_t *, sol_object_t *);
162 185
 sol_object_t *sol_f_str_mul(sol_state_t *, sol_object_t *);
163 186
 sol_object_t *sol_f_str_len(sol_state_t *, sol_object_t *);
187
+sol_object_t *sol_f_str_iter(sol_state_t *, sol_object_t *);
164 188
 sol_object_t *sol_f_str_cmp(sol_state_t *, sol_object_t *);
165 189
 sol_object_t *sol_f_str_toint(sol_state_t *, sol_object_t *);
166 190
 sol_object_t *sol_f_str_tofloat(sol_state_t *, sol_object_t *);
@@ -171,15 +195,20 @@ sol_object_t *sol_f_list_mul(sol_state_t *, sol_object_t *);
171 195
 sol_object_t *sol_f_list_index(sol_state_t *, sol_object_t *);
172 196
 sol_object_t *sol_f_list_setindex(sol_state_t *, sol_object_t *);
173 197
 sol_object_t *sol_f_list_len(sol_state_t *, sol_object_t *);
198
+sol_object_t *sol_f_list_iter(sol_state_t *, sol_object_t *);
174 199
 sol_object_t *sol_f_list_tostring(sol_state_t *, sol_object_t *);
175 200
 
176 201
 sol_object_t *sol_f_map_add(sol_state_t *, sol_object_t *);
177 202
 sol_object_t *sol_f_map_index(sol_state_t *, sol_object_t *);
178 203
 sol_object_t *sol_f_map_setindex(sol_state_t *, sol_object_t *);
204
+sol_object_t *sol_f_map_call(sol_state_t *, sol_object_t *);
179 205
 sol_object_t *sol_f_map_len(sol_state_t *, sol_object_t *);
206
+sol_object_t *sol_f_map_iter(sol_state_t *, sol_object_t *);
180 207
 sol_object_t *sol_f_map_tostring(sol_state_t *, sol_object_t *);
181 208
 
182 209
 sol_object_t *sol_f_func_call(sol_state_t *, sol_object_t *); // Defined in ast.c
210
+sol_object_t *sol_f_func_index(sol_state_t *, sol_object_t *);
211
+sol_object_t *sol_f_func_setindex(sol_state_t *, sol_object_t *);
183 212
 sol_object_t *sol_f_func_tostring(sol_state_t *, sol_object_t *);
184 213
 
185 214
 sol_object_t *sol_f_cfunc_call(sol_state_t *, sol_object_t *);
@@ -199,8 +228,8 @@ void sol_obj_release(sol_object_t *);
199 228
 #define sol_is_int(obj) ((obj)-> type == SOL_INTEGER)
200 229
 #define sol_is_float(obj) ((obj)->type == SOL_FLOAT)
201 230
 #define sol_is_string(obj) ((obj)->type == SOL_STRING)
202
-#define sol_is_list(obj) ((obj)->type == SOL_LIST)
203
-#define sol_is_map(obj) ((obj)->type == SOL_MAP)
231
+#define sol_is_list(obj) ((obj)->type == SOL_LIST || (obj)->type == SOL_LCELL)
232
+#define sol_is_map(obj) ((obj)->type == SOL_MAP || (obj)->type == SOL_MCELL)
204 233
 #define sol_is_func(obj) ((obj)->type == SOL_FUNCTION)
205 234
 #define sol_is_cfunc(obj) ((obj)->type == SOL_CFUNCTION)
206 235
 #define sol_is_cdata(obj) ((obj)->type == SOL_CDATA)
@@ -219,18 +248,20 @@ int sol_list_len(sol_state_t *, sol_object_t *);
219 248
 sol_object_t *sol_list_sublist(sol_state_t *, sol_object_t *, int);
220 249
 sol_object_t *sol_list_get_index(sol_state_t *, sol_object_t *, int);
221 250
 void sol_list_set_index(sol_state_t *, sol_object_t *, int, sol_object_t *);
222
-void sol_list_insert(sol_state_t *, sol_object_t **, int, sol_object_t *);
223
-sol_object_t *sol_list_remove(sol_state_t *, sol_object_t **, int);
251
+void sol_list_insert(sol_state_t *, sol_object_t *, int, sol_object_t *);
252
+sol_object_t *sol_list_remove(sol_state_t *, sol_object_t *, int);
224 253
 sol_object_t *sol_list_copy(sol_state_t *, sol_object_t *);
225 254
 void sol_list_append(sol_state_t *, sol_object_t *, sol_object_t *);
226
-#define sol_list_push(st, ls, obj) sol_list_insert(st, &(ls), 0, obj);
227
-#define sol_list_pop(st, ls) sol_list_remove(st, &(ls), 0);
255
+#define sol_list_push(st, ls, obj) sol_list_insert(st, ls, 0, obj);
256
+#define sol_list_pop(st, ls) sol_list_remove(st, ls, 0);
228 257
 
229 258
 sol_object_t *sol_new_map(sol_state_t *);
230 259
 int sol_map_len(sol_state_t *, sol_object_t *);
231 260
 sol_object_t *sol_map_submap(sol_state_t *, sol_object_t *, sol_object_t *);
232 261
 sol_object_t *sol_map_get(sol_state_t *, sol_object_t *, sol_object_t *);
262
+sol_object_t *sol_map_get_name(sol_state_t *, sol_object_t *, char *);
233 263
 void sol_map_set(sol_state_t *, sol_object_t *, sol_object_t *, sol_object_t *);
264
+void sol_map_set_name(sol_state_t *, sol_object_t *, char *, sol_object_t *);
234 265
 void sol_map_set_existing(sol_state_t *, sol_object_t *, sol_object_t *, sol_object_t *);
235 266
 sol_object_t *sol_map_copy(sol_state_t *, sol_object_t *);
236 267
 void sol_map_merge(sol_state_t *, sol_object_t *, sol_object_t *);
@@ -248,7 +279,9 @@ sol_object_t *sol_cast_string(sol_state_t *, sol_object_t *);
248 279
 
249 280
 sol_object_t *sol_f_str_free(sol_state_t *, sol_object_t *);
250 281
 sol_object_t *sol_f_list_free(sol_state_t *, sol_object_t *);
282
+sol_object_t *sol_f_lcell_free(sol_state_t *, sol_object_t *);
251 283
 sol_object_t *sol_f_map_free(sol_state_t *, sol_object_t *);
284
+sol_object_t *sol_f_mcell_free(sol_state_t *, sol_object_t *);
252 285
 
253 286
 int sol_validate_list(sol_state_t *, sol_object_t *);
254 287
 int sol_validate_map(sol_state_t *, sol_object_t *);

+ 68
- 93
state.c View File

@@ -1,7 +1,7 @@
1 1
 #include "sol.h"
2 2
 
3 3
 int sol_state_init(sol_state_t *state) {
4
-	sol_object_t *globals;
4
+	sol_object_t *globals, *debug, *iter;
5 5
 
6 6
 	state->None = NULL;
7 7
 	state->OutOfMemory = NULL;
@@ -27,17 +27,30 @@ int sol_state_init(sol_state_t *state) {
27 27
 	state->NullOps.band = sol_f_not_impl;
28 28
 	state->NullOps.bor = sol_f_not_impl;
29 29
 	state->NullOps.bxor = sol_f_not_impl;
30
+	state->NullOps.blsh = sol_f_not_impl;
31
+	state->NullOps.brsh = sol_f_not_impl;
30 32
 	state->NullOps.bnot = sol_f_not_impl;
31 33
 	state->NullOps.cmp = sol_f_default_cmp;
32 34
 	state->NullOps.call = sol_f_not_impl;
33 35
 	state->NullOps.index = sol_f_not_impl;
34 36
 	state->NullOps.setindex = sol_f_not_impl;
35 37
 	state->NullOps.len = sol_f_not_impl;
38
+	state->NullOps.iter = sol_f_not_impl;
36 39
 	state->NullOps.toint = sol_f_not_impl;
37 40
 	state->NullOps.tofloat = sol_f_not_impl;
38 41
 	state->NullOps.tostring = sol_f_not_impl;
39 42
 	state->NullOps.init = sol_f_no_op;
40 43
 	state->NullOps.free = sol_f_no_op;
44
+	
45
+	state->IntOps = state->NullOps;
46
+	state->FloatOps = state->NullOps;
47
+	state->StringOps = state->NullOps;
48
+	state->ListOps = state->NullOps;
49
+	state->LCellOps = state->NullOps;
50
+	state->MapOps = state->NullOps;
51
+	state->MCellOps = state->NullOps;
52
+	state->FuncOps = state->NullOps;
53
+	state->CFuncOps = state->NullOps;
41 54
 
42 55
 	state->IntOps.add = sol_f_int_add;
43 56
 	state->IntOps.sub = sol_f_int_sub;
@@ -46,148 +59,102 @@ int sol_state_init(sol_state_t *state) {
46 59
 	state->IntOps.band = sol_f_int_band;
47 60
 	state->IntOps.bor = sol_f_int_bor;
48 61
 	state->IntOps.bxor = sol_f_int_bxor;
62
+	state->IntOps.blsh = sol_f_int_blsh;
63
+	state->IntOps.brsh = sol_f_int_brsh;
49 64
 	state->IntOps.bnot = sol_f_int_bnot;
50 65
 	state->IntOps.cmp = sol_f_int_cmp;
51
-	state->IntOps.call = sol_f_not_impl;
52
-	state->IntOps.index = sol_f_not_impl;
53
-	state->IntOps.setindex = sol_f_not_impl;
54
-	state->IntOps.len = sol_f_not_impl;
55 66
 	state->IntOps.toint = sol_f_int_toint;
56 67
 	state->IntOps.tofloat = sol_f_int_tofloat;
57 68
 	state->IntOps.tostring = sol_f_int_tostring;
58
-	state->IntOps.init = sol_f_no_op;
59
-	state->IntOps.free = sol_f_no_op;
60 69
 
61 70
 	state->FloatOps.add = sol_f_float_add;
62 71
 	state->FloatOps.sub = sol_f_float_sub;
63 72
 	state->FloatOps.mul = sol_f_float_mul;
64 73
 	state->FloatOps.div = sol_f_float_div;
65
-	state->FloatOps.band = sol_f_not_impl;
66
-	state->FloatOps.bor = sol_f_not_impl;
67
-	state->FloatOps.bxor = sol_f_not_impl;
68
-	state->FloatOps.bnot = sol_f_not_impl;
69 74
 	state->FloatOps.cmp = sol_f_float_cmp;
70
-	state->FloatOps.call = sol_f_not_impl;
71
-	state->FloatOps.index = sol_f_not_impl;
72
-	state->FloatOps.setindex = sol_f_not_impl;
73
-	state->FloatOps.len = sol_f_not_impl;
74 75
 	state->FloatOps.toint = sol_f_float_toint;
75 76
 	state->FloatOps.tofloat = sol_f_float_tofloat;
76 77
 	state->FloatOps.tostring = sol_f_float_tostring;
77
-	state->FloatOps.init = sol_f_no_op;
78
-	state->FloatOps.free = sol_f_no_op;
79 78
 
80 79
 	state->StringOps.add = sol_f_str_add;
81
-	state->StringOps.sub = sol_f_not_impl;
82 80
 	state->StringOps.mul = sol_f_str_mul;
83
-	state->StringOps.div = sol_f_not_impl;
84
-	state->StringOps.band = sol_f_not_impl;
85
-	state->StringOps.bor = sol_f_not_impl;
86
-	state->StringOps.bxor = sol_f_not_impl;
87
-	state->StringOps.bnot = sol_f_not_impl;
88 81
 	state->StringOps.cmp = sol_f_str_cmp;
89
-	state->StringOps.call = sol_f_not_impl;
90
-	state->StringOps.index = sol_f_not_impl;
91
-	state->StringOps.setindex = sol_f_not_impl;
92 82
 	state->StringOps.len = sol_f_str_len;
83
+	state->StringOps.iter = sol_f_str_iter;
93 84
 	state->StringOps.toint = sol_f_str_toint;
94 85
 	state->StringOps.tofloat = sol_f_str_tofloat;
95 86
 	state->StringOps.tostring = sol_f_str_tostring;
96
-	state->StringOps.init = sol_f_no_op;
97 87
 	state->StringOps.free = sol_f_str_free;
98 88
 
99 89
 	state->ListOps.add = sol_f_list_add;
100
-	state->ListOps.sub = sol_f_not_impl;
101 90
 	state->ListOps.mul = sol_f_list_mul;
102
-	state->ListOps.div = sol_f_not_impl;
103
-	state->ListOps.band = sol_f_not_impl;
104
-	state->ListOps.bor = sol_f_not_impl;
105
-	state->ListOps.bxor = sol_f_not_impl;
106
-	state->ListOps.bnot = sol_f_not_impl;
107
-	state->ListOps.cmp = sol_f_default_cmp;
108 91
 	state->ListOps.call = sol_f_not_impl;
109 92
 	state->ListOps.index = sol_f_list_index;
110 93
 	state->ListOps.setindex = sol_f_list_setindex;
111 94
 	state->ListOps.len = sol_f_list_len;
112
-	state->ListOps.toint = sol_f_not_impl;
113
-	state->ListOps.tofloat = sol_f_not_impl;
95
+	state->ListOps.iter = sol_f_list_iter;
114 96
 	state->ListOps.tostring = sol_f_list_tostring;
115
-	state->ListOps.init = sol_f_no_op;
116 97
 	state->ListOps.free = sol_f_list_free;
98
+	
99
+	state->LCellOps = state->ListOps;
100
+	state->LCellOps.free = sol_f_lcell_free;
117 101
 
118 102
 	state->MapOps.add = sol_f_map_add;
119
-	state->MapOps.sub = sol_f_not_impl;
120
-	state->MapOps.mul = sol_f_not_impl;
121
-	state->MapOps.div = sol_f_not_impl;
122
-	state->MapOps.band = sol_f_not_impl;
123
-	state->MapOps.bor = sol_f_not_impl;
124
-	state->MapOps.bxor = sol_f_not_impl;
125
-	state->MapOps.bnot = sol_f_not_impl;
126
-	state->MapOps.cmp = sol_f_default_cmp;
127
-	state->MapOps.call = sol_f_not_impl;
103
+	state->MapOps.call = sol_f_map_call;
128 104
 	state->MapOps.index = sol_f_map_index;
129 105
 	state->MapOps.setindex = sol_f_map_setindex;
130 106
 	state->MapOps.len = sol_f_map_len;
131
-	state->MapOps.toint = sol_f_not_impl;
132
-	state->MapOps.tofloat = sol_f_not_impl;
107
+	state->MapOps.iter = sol_f_map_iter;
133 108
 	state->MapOps.tostring = sol_f_map_tostring;
134
-	state->MapOps.init = sol_f_no_op;
135 109
 	state->MapOps.free = sol_f_map_free;
110
+	
111
+	state->MCellOps = state->MapOps;
112
+	state->MCellOps.free = sol_f_mcell_free;
136 113
 
137
-	state->FuncOps.add = sol_f_not_impl;
138
-	state->FuncOps.sub = sol_f_not_impl;
139
-	state->FuncOps.mul = sol_f_not_impl;
140
-	state->FuncOps.div = sol_f_not_impl;
141
-	state->FuncOps.band = sol_f_not_impl;
142
-	state->FuncOps.bor = sol_f_not_impl;
143
-	state->FuncOps.bxor = sol_f_not_impl;
144
-	state->FuncOps.bnot = sol_f_not_impl;
145
-	state->FuncOps.cmp = sol_f_default_cmp;
146 114
 	state->FuncOps.call = sol_f_func_call;
147
-	state->FuncOps.index = sol_f_not_impl;
148
-	state->FuncOps.setindex = sol_f_not_impl;
149
-	state->FuncOps.len = sol_f_not_impl;
150
-	state->FuncOps.toint = sol_f_not_impl;
151
-	state->FuncOps.tofloat = sol_f_not_impl;
115
+	state->FuncOps.index = sol_f_func_index;
116
+	state->FuncOps.setindex = sol_f_func_setindex;
152 117
 	state->FuncOps.tostring = sol_f_func_tostring;
153
-	state->FuncOps.init = sol_f_no_op;
154
-	state->FuncOps.free = sol_f_no_op;
155
-
156
-	state->CFuncOps.add = sol_f_not_impl;
157
-	state->CFuncOps.sub = sol_f_not_impl;
158
-	state->CFuncOps.mul = sol_f_not_impl;
159
-	state->CFuncOps.div = sol_f_not_impl;
160
-	state->CFuncOps.band = sol_f_not_impl;
161
-	state->CFuncOps.bor = sol_f_not_impl;
162
-	state->CFuncOps.bxor = sol_f_not_impl;
163
-	state->CFuncOps.bnot = sol_f_not_impl;
164
-	state->CFuncOps.cmp = sol_f_default_cmp;
118
+
165 119
 	state->CFuncOps.call = sol_f_cfunc_call;
166
-	state->CFuncOps.index = sol_f_not_impl;
167
-	state->CFuncOps.setindex = sol_f_not_impl;
168
-	state->CFuncOps.len = sol_f_not_impl;
169
-	state->CFuncOps.toint = sol_f_not_impl;
170
-	state->CFuncOps.tofloat = sol_f_not_impl;
171 120
 	state->CFuncOps.tostring = sol_f_cfunc_tostring;
172
-	state->CFuncOps.init = sol_f_no_op;
173
-	state->CFuncOps.free = sol_f_no_op;
174 121
 
175 122
 	state->error = state->None;
176 123
 	state->scopes = sol_new_list(state);
177 124
 	if(sol_has_error(state)) goto cleanup;
178 125
 	globals = sol_new_map(state);
126
+	debug = sol_new_map(state);
127
+	iter = sol_new_map(state);
179 128
 	if(sol_has_error(state)) goto cleanup;
180
-	sol_list_insert(state, &(state->scopes), 0, globals);
129
+	sol_list_insert(state, state->scopes, 0, globals);
181 130
 	if(sol_has_error(state)) goto cleanup;
182 131
 	// I'm going to buffer all of these together because I can.
183
-	sol_map_set(state, globals, sol_new_string(state, "OutOfMemory"), state->OutOfMemory);
184
-	sol_map_set(state, globals, sol_new_string(state, "StopIteration"), state->StopIteration);
185
-	sol_map_set(state, globals, sol_new_string(state, "toint"), sol_new_cfunc(state, sol_f_toint));
186
-	sol_map_set(state, globals, sol_new_string(state, "tofloat"), sol_new_cfunc(state, sol_f_tofloat));
187
-	sol_map_set(state, globals, sol_new_string(state, "tostring"), sol_new_cfunc(state, sol_f_tostring));
188
-	sol_map_set(state, globals, sol_new_string(state, "try"), sol_new_cfunc(state, sol_f_try));
189
-	sol_map_set(state, globals, sol_new_string(state, "type"), sol_new_cfunc(state, sol_f_type));
190
-	sol_map_set(state, globals, sol_new_string(state, "prepr"), sol_new_cfunc(state, sol_f_prepr));
132
+	sol_map_set_name(state, globals, "OutOfMemory", state->OutOfMemory);
133
+	sol_map_set_name(state, globals, "StopIteration", state->StopIteration);
134
+	sol_map_set_name(state, globals, "toint", sol_new_cfunc(state, sol_f_toint));
135
+	sol_map_set_name(state, globals, "tofloat", sol_new_cfunc(state, sol_f_tofloat));
136
+	sol_map_set_name(state, globals, "tostring", sol_new_cfunc(state, sol_f_tostring));
137
+	sol_map_set_name(state, globals, "try", sol_new_cfunc(state, sol_f_try));
138
+	sol_map_set_name(state, globals, "type", sol_new_cfunc(state, sol_f_type));
139
+	sol_map_set_name(state, globals, "prepr", sol_new_cfunc(state, sol_f_prepr));
140
+	sol_map_set_name(state, globals, "print", sol_new_cfunc(state, sol_f_print));
141
+	sol_map_set_name(state, globals, "rawget", sol_new_cfunc(state, sol_f_rawget));
142
+	sol_map_set_name(state, globals, "rawset", sol_new_cfunc(state, sol_f_rawset));
143
+	sol_map_set_name(state, globals, "range", sol_new_cfunc(state, sol_f_range));
144
+	
145
+	sol_map_set_name(state, debug, "getref", sol_new_cfunc(state, sol_f_debug_getref));
146
+	sol_map_set_name(state, debug, "setref", sol_new_cfunc(state, sol_f_debug_setref));
147
+	sol_map_set_name(state, debug, "closure", sol_new_cfunc(state, sol_f_debug_closure));
148
+	sol_map_set_name(state, debug, "globals", sol_new_cfunc(state, sol_f_debug_globals));
149
+	sol_map_set_name(state, debug, "locals", sol_new_cfunc(state, sol_f_debug_locals));
150
+	sol_map_set_name(state, globals, "debug", debug);
151
+	sol_obj_free(debug);
152
+	
153
+	sol_map_set_name(state, iter, "str", sol_new_cfunc(state, sol_f_iter_str));
154
+	sol_map_set_name(state, iter, "list", sol_new_cfunc(state, sol_f_iter_list));
155
+	sol_map_set_name(state, iter, "map", sol_new_cfunc(state, sol_f_iter_map));
156
+	sol_map_set_name(state, globals, "iter", iter);
157
+	sol_obj_free(iter);
191 158
 	if(sol_has_error(state)) goto cleanup;
192 159
 
193 160
 	// We're all set!
@@ -224,7 +191,7 @@ sol_object_t *sol_state_resolve_name(sol_state_t *state, const char *name) {
224 191
 }
225 192
 
226 193
 void sol_state_assign(sol_state_t *state, sol_object_t *key, sol_object_t *val) {
227
-	sol_object_t *cur = state->scopes, *next;
194
+	sol_object_t *cur = state->scopes, *next, *active = NULL;
228 195
 
229 196
 	if(!cur) {
230 197
 		sol_set_error_string(state, "Global state does not exist");
@@ -234,10 +201,16 @@ void sol_state_assign(sol_state_t *state, sol_object_t *key, sol_object_t *val)
234 201
 	next = cur->lnext;
235 202
 	while(next) {
236 203
 		cur = next;
204
+		if(cur->lvalue) active = cur;
237 205
 		next = cur->lnext;
238 206
 	}
207
+	
208
+	if(!active) {
209
+		sol_set_error_string(state, "No scopes exist");
210
+		return;
211
+	}
239 212
 
240
-	sol_map_set(state, cur->lvalue, key, val);
213
+	sol_map_set(state, active->lvalue, key, val);
241 214
 }
242 215
 
243 216
 void sol_state_assign_name(sol_state_t *state, const char *name, sol_object_t *val) {
@@ -251,6 +224,8 @@ void sol_state_assign_name(sol_state_t *state, const char *name, sol_object_t *v
251 224
 
252 225
 void sol_state_assign_l(sol_state_t *state, sol_object_t *key, sol_object_t *val) {
253 226
 	sol_object_t *cur = state->scopes;
227
+	
228
+	while(cur && !cur->lvalue) cur = cur->lnext;
254 229
 
255 230
 	if(!cur) {
256 231
 		sol_set_error_string(state, "Local state does not exist");

+ 20
- 5
test.sol View File

@@ -5,14 +5,16 @@ while a < 10 do
5 5
 end
6 6
 
7 7
 func mul9(b)
8
-	for i in range(len(b)) do
8
+	for i in range(#b) do
9 9
 		b[i] *= 9
10 10
 	end
11 11
 end
12 12
 
13 13
 l = [1 2 3 4 5]
14 14
 mul9(l)
15
-for i in iter(l) do print(i) end
15
+for i in l do print(i) end
16
+
17
+PI = 3.14159265358979
16 18
 
17 19
 d = {
18 20
 	integer = 1
@@ -22,10 +24,23 @@ d = {
22 24
 		health = 42.0
23 25
 	}
24 26
 	sublist = [1 1 2 3 5 8],
25
-	["this time with spaces"] = 2*PI,
27
+	["this time with spaces"] = PI*2,
26 28
 	[1 + 5] = 1 + 5
27 29
 }
28 30
 
29
-d["integer"]
30
-d.integer
31
+print(d)
32
+
33
+func bad(x)
34
+	x.c()
35
+end
36
+
37
+test1 = {c = func() end}
38
+test2 = {}
39
+
40
+print(try(bad, test1))
41
+print(try(bad, test2))
42
+
43
+print(d["integer"])
44
+print(d.integer)
31 45
 d.integer += 5
46
+print(d.integer)

+ 4
- 0
tokenizer.lex View File

@@ -142,6 +142,10 @@ None { return NONE; }
142 142
 
143 143
 ">=" { return GREATEREQ; }
144 144
 
145
+">>" { return RSHIFT; }
146
+
147
+"<<" { return LSHIFT; }
148
+
145 149
 "{" { return LBRACE; }
146 150
 
147 151
 "}" { return RBRACE; }

Loading…
Cancel
Save