Преглед изворни кода

Sol Part 38: RELEASE THE CLOWNS

master
Graham Northup пре 6 година
родитељ
комит
62dc3621d8
  1. 12
      Makefile
  2. 17
      ast.h
  3. 175
      builtins.c
  4. 14
      gc.c
  5. 20
      gcstat.py
  6. 27
      object.c
  7. 2
      old-sol-gdb.py
  8. 56
      parser.tab.c
  9. 56
      parser.y
  10. 400
      runtime.c
  11. 20
      sol.h
  12. 32
      state.c
  13. 4
      test.sol

12
Makefile

@ -1,4 +1,4 @@
CFLAGS= -g -DDEBUG_CC
CFLAGS= -g
OBJ= lex.yy.o parser.tab.o dsl/seq.o dsl/list.o dsl/array.o dsl/generic.o astprint.o runtime.o gc.o object.o state.o builtins.o solrun.o
all: $(OBJ)
@ -8,5 +8,15 @@ all: $(OBJ)
%.o: %.c
gcc -c -o $@ $? $(CFLAGS)
%.tab.c %.tab.h: %.y
bison -rall -fall -d $?
lex.yy.c: tokenizer.lex parser.tab.h
flex $<
clean:
rm -f *.o dsl/*.o sol
docs: Doxyfile
doxygen Doxyfile
sphinx-build -b html . ./_build

17
ast.h

@ -171,7 +171,7 @@ typedef struct tag_stmt_node {
nd->binop->left = NEW_EX(); \
nd->binop->left->type = EX_REF; \
nd->binop->left->ref = NEW(ref_node); \
nd->binop->left->ref->ident = name; \
nd->binop->left->ref->ident = strdup(name); \
nd->binop->right = val
#define MAKE_IDX_BINOP(nd, tp, obj, idx, val) nd = NEW_EX(); \
nd->type = EX_BINOP; \
@ -180,8 +180,8 @@ typedef struct tag_stmt_node {
nd->binop->left = NEW_EX(); \
nd->binop->left->type = EX_INDEX; \
nd->binop->left->index = NEW(index_node); \
nd->binop->left->index->expr = obj; \
nd->binop->left->index->index = idx; \
nd->binop->left->index->expr = ex_copy(obj); \
nd->binop->left->index->index = ex_copy(idx); \
nd->binop->right = val
#define BOOL_TO_INT(cond) ((cond)?1:0)
#define CALL_METHOD(state, obj, meth, args) ({\
@ -205,8 +205,19 @@ stmt_node *sol_compile_file(FILE *);
expr_node *sol_comp_as_expr(stmt_node *);
void sol_compile_free(stmt_node *);
stmt_node *st_copy(stmt_node *);
expr_node *ex_copy(expr_node *);
stmtlist_node *stl_copy(stmtlist_node *);
exprlist_node *exl_copy(exprlist_node *);
assoclist_node *asl_copy(assoclist_node *);
identlist_node *idl_copy(identlist_node *);
void st_free(stmt_node *);
void ex_free(expr_node *);
void stl_free(stmtlist_node *);
void exl_free(exprlist_node *);
void asl_free(assoclist_node *);
void idl_free(identlist_node *);
void st_print(sol_state_t *, stmt_node *);
void ex_print(sol_state_t *, expr_node *);

175
builtins.c

@ -690,11 +690,15 @@ sol_object_t *sol_f_int_bnot(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_int_cmp(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bint = sol_cast_int(state, b);
sol_object_t *res = sol_new_int(state, a->ival == bint->ival ? 0 : (a->ival < bint->ival ? -1 : 1));
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
sol_object_t *res;
if(sol_is_int(b)) {
res = sol_new_int(state, a->ival == b->ival ? 0 : (a->ival < b->ival ? -1 : 1));
} else {
res = sol_new_int(state, 1);
}
sol_obj_free(a);
sol_obj_free(b);
sol_obj_free(bint);
return res;
}
@ -779,11 +783,15 @@ sol_object_t *sol_f_float_pow(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_float_cmp(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bflt = sol_cast_float(state, b);
sol_object_t *res = sol_new_int(state, a->fval==bflt->fval? 0 : (a->fval<bflt->fval? -1 : 1));
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
sol_object_t *res;
if(sol_is_float(b)) {
res = sol_new_int(state, a->fval==b->fval? 0 : (a->fval<b->fval? -1 : 1));
} else {
res = sol_new_int(state, 1);
}
sol_obj_free(a);
sol_obj_free(b);
sol_obj_free(bflt);
return res;
}
@ -841,11 +849,15 @@ sol_object_t *sol_f_str_mul(sol_state_t *state, sol_object_t *args) {
}
sol_object_t *sol_f_str_cmp(sol_state_t *state, sol_object_t *args) {
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *bstr = sol_cast_string(state, b);
sol_object_t *res = sol_new_int(state, strcmp(a->str, bstr->str));
sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
sol_object_t *res;
if(sol_is_string(b)) {
res = sol_new_int(state, strcmp(a->str, b->str));
} else {
res = sol_new_int(state, 1);
}
sol_obj_free(a);
sol_obj_free(b);
sol_obj_free(bstr);
return res;
}
@ -1388,7 +1400,7 @@ sol_object_t *sol_f_func_index(sol_state_t *state, sol_object_t *args) {
} else if(sol_string_eq(state, key, "udata")) {
res = sol_incref(func->udata);
} else if(sol_string_eq(state, key, "stmt")) {
res = sol_new_stmtnode(state, (stmt_node *) func->func);
res = sol_new_stmtnode(state, st_copy((stmt_node *) func->func));
} else if(sol_string_eq(state, key, "args")) {
res = sol_new_list(state);
curi = func->args;
@ -1406,7 +1418,9 @@ sol_object_t *sol_f_func_index(sol_state_t *state, sol_object_t *args) {
}
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), *temp;
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), *temp, *str;
size_t i, len;
identlist_node *cur, *prev;
if(sol_string_eq(state, key, "name") && sol_is_string(val)) {
free(func->fname);
func->fname = strdup(val->str);
@ -1419,7 +1433,27 @@ sol_object_t *sol_f_func_setindex(sol_state_t *state, sol_object_t *args) {
func->udata = sol_incref(val);
sol_obj_free(temp);
} else if(sol_string_eq(state, key, "stmt") && sol_is_aststmt(val)) {
func->func = val->node;
st_free(func->func);
func->func = st_copy(val->node);
} else if(sol_string_eq(state, key, "args") && sol_is_list(val)) {
idl_free(func->args);
func->args = NEW(identlist_node);
cur = func->args;
prev = cur;
len = sol_list_len(state, val);
for(i = 0; i < len; i++ ) {
temp = sol_list_get_index(state, val, i);
str = sol_cast_string(state, temp);
cur->ident = strdup(str->str);
sol_obj_free(temp);
sol_obj_free(str);
prev = cur;
cur->next = NEW(identlist_node);
cur = cur->next;
}
prev->next = NULL;
if(cur == func->args) func->args = NULL;
free(cur);
} else {
sol_map_set(state, func->udata, key, val);
}
@ -1503,25 +1537,25 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
switch(stmt->type) {
case ST_EXPR:
if(sol_string_eq(state, str, "expr")) {
res = sol_new_exprnode(state, stmt->expr);
res = sol_new_exprnode(state, ex_copy(stmt->expr));
}
break;
case ST_IFELSE:
if(sol_string_eq(state, str, "cond")) {
res = sol_new_exprnode(state, stmt->ifelse->cond);
res = sol_new_exprnode(state, ex_copy(stmt->ifelse->cond));
} else if(sol_string_eq(state, str, "iftrue")) {
res = sol_new_stmtnode(state, stmt->ifelse->iftrue);
res = sol_new_stmtnode(state, st_copy(stmt->ifelse->iftrue));
} else if(sol_string_eq(state, str, "iffalse")) {
res = sol_new_stmtnode(state, stmt->ifelse->iffalse);
res = sol_new_stmtnode(state, st_copy(stmt->ifelse->iffalse));
}
break;
case ST_LOOP:
if(sol_string_eq(state, str, "cond")) {
res = sol_new_exprnode(state, stmt->loop->cond);
res = sol_new_exprnode(state, ex_copy(stmt->loop->cond));
} else if(sol_string_eq(state, str, "loop")) {
res = sol_new_stmtnode(state, stmt->loop->loop);
res = sol_new_stmtnode(state, st_copy(stmt->loop->loop));
}
break;
@ -1529,9 +1563,9 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
if(sol_string_eq(state, str, "var")) {
res = sol_new_string(state, stmt->iter->var);
} else if(sol_string_eq(state, str, "iter")) {
res = sol_new_exprnode(state, stmt->iter->iter);
res = sol_new_exprnode(state, ex_copy(stmt->iter->iter));
} else if(sol_string_eq(state, str, "loop")) {
res = sol_new_stmtnode(state, stmt->iter->loop);
res = sol_new_stmtnode(state, st_copy(stmt->iter->loop));
}
break;
@ -1540,7 +1574,7 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
res = sol_new_list(state);
curs = stmt->stmtlist;
while(curs) {
sol_list_insert(state, res, i++, sol_new_stmtnode(state, curs->stmt));
sol_list_insert(state, res, i++, sol_new_stmtnode(state, st_copy(curs->stmt)));
curs = curs->next;
}
}
@ -1548,7 +1582,7 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
case ST_RET:
if(sol_string_eq(state, str, "ret")) {
res = sol_new_exprnode(state, stmt->ret->ret);
res = sol_new_exprnode(state, ex_copy(stmt->ret->ret));
}
break;
}
@ -1579,7 +1613,7 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
res = sol_new_list(state);
cure = expr->listgen->list;
while(cure) {
sol_list_insert(state, res, i++, sol_new_exprnode(state, cure->expr));
sol_list_insert(state, res, i++, sol_new_exprnode(state, ex_copy(cure->expr)));
cure = cure->next;
}
}
@ -1591,8 +1625,8 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
cura = expr->mapgen->map;
while(cura) {
pair = sol_new_list(state);
sol_list_insert(state, pair, 0, sol_new_exprnode(state, cura->item->key));
sol_list_insert(state, pair, 1, sol_new_exprnode(state, cura->item->value));
sol_list_insert(state, pair, 0, sol_new_exprnode(state, ex_copy(cura->item->key)));
sol_list_insert(state, pair, 1, sol_new_exprnode(state, ex_copy(cura->item->value)));
sol_list_insert(state, res, i++, pair);
sol_obj_free(pair);
}
@ -1603,9 +1637,9 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
if(sol_string_eq(state, str, "binoptype")) {
res = sol_new_int(state, expr->binop->type);
} else if(sol_string_eq(state, str, "left")) {
res = sol_new_exprnode(state, expr->binop->left);
res = sol_new_exprnode(state, ex_copy(expr->binop->left));
} else if(sol_string_eq(state, str, "right")) {
res = sol_new_exprnode(state, expr->binop->right);
res = sol_new_exprnode(state, ex_copy(expr->binop->right));
}
break;
@ -1613,25 +1647,25 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
if(sol_string_eq(state, str, "unoptype")) {
res = sol_new_int(state, expr->unop->type);
} else if(sol_string_eq(state, str, "expr")) {
res = sol_new_exprnode(state, expr->unop->expr);
res = sol_new_exprnode(state, ex_copy(expr->unop->expr));
}
break;
case EX_INDEX:
if(sol_string_eq(state, str, "expr")) {
res = sol_new_exprnode(state, expr->index->expr);
res = sol_new_exprnode(state, ex_copy(expr->index->expr));
} else if(sol_string_eq(state, str, "index")) {
res = sol_new_exprnode(state, expr->index->index);
res = sol_new_exprnode(state, ex_copy(expr->index->index));
}
break;
case EX_SETINDEX:
if(sol_string_eq(state, str, "expr")) {
res = sol_new_exprnode(state, expr->setindex->expr);
res = sol_new_exprnode(state, ex_copy(expr->setindex->expr));
} else if(sol_string_eq(state, str, "index")) {
res = sol_new_exprnode(state, expr->setindex->index);
res = sol_new_exprnode(state, ex_copy(expr->setindex->index));
} else if(sol_string_eq(state, str, "value")) {
res = sol_new_exprnode(state, expr->setindex->value);
res = sol_new_exprnode(state, ex_copy(expr->setindex->value));
}
break;
@ -1639,7 +1673,7 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
if(sol_string_eq(state, str, "ident")) {
res = sol_new_string(state, expr->assign->ident);
} else if(sol_string_eq(state, str, "value")) {
res = sol_new_exprnode(state, expr->assign->value);
res = sol_new_exprnode(state, ex_copy(expr->assign->value));
}
break;
@ -1651,12 +1685,12 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
case EX_CALL:
if(sol_string_eq(state, str, "expr")) {
res = sol_new_exprnode(state, expr->call->expr);
res = sol_new_exprnode(state, ex_copy(expr->call->expr));
} else if(sol_string_eq(state, str, "args")) {
res = sol_new_list(state);
cure = expr->call->args;
while(cure) {
sol_list_insert(state, res, i++, sol_new_exprnode(state, cure->expr));
sol_list_insert(state, res, i++, sol_new_exprnode(state, ex_copy(cure->expr)));
cure = cure->next;
}
}
@ -1673,7 +1707,7 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
curi = curi->next;
}
} else if(sol_string_eq(state, str, "body")) {
res = sol_new_stmtnode(state, expr->funcdecl->body);
res = sol_new_stmtnode(state, st_copy(expr->funcdecl->body));
}
break;
}
@ -1725,25 +1759,31 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
switch(stmt->type) {
case ST_EXPR:
if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
stmt->expr = val->node;
ex_free(stmt->expr);
stmt->expr = ex_copy(val->node);
}
break;
case ST_IFELSE:
if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
stmt->ifelse->cond = val->node;
ex_free(stmt->ifelse->cond);
stmt->ifelse->cond = ex_copy(val->node);
} else if(sol_string_eq(state, str, "iftrue") && sol_is_aststmt(val)) {
stmt->ifelse->iftrue = val->node;
st_free(stmt->ifelse->iftrue);
stmt->ifelse->iftrue = st_copy(val->node);
} else if(sol_string_eq(state, str, "iffalse") && sol_is_aststmt(val)) {
stmt->ifelse->iffalse = val->node;
st_free(stmt->ifelse->iffalse);
stmt->ifelse->iffalse = st_copy(val->node);
}
break;
case ST_LOOP:
if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
stmt->loop->cond = val->node;
ex_free(stmt->loop->cond);
stmt->loop->cond = ex_copy(val->node);
} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
stmt->loop->loop = val->node;
st_free(stmt->loop->loop);
stmt->loop->loop = st_copy(val->node);
}
break;
@ -1753,21 +1793,24 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
stmt->iter->var = strdup(sval->str);
sol_obj_free(sval);
} else if(sol_string_eq(state, str, "iter") && sol_is_astexpr(val)) {
stmt->iter->iter = val->node;
ex_free(stmt->iter->iter);
stmt->iter->iter = ex_copy(val->node);
} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
stmt->iter->loop = val->node;
st_free(stmt->iter->loop);
stmt->iter->loop = st_copy(val->node);
}
break;
case ST_LIST:
if(sol_string_eq(state, str, "stmtlist") && sol_is_list(val)) {
stl_free(stmt->stmtlist);
len = sol_list_len(state, val);
if(len > 0) {
curs = malloc(sizeof(stmtlist_node));
stmt->stmtlist = curs;
for(i = 0; i < len; i++) {
if(sol_is_aststmt(sol_list_get_index(state, val, i))) {
curs->stmt = sol_list_get_index(state, val, i)->node;
curs->stmt = st_copy(sol_list_get_index(state, val, i)->node);
prevs = curs;
curs = malloc(sizeof(stmtlist_node));
prevs->next = curs;
@ -1788,7 +1831,8 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
case ST_RET:
if(sol_string_eq(state, str, "ret") && sol_is_astexpr(val)) {
stmt->ret->ret = val->node;
ex_free(stmt->ret->ret);
stmt->ret->ret = ex_copy(val->node);
}
break;
}
@ -1833,6 +1877,7 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
case EX_LISTGEN:
if(sol_string_eq(state, str, "list") && sol_is_list(val)) {
exl_free(expr->listgen->list);
len = sol_list_len(state, val);
if(len > 0) {
cure = malloc(sizeof(exprlist_node));
@ -1860,6 +1905,7 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
case EX_MAPGEN:
if(sol_string_eq(state, str, "map") && sol_is_list(val)) {
asl_free(expr->mapgen->map);
len = sol_list_len(state, val);
if(len > 0) {
cura = malloc(sizeof(assoclist_node));
@ -1896,9 +1942,11 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
expr->binop->type = ival->ival;
sol_obj_free(ival);
} else if(sol_string_eq(state, str, "left") && sol_is_astexpr(val)) {
expr->binop->left = val->node;
ex_free(expr->binop->left);
expr->binop->left = ex_copy(val->node);
} else if(sol_string_eq(state, str, "right") && sol_is_astexpr(val)) {
expr->binop->right = val->node;
ex_free(expr->binop->right);
expr->binop->right = ex_copy(val->node);
}
break;
@ -1908,25 +1956,31 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
expr->unop->type = ival->ival;
sol_obj_free(ival);
} else if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
expr->unop->expr = val->node;
ex_free(expr->unop->expr);
expr->unop->expr = ex_copy(val->node);
}
break;
case EX_INDEX:
if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
expr->index->expr = val->node;
ex_free(expr->index->expr);
expr->index->expr = ex_copy(val->node);
} else if(sol_string_eq(state, str, "index") && sol_is_astexpr(val)) {
expr->index->index = val->node;
ex_free(expr->index->index);
expr->index->index = ex_copy(val->node);
}
break;
case EX_SETINDEX:
if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
expr->setindex->expr = val->node;
ex_free(expr->setindex->expr);
expr->setindex->expr = ex_copy(val->node);
} else if(sol_string_eq(state, str, "index") && sol_is_astexpr(val)) {
expr->setindex->index = val->node;
ex_free(expr->setindex->index);
expr->setindex->index = ex_copy(val->node);
} else if(sol_string_eq(state, str, "value") && sol_is_astexpr(val)) {
expr->setindex->value = val->node;
ex_free(expr->setindex->value);
expr->setindex->value = ex_copy(val->node);
}
break;
@ -1936,7 +1990,8 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
expr->assign->ident = strdup(sval->str);
sol_obj_free(sval);
} else if(sol_string_eq(state, str, "value") && sol_is_astexpr(val)) {
expr->assign->value = val->node;
ex_free(expr->assign->value);
expr->assign->value = ex_copy(val->node);
}
break;
@ -1950,8 +2005,10 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
case EX_CALL:
if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
expr->call->expr = val->node;
ex_free(expr->call->expr);
expr->call->expr = ex_copy(val->node);
} else if(sol_string_eq(state, str, "args") && sol_is_list(val)) {
exl_free(expr->call->args);
len = sol_list_len(state, val);
if(len > 0) {
cure = malloc(sizeof(exprlist_node));
@ -1983,6 +2040,7 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
expr->funcdecl->name = strdup(sval->str);
sol_obj_free(sval);
} else if(sol_string_eq(state, str, "args") && sol_is_list(val)) {
idl_free(expr->funcdecl->args);
len = sol_list_len(state, val);
if(len > 0) {
curi = malloc(sizeof(identlist_node));
@ -2006,7 +2064,8 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
expr->funcdecl->args = NULL;
}
} else if(sol_string_eq(state, str, "body") && sol_is_aststmt(val)) {
expr->funcdecl->body = val->node;
st_free(expr->funcdecl->body);
expr->funcdecl->body = st_copy(val->node);
}
break;
}

14
gc.c

@ -73,35 +73,35 @@ void sol_mm_finalize(sol_state_t *state) {
}
sol_object_t *_int_sol_alloc_object(const char *func, sol_state_t *state) {
fprintf(gclog, "%s\t%s\tALLOC\n", prtime(), func);
fprintf(gclog, "%s\tA\n", func);
return _sol_gc_alloc_object(state);
}
sol_object_t *_int_sol_incref(const char *func, sol_object_t *obj) {
int oldref = obj->refcnt++;
fprintf(gclog, "%s\t%s\tINCREF\t%s\t%p\t%d\t->\t%d\n", prtime(), func, obj->ops->tname, obj, oldref, obj->refcnt);
fprintf(gclog, "%s\tI\t%s\t%p\t%d\t->\t%d\n", func, obj->ops->tname, obj, oldref, obj->refcnt);
return obj;
}
void _int_sol_obj_free(const char *func, sol_object_t *obj) {
fprintf(gclog, "%s\t%s\tDECREF\t%s\t%p\t%d\t->\t%d\n", prtime(), func, obj->ops->tname, obj, obj->refcnt, obj->refcnt - 1);
fprintf(gclog, "%s\tD\t%s\t%p\t%d\t->\t%d\n", func, obj->ops->tname, obj, obj->refcnt, obj->refcnt - 1);
_sol_gc_obj_free(obj);
}
void sol_obj_release(sol_object_t *obj) {
fprintf(gclog, "%s\t\tFREE\t%s\t%p\n", prtime(), obj->ops->tname, obj);
fprintf(gclog, "\tF\t%s\t%p\n", obj->ops->tname, obj);
if(obj->ops->free) obj->ops->free(NULL, obj);
free(obj);
}
sol_object_t *_sol_gc_dsl_copier(sol_object_t *obj) {
fprintf(gclog, "%s\t<dsl>\tINCREF\t%s\t%p\t%d\t->\t%d\n", prtime(), obj->ops->tname, obj, obj->refcnt, ++obj->refcnt);
fprintf(gclog, "<dsl>\tI\t%s\t%p\t%d\t->\t%d\n", obj->ops->tname, obj, obj->refcnt, ++obj->refcnt);
return obj;
}
void _sol_gc_dsl_destructor(sol_object_t *obj) {
fprintf(gclog, "%s\t<dsl>\tDECREF\t%s\t%p\t%d\t->\t%d\n", prtime(), obj->ops->tname, obj, obj->refcnt, obj->refcnt - 1);
fprintf(gclog, "<dsl>\tD\t%s\t%p\t%d\t->\t%d\n", obj->ops->tname, obj, obj->refcnt, obj->refcnt - 1);
_sol_gc_obj_free(obj);
}
@ -125,4 +125,4 @@ void sol_obj_release(sol_object_t *obj) {
void sol_mm_initialize(sol_state_t *state) {}
void sol_mm_finalize(sol_state_t *state) {}
#endif
#endif

20
gcstat.py

@ -18,16 +18,16 @@ for line in f:
if line[0] == '=':
continue
parts = line.split('\t')
if parts[2] == 'INCREF':
incs[parts[1]] += 1
refs[parts[4]] += 1
types[parts[4]] = parts[3]
seenrefs[parts[4]] = parts[7]
elif parts[2] == 'DECREF':
decs[parts[1]] += 1
refs[parts[4]] -= 1
types[parts[4]] = parts[3]
seenrefs[parts[4]] = parts[7]
if parts[1] == 'I':
incs[parts[0]] += 1
refs[parts[3]] += 1
types[parts[3]] = parts[2]
seenrefs[parts[3]] = parts[6]
elif parts[1] == 'D':
decs[parts[0]] += 1
refs[parts[3]] -= 1
types[parts[3]] = parts[2]
seenrefs[parts[3]] = parts[6]
incpairs = incs.items()
decpairs = decs.items()

27
object.c

@ -14,7 +14,7 @@ sol_object_t *sol_cast_int(sol_state_t *state, sol_object_t *obj) {
}
ls = sol_new_list(state);
sol_list_insert(state, ls, 0, obj);
res = obj->ops->toint(state, ls);
res = CALL_METHOD(state, obj, toint, ls);
sol_obj_free(ls);
return res;
}
@ -26,7 +26,7 @@ sol_object_t *sol_cast_float(sol_state_t *state, sol_object_t *obj) {
}
ls = sol_new_list(state);
sol_list_insert(state, ls, 0, obj);
res = obj->ops->tofloat(state, ls);
res = CALL_METHOD(state, obj, tofloat, ls);
sol_obj_free(ls);
return res;
}
@ -38,7 +38,7 @@ sol_object_t *sol_cast_string(sol_state_t *state, sol_object_t *obj) {
}
ls = sol_new_list(state);
sol_list_insert(state, ls, 0, obj);
res = obj->ops->tostring(state, ls);
res = CALL_METHOD(state, obj, tostring, ls);
sol_obj_free(ls);
return res;
}
@ -46,7 +46,7 @@ sol_object_t *sol_cast_string(sol_state_t *state, sol_object_t *obj) {
sol_object_t *sol_cast_repr(sol_state_t *state, sol_object_t *obj) {
sol_object_t *res, *ls = sol_new_list(state);
sol_list_insert(state, ls, 0, obj);
res = obj->ops->repr(state, ls);
res = CALL_METHOD(state, obj, repr, ls);
sol_obj_free(ls);
return res;
}
@ -322,11 +322,16 @@ sol_object_t *sol_map_mcell(sol_state_t *state, sol_object_t *map, sol_object_t
sol_obj_free(list);
return sol_incref(state->None);
}
sol_list_insert(state, list, 0, key);
sol_list_insert(state, list, 1, state->None);
sol_list_insert(state, list, 0, state->None);
sol_list_insert(state, list, 1, key);
while(!res && !dsl_seq_iter_is_invalid(iter)) {
sol_list_set_index(state, list, 1, AS_OBJ(dsl_seq_iter_at(iter))->key);
cmp = CALL_METHOD(state, key, cmp, list);
sol_list_set_index(state, list, 0, AS_OBJ(dsl_seq_iter_at(iter))->key);
cmp = CALL_METHOD(state, AS_OBJ(dsl_seq_iter_at(iter))->key, cmp, list);
if(sol_has_error(state)) {
sol_obj_free(cmp);
sol_clear_error(state);
continue;
}
icmp = sol_cast_int(state, cmp);
sol_obj_free(cmp);
if(icmp->ival == 0) {
@ -583,7 +588,8 @@ size_t sol_stream_printf(sol_state_t *state, sol_object_t *stream, const char *f
return 0;
}
va_start(va, fmt);
res = vfprintf(stream->stream, fmt, va);
//res = vfprintf(stream->stream, fmt, va);
res = vprintf(fmt, va);
va_end(va);
return res;
}
@ -595,7 +601,8 @@ size_t sol_stream_vprintf(sol_state_t *state, sol_object_t *stream, const char *
}
return 0;
}
return vfprintf(stream->stream, fmt, va);
//return vfprintf(stream->stream, fmt, va);
return vprintf(fmt, va);
}
size_t sol_stream_scanf(sol_state_t *state, sol_object_t *stream, const char *fmt, ...) {

2
old-sol-gdb.py

@ -153,6 +153,6 @@ class SolObjectPrettyPrinter(object):
# pp.add_printer('sol_object_t', '^sol_object_t.*$', SolObjectPrettyPrinter)
# pp.add_printer('sol_tag_object_t', '^struct sol_tag_object_t.*$', SolObjectPrettyPrinter)
# gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
gdb.current_objfile().pretty_printers.append(SolObjectPrettyPrinter.check_printable)
gdb.pretty_printers.append(SolObjectPrettyPrinter.check_printable)
print('Sol extensions loaded!')

56
parser.tab.c

@ -1838,10 +1838,10 @@ yyreduce:
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_SETINDEX;
AS_EX((yyval))->setindex = NEW(setindex_node);
AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
AS_EX((yyval))->setindex->value = (yyvsp[0]);
//ex_free(AS_EX($1));
ex_free(AS_EX((yyvsp[-2])));
}
#line 1847 "parser.tab.c" /* yacc.c:1646 */
break;
@ -1856,10 +1856,10 @@ yyreduce:
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_SETINDEX;
AS_EX((yyval))->setindex = NEW(setindex_node);
AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_ADD, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
//ex_free(AS_EX($1));
ex_free(AS_EX((yyvsp[-2])));
}
#line 1865 "parser.tab.c" /* yacc.c:1646 */
break;
@ -1874,10 +1874,10 @@ yyreduce:
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_SETINDEX;
AS_EX((yyval))->setindex = NEW(setindex_node);
AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_SUB, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
//ex_free(AS_EX($1));
ex_free(AS_EX((yyvsp[-2])));
}
#line 1883 "parser.tab.c" /* yacc.c:1646 */
break;
@ -1892,10 +1892,10 @@ yyreduce:
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_SETINDEX;
AS_EX((yyval))->setindex = NEW(setindex_node);
AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_MUL, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
//ex_free(AS_EX($1));
ex_free(AS_EX((yyvsp[-2])));
}
#line 1901 "parser.tab.c" /* yacc.c:1646 */
break;
@ -1910,10 +1910,10 @@ yyreduce:
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_SETINDEX;
AS_EX((yyval))->setindex = NEW(setindex_node);
AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_DIV, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
//ex_free(AS_EX($1));
ex_free(AS_EX((yyvsp[-2])));
}
#line 1919 "parser.tab.c" /* yacc.c:1646 */
break;
@ -1928,10 +1928,10 @@ yyreduce:
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_SETINDEX;
AS_EX((yyval))->setindex = NEW(setindex_node);
AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_POW, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
//ex_free(AS_EX($1));
ex_free(AS_EX((yyvsp[-2])));
}
#line 1937 "parser.tab.c" /* yacc.c:1646 */
break;
@ -1946,10 +1946,10 @@ yyreduce:
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_SETINDEX;
AS_EX((yyval))->setindex = NEW(setindex_node);
AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BAND, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
//ex_free(AS_EX($1));
ex_free(AS_EX((yyvsp[-2])));
}
#line 1955 "parser.tab.c" /* yacc.c:1646 */
break;
@ -1964,10 +1964,10 @@ yyreduce:
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_SETINDEX;
AS_EX((yyval))->setindex = NEW(setindex_node);
AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BOR, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
//ex_free(AS_EX($1));
ex_free(AS_EX((yyvsp[-2])));
}
#line 1973 "parser.tab.c" /* yacc.c:1646 */
break;
@ -1982,10 +1982,10 @@ yyreduce:
(yyval) = NEW_EX();
AS_EX((yyval))->type = EX_SETINDEX;
AS_EX((yyval))->setindex = NEW(setindex_node);
AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BXOR, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
//ex_free(AS_EX($1));
ex_free(AS_EX((yyvsp[-2])));
}
#line 1991 "parser.tab.c" /* yacc.c:1646 */
break;
@ -2204,7 +2204,7 @@ yyreduce:
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 = (yyvsp[-5]);
AS_EX((yyval))->call->args->expr = ex_copy((yyvsp[-5]));
AS_EX((yyval))->call->args->next = (yyvsp[-1]);
}
#line 2211 "parser.tab.c" /* yacc.c:1646 */

56
parser.y

@ -133,10 +133,10 @@ expr:
$$ = NEW_EX();
AS_EX($$)->type = EX_SETINDEX;
AS_EX($$)->setindex = NEW(setindex_node);
AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
AS_EX($$)->setindex->index = AS_EX($1)->index->index;
AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
AS_EX($$)->setindex->value = $3;
//ex_free(AS_EX($1));
ex_free(AS_EX($1));
}
| ex_index_expr ASSIGNPLUS expr {
if(AS_EX($1)->type != EX_INDEX) {
@ -146,10 +146,10 @@ expr:
$$ = NEW_EX();
AS_EX($$)->type = EX_SETINDEX;
AS_EX($$)->setindex = NEW(setindex_node);
AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
AS_EX($$)->setindex->index = AS_EX($1)->index->index;
AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_ADD, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
//ex_free(AS_EX($1));
ex_free(AS_EX($1));
}
| ex_index_expr ASSIGNMINUS expr {
if(AS_EX($1)->type != EX_INDEX) {
@ -159,10 +159,10 @@ expr:
$$ = NEW_EX();
AS_EX($$)->type = EX_SETINDEX;
AS_EX($$)->setindex = NEW(setindex_node);
AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
AS_EX($$)->setindex->index = AS_EX($1)->index->index;
AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_SUB, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
//ex_free(AS_EX($1));
ex_free(AS_EX($1));
}
| ex_index_expr ASSIGNSTAR expr {
if(AS_EX($1)->type != EX_INDEX) {
@ -172,10 +172,10 @@ expr:
$$ = NEW_EX();
AS_EX($$)->type = EX_SETINDEX;
AS_EX($$)->setindex = NEW(setindex_node);
AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
AS_EX($$)->setindex->index = AS_EX($1)->index->index;
AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_MUL, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
//ex_free(AS_EX($1));
ex_free(AS_EX($1));
}
| ex_index_expr ASSIGNSLASH expr {
if(AS_EX($1)->type != EX_INDEX) {
@ -185,10 +185,10 @@ expr:
$$ = NEW_EX();
AS_EX($$)->type = EX_SETINDEX;
AS_EX($$)->setindex = NEW(setindex_node);
AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
AS_EX($$)->setindex->index = AS_EX($1)->index->index;
AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_DIV, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
//ex_free(AS_EX($1));
ex_free(AS_EX($1));
}
| ex_index_expr ASSIGNDSTAR expr {
if(AS_EX($1)->type != EX_INDEX) {
@ -198,10 +198,10 @@ expr:
$$ = NEW_EX();
AS_EX($$)->type = EX_SETINDEX;
AS_EX($$)->setindex = NEW(setindex_node);
AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
AS_EX($$)->setindex->index = AS_EX($1)->index->index;
AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_POW, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
//ex_free(AS_EX($1));
ex_free(AS_EX($1));
}
| ex_index_expr ASSIGNBAND expr {
if(AS_EX($1)->type != EX_INDEX) {
@ -211,10 +211,10 @@ expr:
$$ = NEW_EX();
AS_EX($$)->type = EX_SETINDEX;
AS_EX($$)->setindex = NEW(setindex_node);
AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
AS_EX($$)->setindex->index = AS_EX($1)->index->index;
AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_BAND, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
//ex_free(AS_EX($1));
ex_free(AS_EX($1));
}
| ex_index_expr ASSIGNBOR expr {
if(AS_EX($1)->type != EX_INDEX) {
@ -224,10 +224,10 @@ expr:
$$ = NEW_EX();
AS_EX($$)->type = EX_SETINDEX;
AS_EX($$)->setindex = NEW(setindex_node);
AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
AS_EX($$)->setindex->index = AS_EX($1)->index->index;
AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_BOR, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
//ex_free(AS_EX($1));
ex_free(AS_EX($1));
}
| ex_index_expr ASSIGNBXOR expr {
if(AS_EX($1)->type != EX_INDEX) {
@ -237,10 +237,10 @@ expr:
$$ = NEW_EX();
AS_EX($$)->type = EX_SETINDEX;
AS_EX($$)->setindex = NEW(setindex_node);
AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
AS_EX($$)->setindex->index = AS_EX($1)->index->index;
AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_BXOR, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
//ex_free(AS_EX($1));
ex_free(AS_EX($1));
}
| logic_expr { $$ = $1; }
;
@ -319,7 +319,7 @@ call_expr:
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->expr = ex_copy($1);
AS_EX($$)->call->args->next = $5;
}
| funcdecl_expr { $$ = $1; }

400
runtime.c

@ -14,6 +14,275 @@ void sol_comp_free(stmt_node *stmt) {
st_free(stmt);
}
expr_node *ex_copy(expr_node *);
stmt_node *st_copy(stmt_node *old) {
stmt_node *new;
stmtlist_node *curn, *curo;
if(!old) {
printf("WARNING: Copying NULL statement\n");
return NULL;
}
new = NEW(stmt_node);
new->type = old->type;
switch(old->type) {
case ST_EXPR:
new->expr = ex_copy(old->expr);
break;
case ST_IFELSE:
new->ifelse = NEW(ifelse_node);
new->ifelse->cond = ex_copy(old->ifelse->cond);
if(old->ifelse->iftrue)
new->ifelse->iftrue = st_copy(old->ifelse->iftrue);
else
new->ifelse->iftrue = NULL;
if(old->ifelse->iffalse)
new->ifelse->iffalse = st_copy(old->ifelse->iffalse);
else
new->ifelse->iffalse = NULL;
break;
case ST_LOOP:
new->loop = NEW(loop_node);
new->loop->cond = ex_copy(old->loop->cond);
new->loop->loop = st_copy(old->loop->loop);
break;
case ST_ITER:
new->iter = NEW(iter_node);
new->iter->var = strdup(old->iter->var);
new->iter->iter = ex_copy(old->iter->iter);
new->iter->loop = st_copy(old->iter->loop);
break;
case ST_LIST:
new->stmtlist = stl_copy(old->stmtlist);
break;
case ST_RET:
new->ret = NEW(ret_node);
new->ret->ret = ex_copy(old->ret->ret);
break;
case ST_CONT:
case ST_BREAK:
break;
default:
printf("WARNING: Unknown statement type to copy: %d\n", old->type);
break;
}
return new;
}
stmtlist_node *stl_copy(stmtlist_node *old) {
stmtlist_node *new, *curn, *curo;
if(!old) {
return NULL;
}
new = NEW(stmtlist_node);
curn = new;
curo = old;
while(curo) {
if(curo->stmt) {
curn->stmt = st_copy(curo->stmt);
} else {
curn->stmt = NULL;
}
if(curo->next) {
curn->next = NEW(stmtlist_node);
curn = curn->next;
}
curo = curo->next;
}
curn->next = NULL;
return new;
}
expr_node *ex_copy(expr_node *old) {
expr_node *new;
exprlist_node *cureo, *curen;
assoclist_node *curao, *curan;
identlist_node *curio, *curin;
if(!old) {
printf("WARNING: Copying NULL expression\n");
return NULL;
}
new = NEW(expr_node);
new->type = old->type;
switch(old->type) {
case EX_LIT:
new->lit = NEW(lit_node);
new->lit->type = old->lit->type;
switch(old->lit->type) {
case LIT_INT:
new->lit->ival = old->lit->ival;
break;
case LIT_FLOAT:
new->lit->fval = old->lit->fval;
break;
case LIT_STRING:
new->lit->str = strdup(old->lit->str);
break;
case LIT_NONE:
break;
default:
printf("WARNING: Unknown literal type %d in copy\n", old->lit->type);
break;
}
break;
case EX_LISTGEN:
new->listgen = NEW(listgen_node);
new->listgen->list = exl_copy(old->listgen->list);
break;
case EX_MAPGEN:
new->mapgen = NEW(mapgen_node);
new->mapgen->map = asl_copy(old->mapgen->map);
break;
case EX_BINOP:
new->binop = NEW(binop_node);
new->binop->type = old->binop->type;
new->binop->left = ex_copy(old->binop->left);
new->binop->right = ex_copy(old->binop->right);
break;
case EX_UNOP:
new->unop = NEW(unop_node);
new->unop->type = old->unop->type;
new->unop->expr = ex_copy(old->unop->expr);
break;
case EX_INDEX:
new->index = NEW(index_node);
new->index->expr = ex_copy(old->index->expr);
new->index->index = ex_copy(old->index->index);
break;
case EX_SETINDEX:
new->setindex = NEW(setindex_node);
new->setindex->expr = ex_copy(old->setindex->expr);
new->setindex->index = ex_copy(old->setindex->index);
new->setindex->value = ex_copy(old->setindex->value);
break;
case EX_ASSIGN:
new->assign = NEW(assign_node);
new->assign->ident = strdup(old->assign->ident);
new->assign->value = ex_copy(old->assign->value);
break;
case EX_REF:
new->ref = NEW(ref_node);
new->ref->ident = strdup(old->ref->ident);
break;
case EX_CALL:
new->call = NEW(call_node);
new->call->expr = ex_copy(old->call->expr);
new->call->args = exl_copy(old->call->args);
break;
case EX_FUNCDECL:
new->funcdecl = NEW(funcdecl_node);
if(old->funcdecl->name) {
new->funcdecl->name = strdup(old->funcdecl->name);
} else {
new->funcdecl->name = NULL;
}
new->funcdecl->args = idl_copy(old->funcdecl->args);
new->funcdecl->body = st_copy(old->funcdecl->body);
break;
default:
printf("WARNING: Unknown expression type to copy: %d\n", old->type);
break;
}
return new;
}
assoclist_node *asl_copy(assoclist_node *old) {
assoclist_node *new, *curn, *curo;
if(!old) {
return NULL;
}
new = NEW(assoclist_node);
curn = new;
curo = old;
while(curo) {
if(curo->item && curo->item->key && curo->item->value) {
curn->item = NEW(associtem_node);
curn->item->key = ex_copy(curo->item->key);
curn->item->value = ex_copy(curo->item->value);
} else {
curn->item = NULL;
}
if(curo->next) {
curn->next = NEW(assoclist_node);
curn = curn->next;
}
curo = curo->next;
}
curn->next = NULL;
return new;
}
exprlist_node *exl_copy(exprlist_node *old) {
exprlist_node *new, *curn, *curo;
if(!old) {
return NULL;
}
new = NEW(exprlist_node);
curn = new;
curo = old;
while(curo) {
if(curo->expr) {
curn->expr = ex_copy(curo->expr);
} else {
curn->expr = NULL;
}
if(curo->next) {
curn->next = NEW(exprlist_node);
curn = curn->next;
}
curo = curo->next;
}
curn->next = NULL;
return new;
}
identlist_node *idl_copy(identlist_node *old) {
identlist_node *new, *curn, *curo;
if(!old) {
return NULL;
}
new = NEW(identlist_node);
curn = new;
curo = old;
while(curo) {
if(curo->ident) {
curn->ident = strdup(curo->ident);
} else {
curn->ident = NULL;
}
if(curo->next) {
curn->next = NEW(identlist_node);
curn = curn->next;
}
curo = curo->next;
}
curn->next = NULL;
return new;
}
void ex_free(expr_node *);
void st_free(stmt_node *stmt) {
@ -47,15 +316,7 @@ void st_free(stmt_node *stmt) {
break;
case ST_LIST:
curs = stmt->stmtlist;
while(curs) {
if(curs->stmt) {
st_free(curs->stmt);
}
prevs = curs;
curs = curs->next;
free(prevs);
}
stl_free(stmt->stmtlist);
break;
case ST_RET:
@ -70,6 +331,18 @@ void st_free(stmt_node *stmt) {
free(stmt);
}
void stl_free(stmtlist_node *list) {
stmtlist_node *cur = list, *prev;
while(cur) {
if(cur->stmt) {
free(cur->stmt);
}
prev = cur;
cur = cur->next;
free(prev);
}
}
void ex_free(expr_node *expr) {