Просмотр исходного кода

Sol Part 34: When Life Gives You Language, Make Solade!

(should fix #4 )
Graham Northup 5 лет назад
Родитель
Сommit
1073d60787
8 измененных файлов: 185 добавлений и 89 удалений
  1. 2
    2
      .gitignore
  2. 9
    0
      ast.h
  3. 1
    1
      build.sh
  4. 38
    29
      builtins.c
  5. 10
    4
      object.c
  6. 50
    26
      runtime.c
  7. 22
    0
      sol.h
  8. 53
    27
      state.c

+ 2
- 2
.gitignore Просмотреть файл

@@ -3,7 +3,7 @@ sol
3 3
 stdout
4 4
 .submodule_stamp
5 5
 *.orig
6
-*.swp
7
-*.swo
6
+*.sw?
8 7
 gclog.txt
9 8
 gcstat.txt
9
+iss*

+ 9
- 0
ast.h Просмотреть файл

@@ -184,6 +184,15 @@ typedef struct tag_stmt_node {
184 184
 	nd->binop->left->index->index = idx; \
185 185
 	nd->binop->right = val
186 186
 #define BOOL_TO_INT(cond) ((cond)?1:0)
187
+#define CALL_METHOD(state, obj, meth, args) ({\
188
+		sol_object_t *res;\
189
+		state->calling_type = obj->ops->tname;\
190
+		state->calling_meth = #meth;\
191
+		res = obj->ops->meth(state, args);\
192
+		state->calling_type = "(none)";\
193
+		state->calling_meth = "(none)";\
194
+		res;\
195
+})
187 196
 
188 197
 sol_object_t *sol_new_func(sol_state_t *, identlist_node *, stmt_node *, char *);
189 198
 sol_object_t *sol_new_stmtnode(sol_state_t *, stmt_node *);

+ 1
- 1
build.sh Просмотреть файл

@@ -4,7 +4,7 @@ if [ ! -f .submodule_stamp ]; then
4 4
 fi
5 5
 
6 6
 if [ -z "$CFLAGS" ]; then
7
-    CFLAGS="-g"
7
+    CFLAGS="-g -DDEBUG_GC"
8 8
 fi
9 9
 
10 10
 gcc -c $CFLAGS dsl/seq.c

+ 38
- 29
builtins.c Просмотреть файл

@@ -26,7 +26,9 @@ static char *_ftoa(double f) {
26 26
 }
27 27
 
28 28
 sol_object_t *sol_f_not_impl(sol_state_t *state, sol_object_t *args) {
29
-	return sol_set_error_string(state, "Undefined method");
29
+	char buffer[64];
30
+	snprintf(buffer, 64, "Undefined method (%s on %s)", state->calling_meth, state->calling_type);
31
+	return sol_set_error_string(state, buffer);
30 32
 }
31 33
 
32 34
 sol_object_t *sol_f_default_cmp(sol_state_t *state, sol_object_t *args) {
@@ -46,7 +48,7 @@ sol_object_t *sol_f_default_tostring(sol_state_t *state, sol_object_t *args) {
46 48
 }
47 49
 
48 50
 sol_object_t *sol_f_default_repr(sol_state_t *state, sol_object_t *args) {
49
-	sol_object_t *obj = sol_list_get_index(state, args, 0), *res = obj->ops->tostring(state, args);
51
+	sol_object_t *obj = sol_list_get_index(state, args, 0), *res = CALL_METHOD(state, obj, tostring, args);
50 52
 	sol_obj_free(obj);
51 53
 	return res;
52 54
 }
@@ -60,21 +62,21 @@ sol_object_t *sol_f_no_op(sol_state_t *state, sol_object_t *args) {
60 62
 
61 63
 sol_object_t *sol_f_toint(sol_state_t *state, sol_object_t *args) {
62 64
 	sol_object_t *obj = sol_list_get_index(state, args, 0);
63
-	sol_object_t *res = obj->ops->toint(state, args);
65
+	sol_object_t *res = CALL_METHOD(state, obj, toint, args);
64 66
 	sol_obj_free(obj);
65 67
 	return res;
66 68
 }
67 69
 
68 70
 sol_object_t *sol_f_tofloat(sol_state_t *state, sol_object_t *args) {
69 71
 	sol_object_t *obj = sol_list_get_index(state, args, 0);
70
-	sol_object_t *res = obj->ops->tofloat(state, args);
72
+	sol_object_t *res = CALL_METHOD(state, obj, tofloat, args);
71 73
 	sol_obj_free(obj);
72 74
 	return res;
73 75
 }
74 76
 
75 77
 sol_object_t *sol_f_tostring(sol_state_t *state, sol_object_t *args) {
76 78
 	sol_object_t *obj = sol_list_get_index(state, args, 0);
77
-	sol_object_t *res = obj->ops->tostring(state, args);
79
+	sol_object_t *res = CALL_METHOD(state, obj, tostring, args);
78 80
 	sol_obj_free(obj);
79 81
 	return res;
80 82
 }
@@ -84,7 +86,7 @@ sol_object_t *sol_f_try(sol_state_t *state, sol_object_t *args) {
84 86
 	sol_object_t *ls = sol_new_list(state), *one = sol_new_int(state, 1);
85 87
 	sol_object_t *res;
86 88
 	sol_list_insert(state, fargs, 0, func);
87
-	res = func->ops->call(state, fargs);
89
+	res = CALL_METHOD(state, func, call, fargs);
88 90
 	sol_obj_free(func);
89 91
 	sol_obj_free(fargs);
90 92
 	if(sol_has_error(state)) {
@@ -452,24 +454,31 @@ sol_object_t *sol_f_debug_scopes(sol_state_t *state, sol_object_t *args) {
452 454
 	return sol_incref(state->scopes);
453 455
 }
454 456
 
457
+void _sol_freef_seq_iter(void *iter, size_t sz) {
458
+	dsl_free_seq_iter((dsl_seq_iter *) iter);
459
+}
460
+
455 461
 sol_object_t *sol_f_iter_str(sol_state_t *state, sol_object_t *args) {
456 462
 	sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
457
-	sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
463
+	sol_object_t *index = sol_map_get_name(state, local, "idx"), *max = sol_map_get_name(state, local, "sz"), *res;
458 464
 	char temp[2] = {0, 0};
459
-	if(sol_is_none(state, index)) {
465
+	if(sol_is_none(state, index) || sol_is_none(state, max)) {
460 466
 		sol_obj_free(index);
461
-		index = sol_new_int(state, 0);
467
+		index = sol_new_buffer(state, (void *) 0, sizeof(void *), OWN_NONE, NULL, NULL);
462 468
 		sol_map_set_name(state, local, "idx", index);
469
+		sol_obj_free(max);
470
+		max = sol_new_int(state, strlen(obj->str));
471
+		sol_map_set_name(state, local, "sz", max);
463 472
 	}
464
-	if(index->ival >= strlen(obj->str)) {
473
+	if(((size_t) index->buffer) >= max->ival) {
465 474
 		sol_obj_free(index);
466 475
 		sol_obj_free(obj);
467 476
 		sol_obj_free(local);
468 477
 		return sol_incref(state->StopIteration);
469 478
 	}
470
-	temp[0] = obj->str[index->ival];
479
+	temp[0] = obj->str[((size_t) index->buffer)];
471 480
 	res = sol_new_string(state, temp);
472
-	index->ival++;
481
+	index->buffer = (void *) ((size_t) index->buffer + 1);
473 482
 	sol_obj_free(index);
474 483
 	sol_obj_free(local);
475 484
 	sol_obj_free(obj);
@@ -481,18 +490,18 @@ sol_object_t *sol_f_iter_list(sol_state_t *state, sol_object_t *args) {
481 490
 	sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
482 491
 	if(sol_is_none(state, index)) {
483 492
 		sol_obj_free(index);
484
-		index = sol_new_int(state, 0);
493
+		index = sol_new_buffer(state, dsl_new_seq_iter(obj->seq), sizeof(dsl_seq_iter), OWN_CALLF, _sol_freef_seq_iter, NULL);
485 494
 		sol_map_set_name(state, local, "idx", index);
486 495
 		sol_obj_free(index);
487 496
 	}
488
-	if(index->ival >= sol_list_len(state, obj)) {
497
+	if(dsl_seq_iter_is_invalid(index->buffer)) {
489 498
 		sol_obj_free(index);
490 499
 		sol_obj_free(obj);
491 500
 		sol_obj_free(local);
492 501
 		return sol_incref(state->StopIteration);
493 502
 	}
494
-	res = sol_list_get_index(state, obj, index->ival);
495
-	index->ival++;
503
+	res = sol_incref(AS_OBJ(dsl_seq_iter_at(index->buffer)));
504
+	dsl_seq_iter_next(index->buffer);
496 505
 	sol_obj_free(local);
497 506
 	sol_obj_free(obj);
498 507
 	return res;
@@ -503,18 +512,18 @@ sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) {
503 512
 	sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
504 513
 	if(sol_is_none(state, index)) {
505 514
 		sol_obj_free(index);
506
-		index = sol_new_int(state, 0);
515
+		index = sol_new_buffer(state, dsl_new_seq_iter(obj->seq), sizeof(dsl_seq_iter), OWN_CALLF, _sol_freef_seq_iter, NULL);
507 516
 		sol_map_set_name(state, local, "idx", index);
508 517
 		sol_obj_free(index);
509 518
 	}
510
-	if(index->ival >= dsl_seq_len(obj->seq)) {
519
+	if(dsl_seq_iter_is_invalid(index->buffer)) {
511 520
 		sol_obj_free(index);
512 521
 		sol_obj_free(obj);
513 522
 		sol_obj_free(local);
514 523
 		return sol_incref(state->StopIteration);
515 524
 	}
516
-	res = sol_incref(AS_OBJ(dsl_seq_get(obj->seq, index->ival))->key);
517
-	index->ival++;
525
+	res = sol_incref(AS_OBJ(dsl_seq_iter_at(index->buffer))->key);
526
+	dsl_seq_iter_next(index->buffer);
518 527
 	sol_obj_free(local);
519 528
 	sol_obj_free(obj);
520 529
 	return res;
@@ -1127,7 +1136,7 @@ sol_object_t *sol_f_list_map(sol_state_t *state, sol_object_t *args) {
1127 1136
 		item = sol_list_get_index(state, list, idx);
1128 1137
 		sol_list_insert(state, fargs, 1, item);
1129 1138
 		sol_obj_free(item);
1130
-		item = func->ops->call(state, fargs);
1139
+		item = CALL_METHOD(state, func, call, fargs);
1131 1140
 		if(sol_has_error(state)) {
1132 1141
 			return list;
1133 1142
 		}
@@ -1150,7 +1159,7 @@ sol_object_t *sol_f_list_filter(sol_state_t *state, sol_object_t *args) {
1150 1159
 		item = sol_list_get_index(state, list, idx);
1151 1160
 		sol_list_insert(state, fargs, 1, item);
1152 1161
 		sol_obj_free(item);
1153
-		item = func->ops->call(state, fargs);
1162
+		item = CALL_METHOD(state, func, call, fargs);
1154 1163
 		if(sol_has_error(state)) {
1155 1164
 			return list;
1156 1165
 		}
@@ -1195,13 +1204,13 @@ sol_object_t *sol_f_map_index(sol_state_t *state, sol_object_t *args) {
1195 1204
 				newls = sol_new_list(state);
1196 1205
 				sol_list_insert(state, newls, 0, indexf);
1197 1206
 				sol_list_append(state, newls, args);
1198
-				res = indexf->ops->call(state, newls);
1207
+				res = CALL_METHOD(state, indexf, call, newls);
1199 1208
 				sol_obj_free(newls);
1200 1209
 			} else if(indexf->ops->index && indexf->ops->index != sol_f_not_impl) {
1201 1210
 				newls = sol_new_list(state);
1202 1211
 				sol_list_insert(state, newls, 0, indexf);
1203 1212
 				sol_list_insert(state, newls, 1, b);
1204
-				res = indexf->ops->index(state, newls);
1213
+				res = CALL_METHOD(state, indexf, index, newls);
1205 1214
 				sol_obj_free(newls);
1206 1215
 			}
1207 1216
 		}
@@ -1221,7 +1230,7 @@ sol_object_t *sol_f_map_setindex(sol_state_t *state, sol_object_t *args) {
1221 1230
 			newls = sol_new_list(state);
1222 1231
 			sol_list_insert(state, newls, 0, setindexf);
1223 1232
 			sol_list_append(state, newls, args);
1224
-			sol_obj_free(setindexf->ops->call(state, newls));
1233
+			sol_obj_free(CALL_METHOD(state, setindexf, call, newls));
1225 1234
 			sol_obj_free(newls);
1226 1235
 			return sol_incref(state->None);
1227 1236
 		} else if(setindexf->ops->setindex && setindexf->ops->setindex != sol_f_not_impl) {
@@ -1229,7 +1238,7 @@ sol_object_t *sol_f_map_setindex(sol_state_t *state, sol_object_t *args) {
1229 1238
 			sol_list_insert(state, newls, 0, setindexf);
1230 1239
 			sol_list_insert(state, newls, 1, b);
1231 1240
 			sol_list_insert(state, newls, 2, val);
1232
-			sol_obj_free(setindexf->ops->index(state, newls));
1241
+			sol_obj_free(CALL_METHOD(state, setindexf, index, newls));
1233 1242
 			sol_obj_free(newls);
1234 1243
 			return sol_incref(state->None);
1235 1244
 		}
@@ -1249,7 +1258,7 @@ sol_object_t *sol_f_map_call(sol_state_t *state, sol_object_t *args) {
1249 1258
 		if(callf->ops->call) {
1250 1259
 			sol_list_insert(state, fargs, 0, callf);
1251 1260
 			sol_list_insert(state, fargs, 1, map);
1252
-			res = callf->ops->call(state, fargs);
1261
+			res = CALL_METHOD(state,  callf, call, fargs);
1253 1262
 		}
1254 1263
 	}
1255 1264
 	sol_obj_free(map);
@@ -1279,7 +1288,7 @@ sol_object_t *sol_f_map_tostring(sol_state_t *state, sol_object_t *args) {
1279 1288
 		fargs = sol_new_list(state);
1280 1289
 		sol_list_insert(state, fargs, 0, tostrf);
1281 1290
 		sol_list_insert(state, fargs, 1, map);
1282
-		res = tostrf->ops->call(state, fargs);
1291
+		res = CALL_METHOD(state, tostrf, call, fargs);
1283 1292
 		sol_obj_free(fargs);
1284 1293
 	} else {
1285 1294
 		res = sol_cast_repr(state, map);
@@ -1298,7 +1307,7 @@ sol_object_t *sol_f_map_repr(sol_state_t *state, sol_object_t *args) {
1298 1307
 		fargs = sol_new_list(state);
1299 1308
 		sol_list_insert(state, fargs, 0, reprf);
1300 1309
 		sol_list_insert(state, fargs, 1, obj);
1301
-		cur = reprf->ops->call(state, fargs);
1310
+		cur = CALL_METHOD(state, reprf, call, fargs);
1302 1311
 		sol_obj_free(fargs);
1303 1312
 		sol_obj_free(obj);
1304 1313
 		sol_obj_free(reprf);

+ 10
- 4
object.c Просмотреть файл

@@ -1,4 +1,4 @@
1
-#include "sol.h"
1
+#include "ast.h"  // For CALL_METHOD
2 2
 
3 3
 #include <stdlib.h>
4 4
 #include <string.h>
@@ -73,7 +73,13 @@ void sol_init_object(sol_state_t *state, sol_object_t *obj) {
73 73
 }
74 74
 
75 75
 sol_object_t *sol_new_int(sol_state_t *state, long i) {
76
-	sol_object_t *res = sol_alloc_object(state);
76
+	sol_object_t *res;
77
+#ifdef SOL_ICACHE
78
+	if(!state->icache_bypass && i >= SOL_ICACHE_MIN && i <= SOL_ICACHE_MAX) {
79
+		return sol_incref(state->icache[i - SOL_ICACHE_MIN]);
80
+	}
81
+#endif
82
+	res = sol_alloc_object(state);
77 83
 	res->type = SOL_INTEGER;
78 84
 	res->ival = i;
79 85
 	res->ops = &(state->IntOps);
@@ -311,7 +317,7 @@ sol_object_t *sol_map_mcell(sol_state_t *state, sol_object_t *map, sol_object_t
311 317
 	sol_list_insert(state, list, 1, state->None);
312 318
 	if(!dsl_seq_iter_is_invalid(iter)) do {
313 319
 			sol_list_set_index(state, list, 1, AS_OBJ(dsl_seq_iter_at(iter))->key);
314
-			cmp = key->ops->cmp(state, list);
320
+			cmp = CALL_METHOD(state, key, cmp, list);
315 321
 			icmp = sol_cast_int(state, cmp);
316 322
 			sol_obj_free(cmp);
317 323
 			if(icmp->ival == 0) {
@@ -488,7 +494,7 @@ sol_object_t *sol_f_buffer_free(sol_state_t *state, sol_object_t *buf) {
488 494
 			break;
489 495
 
490 496
 		case OWN_CALLF:
491
-			buf->freef(buf->buffer, buf->sz);
497
+			if(buf->freef) buf->freef(buf->buffer, buf->sz);
492 498
 			break;
493 499
 	}
494 500
 	return buf;

+ 50
- 26
runtime.c Просмотреть файл

@@ -247,39 +247,39 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
247 247
 			sol_list_insert(state, list, 1, right);
248 248
 			switch(expr->binop->type) {
249 249
 				case OP_ADD:
250
-					res = left->ops->add(state, list);
250
+					res = CALL_METHOD(state, left, add, list);
251 251
 					break;
252 252
 
253 253
 				case OP_SUB:
254
-					res = left->ops->sub(state, list);
254
+					res = CALL_METHOD(state, left, sub, list);
255 255
 					break;
256 256
 
257 257
 				case OP_MUL:
258
-					res = left->ops->mul(state, list);
258
+					res = CALL_METHOD(state, left, mul, list);
259 259
 					break;
260 260
 
261 261
 				case OP_DIV:
262
-					res = left->ops->div(state, list);
262
+					res = CALL_METHOD(state, left, div, list);
263 263
 					break;
264 264
 
265 265
 				case OP_MOD:
266
-					res = left->ops->mod(state, list);
266
+					res = CALL_METHOD(state, left, mod, list);
267 267
 					break;
268 268
 
269 269
 				case OP_POW:
270
-					res = left->ops->pow(state, list);
270
+					res = CALL_METHOD(state, left, pow, list);
271 271
 					break;
272 272
 
273 273
 				case OP_BAND:
274
-					res = left->ops->band(state, list);
274
+					res = CALL_METHOD(state, left, band, list);
275 275
 					break;
276 276
 
277 277
 				case OP_BOR:
278
-					res = left->ops->bor(state, list);
278
+					res = CALL_METHOD(state, left, bor, list);
279 279
 					break;
280 280
 
281 281
 				case OP_BXOR:
282
-					res = left->ops->bxor(state, list);
282
+					res = CALL_METHOD(state, left, bxor, list);
283 283
 					break;
284 284
 
285 285
 				case OP_LAND:
@@ -303,35 +303,59 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
303 303
 					break;
304 304
 
305 305
 				case OP_EQUAL:
306
-					res = sol_new_int(state, BOOL_TO_INT(sol_cast_int(state, left->ops->cmp(state, list))->ival == 0));
306
+					value = CALL_METHOD(state, left, cmp, list);
307
+					lint = sol_cast_int(state, value);
308
+					res = sol_new_int(state, BOOL_TO_INT(lint->ival == 0));
309
+					sol_obj_free(lint);
310
+					sol_obj_free(value);
307 311
 					break;
308 312
 
309 313
 				case OP_NEQUAL:
310
-					res = sol_new_int(state, BOOL_TO_INT(sol_cast_int(state, left->ops->cmp(state, list))->ival != 0));
314
+					value = CALL_METHOD(state, left, cmp, list);
315
+					lint = sol_cast_int(state, value);
316
+					res = sol_new_int(state, BOOL_TO_INT(lint->ival != 0));
317
+					sol_obj_free(lint);
318
+					sol_obj_free(value);
311 319
 					break;
312 320
 
313 321
 				case OP_LESS:
314
-					res = sol_new_int(state, BOOL_TO_INT(sol_cast_int(state, left->ops->cmp(state, list))->ival < 0));
322
+					value = CALL_METHOD(state, left, cmp, list);
323
+					lint = sol_cast_int(state, value);
324
+					res = sol_new_int(state, BOOL_TO_INT(lint->ival < 0));
325
+					sol_obj_free(lint);
326
+					sol_obj_free(value);
315 327
 					break;
316 328
 
317 329
 				case OP_GREATER:
318
-					res = sol_new_int(state, BOOL_TO_INT(sol_cast_int(state, left->ops->cmp(state, list))->ival > 0));
330
+					value = CALL_METHOD(state, left, cmp, list);
331
+					lint = sol_cast_int(state, value);
332
+					res = sol_new_int(state, BOOL_TO_INT(lint->ival > 0));
333
+					sol_obj_free(lint);
334
+					sol_obj_free(value);
319 335
 					break;
320 336
 
321 337
 				case OP_LESSEQ:
322
-					res = sol_new_int(state, BOOL_TO_INT(sol_cast_int(state, left->ops->cmp(state, list))->ival <= 0));
338
+					value = CALL_METHOD(state, left, cmp, list);
339
+					lint = sol_cast_int(state, value);
340
+					res = sol_new_int(state, BOOL_TO_INT(lint->ival <= 0));
341
+					sol_obj_free(lint);
342
+					sol_obj_free(value);
323 343
 					break;
324 344
 
325 345
 				case OP_GREATEREQ:
326
-					res = sol_new_int(state, BOOL_TO_INT(sol_cast_int(state, left->ops->cmp(state, list))->ival >= 0));
346
+					value = CALL_METHOD(state, left, cmp, list);
347
+					lint = sol_cast_int(state, value);
348
+					res = sol_new_int(state, BOOL_TO_INT(lint->ival >= 0));
349
+					sol_obj_free(lint);
350
+					sol_obj_free(value);
327 351
 					break;
328 352
 
329 353
 				case OP_LSHIFT:
330
-					res = left->ops->blsh(state, list);
354
+					res = CALL_METHOD(state, left, blsh, list);
331 355
 					break;
332 356
 
333 357
 				case OP_RSHIFT:
334
-					res = left->ops->brsh(state, list);
358
+					res = CALL_METHOD(state, left, brsh, list);
335 359
 					break;
336 360
 			}
337 361
 			sol_obj_free(list);
@@ -351,12 +375,12 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
351 375
 				case OP_NEG:
352 376
 					right = sol_new_int(state, -1);
353 377
 					sol_list_insert(state, list, 1, right);
354
-					res = left->ops->mul(state, list);
378
+					res = CALL_METHOD(state, left, mul, list);
355 379
 					sol_obj_free(right);
356 380
 					break;
357 381
 
358 382
 				case OP_BNOT:
359
-					res = left->ops->bnot(state, list);
383
+					res = CALL_METHOD(state, left, bnot, list);
360 384
 					break;
361 385
 
362 386
 				case OP_LNOT:
@@ -367,7 +391,7 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
367 391
 					break;
368 392
 
369 393
 				case OP_LEN:
370
-					res = left->ops->len(state, list);
394
+					res = CALL_METHOD(state, left, len, list);
371 395
 					break;
372 396
 			}
373 397
 			sol_obj_free(left);
@@ -385,7 +409,7 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
385 409
 			ERR_CHECK(state);
386 410
 			sol_list_insert(state, list, 0, left);
387 411
 			sol_list_insert(state, list, 1, right);
388
-			res = left->ops->index(state, list);
412
+			res = CALL_METHOD(state, left, index, list);
389 413
 			sol_obj_free(left);
390 414
 			sol_obj_free(right);
391 415
 			sol_obj_free(list);
@@ -405,7 +429,7 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
405 429
 			sol_list_insert(state, list, 0, left);
406 430
 			sol_list_insert(state, list, 1, right);
407 431
 			sol_list_insert(state, list, 2, value);
408
-			res = left->ops->setindex(state, list);
432
+			res = CALL_METHOD(state, left, setindex, list);
409 433
 			sol_obj_free(left);
410 434
 			sol_obj_free(right);
411 435
 			sol_obj_free(value);
@@ -439,7 +463,7 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
439 463
 				ERR_CHECK(state);
440 464
 				cure = cure->next;
441 465
 			}
442
-			res = value->ops->call(state, list);
466
+			res = CALL_METHOD(state, value, call, list);
443 467
 			sol_obj_free(value);
444 468
 			sol_obj_free(list);
445 469
 			ERR_CHECK(state);
@@ -532,7 +556,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
532 556
 			if(value->ops->iter && value->ops->iter != sol_f_not_impl) {
533 557
 				list = sol_new_list(state);
534 558
 				sol_list_insert(state, list, 0, value);
535
-				iter = value->ops->iter(state, list);
559
+				iter = CALL_METHOD(state, value, iter, list);
536 560
 				sol_obj_free(list);
537 561
 			} else {
538 562
 				iter = value;
@@ -545,7 +569,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
545 569
 			sol_list_insert(state, list, 0, iter);
546 570
 			sol_list_insert(state, list, 1, value);
547 571
 			sol_list_insert(state, list, 2, sol_new_map(state));
548
-			item = iter->ops->call(state, list);
572
+			item = CALL_METHOD(state, iter, call, list);
549 573
 			while(item != state->StopIteration) {
550 574
 				sol_state_assign_l_name(state, stmt->iter->var, item);
551 575
 				sol_exec(state, stmt->iter->loop);
@@ -554,7 +578,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
554 578
 					item = sol_incref(state->StopIteration);
555 579
 				}
556 580
 				state->sflag = SF_NORMAL;
557
-				item = iter->ops->call(state, list);
581
+				item = CALL_METHOD(state, iter, call, list);
558 582
 			}
559 583
 			state->sflag = SF_NORMAL;
560 584
 			if(sol_has_error(state)) {

+ 22
- 0
sol.h Просмотреть файл

@@ -12,6 +12,18 @@
12 12
 #define VERSION "0.1a1"
13 13
 #define HEXVER 0x0001A01
14 14
 
15
+#ifndef SOL_ICACHE_MIN
16
+#define SOL_ICACHE_MIN -128
17
+#endif
18
+
19
+#ifndef SOL_ICACHE_MAX
20
+#define SOL_ICACHE_MAX 256
21
+#endif
22
+
23
+#if !defined(SOL_ICACHE) && (SOL_ICACHE_MIN < SOL_ICACHE_MAX)
24
+#define SOL_ICACHE
25
+#endif
26
+
15 27
 // Forward declarations:
16 28
 struct sol_tag_object_t;
17 29
 typedef struct sol_tag_object_t sol_object_t;
@@ -160,6 +172,9 @@ typedef struct sol_tag_state_t {
160 172
 	sol_object_t *traceback; // The last stack of statement (nodes) in the last error, or NULL
161 173
 	sol_state_flag_t sflag; // Used to implement break/continue
162 174
 	sol_object_t *error; // Some arbitrary error descriptor, None if no error
175
+	sol_object_t *stdout; // Standard output stream object (for print())
176
+	sol_object_t *stdin; // Standard input stream object
177
+	sol_object_t *stderr; // Standard error stream object
163 178
 	sol_object_t *None;
164 179
 	sol_object_t *OutOfMemory;
165 180
 	sol_object_t *StopIteration;
@@ -181,6 +196,12 @@ typedef struct sol_tag_state_t {
181 196
 	sol_object_t *modules;
182 197
 	sol_object_t *methods;
183 198
 	dsl_object_funcs obfuncs;
199
+	const char *calling_type;
200
+	const char *calling_meth;
201
+#ifdef SOL_ICACHE
202
+	sol_object_t *icache[SOL_ICACHE_MAX - SOL_ICACHE_MIN + 1];
203
+	char icache_bypass;
204
+#endif
184 205
 } sol_state_t;
185 206
 
186 207
 // state.c
@@ -216,6 +237,7 @@ void sol_register_methods_name(sol_state_t *, char *, sol_object_t *);
216 237
 sol_object_t *sol_get_methods(sol_state_t *, sol_object_t *);
217 238
 sol_object_t *sol_get_methods_name(sol_state_t *, char *);
218 239
 
240
+sol_object_t *sol_f_io_setindex(sol_state_t *, sol_object_t *);
219 241
 sol_object_t *sol_get_stdin(sol_state_t *);
220 242
 sol_object_t *sol_get_stdout(sol_state_t *);
221 243
 sol_object_t *sol_get_stderr(sol_state_t *);

+ 53
- 27
state.c Просмотреть файл

@@ -5,6 +5,7 @@
5 5
 int sol_state_init(sol_state_t *state) {
6 6
 	sol_object_t *globals, *mod, *meths;
7 7
 	sol_object_t *btype, *bsize, *bobj;
8
+	unsigned long i;
8 9
 
9 10
 	sol_mm_initialize(state);
10 11
 
@@ -171,6 +172,17 @@ int sol_state_init(sol_state_t *state) {
171 172
 	state->obfuncs.destr = (dsl_destructor) sol_obj_free;
172 173
 #endif
173 174
 
175
+#ifdef SOL_ICACHE
176
+	state->icache_bypass = 1;
177
+	for(i = 0; i <= (SOL_ICACHE_MAX - SOL_ICACHE_MIN); i++) {
178
+		state->icache[i] = sol_new_int(state, ((long) i) + SOL_ICACHE_MIN);
179
+	}
180
+	state->icache_bypass = 0;
181
+#endif
182
+
183
+	state->calling_type = "(none)";
184
+	state->calling_meth = "(none)";
185
+
174 186
 	state->error = state->None;
175 187
 	state->scopes = sol_new_list(state);
176 188
 	if(sol_has_error(state)) {
@@ -187,6 +199,11 @@ int sol_state_init(sol_state_t *state) {
187 199
 	if(sol_has_error(state)) {
188 200
 		goto cleanup;
189 201
 	}
202
+
203
+	state->stdin = sol_new_stream(state, stdin, MODE_READ);
204
+	state->stdout = sol_new_stream(state, stdout, MODE_WRITE);
205
+	state->stderr = sol_new_stream(state, stderr, MODE_WRITE);
206
+
190 207
 	// I'm going to buffer all of these together because I can.
191 208
 	sol_map_set_name(state, globals, "OutOfMemory", state->OutOfMemory);
192 209
 	sol_map_set_name(state, globals, "StopIteration", state->StopIteration);
@@ -217,6 +234,10 @@ int sol_state_init(sol_state_t *state) {
217 234
 	sol_map_set_name(state, mod, "scopes", sol_new_cfunc(state, sol_f_debug_scopes));
218 235
 	sol_map_set_name(state, mod, "version", sol_new_string(state, VERSION));
219 236
 	sol_map_set_name(state, mod, "hexversion", sol_new_int(state, HEXVER));
237
+#ifdef SOL_ICACHE
238
+	sol_map_set_name(state, mod, "icache_min", sol_new_int(state, SOL_ICACHE_MIN));
239
+	sol_map_set_name(state, mod, "icache_max", sol_new_int(state, SOL_ICACHE_MAX));
240
+#endif
220 241
 	sol_register_module_name(state, "debug", mod);
221 242
 	sol_obj_free(mod);
222 243
 
@@ -368,6 +389,7 @@ int sol_state_init(sol_state_t *state) {
368 389
 	sol_map_set_name(state, mod, "stdout", sol_new_stream(state, stdout, MODE_WRITE));
369 390
 	sol_map_set_name(state, mod, "stderr", sol_new_stream(state, stderr, MODE_WRITE));
370 391
 	sol_map_set_name(state, mod, "open", sol_new_cfunc(state, sol_f_stream_open));
392
+	sol_map_set_name(state, mod, "__setindex", sol_new_cfunc(state, sol_f_io_setindex));
371 393
 	sol_register_module_name(state, "io", mod);
372 394
 	sol_obj_free(mod);
373 395
 
@@ -442,7 +464,7 @@ sol_object_t *sol_state_resolve(sol_state_t *state, sol_object_t *key) {
442 464
 	sol_list_insert(state, args, 1, key);
443 465
 	while(!dsl_seq_iter_is_invalid(iter)) {
444 466
 		sol_list_set_index(state, args, 0, dsl_seq_iter_at(iter));
445
-		temp = ((sol_object_t *) dsl_seq_iter_at(iter))->ops->index(state, args);
467
+		temp = CALL_METHOD(state, ((sol_object_t *) dsl_seq_iter_at(iter)), index, args);
446 468
 		if(!sol_is_none(state, temp)) {
447 469
 			dsl_free_seq_iter(iter);
448 470
 			sol_obj_free(args);
@@ -494,7 +516,7 @@ void sol_state_assign(sol_state_t *state, sol_object_t *key, sol_object_t *val)
494 516
 	sol_list_insert(state, args, 0, active);
495 517
 	sol_list_insert(state, args, 1, key);
496 518
 	sol_list_insert(state, args, 2, val);
497
-	sol_obj_free(active->ops->setindex(state, args));
519
+	sol_obj_free(CALL_METHOD(state, active, setindex, args));
498 520
 	sol_obj_free(args);
499 521
 }
500 522
 
@@ -523,7 +545,7 @@ void sol_state_assign_l(sol_state_t *state, sol_object_t *key, sol_object_t *val
523 545
 	sol_list_insert(state, args, 0, cur);
524 546
 	sol_list_insert(state, args, 1, key);
525 547
 	sol_list_insert(state, args, 2, val);
526
-	sol_obj_free(cur->ops->setindex(state, args));
548
+	sol_obj_free(CALL_METHOD(state, cur, setindex, args));
527 549
 	sol_obj_free(args);
528 550
 }
529 551
 
@@ -631,37 +653,41 @@ sol_object_t *sol_get_methods_name(sol_state_t *state, char *name) {
631 653
 	return sol_map_get_name(state, state->methods, name);
632 654
 }
633 655
 
634
-sol_object_t *sol_get_stdin(sol_state_t *state) {
635
-	sol_object_t *io = sol_state_resolve_name(state, "io");
636
-	sol_object_t *res = sol_map_get_name(state, io, "stdin");
637
-	sol_obj_free(io);
638
-	if(sol_is_none(state, res)) {
639
-		printf("WARNING: No io.stdin, returning a new ref\n");
640
-		return sol_new_stream(state, stdin, MODE_READ);
656
+sol_object_t *sol_f_io_setindex(sol_state_t *state, sol_object_t *args) {
657
+	sol_object_t *name = sol_list_get_index(state, args, 1), *value = sol_list_get_index(state, args, 2);
658
+	sol_object_t *namestr = sol_cast_string(state, name), *io;
659
+	if(sol_string_eq(state, namestr, "stdin")) {
660
+		state->stdin = sol_incref(value);
661
+		goto done;
641 662
 	}
642
-	return res;
663
+	if(sol_string_eq(state, namestr, "stdout")) {
664
+		state->stdout = sol_incref(value);
665
+		goto done;
666
+	}
667
+	if(sol_string_eq(state, namestr, "stderr")) {
668
+		state->stderr = sol_incref(value);
669
+		goto done;
670
+	}
671
+	io = sol_list_get_index(state, args, 0);
672
+	sol_map_set(state, io, name, value);
673
+	sol_obj_free(io);
674
+done:
675
+	sol_obj_free(namestr);
676
+	sol_obj_free(value);
677
+	sol_obj_free(name);
678
+	return sol_incref(state->None);
679
+}
680
+
681
+sol_object_t *sol_get_stdin(sol_state_t *state) {
682
+	return sol_incref(state->stdin);
643 683
 }
644 684
 
645 685
 sol_object_t *sol_get_stdout(sol_state_t *state) {
646
-	sol_object_t *io = sol_state_resolve_name(state, "io");
647
-	sol_object_t *res = sol_map_get_name(state, io, "stdout");
648
-	sol_obj_free(io);
649
-	if(sol_is_none(state, res)) {
650
-		printf("WARNING: No io.stdout, returning a new ref\n");
651
-		return sol_new_stream(state, stdout, MODE_WRITE);
652
-	}
653
-	return res;
686
+	return sol_incref(state->stdout);
654 687
 }
655 688
 
656 689
 sol_object_t *sol_get_stderr(sol_state_t *state) {
657
-	sol_object_t *io = sol_state_resolve_name(state, "io");
658
-	sol_object_t *res = sol_map_get_name(state, io, "stderr");
659
-	sol_obj_free(io);
660
-	if(sol_is_none(state, res)) {
661
-		printf("WARNING: No io.stderr, returning a new ref\n");
662
-		return sol_new_stream(state, stderr, MODE_WRITE);
663
-	}
664
-	return res;
690
+	return sol_incref(state->stderr);
665 691
 }
666 692
 
667 693
 void sol_ops_init(sol_ops_t *ops) {

Загрузка…
Отмена
Сохранить