Browse Source

Sol Part 38: RELEASE THE CLOWNS

Graham Northup 5 years ago
parent
commit
62dc3621d8
13 changed files with 619 additions and 216 deletions
  1. 11
    1
      Makefile
  2. 14
    3
      ast.h
  3. 117
    58
      builtins.c
  4. 7
    7
      gc.c
  5. 10
    10
      gcstat.py
  6. 17
    10
      object.c
  7. 1
    1
      old-sol-gdb.py
  8. 28
    28
      parser.tab.c
  9. 28
    28
      parser.y
  10. 343
    57
      runtime.c
  11. 11
    9
      sol.h
  12. 29
    3
      state.c
  13. 3
    1
      test.sol

+ 11
- 1
Makefile View File

@@ -1,4 +1,4 @@
1
-CFLAGS= -g -DDEBUG_CC
1
+CFLAGS= -g 
2 2
 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
3 3
 
4 4
 all: $(OBJ)
@@ -8,5 +8,15 @@ all: $(OBJ)
8 8
 %.o: %.c
9 9
 	gcc -c -o $@ $? $(CFLAGS)
10 10
 
11
+%.tab.c %.tab.h: %.y
12
+	bison -rall -fall -d $?
13
+
14
+lex.yy.c: tokenizer.lex parser.tab.h
15
+	flex $<
16
+
11 17
 clean:
12 18
 	rm -f *.o dsl/*.o sol
19
+
20
+docs: Doxyfile 
21
+	doxygen Doxyfile
22
+	sphinx-build -b html . ./_build

+ 14
- 3
ast.h View File

@@ -171,7 +171,7 @@ typedef struct tag_stmt_node {
171 171
 	nd->binop->left = NEW_EX(); \
172 172
 	nd->binop->left->type = EX_REF; \
173 173
 	nd->binop->left->ref = NEW(ref_node); \
174
-	nd->binop->left->ref->ident = name; \
174
+	nd->binop->left->ref->ident = strdup(name); \
175 175
 	nd->binop->right = val
176 176
 #define MAKE_IDX_BINOP(nd, tp, obj, idx, val) nd = NEW_EX(); \
177 177
 	nd->type = EX_BINOP; \
@@ -180,8 +180,8 @@ typedef struct tag_stmt_node {
180 180
 	nd->binop->left = NEW_EX(); \
181 181
 	nd->binop->left->type = EX_INDEX; \
182 182
 	nd->binop->left->index = NEW(index_node); \
183
-	nd->binop->left->index->expr = obj; \
184
-	nd->binop->left->index->index = idx; \
183
+	nd->binop->left->index->expr = ex_copy(obj); \
184
+	nd->binop->left->index->index = ex_copy(idx); \
185 185
 	nd->binop->right = val
186 186
 #define BOOL_TO_INT(cond) ((cond)?1:0)
187 187
 #define CALL_METHOD(state, obj, meth, args) ({\
@@ -205,8 +205,19 @@ stmt_node *sol_compile_file(FILE *);
205 205
 expr_node *sol_comp_as_expr(stmt_node *);
206 206
 void sol_compile_free(stmt_node *);
207 207
 
208
+stmt_node *st_copy(stmt_node *);
209
+expr_node *ex_copy(expr_node *);
210
+stmtlist_node *stl_copy(stmtlist_node *);
211
+exprlist_node *exl_copy(exprlist_node *);
212
+assoclist_node *asl_copy(assoclist_node *);
213
+identlist_node *idl_copy(identlist_node *);
214
+
208 215
 void st_free(stmt_node *);
209 216
 void ex_free(expr_node *);
217
+void stl_free(stmtlist_node *);
218
+void exl_free(exprlist_node *);
219
+void asl_free(assoclist_node *);
220
+void idl_free(identlist_node *);
210 221
 
211 222
 void st_print(sol_state_t *, stmt_node *);
212 223
 void ex_print(sol_state_t *, expr_node *);

+ 117
- 58
builtins.c View File

@@ -690,11 +690,15 @@ sol_object_t *sol_f_int_bnot(sol_state_t *state, sol_object_t *args) {
690 690
 }
691 691
 
692 692
 sol_object_t *sol_f_int_cmp(sol_state_t *state, sol_object_t *args) {
693
-	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);
694
-	sol_object_t *res = sol_new_int(state, a->ival == bint->ival ? 0 : (a->ival < bint->ival ? -1 : 1));
693
+	sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
694
+	sol_object_t *res;
695
+	if(sol_is_int(b)) {
696
+		res = sol_new_int(state, a->ival == b->ival ? 0 : (a->ival < b->ival ? -1 : 1));
697
+	} else {
698
+		res = sol_new_int(state, 1);
699
+	}
695 700
 	sol_obj_free(a);
696 701
 	sol_obj_free(b);
697
-	sol_obj_free(bint);
698 702
 	return res;
699 703
 }
700 704
 
@@ -779,11 +783,15 @@ sol_object_t *sol_f_float_pow(sol_state_t *state, sol_object_t *args) {
779 783
 }
780 784
 
781 785
 sol_object_t *sol_f_float_cmp(sol_state_t *state, sol_object_t *args) {
782
-    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);
783
-    sol_object_t *res = sol_new_int(state, a->fval==bflt->fval? 0 : (a->fval<bflt->fval? -1 : 1));
786
+    sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
787
+    sol_object_t *res;
788
+	if(sol_is_float(b)) {
789
+		res = sol_new_int(state, a->fval==b->fval? 0 : (a->fval<b->fval? -1 : 1));
790
+	} else {
791
+		res = sol_new_int(state, 1);
792
+	}
784 793
     sol_obj_free(a);
785 794
     sol_obj_free(b);
786
-	sol_obj_free(bflt);
787 795
     return res;
788 796
 }
789 797
 
@@ -841,11 +849,15 @@ sol_object_t *sol_f_str_mul(sol_state_t *state, sol_object_t *args) {
841 849
 }
842 850
 
843 851
 sol_object_t *sol_f_str_cmp(sol_state_t *state, sol_object_t *args) {
844
-    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);
845
-    sol_object_t *res = sol_new_int(state, strcmp(a->str, bstr->str));
852
+    sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
853
+    sol_object_t *res;
854
+	if(sol_is_string(b)) {
855
+		res = sol_new_int(state, strcmp(a->str, b->str));
856
+	} else {
857
+		res = sol_new_int(state, 1);
858
+	}
846 859
     sol_obj_free(a);
847 860
     sol_obj_free(b);
848
-	sol_obj_free(bstr);
849 861
     return res;
850 862
 }
851 863
 
@@ -1388,7 +1400,7 @@ sol_object_t *sol_f_func_index(sol_state_t *state, sol_object_t *args) {
1388 1400
 		} else if(sol_string_eq(state, key, "udata")) {
1389 1401
 			res = sol_incref(func->udata);
1390 1402
 		} else if(sol_string_eq(state, key, "stmt")) {
1391
-			res = sol_new_stmtnode(state, (stmt_node *) func->func);
1403
+			res = sol_new_stmtnode(state, st_copy((stmt_node *) func->func));
1392 1404
 		} else if(sol_string_eq(state, key, "args")) {
1393 1405
 			res = sol_new_list(state);
1394 1406
 			curi = func->args;
@@ -1406,7 +1418,9 @@ sol_object_t *sol_f_func_index(sol_state_t *state, sol_object_t *args) {
1406 1418
 }
1407 1419
 
1408 1420
 sol_object_t *sol_f_func_setindex(sol_state_t *state, sol_object_t *args) {
1409
-	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;
1421
+	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;
1422
+	size_t i, len;
1423
+	identlist_node *cur, *prev;
1410 1424
 	if(sol_string_eq(state, key, "name") && sol_is_string(val)) {
1411 1425
 		free(func->fname);
1412 1426
 		func->fname = strdup(val->str);
@@ -1419,7 +1433,27 @@ sol_object_t *sol_f_func_setindex(sol_state_t *state, sol_object_t *args) {
1419 1433
 		func->udata = sol_incref(val);
1420 1434
 		sol_obj_free(temp);
1421 1435
 	} else if(sol_string_eq(state, key, "stmt") && sol_is_aststmt(val)) {
1422
-		func->func = val->node;
1436
+		st_free(func->func);
1437
+		func->func = st_copy(val->node);
1438
+	} else if(sol_string_eq(state, key, "args") && sol_is_list(val)) {
1439
+		idl_free(func->args);
1440
+		func->args = NEW(identlist_node);
1441
+		cur = func->args;
1442
+		prev = cur;
1443
+		len = sol_list_len(state, val);
1444
+		for(i = 0; i < len; i++ ) {
1445
+			temp = sol_list_get_index(state, val, i);
1446
+			str = sol_cast_string(state, temp);
1447
+			cur->ident = strdup(str->str);
1448
+			sol_obj_free(temp);
1449
+			sol_obj_free(str);
1450
+			prev = cur;
1451
+			cur->next = NEW(identlist_node);
1452
+			cur = cur->next;
1453
+		} 
1454
+		prev->next = NULL;
1455
+		if(cur == func->args) func->args = NULL;
1456
+		free(cur);
1423 1457
 	} else {
1424 1458
 		sol_map_set(state, func->udata, key, val);
1425 1459
 	}
@@ -1503,25 +1537,25 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1503 1537
 			switch(stmt->type) {
1504 1538
 				case ST_EXPR:
1505 1539
 					if(sol_string_eq(state, str, "expr")) {
1506
-						res = sol_new_exprnode(state, stmt->expr);
1540
+						res = sol_new_exprnode(state, ex_copy(stmt->expr));
1507 1541
 					}
1508 1542
 					break;
1509 1543
 
1510 1544
 				case ST_IFELSE:
1511 1545
 					if(sol_string_eq(state, str, "cond")) {
1512
-						res = sol_new_exprnode(state, stmt->ifelse->cond);
1546
+						res = sol_new_exprnode(state, ex_copy(stmt->ifelse->cond));
1513 1547
 					} else if(sol_string_eq(state, str, "iftrue")) {
1514
-						res = sol_new_stmtnode(state, stmt->ifelse->iftrue);
1548
+						res = sol_new_stmtnode(state, st_copy(stmt->ifelse->iftrue));
1515 1549
 					} else if(sol_string_eq(state, str, "iffalse")) {
1516
-						res = sol_new_stmtnode(state, stmt->ifelse->iffalse);
1550
+						res = sol_new_stmtnode(state, st_copy(stmt->ifelse->iffalse));
1517 1551
 					}
1518 1552
 					break;
1519 1553
 
1520 1554
 				case ST_LOOP:
1521 1555
 					if(sol_string_eq(state, str, "cond")) {
1522
-						res = sol_new_exprnode(state, stmt->loop->cond);
1556
+						res = sol_new_exprnode(state, ex_copy(stmt->loop->cond));
1523 1557
 					} else if(sol_string_eq(state, str, "loop")) {
1524
-						res = sol_new_stmtnode(state, stmt->loop->loop);
1558
+						res = sol_new_stmtnode(state, st_copy(stmt->loop->loop));
1525 1559
 					}
1526 1560
 					break;
1527 1561
 
@@ -1529,9 +1563,9 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1529 1563
 					if(sol_string_eq(state, str, "var")) {
1530 1564
 						res = sol_new_string(state, stmt->iter->var);
1531 1565
 					} else if(sol_string_eq(state, str, "iter")) {
1532
-						res = sol_new_exprnode(state, stmt->iter->iter);
1566
+						res = sol_new_exprnode(state, ex_copy(stmt->iter->iter));
1533 1567
 					} else if(sol_string_eq(state, str, "loop")) {
1534
-						res = sol_new_stmtnode(state, stmt->iter->loop);
1568
+						res = sol_new_stmtnode(state, st_copy(stmt->iter->loop));
1535 1569
 					}
1536 1570
 					break;
1537 1571
 
@@ -1540,7 +1574,7 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1540 1574
 						res = sol_new_list(state);
1541 1575
 						curs = stmt->stmtlist;
1542 1576
 						while(curs) {
1543
-							sol_list_insert(state, res, i++, sol_new_stmtnode(state, curs->stmt));
1577
+							sol_list_insert(state, res, i++, sol_new_stmtnode(state, st_copy(curs->stmt)));
1544 1578
 							curs = curs->next;
1545 1579
 						}
1546 1580
 					}
@@ -1548,7 +1582,7 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1548 1582
 
1549 1583
 				case ST_RET:
1550 1584
 					if(sol_string_eq(state, str, "ret")) {
1551
-						res = sol_new_exprnode(state, stmt->ret->ret);
1585
+						res = sol_new_exprnode(state, ex_copy(stmt->ret->ret));
1552 1586
 					}
1553 1587
 					break;
1554 1588
 			}
@@ -1579,7 +1613,7 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1579 1613
 						res = sol_new_list(state);
1580 1614
 						cure = expr->listgen->list;
1581 1615
 						while(cure) {
1582
-							sol_list_insert(state, res, i++, sol_new_exprnode(state, cure->expr));
1616
+							sol_list_insert(state, res, i++, sol_new_exprnode(state, ex_copy(cure->expr)));
1583 1617
 							cure = cure->next;
1584 1618
 						}
1585 1619
 					}
@@ -1591,8 +1625,8 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1591 1625
 						cura = expr->mapgen->map;
1592 1626
 						while(cura) {
1593 1627
 							pair = sol_new_list(state);
1594
-							sol_list_insert(state, pair, 0, sol_new_exprnode(state, cura->item->key));
1595
-							sol_list_insert(state, pair, 1, sol_new_exprnode(state, cura->item->value));
1628
+							sol_list_insert(state, pair, 0, sol_new_exprnode(state, ex_copy(cura->item->key)));
1629
+							sol_list_insert(state, pair, 1, sol_new_exprnode(state, ex_copy(cura->item->value)));
1596 1630
 							sol_list_insert(state, res, i++, pair);
1597 1631
 							sol_obj_free(pair);
1598 1632
 						}
@@ -1603,9 +1637,9 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1603 1637
 					if(sol_string_eq(state, str, "binoptype")) {
1604 1638
 						res = sol_new_int(state, expr->binop->type);
1605 1639
 					} else if(sol_string_eq(state, str, "left")) {
1606
-						res = sol_new_exprnode(state, expr->binop->left);
1640
+						res = sol_new_exprnode(state, ex_copy(expr->binop->left));
1607 1641
 					} else if(sol_string_eq(state, str, "right")) {
1608
-						res = sol_new_exprnode(state, expr->binop->right);
1642
+						res = sol_new_exprnode(state, ex_copy(expr->binop->right));
1609 1643
 					}
1610 1644
 					break;
1611 1645
 
@@ -1613,25 +1647,25 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1613 1647
 					if(sol_string_eq(state, str, "unoptype")) {
1614 1648
 						res = sol_new_int(state, expr->unop->type);
1615 1649
 					} else if(sol_string_eq(state, str, "expr")) {
1616
-						res = sol_new_exprnode(state, expr->unop->expr);
1650
+						res = sol_new_exprnode(state, ex_copy(expr->unop->expr));
1617 1651
 					}
1618 1652
 					break;
1619 1653
 
1620 1654
 				case EX_INDEX:
1621 1655
 					if(sol_string_eq(state, str, "expr")) {
1622
-						res = sol_new_exprnode(state, expr->index->expr);
1656
+						res = sol_new_exprnode(state, ex_copy(expr->index->expr));
1623 1657
 					} else if(sol_string_eq(state, str, "index")) {
1624
-						res = sol_new_exprnode(state, expr->index->index);
1658
+						res = sol_new_exprnode(state, ex_copy(expr->index->index));
1625 1659
 					}
1626 1660
 					break;
1627 1661
 
1628 1662
 				case EX_SETINDEX:
1629 1663
 					if(sol_string_eq(state, str, "expr")) {
1630
-						res = sol_new_exprnode(state, expr->setindex->expr);
1664
+						res = sol_new_exprnode(state, ex_copy(expr->setindex->expr));
1631 1665
 					} else if(sol_string_eq(state, str, "index")) {
1632
-						res = sol_new_exprnode(state, expr->setindex->index);
1666
+						res = sol_new_exprnode(state, ex_copy(expr->setindex->index));
1633 1667
 					} else if(sol_string_eq(state, str, "value")) {
1634
-						res = sol_new_exprnode(state, expr->setindex->value);
1668
+						res = sol_new_exprnode(state, ex_copy(expr->setindex->value));
1635 1669
 					}
1636 1670
 					break;
1637 1671
 
@@ -1639,7 +1673,7 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1639 1673
 					if(sol_string_eq(state, str, "ident")) {
1640 1674
 						res = sol_new_string(state, expr->assign->ident);
1641 1675
 					} else if(sol_string_eq(state, str, "value")) {
1642
-						res = sol_new_exprnode(state, expr->assign->value);
1676
+						res = sol_new_exprnode(state, ex_copy(expr->assign->value));
1643 1677
 					}
1644 1678
 					break;
1645 1679
 
@@ -1651,12 +1685,12 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1651 1685
 
1652 1686
 				case EX_CALL:
1653 1687
 					if(sol_string_eq(state, str, "expr")) {
1654
-						res = sol_new_exprnode(state, expr->call->expr);
1688
+						res = sol_new_exprnode(state, ex_copy(expr->call->expr));
1655 1689
 					} else if(sol_string_eq(state, str, "args")) {
1656 1690
 						res = sol_new_list(state);
1657 1691
 						cure = expr->call->args;
1658 1692
 						while(cure) {
1659
-							sol_list_insert(state, res, i++, sol_new_exprnode(state, cure->expr));
1693
+							sol_list_insert(state, res, i++, sol_new_exprnode(state, ex_copy(cure->expr)));
1660 1694
 							cure = cure->next;
1661 1695
 						}
1662 1696
 					}
@@ -1673,7 +1707,7 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1673 1707
 							curi = curi->next;
1674 1708
 						}
1675 1709
 					} else if(sol_string_eq(state, str, "body")) {
1676
-						res = sol_new_stmtnode(state, expr->funcdecl->body);
1710
+						res = sol_new_stmtnode(state, st_copy(expr->funcdecl->body));
1677 1711
 					}
1678 1712
 					break;
1679 1713
 			}
@@ -1725,25 +1759,31 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1725 1759
 			switch(stmt->type) {
1726 1760
 				case ST_EXPR:
1727 1761
 					if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
1728
-						stmt->expr = val->node;
1762
+						ex_free(stmt->expr);
1763
+						stmt->expr = ex_copy(val->node);
1729 1764
 					}
1730 1765
 					break;
1731 1766
 
1732 1767
 				case ST_IFELSE:
1733 1768
 					if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
1734
-						stmt->ifelse->cond = val->node;
1769
+						ex_free(stmt->ifelse->cond);
1770
+						stmt->ifelse->cond = ex_copy(val->node);
1735 1771
 					} else if(sol_string_eq(state, str, "iftrue") && sol_is_aststmt(val)) {
1736
-						stmt->ifelse->iftrue = val->node;
1772
+						st_free(stmt->ifelse->iftrue);
1773
+						stmt->ifelse->iftrue = st_copy(val->node);
1737 1774
 					} else if(sol_string_eq(state, str, "iffalse") && sol_is_aststmt(val)) {
1738
-						stmt->ifelse->iffalse = val->node;
1775
+						st_free(stmt->ifelse->iffalse);
1776
+						stmt->ifelse->iffalse = st_copy(val->node);
1739 1777
 					}
1740 1778
 					break;
1741 1779
 
1742 1780
 				case ST_LOOP:
1743 1781
 					if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
1744
-						stmt->loop->cond = val->node;
1782
+						ex_free(stmt->loop->cond);
1783
+						stmt->loop->cond = ex_copy(val->node);
1745 1784
 					} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
1746
-						stmt->loop->loop = val->node;
1785
+						st_free(stmt->loop->loop);
1786
+						stmt->loop->loop = st_copy(val->node);
1747 1787
 					}
1748 1788
 					break;
1749 1789
 
@@ -1753,21 +1793,24 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1753 1793
 						stmt->iter->var = strdup(sval->str);
1754 1794
 						sol_obj_free(sval);
1755 1795
 					} else if(sol_string_eq(state, str, "iter") && sol_is_astexpr(val)) {
1756
-						stmt->iter->iter = val->node;
1796
+						ex_free(stmt->iter->iter);
1797
+						stmt->iter->iter = ex_copy(val->node);
1757 1798
 					} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
1758
-						stmt->iter->loop = val->node;
1799
+						st_free(stmt->iter->loop);
1800
+						stmt->iter->loop = st_copy(val->node);
1759 1801
 					}
1760 1802
 					break;
1761 1803
 
1762 1804
 				case ST_LIST:
1763 1805
 					if(sol_string_eq(state, str, "stmtlist") && sol_is_list(val)) {
1806
+						stl_free(stmt->stmtlist);
1764 1807
 						len = sol_list_len(state, val);
1765 1808
 						if(len > 0) {
1766 1809
 							curs = malloc(sizeof(stmtlist_node));
1767 1810
 							stmt->stmtlist = curs;
1768 1811
 							for(i = 0; i < len; i++) {
1769 1812
 								if(sol_is_aststmt(sol_list_get_index(state, val, i))) {
1770
-									curs->stmt = sol_list_get_index(state, val, i)->node;
1813
+									curs->stmt = st_copy(sol_list_get_index(state, val, i)->node);
1771 1814
 									prevs = curs;
1772 1815
 									curs = malloc(sizeof(stmtlist_node));
1773 1816
 									prevs->next = curs;
@@ -1788,7 +1831,8 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1788 1831
 
1789 1832
 				case ST_RET:
1790 1833
 					if(sol_string_eq(state, str, "ret") && sol_is_astexpr(val)) {
1791
-						stmt->ret->ret = val->node;
1834
+						ex_free(stmt->ret->ret);
1835
+						stmt->ret->ret = ex_copy(val->node);
1792 1836
 					}
1793 1837
 					break;
1794 1838
 			}
@@ -1833,6 +1877,7 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1833 1877
 
1834 1878
 				case EX_LISTGEN:
1835 1879
 					if(sol_string_eq(state, str, "list") && sol_is_list(val)) {
1880
+						exl_free(expr->listgen->list);
1836 1881
 						len = sol_list_len(state, val);
1837 1882
 						if(len > 0) {
1838 1883
 							cure = malloc(sizeof(exprlist_node));
@@ -1860,6 +1905,7 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1860 1905
 
1861 1906
 				case EX_MAPGEN:
1862 1907
 					if(sol_string_eq(state, str, "map") && sol_is_list(val)) {
1908
+						asl_free(expr->mapgen->map);
1863 1909
 						len = sol_list_len(state, val);
1864 1910
 						if(len > 0) {
1865 1911
 							cura = malloc(sizeof(assoclist_node));
@@ -1896,9 +1942,11 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1896 1942
 						expr->binop->type = ival->ival;
1897 1943
 						sol_obj_free(ival);
1898 1944
 					} else if(sol_string_eq(state, str, "left") && sol_is_astexpr(val)) {
1899
-						expr->binop->left = val->node;
1945
+						ex_free(expr->binop->left);
1946
+						expr->binop->left = ex_copy(val->node);
1900 1947
 					} else if(sol_string_eq(state, str, "right") && sol_is_astexpr(val)) {
1901
-						expr->binop->right = val->node;
1948
+						ex_free(expr->binop->right);
1949
+						expr->binop->right = ex_copy(val->node);
1902 1950
 					}
1903 1951
 					break;
1904 1952
 
@@ -1908,25 +1956,31 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1908 1956
 						expr->unop->type = ival->ival;
1909 1957
 						sol_obj_free(ival);
1910 1958
 					} else if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
1911
-						expr->unop->expr = val->node;
1959
+						ex_free(expr->unop->expr);
1960
+						expr->unop->expr = ex_copy(val->node);
1912 1961
 					}
1913 1962
 					break;
1914 1963
 
1915 1964
 				case EX_INDEX:
1916 1965
 					if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
1917
-						expr->index->expr = val->node;
1966
+						ex_free(expr->index->expr);
1967
+						expr->index->expr = ex_copy(val->node);
1918 1968
 					} else if(sol_string_eq(state, str, "index") && sol_is_astexpr(val)) {
1919
-						expr->index->index = val->node;
1969
+						ex_free(expr->index->index);
1970
+						expr->index->index = ex_copy(val->node);
1920 1971
 					}
1921 1972
 					break;
1922 1973
 
1923 1974
 				case EX_SETINDEX:
1924 1975
 					if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
1925
-						expr->setindex->expr = val->node;
1976
+						ex_free(expr->setindex->expr);
1977
+						expr->setindex->expr = ex_copy(val->node);
1926 1978
 					} else if(sol_string_eq(state, str, "index") && sol_is_astexpr(val)) {
1927
-						expr->setindex->index = val->node;
1979
+						ex_free(expr->setindex->index);
1980
+						expr->setindex->index = ex_copy(val->node);
1928 1981
 					} else if(sol_string_eq(state, str, "value") && sol_is_astexpr(val)) {
1929
-						expr->setindex->value = val->node;
1982
+						ex_free(expr->setindex->value);
1983
+						expr->setindex->value = ex_copy(val->node);
1930 1984
 					}
1931 1985
 					break;
1932 1986
 
@@ -1936,7 +1990,8 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1936 1990
 						expr->assign->ident = strdup(sval->str);
1937 1991
 						sol_obj_free(sval);
1938 1992
 					} else if(sol_string_eq(state, str, "value") && sol_is_astexpr(val)) {
1939
-						expr->assign->value = val->node;
1993
+						ex_free(expr->assign->value);
1994
+						expr->assign->value = ex_copy(val->node);
1940 1995
 					}
1941 1996
 					break;
1942 1997
 
@@ -1950,8 +2005,10 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1950 2005
 
1951 2006
 				case EX_CALL:
1952 2007
 					if(sol_string_eq(state, str, "expr") && sol_is_astexpr(val)) {
1953
-						expr->call->expr = val->node;
2008
+						ex_free(expr->call->expr);
2009
+						expr->call->expr = ex_copy(val->node);
1954 2010
 					} else if(sol_string_eq(state, str, "args") && sol_is_list(val)) {
2011
+						exl_free(expr->call->args);
1955 2012
 						len = sol_list_len(state, val);
1956 2013
 						if(len > 0) {
1957 2014
 							cure = malloc(sizeof(exprlist_node));
@@ -1983,6 +2040,7 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1983 2040
 						expr->funcdecl->name = strdup(sval->str);
1984 2041
 						sol_obj_free(sval);
1985 2042
 					} else if(sol_string_eq(state, str, "args") && sol_is_list(val)) {
2043
+						idl_free(expr->funcdecl->args);
1986 2044
 						len = sol_list_len(state, val);
1987 2045
 						if(len > 0) {
1988 2046
 							curi = malloc(sizeof(identlist_node));
@@ -2006,7 +2064,8 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
2006 2064
 							expr->funcdecl->args = NULL;
2007 2065
 						}
2008 2066
 					} else if(sol_string_eq(state, str, "body") && sol_is_aststmt(val)) {
2009
-						expr->funcdecl->body = val->node;
2067
+						st_free(expr->funcdecl->body);
2068
+						expr->funcdecl->body = st_copy(val->node);
2010 2069
 					}
2011 2070
 					break;
2012 2071
 			}

+ 7
- 7
gc.c View File

@@ -73,35 +73,35 @@ void sol_mm_finalize(sol_state_t *state) {
73 73
 }
74 74
 
75 75
 sol_object_t *_int_sol_alloc_object(const char *func, sol_state_t *state) {
76
-	fprintf(gclog, "%s\t%s\tALLOC\n", prtime(), func);
76
+	fprintf(gclog, "%s\tA\n", func);
77 77
 	return _sol_gc_alloc_object(state);
78 78
 }
79 79
 
80 80
 sol_object_t *_int_sol_incref(const char *func, sol_object_t *obj) {
81 81
 	int oldref = obj->refcnt++;
82
-	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);
82
+	fprintf(gclog, "%s\tI\t%s\t%p\t%d\t->\t%d\n", func, obj->ops->tname, obj, oldref, obj->refcnt);
83 83
 	return obj;
84 84
 }
85 85
 
86 86
 void _int_sol_obj_free(const char *func, sol_object_t *obj) {
87
-	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);
87
+	fprintf(gclog, "%s\tD\t%s\t%p\t%d\t->\t%d\n", func, obj->ops->tname, obj, obj->refcnt, obj->refcnt - 1);
88 88
 	_sol_gc_obj_free(obj);
89 89
 }
90 90
 
91 91
 
92 92
 void sol_obj_release(sol_object_t *obj) {
93
-	fprintf(gclog, "%s\t\tFREE\t%s\t%p\n", prtime(), obj->ops->tname, obj);
93
+	fprintf(gclog, "\tF\t%s\t%p\n", obj->ops->tname, obj);
94 94
     if(obj->ops->free) obj->ops->free(NULL, obj);
95 95
     free(obj);
96 96
 }
97 97
 
98 98
 sol_object_t *_sol_gc_dsl_copier(sol_object_t *obj) {
99
-	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);
99
+	fprintf(gclog, "<dsl>\tI\t%s\t%p\t%d\t->\t%d\n", obj->ops->tname, obj, obj->refcnt, ++obj->refcnt);
100 100
 	return obj;
101 101
 }
102 102
 
103 103
 void _sol_gc_dsl_destructor(sol_object_t *obj) {
104
-	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);
104
+	fprintf(gclog, "<dsl>\tD\t%s\t%p\t%d\t->\t%d\n", obj->ops->tname, obj, obj->refcnt, obj->refcnt - 1);
105 105
 	_sol_gc_obj_free(obj);
106 106
 }
107 107
 
@@ -125,4 +125,4 @@ void sol_obj_release(sol_object_t *obj) {
125 125
 void sol_mm_initialize(sol_state_t *state) {}
126 126
 void sol_mm_finalize(sol_state_t *state) {}
127 127
 
128
-#endif
128
+#endif

+ 10
- 10
gcstat.py View File

@@ -18,16 +18,16 @@ for line in f:
18 18
 	if line[0] == '=':
19 19
 		continue
20 20
 	parts = line.split('\t')
21
-	if parts[2] == 'INCREF':
22
-		incs[parts[1]] += 1
23
-		refs[parts[4]] += 1
24
-		types[parts[4]] = parts[3]
25
-		seenrefs[parts[4]] = parts[7]
26
-	elif parts[2] == 'DECREF':
27
-		decs[parts[1]] += 1
28
-		refs[parts[4]] -= 1
29
-		types[parts[4]] = parts[3]
30
-		seenrefs[parts[4]] = parts[7]
21
+	if parts[1] == 'I':
22
+		incs[parts[0]] += 1
23
+		refs[parts[3]] += 1
24
+		types[parts[3]] = parts[2]
25
+		seenrefs[parts[3]] = parts[6]
26
+	elif parts[1] == 'D':
27
+		decs[parts[0]] += 1
28
+		refs[parts[3]] -= 1
29
+		types[parts[3]] = parts[2]
30
+		seenrefs[parts[3]] = parts[6]
31 31
 
32 32
 incpairs = incs.items()
33 33
 decpairs = decs.items()

+ 17
- 10
object.c View File

@@ -14,7 +14,7 @@ sol_object_t *sol_cast_int(sol_state_t *state, sol_object_t *obj) {
14 14
 	}
15 15
 	ls = sol_new_list(state);
16 16
 	sol_list_insert(state, ls, 0, obj);
17
-	res = obj->ops->toint(state, ls);
17
+	res = CALL_METHOD(state, obj, toint, ls);
18 18
 	sol_obj_free(ls);
19 19
 	return res;
20 20
 }
@@ -26,7 +26,7 @@ sol_object_t *sol_cast_float(sol_state_t *state, sol_object_t *obj) {
26 26
 	}
27 27
 	ls = sol_new_list(state);
28 28
 	sol_list_insert(state, ls, 0, obj);
29
-	res = obj->ops->tofloat(state, ls);
29
+	res = CALL_METHOD(state, obj, tofloat, ls);
30 30
 	sol_obj_free(ls);
31 31
 	return res;
32 32
 }
@@ -38,7 +38,7 @@ sol_object_t *sol_cast_string(sol_state_t *state, sol_object_t *obj) {
38 38
 	}
39 39
 	ls = sol_new_list(state);
40 40
 	sol_list_insert(state, ls, 0, obj);
41
-	res = obj->ops->tostring(state, ls);
41
+	res = CALL_METHOD(state, obj, tostring, ls);
42 42
 	sol_obj_free(ls);
43 43
 	return res;
44 44
 }
@@ -46,7 +46,7 @@ sol_object_t *sol_cast_string(sol_state_t *state, sol_object_t *obj) {
46 46
 sol_object_t *sol_cast_repr(sol_state_t *state, sol_object_t *obj) {
47 47
 	sol_object_t *res, *ls = sol_new_list(state);
48 48
 	sol_list_insert(state, ls, 0, obj);
49
-	res = obj->ops->repr(state, ls);
49
+	res = CALL_METHOD(state, obj, repr, ls);
50 50
 	sol_obj_free(ls);
51 51
 	return res;
52 52
 }
@@ -322,11 +322,16 @@ sol_object_t *sol_map_mcell(sol_state_t *state, sol_object_t *map, sol_object_t
322 322
 		sol_obj_free(list);
323 323
 		return sol_incref(state->None);
324 324
 	}
325
-	sol_list_insert(state, list, 0, key);
326
-	sol_list_insert(state, list, 1, state->None);
325
+	sol_list_insert(state, list, 0, state->None);
326
+	sol_list_insert(state, list, 1, key);
327 327
 	while(!res && !dsl_seq_iter_is_invalid(iter)) {
328
-		sol_list_set_index(state, list, 1, AS_OBJ(dsl_seq_iter_at(iter))->key);
329
-		cmp = CALL_METHOD(state, key, cmp, list);
328
+		sol_list_set_index(state, list, 0, AS_OBJ(dsl_seq_iter_at(iter))->key);
329
+		cmp = CALL_METHOD(state, AS_OBJ(dsl_seq_iter_at(iter))->key, cmp, list);
330
+		if(sol_has_error(state)) {
331
+			sol_obj_free(cmp);
332
+			sol_clear_error(state);
333
+			continue;
334
+		}
330 335
 		icmp = sol_cast_int(state, cmp);
331 336
 		sol_obj_free(cmp);
332 337
 		if(icmp->ival == 0) {
@@ -583,7 +588,8 @@ size_t sol_stream_printf(sol_state_t *state, sol_object_t *stream, const char *f
583 588
 		return 0;
584 589
 	}
585 590
 	va_start(va, fmt);
586
-	res = vfprintf(stream->stream, fmt, va);
591
+	//res = vfprintf(stream->stream, fmt, va);
592
+	res = vprintf(fmt, va);
587 593
 	va_end(va);
588 594
 	return res;
589 595
 }
@@ -595,7 +601,8 @@ size_t sol_stream_vprintf(sol_state_t *state, sol_object_t *stream, const char *
595 601
 		}
596 602
 		return 0;
597 603
 	}
598
-	return vfprintf(stream->stream, fmt, va);
604
+	//return vfprintf(stream->stream, fmt, va);
605
+	return vprintf(fmt, va);
599 606
 }
600 607
 
601 608
 size_t sol_stream_scanf(sol_state_t *state, sol_object_t *stream, const char *fmt, ...) {

+ 1
- 1
old-sol-gdb.py View File

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

+ 28
- 28
parser.tab.c View File

@@ -1838,10 +1838,10 @@ yyreduce:
1838 1838
     (yyval) = NEW_EX();
1839 1839
     AS_EX((yyval))->type = EX_SETINDEX;
1840 1840
     AS_EX((yyval))->setindex = NEW(setindex_node);
1841
-    AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
1842
-    AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
1841
+    AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
1842
+    AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
1843 1843
     AS_EX((yyval))->setindex->value = (yyvsp[0]);
1844
-    //ex_free(AS_EX($1));
1844
+    ex_free(AS_EX((yyvsp[-2])));
1845 1845
 }
1846 1846
 #line 1847 "parser.tab.c" /* yacc.c:1646  */
1847 1847
     break;
@@ -1856,10 +1856,10 @@ yyreduce:
1856 1856
     (yyval) = NEW_EX();
1857 1857
     AS_EX((yyval))->type = EX_SETINDEX;
1858 1858
     AS_EX((yyval))->setindex = NEW(setindex_node);
1859
-    AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
1860
-    AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
1859
+    AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
1860
+    AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
1861 1861
     MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_ADD, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
1862
-    //ex_free(AS_EX($1));
1862
+    ex_free(AS_EX((yyvsp[-2])));
1863 1863
 }
1864 1864
 #line 1865 "parser.tab.c" /* yacc.c:1646  */
1865 1865
     break;
@@ -1874,10 +1874,10 @@ yyreduce:
1874 1874
     (yyval) = NEW_EX();
1875 1875
     AS_EX((yyval))->type = EX_SETINDEX;
1876 1876
     AS_EX((yyval))->setindex = NEW(setindex_node);
1877
-    AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
1878
-    AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
1877
+    AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
1878
+    AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
1879 1879
     MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_SUB, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
1880
-    //ex_free(AS_EX($1));
1880
+    ex_free(AS_EX((yyvsp[-2])));
1881 1881
 }
1882 1882
 #line 1883 "parser.tab.c" /* yacc.c:1646  */
1883 1883
     break;
@@ -1892,10 +1892,10 @@ yyreduce:
1892 1892
     (yyval) = NEW_EX();
1893 1893
     AS_EX((yyval))->type = EX_SETINDEX;
1894 1894
     AS_EX((yyval))->setindex = NEW(setindex_node);
1895
-    AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
1896
-    AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
1895
+    AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
1896
+    AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
1897 1897
     MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_MUL, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
1898
-    //ex_free(AS_EX($1));
1898
+    ex_free(AS_EX((yyvsp[-2])));
1899 1899
 }
1900 1900
 #line 1901 "parser.tab.c" /* yacc.c:1646  */
1901 1901
     break;
@@ -1910,10 +1910,10 @@ yyreduce:
1910 1910
     (yyval) = NEW_EX();
1911 1911
     AS_EX((yyval))->type = EX_SETINDEX;
1912 1912
     AS_EX((yyval))->setindex = NEW(setindex_node);
1913
-    AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
1914
-    AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
1913
+    AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
1914
+    AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
1915 1915
     MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_DIV, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
1916
-    //ex_free(AS_EX($1));
1916
+    ex_free(AS_EX((yyvsp[-2])));
1917 1917
 }
1918 1918
 #line 1919 "parser.tab.c" /* yacc.c:1646  */
1919 1919
     break;
@@ -1928,10 +1928,10 @@ yyreduce:
1928 1928
     (yyval) = NEW_EX();
1929 1929
     AS_EX((yyval))->type = EX_SETINDEX;
1930 1930
     AS_EX((yyval))->setindex = NEW(setindex_node);
1931
-    AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
1932
-    AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
1931
+    AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
1932
+    AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
1933 1933
     MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_POW, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
1934
-    //ex_free(AS_EX($1));
1934
+    ex_free(AS_EX((yyvsp[-2])));
1935 1935
 }
1936 1936
 #line 1937 "parser.tab.c" /* yacc.c:1646  */
1937 1937
     break;
@@ -1946,10 +1946,10 @@ yyreduce:
1946 1946
     (yyval) = NEW_EX();
1947 1947
     AS_EX((yyval))->type = EX_SETINDEX;
1948 1948
     AS_EX((yyval))->setindex = NEW(setindex_node);
1949
-    AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
1950
-    AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
1949
+    AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
1950
+    AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
1951 1951
     MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BAND, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
1952
-    //ex_free(AS_EX($1));
1952
+    ex_free(AS_EX((yyvsp[-2])));
1953 1953
 }
1954 1954
 #line 1955 "parser.tab.c" /* yacc.c:1646  */
1955 1955
     break;
@@ -1964,10 +1964,10 @@ yyreduce:
1964 1964
     (yyval) = NEW_EX();
1965 1965
     AS_EX((yyval))->type = EX_SETINDEX;
1966 1966
     AS_EX((yyval))->setindex = NEW(setindex_node);
1967
-    AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
1968
-    AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
1967
+    AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
1968
+    AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
1969 1969
     MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BOR, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
1970
-    //ex_free(AS_EX($1));
1970
+    ex_free(AS_EX((yyvsp[-2])));
1971 1971
 }
1972 1972
 #line 1973 "parser.tab.c" /* yacc.c:1646  */
1973 1973
     break;
@@ -1982,10 +1982,10 @@ yyreduce:
1982 1982
     (yyval) = NEW_EX();
1983 1983
     AS_EX((yyval))->type = EX_SETINDEX;
1984 1984
     AS_EX((yyval))->setindex = NEW(setindex_node);
1985
-    AS_EX((yyval))->setindex->expr = AS_EX((yyvsp[-2]))->index->expr;
1986
-    AS_EX((yyval))->setindex->index = AS_EX((yyvsp[-2]))->index->index;
1985
+    AS_EX((yyval))->setindex->expr = ex_copy(AS_EX((yyvsp[-2]))->index->expr);
1986
+    AS_EX((yyval))->setindex->index = ex_copy(AS_EX((yyvsp[-2]))->index->index);
1987 1987
     MAKE_IDX_BINOP(AS_EX((yyval))->setindex->value, OP_BXOR, AS_EX((yyvsp[-2]))->index->expr, AS_EX((yyvsp[-2]))->index->index, (yyvsp[0]));
1988
-    //ex_free(AS_EX($1));
1988
+    ex_free(AS_EX((yyvsp[-2])));
1989 1989
 }
1990 1990
 #line 1991 "parser.tab.c" /* yacc.c:1646  */
1991 1991
     break;
@@ -2204,7 +2204,7 @@ yyreduce:
2204 2204
 	AS_EX((yyval))->call->expr->index->index->lit->type = LIT_STRING;
2205 2205
 	AS_EX((yyval))->call->expr->index->index->lit->str = (yyvsp[-3]);
2206 2206
 	AS_EX((yyval))->call->args = NEW(exprlist_node);
2207
-	AS_EX((yyval))->call->args->expr = (yyvsp[-5]);
2207
+	AS_EX((yyval))->call->args->expr = ex_copy((yyvsp[-5]));
2208 2208
 	AS_EX((yyval))->call->args->next = (yyvsp[-1]);
2209 2209
 }
2210 2210
 #line 2211 "parser.tab.c" /* yacc.c:1646  */

+ 28
- 28
parser.y View File

@@ -133,10 +133,10 @@ expr:
133 133
     $$ = NEW_EX();
134 134
     AS_EX($$)->type = EX_SETINDEX;
135 135
     AS_EX($$)->setindex = NEW(setindex_node);
136
-    AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
137
-    AS_EX($$)->setindex->index = AS_EX($1)->index->index;
136
+    AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
137
+    AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
138 138
     AS_EX($$)->setindex->value = $3;
139
-    //ex_free(AS_EX($1));
139
+    ex_free(AS_EX($1));
140 140
 }
141 141
 | ex_index_expr ASSIGNPLUS expr {
142 142
     if(AS_EX($1)->type != EX_INDEX) {
@@ -146,10 +146,10 @@ expr:
146 146
     $$ = NEW_EX();
147 147
     AS_EX($$)->type = EX_SETINDEX;
148 148
     AS_EX($$)->setindex = NEW(setindex_node);
149
-    AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
150
-    AS_EX($$)->setindex->index = AS_EX($1)->index->index;
149
+    AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
150
+    AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
151 151
     MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_ADD, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
152
-    //ex_free(AS_EX($1));
152
+    ex_free(AS_EX($1));
153 153
 }
154 154
 | ex_index_expr ASSIGNMINUS expr {
155 155
     if(AS_EX($1)->type != EX_INDEX) {
@@ -159,10 +159,10 @@ expr:
159 159
     $$ = NEW_EX();
160 160
     AS_EX($$)->type = EX_SETINDEX;
161 161
     AS_EX($$)->setindex = NEW(setindex_node);
162
-    AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
163
-    AS_EX($$)->setindex->index = AS_EX($1)->index->index;
162
+    AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
163
+    AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
164 164
     MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_SUB, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
165
-    //ex_free(AS_EX($1));
165
+    ex_free(AS_EX($1));
166 166
 }
167 167
 | ex_index_expr ASSIGNSTAR expr {
168 168
     if(AS_EX($1)->type != EX_INDEX) {
@@ -172,10 +172,10 @@ expr:
172 172
     $$ = NEW_EX();
173 173
     AS_EX($$)->type = EX_SETINDEX;
174 174
     AS_EX($$)->setindex = NEW(setindex_node);
175
-    AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
176
-    AS_EX($$)->setindex->index = AS_EX($1)->index->index;
175
+    AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
176
+    AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
177 177
     MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_MUL, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
178
-    //ex_free(AS_EX($1));
178
+    ex_free(AS_EX($1));
179 179
 }
180 180
 | ex_index_expr ASSIGNSLASH expr {
181 181
     if(AS_EX($1)->type != EX_INDEX) {
@@ -185,10 +185,10 @@ expr:
185 185
     $$ = NEW_EX();
186 186
     AS_EX($$)->type = EX_SETINDEX;
187 187
     AS_EX($$)->setindex = NEW(setindex_node);
188
-    AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
189
-    AS_EX($$)->setindex->index = AS_EX($1)->index->index;
188
+    AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
189
+    AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
190 190
     MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_DIV, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
191
-    //ex_free(AS_EX($1));
191
+    ex_free(AS_EX($1));
192 192
 }
193 193
 | ex_index_expr ASSIGNDSTAR expr {
194 194
     if(AS_EX($1)->type != EX_INDEX) {
@@ -198,10 +198,10 @@ expr:
198 198
     $$ = NEW_EX();
199 199
     AS_EX($$)->type = EX_SETINDEX;
200 200
     AS_EX($$)->setindex = NEW(setindex_node);
201
-    AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
202
-    AS_EX($$)->setindex->index = AS_EX($1)->index->index;
201
+    AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
202
+    AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
203 203
     MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_POW, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
204
-    //ex_free(AS_EX($1));
204
+    ex_free(AS_EX($1));
205 205
 }
206 206
 | ex_index_expr ASSIGNBAND expr {
207 207
     if(AS_EX($1)->type != EX_INDEX) {
@@ -211,10 +211,10 @@ expr:
211 211
     $$ = NEW_EX();
212 212
     AS_EX($$)->type = EX_SETINDEX;
213 213
     AS_EX($$)->setindex = NEW(setindex_node);
214
-    AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
215
-    AS_EX($$)->setindex->index = AS_EX($1)->index->index;
214
+    AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
215
+    AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
216 216
     MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_BAND, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
217
-    //ex_free(AS_EX($1));
217
+    ex_free(AS_EX($1));
218 218
 }
219 219
 | ex_index_expr ASSIGNBOR expr {
220 220
     if(AS_EX($1)->type != EX_INDEX) {
@@ -224,10 +224,10 @@ expr:
224 224
     $$ = NEW_EX();
225 225
     AS_EX($$)->type = EX_SETINDEX;
226 226
     AS_EX($$)->setindex = NEW(setindex_node);
227
-    AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
228
-    AS_EX($$)->setindex->index = AS_EX($1)->index->index;
227
+    AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
228
+    AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
229 229
     MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_BOR, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
230
-    //ex_free(AS_EX($1));
230
+    ex_free(AS_EX($1));
231 231
 }
232 232
 | ex_index_expr ASSIGNBXOR expr {
233 233
     if(AS_EX($1)->type != EX_INDEX) {
@@ -237,10 +237,10 @@ expr:
237 237
     $$ = NEW_EX();
238 238
     AS_EX($$)->type = EX_SETINDEX;
239 239
     AS_EX($$)->setindex = NEW(setindex_node);
240
-    AS_EX($$)->setindex->expr = AS_EX($1)->index->expr;
241
-    AS_EX($$)->setindex->index = AS_EX($1)->index->index;
240
+    AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
241
+    AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
242 242
     MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_BXOR, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
243
-    //ex_free(AS_EX($1));
243
+    ex_free(AS_EX($1));
244 244
 }
245 245
 | logic_expr { $$ = $1; }
246 246
 ;
@@ -319,7 +319,7 @@ call_expr:
319 319
 	AS_EX($$)->call->expr->index->index->lit->type = LIT_STRING;
320 320
 	AS_EX($$)->call->expr->index->index->lit->str = $3;
321 321
 	AS_EX($$)->call->args = NEW(exprlist_node);
322
-	AS_EX($$)->call->args->expr = $1;
322
+	AS_EX($$)->call->args->expr = ex_copy($1);
323 323
 	AS_EX($$)->call->args->next = $5;
324 324
 }
325 325
 | funcdecl_expr { $$ = $1; }

+ 343
- 57
runtime.c View File

@@ -14,6 +14,275 @@ void sol_comp_free(stmt_node *stmt) {
14 14
 	st_free(stmt);
15 15
 }
16 16
 
17
+expr_node *ex_copy(expr_node *);
18
+
19
+stmt_node *st_copy(stmt_node *old) {
20
+	stmt_node *new;
21
+	stmtlist_node *curn, *curo;
22
+	if(!old) {
23
+		printf("WARNING: Copying NULL statement\n");
24
+		return NULL;
25
+	}
26
+	new = NEW(stmt_node);
27
+	new->type = old->type;
28
+	switch(old->type) {
29
+		case ST_EXPR:
30
+			new->expr = ex_copy(old->expr);
31
+			break;
32
+
33
+		case ST_IFELSE:
34
+			new->ifelse = NEW(ifelse_node);
35
+			new->ifelse->cond = ex_copy(old->ifelse->cond);
36
+			if(old->ifelse->iftrue)
37
+				new->ifelse->iftrue = st_copy(old->ifelse->iftrue);
38
+			else
39
+				new->ifelse->iftrue = NULL;
40
+			if(old->ifelse->iffalse)
41
+				new->ifelse->iffalse = st_copy(old->ifelse->iffalse);
42
+			else
43
+				new->ifelse->iffalse = NULL;
44
+			break;
45
+
46
+		case ST_LOOP:
47
+			new->loop = NEW(loop_node);
48
+			new->loop->cond = ex_copy(old->loop->cond);
49
+			new->loop->loop = st_copy(old->loop->loop);
50
+			break;
51
+
52
+		case ST_ITER:
53
+			new->iter = NEW(iter_node);
54
+			new->iter->var = strdup(old->iter->var);
55
+			new->iter->iter = ex_copy(old->iter->iter);
56
+			new->iter->loop = st_copy(old->iter->loop);
57
+			break;
58
+
59
+		case ST_LIST:
60
+			
61
+			new->stmtlist = stl_copy(old->stmtlist);
62
+			break;
63
+
64
+		case ST_RET:
65
+			new->ret = NEW(ret_node);
66
+			new->ret->ret = ex_copy(old->ret->ret);
67
+			break;
68
+
69
+		case ST_CONT:
70
+		case ST_BREAK:
71
+			break;
72
+
73
+		default:
74
+			printf("WARNING: Unknown statement type to copy: %d\n", old->type);
75
+			break;
76
+	}
77
+	return new;
78
+}
79
+
80
+stmtlist_node *stl_copy(stmtlist_node *old) {
81
+	stmtlist_node *new, *curn, *curo;
82
+	if(!old) {
83
+		return NULL;
84
+	}
85
+	new = NEW(stmtlist_node);
86
+	curn = new;
87
+	curo = old;
88
+	while(curo) {
89
+		if(curo->stmt) {
90
+			curn->stmt = st_copy(curo->stmt);
91
+		} else {
92
+			curn->stmt = NULL;
93
+		}
94
+		if(curo->next) {
95
+			curn->next = NEW(stmtlist_node);
96
+			curn = curn->next;
97
+		}
98
+		curo = curo->next;
99
+	}
100
+	curn->next = NULL;
101
+	return new;
102
+}
103
+
104
+expr_node *ex_copy(expr_node *old) {
105
+	expr_node *new;
106
+	exprlist_node *cureo, *curen;
107
+	assoclist_node *curao, *curan;
108
+	identlist_node *curio, *curin;
109
+	if(!old) {
110
+		printf("WARNING: Copying NULL expression\n");
111
+		return NULL;
112
+	}
113
+	new = NEW(expr_node);
114
+	new->type = old->type;
115
+	switch(old->type) {
116
+		case EX_LIT:
117
+			new->lit = NEW(lit_node);
118
+			new->lit->type = old->lit->type;
119
+			switch(old->lit->type) {
120
+				case LIT_INT:
121
+					new->lit->ival = old->lit->ival;
122
+					break;
123
+
124
+				case LIT_FLOAT:
125
+					new->lit->fval = old->lit->fval;
126
+					break;
127
+
128
+				case LIT_STRING:
129
+					new->lit->str = strdup(old->lit->str);
130
+					break;
131
+
132
+				case LIT_NONE:
133
+					break;
134
+
135
+				default:
136
+					printf("WARNING: Unknown literal type %d in copy\n", old->lit->type);
137
+					break;
138
+			}
139
+			break;
140
+
141
+		case EX_LISTGEN:
142
+			new->listgen = NEW(listgen_node);
143
+			new->listgen->list = exl_copy(old->listgen->list);
144
+			break;
145
+
146
+		case EX_MAPGEN:
147
+			new->mapgen = NEW(mapgen_node);
148
+			new->mapgen->map = asl_copy(old->mapgen->map);
149
+			break;
150
+
151
+		case EX_BINOP:
152
+			new->binop = NEW(binop_node);
153
+			new->binop->type = old->binop->type;
154
+			new->binop->left = ex_copy(old->binop->left);
155
+			new->binop->right = ex_copy(old->binop->right);
156
+			break;
157
+
158
+		case EX_UNOP:
159
+			new->unop = NEW(unop_node);
160
+			new->unop->type = old->unop->type;
161
+			new->unop->expr = ex_copy(old->unop->expr);
162
+			break;
163
+
164
+		case EX_INDEX:
165
+			new->index = NEW(index_node);
166
+			new->index->expr = ex_copy(old->index->expr);
167
+			new->index->index = ex_copy(old->index->index);
168
+			break;
169
+
170
+		case EX_SETINDEX:
171
+			new->setindex = NEW(setindex_node);
172
+			new->setindex->expr = ex_copy(old->setindex->expr);
173
+			new->setindex->index = ex_copy(old->setindex->index);
174
+			new->setindex->value = ex_copy(old->setindex->value);
175
+			break;
176
+
177
+		case EX_ASSIGN:
178
+			new->assign = NEW(assign_node);
179
+			new->assign->ident = strdup(old->assign->ident);
180
+			new->assign->value = ex_copy(old->assign->value);
181
+			break;
182
+
183
+		case EX_REF:
184
+			new->ref = NEW(ref_node);
185
+			new->ref->ident = strdup(old->ref->ident);
186
+			break;
187
+
188
+		case EX_CALL:
189
+			new->call = NEW(call_node);
190
+			new->call->expr = ex_copy(old->call->expr);
191
+			new->call->args = exl_copy(old->call->args);
192
+			break;
193
+
194
+		case EX_FUNCDECL:
195
+			new->funcdecl = NEW(funcdecl_node);
196
+			if(old->funcdecl->name) {
197
+				new->funcdecl->name = strdup(old->funcdecl->name);
198
+			} else {
199
+				new->funcdecl->name = NULL;
200
+			}
201
+			new->funcdecl->args = idl_copy(old->funcdecl->args);
202
+			new->funcdecl->body = st_copy(old->funcdecl->body);
203
+			break;
204
+
205
+		default:
206
+			printf("WARNING: Unknown expression type to copy: %d\n", old->type);
207
+			break;
208
+	}
209
+	return new;
210
+}
211
+
212
+assoclist_node *asl_copy(assoclist_node *old) {
213
+	assoclist_node *new, *curn, *curo;
214
+	if(!old) {
215
+		return NULL;
216
+	}
217
+	new = NEW(assoclist_node);
218
+	curn = new;
219
+	curo = old;
220
+	while(curo) {
221
+		if(curo->item && curo->item->key && curo->item->value) {
222
+			curn->item = NEW(associtem_node);
223
+			curn->item->key = ex_copy(curo->item->key);
224
+			curn->item->value = ex_copy(curo->item->value);
225
+		} else {
226
+			curn->item = NULL;
227
+		}
228
+		if(curo->next) {
229
+			curn->next = NEW(assoclist_node);
230
+			curn = curn->next;
231
+		}
232
+		curo = curo->next;
233
+	}
234
+	curn->next = NULL;
235
+	return new;
236
+}
237
+
238
+exprlist_node *exl_copy(exprlist_node *old) {
239
+	exprlist_node *new, *curn, *curo;
240
+	if(!old) {
241
+		return NULL;
242
+	}
243
+	new = NEW(exprlist_node);
244
+	curn = new;
245
+	curo = old;
246
+	while(curo) {
247
+		if(curo->expr) {
248
+			curn->expr = ex_copy(curo->expr);
249
+		} else {
250
+			curn->expr = NULL;
251
+		}
252
+		if(curo->next) {
253
+			curn->next = NEW(exprlist_node);
254
+			curn = curn->next;
255
+		}
256
+		curo = curo->next;
257
+	}
258
+	curn->next = NULL;
259
+	return new;
260
+}
261
+
262
+identlist_node *idl_copy(identlist_node *old) {
263
+	identlist_node *new, *curn, *curo;
264
+	if(!old) {
265
+		return NULL;
266
+	}
267
+	new = NEW(identlist_node);
268
+	curn = new;
269
+	curo = old;
270
+	while(curo) {
271
+		if(curo->ident) {
272
+			curn->ident = strdup(curo->ident);
273
+		} else {
274
+			curn->ident = NULL;
275
+		}
276
+		if(curo->next) {
277
+			curn->next = NEW(identlist_node);
278
+			curn = curn->next;
279
+		}
280
+		curo = curo->next;
281
+	}
282
+	curn->next = NULL;
283
+	return new;
284
+}
285
+
17 286
 void ex_free(expr_node *);
18 287
 
19 288
 void st_free(stmt_node *stmt) {
@@ -47,15 +316,7 @@ void st_free(stmt_node *stmt) {
47 316
 			break;
48 317
 
49 318
 		case ST_LIST:
50
-			curs = stmt->stmtlist;
51
-			while(curs) {
52
-				if(curs->stmt) {
53
-					st_free(curs->stmt);
54
-				}
55
-				prevs = curs;
56
-				curs = curs->next;
57
-				free(prevs);
58
-			}
319
+			stl_free(stmt->stmtlist);
59 320
 			break;
60 321
 
61 322
 		case ST_RET:
@@ -70,6 +331,18 @@ void st_free(stmt_node *stmt) {
70 331
 	free(stmt);
71 332
 }
72 333
 
334
+void stl_free(stmtlist_node *list) {
335
+	stmtlist_node *cur = list, *prev;
336
+	while(cur) {
337
+		if(cur->stmt) {
338
+			free(cur->stmt);
339
+		}
340
+		prev = cur;
341
+		cur = cur->next;
342
+		free(prev);
343
+	}
344
+}
345
+
73 346
 void ex_free(expr_node *expr) {
74 347
 	exprlist_node *cure, *preve;
75 348
 	assoclist_node *cura, *preva;
@@ -86,30 +359,12 @@ void ex_free(expr_node *expr) {
86 359
 			break;
87 360
 
88 361
 		case EX_LISTGEN:
89
-			cure = expr->listgen->list;
90
-			while(cure) {
91
-				if(cure->expr) {
92
-					ex_free(cure->expr);
93
-				}
94
-				preve = cure;
95
-				cure = cure->next;
96
-				free(preve);
97
-			}
362
+			exl_free(expr->listgen->list);
98 363
 			free(expr->listgen);
99 364
 			break;
100 365
 
101 366
 		case EX_MAPGEN:
102
-			cura = expr->mapgen->map;
103
-			while(cura) {
104
-				if(cura->item) {
105
-					ex_free(cura->item->key);
106
-					ex_free(cura->item->value);
107
-					free(cura->item);
108
-				}
109
-				preva = cura;
110
-				cura = cura->next;
111
-				free(preva);
112
-			}
367
+			asl_free(expr->mapgen->map);
113 368
 			free(expr->mapgen);
114 369
 			break;
115 370
 
@@ -150,36 +405,58 @@ void ex_free(expr_node *expr) {
150 405
 
151 406
 		case EX_CALL:
152 407
 			ex_free(expr->call->expr);
153
-			cure = expr->call->args;
154
-			while(cure) {
155
-				if(cure->expr) {
156
-					ex_free(cure->expr);
157
-				}
158
-				preve = cure;
159
-				cure = cure->next;
160
-				free(preve);
161
-			}
408
+			exl_free(expr->call->args);
162 409
 			free(expr->call);
163 410
 			break;
164 411
 
165 412
 		case EX_FUNCDECL:
166 413
 			free(expr->funcdecl->name);
167 414
 			st_free(expr->funcdecl->body);
168
-			curi = expr->funcdecl->args;
169
-			while(curi) {
170
-				if(curi->ident) {
171
-					free(curi->ident);
172
-				}
173
-				previ = curi;
174
-				curi = curi->next;
175
-				free(previ);
176
-			}
415
+			idl_free(expr->funcdecl->args);
177 416
 			free(expr->funcdecl);
178 417
 			break;
179 418
 	}
180 419
 	free(expr);
181 420
 }
182 421
 
422
+void exl_free(exprlist_node *list) {
423
+	exprlist_node *cur = list, *prev;
424
+	while(cur) {
425
+		if(cur->expr) {
426
+			free(cur->expr);
427
+		}
428
+		prev = cur;
429
+		cur = cur->next;
430
+		free(prev);
431
+	}
432
+}
433
+
434
+void asl_free(assoclist_node *list) {
435
+	assoclist_node *cur = list, *prev;
436
+	while(cur) {
437
+		if(cur->item) {
438
+			free(cur->item->key);
439
+			free(cur->item->value);
440
+			free(cur->item);
441
+		}
442
+		prev = cur;
443
+		cur = cur->next;
444
+		free(prev);
445
+	}
446
+}
447
+
448
+void idl_free(identlist_node *list) {
449
+	identlist_node *cur = list, *prev;
450
+	while(cur) {
451
+		if(cur->ident) {
452
+			free(cur->ident);
453
+		}
454
+		prev = cur;
455
+		cur = cur->next;
456
+		free(prev);
457
+	}
458
+}
459
+
183 460
 #define ERR_CHECK(state) do { if(sol_has_error(state)) longjmp(jmp, 1); } while(0)
184 461
 sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
185 462
 	sol_object_t *res, *left, *right, *lint, *rint, *value, *list;
@@ -504,7 +781,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
504 781
 		case ST_EXPR:
505 782
 			sol_obj_free(sol_eval(state, stmt->expr));
506 783
 			if(sol_has_error(state)) {
507
-				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
784
+				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
508 785
 			}
509 786
 			break;
510 787
 
@@ -523,7 +800,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
523 800
 			sol_obj_free(value);
524 801
 			sol_obj_free(vint);
525 802
 			if(sol_has_error(state)) {
526
-				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
803
+				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
527 804
 			}
528 805
 			break;
529 806
 
@@ -545,7 +822,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
545 822
 			}
546 823
 			state->sflag = SF_NORMAL;
547 824
 			if(sol_has_error(state)) {
548
-				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
825
+				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
549 826
 			}
550 827
 			sol_obj_free(value);
551 828
 			sol_obj_free(vint);
@@ -582,7 +859,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
582 859
 			}
583 860
 			state->sflag = SF_NORMAL;
584 861
 			if(sol_has_error(state)) {
585
-				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
862
+				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
586 863
 			}
587 864
 			sol_obj_free(iter);
588 865
 			sol_obj_free(value);
@@ -599,7 +876,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
599 876
 				curs = curs->next;
600 877
 			}
601 878
 			if(sol_has_error(state)) {
602
-				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
879
+				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
603 880
 			}
604 881
 			break;
605 882
 
@@ -610,7 +887,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
610 887
 				state->ret = sol_incref(state->None);
611 888
 			}
612 889
 			if(sol_has_error(state)) {
613
-				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
890
+				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
614 891
 			}
615 892
 			break;
616 893
 
@@ -682,8 +959,8 @@ sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
682 959
 
683 960
 sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_node *body, char *name) {
684 961
 	sol_object_t *obj = sol_alloc_object(state);
685
-	obj->func = body;
686
-	obj->args = identlist;
962
+	obj->func = st_copy(body);
963
+	obj->args = idl_copy(identlist);
687 964
 	obj->fname = (name ? strdup(name) : NULL);
688 965
 	obj->closure = sol_new_map(state);
689 966
 	obj->udata = sol_new_map(state);
@@ -692,11 +969,20 @@ sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_n
692 969
 	return obj;
693 970
 }
694 971
 
972
+sol_object_t *sol_f_func_free(sol_state_t *state, sol_object_t *func) {
973
+	st_free((stmt_node *) func->func);
974
+	idl_free((identlist_node *) func->args);
975
+	if(func->fname) free(func->fname);
976
+	sol_obj_free(func->closure);
977
+	sol_obj_free(func->udata);
978
+	return func;
979
+}
980
+
695 981
 sol_object_t *sol_new_stmtnode(sol_state_t *state, stmt_node *stmt) {
696 982
 	sol_object_t *obj = sol_alloc_object(state);
697 983
 	obj->type = SOL_STMT;
698 984
 	obj->ops = &(state->ASTNodeOps);
699
-	obj->node = stmt;
985
+	obj->node = st_copy(stmt);
700 986
 	return obj;
701 987
 }
702 988
 
@@ -704,6 +990,6 @@ sol_object_t *sol_new_exprnode(sol_state_t *state, expr_node *expr) {
704 990
 	sol_object_t *obj = sol_alloc_object(state);
705 991
 	obj->type = SOL_EXPR;
706 992
 	obj->ops = &(state->ASTNodeOps);
707
-	obj->node = expr;
993
+	obj->node = ex_copy(expr);
708 994
 	return obj;
709 995
 }

+ 11
- 9
sol.h View File

@@ -237,6 +237,7 @@ void sol_register_methods_name(sol_state_t *, char *, sol_object_t *);
237 237
 sol_object_t *sol_get_methods(sol_state_t *, sol_object_t *);
238 238
 sol_object_t *sol_get_methods_name(sol_state_t *, char *);
239 239
 
240
+sol_object_t *sol_f_io_index(sol_state_t *, sol_object_t *);
240 241
 sol_object_t *sol_f_io_setindex(sol_state_t *, sol_object_t *);
241 242
 sol_object_t *sol_get_stdin(sol_state_t *);
242 243
 sol_object_t *sol_get_stdout(sol_state_t *);
@@ -458,15 +459,15 @@ sol_object_t *sol_map_get(sol_state_t *, sol_object_t *, sol_object_t *);
458 459
 sol_object_t *sol_map_get_name(sol_state_t *, sol_object_t *, char *);
459 460
 void sol_map_set(sol_state_t *, sol_object_t *, sol_object_t *, sol_object_t *);
460 461
 #define sol_map_borrow(state, map, key, object) do {\
461
-	sol_object_t *_obj = (object);\
462
-	sol_map_set((state), (map), (key), _obj);\
463
-	sol_obj_free(_obj);\
462
+	sol_object_t *__obj = (object);\
463
+	sol_map_set((state), (map), (key), __obj);\
464
+	sol_obj_free(__obj);\
464 465
 } while(0)
465 466
 void sol_map_set_name(sol_state_t *, sol_object_t *, char *, sol_object_t *);
466 467
 #define sol_map_borrow_name(state, map, str, object) do {\
467
-	sol_object_t *_obj = (object);\
468
-	sol_map_set_name((state), (map), (str), _obj);\
469
-	sol_obj_free(_obj);\
468
+	sol_object_t *__obj = (object);\
469
+	sol_map_set_name((state), (map), (str), __obj);\
470
+	sol_obj_free(__obj);\
470 471
 } while(0)
471 472
 void sol_map_set_existing(sol_state_t *, sol_object_t *, sol_object_t *, sol_object_t *);
472 473
 sol_object_t *sol_map_copy(sol_state_t *, sol_object_t *);
@@ -497,9 +498,9 @@ size_t sol_stream_fwrite(sol_state_t *, sol_object_t *, char *, size_t, size_t);
497 498
 char *sol_stream_fgets(sol_state_t *, sol_object_t *, char *, size_t);
498 499
 int sol_stream_fputc(sol_state_t *, sol_object_t *, int);
499 500
 #define _sol_io_on(state, op, strname, ...) do {\
500
-	sol_object_t *str = sol_get_##strname(state);\
501
-	sol_stream_##op((state), str, __VA_ARGS__);\
502
-	sol_obj_free(str);\
501
+	sol_object_t *__str = sol_get_##strname(state);\
502
+	sol_stream_##op((state), __str, __VA_ARGS__);\
503
+	sol_obj_free(__str);\
503 504
 } while(0)
504 505
 #define sol_printf(state, ...) _sol_io_on(state, printf, stdout, __VA_ARGS__)
505 506
 #define sol_vprintf(state, ...) _sol_io_on(state, vprintf, stdout, __VA_ARGS__)
@@ -524,6 +525,7 @@ sol_object_t *sol_f_str_free(sol_state_t *, sol_object_t *);
524 525
 sol_object_t *sol_f_list_free(sol_state_t *, sol_object_t *);
525 526
 sol_object_t *sol_f_map_free(sol_state_t *, sol_object_t *);
526 527
 sol_object_t *sol_f_mcell_free(sol_state_t *, sol_object_t *);
528
+sol_object_t *sol_f_func_free(sol_state_t *, sol_object_t *);
527 529
 sol_object_t *sol_f_astnode_free(sol_state_t *, sol_object_t *);
528 530
 sol_object_t *sol_f_buffer_free(sol_state_t *, sol_object_t *);
529 531
 sol_object_t *sol_f_dylib_free(sol_state_t *, sol_object_t *);

+ 29
- 3
state.c View File

@@ -131,6 +131,7 @@ int sol_state_init(sol_state_t *state) {
131 131
 	state->FuncOps.index = sol_f_func_index;
132 132
 	state->FuncOps.setindex = sol_f_func_setindex;
133 133
 	state->FuncOps.tostring = sol_f_func_tostring;
134
+	state->FuncOps.free = sol_f_func_free;
134 135
 
135 136
 	state->CFuncOps.tname = "cfunction";
136 137
 	state->CFuncOps.call = sol_f_cfunc_call;
@@ -387,11 +388,9 @@ int sol_state_init(sol_state_t *state) {
387 388
 	sol_map_borrow_name(state, mod, "SEEK_END", sol_new_int(state, SEEK_END));
388 389
 	sol_map_borrow_name(state, mod, "ALL", sol_new_string(state, "ALL"));
389 390
 	sol_map_borrow_name(state, mod, "LINE", sol_new_string(state, "LINE"));
390
-	sol_map_borrow_name(state, mod, "stdin", sol_new_stream(state, stdin, MODE_READ));
391
-	sol_map_borrow_name(state, mod, "stdout", sol_new_stream(state, stdout, MODE_WRITE));
392
-	sol_map_borrow_name(state, mod, "stderr", sol_new_stream(state, stderr, MODE_WRITE));
393 391
 	sol_map_borrow_name(state, mod, "open", sol_new_cfunc(state, sol_f_stream_open));
394 392
 	sol_map_borrow_name(state, mod, "__setindex", sol_new_cfunc(state, sol_f_io_setindex));
393
+	sol_map_borrow_name(state, mod, "__index", sol_new_cfunc(state, sol_f_io_index));
395 394
 	sol_register_module_name(state, "io", mod);
396 395
 	sol_obj_free(mod);
397 396
 
@@ -664,18 +663,45 @@ sol_object_t *sol_get_methods_name(sol_state_t *state, char *name) {
664 663
 	return sol_map_get_name(state, state->methods, name);
665 664
 }
666 665
 
666
+sol_object_t *sol_f_io_index(sol_state_t *state, sol_object_t *args) {
667
+	sol_object_t *self = sol_list_get_index(state, args, 0), *name = sol_list_get_index(state, args, 1), *namestr = sol_cast_string(state, name), *res;
668
+	if(sol_string_eq(state, namestr, "stdin")) {
669
+		sol_obj_free(name);
670
+		sol_obj_free(namestr);
671
+		return sol_incref(state->stdin);
672
+	}
673
+	if(sol_string_eq(state, namestr, "stdout")) {
674
+		sol_obj_free(name);
675
+		sol_obj_free(namestr);
676
+		return sol_incref(state->stdout);
677
+	}
678
+	if(sol_string_eq(state, namestr, "stderr")) {
679
+		sol_obj_free(name);
680
+		sol_obj_free(namestr);
681
+		return sol_incref(state->stderr);
682
+	}
683
+	sol_obj_free(namestr);
684
+	res = sol_map_get(state, self, name);
685
+	sol_obj_free(self);
686
+	sol_obj_free(name);
687
+	return res;
688
+}
689
+
667 690
 sol_object_t *sol_f_io_setindex(sol_state_t *state, sol_object_t *args) {
668 691
 	sol_object_t *name = sol_list_get_index(state, args, 1), *value = sol_list_get_index(state, args, 2);
669 692
 	sol_object_t *namestr = sol_cast_string(state, name), *io;
670 693
 	if(sol_string_eq(state, namestr, "stdin")) {
694
+		sol_obj_free(state->stdin);
671 695
 		state->stdin = sol_incref(value);
672 696
 		goto done;
673 697
 	}
674 698
 	if(sol_string_eq(state, namestr, "stdout")) {
699
+		sol_obj_free(state->stdout);
675 700
 		state->stdout = sol_incref(value);
676 701
 		goto done;
677 702
 	}
678 703
 	if(sol_string_eq(state, namestr, "stderr")) {
704
+		sol_obj_free(state->stderr);
679 705
 		state->stderr = sol_incref(value);
680 706
 		goto done;
681 707
 	}

+ 3
- 1
test.sol View File

@@ -331,7 +331,9 @@ print('(buffer.sizeof.ptr = ', buffer.sizeof.ptr, ')')
331 331
 print('(buffer.sizeof.int = ', buffer.sizeof.int, ')')
332 332
 print('(buffer.sizeof.int*2 = ', buffer.sizeof.int*2, ')')
333 333
 print('(buffer.sizeof.int*2 + buffer.sizeof.ptr = ', buffer.sizeof.int*2 + (buffer.sizeof.ptr), ')')
334
-print('...with value:', b:get(buffer.type.ptr, buffer.sizeof.int*2 + (buffer.sizeof.ptr)):get(buffer.type.cstr))
334
+bs = b:get(buffer.type.ptr, buffer.sizeof.int*2 + (buffer.sizeof.ptr))
335
+print('...string buffer:', bs)
336
+print('...with value:', bs:get(buffer.type.cstr))
335 337
 
336 338
 print('--- IO redirection')
337 339
 

Loading…
Cancel
Save