Browse Source

Merge pull request #15 from sol-lang/grissess_stmt-exprs

Sol Part 43: EXPRESSIONS EVERYWHERE
Benjamin Lannon 5 years ago
parent
commit
7ff1611a5d
10 changed files with 9599 additions and 8412 deletions
  1. 30
    20
      ast.h
  2. 34
    32
      astprint.c
  3. 93
    67
      builtins.c
  4. 8665
    7663
      parser.output
  5. 589
    516
      parser.tab.c
  6. 43
    6
      parser.y
  7. 8
    0
      programs/fizzbuzz.sol
  8. 125
    103
      runtime.c
  9. 4
    2
      sol.h
  10. 8
    3
      state.c

+ 30
- 20
ast.h View File

@@ -98,7 +98,24 @@ typedef struct {
98 98
 	stmt_node *body;
99 99
 } funcdecl_node;
100 100
 
101
-typedef enum {EX_LIT, EX_LISTGEN, EX_MAPGEN, EX_BINOP, EX_UNOP, EX_INDEX, EX_SETINDEX, EX_ASSIGN, EX_REF, EX_CALL, EX_FUNCDECL} expr_t;
101
+typedef struct {
102
+	expr_node *cond;
103
+	stmt_node *iftrue;
104
+	stmt_node *iffalse;
105
+} ifelse_node;
106
+
107
+typedef struct {
108
+	expr_node *cond;
109
+	stmt_node *loop;
110
+} loop_node;
111
+
112
+typedef struct {
113
+	char *var;
114
+	expr_node *iter;
115
+	stmt_node *loop;
116
+} iter_node;
117
+
118
+typedef enum {EX_LIT, EX_LISTGEN, EX_MAPGEN, EX_BINOP, EX_UNOP, EX_INDEX, EX_SETINDEX, EX_ASSIGN, EX_REF, EX_CALL, EX_FUNCDECL, EX_IFELSE, EX_LOOP, EX_ITER} expr_t;
102 119
 typedef struct tag_expr_node {
103 120
 	expr_t type;
104 121
 	loc_t loc;
@@ -114,46 +131,39 @@ typedef struct tag_expr_node {
114 131
 		ref_node *ref;
115 132
 		call_node *call;
116 133
 		funcdecl_node *funcdecl;
134
+		ifelse_node *ifelse;
135
+		loop_node *loop;
136
+		iter_node *iter;
117 137
 	};
118 138
 } expr_node;
119 139
 
120 140
 typedef struct {
121
-	expr_node *cond;
122
-	stmt_node *iftrue;
123
-	stmt_node *iffalse;
124
-} ifelse_node;
125
-
126
-typedef struct {
127
-	expr_node *cond;
128
-	stmt_node *loop;
129
-} loop_node;
141
+	expr_node *ret;
142
+} ret_node;
130 143
 
131 144
 typedef struct {
132
-	char *var;
133
-	expr_node *iter;
134
-	stmt_node *loop;
135
-} iter_node;
145
+	expr_node *val;
146
+} cont_node;
136 147
 
137 148
 typedef struct {
138
-	expr_node *ret;
139
-} ret_node;
149
+	expr_node *val;
150
+} break_node;
140 151
 
141 152
 typedef struct tag_stmtlist_node {
142 153
 	stmt_node *stmt;
143 154
 	struct tag_stmtlist_node *next;
144 155
 } stmtlist_node;
145 156
 
146
-typedef enum {ST_EXPR, ST_IFELSE, ST_LOOP, ST_ITER, ST_LIST, ST_RET, ST_CONT, ST_BREAK} stmt_t;
157
+typedef enum {ST_EXPR, ST_LIST, ST_RET, ST_CONT, ST_BREAK} stmt_t;
147 158
 typedef struct tag_stmt_node {
148 159
 	stmt_t type;
149 160
 	loc_t loc;
150 161
 	union {
151 162
 		expr_node *expr;
152
-		ifelse_node *ifelse;
153
-		loop_node *loop;
154
-		iter_node *iter;
155 163
 		stmtlist_node *stmtlist;
156 164
 		ret_node *ret;
165
+		cont_node *cont;
166
+		break_node *brk;
157 167
 	};
158 168
 } stmt_node;
159 169
 

+ 34
- 32
astprint.c View File

@@ -31,36 +31,6 @@ void prst(sol_state_t *state, stmt_node *node, int lev) {
31 31
 			prex(state, node->expr, lev + 1);
32 32
 			break;
33 33
 
34
-		case ST_IFELSE:
35
-			prlev(state, lev, "Stmt<IfElse>:");
36
-			lev++;
37
-			prlev(state, lev, "Cond:");
38
-			prex(state, node->ifelse->cond, lev + 1);
39
-			prlev(state, lev, "IfTrue:");
40
-			prst(state, node->ifelse->iftrue, lev + 1);
41
-			prlev(state, lev, "IfFalse:");
42
-			prst(state, node->ifelse->iffalse, lev + 1);
43
-			break;
44
-
45
-		case ST_LOOP:
46
-			prlev(state, lev, "Stmt<Loop>:");
47
-			lev++;
48
-			prlev(state, lev, "Cond:");
49
-			prex(state, node->loop->cond, lev + 1);
50
-			prlev(state, lev, "Loop:");
51
-			prst(state, node->loop->loop, lev + 1);
52
-			break;
53
-
54
-		case ST_ITER:
55
-			prlev(state, lev, "Stmt<Iter>:");
56
-			lev++;
57
-			prlev(state, lev, "Var: %s", node->iter->var);
58
-			prlev(state, lev, "Iter:");
59
-			prex(state, node->iter->iter, lev + 1);
60
-			prlev(state, lev, "Loop:");
61
-			prst(state, node->iter->loop, lev + 1);
62
-			break;
63
-
64 34
 		case ST_LIST:
65 35
 			prlev(state, lev, "Stmt<List>:");
66 36
 			stmtlist_node *cur = node->stmtlist;
@@ -76,11 +46,13 @@ void prst(sol_state_t *state, stmt_node *node, int lev) {
76 46
 			break;
77 47
 
78 48
 		case ST_CONT:
79
-			prlev(state, lev, "Stmt<Continue>");
49
+			prlev(state, lev, "Stmt<Continue>:");
50
+			prex(state, node->cont->val, lev + 1);
80 51
 			break;
81 52
 
82 53
 		case ST_BREAK:
83
-			prlev(state, lev, "Stmt<Break>");
54
+			prlev(state, lev, "Stmt<Break>:");
55
+			prex(state, node->brk->val, lev + 1);
84 56
 			break;
85 57
 	}
86 58
 }
@@ -306,6 +278,36 @@ void prex(sol_state_t *state, expr_node *node, int lev) {
306 278
 			prlev(state, lev, "Body:");
307 279
 			prst(state, node->funcdecl->body, lev + 1);
308 280
 			break;
281
+
282
+		case EX_IFELSE:
283
+			prlev(state, lev, "Expr<IfElse>:");
284
+			lev++;
285
+			prlev(state, lev, "Cond:");
286
+			prex(state, node->ifelse->cond, lev + 1);
287
+			prlev(state, lev, "IfTrue:");
288
+			prst(state, node->ifelse->iftrue, lev + 1);
289
+			prlev(state, lev, "IfFalse:");
290
+			prst(state, node->ifelse->iffalse, lev + 1);
291
+			break;
292
+
293
+		case EX_LOOP:
294
+			prlev(state, lev, "Expr<Loop>:");
295
+			lev++;
296
+			prlev(state, lev, "Cond:");
297
+			prex(state, node->loop->cond, lev + 1);
298
+			prlev(state, lev, "Loop:");
299
+			prst(state, node->loop->loop, lev + 1);
300
+			break;
301
+
302
+		case EX_ITER:
303
+			prlev(state, lev, "Expr<Iter>:");
304
+			lev++;
305
+			prlev(state, lev, "Var: %s", node->iter->var);
306
+			prlev(state, lev, "Iter:");
307
+			prex(state, node->iter->iter, lev + 1);
308
+			prlev(state, lev, "Loop:");
309
+			prst(state, node->iter->loop, lev + 1);
310
+			break;
309 311
 	}
310 312
 }
311 313
 

+ 93
- 67
builtins.c View File

@@ -1572,34 +1572,6 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1572 1572
 					}
1573 1573
 					break;
1574 1574
 
1575
-				case ST_IFELSE:
1576
-					if(sol_string_eq(state, str, "cond")) {
1577
-						res = sol_new_exprnode(state, ex_copy(stmt->ifelse->cond));
1578
-					} else if(sol_string_eq(state, str, "iftrue")) {
1579
-						res = sol_new_stmtnode(state, st_copy(stmt->ifelse->iftrue));
1580
-					} else if(sol_string_eq(state, str, "iffalse")) {
1581
-						res = sol_new_stmtnode(state, st_copy(stmt->ifelse->iffalse));
1582
-					}
1583
-					break;
1584
-
1585
-				case ST_LOOP:
1586
-					if(sol_string_eq(state, str, "cond")) {
1587
-						res = sol_new_exprnode(state, ex_copy(stmt->loop->cond));
1588
-					} else if(sol_string_eq(state, str, "loop")) {
1589
-						res = sol_new_stmtnode(state, st_copy(stmt->loop->loop));
1590
-					}
1591
-					break;
1592
-
1593
-				case ST_ITER:
1594
-					if(sol_string_eq(state, str, "var")) {
1595
-						res = sol_new_string(state, stmt->iter->var);
1596
-					} else if(sol_string_eq(state, str, "iter")) {
1597
-						res = sol_new_exprnode(state, ex_copy(stmt->iter->iter));
1598
-					} else if(sol_string_eq(state, str, "loop")) {
1599
-						res = sol_new_stmtnode(state, st_copy(stmt->iter->loop));
1600
-					}
1601
-					break;
1602
-
1603 1575
 				case ST_LIST:
1604 1576
 					if(sol_string_eq(state, str, "stmtlist")) {
1605 1577
 						res = sol_new_list(state);
@@ -1616,6 +1588,18 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1616 1588
 						res = sol_new_exprnode(state, ex_copy(stmt->ret->ret));
1617 1589
 					}
1618 1590
 					break;
1591
+
1592
+				case ST_CONT:
1593
+					if(sol_string_eq(state, str, "val")) {
1594
+						res = sol_new_exprnode(state, ex_copy(stmt->cont->val));
1595
+					}
1596
+					break;
1597
+
1598
+				case ST_BREAK:
1599
+					if(sol_string_eq(state, str, "val")) {
1600
+						res = sol_new_exprnode(state, ex_copy(stmt->brk->val));
1601
+					}
1602
+					break;
1619 1603
 			}
1620 1604
 		}
1621 1605
 	} else {
@@ -1741,6 +1725,34 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1741 1725
 						res = sol_new_stmtnode(state, st_copy(expr->funcdecl->body));
1742 1726
 					}
1743 1727
 					break;
1728
+
1729
+				case EX_IFELSE:
1730
+					if(sol_string_eq(state, str, "cond")) {
1731
+						res = sol_new_exprnode(state, ex_copy(expr->ifelse->cond));
1732
+					} else if(sol_string_eq(state, str, "iftrue")) {
1733
+						res = sol_new_stmtnode(state, st_copy(expr->ifelse->iftrue));
1734
+					} else if(sol_string_eq(state, str, "iffalse")) {
1735
+						res = sol_new_stmtnode(state, st_copy(expr->ifelse->iffalse));
1736
+					}
1737
+					break;
1738
+
1739
+				case EX_LOOP:
1740
+					if(sol_string_eq(state, str, "cond")) {
1741
+						res = sol_new_exprnode(state, ex_copy(expr->loop->cond));
1742
+					} else if(sol_string_eq(state, str, "loop")) {
1743
+						res = sol_new_stmtnode(state, st_copy(expr->loop->loop));
1744
+					}
1745
+					break;
1746
+
1747
+				case EX_ITER:
1748
+					if(sol_string_eq(state, str, "var")) {
1749
+						res = sol_new_string(state, expr->iter->var);
1750
+					} else if(sol_string_eq(state, str, "iter")) {
1751
+						res = sol_new_exprnode(state, ex_copy(expr->iter->iter));
1752
+					} else if(sol_string_eq(state, str, "loop")) {
1753
+						res = sol_new_stmtnode(state, st_copy(expr->iter->loop));
1754
+					}
1755
+					break;
1744 1756
 			}
1745 1757
 		}
1746 1758
 	}
@@ -1795,43 +1807,6 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1795 1807
 					}
1796 1808
 					break;
1797 1809
 
1798
-				case ST_IFELSE:
1799
-					if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
1800
-						ex_free(stmt->ifelse->cond);
1801
-						stmt->ifelse->cond = ex_copy(val->node);
1802
-					} else if(sol_string_eq(state, str, "iftrue") && sol_is_aststmt(val)) {
1803
-						st_free(stmt->ifelse->iftrue);
1804
-						stmt->ifelse->iftrue = st_copy(val->node);
1805
-					} else if(sol_string_eq(state, str, "iffalse") && sol_is_aststmt(val)) {
1806
-						st_free(stmt->ifelse->iffalse);
1807
-						stmt->ifelse->iffalse = st_copy(val->node);
1808
-					}
1809
-					break;
1810
-
1811
-				case ST_LOOP:
1812
-					if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
1813
-						ex_free(stmt->loop->cond);
1814
-						stmt->loop->cond = ex_copy(val->node);
1815
-					} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
1816
-						st_free(stmt->loop->loop);
1817
-						stmt->loop->loop = st_copy(val->node);
1818
-					}
1819
-					break;
1820
-
1821
-				case ST_ITER:
1822
-					if(sol_string_eq(state, str, "var")) {
1823
-						sval = sol_cast_string(state, val);
1824
-						stmt->iter->var = strdup(sval->str);
1825
-						sol_obj_free(sval);
1826
-					} else if(sol_string_eq(state, str, "iter") && sol_is_astexpr(val)) {
1827
-						ex_free(stmt->iter->iter);
1828
-						stmt->iter->iter = ex_copy(val->node);
1829
-					} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
1830
-						st_free(stmt->iter->loop);
1831
-						stmt->iter->loop = st_copy(val->node);
1832
-					}
1833
-					break;
1834
-
1835 1810
 				case ST_LIST:
1836 1811
 					if(sol_string_eq(state, str, "stmtlist") && sol_is_list(val)) {
1837 1812
 						stl_free(stmt->stmtlist);
@@ -1866,6 +1841,20 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1866 1841
 						stmt->ret->ret = ex_copy(val->node);
1867 1842
 					}
1868 1843
 					break;
1844
+
1845
+				case ST_CONT:
1846
+					if(sol_string_eq(state, str, "val") && sol_is_astexpr(val)) {
1847
+						ex_free(stmt->cont->val);
1848
+						stmt->cont->val = ex_copy(val->node);
1849
+					}
1850
+					break;
1851
+
1852
+				case ST_BREAK:
1853
+					if(sol_string_eq(state, str, "val") && sol_is_astexpr(val)) {
1854
+						ex_free(stmt->brk->val);
1855
+						stmt->brk->val = ex_copy(val->node);
1856
+					}
1857
+					break;
1869 1858
 			}
1870 1859
 		}
1871 1860
 	} else {
@@ -2099,6 +2088,43 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
2099 2088
 						expr->funcdecl->body = st_copy(val->node);
2100 2089
 					}
2101 2090
 					break;
2091
+
2092
+				case EX_IFELSE:
2093
+					if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
2094
+						ex_free(expr->ifelse->cond);
2095
+						expr->ifelse->cond = ex_copy(val->node);
2096
+					} else if(sol_string_eq(state, str, "iftrue") && sol_is_aststmt(val)) {
2097
+						st_free(expr->ifelse->iftrue);
2098
+						expr->ifelse->iftrue = st_copy(val->node);
2099
+					} else if(sol_string_eq(state, str, "iffalse") && sol_is_aststmt(val)) {
2100
+						st_free(expr->ifelse->iffalse);
2101
+						expr->ifelse->iffalse = st_copy(val->node);
2102
+					}
2103
+					break;
2104
+
2105
+				case EX_LOOP:
2106
+					if(sol_string_eq(state, str, "cond") && sol_is_astexpr(val)) {
2107
+						ex_free(expr->loop->cond);
2108
+						expr->loop->cond = ex_copy(val->node);
2109
+					} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
2110
+						st_free(expr->loop->loop);
2111
+						expr->loop->loop = st_copy(val->node);
2112
+					}
2113
+					break;
2114
+
2115
+				case EX_ITER:
2116
+					if(sol_string_eq(state, str, "var")) {
2117
+						sval = sol_cast_string(state, val);
2118
+						expr->iter->var = strdup(sval->str);
2119
+						sol_obj_free(sval);
2120
+					} else if(sol_string_eq(state, str, "iter") && sol_is_astexpr(val)) {
2121
+						ex_free(expr->iter->iter);
2122
+						expr->iter->iter = ex_copy(val->node);
2123
+					} else if(sol_string_eq(state, str, "loop") && sol_is_aststmt(val)) {
2124
+						st_free(expr->iter->loop);
2125
+						expr->iter->loop = st_copy(val->node);
2126
+					}
2127
+					break;
2102 2128
 			}
2103 2129
 		}
2104 2130
 	}
@@ -2108,8 +2134,8 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
2108 2134
 	return val;
2109 2135
 }
2110 2136
 
2111
-static char *sol_StmtNames[] = {"EXPR", "IFSELSE", "LOOP", "ITER", "LIST", "RET", "CONT", "BREAK"};
2112
-static char *sol_ExprNames[] = {"LIT", "LISTGEN", "MAPGEN", "BINOP", "UNOP", "INDEX", "SETINDEX", "ASSIGN", "REF", "CALL", "FUNCDECL"};
2137
+static char *sol_StmtNames[] = {"EXPR", "LIST", "RET", "CONT", "BREAK"};
2138
+static char *sol_ExprNames[] = {"LIT", "LISTGEN", "MAPGEN", "BINOP", "UNOP", "INDEX", "SETINDEX", "ASSIGN", "REF", "CALL", "FUNCDECL", "IFELSE", "LOOP", "ITER"};
2113 2139
 
2114 2140
 sol_object_t *sol_f_astnode_tostring(sol_state_t *state, sol_object_t *args) {
2115 2141
 	sol_object_t *obj = sol_list_get_index(state, args, 0), *res;

+ 8665
- 7663
parser.output
File diff suppressed because it is too large
View File


+ 589
- 516
parser.tab.c
File diff suppressed because it is too large
View File


+ 43
- 6
parser.y View File

@@ -56,18 +56,55 @@ stmt_list:
56 56
 
57 57
 stmt:
58 58
   expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_EXPR; AS_ST($$)->expr = $1; }
59
-| IF expr THEN stmt_list END { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_IFELSE; AS_ST($$)->ifelse = NEW(ifelse_node); AS_ST($$)->ifelse->cond = $2; AS_ST($$)->ifelse->iftrue = $4; AS_ST($$)->ifelse->iffalse = NULL; }
60
-| IF expr THEN stmt_list ELSE stmt_list END { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_IFELSE; AS_ST($$)->ifelse = NEW(ifelse_node); AS_ST($$)->ifelse->cond = $2; AS_ST($$)->ifelse->iftrue = $4; AS_ST($$)->ifelse->iffalse = $6; }
61
-| WHILE expr DO stmt_list END { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_LOOP; AS_ST($$)->loop = NEW(loop_node); AS_ST($$)->loop->cond = $2; AS_ST($$)->loop->loop = $4; }
62
-| FOR IDENT IN expr DO stmt_list END { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_ITER; AS_ST($$)->iter = NEW(iter_node); AS_ST($$)->iter->var = $2; AS_ST($$)->iter->iter = $4; AS_ST($$)->iter->loop = $6; }
63 59
 | RETURN expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = $2; }
64 60
 | RETURN { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = NULL; }
65
-| BREAK { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_BREAK; }
66
-| CONTINUE { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_CONT; }
61
+| BREAK { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_BREAK; AS_ST($$)->brk = NEW(break_node); }
62
+| BREAK expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_BREAK; AS_ST($$)->brk = NEW(break_node); AS_ST($$)->brk->val = $2; }
63
+| CONTINUE { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_CONT; AS_ST($$)->cont = NEW(cont_node); }
64
+| CONTINUE expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_CONT; AS_ST($$)->cont = NEW(cont_node); AS_ST($$)->cont->val = $2; }
67 65
 | stmt SEMICOLON { $$ = $1; }
68 66
 ;
69 67
 
70 68
 expr:
69
+  control_expr { $$ = $1; }
70
+;
71
+
72
+control_expr:
73
+  IF expr THEN stmt_list END {
74
+	$$ = NEW_EX();
75
+	AS_EX($$)->type = EX_IFELSE;
76
+	AS_EX($$)->ifelse = NEW(ifelse_node);
77
+	AS_EX($$)->ifelse->cond = $2;
78
+	AS_EX($$)->ifelse->iftrue = $4;
79
+	AS_EX($$)->ifelse->iffalse = NULL;
80
+}
81
+| IF expr THEN stmt_list ELSE stmt_list END {
82
+	$$ = NEW_EX();
83
+	AS_EX($$)->type = EX_IFELSE;
84
+	AS_EX($$)->ifelse = NEW(ifelse_node);
85
+	AS_EX($$)->ifelse->cond = $2;
86
+	AS_EX($$)->ifelse->iftrue = $4;
87
+	AS_EX($$)->ifelse->iffalse = $6;
88
+}
89
+| WHILE expr DO stmt_list END {
90
+	$$ = NEW_EX();
91
+	AS_EX($$)->type = EX_LOOP;
92
+	AS_EX($$)->loop = NEW(loop_node);
93
+	AS_EX($$)->loop->cond = $2;
94
+	AS_EX($$)->loop->loop = $4;
95
+}
96
+| FOR IDENT IN expr DO stmt_list END {
97
+	$$ = NEW_EX();
98
+	AS_EX($$)->type = EX_ITER;
99
+	AS_EX($$)->iter = NEW(iter_node);
100
+	AS_EX($$)->iter->var = $2;
101
+	AS_EX($$)->iter->iter = $4;
102
+	AS_EX($$)->iter->loop = $6;
103
+}
104
+| assign_expr { $$ = $1; }
105
+;
106
+
107
+assign_expr:
71 108
   IDENT ASSIGN expr { $$ = NEW_EX(); AS_EX($$)->type = EX_ASSIGN; AS_EX($$)->assign = NEW(assign_node); AS_EX($$)->assign->ident = $1; AS_EX($$)->assign->value = $3; }
72 109
 | IDENT ASSIGNPLUS expr {
73 110
 	$$ = NEW_EX();

+ 8
- 0
programs/fizzbuzz.sol View File

@@ -0,0 +1,8 @@
1
+ID = lambda(x) x end
2
+FIZZ = lambda(x) 'FIZZ' end
3
+BUZZ = lambda(x) 'BUZZ' end
4
+FIZZBUZZ = lambda(x) 'FIZZBUZZ' end
5
+L = [FIZZBUZZ] + (for i in range(14) do if !((i + 1) % 3) then continue FIZZ end if !((i + 1) % 5) then continue BUZZ end continue ID end)
6
+func fizzbuzz(s, e) return for i in range(e-s) do continue L[(i + s)%(#L)](i + s) end end
7
+
8
+for i in fizzbuzz(1, 101) do print(i) end

+ 125
- 103
runtime.c View File

@@ -20,7 +20,7 @@ stmt_node *st_copy(stmt_node *old) {
20 20
 	stmt_node *new;
21 21
 	stmtlist_node *curn, *curo;
22 22
 	if(!old) {
23
-		printf("WARNING: Copying NULL statement\n");
23
+		// printf("WARNING: Copying NULL statement\n");
24 24
 		return NULL;
25 25
 	}
26 26
 	new = NEW(stmt_node);
@@ -30,34 +30,7 @@ stmt_node *st_copy(stmt_node *old) {
30 30
 			new->expr = ex_copy(old->expr);
31 31
 			break;
32 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 33
 		case ST_LIST:
60
-			
61 34
 			new->stmtlist = stl_copy(old->stmtlist);
62 35
 			break;
63 36
 
@@ -67,7 +40,13 @@ stmt_node *st_copy(stmt_node *old) {
67 40
 			break;
68 41
 
69 42
 		case ST_CONT:
43
+			new->cont = NEW(cont_node);
44
+			new->cont->val = ex_copy(old->cont->val);
45
+			break;
46
+
70 47
 		case ST_BREAK:
48
+			new->brk = NEW(break_node);
49
+			new->brk->val = ex_copy(old->cont->val);
71 50
 			break;
72 51
 
73 52
 		default:
@@ -107,7 +86,7 @@ expr_node *ex_copy(expr_node *old) {
107 86
 	assoclist_node *curao, *curan;
108 87
 	identlist_node *curio, *curin;
109 88
 	if(!old) {
110
-		printf("WARNING: Copying NULL expression\n");
89
+		// printf("WARNING: Copying NULL expression\n");
111 90
 		return NULL;
112 91
 	}
113 92
 	new = NEW(expr_node);
@@ -202,6 +181,32 @@ expr_node *ex_copy(expr_node *old) {
202 181
 			new->funcdecl->body = st_copy(old->funcdecl->body);
203 182
 			break;
204 183
 
184
+		case EX_IFELSE:
185
+			new->ifelse = NEW(ifelse_node);
186
+			new->ifelse->cond = ex_copy(old->ifelse->cond);
187
+			if(old->ifelse->iftrue)
188
+				new->ifelse->iftrue = st_copy(old->ifelse->iftrue);
189
+			else
190
+				new->ifelse->iftrue = NULL;
191
+			if(old->ifelse->iffalse)
192
+				new->ifelse->iffalse = st_copy(old->ifelse->iffalse);
193
+			else
194
+				new->ifelse->iffalse = NULL;
195
+			break;
196
+
197
+		case EX_LOOP:
198
+			new->loop = NEW(loop_node);
199
+			new->loop->cond = ex_copy(old->loop->cond);
200
+			new->loop->loop = st_copy(old->loop->loop);
201
+			break;
202
+
203
+		case EX_ITER:
204
+			new->iter = NEW(iter_node);
205
+			new->iter->var = strdup(old->iter->var);
206
+			new->iter->iter = ex_copy(old->iter->iter);
207
+			new->iter->loop = st_copy(old->iter->loop);
208
+			break;
209
+
205 210
 		default:
206 211
 			printf("WARNING: Unknown expression type to copy: %d\n", old->type);
207 212
 			break;
@@ -295,26 +300,6 @@ void st_free(stmt_node *stmt) {
295 300
 			ex_free(stmt->expr);
296 301
 			break;
297 302
 
298
-		case ST_IFELSE:
299
-			ex_free(stmt->ifelse->cond);
300
-			st_free(stmt->ifelse->iftrue);
301
-			st_free(stmt->ifelse->iffalse);
302
-			free(stmt->ifelse);
303
-			break;
304
-
305
-		case ST_LOOP:
306
-			ex_free(stmt->loop->cond);
307
-			st_free(stmt->loop->loop);
308
-			free(stmt->loop);
309
-			break;
310
-
311
-		case ST_ITER:
312
-			free(stmt->iter->var);
313
-			ex_free(stmt->iter->iter);
314
-			st_free(stmt->iter->loop);
315
-			free(stmt->iter);
316
-			break;
317
-
318 303
 		case ST_LIST:
319 304
 			stl_free(stmt->stmtlist);
320 305
 			break;
@@ -325,8 +310,12 @@ void st_free(stmt_node *stmt) {
325 310
 			break;
326 311
 
327 312
 		case ST_CONT:
313
+			ex_free(stmt->cont->val);
314
+			break;
315
+
328 316
 		case ST_BREAK:
329
-			break; // Make the compiler happy :D
317
+			ex_free(stmt->brk->val);
318
+			break; 
330 319
 	}
331 320
 	free(stmt);
332 321
 }
@@ -415,6 +404,26 @@ void ex_free(expr_node *expr) {
415 404
 			idl_free(expr->funcdecl->args);
416 405
 			free(expr->funcdecl);
417 406
 			break;
407
+
408
+		case EX_IFELSE:
409
+			ex_free(expr->ifelse->cond);
410
+			st_free(expr->ifelse->iftrue);
411
+			st_free(expr->ifelse->iffalse);
412
+			free(expr->ifelse);
413
+			break;
414
+
415
+		case EX_LOOP:
416
+			ex_free(expr->loop->cond);
417
+			st_free(expr->loop->loop);
418
+			free(expr->loop);
419
+			break;
420
+
421
+		case EX_ITER:
422
+			free(expr->iter->var);
423
+			ex_free(expr->iter->iter);
424
+			st_free(expr->iter->loop);
425
+			free(expr->iter);
426
+			break;
418 427
 	}
419 428
 	free(expr);
420 429
 }
@@ -459,7 +468,7 @@ void idl_free(identlist_node *list) {
459 468
 
460 469
 #define ERR_CHECK(state) do { if(sol_has_error(state)) longjmp(jmp, 1); } while(0)
461 470
 sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
462
-	sol_object_t *res, *left, *right, *lint, *rint, *value, *list;
471
+	sol_object_t *res, *left, *right, *lint, *rint, *value, *list, *vint, *iter, *item;
463 472
 	exprlist_node *cure;
464 473
 	assoclist_node *cura;
465 474
 	if(!expr) {
@@ -756,80 +765,52 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
756 765
 			}
757 766
 			return res;
758 767
 			break;
759
-	}
760
-	printf("WARNING: Unhandled expression (type %d) returning None\n", expr->type);
761
-	return sol_incref(state->None);
762
-}
763 768
 
764
-sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
765
-	jmp_buf jmp;
766
-	if(!setjmp(jmp)) {
767
-		return sol_eval_inner(state, expr, jmp);
768
-	} else {
769
-		return sol_incref(state->None);
770
-	}
771
-}
772
-
773
-void sol_exec(sol_state_t *state, stmt_node *stmt) {
774
-	sol_object_t *value, *vint, *list, *iter, *item;
775
-	stmtlist_node *curs;
776
-	if(!stmt) {
777
-		sol_obj_free(sol_set_error_string(state, "Execute NULL statement"));
778
-		return;
779
-	}
780
-	switch(stmt->type) {
781
-		case ST_EXPR:
782
-			sol_obj_free(sol_eval(state, stmt->expr));
783
-			if(sol_has_error(state)) {
784
-				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
785
-			}
786
-			break;
787
-
788
-		case ST_IFELSE:
789
-			value = sol_eval(state, stmt->ifelse->cond);
769
+		case EX_IFELSE:
770
+			value = sol_eval(state, expr->ifelse->cond);
790 771
 			vint = sol_cast_int(state, value);
791 772
 			if(vint->ival) {
792
-				if(stmt->ifelse->iftrue) {
793
-					sol_exec(state, stmt->ifelse->iftrue);
773
+				if(expr->ifelse->iftrue) {
774
+					sol_exec(state, expr->ifelse->iftrue);
794 775
 				}
795 776
 			} else {
796
-				if(stmt->ifelse->iffalse) {
797
-					sol_exec(state, stmt->ifelse->iffalse);
777
+				if(expr->ifelse->iffalse) {
778
+					sol_exec(state, expr->ifelse->iffalse);
798 779
 				}
799 780
 			}
800 781
 			sol_obj_free(value);
801 782
 			sol_obj_free(vint);
802
-			if(sol_has_error(state)) {
803
-				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
804
-			}
783
+			return sol_incref(state->lastvalue);
805 784
 			break;
806 785
 
807
-		case ST_LOOP:
808
-			value = sol_eval(state, stmt->loop->cond);
786
+		case EX_LOOP:
787
+			sol_obj_free(state->loopvalue);
788
+			state->loopvalue = sol_new_list(state);
789
+			value = sol_eval(state, expr->loop->cond);
809 790
 			vint = sol_cast_int(state, value);
810 791
 			while(vint->ival) {
811 792
 				sol_obj_free(value);
812 793
 				sol_obj_free(vint);
813
-				sol_exec(state, stmt->loop->loop);
794
+				sol_exec(state, expr->loop->loop);
814 795
 				if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
815 796
 					value = sol_incref(state->None);
816 797
 					vint = sol_new_int(state, 0);
817 798
 					continue;
818 799
 				}
819 800
 				state->sflag = SF_NORMAL;
820
-				value = sol_eval(state, stmt->loop->cond);
801
+				value = sol_eval(state, expr->loop->cond);
821 802
 				vint = sol_cast_int(state, value);
822 803
 			}
823 804
 			state->sflag = SF_NORMAL;
824
-			if(sol_has_error(state)) {
825
-				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
826
-			}
827 805
 			sol_obj_free(value);
828 806
 			sol_obj_free(vint);
807
+			return sol_incref(state->loopvalue);
829 808
 			break;
830 809
 
831
-		case ST_ITER:
832
-			value = sol_eval(state, stmt->iter->iter);
810
+		case EX_ITER:
811
+			sol_obj_free(state->loopvalue);
812
+			state->loopvalue = sol_new_list(state);
813
+			value = sol_eval(state, expr->iter->iter);
833 814
 			if(value->ops->iter && value->ops->iter != sol_f_not_impl) {
834 815
 				list = sol_new_list(state);
835 816
 				sol_list_insert(state, list, 0, value);
@@ -840,7 +821,7 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
840 821
 			}
841 822
 			if(!iter->ops->call || iter->ops->call == sol_f_not_impl) {
842 823
 				sol_obj_free(sol_set_error_string(state, "Iterate over non-iterable"));
843
-				return;
824
+				return sol_incref(state->None);
844 825
 			}
845 826
 			list = sol_new_list(state);
846 827
 			sol_list_insert(state, list, 0, iter);
@@ -848,8 +829,8 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
848 829
 			sol_list_insert(state, list, 2, sol_new_map(state));
849 830
 			item = CALL_METHOD(state, iter, call, list);
850 831
 			while(item != state->StopIteration) {
851
-				sol_state_assign_l_name(state, stmt->iter->var, item);
852
-				sol_exec(state, stmt->iter->loop);
832
+				sol_state_assign_l_name(state, expr->iter->var, item);
833
+				sol_exec(state, expr->iter->loop);
853 834
 				sol_obj_free(item);
854 835
 				if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
855 836
 					item = sol_incref(state->StopIteration);
@@ -858,13 +839,41 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
858 839
 				item = CALL_METHOD(state, iter, call, list);
859 840
 			}
860 841
 			state->sflag = SF_NORMAL;
861
-			if(sol_has_error(state)) {
862
-				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
863
-			}
864 842
 			sol_obj_free(iter);
865 843
 			sol_obj_free(value);
866 844
 			sol_obj_free(list);
867 845
 			sol_obj_free(item);
846
+			return sol_incref(state->loopvalue);
847
+			break;
848
+	}
849
+	printf("WARNING: Unhandled expression (type %d) returning None\n", expr->type);
850
+	return sol_incref(state->None);
851
+}
852
+
853
+sol_object_t *sol_eval(sol_state_t *state, expr_node *expr) {
854
+	jmp_buf jmp;
855
+	if(!setjmp(jmp)) {
856
+		return sol_eval_inner(state, expr, jmp);
857
+	} else {
858
+		return sol_incref(state->None);
859
+	}
860
+}
861
+
862
+void sol_exec(sol_state_t *state, stmt_node *stmt) {
863
+	sol_object_t *value, *vint, *list, *iter, *item;
864
+	stmtlist_node *curs;
865
+	if(!stmt) {
866
+		sol_obj_free(sol_set_error_string(state, "Execute NULL statement"));
867
+		return;
868
+	}
869
+	switch(stmt->type) {
870
+		case ST_EXPR:
871
+			value = state->lastvalue;
872
+			state->lastvalue = sol_eval(state, stmt->expr);
873
+			sol_obj_free(value);
874
+			if(sol_has_error(state)) {
875
+				sol_add_traceback(state, sol_new_stmtnode(state, st_copy(stmt)));
876
+			}
868 877
 			break;
869 878
 
870 879
 		case ST_LIST:
@@ -892,10 +901,23 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
892 901
 			break;
893 902
 
894 903
 		case ST_CONT:
904
+			if(stmt->cont->val && sol_is_list(state->loopvalue)) {
905
+				value = sol_eval(state, stmt->cont->val);
906
+				sol_list_insert(state, state->loopvalue, sol_list_len(state, state->loopvalue), value);
907
+				sol_obj_free(value);
908
+			}
895 909
 			state->sflag = SF_CONTINUING;
896 910
 			break;
897 911
 
898 912
 		case ST_BREAK:
913
+			if(stmt->brk->val) {
914
+				value = sol_eval(state, stmt->brk->val);
915
+			} else {
916
+				value = sol_incref(state->None);
917
+			}
918
+			vint = state->loopvalue;
919
+			state->loopvalue = sol_incref(value);
920
+			sol_obj_free(vint);
899 921
 			state->sflag = SF_BREAKING;
900 922
 			break;
901 923
 

+ 4
- 2
sol.h View File

@@ -9,8 +9,8 @@
9 9
 #include <stdarg.h>
10 10
 #include "dsl/dsl.h"
11 11
 
12
-#define VERSION "0.1a5"
13
-#define HEXVER 0x0001A05
12
+#define VERSION "0.2a0"
13
+#define HEXVER 0x0002A00
14 14
 
15 15
 #ifndef SOL_ICACHE_MIN
16 16
 #define SOL_ICACHE_MIN -128
@@ -202,6 +202,8 @@ typedef struct sol_tag_state_t {
202 202
 	sol_object_t *icache[SOL_ICACHE_MAX - SOL_ICACHE_MIN + 1];
203 203
 	char icache_bypass;
204 204
 #endif
205
+	sol_object_t *lastvalue;
206
+	sol_object_t *loopvalue;
205 207
 } sol_state_t;
206 208
 
207 209
 // state.c

+ 8
- 3
state.c View File

@@ -16,6 +16,8 @@ int sol_state_init(sol_state_t *state) {
16 16
 	state->traceback = NULL;
17 17
 	state->ret = NULL;
18 18
 	state->sflag = SF_NORMAL;
19
+	state->lastvalue = NULL;
20
+	state->loopvalue = NULL;
19 21
 
20 22
 #ifdef DEBUG_GC
21 23
 	// This is necessary for DEBUG_GC's early allocation; it gets overwritten,
@@ -186,6 +188,9 @@ int sol_state_init(sol_state_t *state) {
186 188
 	state->calling_type = "(none)";
187 189
 	state->calling_meth = "(none)";
188 190
 
191
+	state->lastvalue = sol_incref(state->None);
192
+	state->loopvalue = sol_incref(state->None);
193
+
189 194
 	state->error = state->None;
190 195
 	state->scopes = sol_new_list(state);
191 196
 	if(sol_has_error(state)) {
@@ -259,9 +264,6 @@ int sol_state_init(sol_state_t *state) {
259 264
 
260 265
 	mod = sol_new_map(state);
261 266
 	sol_map_borrow_name(state, mod, "ST_EXPR", sol_new_int(state, ST_EXPR));
262
-	sol_map_borrow_name(state, mod, "ST_IFELSE", sol_new_int(state, ST_IFELSE));
263
-	sol_map_borrow_name(state, mod, "ST_LOOP", sol_new_int(state, ST_LOOP));
264
-	sol_map_borrow_name(state, mod, "ST_ITER", sol_new_int(state, ST_ITER));
265 267
 	sol_map_borrow_name(state, mod, "ST_LIST", sol_new_int(state, ST_LIST));
266 268
 	sol_map_borrow_name(state, mod, "ST_RET", sol_new_int(state, ST_RET));
267 269
 	sol_map_borrow_name(state, mod, "ST_CONT", sol_new_int(state, ST_CONT));
@@ -277,6 +279,9 @@ int sol_state_init(sol_state_t *state) {
277 279
 	sol_map_borrow_name(state, mod, "EX_REF", sol_new_int(state, EX_LIT));
278 280
 	sol_map_borrow_name(state, mod, "EX_CALL", sol_new_int(state, EX_LIT));
279 281
 	sol_map_borrow_name(state, mod, "EX_FUNCDECL", sol_new_int(state, EX_LIT));
282
+	sol_map_borrow_name(state, mod, "EX_IFELSE", sol_new_int(state, EX_IFELSE));
283
+	sol_map_borrow_name(state, mod, "EX_LOOP", sol_new_int(state, EX_LOOP));
284
+	sol_map_borrow_name(state, mod, "EX_ITER", sol_new_int(state, EX_ITER));
280 285
 	sol_map_borrow_name(state, mod, "OP_ADD", sol_new_int(state, OP_ADD));
281 286
 	sol_map_borrow_name(state, mod, "OP_SUB", sol_new_int(state, OP_SUB));
282 287
 	sol_map_borrow_name(state, mod, "OP_MUL", sol_new_int(state, OP_MUL));

Loading…
Cancel
Save