Browse Source

Sol Part 58: Insert Witty Commit Message Here!

master
Graham Northup 5 years ago
parent
commit
6bcb85a19e
Signed by: grissess GPG Key ID: 5D000E6F539376FB
  1. 8
      Makefile
  2. 1
      ast.h
  3. 1
      astprint.c
  4. 20
      builtins.c
  5. 4
      cdata.c
  6. 8
      object.c
  7. 181
      parser.tab.c
  8. 17
      parser.y
  9. 26
      runtime.c
  10. 19
      sol.h
  11. 21
      solrun.c
  12. 165
      state.c
  13. 1
      tests/_lib.sol
  14. 20
      tests/lang_method.sol

8
Makefile

@ -4,8 +4,9 @@ OBJ= lex.yy.o parser.tab.o dsl/seq.o dsl/list.o dsl/array.o dsl/generic.o astpri
.PHONY: all test
all: $(OBJ)
git submodule init && git submodule sync && git submodule update
all: dsl sol
sol: $(OBJ)
gcc $(CFLAGS) $? $(LDFLAGS) -o sol
test: all $(sort $(patsubst tests/%.sol,test_%,$(wildcard tests/*.sol)))
@ -13,6 +14,9 @@ test: all $(sort $(patsubst tests/%.sol,test_%,$(wildcard tests/*.sol)))
test_%: tests/%.sol
./sol r $?
dsl:
git submodule init && git submodule sync && git submodule update
%.o: %.c
gcc -c -o $@ $? $(CFLAGS)

1
ast.h

@ -121,6 +121,7 @@ typedef struct {
typedef struct {
expr_node *expr;
exprlist_node *args;
char *method;
} call_node;
typedef struct tag_identlist_node {

1
astprint.c

@ -261,6 +261,7 @@ void prex(sol_state_t *state, expr_node *node, int lev) {
lev++;
prlev(state, lev, "Expr:");
prex(state, node->call->expr, lev + 1);
prlev(state, lev, "Method: %s\n", node->call->method);
prlev(state, lev, "Args:");
cure = node->call->args;
while(cure && cure->expr) {

20
builtins.c

@ -943,7 +943,7 @@ sol_object_t *sol_f_str_index(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_str_iter(sol_state_t *state, sol_object_t *args) {
return sol_new_cfunc(state, sol_f_iter_str);
return sol_new_cfunc(state, sol_f_iter_str, "iter.str");
}
sol_object_t *sol_f_str_toint(sol_state_t *state, sol_object_t *args) {
@ -1172,7 +1172,7 @@ sol_object_t *sol_f_list_len(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_list_iter(sol_state_t *state, sol_object_t *args) {
return sol_new_cfunc(state, sol_f_iter_list);
return sol_new_cfunc(state, sol_f_iter_list, "iter.list");
}
sol_object_t *sol_f_list_tostring(sol_state_t *state, sol_object_t *args) {
@ -1390,7 +1390,7 @@ sol_object_t *sol_f_map_len(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_map_iter(sol_state_t *state, sol_object_t *args) {
return sol_new_cfunc(state, sol_f_iter_map);
return sol_new_cfunc(state, sol_f_iter_map, "iter.map");
}
sol_object_t *sol_f_map_tostring(sol_state_t *state, sol_object_t *args) {
@ -1581,7 +1581,17 @@ sol_object_t *sol_f_cfunc_call(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_cfunc_tostring(sol_state_t *state, sol_object_t *args) {
return sol_new_string(state, "<CFunction>");
sol_object_t *cfunc = sol_list_get_index(state, args, 0), *ret;
char *s = malloc(256 * sizeof(char));
if(cfunc->cfname) {
snprintf(s, 256, "<CFunction %s>", cfunc->cfname);
} else {
snprintf(s, 256, "<CFunction>");
}
ret = sol_new_string(state, s);
free(s);
sol_obj_free(cfunc);
return ret;
}
sol_object_t *sol_f_astnode_call(sol_state_t *state, sol_object_t *args) {
@ -2726,7 +2736,7 @@ sol_object_t *sol_f_stream_open(sol_state_t *state, sol_object_t *args) {
sol_object_t *fn = sol_list_get_index(state, args, 0), *mode = sol_list_get_index(state, args, 1);
sol_object_t *sfn = sol_cast_string(state, fn), *imode = sol_cast_int(state, mode);
sol_modes_t m = imode->ival;
char *smode = sol_FileModes[m];
char *smode = sol_FileModes[(m >= 0 && m < (sizeof(sol_FileModes) / sizeof(char *))) ? m : 0];
FILE *f;
sol_obj_free(mode);
sol_obj_free(imode);

4
cdata.c

@ -162,7 +162,7 @@ sol_object_t *sol_f_cstruct_index(sol_state_t *state, sol_object_t *args) {
break;
case SOL_MT_CFUNC:
res = sol_new_cfunc(state, AT(cstruct->data, sol_cfunc_t, spec->offset));
res = sol_new_cfunc(state, AT(cstruct->data, sol_cfunc_t, spec->offset), NULL);
break;
case SOL_MT_PTR:
@ -172,7 +172,7 @@ sol_object_t *sol_f_cstruct_index(sol_state_t *state, sol_object_t *args) {
break;
case SOL_CS_CFUNC:
res = sol_new_cfunc(state, spec->cfunc);
res = sol_new_cfunc(state, spec->cfunc, NULL);
break;
}
if(!res) {

8
object.c

@ -504,15 +504,21 @@ sol_object_t *sol_f_mcell_free(sol_state_t *state, sol_object_t *mcell) {
return 0;
}*/
sol_object_t *sol_new_cfunc(sol_state_t *state, sol_cfunc_t cfunc) {
sol_object_t *sol_new_cfunc(sol_state_t *state, sol_cfunc_t cfunc, char *name) {
sol_object_t *res = sol_alloc_object(state);
res->type = SOL_CFUNCTION;
res->ops = &(state->CFuncOps);
res->cfunc = cfunc;
res->cfname = name ? strdup(name) : NULL;
sol_init_object(state, res);
return res;
}
sol_object_t *sol_f_cfunc_free(sol_state_t *state, sol_object_t *cfunc) {
free(cfunc->cfname);
return cfunc;
}
sol_object_t *sol_new_cdata(sol_state_t *state, void *cdata, sol_ops_t *ops) {
sol_object_t *res = sol_alloc_object(state);
res->type = SOL_CDATA;

181
parser.tab.c

@ -512,11 +512,11 @@ static const yytype_uint16 yyrline[] =
289, 293, 294, 298, 299, 300, 301, 302, 303, 304,
308, 309, 310, 314, 315, 316, 317, 321, 322, 326,
327, 332, 333, 334, 335, 336, 337, 341, 342, 346,
347, 351, 352, 369, 373, 381, 389, 400, 404, 405,
416, 420, 421, 435, 436, 440, 441, 442, 443, 444,
445, 449, 450, 451, 455, 459, 460, 465, 466, 497,
498, 532, 544, 569, 573, 574, 579, 580, 592, 597,
609, 610
347, 351, 352, 360, 364, 372, 380, 391, 395, 396,
407, 411, 412, 426, 427, 431, 432, 433, 434, 435,
436, 440, 441, 442, 446, 450, 451, 456, 457, 488,
489, 523, 535, 560, 564, 565, 570, 571, 583, 588,
600, 601
};
#endif
@ -2266,7 +2266,7 @@ yyreduce:
case 71:
#line 351 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_CALL; AS_EX((yyval))->call = NEW(call_node); AS_EX((yyval))->call->expr = (yyvsp[-3]); AS_EX((yyval))->call->args = (yyvsp[-1]); }
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_CALL; AS_EX((yyval))->call = NEW(call_node); AS_EX((yyval))->call->expr = (yyvsp[-3]); AS_EX((yyval))->call->args = (yyvsp[-1]); AS_EX((yyval))->call->method = NULL; }
#line 2271 "parser.tab.c" /* yacc.c:1646 */
break;
@ -2276,30 +2276,21 @@ yyreduce:
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_CALL;
AS_EX((yyval))->call = NEW(call_node);
AS_EX((yyval))->call->expr = NEW_EX();
AS_EX((yyval))->call->expr->type = EX_INDEX;
AS_EX((yyval))->call->expr->index = NEW(index_node);
AS_EX((yyval))->call->expr->index->expr = (yyvsp[-5]);
AS_EX((yyval))->call->expr->index->index = NEW_EX();
AS_EX((yyval))->call->expr->index->index->type = EX_LIT;
AS_EX((yyval))->call->expr->index->index->lit = NEW(lit_node);
AS_EX((yyval))->call->expr->index->index->lit->type = LIT_STRING;
AS_EX((yyval))->call->expr->index->index->lit->str = (yyvsp[-3]);
AS_EX((yyval))->call->args = NEW(exprlist_node);
AS_EX((yyval))->call->args->expr = ex_copy((yyvsp[-5]));
AS_EX((yyval))->call->args->next = (yyvsp[-1]);
AS_EX((yyval))->call->expr = (yyvsp[-5]);
AS_EX((yyval))->call->args = (yyvsp[-1]);
AS_EX((yyval))->call->method = (yyvsp[-3]);
}
#line 2293 "parser.tab.c" /* yacc.c:1646 */
#line 2284 "parser.tab.c" /* yacc.c:1646 */
break;
case 73:
#line 369 "parser.y" /* yacc.c:1646 */
#line 360 "parser.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
#line 2299 "parser.tab.c" /* yacc.c:1646 */
#line 2290 "parser.tab.c" /* yacc.c:1646 */
break;
case 74:
#line 373 "parser.y" /* yacc.c:1646 */
#line 364 "parser.y" /* yacc.c:1646 */
{
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_FUNCDECL;
@ -2308,11 +2299,11 @@ yyreduce:
AS_EX((yyval))->funcdecl->params = (yyvsp[-3]);
AS_EX((yyval))->funcdecl->body = (yyvsp[-1]);
}
#line 2312 "parser.tab.c" /* yacc.c:1646 */
#line 2303 "parser.tab.c" /* yacc.c:1646 */
break;
case 75:
#line 381 "parser.y" /* yacc.c:1646 */
#line 372 "parser.y" /* yacc.c:1646 */
{
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_FUNCDECL;
@ -2321,11 +2312,11 @@ yyreduce:
AS_EX((yyval))->funcdecl->params = (yyvsp[-3]);
AS_EX((yyval))->funcdecl->body = (yyvsp[-1]);
}
#line 2325 "parser.tab.c" /* yacc.c:1646 */
#line 2316 "parser.tab.c" /* yacc.c:1646 */
break;
case 76:
#line 389 "parser.y" /* yacc.c:1646 */
#line 380 "parser.y" /* yacc.c:1646 */
{
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_FUNCDECL;
@ -2337,23 +2328,23 @@ yyreduce:
AS_EX((yyval))->funcdecl->body->ret = NEW(ret_node);
AS_EX((yyval))->funcdecl->body->ret->ret = (yyvsp[-1]);
}
#line 2341 "parser.tab.c" /* yacc.c:1646 */
#line 2332 "parser.tab.c" /* yacc.c:1646 */
break;
case 77:
#line 400 "parser.y" /* yacc.c:1646 */
#line 391 "parser.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
#line 2347 "parser.tab.c" /* yacc.c:1646 */
#line 2338 "parser.tab.c" /* yacc.c:1646 */
break;
case 78:
#line 404 "parser.y" /* yacc.c:1646 */
#line 395 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_INDEX; AS_EX((yyval))->index = NEW(index_node); AS_EX((yyval))->index->expr = (yyvsp[-3]); AS_EX((yyval))->index->index = (yyvsp[-1]); }
#line 2353 "parser.tab.c" /* yacc.c:1646 */
#line 2344 "parser.tab.c" /* yacc.c:1646 */
break;
case 79:
#line 405 "parser.y" /* yacc.c:1646 */
#line 396 "parser.y" /* yacc.c:1646 */
{
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_INDEX;
@ -2365,23 +2356,23 @@ yyreduce:
AS_EX((yyval))->index->index->lit->type = LIT_STRING;
AS_EX((yyval))->index->index->lit->str = (yyvsp[0]);
}
#line 2369 "parser.tab.c" /* yacc.c:1646 */
#line 2360 "parser.tab.c" /* yacc.c:1646 */
break;
case 80:
#line 416 "parser.y" /* yacc.c:1646 */
#line 407 "parser.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
#line 2375 "parser.tab.c" /* yacc.c:1646 */
#line 2366 "parser.tab.c" /* yacc.c:1646 */
break;
case 81:
#line 420 "parser.y" /* yacc.c:1646 */
#line 411 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_INDEX; AS_EX((yyval))->index = NEW(index_node); AS_EX((yyval))->index->expr = (yyvsp[-3]); AS_EX((yyval))->index->index = (yyvsp[-1]); }
#line 2381 "parser.tab.c" /* yacc.c:1646 */
#line 2372 "parser.tab.c" /* yacc.c:1646 */
break;
case 82:
#line 421 "parser.y" /* yacc.c:1646 */
#line 412 "parser.y" /* yacc.c:1646 */
{
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_INDEX;
@ -2393,105 +2384,105 @@ yyreduce:
AS_EX((yyval))->index->index->lit->type = LIT_STRING;
AS_EX((yyval))->index->index->lit->str = (yyvsp[0]);
}
#line 2397 "parser.tab.c" /* yacc.c:1646 */
#line 2388 "parser.tab.c" /* yacc.c:1646 */
break;
case 83:
#line 435 "parser.y" /* yacc.c:1646 */
#line 426 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_REF; AS_EX((yyval))->ref = NEW(ref_node); AS_EX((yyval))->ref->ident = (yyvsp[0]); }
#line 2403 "parser.tab.c" /* yacc.c:1646 */
#line 2394 "parser.tab.c" /* yacc.c:1646 */
break;
case 84:
#line 436 "parser.y" /* yacc.c:1646 */
#line 427 "parser.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
#line 2409 "parser.tab.c" /* yacc.c:1646 */
#line 2400 "parser.tab.c" /* yacc.c:1646 */
break;
case 85:
#line 440 "parser.y" /* yacc.c:1646 */
#line 431 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_INT; AS_EX((yyval))->lit->ival = *AS((yyvsp[0]), long); free((yyvsp[0])); }
#line 2415 "parser.tab.c" /* yacc.c:1646 */
#line 2406 "parser.tab.c" /* yacc.c:1646 */
break;
case 86:
#line 441 "parser.y" /* yacc.c:1646 */
#line 432 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_INT; AS_EX((yyval))->lit->ival = -(*AS((yyvsp[0]), long)); free((yyvsp[0])); }
#line 2421 "parser.tab.c" /* yacc.c:1646 */
#line 2412 "parser.tab.c" /* yacc.c:1646 */
break;
case 87:
#line 442 "parser.y" /* yacc.c:1646 */
#line 433 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_FLOAT; AS_EX((yyval))->lit->fval = *AS((yyvsp[0]), double); free((yyvsp[0])); }
#line 2427 "parser.tab.c" /* yacc.c:1646 */
#line 2418 "parser.tab.c" /* yacc.c:1646 */
break;
case 88:
#line 443 "parser.y" /* yacc.c:1646 */
#line 434 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_STRING; AS_EX((yyval))->lit->str = (yyvsp[0]); }
#line 2433 "parser.tab.c" /* yacc.c:1646 */
#line 2424 "parser.tab.c" /* yacc.c:1646 */
break;
case 89:
#line 444 "parser.y" /* yacc.c:1646 */
#line 435 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LIT; AS_EX((yyval))->lit = NEW(lit_node); AS_EX((yyval))->lit->type = LIT_NONE; }
#line 2439 "parser.tab.c" /* yacc.c:1646 */
#line 2430 "parser.tab.c" /* yacc.c:1646 */
break;
case 90:
#line 445 "parser.y" /* yacc.c:1646 */
#line 436 "parser.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
#line 2445 "parser.tab.c" /* yacc.c:1646 */
#line 2436 "parser.tab.c" /* yacc.c:1646 */
break;
case 91:
#line 449 "parser.y" /* yacc.c:1646 */
#line 440 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_LISTGEN; AS_EX((yyval))->listgen = NEW(listgen_node); AS_EX((yyval))->listgen->list = (yyvsp[-1]); }
#line 2451 "parser.tab.c" /* yacc.c:1646 */
#line 2442 "parser.tab.c" /* yacc.c:1646 */
break;
case 92:
#line 450 "parser.y" /* yacc.c:1646 */
#line 441 "parser.y" /* yacc.c:1646 */
{ (yyval) = NEW_EX(); AS_EX((yyval))->type = EX_MAPGEN; AS_EX((yyval))->mapgen = NEW(mapgen_node); AS_EX((yyval))->mapgen->map = (yyvsp[-1]); }
#line 2457 "parser.tab.c" /* yacc.c:1646 */
#line 2448 "parser.tab.c" /* yacc.c:1646 */
break;
case 93:
#line 451 "parser.y" /* yacc.c:1646 */
#line 442 "parser.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[0]); }
#line 2463 "parser.tab.c" /* yacc.c:1646 */
#line 2454 "parser.tab.c" /* yacc.c:1646 */
break;
case 94:
#line 455 "parser.y" /* yacc.c:1646 */
#line 446 "parser.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
#line 2469 "parser.tab.c" /* yacc.c:1646 */
#line 2460 "parser.tab.c" /* yacc.c:1646 */
break;
case 95:
#line 459 "parser.y" /* yacc.c:1646 */
#line 450 "parser.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
#line 2475 "parser.tab.c" /* yacc.c:1646 */
#line 2466 "parser.tab.c" /* yacc.c:1646 */
break;
case 96:
#line 460 "parser.y" /* yacc.c:1646 */
#line 451 "parser.y" /* yacc.c:1646 */
{
(yyval) = NEW(exprlist_node);
AS((yyval), exprlist_node)->expr = (yyvsp[0]);
AS((yyval), exprlist_node)->next = NULL;
}
#line 2485 "parser.tab.c" /* yacc.c:1646 */
#line 2476 "parser.tab.c" /* yacc.c:1646 */
break;
case 97:
#line 465 "parser.y" /* yacc.c:1646 */
#line 456 "parser.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
#line 2491 "parser.tab.c" /* yacc.c:1646 */
#line 2482 "parser.tab.c" /* yacc.c:1646 */
break;
case 98:
#line 466 "parser.y" /* yacc.c:1646 */
#line 457 "parser.y" /* yacc.c:1646 */
{
exprlist_node *cur = (yyvsp[-1]);
while(cur->next) cur = cur->next;
@ -2501,17 +2492,17 @@ yyreduce:
cur->next = NULL;
(yyval) = (yyvsp[-1]);
}
#line 2505 "parser.tab.c" /* yacc.c:1646 */
#line 2496 "parser.tab.c" /* yacc.c:1646 */
break;
case 99:
#line 497 "parser.y" /* yacc.c:1646 */
#line 488 "parser.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
#line 2511 "parser.tab.c" /* yacc.c:1646 */
#line 2502 "parser.tab.c" /* yacc.c:1646 */
break;
case 100:
#line 498 "parser.y" /* yacc.c:1646 */
#line 489 "parser.y" /* yacc.c:1646 */
{
paramlist_node *pl = (yyvsp[-3]);
identlist_node *curk;
@ -2546,11 +2537,11 @@ yyreduce:
curv->next = NULL;
(yyval) = pl;
}
#line 2550 "parser.tab.c" /* yacc.c:1646 */
#line 2541 "parser.tab.c" /* yacc.c:1646 */
break;
case 101:
#line 532 "parser.y" /* yacc.c:1646 */
#line 523 "parser.y" /* yacc.c:1646 */
{
paramlist_node *pl = (yyvsp[-2]);
if(!pl) {
@ -2563,11 +2554,11 @@ yyreduce:
pl-> rest = (yyvsp[0]);
(yyval) = pl;
}
#line 2567 "parser.tab.c" /* yacc.c:1646 */
#line 2558 "parser.tab.c" /* yacc.c:1646 */
break;
case 102:
#line 544 "parser.y" /* yacc.c:1646 */
#line 535 "parser.y" /* yacc.c:1646 */
{
paramlist_node *pl = (yyvsp[-1]);
identlist_node *cura;
@ -2593,39 +2584,39 @@ yyreduce:
cura->next = NULL;
(yyval) = pl;
}
#line 2597 "parser.tab.c" /* yacc.c:1646 */
#line 2588 "parser.tab.c" /* yacc.c:1646 */
break;
case 103:
#line 569 "parser.y" /* yacc.c:1646 */
#line 560 "parser.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
#line 2603 "parser.tab.c" /* yacc.c:1646 */
#line 2594 "parser.tab.c" /* yacc.c:1646 */
break;
case 104:
#line 573 "parser.y" /* yacc.c:1646 */
#line 564 "parser.y" /* yacc.c:1646 */
{ (yyval) = NULL; }
#line 2609 "parser.tab.c" /* yacc.c:1646 */
#line 2600 "parser.tab.c" /* yacc.c:1646 */
break;
case 105:
#line 574 "parser.y" /* yacc.c:1646 */
#line 565 "parser.y" /* yacc.c:1646 */
{
(yyval) = NEW(assoclist_node);
AS((yyval), assoclist_node)->item = (yyvsp[0]);
AS((yyval), assoclist_node)->next = NULL;
}
#line 2619 "parser.tab.c" /* yacc.c:1646 */
#line 2610 "parser.tab.c" /* yacc.c:1646 */
break;
case 106:
#line 579 "parser.y" /* yacc.c:1646 */
#line 570 "parser.y" /* yacc.c:1646 */
{ (yyval) = (yyvsp[-1]); }
#line 2625 "parser.tab.c" /* yacc.c:1646 */
#line 2616 "parser.tab.c" /* yacc.c:1646 */
break;
case 107:
#line 580 "parser.y" /* yacc.c:1646 */
#line 571 "parser.y" /* yacc.c:1646 */
{
assoclist_node *cur = (yyvsp[-1]);
while(cur->next) cur = cur->next;
@ -2635,21 +2626,21 @@ yyreduce:
cur->next = NULL;
(yyval) = (yyvsp[-1]);
}
#line 2639 "parser.tab.c" /* yacc.c:1646 */
#line 2630 "parser.tab.c" /* yacc.c:1646 */
break;
case 108:
#line 592 "parser.y" /* yacc.c:1646 */
#line 583 "parser.y" /* yacc.c:1646 */
{
(yyval) = NEW(associtem_node);
AS((yyval), associtem_node)->key = (yyvsp[-3]);
AS((yyval), associtem_node)->value = (yyvsp[0]);
}
#line 2649 "parser.tab.c" /* yacc.c:1646 */
#line 2640 "parser.tab.c" /* yacc.c:1646 */
break;
case 109:
#line 597 "parser.y" /* yacc.c:1646 */
#line 588 "parser.y" /* yacc.c:1646 */
{
(yyval) = NEW(associtem_node);
AS((yyval), associtem_node)->key = NEW_EX();
@ -2659,11 +2650,11 @@ yyreduce:
AS((yyval), associtem_node)->key->lit->str = (yyvsp[-2]);
AS((yyval), associtem_node)->value = (yyvsp[0]);
}
#line 2663 "parser.tab.c" /* yacc.c:1646 */
#line 2654 "parser.tab.c" /* yacc.c:1646 */
break;
#line 2667 "parser.tab.c" /* yacc.c:1646 */
#line 2658 "parser.tab.c" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@ -2898,7 +2889,7 @@ yyreturn:
#endif
return yyresult;
}
#line 613 "parser.y" /* yacc.c:1906 */
#line 604 "parser.y" /* yacc.c:1906 */
// TODO

17
parser.y

@ -348,23 +348,14 @@ ulen_expr:
;
call_expr:
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; }
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; AS_EX($$)->call->method = NULL; }
| call_expr COLON IDENT LPAREN expr_list RPAREN {
$$ = NEW_EX();
AS_EX($$)->type = EX_CALL;
AS_EX($$)->call = NEW(call_node);
AS_EX($$)->call->expr = NEW_EX();
AS_EX($$)->call->expr->type = EX_INDEX;
AS_EX($$)->call->expr->index = NEW(index_node);
AS_EX($$)->call->expr->index->expr = $1;
AS_EX($$)->call->expr->index->index = NEW_EX();
AS_EX($$)->call->expr->index->index->type = EX_LIT;
AS_EX($$)->call->expr->index->index->lit = NEW(lit_node);
AS_EX($$)->call->expr->index->index->lit->type = LIT_STRING;
AS_EX($$)->call->expr->index->index->lit->str = $3;
AS_EX($$)->call->args = NEW(exprlist_node);
AS_EX($$)->call->args->expr = ex_copy($1);
AS_EX($$)->call->args->next = $5;
AS_EX($$)->call->expr = $1;
AS_EX($$)->call->args = $5;
AS_EX($$)->call->method = $3;
}
| funcdecl_expr { $$ = $1; }
;

26
runtime.c

@ -168,6 +168,7 @@ expr_node *ex_copy(expr_node *old) {
new->call = NEW(call_node);
new->call->expr = ex_copy(old->call->expr);
new->call->args = exl_copy(old->call->args);
new->call->method = old->call->method ? strdup(old->call->method) : NULL;
break;
case EX_FUNCDECL:
@ -406,6 +407,7 @@ void ex_free(expr_node *expr) {
case EX_CALL:
ex_free(expr->call->expr);
exl_free(expr->call->args);
free(expr->call->method);
free(expr->call);
break;
@ -764,7 +766,25 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
ERR_CHECK(state);
list = sol_new_list(state);
ERR_CHECK(state);
sol_list_insert(state, list, 0, value);
if(expr->call->method) {
left = sol_incref(value);
sol_list_insert(state, list, 0, value);
right = sol_new_string(state, expr->call->method);
sol_list_insert(state, list, 1, right);
sol_obj_free(right);
res = CALL_METHOD(state, value, index, list);
sol_obj_free(value);
value = sol_incref(res);
sol_obj_free(res);
ERR_CHECK(state);
sol_obj_free(list);
list = sol_new_list(state);
sol_list_insert(state, list, 0, value);
sol_list_insert(state, list, 1, left);
sol_obj_free(left);
} else {
sol_list_insert(state, list, 0, value);
}
cure = expr->call->args;
while(cure) {
if(cure->expr) {
@ -774,8 +794,8 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
cure = cure->next;
}
res = CALL_METHOD(state, value, call, list);
sol_obj_free(value);
sol_obj_free(list);
sol_obj_free(value);
ERR_CHECK(state);
return res;
break;
@ -793,6 +813,8 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
curi = curi->next;
cure = cure->next;
}
} else {
res->rest = NULL;
}
if(expr->funcdecl->name) {
sol_state_assign_l_name(state, expr->funcdecl->name, res);

19
sol.h

@ -10,7 +10,7 @@
#include "dsl/dsl.h"
/** The version of the project, as made available through `debug.version`. */
#define VERSION "0.3a0"
#define SOL_VERSION "0.3a1"
/** The hexadecimal version of the project, formatted 0xAAIIRPP where:
*
* - AA is the two-digit major version
@ -20,7 +20,7 @@
*
* This value is guaranteed to only monotonically increase by revision.
*/
#define HEXVER 0x0003A00
#define SOL_HEXVER 0x0003A01
#ifndef SOL_ICACHE_MIN
/** The smallest integer to cache. */
@ -335,8 +335,12 @@ typedef struct sol_tag_object_t {
/* For `SOL_FUNCTION`, the name of an argument that receives extra parameters as a list (otherwise NULL). */
char *rest;
};
/** For `SOL_CFUNCTION`, the C function pointer. */
sol_cfunc_t cfunc;
struct {
/** For `SOL_CFUNCTION`, the C function pointer. */
sol_cfunc_t cfunc;
/** For `SOL_CFUNCTION`, the name of this function, or NULL. */
char *cfname;
};
/** For `SOL_STMT` and `SOL_EXPR`, the `stmt_node` or `expr_node` pointer, respectively. */
void *node;
struct {
@ -418,8 +422,12 @@ typedef struct sol_tag_state_t {
#endif
sol_object_t *lastvalue; ///< Holds the value of the last expression evaluated, returned by an `if` expression
sol_object_t *loopvalue; ///< Holds an initially-empty list appended to by `continue <expr>` or set to another object by `break <expr>`
unsigned short features; ///< A flag field used to control the Sol initialization processs
} sol_state_t;
/** Don't run user initialization files. */
#define SOL_FT_NO_USR_INIT 0x0001
// state.c
/** Initializes the state.
@ -1021,7 +1029,7 @@ void sol_map_invert(sol_state_t *, sol_object_t *);
// sol_object_t *sol_new_stmtnode(sol_state_t *, stmt_node *);
// sol_object_t *sol_new_exprnode(sol_state_t *, expr_node *);
sol_object_t *sol_new_cfunc(sol_state_t *, sol_cfunc_t);
sol_object_t *sol_new_cfunc(sol_state_t *, sol_cfunc_t, char *);
sol_object_t *sol_new_cdata(sol_state_t *, void *, sol_ops_t *);
sol_object_t *sol_new_buffer(sol_state_t *, void *, ssize_t, sol_owntype_t, sol_freefunc_t, sol_movefunc_t);
@ -1067,6 +1075,7 @@ sol_object_t *sol_f_list_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_map_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_mcell_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_func_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_cfunc_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_astnode_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_buffer_free(sol_state_t *, sol_object_t *);
sol_object_t *sol_f_dylib_free(sol_state_t *, sol_object_t *);

21
solrun.c

@ -6,10 +6,12 @@ int main(int argc, char **argv) {
stmt_node *program;
sol_state_t state;
char *c;
int printtree = 0;
int printtree = 0, clean = 1;
FILE *prgstream = stdin;
int result = 0;
state.features = 0;
if(argc > 1) {
c = argv[1];
while(*c) {
@ -28,6 +30,11 @@ int main(int argc, char **argv) {
return 2;
}
prgstream = fopen(argv[2], "r");
break;
case 'i':
state.features |= SOL_FT_NO_USR_INIT;
break;
}
c++;
}
@ -49,13 +56,21 @@ int main(int argc, char **argv) {
fclose(prgstream);
}
sol_state_init(&state);
if(!sol_state_init(&state)) {
printf("State init error (internal bug)\n");
result = 2;
clean = 0;
goto out_results;
}
if(printtree) {
st_print(&state, program);
}
sol_exec(&state, program);
out_results:
if(sol_has_error(&state)) {
printf("Error: ");
ob_print(state.error);
@ -72,7 +87,7 @@ int main(int argc, char **argv) {
}
}
st_free(program);
sol_state_cleanup(&state);
if(clean) sol_state_cleanup(&state);
return result;
}

165
state.c

@ -157,6 +157,7 @@ int sol_state_init(sol_state_t *state) {
state->CFuncOps.tname = "cfunction";
state->CFuncOps.call = sol_f_cfunc_call;
state->CFuncOps.tostring = sol_f_cfunc_tostring;
state->CFuncOps.free = sol_f_cfunc_free;
state->ASTNodeOps.tname = "astnode";
state->ASTNodeOps.call = sol_f_astnode_call;
@ -233,35 +234,37 @@ int sol_state_init(sol_state_t *state) {
// NB: None is actually a keyword in the language--it doesn't need to be a
// global (see parser.y)
sol_map_borrow_name(state, globals, "OutOfMemory", state->OutOfMemory);
sol_map_borrow_name(state, globals, "toint", sol_new_cfunc(state, sol_f_toint));
sol_map_borrow_name(state, globals, "tofloat", sol_new_cfunc(state, sol_f_tofloat));
sol_map_borrow_name(state, globals, "tostring", sol_new_cfunc(state, sol_f_tostring));
sol_map_borrow_name(state, globals, "try", sol_new_cfunc(state, sol_f_try));
sol_map_borrow_name(state, globals, "apply", sol_new_cfunc(state, sol_f_apply));
sol_map_borrow_name(state, globals, "error", sol_new_cfunc(state, sol_f_error));
sol_map_borrow_name(state, globals, "type", sol_new_cfunc(state, sol_f_type));
sol_map_borrow_name(state, globals, "prepr", sol_new_cfunc(state, sol_f_prepr));
sol_map_borrow_name(state, globals, "print", sol_new_cfunc(state, sol_f_print));
sol_map_borrow_name(state, globals, "rawget", sol_new_cfunc(state, sol_f_rawget));
sol_map_borrow_name(state, globals, "rawset", sol_new_cfunc(state, sol_f_rawset));
sol_map_borrow_name(state, globals, "range", sol_new_cfunc(state, sol_f_range));
sol_map_borrow_name(state, globals, "exec", sol_new_cfunc(state, sol_f_exec));
sol_map_borrow_name(state, globals, "eval", sol_new_cfunc(state, sol_f_eval));
sol_map_borrow_name(state, globals, "execfile", sol_new_cfunc(state, sol_f_execfile));
sol_map_borrow_name(state, globals, "parse", sol_new_cfunc(state, sol_f_parse));
sol_map_borrow_name(state, globals, "ord", sol_new_cfunc(state, sol_f_ord));
sol_map_borrow_name(state, globals, "chr", sol_new_cfunc(state, sol_f_chr));
// OutOfMemory (and other important singlets) are set, not borrowed,
// because the state still holds a reference to them
sol_map_set_name(state, globals, "OutOfMemory", state->OutOfMemory);
sol_map_borrow_name(state, globals, "toint", sol_new_cfunc(state, sol_f_toint, "toint"));
sol_map_borrow_name(state, globals, "tofloat", sol_new_cfunc(state, sol_f_tofloat, "tofloat"));
sol_map_borrow_name(state, globals, "tostring", sol_new_cfunc(state, sol_f_tostring, "tostring"));
sol_map_borrow_name(state, globals, "try", sol_new_cfunc(state, sol_f_try, "try"));
sol_map_borrow_name(state, globals, "apply", sol_new_cfunc(state, sol_f_apply, "apply"));
sol_map_borrow_name(state, globals, "error", sol_new_cfunc(state, sol_f_error, "error"));
sol_map_borrow_name(state, globals, "type", sol_new_cfunc(state, sol_f_type, "type"));
sol_map_borrow_name(state, globals, "prepr", sol_new_cfunc(state, sol_f_prepr, "prepr"));
sol_map_borrow_name(state, globals, "print", sol_new_cfunc(state, sol_f_print, "print"));
sol_map_borrow_name(state, globals, "rawget", sol_new_cfunc(state, sol_f_rawget, "rawget"));
sol_map_borrow_name(state, globals, "rawset", sol_new_cfunc(state, sol_f_rawset, "rawset"));
sol_map_borrow_name(state, globals, "range", sol_new_cfunc(state, sol_f_range, "range"));
sol_map_borrow_name(state, globals, "exec", sol_new_cfunc(state, sol_f_exec, "exec"));
sol_map_borrow_name(state, globals, "eval", sol_new_cfunc(state, sol_f_eval, "eval"));
sol_map_borrow_name(state, globals, "execfile", sol_new_cfunc(state, sol_f_execfile, "execfile"));
sol_map_borrow_name(state, globals, "parse", sol_new_cfunc(state, sol_f_parse, "parse"));
sol_map_borrow_name(state, globals, "ord", sol_new_cfunc(state, sol_f_ord, "ord"));
sol_map_borrow_name(state, globals, "chr", sol_new_cfunc(state, sol_f_chr, "chr"));
mod = sol_new_map(state);
sol_map_borrow_name(state, mod, "getref", sol_new_cfunc(state, sol_f_debug_getref));
sol_map_borrow_name(state, mod, "setref", sol_new_cfunc(state, sol_f_debug_setref));
sol_map_borrow_name(state, mod, "closure", sol_new_cfunc(state, sol_f_debug_closure));
sol_map_borrow_name(state, mod, "globals", sol_new_cfunc(state, sol_f_debug_globals));
sol_map_borrow_name(state, mod, "locals", sol_new_cfunc(state, sol_f_debug_locals));
sol_map_borrow_name(state, mod, "scopes", sol_new_cfunc(state, sol_f_debug_scopes));
sol_map_borrow_name(state, mod, "version", sol_new_string(state, VERSION));
sol_map_borrow_name(state, mod, "hexversion", sol_new_int(state, HEXVER));
sol_map_borrow_name(state, mod, "getref", sol_new_cfunc(state, sol_f_debug_getref, "debug.getref"));
sol_map_borrow_name(state, mod, "setref", sol_new_cfunc(state, sol_f_debug_setref, "debug.setref"));
sol_map_borrow_name(state, mod, "closure", sol_new_cfunc(state, sol_f_debug_closure, "debug.closure"));
sol_map_borrow_name(state, mod, "globals", sol_new_cfunc(state, sol_f_debug_globals, "debug.globals"));
sol_map_borrow_name(state, mod, "locals", sol_new_cfunc(state, sol_f_debug_locals, "debug.locals"));
sol_map_borrow_name(state, mod, "scopes", sol_new_cfunc(state, sol_f_debug_scopes, "debug.scopes"));
sol_map_borrow_name(state, mod, "version", sol_new_string(state, SOL_VERSION));
sol_map_borrow_name(state, mod, "hexversion", sol_new_int(state, SOL_HEXVER));
#ifdef SOL_ICACHE
sol_map_borrow_name(state, mod, "icache_min", sol_new_int(state, SOL_ICACHE_MIN));
sol_map_borrow_name(state, mod, "icache_max", sol_new_int(state, SOL_ICACHE_MAX));
@ -270,15 +273,15 @@ int sol_state_init(sol_state_t *state) {
sol_obj_free(mod);
mod = sol_new_map(state);
sol_map_borrow_name(state, mod, "str", sol_new_cfunc(state, sol_f_iter_str));
sol_map_borrow_name(state, mod, "list", sol_new_cfunc(state, sol_f_iter_list));
sol_map_borrow_name(state, mod, "map", sol_new_cfunc(state, sol_f_iter_map));
sol_map_borrow_name(state, mod, "str", sol_new_cfunc(state, sol_f_iter_str, "iter.str"));
sol_map_borrow_name(state, mod, "list", sol_new_cfunc(state, sol_f_iter_list, "iter.list"));
sol_map_borrow_name(state, mod, "map", sol_new_cfunc(state, sol_f_iter_map, "iter.map"));
sol_register_module_name(state, "iter", mod);
sol_obj_free(mod);
mod = sol_new_map(state);
sol_map_borrow_name(state, mod, "readline", sol_new_cfunc(state, sol_f_readline_readline));
sol_map_borrow_name(state, mod, "add_history", sol_new_cfunc(state, sol_f_readline_add_history));
sol_map_borrow_name(state, mod, "readline", sol_new_cfunc(state, sol_f_readline_readline, "readline.readline"));
sol_map_borrow_name(state, mod, "add_history", sol_new_cfunc(state, sol_f_readline_add_history, "readline.add_history"));
sol_register_module_name(state, "readline", mod);
sol_obj_free(mod);
@ -332,7 +335,7 @@ int sol_state_init(sol_state_t *state) {
sol_map_borrow_name(state, mod, "KIND_STMT", sol_new_int(state, -1));
sol_map_borrow_name(state, mod, "KIND_EXPR", sol_new_int(state, -2));
sol_map_invert(state, mod);
sol_map_borrow_name(state, mod, "print", sol_new_cfunc(state, sol_f_ast_print));
sol_map_borrow_name(state, mod, "print", sol_new_cfunc(state, sol_f_ast_print, "ast.print"));
sol_register_module_name(state, "ast", mod);
btype = sol_new_map(state);
@ -397,10 +400,10 @@ int sol_state_init(sol_state_t *state) {
sol_map_invert(state, bobj);
mod = sol_new_map(state);
sol_map_borrow_name(state, mod, "new", sol_new_cfunc(state, sol_f_buffer_new));
sol_map_borrow_name(state, mod, "fromstring", sol_new_cfunc(state, sol_f_buffer_fromstring));
sol_map_borrow_name(state, mod, "fromobject", sol_new_cfunc(state, sol_f_buffer_fromobject));
sol_map_borrow_name(state, mod, "fromaddress", sol_new_cfunc(state, sol_f_buffer_fromaddress));
sol_map_borrow_name(state, mod, "new", sol_new_cfunc(state, sol_f_buffer_new, "buffer.new"));
sol_map_borrow_name(state, mod, "fromstring", sol_new_cfunc(state, sol_f_buffer_fromstring, "buffer.fromstring"));
sol_map_borrow_name(state, mod, "fromobject", sol_new_cfunc(state, sol_f_buffer_fromobject, "buffer.fromobject"));
sol_map_borrow_name(state, mod, "fromaddress", sol_new_cfunc(state, sol_f_buffer_fromaddress, "buffer.fromaddress"));
sol_map_set_name(state, mod, "type", btype);
sol_map_set_name(state, mod, "sizeof", bsize);
sol_map_set_name(state, mod, "objtype", bobj);
@ -421,44 +424,44 @@ int sol_state_init(sol_state_t *state) {
sol_map_borrow_name(state, mod, "SEEK_END", sol_new_int(state, SEEK_END));
sol_map_borrow_name(state, mod, "ALL", sol_new_string(state, "ALL"));
sol_map_borrow_name(state, mod, "LINE", sol_new_string(state, "LINE"));
sol_map_borrow_name(state, mod, "open", sol_new_cfunc(state, sol_f_stream_open));
sol_map_borrow_name(state, mod, "__setindex", sol_new_cfunc(state, sol_f_io_setindex));
sol_map_borrow_name(state, mod, "__index", sol_new_cfunc(state, sol_f_io_index));
sol_map_borrow_name(state, mod, "open", sol_new_cfunc(state, sol_f_stream_open, "io.open"));
sol_map_borrow_name(state, mod, "__setindex", sol_new_cfunc(state, sol_f_io_setindex, "io.__setindex"));
sol_map_borrow_name(state, mod, "__index", sol_new_cfunc(state, sol_f_io_index, "io.__index"));
sol_register_module_name(state, "io", mod);
sol_obj_free(mod);
meths = sol_new_map(state);
sol_map_borrow_name(state, meths, "get", sol_new_cfunc(state, sol_f_buffer_get));
sol_map_borrow_name(state, meths, "set", sol_new_cfunc(state, sol_f_buffer_set));
sol_map_borrow_name(state, meths, "address", sol_new_cfunc(state, sol_f_buffer_address));
sol_map_borrow_name(state, meths, "size", sol_new_cfunc(state, sol_f_buffer_size));
sol_map_borrow_name(state, meths, "get", sol_new_cfunc(state, sol_f_buffer_get, "buffer.get"));
sol_map_borrow_name(state, meths, "set", sol_new_cfunc(state, sol_f_buffer_set, "buffer.set"));
sol_map_borrow_name(state, meths, "address", sol_new_cfunc(state, sol_f_buffer_address, "buffer.address"));
sol_map_borrow_name(state, meths, "size", sol_new_cfunc(state, sol_f_buffer_size, "buffer.size"));
sol_register_methods_name(state, "buffer", meths);
sol_obj_free(meths);
meths = sol_new_map(state);
sol_map_borrow_name(state, meths, "copy", sol_new_cfunc(state, sol_f_list_copy));
sol_map_borrow_name(state, meths, "insert", sol_new_cfunc(state, sol_f_list_insert));
sol_map_borrow_name(state, meths, "remove", sol_new_cfunc(state, sol_f_list_remove));
sol_map_borrow_name(state, meths, "truncate", sol_new_cfunc(state, sol_f_list_truncate));
sol_map_borrow_name(state, meths, "map", sol_new_cfunc(state, sol_f_list_map));
sol_map_borrow_name(state, meths, "filter", sol_new_cfunc(state, sol_f_list_filter));
sol_map_borrow_name(state, meths, "copy", sol_new_cfunc(state, sol_f_list_copy, "list.copy"));
sol_map_borrow_name(state, meths, "insert", sol_new_cfunc(state, sol_f_list_insert, "list.insert"));
sol_map_borrow_name(state, meths, "remove", sol_new_cfunc(state, sol_f_list_remove, "list.remove"));
sol_map_borrow_name(state, meths, "truncate", sol_new_cfunc(state, sol_f_list_truncate, "list.truncate"));
sol_map_borrow_name(state, meths, "map", sol_new_cfunc(state, sol_f_list_map, "list.map"));
sol_map_borrow_name(state, meths, "filter", sol_new_cfunc(state, sol_f_list_filter, "list.filter"));
sol_register_methods_name(state, "list", meths);
sol_obj_free(meths);
meths = sol_new_map(state);
sol_map_borrow_name(state, meths, "read", sol_new_cfunc(state, sol_f_stream_read));
sol_map_borrow_name(state, meths, "write", sol_new_cfunc(state, sol_f_stream_write));
sol_map_borrow_name(state, meths, "seek", sol_new_cfunc(state, sol_f_stream_seek));
sol_map_borrow_name(state, meths, "tell", sol_new_cfunc(state, sol_f_stream_tell));
sol_map_borrow_name(state, meths, "flush", sol_new_cfunc(state, sol_f_stream_flush));
sol_map_borrow_name(state, meths, "eof", sol_new_cfunc(state, sol_f_stream_eof));
sol_map_borrow_name(state, meths, "read", sol_new_cfunc(state, sol_f_stream_read, "stream.read"));
sol_map_borrow_name(state, meths, "write", sol_new_cfunc(state, sol_f_stream_write, "stream.write"));
sol_map_borrow_name(state, meths, "seek", sol_new_cfunc(state, sol_f_stream_seek, "stream.seek"));
sol_map_borrow_name(state, meths, "tell", sol_new_cfunc(state, sol_f_stream_tell, "stream.tell"));
sol_map_borrow_name(state, meths, "flush", sol_new_cfunc(state, sol_f_stream_flush, "stream.flush"));
sol_map_borrow_name(state, meths, "eof", sol_new_cfunc(state, sol_f_stream_eof, "stream.eof"));
sol_register_methods_name(state, "stream", meths);
sol_obj_free(meths);
meths = sol_new_map(state);
sol_map_borrow_name(state, meths, "sub", sol_new_cfunc(state, sol_f_str_sub));
sol_map_borrow_name(state, meths, "split", sol_new_cfunc(state, sol_f_str_split));
sol_map_borrow_name(state, meths, "find", sol_new_cfunc(state, sol_f_str_find));
sol_map_borrow_name(state, meths, "sub", sol_new_cfunc(state, sol_f_str_sub, "str.sub"));
sol_map_borrow_name(state, meths, "split", sol_new_cfunc(state, sol_f_str_split, "str.split"));
sol_map_borrow_name(state, meths, "find", sol_new_cfunc(state, sol_f_str_find, "str.find"));
sol_register_methods_name(state, "string", meths);
sol_obj_free(meths);
@ -469,23 +472,9 @@ int sol_state_init(sol_state_t *state) {
// Perform initialization based on the user profile, if so requested.
// TODO: Make this switchable at runtime.
for(i = 0; i < LENGTH(sol_AbsInitPaths); i++) {
fp = fopen(sol_AbsInitPaths[i], "r");
if(fp) {
stmt = sol_compile_file(fp);
sol_exec(state, stmt);
st_free(stmt);
fclose(fp);
}
}
suffix = getenv("HOME");
if(suffix) {
strncpy(sol_TempPath, suffix, TMP_PATH_SZ);
suffix = sol_TempPath + strlen(sol_TempPath);
for(i = 0; i < LENGTH(sol_HomeInitPaths); i++) {
strncpy(suffix, sol_HomeInitPaths[i], TMP_PATH_SZ - (suffix - sol_TempPath));
fp = fopen(sol_TempPath, "r");
if(!(state->features & SOL_FT_NO_USR_INIT)) {
for(i = 0; i < LENGTH(sol_AbsInitPaths); i++) {
fp = fopen(sol_AbsInitPaths[i], "r");
if(fp) {
stmt = sol_compile_file(fp);
sol_exec(state, stmt);
@ -493,10 +482,26 @@ int sol_state_init(sol_state_t *state) {
fclose(fp);
}
}
}
if(sol_has_error(state)) {
goto cleanup;
suffix = getenv("HOME");
if(suffix) {
strncpy(sol_TempPath, suffix, TMP_PATH_SZ);
suffix = sol_TempPath + strlen(sol_TempPath);
for(i = 0; i < LENGTH(sol_HomeInitPaths); i++) {
strncpy(suffix, sol_HomeInitPaths[i], TMP_PATH_SZ - (suffix - sol_TempPath));
fp = fopen(sol_TempPath, "r");
if(fp) {
stmt = sol_compile_file(fp);
sol_exec(state, stmt);
st_free(stmt);
fclose(fp);
}
}
}
if(sol_has_error(state)) {
goto cleanup;
}
}
// We're all set!

1
tests/_lib.sol

@ -2,6 +2,7 @@ func assert(x, msg, _test_count = 0)
_test_count += 1
io.stdout:write('Test ' + tostring(_test_count) + ': ' + msg)
if !x then
print("")
error("Assertion failed: " + tostring(msg))
end
print("...passed")

20
tests/lang_method.sol

@ -0,0 +1,20 @@
execfile("tests/_lib.sol")
func count(v, c=0, lv=0)
c += 1
lv = v
end
d = {method = count}
d:method()
assert_eq(d, count.closure.lv, "method called with self")
assert_eq(1, count.closure.c, "method evaluated once (expr is map)")
func count(c = 0)
c += 1
return {v = c, method = func(self) return self.v end}
end
assert_eq(count():method(), count.closure.c, "method evaluation consistent")
assert_eq(1, count.closure.c, "method evaluated once (expr is call)")
Loading…
Cancel
Save