Browse Source

Sol Part 5: Kid Tested, Mother Approved!

master
Graham Northup 7 years ago
parent
commit
1ffe68b513
  1. 2
      ast.h
  2. 8
      astprint.c
  3. 291
      builtins.c
  4. 11
      dsdebug.gdb
  5. 202
      lex.yy.c
  6. 173
      object.c
  7. 6507
      parser.output
  8. 748
      parser.tab.c
  9. 24
      parser.tab.h
  10. 29
      parser.y
  11. 86
      runtime.c
  12. 45
      sol.h
  13. 161
      state.c
  14. 25
      test.sol
  15. 4
      tokenizer.lex

2
ast.h

@ -21,7 +21,7 @@ typedef struct {
};
} lit_node;
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;
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;
typedef struct {
binop_t type;
expr_node *left;

8
astprint.c

@ -198,6 +198,14 @@ void prex(expr_node *node, int lev) {
case OP_GREATEREQ:
prlev(lev, "Op: >=");
break;
case OP_LSHIFT:
prlev(lev, "Op: <<");
break;
case OP_RSHIFT:
prlev(lev, "Op: >>");
break;
}
prlev(lev, "Left:");
prex(node->binop->left, lev+1);

291
builtins.c

@ -70,20 +70,20 @@ sol_object_t *sol_f_try(sol_state_t *state, sol_object_t *args) {
sol_obj_free(res);
sol_obj_free(one);
sol_clear_error(state);
sol_list_insert(state, &ls, 0, err);
sol_list_insert(state, ls, 0, err);
sol_obj_free(err);
sol_list_insert(state, &ls, 0, zero);
sol_list_insert(state, ls, 0, zero);
sol_obj_free(zero);
return ls;
}
sol_list_insert(state, &ls, 0, res);
sol_list_insert(state, ls, 0, res);
sol_obj_free(res);
sol_list_insert(state, &ls, 0, one);
sol_list_insert(state, ls, 0, one);
sol_obj_free(one);
return ls;
}
static char *sol_TypeNames[] = {"singlet", "integer", "float", "string", "list", "map", "function", "cfunction", "cdata"};
static char *sol_TypeNames[] = {"singlet", "integer", "float", "string", "list", "listcell", "map", "mapcell", "function", "cfunction", "cdata"};
sol_object_t *sol_f_type(sol_state_t *state, sol_object_t *args) {
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) {
return res;
}
sol_object_t *p_seen[1024] = {0};
void ob_print(sol_object_t *obj) {
sol_object_t *cur;
int i;
for(i=0; i<1024; i++) {
if(!p_seen[i]) {
p_seen[i] = obj;
break;
}
if(p_seen[i] == obj) {
printf("... (%p)", obj);
return;
}
}
switch(obj->type) {
case SOL_SINGLET:
printf("<Singlet>");
@ -110,6 +123,10 @@ void ob_print(sol_object_t *obj) {
case SOL_STRING:
printf("\"%s\"", obj->str);
break;
case SOL_LCELL:
printf("<<");
/* fall through */
case SOL_LIST:
printf("[");
@ -125,6 +142,10 @@ void ob_print(sol_object_t *obj) {
}
printf("]");
break;
case SOL_MCELL:
printf("<<");
/* fall through */
case SOL_MAP:
printf("{");
@ -161,13 +182,170 @@ void ob_print(sol_object_t *obj) {
}
sol_object_t *sol_f_prepr(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0);
ob_print(obj);
printf("\n");
sol_obj_free(obj);
int i, sz = sol_list_len(state, args);
sol_object_t *obj;
for(i=0; i<1024; i++) p_seen[i] = NULL;
for(i=0; i<sz; i++) {
obj = sol_list_get_index(state, args, i);
ob_print(obj);
printf(" ");
sol_obj_free(obj);
}
printf("\n");
return sol_incref(state->None);
}
sol_object_t *sol_f_print(sol_state_t *state, sol_object_t *args) {
int i, sz = sol_list_len(state, args);
sol_object_t *obj;
for(i=0; i<1024; i++) p_seen[i] = NULL;
for(i=0; i<sz; i++) {
obj = sol_list_get_index(state, args, i);
if(sol_is_string(obj)) {
printf("%s", obj->str);
} else {
ob_print(obj);
}
printf(" ");
sol_obj_free(obj);
}
printf("\n");
return sol_incref(state->None);
}
sol_object_t *sol_f_rawget(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *key, *res;
if(!sol_is_map(obj)) return sol_set_error_string(state, "Rawset of non-map");
key = sol_list_get_index(state, args, 1);
res = sol_map_get(state, obj, key);
sol_obj_free(key);
sol_obj_free(obj);
return sol_incref(state->None);
}
sol_object_t *sol_f_rawset(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *key, *val;
if(!sol_is_map(obj)) return sol_set_error_string(state, "Rawset of non-map");
key = sol_list_get_index(state, args, 1);
val = sol_list_get_index(state, args, 2);
sol_map_set(state, obj, key, val);
sol_obj_free(val);
sol_obj_free(key);
sol_obj_free(obj);
return sol_incref(state->None);
}
sol_object_t *sol_f_range(sol_state_t *state, sol_object_t *args) {
sol_object_t *res = sol_new_list(state), *bound = sol_cast_int(state, sol_list_get_index(state, args, 0));
int i;
for(i=0; i<bound->ival; i++) {
sol_list_insert(state, res, sol_list_len(state, res), sol_new_int(state, i));
}
sol_obj_free(bound);
return res;
}
sol_object_t *sol_f_debug_getref(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0);
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.
sol_obj_free(obj);
return res;
}
sol_object_t *sol_f_debug_setref(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *cnt = sol_list_get_index(state, args, 1);
obj->refcnt = sol_cast_int(state, cnt)->ival + 2; // NB: As above.
sol_obj_free(cnt);
sol_obj_free(obj);
return sol_incref(state->None);
}
sol_object_t *sol_f_debug_closure(sol_state_t *state, sol_object_t *args) {
sol_object_t *func = sol_list_get_index(state, args, 0);
sol_object_t *res = sol_incref(func->closure);
sol_obj_free(func);
return res;
}
sol_object_t *sol_f_debug_globals(sol_state_t *state, sol_object_t *args) {
return sol_list_get_index(state, state->scopes, sol_list_len(state, state->scopes)-1);
}
sol_object_t *sol_f_debug_locals(sol_state_t *state, sol_object_t *args) {
return sol_list_get_index(state, state->scopes, 0);
}
sol_object_t *sol_f_iter_str(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
char temp[2] = {0, 0};
if(sol_is_none(state, index)) {
sol_obj_free(index);
index = sol_new_int(state, 0);
sol_map_set_name(state, local, "idx", index);
}
if(index->ival >= strlen(obj->str)) {
sol_obj_free(index);
sol_obj_free(obj);
sol_obj_free(local);
return sol_incref(state->StopIteration);
}
temp[0] = obj->str[index->ival];
res = sol_new_string(state, temp);
index->ival++;
sol_obj_free(index);
sol_obj_free(local);
sol_obj_free(obj);
return res;
}
sol_object_t *sol_f_iter_list(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
if(sol_is_none(state, index)) {
sol_obj_free(index);
index = sol_new_int(state, 0);
sol_map_set_name(state, local, "idx", index);
}
if(index->ival >= sol_list_len(state, obj)) {
sol_obj_free(index);
sol_obj_free(obj);
sol_obj_free(local);
return sol_incref(state->StopIteration);
}
res = sol_list_get_index(state, obj, index->ival);
index->ival++;
sol_obj_free(index);
sol_obj_free(local);
sol_obj_free(obj);
return res;
}
sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) {
sol_object_t *obj = sol_list_get_index(state, args, 0), *local = sol_list_get_index(state, args, 1);
sol_object_t *index = sol_map_get_name(state, local, "idx"), *res;
if(sol_is_none(state, index)) {
sol_obj_free(index);
index = obj;
sol_map_set_name(state, local, "idx", index);
}
while(index && !index->mkey) index = index->mnext;
if(!index || !index->mnext) {
sol_obj_free(index);
sol_obj_free(obj);
sol_obj_free(local);
return sol_incref(state->StopIteration);
}
res = sol_incref(index->mkey);
index = index->mnext;
sol_map_set_name(state, local, "idx", index);
sol_obj_free(index);
sol_obj_free(local);
sol_obj_free(obj);
return res;
}
sol_object_t *sol_f_int_add(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
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) {
return res;
}
sol_object_t *sol_f_int_blsh(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
sol_object_t *res = sol_new_int(state, a->ival << b->ival);
sol_obj_free(a);
sol_obj_free(b);
if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
return res;
}
sol_object_t *sol_f_int_brsh(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
sol_object_t *res = sol_new_int(state, a->ival >> b->ival);
sol_obj_free(a);
sol_obj_free(b);
if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
return res;
}
sol_object_t *sol_f_int_bnot(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0);
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) {
return res;
}
sol_object_t *sol_f_str_iter(sol_state_t *state, sol_object_t *args) {
return sol_new_cfunc(state, sol_f_iter_str);
}
sol_object_t *sol_f_str_toint(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0);
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) {
return res;
}
sol_object_t *sol_f_list_iter(sol_state_t *state, sol_object_t *args) {
return sol_new_cfunc(state, sol_f_iter_list);
}
sol_object_t *sol_f_list_tostring(sol_state_t *state, sol_object_t *args) {
return sol_new_string(state, "<List>");
}
@ -487,7 +691,21 @@ sol_object_t *sol_f_map_add(sol_state_t *state, sol_object_t *args) {
sol_object_t *sol_f_map_index(sol_state_t *state, sol_object_t *args) {
sol_object_t *map = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
sol_object_t *res = sol_map_get(state, map, b);
sol_object_t *indexf = sol_map_get_name(state, map, "__index");
sol_object_t *res = NULL, *newls;
if(!sol_is_none(state, indexf)) {
if(indexf->ops->call && indexf->ops->call != sol_f_not_impl) {
newls = sol_new_list(state);
sol_list_insert(state, newls, 0, indexf);
sol_list_append(state, newls, args);
res = indexf->ops->call(state, newls);
sol_obj_free(newls);
} else if(indexf->ops->index && indexf->ops->index != sol_f_not_impl) {
res = indexf->ops->index(state, args);
}
}
if(!res) res = sol_map_get(state, map, b);
sol_obj_free(indexf);
sol_obj_free(map);
sol_obj_free(b);
return res;
@ -496,6 +714,21 @@ sol_object_t *sol_f_map_index(sol_state_t *state, sol_object_t *args) {
sol_object_t *sol_f_map_setindex(sol_state_t *state, sol_object_t *args) {
sol_object_t *map = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
sol_object_t *val = sol_list_get_index(state, args, 2);
sol_object_t *setindexf = sol_map_get_name(state, map, "__setindex"), *newls;
if(!sol_is_none(state, setindexf)) {
if(setindexf->ops->call && setindexf->ops->call != sol_f_not_impl) {
newls = sol_new_list(state);
sol_list_insert(state, newls, 0, setindexf);
sol_list_append(state, newls, args);
sol_obj_free(setindexf->ops->call(state, newls));
sol_obj_free(newls);
return sol_incref(state->None);
} else if(setindexf->ops->setindex && setindexf->ops->setindex != sol_f_not_impl) {
setindexf->ops->setindex(state, args);
return sol_incref(state->None);
}
}
sol_obj_free(setindexf);
sol_map_set(state, map, b, val);
sol_obj_free(map);
sol_obj_free(b);
@ -503,6 +736,23 @@ sol_object_t *sol_f_map_setindex(sol_state_t *state, sol_object_t *args) {
return sol_incref(state->None);
}
sol_object_t *sol_f_map_call(sol_state_t *state, sol_object_t *args) {
sol_object_t *map = sol_list_get_index(state, args, 0), *fargs = sol_list_sublist(state, args, 1);
sol_object_t *callf = sol_map_get_name(state, map, "__call"), *res = NULL;
if(!sol_is_none(state, callf)) {
if(callf->ops->call) {
sol_list_insert(state, fargs, 0, callf);
sol_list_insert(state, fargs, 1, map);
res = callf->ops->call(state, fargs);
}
}
sol_obj_free(map);
sol_obj_free(fargs);
sol_obj_free(callf);
if(res) return res;
return sol_set_error_string(state, "Call map without call method");
}
sol_object_t *sol_f_map_len(sol_state_t *state, sol_object_t *args) {
sol_object_t *map = sol_list_get_index(state, args, 0);
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) {
return res;
}
sol_object_t *sol_f_map_iter(sol_state_t *state, sol_object_t *args) {
return sol_new_cfunc(state, sol_f_iter_map);
}
sol_object_t *sol_f_map_tostring(sol_state_t *state, sol_object_t *args) {
return sol_new_string(state, "<Map>");
}
sol_object_t *sol_f_func_index(sol_state_t *state, sol_object_t *args) {
sol_object_t *func = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *res;
res = sol_map_get(state, func->closure, key);
sol_obj_free(func);
sol_obj_free(key);
return res;
}
sol_object_t *sol_f_func_setindex(sol_state_t *state, sol_object_t *args) {
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);
sol_map_set(state, func->closure, key, val);
sol_obj_free(func);
sol_obj_free(key);
sol_obj_free(val);
return sol_incref(state->None);
}
sol_object_t *sol_f_func_tostring(sol_state_t *state, sol_object_t *args) {
return sol_new_string(state, "<Function>");
}

11
dsdebug.gdb

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

202
lex.yy.c

@ -368,8 +368,8 @@ static void yy_fatal_error (yyconst char msg[] );
*yy_cp = '\0'; \
(yy_c_buf_p) = yy_cp;
#define YY_NUM_RULES 58
#define YY_END_OF_BUFFER 59
#define YY_NUM_RULES 60
#define YY_END_OF_BUFFER 61
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@ -377,20 +377,20 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
static yyconst flex_int16_t yy_accept[109] =
static yyconst flex_int16_t yy_accept[111] =
{ 0,
0, 0, 59, 58, 57, 29, 58, 54, 23, 58,
48, 49, 20, 18, 53, 19, 50, 21, 2, 51,
52, 40, 30, 41, 55, 55, 46, 47, 25, 55,
55, 55, 55, 55, 55, 55, 55, 55, 44, 24,
45, 26, 57, 0, 3, 27, 36, 0, 4, 22,
33, 31, 0, 32, 34, 1, 2, 42, 39, 43,
55, 55, 38, 55, 55, 11, 55, 55, 55, 55,
5, 10, 55, 55, 55, 37, 28, 35, 0, 56,
1, 55, 55, 55, 55, 16, 9, 55, 55, 55,
55, 17, 55, 55, 7, 12, 55, 6, 55, 14,
55, 55, 8, 55, 13, 55, 15, 0
0, 0, 61, 60, 59, 29, 60, 56, 23, 60,
50, 51, 20, 18, 55, 19, 52, 21, 2, 53,
54, 40, 30, 41, 57, 57, 48, 49, 25, 57,
57, 57, 57, 57, 57, 57, 57, 57, 46, 24,
47, 26, 59, 0, 3, 27, 36, 0, 4, 22,
33, 31, 0, 32, 34, 1, 2, 45, 42, 39,
43, 44, 57, 57, 38, 57, 57, 11, 57, 57,
57, 57, 5, 10, 57, 57, 57, 37, 28, 35,
0, 58, 1, 57, 57, 57, 57, 16, 9, 57,
57, 57, 57, 17, 57, 57, 7, 12, 57, 6,
57, 14, 57, 57, 8, 57, 13, 57, 15, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
@ -434,84 +434,84 @@ static yyconst flex_int32_t yy_meta[49] =
2, 2, 2, 2, 1, 1, 1, 1
} ;
static yyconst flex_int16_t yy_base[113] =
static yyconst flex_int16_t yy_base[115] =
{ 0,
0, 0, 126, 127, 47, 127, 120, 127, 44, 116,
127, 127, 41, 102, 127, 39, 127, 101, 39, 127,
127, 100, 99, 98, 0, 79, 127, 127, 96, 76,
76, 75, 20, 16, 28, 81, 78, 77, 127, 42,
127, 127, 65, 105, 127, 127, 127, 101, 127, 87,
127, 127, 104, 127, 127, 89, 54, 127, 127, 127,
0, 67, 127, 72, 65, 0, 61, 70, 60, 61,
0, 0, 56, 65, 61, 127, 127, 127, 92, 127,
70, 54, 57, 42, 51, 0, 0, 52, 38, 42,
42, 0, 42, 42, 0, 0, 36, 0, 43, 0,
36, 35, 0, 29, 0, 38, 0, 127, 88, 90,
62, 92
0, 0, 128, 129, 47, 129, 122, 129, 44, 118,
129, 129, 41, 104, 129, 39, 129, 103, 39, 129,
129, 37, 102, 42, 0, 83, 129, 129, 100, 80,
80, 79, 29, 16, 35, 85, 82, 81, 129, 40,
129, 129, 67, 109, 129, 129, 129, 105, 129, 91,
129, 129, 108, 129, 129, 93, 57, 129, 129, 129,
129, 129, 0, 71, 129, 76, 69, 0, 65, 74,
64, 65, 0, 0, 60, 69, 65, 129, 129, 129,
96, 129, 81, 65, 68, 53, 62, 0, 0, 63,
42, 46, 46, 0, 46, 46, 0, 0, 40, 0,
47, 0, 40, 39, 0, 33, 0, 43, 0, 129,
86, 88, 69, 90
} ;
static yyconst flex_int16_t yy_def[113] =
static yyconst flex_int16_t yy_def[115] =
{ 0,
108, 1, 108, 108, 108, 108, 109, 108, 108, 110,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
108, 108, 108, 108, 111, 111, 108, 108, 108, 111,
111, 111, 111, 111, 111, 111, 111, 111, 108, 108,
108, 108, 108, 109, 108, 108, 108, 110, 108, 108,
108, 108, 112, 108, 108, 108, 108, 108, 108, 108,
111, 111, 108, 111, 111, 111, 111, 111, 111, 111,
111, 111, 111, 111, 111, 108, 108, 108, 112, 108,
108, 111, 111, 111, 111, 111, 111, 111, 111, 111,
111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
111, 111, 111, 111, 111, 111, 111, 0, 108, 108,
108, 108
110, 1, 110, 110, 110, 110, 111, 110, 110, 112,
110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 113, 113, 110, 110, 110, 113,
113, 113, 113, 113, 113, 113, 113, 113, 110, 110,
110, 110, 110, 111, 110, 110, 110, 112, 110, 110,
110, 110, 114, 110, 110, 110, 110, 110, 110, 110,
110, 110, 113, 113, 110, 113, 113, 113, 113, 113,
113, 113, 113, 113, 113, 113, 113, 110, 110, 110,
114, 110, 110, 113, 113, 113, 113, 113, 113, 113,
113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
113, 113, 113, 113, 113, 113, 113, 113, 113, 0,
110, 110, 110, 110
} ;
static yyconst flex_int16_t yy_nxt[176] =
static yyconst flex_int16_t yy_nxt[178] =
{ 0,
4, 5, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 25, 30, 31,
32, 33, 34, 25, 35, 25, 25, 25, 25, 36,
25, 37, 25, 38, 39, 40, 41, 42, 43, 43,
46, 50, 53, 56, 69, 57, 67, 68, 70, 54,
71, 51, 76, 61, 47, 72, 43, 43, 56, 107,
57, 106, 105, 104, 103, 102, 101, 100, 99, 98,
97, 96, 95, 94, 93, 92, 81, 77, 44, 44,
48, 48, 79, 79, 80, 91, 90, 89, 88, 87,
86, 85, 84, 83, 82, 81, 80, 78, 49, 45,
75, 74, 73, 66, 65, 64, 63, 62, 60, 59,
58, 55, 52, 49, 45, 108, 3, 108, 108, 108,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
108, 108, 108, 108, 108
46, 50, 53, 56, 71, 57, 58, 59, 72, 54,
78, 51, 61, 62, 47, 69, 70, 73, 43, 43,
63, 56, 74, 57, 109, 108, 107, 106, 105, 104,
103, 102, 101, 100, 99, 79, 44, 44, 48, 48,
81, 81, 98, 97, 96, 95, 94, 83, 82, 93,
92, 91, 90, 89, 88, 87, 86, 85, 84, 83,
82, 80, 49, 45, 77, 76, 75, 68, 67, 66,
65, 64, 60, 55, 52, 49, 45, 110, 3, 110,
110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110
} ;
static yyconst flex_int16_t yy_chk[176] =
static yyconst flex_int16_t yy_chk[178] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 5, 5,
9, 13, 16, 19, 34, 19, 33, 33, 34, 16,
35, 13, 40, 111, 9, 35, 43, 43, 57, 106,
57, 104, 102, 101, 99, 97, 94, 93, 91, 90,
89, 88, 85, 84, 83, 82, 81, 40, 109, 109,
110, 110, 112, 112, 79, 75, 74, 73, 70, 69,
68, 67, 65, 64, 62, 56, 53, 50, 48, 44,
38, 37, 36, 32, 31, 30, 29, 26, 24, 23,
22, 18, 14, 10, 7, 3, 108, 108, 108, 108,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
108, 108, 108, 108, 108
9, 13, 16, 19, 34, 19, 22, 22, 34, 16,
40, 13, 24, 24, 9, 33, 33, 35, 43, 43,
113, 57, 35, 57, 108, 106, 104, 103, 101, 99,
96, 95, 93, 92, 91, 40, 111, 111, 112, 112,
114, 114, 90, 87, 86, 85, 84, 83, 81, 77,
76, 75, 72, 71, 70, 69, 67, 66, 64, 56,
53, 50, 48, 44, 38, 37, 36, 32, 31, 30,
29, 26, 23, 18, 14, 10, 7, 3, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110
} ;
static yy_state_type yy_last_accepting_state;
@ -820,13 +820,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 109 )
if ( yy_current_state >= 111 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
while ( yy_base[yy_current_state] != 127 );
while ( yy_base[yy_current_state] != 129 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
@ -1070,81 +1070,91 @@ YY_RULE_SETUP
case 44:
YY_RULE_SETUP
#line 145 "tokenizer.lex"
{ return LBRACE; }
{ return RSHIFT; }
YY_BREAK
case 45:
YY_RULE_SETUP
#line 147 "tokenizer.lex"
{ return RBRACE; }
{ return LSHIFT; }
YY_BREAK
case 46:
YY_RULE_SETUP
#line 149 "tokenizer.lex"
{ return LBRACKET; }
{ return LBRACE; }
YY_BREAK
case 47:
YY_RULE_SETUP
#line 151 "tokenizer.lex"
{ return RBRACKET; }
{ return RBRACE; }
YY_BREAK
case 48:
YY_RULE_SETUP
#line 153 "tokenizer.lex"
{ return LPAREN; }
{ return LBRACKET; }
YY_BREAK
case 49:
YY_RULE_SETUP
#line 155 "tokenizer.lex"
{ return RPAREN; }
{ return RBRACKET; }
YY_BREAK
case 50:
YY_RULE_SETUP
#line 157 "tokenizer.lex"
{ return DOT; }
{ return LPAREN; }
YY_BREAK
case 51:
YY_RULE_SETUP
#line 159 "tokenizer.lex"
{ return COLON; }
{ return RPAREN; }
YY_BREAK
case 52:
YY_RULE_SETUP
#line 161 "tokenizer.lex"
{ return SEMICOLON; }
{ return DOT; }
YY_BREAK
case 53:
YY_RULE_SETUP
#line 163 "tokenizer.lex"
{ return COMMA; }
{ return COLON; }
YY_BREAK
case 54:
YY_RULE_SETUP
#line 165 "tokenizer.lex"
{ return POUND; }
{ return SEMICOLON; }
YY_BREAK
case 55:
YY_RULE_SETUP
#line 167 "tokenizer.lex"
{ yylval = strdup(yytext); return IDENT; }
{ return COMMA; }
YY_BREAK
case 56:
/* rule 56 can match eol */
YY_RULE_SETUP
#line 169 "tokenizer.lex"
/* Skip comments */
{ return POUND; }
YY_BREAK
case 57:
/* rule 57 can match eol */
YY_RULE_SETUP
#line 171 "tokenizer.lex"
/* Skip whitespace */
{ yylval = strdup(yytext); return IDENT; }
YY_BREAK
case 58:
/* rule 58 can match eol */
YY_RULE_SETUP
#line 173 "tokenizer.lex"
/* Skip comments */
YY_BREAK
case 59:
/* rule 59 can match eol */
YY_RULE_SETUP
#line 175 "tokenizer.lex"
/* Skip whitespace */
YY_BREAK
case 60:
YY_RULE_SETUP
#line 177 "tokenizer.lex"
ECHO;
YY_BREAK
#line 1148 "lex.yy.c"
#line 1158 "lex.yy.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@ -1436,7 +1446,7 @@ static int yy_get_next_buffer (void)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 109 )
if ( yy_current_state >= 111 )
yy_c = yy_meta[(unsigned int) yy_c];
}
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)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 109 )
if ( yy_current_state >= 111 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_is_jam = (yy_current_state == 108);
yy_is_jam = (yy_current_state == 110);
return yy_is_jam ? 0 : yy_current_state;
}
@ -2142,7 +2152,7 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
#line 173 "tokenizer.lex"
#line 177 "tokenizer.lex"

173
object.c

@ -3,12 +3,13 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
sol_object_t *sol_cast_int(sol_state_t *state, sol_object_t *obj) {
sol_object_t *res, *ls;
if(sol_is_int(obj)) return obj;
ls = sol_new_list(state);
sol_list_insert(state, &ls, 0, obj);
sol_list_insert(state, ls, 0, obj);
res = obj->ops->toint(state, ls);
sol_obj_free(ls);
sol_obj_free(obj);
@ -19,7 +20,7 @@ sol_object_t *sol_cast_float(sol_state_t *state, sol_object_t *obj) {
sol_object_t *res, *ls;
if(sol_is_float(obj)) return obj;
ls = sol_new_list(state);
sol_list_insert(state, &ls, 0, obj);
sol_list_insert(state, ls, 0, obj);
res = obj->ops->tofloat(state, ls);
sol_obj_free(ls);
sol_obj_free(obj);
@ -30,7 +31,7 @@ sol_object_t *sol_cast_string(sol_state_t *state, sol_object_t *obj) {
sol_object_t *res, *ls;
if(sol_is_string(obj)) return obj;
ls = sol_new_list(state);
sol_list_insert(state, &ls, 0, obj);
sol_list_insert(state, ls, 0, obj);
res = obj->ops->tostring(state, ls);
sol_obj_free(ls);
sol_obj_free(obj);
@ -67,8 +68,16 @@ void sol_init_object(sol_state_t *state, sol_object_t *obj) {
}
void sol_obj_free(sol_object_t *obj) {
if(!obj) {
printf("WARNING: Attempt to free NULL\n");
return;
}
if(sol_decref(obj) <= 0) {
sol_obj_release(obj);
if(obj->refcnt < 0) {
printf("WARNING: Encountered refcnt < 0!\nObject %p type %d ref %d\n", obj, obj->type, obj->refcnt);
} else {
sol_obj_release(obj);
}
}
}
@ -147,8 +156,8 @@ int sol_list_len(sol_state_t *state, sol_object_t *list) {
sol_obj_free(sol_set_error_string(state, "Compute length of non-list"));
return -1;
}
while(cur && cur->lvalue) {
i++;
while(cur) {
if(cur->lvalue) i++;
cur = cur->lnext;
}
return i;
@ -173,8 +182,8 @@ sol_object_t *sol_list_sublist(sol_state_t *state, sol_object_t *list, int idx)
if(cur->lnext) {
copy->lnext = sol_alloc_object(state);
copy = copy->lnext;
copy->type = SOL_LIST;
copy->ops = &(state->ListOps);
copy->type = SOL_LCELL;
copy->ops = &(state->LCellOps);
copy->lnext = NULL;
copy->lvalue = NULL;
}
@ -193,11 +202,12 @@ sol_object_t *sol_list_get_index(sol_state_t *state, sol_object_t *list, int idx
if(idx < 0) {
return sol_set_error_string(state, "Get negative index");
}
while(cur && cur->lvalue && i < idx) {
i++;
while(cur && i < idx) {
if(cur->lvalue) i++;
cur = cur->lnext;
}
if(cur && cur->lvalue) {
while(cur && !cur->lvalue) cur = cur->lnext;
if(cur) {
return sol_incref(cur->lvalue);
} else {
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
}
void sol_list_set_index(sol_state_t *state, sol_object_t *list, int idx, sol_object_t *obj) {
sol_object_t *cur = list;
sol_object_t *cur = list, *temp;
int i = 0;
if(!sol_is_list(list)) {
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
sol_obj_free(sol_set_error_string(state, "Set negative index"));
return;
}
while(cur && cur->lvalue && i < idx) {
i++;
while(cur && i < idx) {
if(cur->lvalue) i++;
cur = cur->lnext;
}
if(cur) {
sol_obj_free(cur->lvalue);
temp = cur->lvalue;
cur->lvalue = sol_incref(obj);
sol_obj_free(temp);
} else {
sol_obj_free(sol_set_error_string(state, "Set out-of-bounds index"));
return;
}
}
void sol_list_insert(sol_state_t *state, sol_object_t **list, int idx, sol_object_t *obj) {
sol_object_t *next = *list, *prev = NULL, *temp = sol_alloc_object(state);
void sol_list_insert(sol_state_t *state, sol_object_t *list, int idx, sol_object_t *obj) {
sol_object_t *next = list, *prev = NULL, *temp = sol_alloc_object(state);
int i = 0;
if(sol_has_error(state)) return;
if(!sol_is_list(*list)) {
if(!sol_is_list(list)) {
sol_obj_free(sol_set_error_string(state, "Insert into non-list"));
return;
}
@ -240,8 +251,8 @@ void sol_list_insert(sol_state_t *state, sol_object_t **list, int idx, sol_objec
sol_obj_free(sol_set_error_string(state, "Insert at negative index"));
return;
}
temp->type = SOL_LIST;
temp->ops = &(state->ListOps);
temp->type = SOL_LCELL;
temp->ops = &(state->LCellOps);
temp->lvalue = sol_incref(obj);
while(next && i < idx) {
if(next->lvalue) i++;
@ -249,12 +260,18 @@ void sol_list_insert(sol_state_t *state, sol_object_t **list, int idx, sol_objec
next = next->lnext;
}
if(next) {
temp->lnext = next;
if(prev) {
prev->lnext = temp;
} else {
*list = temp;
temp->lnext = next;
} else {
assert(next == list);
temp->lnext = sol_alloc_object(state);
temp->lnext->type = SOL_LCELL;
temp->lnext->ops = &(state->LCellOps);
temp->lnext->lvalue = list->lvalue;
temp->lnext->lnext = list->lnext;
list->lnext = temp;
list->lvalue = NULL;
}
} else {
if(prev) {
@ -267,10 +284,11 @@ void sol_list_insert(sol_state_t *state, sol_object_t **list, int idx, sol_objec
return;
}
}
assert(!sol_validate_list(state, list));
}
sol_object_t *sol_list_remove(sol_state_t *state, sol_object_t **list, int idx) {
sol_object_t *next = *list, *prev = NULL, *res, *temp;
sol_object_t *sol_list_remove(sol_state_t *state, sol_object_t *list, int idx) {
sol_object_t *next = list, *prev = NULL, *res, *temp;
int i = 0;
if(sol_has_error(state)) return sol_incref(state->None);
if(idx < 0) {
@ -285,13 +303,12 @@ sol_object_t *sol_list_remove(sol_state_t *state, sol_object_t **list, int idx)
if(prev) {
res = next->lvalue;
prev->lnext = next->lnext;
free(next);
sol_obj_free(next);
} else {
res = (*list)->lvalue;
temp = *list;
*list = (*list)->lnext;
free(temp);
res = list->lvalue;
list->lvalue = NULL;
}
assert(!sol_validate_list(state, list));
return res;
} else {
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) {
newls->lnext = sol_alloc_object(state);
if(sol_has_error(state)) return sol_incref(state->None);
newls = newls->lnext;
newls->type = SOL_LIST;
newls->ops = &(state->ListOps);
newls->type = SOL_LCELL;
newls->ops = &(state->LCellOps);
}
cur = cur->lnext;
}
@ -318,13 +335,17 @@ sol_object_t *sol_list_copy(sol_state_t *state, sol_object_t *list) {
void sol_list_append(sol_state_t *state, sol_object_t *dest, sol_object_t *src) {
sol_object_t *curd = dest, *curs = src;
while(curd->lnext) curd = curd->lnext;
while(curs && curs->lvalue) {
curd->lnext = sol_alloc_object(state);
if(sol_has_error(state)) return;
curd = curd->lnext;
curd->type = SOL_LIST;
curd->ops = &(state->ListOps);
curd->lvalue = sol_incref(curs->lvalue);
while(curs) {
if(curs->lvalue) {
curd->lvalue = sol_incref(curs->lvalue);
curd->lnext = sol_alloc_object(state);
if(sol_has_error(state)) return;
curd = curd->lnext;
curd->type = SOL_LCELL;
curd->ops = &(state->LCellOps);
curd->lnext = NULL;
curd->lvalue = NULL;
}
curs = curs->lnext;
}
}
@ -332,11 +353,16 @@ void sol_list_append(sol_state_t *state, sol_object_t *dest, sol_object_t *src)
sol_object_t *sol_f_list_free(sol_state_t *state, sol_object_t *list) {
sol_object_t *cur = list, *prev;
while(cur) {
if(cur->lvalue) sol_obj_free(cur->lvalue);
prev = cur;
cur = cur->lnext;
if(prev!=list) free(prev);
if(prev!=list) sol_obj_free(prev);
}
return list;
}
sol_object_t *sol_f_lcell_free(sol_state_t *state, sol_object_t *lcell) {
if(lcell->lvalue) sol_obj_free(lcell->lvalue);
return lcell;
}
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) {
while(cur) {
if(!sol_is_list(cur)) {
snprintf(msg, 128, "Node at index %d not a list node", i);
//sol_obj_free(sol_set_error_string(state, msg));
sol_obj_free(sol_set_error_string(state, msg));
return 1;
}
if(cur->lnext && !cur->lvalue) {
/*if(cur->lnext && !cur->lvalue) {
snprintf(msg, 128, "Node at index %d has a next node but NULL value", i);
//sol_obj_free(sol_set_error_string(state, msg));
sol_obj_free(sol_set_error_string(state, msg));
return 1;
}
}*/
cur = cur->lnext;
i++;
}
if(sol_test_cycle(state, list)) {
snprintf(msg, 128, "Cycle detected");
//sol_obj_free(sol_set_error_string(state, msg));
sol_obj_free(sol_set_error_string(state, msg));
return 1;
}
return 0;
@ -406,12 +432,12 @@ int sol_map_len(sol_state_t *state, sol_object_t *map) {
sol_object_t *sol_map_submap(sol_state_t *state, sol_object_t *map, sol_object_t *key) {
sol_object_t *list = sol_new_list(state), *res = NULL, *cur = map, *cmp;
sol_list_insert(state, &list, 0, key);
sol_list_insert(state, list, 0, key);
while(cur) {
if(cur->mkey) {
sol_list_insert(state, &list, 1, cur->mkey);
sol_list_insert(state, list, 1, cur->mkey);
cmp = sol_cast_int(state, key->ops->cmp(state, list));
sol_list_remove(state, &list, 1);
sol_list_remove(state, list, 1);
if(cmp->ival == 0) {
res = cur;
break;
@ -437,23 +463,29 @@ sol_object_t *sol_map_get(sol_state_t *state, sol_object_t *map, sol_object_t *k
}
}
sol_object_t *sol_map_get_name(sol_state_t *state, sol_object_t *map, char *name) {
sol_object_t *key = sol_new_string(state, name);
sol_object_t *res = sol_map_get(state, map, key);
sol_obj_free(key);
return res;
}
void sol_map_set(sol_state_t *state, sol_object_t *map, sol_object_t *key, sol_object_t *val) {
sol_object_t *cur = map, *prev = NULL, *list = sol_new_list(state), *cmp;
sol_list_insert(state, &list, 0, key);
sol_list_insert(state, list, 0, key);
while(cur) {
if(cur->mkey) {
sol_list_insert(state, &list, 1, cur->mkey);
sol_list_insert(state, list, 1, cur->mkey);
cmp = sol_cast_int(state, key->ops->cmp(state, list));
sol_list_remove(state, &list, 1);
sol_list_remove(state, list, 1);
if(cmp->ival == 0) {
sol_obj_free(cur->mval);
if(sol_is_none(state, val)) {
if(prev) {
prev->mnext = cur->mnext;
sol_obj_free(cur->mkey);
free(cur);
sol_obj_free(cur);
} else {
sol_obj_free(cur->mkey);
sol_obj_free(cur->mval);
cur->mkey = NULL;
cur->mval = NULL;
}
@ -470,30 +502,35 @@ void sol_map_set(sol_state_t *state, sol_object_t *map, sol_object_t *key, sol_o
prev->mnext = sol_alloc_object(state);
if(sol_has_error(state)) return;
cur = prev->mnext;
cur->type = SOL_MAP;
cur->ops = &(state->MapOps);
cur->type = SOL_MCELL;
cur->ops = &(state->MCellOps);
cur->mkey = sol_incref(key);
cur->mval = sol_incref(val);
cur->mnext = NULL;
}
void sol_map_set_name(sol_state_t *state, sol_object_t *map, char *name, sol_object_t *val) {
sol_object_t *key = sol_new_string(state, name);
sol_map_set(state, map, key, val);
sol_obj_free(key);
}
void sol_map_set_existing(sol_state_t *state, sol_object_t *map, sol_object_t *key, sol_object_t *val) {
sol_object_t *cur = map, *prev = NULL, *list = sol_new_list(state), *cmp;
sol_list_insert(state, &list, 0, key);
sol_list_insert(state, list, 0, key);
while(cur) {
if(cur->mkey) {
sol_list_insert(state, &list, 1, cur->mkey);
sol_list_insert(state, list, 1, cur->mkey);
cmp = sol_cast_int(state, key->ops->cmp(state, list));
sol_obj_free(sol_list_remove(state, &list, 1));
sol_obj_free(sol_list_remove(state, list, 1));
if(cmp->ival == 0) {
sol_obj_free(cur->mval);
if(sol_is_none(state, val)) {
if(prev) {
prev->mnext = cur->mnext;
sol_obj_free(cur->mkey);
free(cur);
sol_obj_free(cur);
} else {
sol_obj_free(cur->mkey);
sol_obj_free(cur->mval);
cur->mkey = NULL;
cur->mval = NULL;
}
@ -516,8 +553,8 @@ sol_object_t *sol_map_copy(sol_state_t *state, sol_object_t *map) {
newcur->mval = sol_incref(cur->mval);
newcur->mnext = sol_alloc_object(state);
newcur = newcur->mnext;
newcur->type = SOL_MAP;
newcur->ops = &(state->MapOps);
newcur->type = SOL_MCELL;
newcur->ops = &(state->MCellOps);
newcur->mkey = NULL;
newcur->mval = NULL;
newcur->mnext = NULL;
@ -561,6 +598,12 @@ sol_object_t *sol_f_map_free(sol_state_t *state, sol_object_t *map) {
return map;
}
sol_object_t *sol_f_mcell_free(sol_state_t *state, sol_object_t *mcell) {
if(mcell->mkey) sol_obj_free(mcell->mkey);
if(mcell->mval) sol_obj_free(mcell->mval);
return mcell;
}
int sol_validate_map(sol_state_t *state, sol_object_t *map) {
sol_object_t *cur = map;
int i = 0;

6507
parser.output
File diff suppressed because it is too large
View File

748
parser.tab.c
File diff suppressed because it is too large
View File

24
parser.tab.h

@ -89,17 +89,19 @@ extern int yydebug;
GREATER = 298,
LESSEQ = 299,
GREATEREQ = 300,
LBRACE = 301,
RBRACE = 302,
LPAREN = 303,
RPAREN = 304,
LBRACKET = 305,
RBRACKET = 306,
DOT = 307,
COLON = 308,
SEMICOLON = 309,
COMMA = 310,
POUND = 311
RSHIFT = 301,
LSHIFT = 302,
LBRACE = 303,
RBRACE = 304,
LPAREN = 305,
RPAREN = 306,
LBRACKET = 307,
RBRACKET = 308,
DOT = 309,
COLON = 310,
SEMICOLON = 311,
COMMA = 312,
POUND = 313
};
#endif

29
parser.y

@ -18,7 +18,7 @@
%token INT FLOAT STRING
%token PLUS MINUS STAR SLASH DSTAR BAND BOR BXOR BNOT LAND LOR LNOT
%token ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNSTAR ASSIGNSLASH ASSIGNDSTAR ASSIGNBAND ASSIGNBOR ASSIGNBXOR
%token EQUAL LESS GREATER LESSEQ GREATEREQ
%token EQUAL LESS GREATER LESSEQ GREATEREQ RSHIFT LSHIFT
%token LBRACE RBRACE LPAREN RPAREN LBRACKET RBRACKET DOT COLON SEMICOLON COMMA POUND
%parse-param {stmt_node **program}
@ -36,7 +36,7 @@ stmt:
| 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; }
| 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; }
| 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; }
| 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; }
| 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; }
| RETURN expr { $$ = NEW_ST(); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = $2; }
| RETURN { $$ = NEW_ST(); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = NULL; }
| BREAK { $$ = NEW_ST(); AS_ST($$)->type = ST_BREAK; }
@ -282,9 +282,11 @@ power_expr:
;
binary_expr:
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; }
| 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; }
| 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; }
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; }
| 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; }
| 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; }
| 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; }
| 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; }
| ubinary_expr { $$ = $1; }
;
@ -300,6 +302,23 @@ 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 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 = $1;
AS_EX($$)->call->args->next = $5;
}
| funcdecl_expr { $$ = $1; }
;

86
runtime.c

@ -190,7 +190,7 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
res = sol_new_list(state);
cure = expr->listgen->list;
while(cure) {
if(cure->expr) sol_list_insert(state, &res, sol_list_len(state, res), sol_eval(state, cure->expr));
if(cure->expr) sol_list_insert(state, res, sol_list_len(state, res), sol_eval(state, cure->expr));
cure = cure->next;
}
return res;
@ -210,8 +210,8 @@ sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
list = sol_new_list(state);
left = sol_eval(state, expr->binop->left);
right = sol_eval(state, expr->binop->right);
sol_list_insert(state, &list, 0, left);
sol_list_insert(state, &list, 1, right);
sol_list_insert(state, list, 0, left);
sol_list_insert(state, list, 1, right);