Browse Source

Sol Part 26: Yo Dawg, I Herd U Liek Languages...

Graham Northup 6 years ago
parent
commit
5aaa5396e8
19 changed files with 2077 additions and 1104 deletions
  1. 10
    2
      ast.h
  2. 111
    111
      astprint.c
  3. 1
    0
      build.sh
  4. 171
    43
      builtins.c
  5. 42
    0
      gc.c
  6. 10
    0
      interp.sol
  7. 36
    35
      lex.yy.c
  8. 472
    0
      monty.sol
  9. 22
    40
      object.c
  10. 17
    17
      parser.output
  11. 955
    754
      parser.tab.c
  12. 87
    75
      parser.tab.h
  13. 9
    9
      parser.y
  14. 30
    6
      runtime.c
  15. 45
    9
      sol.h
  16. 2
    2
      solrun.c
  17. 32
    1
      state.c
  18. 15
    0
      test.sol
  19. 10
    0
      test_monty.sol

+ 10
- 2
ast.h View File

@@ -5,6 +5,11 @@
5 5
 
6 6
 #include <stdio.h>
7 7
 
8
+typedef struct {
9
+	size_t line;
10
+	size_t col;
11
+} loc_t;
12
+
8 13
 struct tag_expr_node;
9 14
 typedef struct tag_expr_node expr_node;
10 15
 
@@ -96,6 +101,7 @@ typedef struct {
96 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;
97 102
 typedef struct tag_expr_node {
98 103
 	expr_t type;
104
+	loc_t loc;
99 105
 	union {
100 106
 		lit_node *lit;
101 107
 		listgen_node *listgen;
@@ -140,6 +146,7 @@ typedef struct tag_stmtlist_node {
140 146
 typedef enum {ST_EXPR, ST_IFELSE, ST_LOOP, ST_ITER, ST_LIST, ST_RET, ST_CONT, ST_BREAK} stmt_t;
141 147
 typedef struct tag_stmt_node {
142 148
 	stmt_t type;
149
+	loc_t loc;
143 150
 	union {
144 151
 		expr_node *expr;
145 152
 		ifelse_node *ifelse;
@@ -155,6 +162,7 @@ typedef struct tag_stmt_node {
155 162
 #define AS(arg, tp) ((tp *) (arg))
156 163
 #define NEW_ST() malloc(sizeof(stmt_node))
157 164
 #define NEW_EX() malloc(sizeof(expr_node))
165
+#define SET_LOC(node, l) do { (node)->loc.line = (l).first_line; (node)->loc.col = (l).first_column; } while(0)
158 166
 #define NEW(arg) malloc(sizeof(arg))
159 167
 #define MAKE_REF_BINOP(nd, tp, name, val) nd = NEW_EX(); \
160 168
 	nd->type = EX_BINOP; \
@@ -191,8 +199,8 @@ void sol_compile_free(stmt_node *);
191 199
 void st_free(stmt_node *);
192 200
 void ex_free(expr_node *);
193 201
 
194
-void st_print(stmt_node *);
195
-void ex_print(expr_node *);
202
+void st_print(sol_state_t *, stmt_node *);
203
+void ex_print(sol_state_t *, expr_node *);
196 204
 void ob_print(sol_object_t *);
197 205
 
198 206
 sol_object_t *sol_eval(sol_state_t *, expr_node *);

+ 111
- 111
astprint.c View File

@@ -4,310 +4,310 @@
4 4
 #include <stdarg.h>
5 5
 #include <stdio.h>
6 6
 
7
-void prlev(int lev, const char *fmt, ...) {
7
+void prlev(sol_state_t *state, int lev, const char *fmt, ...) {
8 8
 	va_list vl;
9 9
 	int i;
10 10
 
11
-	for(i = 0; i < lev; i++) { putchar('|'); putchar(' '); }
11
+	for(i = 0; i < lev; i++) { sol_putchar(state, '|'); sol_putchar(state, ' '); }
12 12
 	va_start(vl, fmt);
13
-	vprintf(fmt, vl);
13
+	sol_vprintf(state, fmt, vl);
14 14
 	va_end(vl);
15
-	putchar('\n');
15
+	sol_putchar(state, '\n');
16 16
 }
17 17
 
18
-void prex(expr_node *, int);
18
+void prex( sol_state_t *, expr_node *, int);
19 19
 
20
-void prst(stmt_node *node, int lev) {
20
+void prst(sol_state_t *state, stmt_node *node, int lev) {
21 21
 	if(!node) {
22
-		prlev(lev, "<NULL>");
22
+		prlev(state, lev, "<NULL>");
23 23
 		return;
24 24
 	}
25 25
 	switch(node->type) {
26 26
 		case ST_EXPR:
27
-			prlev(lev, "Stmt<Expr>:");
28
-			prex(node->expr, lev+1);
27
+			prlev(state, lev, "Stmt<Expr>:");
28
+			prex(state, node->expr, lev+1);
29 29
 			break;
30 30
 
31 31
 		case ST_IFELSE:
32
-			prlev(lev, "Stmt<IfElse>:");
32
+			prlev(state, lev, "Stmt<IfElse>:");
33 33
 			lev++;
34
-			prlev(lev, "Cond:");
35
-			prex(node->ifelse->cond, lev+1);
36
-			prlev(lev, "IfTrue:");
37
-			prst(node->ifelse->iftrue, lev+1);
38
-			prlev(lev, "IfFalse:");
39
-			prst(node->ifelse->iffalse, lev+1);
34
+			prlev(state, lev, "Cond:");
35
+			prex(state, node->ifelse->cond, lev+1);
36
+			prlev(state, lev, "IfTrue:");
37
+			prst(state, node->ifelse->iftrue, lev+1);
38
+			prlev(state, lev, "IfFalse:");
39
+			prst(state, node->ifelse->iffalse, lev+1);
40 40
 			break;
41 41
 
42 42
 		case ST_LOOP:
43
-			prlev(lev, "Stmt<Loop>:");
43
+			prlev(state, lev, "Stmt<Loop>:");
44 44
 			lev++;
45
-			prlev(lev, "Cond:");
46
-			prex(node->loop->cond, lev+1);
47
-			prlev(lev, "Loop:");
48
-			prst(node->loop->loop, lev+1);
45
+			prlev(state, lev, "Cond:");
46
+			prex(state, node->loop->cond, lev+1);
47
+			prlev(state, lev, "Loop:");
48
+			prst(state, node->loop->loop, lev+1);
49 49
 			break;
50 50
 
51 51
 		case ST_ITER:
52
-			prlev(lev, "Stmt<Iter>:");
52
+			prlev(state, lev, "Stmt<Iter>:");
53 53
 			lev++;
54
-			prlev(lev, "Var: %s", node->iter->var);
55
-			prlev(lev, "Iter:");
56
-			prex(node->iter->iter, lev+1);
57
-			prlev(lev, "Loop:");
58
-			prst(node->iter->loop, lev+1);
54
+			prlev(state, lev, "Var: %s", node->iter->var);
55
+			prlev(state, lev, "Iter:");
56
+			prex(state, node->iter->iter, lev+1);
57
+			prlev(state, lev, "Loop:");
58
+			prst(state, node->iter->loop, lev+1);
59 59
 			break;
60 60
 
61 61
 		case ST_LIST:
62
-			prlev(lev, "Stmt<List>:");
62
+			prlev(state, lev, "Stmt<List>:");
63 63
 			stmtlist_node *cur = node->stmtlist;
64 64
 			while(cur && cur->stmt) {
65
-				prst(cur->stmt, lev+1);
65
+				prst(state, cur->stmt, lev+1);
66 66
 				cur = cur->next;
67 67
 			}
68 68
 			break;
69 69
 
70 70
         case ST_RET:
71
-            prlev(lev, "Stmt<Ret>:");
72
-            prex(node->ret->ret, lev+1);
71
+            prlev(state, lev, "Stmt<Ret>:");
72
+            prex(state, node->ret->ret, lev+1);
73 73
             break;
74 74
 
75 75
         case ST_CONT:
76
-            prlev(lev, "Stmt<Continue>");
76
+            prlev(state, lev, "Stmt<Continue>");
77 77
             break;
78 78
 
79 79
         case ST_BREAK:
80
-            prlev(lev, "Stmt<Break>");
80
+            prlev(state, lev, "Stmt<Break>");
81 81
             break;
82 82
 	}
83 83
 }
84 84
 
85
-void prex(expr_node *node, int lev) {
85
+void prex(sol_state_t *state, expr_node *node, int lev) {
86 86
 	assoclist_node *cura;
87 87
 	exprlist_node *cure;
88 88
 	identlist_node *curi;
89 89
 	if(!node) {
90
-		prlev(lev, "<NULL>");
90
+		prlev(state, lev, "<NULL>");
91 91
 		return;
92 92
 	}
93 93
 	switch(node->type) {
94 94
 		case EX_LIT:
95
-			prlev(lev, "Literal:");
95
+			prlev(state, lev, "Literal:");
96 96
 			lev++;
97 97
 			switch(node->lit->type) {
98 98
 				case LIT_INT:
99
-					prlev(lev, "Int: %ld", node->lit->ival);
99
+					prlev(state, lev, "Int: %ld", node->lit->ival);
100 100
 					break;
101 101
 
102 102
 				case LIT_FLOAT:
103
-					prlev(lev, "Float: %f", node->lit->fval);
103
+					prlev(state, lev, "Float: %f", node->lit->fval);
104 104
 					break;
105 105
 
106 106
 				case LIT_STRING:
107
-					prlev(lev, "String: %s", node->lit->str);
107
+					prlev(state, lev, "String: %s", node->lit->str);
108 108
 					break;
109 109
 
110 110
 				case LIT_NONE:
111
-					prlev(lev, "None");
111
+					prlev(state, lev, "None");
112 112
 					break;
113 113
 			}
114 114
 			break;
115 115
 
116 116
 		case EX_LISTGEN:
117
-			prlev(lev, "ListGen:");
117
+			prlev(state, lev, "ListGen:");
118 118
 			cure = node->listgen->list;
119 119
 			while(cure && cure->expr) {
120
-				prex(cure->expr, lev+1);
120
+				prex(state, cure->expr, lev+1);
121 121
 				cure = cure->next;
122 122
 			}
123 123
 			break;
124 124
 
125 125
 		case EX_MAPGEN:
126
-			prlev(lev, "MapGen:");
126
+			prlev(state, lev, "MapGen:");
127 127
 			lev++;
128 128
 			cura = node->mapgen->map;
129 129
 			while(cura && cura->item) {
130
-				prlev(lev, "<Key>:");
131
-				prex(cura->item->key, lev+1);
132
-				prlev(lev, "<Value>:");
133
-				prex(cura->item->value, lev+1);
130
+				prlev(state, lev, "<Key>:");
131
+				prex(state, cura->item->key, lev+1);
132
+				prlev(state, lev, "<Value>:");
133
+				prex(state, cura->item->value, lev+1);
134 134
 				cura = cura->next;
135 135
 			}
136 136
 			break;
137 137
 
138 138
 		case EX_BINOP:
139
-			prlev(lev, "BinOp:");
139
+			prlev(state, lev, "BinOp:");
140 140
 			lev++;
141 141
 			switch(node->binop->type) {
142 142
 				case OP_ADD:
143
-					prlev(lev, "Op: +");
143
+					prlev(state, lev, "Op: +");
144 144
 					break;
145 145
 
146 146
 				case OP_SUB:
147
-					prlev(lev, "Op: -");
147
+					prlev(state, lev, "Op: -");
148 148
 					break;
149 149
 
150 150
 				case OP_MUL:
151
-					prlev(lev, "Op: *");
151
+					prlev(state, lev, "Op: *");
152 152
 					break;
153 153
 
154 154
 				case OP_DIV:
155
-					prlev(lev, "Op: /");
155
+					prlev(state, lev, "Op: /");
156 156
 					break;
157 157
 
158 158
                 case OP_MOD:
159
-					prlev(lev, "Op: %");
159
+					prlev(state, lev, "Op: %");
160 160
 					break;
161 161
 
162 162
 				case OP_POW:
163
-					prlev(lev, "Op: **");
163
+					prlev(state, lev, "Op: **");
164 164
 					break;
165 165
 
166 166
 				case OP_BAND:
167
-					prlev(lev, "Op: &");
167
+					prlev(state, lev, "Op: &");
168 168
 					break;
169 169
 
170 170
 				case OP_BOR:
171
-					prlev(lev, "Op: |");
171
+					prlev(state, lev, "Op: |");
172 172
 					break;
173 173
 
174 174
 				case OP_BXOR:
175
-					prlev(lev, "Op: ^");
175
+					prlev(state, lev, "Op: ^");
176 176
 					break;
177 177
 
178 178
 				case OP_LAND:
179
-					prlev(lev, "Op: &&");
179
+					prlev(state, lev, "Op: &&");
180 180
 					break;
181 181
 
182 182
 				case OP_LOR:
183
-					prlev(lev, "Op: ||");
183
+					prlev(state, lev, "Op: ||");
184 184
 					break;
185 185
 
186 186
 				case OP_EQUAL:
187
-					prlev(lev, "Op: ==");
187
+					prlev(state, lev, "Op: ==");
188 188
 					break;
189 189
 
190 190
 				case OP_LESS:
191
-					prlev(lev, "Op: <");
191
+					prlev(state, lev, "Op: <");
192 192
 					break;
193 193
 
194 194
 				case OP_GREATER:
195
-					prlev(lev, "Op: >");
195
+					prlev(state, lev, "Op: >");
196 196
 					break;
197 197
 
198 198
 				case OP_LESSEQ:
199
-					prlev(lev, "Op: <=");
199
+					prlev(state, lev, "Op: <=");
200 200
 					break;
201 201
 
202 202
 				case OP_GREATEREQ:
203
-					prlev(lev, "Op: >=");
203
+					prlev(state, lev, "Op: >=");
204 204
 					break;
205 205
 
206 206
 				case OP_LSHIFT:
207
-					prlev(lev, "Op: <<");
207
+					prlev(state, lev, "Op: <<");
208 208
 					break;
209 209
 
210 210
 				case OP_RSHIFT:
211
-					prlev(lev, "Op: >>");
211
+					prlev(state, lev, "Op: >>");
212 212
 					break;
213 213
 			}
214
-			prlev(lev, "Left:");
215
-			prex(node->binop->left, lev+1);
216
-			prlev(lev, "Right:");
217
-			prex(node->binop->right, lev+1);
214
+			prlev(state, lev, "Left:");
215
+			prex(state, node->binop->left, lev+1);
216
+			prlev(state, lev, "Right:");
217
+			prex(state, node->binop->right, lev+1);
218 218
 			break;
219 219
 
220 220
 		case EX_UNOP:
221
-			prlev(lev, "UnOp:");
221
+			prlev(state, lev, "UnOp:");
222 222
 			lev++;
223 223
 			switch(node->unop->type) {
224 224
 				case OP_NEG:
225
-					prlev(lev, "Op: -");
225
+					prlev(state, lev, "Op: -");
226 226
 					break;
227 227
 
228 228
 				case OP_BNOT:
229
-					prlev(lev, "Op: ~");
229
+					prlev(state, lev, "Op: ~");
230 230
 					break;
231 231
 
232 232
 				case OP_LNOT:
233
-					prlev(lev, "Op: !");
233
+					prlev(state, lev, "Op: !");
234 234
 					break;
235 235
 
236 236
 				case OP_LEN:
237
-					prlev(lev, "Op: #");
237
+					prlev(state, lev, "Op: #");
238 238
 					break;
239 239
 			}
240
-			prlev(lev, "Expr:");
241
-			prex(node->unop->expr, lev+1);
240
+			prlev(state, lev, "Expr:");
241
+			prex(state, node->unop->expr, lev+1);
242 242
 			break;
243 243
 
244 244
 		case EX_INDEX:
245
-			prlev(lev, "Index:");
245
+			prlev(state, lev, "Index:");
246 246
 			lev++;
247
-			prlev(lev, "Expr:");
248
-			prex(node->index->expr, lev+1);
249
-			prlev(lev, "Index:");
250
-			prex(node->index->index, lev+1);
247
+			prlev(state, lev, "Expr:");
248
+			prex(state, node->index->expr, lev+1);
249
+			prlev(state, lev, "Index:");
250
+			prex(state, node->index->index, lev+1);
251 251
 			break;
252 252
 
253 253
 		case EX_SETINDEX:
254
-			prlev(lev, "SetIndex:");
254
+			prlev(state, lev, "SetIndex:");
255 255
 			lev++;
256
-			prlev(lev, "Expr:");
257
-			prex(node->setindex->expr, lev+1);
258
-			prlev(lev, "Index:");
259
-			prex(node->setindex->index, lev+1);
260
-			prlev(lev, "Value:");
261
-			prex(node->setindex->value, lev+1);
256
+			prlev(state, lev, "Expr:");
257
+			prex(state, node->setindex->expr, lev+1);
258
+			prlev(state, lev, "Index:");
259
+			prex(state, node->setindex->index, lev+1);
260
+			prlev(state, lev, "Value:");
261
+			prex(state, node->setindex->value, lev+1);
262 262
 			break;
263 263
 
264 264
 		case EX_ASSIGN:
265
-			prlev(lev, "Assign:");
265
+			prlev(state, lev, "Assign:");
266 266
 			lev++;
267
-			prlev(lev, "Ident: %s", node->assign->ident);
268
-			prlev(lev, "Value:");
269
-			prex(node->assign->value, lev+1);
267
+			prlev(state, lev, "Ident: %s", node->assign->ident);
268
+			prlev(state, lev, "Value:");
269
+			prex(state, node->assign->value, lev+1);
270 270
 			break;
271 271
 
272 272
 		case EX_REF:
273
-			prlev(lev, "Ref: %s", node->ref->ident);
273
+			prlev(state, lev, "Ref: %s", node->ref->ident);
274 274
 			break;
275 275
 
276 276
 		case EX_CALL:
277
-			prlev(lev, "Call:");
277
+			prlev(state, lev, "Call:");
278 278
 			lev++;
279
-			prlev(lev, "Expr:");
280
-			prex(node->call->expr, lev+1);
281
-			prlev(lev, "Args:");
279
+			prlev(state, lev, "Expr:");
280
+			prex(state, node->call->expr, lev+1);
281
+			prlev(state, lev, "Args:");
282 282
 			cure = node->call->args;
283 283
 			while(cure && cure->expr) {
284
-				prex(cure->expr, lev+1);
284
+				prex(state, cure->expr, lev+1);
285 285
 				cure = cure->next;
286 286
 			}
287 287
 			break;
288 288
 
289 289
 		case EX_FUNCDECL:
290
-			prlev(lev, "FuncDecl:");
290
+			prlev(state, lev, "FuncDecl:");
291 291
 			lev++;
292
-			prlev(lev, "Name: %s", node->funcdecl->name);
293
-			prlev(lev, "Args:");
292
+			prlev(state, lev, "Name: %s", node->funcdecl->name);
293
+			prlev(state, lev, "Args:");
294 294
 			curi = node->funcdecl->args;
295 295
 			while(curi && curi->ident) {
296
-				prlev(lev+1, curi->ident);
296
+				prlev(state, lev+1, curi->ident);
297 297
 				curi = curi->next;
298 298
 			}
299
-			prlev(lev, "Body:");
300
-			prst(node->funcdecl->body, lev+1);
299
+			prlev(state, lev, "Body:");
300
+			prst(state, node->funcdecl->body, lev+1);
301 301
 			break;
302 302
 	}
303 303
 }
304 304
 
305
-void st_print(stmt_node *stmt) {
306
-    prst(stmt, 0);
305
+void st_print(sol_state_t *state, stmt_node *stmt) {
306
+    prst(state, stmt, 0);
307 307
 }
308 308
 
309
-void ex_print(expr_node *expr) {
310
-    prex(expr, 0);
309
+void ex_print(sol_state_t *state, expr_node *expr) {
310
+    prex(state, expr, 0);
311 311
 }
312 312
 
313 313
 /*int main(int argc, char **argv) {
@@ -318,11 +318,11 @@ void ex_print(expr_node *expr) {
318 318
 	if(yyparse(&program)) {
319 319
 		printf("Syntax error (somewhere)\n");
320 320
 		printf("Partial tree:\n");
321
-		prst(program, 0);
321
+		prst(state, program, 0);
322 322
 		return 1;
323 323
 	}
324 324
 
325
-	prst(program, 0);
325
+	prst(state, program, 0);
326 326
 	return 0;
327 327
 }*/
328 328
 

+ 1
- 0
build.sh View File

@@ -6,6 +6,7 @@ gcc -c -g lex.yy.c
6 6
 gcc -c -g parser.tab.c
7 7
 gcc -c -g astprint.c
8 8
 gcc -c -g runtime.c
9
+gcc -c -g gc.c
9 10
 gcc -c -g object.c
10 11
 gcc -c -g state.c
11 12
 gcc -c -g builtins.c

+ 171
- 43
builtins.c View File

@@ -95,6 +95,7 @@ sol_object_t *sol_f_try(sol_state_t *state, sol_object_t *args) {
95 95
 		sol_obj_free(err);
96 96
 		sol_list_insert(state, ls, 0, zero);
97 97
 		sol_obj_free(zero);
98
+		sol_list_insert(state, ls, 2, state->traceback);
98 99
 		return ls;
99 100
 	}
100 101
 	sol_list_insert(state, ls, 0, res);
@@ -207,11 +208,11 @@ void ob_print(sol_object_t *obj) {
207 208
 			break;
208 209
 			
209 210
 		case SOL_STMT:
210
-			st_print(obj->node);
211
+			st_print(NULL, obj->node); //TODO: FIXME
211 212
 			break;
212 213
 			
213 214
 		case SOL_EXPR:
214
-			ex_print(obj->node);
215
+			ex_print(NULL, obj->node); //TODO: FIXME
215 216
 			break;
216 217
 			
217 218
 		case SOL_BUFFER:
@@ -235,14 +236,17 @@ void ob_print(sol_object_t *obj) {
235 236
 
236 237
 sol_object_t *sol_f_prepr(sol_state_t *state, sol_object_t *args) {
237 238
 	int i, sz = sol_list_len(state, args);
238
-    sol_object_t *obj;
239
+    sol_object_t *obj, *str;
239 240
 	seen = dsl_seq_new_array(NULL, NULL);
240 241
 	for(i=0; i<sz; i++) {
241 242
 		obj = sol_list_get_index(state, args, i);
242
-		ob_print(obj);
243
-		printf(" ");
243
+		str = sol_cast_repr(state, obj);
244
+		sol_printf(state, "%s", str->str);
245
+		sol_printf(state, " ");
244 246
 		sol_obj_free(obj);
247
+		sol_obj_free(str);
245 248
 	}
249
+	sol_printf(state, "\n");
246 250
 	printf("\n");
247 251
 	dsl_free_seq(seen);
248 252
 	seen = NULL;
@@ -375,6 +379,39 @@ sol_object_t *sol_f_parse(sol_state_t *state, sol_object_t *args) {
375 379
 	return sol_new_stmtnode(state, program);
376 380
 }
377 381
 
382
+sol_object_t *sol_f_ord(sol_state_t *state, sol_object_t *args) {
383
+	sol_object_t *arg = sol_list_get_index(state, args, 0), *str = sol_cast_string(state, arg);
384
+	sol_object_t *idx = sol_new_int(state, 0), *arg2, *iarg, *res;
385
+	size_t len = strlen(str->str);
386
+	sol_obj_free(arg);
387
+	if(sol_list_len(state, args)>1) {
388
+		arg2 = sol_list_get_index(state, args, 1);
389
+		iarg = sol_cast_int(state, arg2);
390
+		sol_obj_free(arg2);
391
+		idx->ival = iarg->ival;
392
+		sol_obj_free(iarg);
393
+	}
394
+	if(idx->ival < 0 || idx->ival >= len) {
395
+		sol_obj_free(str);
396
+		sol_obj_free(idx);
397
+		return sol_set_error_string(state, "Compute ord of out-of-bounds index");
398
+	}
399
+	res = sol_new_int(state, str->str[idx->ival]);
400
+	sol_obj_free(str);
401
+	sol_obj_free(idx);
402
+	return res;
403
+}
404
+
405
+sol_object_t *sol_f_chr(sol_state_t *state, sol_object_t *args) {
406
+	sol_object_t *arg = sol_list_get_index(state, args, 0), *iarg = sol_cast_int(state, arg);
407
+	char cbuf[2]={iarg->ival, 0};
408
+	sol_object_t *res = sol_new_string(state, cbuf);
409
+	sol_obj_free(arg);
410
+	sol_obj_free(iarg);
411
+	return res;
412
+}
413
+	
414
+
378 415
 sol_object_t *sol_f_debug_getref(sol_state_t *state, sol_object_t *args) {
379 416
 	sol_object_t *obj = sol_list_get_index(state, args, 0);
380 417
 	sol_object_t *res = sol_new_int(state, obj->refcnt - 2); // NB: We grabbed a reference, and there's one in the arglist, so account for them.
@@ -477,6 +514,17 @@ sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) {
477 514
 	return res;
478 515
 }
479 516
 
517
+sol_object_t *sol_f_ast_print(sol_state_t *state, sol_object_t *args) {
518
+	sol_object_t *obj = sol_list_get_index(state, args, 0);
519
+	if(sol_is_aststmt(obj)) {
520
+		st_print(state, obj->node);
521
+	} else {
522
+		ex_print(state, obj->node);
523
+	}
524
+	sol_obj_free(obj);
525
+	return sol_incref(state->None);
526
+}
527
+
480 528
 sol_object_t *sol_f_singlet_tostring(sol_state_t *state, sol_object_t *args) {
481 529
 	sol_object_t *obj = sol_list_get_index(state, args, 0), *res = sol_new_string(state, obj->str);
482 530
 	sol_obj_free(obj);
@@ -845,6 +893,16 @@ sol_object_t *sol_f_str_split(sol_state_t *state, sol_object_t *args) {
845 893
 	return res;
846 894
 }
847 895
 
896
+sol_object_t *sol_f_str_find(sol_state_t *state, sol_object_t *args) {
897
+	sol_object_t *str = sol_list_get_index(state, args, 0), *substr = sol_list_get_index(state, args, 1), *ssubstr = sol_cast_string(state, substr);
898
+	char *ptr = strstr(str->str, ssubstr->str);
899
+	sol_object_t *res = sol_new_int(state, ptr?ptr-str->str:-1);
900
+	sol_obj_free(str);
901
+	sol_obj_free(substr);
902
+	sol_obj_free(ssubstr);
903
+	return res;
904
+}
905
+
848 906
 sol_object_t *sol_f_list_add(sol_state_t *state, sol_object_t *args) {
849 907
 	sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ls;
850 908
 	if(!sol_is_list(b)) {
@@ -1039,22 +1097,25 @@ sol_object_t *sol_f_map_index(sol_state_t *state, sol_object_t *args) {
1039 1097
 	sol_object_t *map = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1);
1040 1098
 	sol_object_t *indexf = sol_map_get_name(state, map, "__index");
1041 1099
 	sol_object_t *res = NULL, *newls;
1042
-	if(!sol_is_none(state, indexf)) {
1043
-		if(indexf->ops->call && (sol_is_func(indexf) || sol_is_cfunc(indexf)) && indexf->ops->call != sol_f_not_impl) {
1044
-			newls = sol_new_list(state);
1045
-			sol_list_insert(state, newls, 0, indexf);
1046
-			sol_list_append(state, newls, args);
1047
-			res = indexf->ops->call(state, newls);
1048
-			sol_obj_free(newls);
1049
-		} else if(indexf->ops->index && indexf->ops->index != sol_f_not_impl) {
1050
-            newls = sol_new_list(state);
1051
-            sol_list_insert(state, newls, 0, indexf);
1052
-            sol_list_insert(state, newls, 1, b);
1053
-			res = indexf->ops->index(state, newls);
1054
-			sol_obj_free(newls);
1100
+	res = sol_map_get(state, map, b);
1101
+	if(sol_is_none(state, res)) {
1102
+		if(!sol_is_none(state, indexf)) {
1103
+			sol_obj_free(res);
1104
+			if(indexf->ops->call && (sol_is_func(indexf) || sol_is_cfunc(indexf)) && indexf->ops->call != sol_f_not_impl) {
1105
+				newls = sol_new_list(state);
1106
+				sol_list_insert(state, newls, 0, indexf);
1107
+				sol_list_append(state, newls, args);
1108
+				res = indexf->ops->call(state, newls);
1109
+				sol_obj_free(newls);
1110
+			} else if(indexf->ops->index && indexf->ops->index != sol_f_not_impl) {
1111
+				newls = sol_new_list(state);
1112
+				sol_list_insert(state, newls, 0, indexf);
1113
+				sol_list_insert(state, newls, 1, b);
1114
+				res = indexf->ops->index(state, newls);
1115
+				sol_obj_free(newls);
1116
+			}
1055 1117
 		}
1056 1118
 	}
1057
-	if(!res) res = sol_map_get(state, map, b);
1058 1119
 	sol_obj_free(indexf);
1059 1120
 	sol_obj_free(map);
1060 1121
 	sol_obj_free(b);
@@ -1120,9 +1181,38 @@ sol_object_t *sol_f_map_iter(sol_state_t *state, sol_object_t *args) {
1120 1181
 }
1121 1182
 
1122 1183
 sol_object_t *sol_f_map_tostring(sol_state_t *state, sol_object_t *args) {
1123
-	sol_object_t *cur = sol_new_string(state, "{"), *next, *str, *obj = sol_list_get_index(state, args, 0), *item;
1124
-	dsl_seq_iter *iter = dsl_new_seq_iter(obj->seq);
1184
+	sol_object_t *map = sol_list_get_index(state, args, 0), *res;
1185
+	sol_object_t *tostrf = sol_map_get_name(state, map, "__tostring"), *fargs;
1186
+	if(!sol_is_none(state, tostrf) && tostrf->ops->call) {
1187
+		fargs = sol_new_list(state);
1188
+		sol_list_insert(state, fargs, 0, tostrf);
1189
+		sol_list_insert(state, fargs, 1, map);
1190
+		res = tostrf->ops->call(state, fargs);
1191
+		sol_obj_free(fargs);
1192
+	} else {
1193
+		res = sol_cast_repr(state, map);
1194
+	}
1195
+	sol_obj_free(tostrf);
1196
+	sol_obj_free(map);
1197
+	return res;
1198
+}
1199
+
1200
+sol_object_t *sol_f_map_repr(sol_state_t *state, sol_object_t *args) {
1201
+	sol_object_t *cur = sol_new_string(state, "{"), *next, *str, *obj = sol_list_get_index(state, args, 0), *item, *reprf = sol_map_get_name(state, obj, "__repr"), *fargs;
1202
+	dsl_seq_iter *iter;
1125 1203
 	char s[64];
1204
+	if(!sol_is_none(state, reprf) && reprf->ops->call) {
1205
+		sol_obj_free(cur);
1206
+		fargs = sol_new_list(state);
1207
+		sol_list_insert(state, fargs, 0, reprf);
1208
+		sol_list_insert(state, fargs, 1, obj);
1209
+		cur = reprf->ops->call(state, fargs);
1210
+		sol_obj_free(fargs);
1211
+		sol_obj_free(obj);
1212
+		sol_obj_free(reprf);
1213
+		return cur;
1214
+	}
1215
+	iter = dsl_new_seq_iter(obj->seq);
1126 1216
 	while(!dsl_seq_iter_is_invalid(iter)) {
1127 1217
 		item = AS_OBJ(dsl_seq_iter_at(iter));
1128 1218
 		if(test_seen(item)) {
@@ -1293,6 +1383,10 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1293 1383
 	if(sol_is_aststmt(obj)) {
1294 1384
 		if(sol_string_eq(state, str, "type")) {
1295 1385
 			res = sol_new_int(state, stmt->type);
1386
+		} else if(sol_string_eq(state, str, "loc")) {
1387
+			res = sol_new_map(state);
1388
+			sol_map_set_name(state, res, "line", sol_new_int(state, stmt->loc.line));
1389
+			sol_map_set_name(state, res, "col", sol_new_int(state, stmt->loc.col));
1296 1390
 		} else {
1297 1391
 			switch(stmt->type) {
1298 1392
 					case ST_EXPR:
@@ -1350,6 +1444,10 @@ sol_object_t *sol_f_astnode_index(sol_state_t *state, sol_object_t *args) {
1350 1444
 	} else {
1351 1445
 		if(sol_string_eq(state, str, "type")) {
1352 1446
 			res = sol_new_int(state, expr->type);
1447
+		} else if(sol_string_eq(state, str, "loc")) {
1448
+			res = sol_new_map(state);
1449
+			sol_map_set_name(state, res, "line", sol_new_int(state, expr->loc.line));
1450
+			sol_map_set_name(state, res, "col", sol_new_int(state, expr->loc.col));
1353 1451
 		} else {
1354 1452
 			switch(expr->type) {
1355 1453
 				case EX_LIT:
@@ -1482,15 +1580,26 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1482 1580
 	stmt_node *stmt = (stmt_node *) obj->node;
1483 1581
 	stmtlist_node *curs, *prevs;
1484 1582
 	expr_node *expr = (expr_node *) obj->node;
1485
-	exprlist_node *cure, *preve;
1486
-	assoclist_node *cura, *preva;
1487
-	identlist_node *curi, *previ;
1583
+	exprlist_node *cure, *preve = NULL;
1584
+	assoclist_node *cura, *preva = NULL;
1585
+	identlist_node *curi, *previ = NULL;
1488 1586
 	int i=0, len;
1489 1587
 	if(sol_is_aststmt(obj)) {
1490 1588
 		if(sol_string_eq(state, str, "type")) {
1491 1589
 			ival = sol_cast_int(state, val);
1492 1590
 			stmt->type = ival->ival;
1493 1591
 			sol_obj_free(ival);
1592
+		} else if(sol_string_eq(state, str, "loc") && sol_is_map(val)) {
1593
+			pair = sol_map_get_name(state, val, "line");
1594
+			ival = sol_cast_int(state, pair);
1595
+			stmt->loc.line = ival->ival;
1596
+			sol_obj_free(ival);
1597
+			sol_obj_free(pair);
1598
+			pair = sol_map_get_name(state, val, "col");
1599
+			ival = sol_cast_int(state, pair);
1600
+			stmt->loc.col = ival->ival;
1601
+			sol_obj_free(ival);
1602
+			sol_obj_free(pair);
1494 1603
 		} else {
1495 1604
 			switch(stmt->type) {
1496 1605
 				case ST_EXPR:
@@ -1543,8 +1652,9 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1543 1652
 									prevs->next = curs;
1544 1653
 								}
1545 1654
 							}
1655
+							if(stmt->stmtlist == curs) stmt->stmtlist = NULL;
1546 1656
 							free(curs);
1547
-							prevs->next = NULL;
1657
+							if(prevs) prevs->next = NULL;
1548 1658
 						} else {
1549 1659
 							stmt->stmtlist = NULL;
1550 1660
 						}
@@ -1563,6 +1673,17 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1563 1673
 			ival = sol_cast_int(state, val);
1564 1674
 			expr->type = ival->ival;
1565 1675
 			sol_obj_free(ival);
1676
+		} else if(sol_string_eq(state, str, "loc") && sol_is_map(val)) {
1677
+			pair = sol_map_get_name(state, val, "line");
1678
+			ival = sol_cast_int(state, pair);
1679
+			expr->loc.line = ival->ival;
1680
+			sol_obj_free(ival);
1681
+			sol_obj_free(pair);
1682
+			pair = sol_map_get_name(state, val, "col");
1683
+			ival = sol_cast_int(state, pair);
1684
+			expr->loc.col = ival->ival;
1685
+			sol_obj_free(ival);
1686
+			sol_obj_free(pair);
1566 1687
 		} else {
1567 1688
 			switch(expr->type) {
1568 1689
 				case EX_LIT:
@@ -1592,15 +1713,16 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1592 1713
 							cure = malloc(sizeof(exprlist_node));
1593 1714
 							expr->listgen->list = cure;
1594 1715
 							for(i=0; i<len; i++) {
1595
-								if(sol_is_aststmt(sol_list_get_index(state, val, i))) {
1716
+								if(sol_is_astexpr(sol_list_get_index(state, val, i))) {
1596 1717
 									cure->expr = sol_list_get_index(state, val, i)->node;
1597 1718
 									preve = cure;
1598 1719
 									cure = malloc(sizeof(exprlist_node));
1599 1720
 									preve->next = cure;
1600 1721
 								}
1601 1722
 							}
1723
+							if(expr->listgen->list == cure) expr->listgen->list = NULL;
1602 1724
 							free(cure);
1603
-							preve->next = NULL;
1725
+							if(preve) preve->next = NULL;
1604 1726
 						} else {
1605 1727
 							expr->listgen->list = NULL;
1606 1728
 						}
@@ -1626,8 +1748,9 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1626 1748
 									}
1627 1749
 								}
1628 1750
 							}
1751
+							if(expr->mapgen->map == cura) expr->mapgen->map = NULL;
1629 1752
 							free(cura);
1630
-							preva->next = NULL;
1753
+							if(preva) preva->next = NULL;
1631 1754
 						} else {
1632 1755
 							expr->mapgen->map = NULL;
1633 1756
 						}
@@ -1701,15 +1824,16 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1701 1824
 							cure = malloc(sizeof(exprlist_node));
1702 1825
 							expr->call->args= cure;
1703 1826
 							for(i=0; i<len; i++) {
1704
-								if(sol_is_aststmt(sol_list_get_index(state, val, i))) {
1827
+								if(sol_is_astexpr(sol_list_get_index(state, val, i))) {
1705 1828
 									cure->expr = sol_list_get_index(state, val, i)->node;
1706 1829
 									preve = cure;
1707 1830
 									cure = malloc(sizeof(exprlist_node));
1708 1831
 									preve->next = cure;
1709 1832
 								}
1710 1833
 							}
1834
+							if(expr->call->args == cure) expr->call->args = NULL;
1711 1835
 							free(cure);
1712
-							preve->next = NULL;
1836
+							if(preve) preve->next = NULL;
1713 1837
 						} else {
1714 1838
 							expr->call->args = NULL;
1715 1839
 						}
@@ -1727,17 +1851,16 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1727 1851
 							curi = malloc(sizeof(identlist_node));
1728 1852
 							expr->funcdecl->args= curi;
1729 1853
 							for(i=0; i<len; i++) {
1730
-								if(sol_is_aststmt(sol_list_get_index(state, val, i))) {
1731
-									sval = sol_cast_string(state, sol_list_get_index(state, val, i));
1732
-									curi->ident = strdup(sval->str);
1733
-									sol_obj_free(sval);
1734
-									previ = curi;
1735
-									curi = malloc(sizeof(identlist_node));
1736
-									previ->next = curi;
1737
-								}
1854
+								sval = sol_cast_string(state, sol_list_get_index(state, val, i));
1855
+								curi->ident = strdup(sval->str);
1856
+								sol_obj_free(sval);
1857
+								previ = curi;
1858
+								curi = malloc(sizeof(identlist_node));
1859
+								previ->next = curi;
1738 1860
 							}
1861
+							if(expr->funcdecl->args == curi) expr->funcdecl->args = NULL;
1739 1862
 							free(curi);
1740
-							previ->next = NULL;
1863
+							if(previ) previ->next = NULL;
1741 1864
 						} else {
1742 1865
 							expr->funcdecl->args = NULL;
1743 1866
 						}
@@ -1751,11 +1874,10 @@ sol_object_t *sol_f_astnode_setindex(sol_state_t *state, sol_object_t *args) {
1751 1874
 	sol_obj_free(obj);
1752 1875
 	sol_obj_free(key);
1753 1876
 	sol_obj_free(str);
1754
-	sol_obj_free(val);
1755
-	return sol_incref(state->None);
1877
+	return val;
1756 1878
 }
1757 1879
 
1758
-static char *sol_StmtNames[]={"EXPR", "IFSELSE", "LOOP", "ITER", "RET", "CONT", "BREAK"};
1880
+static char *sol_StmtNames[]={"EXPR", "IFSELSE", "LOOP", "ITER", "LIST", "RET", "CONT", "BREAK"};
1759 1881
 static char *sol_ExprNames[]={"LIT", "LISTGEN", "MAPGEN", "BINOP", "UNOP", "INDEX", "SETINDEX", "ASSIGN", "REF", "CALL", "FUNCDECL"}; 
1760 1882
 
1761 1883
 sol_object_t *sol_f_astnode_tostring(sol_state_t *state, sol_object_t *args) {
@@ -2161,7 +2283,7 @@ sol_object_t *sol_f_stream_read(sol_state_t *state, sol_object_t *args) {
2161 2283
 		iamt = sol_cast_int(state, amt);
2162 2284
 		s = malloc((iamt->ival + 1)*sizeof(char));
2163 2285
 		count = sol_stream_fread(state, stream, s, sizeof(char), iamt->ival);
2164
-		s[iamt->ival]='\0';
2286
+		s[count]='\0';
2165 2287
 		sol_obj_free(iamt);
2166 2288
 	}
2167 2289
 	if(s) {
@@ -2201,6 +2323,12 @@ sol_object_t *sol_f_stream_flush(sol_state_t *state, sol_object_t *args) {
2201 2323
 	return res;
2202 2324
 }
2203 2325
 
2326
+sol_object_t *sol_f_stream_eof(sol_state_t *state, sol_object_t *args) {
2327
+	sol_object_t *stream = sol_list_get_index(state, args, 0), *res = sol_new_int(state, sol_stream_feof(state, stream));
2328
+	sol_obj_free(stream);
2329
+	return res;
2330
+}
2331
+
2204 2332
 static char *sol_FileModes[]={
2205 2333
 	NULL,
2206 2334
 	"r",

+ 42
- 0
gc.c View File

@@ -0,0 +1,42 @@
1
+#include <stdlib.h>
2
+#include "sol.h"
3
+
4
+#ifdef DEBUG_GC
5
+
6
+#else
7
+
8
+sol_object_t *sol_alloc_object(sol_state_t *state) {
9
+	sol_object_t *res = malloc(sizeof(sol_object_t));
10
+	if(!res) {
11
+		sol_set_error(state, state->OutOfMemory);
12
+		return sol_incref(state->None);
13
+	}
14
+	res->refcnt = 0;
15
+	res->ops = &(state->NullOps);
16
+	return sol_incref(res);
17
+}
18
+
19
+sol_object_t *sol_obj_acquire(sol_object_t *obj) {
20
+	return sol_incref(obj);
21
+}
22
+
23
+void sol_obj_free(sol_object_t *obj) {
24
+	if(!obj) {
25
+		printf("WARNING: Attempt to free NULL\n");
26
+		return;
27
+	}
28
+	if(sol_decref(obj) <= 0) {
29
+		if(obj->refcnt < 0) {
30
+			printf("WARNING: Encountered refcnt < 0!\nObject %p type %d ref %d\n", obj, obj->type, obj->refcnt);
31
+		} else {
32
+			sol_obj_release(obj);
33
+		}
34
+	}
35
+}
36
+
37
+void sol_obj_release(sol_object_t *obj) {
38
+    if(obj->ops->free) obj->ops->free(NULL, obj);
39
+    free(obj);
40
+}
41
+
42
+#endif

+ 10
- 0
interp.sol View File

@@ -56,6 +56,16 @@ while __interp.running do
56 56
 						__interp.result = try(__interp.program[1])
57 57
 						if !__interp.result[0] then
58 58
 							print(__interp.result[1])
59
+							print(__interp.result[2])
60
+							for ent in __interp.result[2] do
61
+								st = ent[0]
62
+								scope = ent[1]
63
+								if st.type == ast.ST_LIST then continue end
64
+								print('In', st, 'at', st.loc.line, ',', st.loc.col, ':')
65
+								ast.print(st)
66
+								print(scope)
67
+								print('---')
68
+							end
59 69
 						else
60 70
 							if __interp.isexpr then
61 71
 								prepr(__interp.result[1])

+ 36
- 35
lex.yy.c View File

@@ -8,7 +8,7 @@
8 8
 #define FLEX_SCANNER
9 9
 #define YY_FLEX_MAJOR_VERSION 2
10 10
 #define YY_FLEX_MINOR_VERSION 5
11
-#define YY_FLEX_SUBMINOR_VERSION 39
11
+#define YY_FLEX_SUBMINOR_VERSION 35
12 12
 #if YY_FLEX_SUBMINOR_VERSION > 0
13 13
 #define FLEX_BETA
14 14
 #endif
@@ -161,12 +161,7 @@ typedef unsigned int flex_uint32_t;
161 161
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
162 162
 #endif
163 163
 
164
-#ifndef YY_TYPEDEF_YY_SIZE_T
165
-#define YY_TYPEDEF_YY_SIZE_T
166
-typedef size_t yy_size_t;
167
-#endif
168
-
169
-extern yy_size_t yyleng;
164
+extern int yyleng;
170 165
 
171 166
 extern FILE *yyin, *yyout;
172 167
 
@@ -175,7 +170,6 @@ extern FILE *yyin, *yyout;
175 170
 #define EOB_ACT_LAST_MATCH 2
176 171
 
177 172
     #define YY_LESS_LINENO(n)
178
-    #define YY_LINENO_REWIND_TO(ptr)
179 173
     
180 174
 /* Return all but the first "n" matched characters back to the input stream. */
181 175
 #define yyless(n) \
@@ -193,6 +187,11 @@ extern FILE *yyin, *yyout;
193 187
 
194 188
 #define unput(c) yyunput( c, (yytext_ptr)  )
195 189
 
190
+#ifndef YY_TYPEDEF_YY_SIZE_T
191
+#define YY_TYPEDEF_YY_SIZE_T
192
+typedef size_t yy_size_t;
193
+#endif
194
+
196 195
 #ifndef YY_STRUCT_YY_BUFFER_STATE
197 196
 #define YY_STRUCT_YY_BUFFER_STATE
198 197
 struct yy_buffer_state
@@ -210,7 +209,7 @@ struct yy_buffer_state
210 209
 	/* Number of characters read into yy_ch_buf, not including EOB
211 210
 	 * characters.
212 211
 	 */
213
-	yy_size_t yy_n_chars;
212
+	int yy_n_chars;
214 213
 
215 214
 	/* Whether we "own" the buffer - i.e., we know we created it,
216 215
 	 * and can realloc() it to grow it, and should free() it to
@@ -280,8 +279,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
280 279
 
281 280
 /* yy_hold_char holds the character lost when yytext is formed. */
282 281
 static char yy_hold_char;
283
-static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
284
-yy_size_t yyleng;
282
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
283
+int yyleng;
285 284
 
286 285
 /* Points to current character in buffer. */
287 286
 static char *yy_c_buf_p = (char *) 0;
@@ -309,7 +308,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
309 308
 
310 309
 YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
311 310
 YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
312
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len  );
311
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
313 312
 
314 313
 void *yyalloc (yy_size_t  );
315 314
 void *yyrealloc (void *,yy_size_t  );
@@ -605,7 +604,7 @@ static void update_loc(YYLTYPE *yylloc, char *yytext){
605 604
 <STRING>. { str_putc(*yytext); }
606 605
 
607 606
 */
608
-#line 609 "lex.yy.c"
607
+#line 608 "lex.yy.c"
609 608
 
610 609
 #define INITIAL 0
611 610
 
@@ -644,7 +643,7 @@ FILE *yyget_out (void );
644 643
 
645 644
 void yyset_out  (FILE * out_str  );
646 645
 
647
-yy_size_t yyget_leng (void );
646
+int yyget_leng (void );
648 647
 
649 648
 char *yyget_text (void );
650 649
 
@@ -806,6 +805,11 @@ YY_DECL
806 805
     
807 806
         YYLTYPE * yylloc;
808 807
     
808
+#line 85 "tokenizer.lex"
809
+
810
+
811
+#line 812 "lex.yy.c"
812
+
809 813
     yylval = yylval_param;
810 814
 
811 815
     yylloc = yylloc_param;
@@ -836,12 +840,6 @@ YY_DECL
836 840
 		yy_load_buffer_state( );
837 841
 		}
838 842
 
839
-	{
840
-#line 85 "tokenizer.lex"
841
-
842
-
843
-#line 844 "lex.yy.c"
844
-
845 843
 	while ( 1 )		/* loops until end-of-file is reached */
846 844
 		{
847 845
 		yy_cp = (yy_c_buf_p);
@@ -858,7 +856,7 @@ YY_DECL
858 856
 yy_match:
859 857
 		do
860 858
 			{
861
-			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
859
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
862 860
 			if ( yy_accept[yy_current_state] )
863 861
 				{
864 862
 				(yy_last_accepting_state) = yy_current_state;
@@ -1206,7 +1204,7 @@ YY_RULE_SETUP
1206 1204
 #line 207 "tokenizer.lex"
1207 1205
 ECHO;
1208 1206
 	YY_BREAK
1209
-#line 1210 "lex.yy.c"
1207
+#line 1208 "lex.yy.c"
1210 1208
 case YY_STATE_EOF(INITIAL):
1211 1209
 	yyterminate();
1212 1210
 
@@ -1337,7 +1335,6 @@ case YY_STATE_EOF(INITIAL):
1337 1335
 			"fatal flex scanner internal error--no action found" );
1338 1336
 	} /* end of action switch */
1339 1337
 		} /* end of scanning one token */
1340
-	} /* end of user's declarations */
1341 1338
 } /* end of yylex */
1342 1339
 
1343 1340
 /* yy_get_next_buffer - try to read in a new buffer
@@ -1393,21 +1390,21 @@ static int yy_get_next_buffer (void)
1393 1390
 
1394 1391
 	else
1395 1392
 		{
1396
-			yy_size_t num_to_read =
1393
+			int num_to_read =
1397 1394
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
1398 1395
 
1399 1396
 		while ( num_to_read <= 0 )
1400 1397
 			{ /* Not enough room in the buffer - grow it. */
1401 1398
 
1402 1399
 			/* just a shorter name for the current buffer */
1403
-			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
1400
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
1404 1401
 
1405 1402
 			int yy_c_buf_p_offset =
1406 1403
 				(int) ((yy_c_buf_p) - b->yy_ch_buf);
1407 1404
 
1408 1405
 			if ( b->yy_is_our_buffer )
1409 1406
 				{
1410
-				yy_size_t new_size = b->yy_buf_size * 2;
1407
+				int new_size = b->yy_buf_size * 2;
1411 1408
 
1412 1409
 				if ( new_size <= 0 )
1413 1410
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1438,7 +1435,7 @@ static int yy_get_next_buffer (void)
1438 1435
 
1439 1436
 		/* Read in more data. */
1440 1437
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
1441
-			(yy_n_chars), num_to_read );
1438
+			(yy_n_chars), (size_t) num_to_read );
1442 1439
 
1443 1440
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1444 1441
 		}
@@ -1533,7 +1530,7 @@ static int yy_get_next_buffer (void)
1533 1530
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1534 1531
 	yy_is_jam = (yy_current_state == 111);
1535 1532
 
1536
-		return yy_is_jam ? 0 : yy_current_state;
1533
+	return yy_is_jam ? 0 : yy_current_state;
1537 1534
 }
1538 1535
 
1539 1536
     static void yyunput (int c, register char * yy_bp )
@@ -1548,7 +1545,7 @@ static int yy_get_next_buffer (void)
1548 1545
 	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
1549 1546
 		{ /* need to shift things up to make room */
1550 1547
 		/* +2 for EOB chars. */
1551
-		register yy_size_t number_to_move = (yy_n_chars) + 2;
1548
+		register int number_to_move = (yy_n_chars) + 2;
1552 1549
 		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
1553 1550
 					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
1554 1551
 		register char *source =
@@ -1597,7 +1594,7 @@ static int yy_get_next_buffer (void)
1597 1594
 
1598 1595
 		else
1599 1596
 			{ /* need more input */
1600
-			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
1597
+			int offset = (yy_c_buf_p) - (yytext_ptr);
1601 1598
 			++(yy_c_buf_p);
1602 1599
 
1603 1600
 			switch ( yy_get_next_buffer(  ) )
@@ -1757,6 +1754,10 @@ static void yy_load_buffer_state  (void)
1757 1754
 	yyfree((void *) b  );
1758 1755
 }
1759 1756
 
1757
+#ifndef __cplusplus
1758
+extern int isatty (int );
1759
+#endif /* __cplusplus */
1760
+    
1760 1761
 /* Initializes or reinitializes a buffer.
1761 1762
  * This function is sometimes called more than once on the same buffer,
1762 1763
  * such as during a yyrestart() or at EOF.
@@ -1869,7 +1870,7 @@ void yypop_buffer_state (void)
1869 1870
  */
1870 1871
 static void yyensure_buffer_stack (void)
1871 1872
 {
1872
-	yy_size_t num_to_alloc;
1873
+	int num_to_alloc;
1873 1874
     
1874 1875
 	if (!(yy_buffer_stack)) {
1875 1876
 
@@ -1966,12 +1967,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
1966 1967
  * 
1967 1968
  * @return the newly allocated buffer state object.
1968 1969
  */
1969
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
1970
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
1970 1971
 {
1971 1972
 	YY_BUFFER_STATE b;
1972 1973
 	char *buf;
1973 1974
 	yy_size_t n;
1974
-	yy_size_t i;
1975
+	int i;
1975 1976
     
1976 1977
 	/* Get memory for full buffer, including space for trailing EOB's. */
1977 1978
 	n = _yybytes_len + 2;
@@ -2053,7 +2054,7 @@ FILE *yyget_out  (void)
2053 2054
 /** Get the length of the current token.
2054 2055
  * 
2055 2056
  */
2056
-yy_size_t yyget_leng  (void)
2057
+int yyget_leng  (void)
2057 2058
 {
2058 2059
         return yyleng;
2059 2060
 }
@@ -2201,7 +2202,7 @@ void yyfree (void * ptr )
2201 2202
 
2202 2203
 #define YYTABLES_NAME "yytables"
2203 2204
 
2204
-#line 206 "tokenizer.lex"
2205
+#line 207 "tokenizer.lex"
2205 2206
 
2206 2207
 
2207 2208
 

+ 472
- 0
monty.sol View File

@@ -0,0 +1,472 @@
1
+TOK = {LPAREN = 1, RPAREN = 2, INT = 3, BOOL = 4, NAME = 5, QUOTE = 6, EOF = 7}
2
+keys = []
3
+for k in TOK do keys:insert(#keys, k) end
4
+for k in keys do TOK[TOK[k]]=k end
5
+
6
+token = {
7
+	new = func (type, value)
8
+		return {type = type, value = value, __index = token}
9
+	end,
10
+	pretty = func(self)
11
+		tname = TOK[self.type]
12
+		tval = tostring(self.value)
13
+		return '{'+tname+':'+tval+'}'
14
+	end
15
+}
16
+
17
+tokenizer = {
18
+	WS = " "+chr(8)+chr(9)+chr(10),
19
+	NAMESET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=+-*/.<>?!@$%^~",
20
+	DIGITS = "0123456789",
21
+	EOF = {},
22
+	new = func (str)
23
+		res = {str = str, pushed = None, __index = tokenizer}
24
+		res:init()
25
+		return res
26
+	end,
27
+	init = func(self)
28
+		--print('In init, self is', self)
29
+		res.cur = res:token()
30
+		res.next = res:token()
31
+	end,
32
+	next_char = func(self)
33
+		if self.pushed == None then
34
+			--print('In next_char, self is', self)
35
+			--print('In next_char, self.str is', self.str)
36
+			if self.str:eof() then return self.EOF end
37
+			res = self.str:read(1)
38
+		else
39
+			--print('Retrieving from pushback', self.pushed)
40
+			res = self.pushed[0]
41
+			self.pushed = self.pushed:sub(1)
42
+			if self.pushed == "" then self.pushed = None end
43
+		end
44
+		--print(res)
45
+		return res
46
+	end,
47
+	push_back = func(self, s)
48
+		--print('Pushing back', s)
49
+		if s == self.EOF then print('WARNING: Attempted to push_back EOF'); return end
50
+		if self.pushed == None then
51
+			self.pushed = s
52
+		else
53
+			self.pushed = s + self.pushed
54
+		end
55
+		--print('self.pushed:', self.pushed)
56
+	end,
57
+	token = func (self)
58
+		--print('In token, self is', self)
59
+		--print('In token, self.str is', self.str)
60
+		c = self:next_char()
61
+		while !(c == self.EOF) do
62
+			if c == "" then return token.new(TOK.EOF, None) end
63
+			if c == "(" then return token.new(TOK.LPAREN, c) end
64
+			if c == ")" then return token.new(TOK.RPAREN, c) end
65
+			if self.NAMESET:find(c) >= 0 then
66
+				--print('{NAME}')
67
+				name = c
68
+				c = self:next_char()
69
+				while 1 do
70
+					found = 0
71
+					if self.NAMESET:find(c) >= 0 then found = 1 end
72
+					if self.DIGITS:find(c) >= 0 then found = 1 end
73
+					if !found then break end
74
+					name += c
75
+					c = self:next_char()
76
+					if c == self.EOF then continue end
77
+				end
78
+				self:push_back(c)
79
+				return token.new(TOK.NAME, name)
80
+			end
81
+			if self.DIGITS:find(c) >= 0 then
82
+				val = c
83
+				c = self:next_char()
84
+				while self.DIGITS:find(c) >= 0 do
85
+					val += c
86
+					c = self:next_char()
87
+					if c == self.EOF then continue end
88
+				end
89
+				self:push_back(c)
90
+				return token.new(TOK.INT, toint(val))
91
+			end
92
+			if c == "#" then
93
+				c = self:next_char()
94
+				if c == "t" then return token.new(TOK.BOOL, 1) end
95
+				if c == "f" then return token.new(TOK.BOOL, 0) end
96
+				error("Invalid value for bool literal: "+c)
97
+			end
98
+			if c == "'" then return token.new(TOK.QUOTE, c) end
99
+			if self.WS:find(c) >= 0 then
100
+				c = self:next_char()
101
+				continue
102
+			end
103
+			if c == ";" then
104
+				c = self:next_char()
105
+				while 1 do
106
+					if c == chr(10) then break end
107
+					c = self:next_char()
108
+				end
109
+				c = self:next_char()
110
+				continue
111
+			end
112
+			error("Invalid character in token stream: "+c)
113
+		end
114
+		return token.new(TOK.EOF, None)
115
+	end,
116
+	advance = func(self)
117
+		self.cur = self.next
118
+		self.next = self:token()
119
+	end
120
+}
121
+
122
+
123
+
124
+ttreegen = {
125
+	new = func(tok)
126
+		return {tok = tok, __index = ttreegen}
127
+	end,
128
+	generate = func(self, consume)
129
+		res = self.TT_DISPATCH[self.tok.cur.type](self, self.tok.cur)
130
+		if None == consume then self.tok:advance() end
131
+		return res
132
+	end,
133
+	TT_DISPATCH = {
134
+		[TOK.LPAREN] = func(self, tok)
135
+			toklist = []
136
+			self.tok:advance()
137
+			tok = self.tok.cur
138
+			while 1 do
139
+				if tok.type == TOK.RPAREN then break end
140
+				if tok.type == TOK.EOF then error('Encountered EOF while matching delimiter') end
141
+				toklist:insert(#toklist, self.TT_DISPATCH[tok.type](self, tok))
142
+				self.tok:advance()
143
+				tok = self.tok.cur
144
+			end
145
+			return toklist
146
+		end,
147
+		[TOK.RPAREN] = func(self, tok)
148
+			error("Unexpected right parenthesis")
149
+		end,
150
+		[TOK.INT] = func(self, tok)
151
+			return tok
152
+		end,
153
+		[TOK.BOOL] = func(self, tok)
154
+			return tok
155
+		end,
156
+		[TOK.NAME] = func(self, tok)
157
+			return tok
158
+		end,
159
+		[TOK.QUOTE] = func(self, tok)
160
+			self.tok:advance()
161
+			tok.quoting = self:generate(0)
162
+			return tok
163
+		end,
164
+		[TOK.EOF] = func(self, tok)
165
+			return None
166
+		end
167
+	}
168
+}
169
+
170
+EX = {CALL=1, ASSIGN=2, FUNCDECL=3, SCOPE=4, IFELSE=5, DATUM=6, LIT=7, REF=8, LIST=9}
171
+keys = []
172
+for k in EX do keys:insert(#keys, k) end
173
+for k in keys do EX[EX[k]]=k end
174
+
175
+node = {
176
+	new = func(type, value)
177
+		return {type=type, value=value, __index=node}
178
+	end,
179
+	pretty = func(self) return self.PRETTY_DISPATCH[self.type](self) end
180
+	PRETTY_DISPATCH = {
181
+		[EX.CALL] = func(self)
182
+			return '<CALL NAME='+(self.value.name)+' ARGS='+tostring(self.value.args:copy():map(func(i) if !(None == i) then return i:pretty() else return tostring(i) end end))+'>'
183
+		end,
184
+		[EX.ASSIGN] = func(self)
185
+			return '<ASSIGN NAME='+(self.value.name)+' VALUE='+(self.value.value:pretty())+'>'
186
+		end,
187
+		[EX.FUNCDECL] = func(self)
188
+			return '<FUNCDECL PARAMS='+tostring(self.value.params)+' BODY='+(self.value.body:pretty())+'>'
189
+		end,
190
+		[EX.SCOPE] = func(self)
191
+			return '<SCOPE '+(self.value:copy():map(func(i) return i:pretty() end))+'>'
192
+		end,
193
+		[EX.IFELSE] = func(self)
194
+			return '<IFELSE COND='+(self.value.cond:pretty())+' IFT='+(self.value.ift:pretty())+' IFF='+(self.value.iff:pretty())+'>'
195
+		end,
196
+		[EX.DATUM] = func(self)
197
+			return '#'+tostring(self.value)
198
+		end,
199
+		[EX.LIT] = func(self)
200
+			if type(self.value) == 'list' then
201
+				return '/'+tostring(self.value:copy():map(func(i) return i:pretty() end))
202
+			end
203
+			return '/'+tostring(self.value)
204
+		end,
205
+		[EX.REF] = func(self)
206
+			--print('In EX.REF, self is', self)
207
+			res = '@'+tostring(self.value)
208
+			--print('In EX.REF, returning', res)
209
+			return res
210
+		end,
211
+		[EX.LIST] = func(self)
212
+			--print('In EX.LIST, self is', self)
213
+			return '<LIST '+(self.value:copy():map(func(i) return i:pretty() end))+'>'
214
+		end
215
+	}
216
+}
217
+
218
+parser = {
219
+	new = func(ttgen)
220
+		return {ttgen = ttgen, __index = parser}
221
+	end,
222
+	parse = func(self, tt)
223
+		if type(tt) == 'map' then
224
+			--print('In parse, self is', self)
225
+			--print('In parse, tt is', tt)
226
+			--print('In parse, dispatch to', self.TT_PARSE_DISPATCH[tt.type])
227
+			res = self.TT_PARSE_DISPATCH[tt.type](self, tt)
228
+		else
229
+			name = tt[0]
230
+			if !(name.type == TOK.NAME) then
231
+				error('Expected name as first element of expression-list')
232
+			end
233
+			rest = tt:copy()
234
+			rest:remove(0)
235
+			sc = self.SCALL_DISPATCH[name.value]
236
+			if !(None == sc) then
237
+				sc = None
238
+				res = self.SCALL_DISPATCH[name.value](self, rest)
239
+			else
240
+				res = node.new(EX.CALL, {name=name.value, args=rest:map(func(i) return self:parse(i) end)})
241
+			end
242
+		end
243
+		--print('In parse, returning', res:pretty())
244
+		return res
245
+	end,
246
+	TT_PARSE_DISPATCH = {
247
+		[TOK.INT] = func(self, tok)
248
+			return node.new(EX.LIT, tok.value)
249
+		end,
250
+		[TOK.BOOL] = func(self, tok)
251
+			return node.new(EX.LIT, tok.value)
252
+		end,
253
+		[TOK.NAME] = func(self, tok)
254
+			--print('In TOK.NAME, tok is', tok)
255
+			res =  node.new(EX.REF, tok.value)
256
+			--print('In TOK.NAME, returning', res)
257
+			return res
258
+		end,
259
+		[TOK.QUOTE] = func(self, tok)
260
+			return self:parse_datum(tok.quoting)
261
+		end
262
+	},
263
+	SCALL_DISPATCH = {
264
+		define = func(self, args)
265
+			name = args[0]
266
+			if !(name.type == TOK.NAME) then error('Define: expected name as first argument') end
267
+			value = self:parse(args[1])
268
+			return node.new(EX.ASSIGN, {name=name.value, value=value})
269
+		end,
270
+		["if"] = func(self, args)
271
+			cond = self:parse(args[0])
272
+			ift = self:parse(args[1])
273
+			iff = self:parse(args[2])
274
+			return node.new(EX.IFELSE, {cond=cond, ift=ift, iff=iff})
275
+		end,
276
+		begin = func(self, args)
277
+			args:map(func(i) return self:parse(i) end)
278
+			return node.new(EX.LIST, args)
279
+		end,
280
+		lambda = func(self, args)
281
+			--print('Lambda args:', args)
282
+			params = args[0]
283
+			if !(type(params) == 'list') then error('Lambda: expected parameters as first argument (got '+tostring(params)+')') end
284
+			params:map(func(i)
285
+				if !(type(i) == 'map') then error('Lambda: expected name token in argument list (got sublist)') end
286
+				if !(i.type == TOK.NAME) then error('Lambda: expected name token in argument list (got '+(i:pretty())+')') end
287
+				return i.value
288
+			end)
289
+			body = args:copy()
290
+			body:remove(0)
291
+			--print('Lambda body:', body)
292
+			body:map(func(i) return self:parse(i) end)
293
+			return node.new(EX.FUNCDECL, {params=params, body=node.new(EX.LIST, body)})
294
+		end,
295
+		let = func(self, args)
296
+			defs = args[0]
297
+			if !(type(defs) == 'list') then error('Let: expected list of bindings are first argument') end
298
+			defs:map(func(i)
299
+				if !(type(i) == 'list') then error('Let: expected a binding entry') end
300
+				return self.SCALL_DISPATCH.define(self, i)
301
+			end)
302
+			body = args:copy()
303
+			body:remove(0)
304
+			body:map(func(i) return self:parse(i) end)
305
+			return node.new(EX.SCOPE, defs+body)
306
+		end,
307
+		letrec = func(self, args)
308
+			defs = args[0]
309
+			if !(type(defs) == 'list') then error('Let: expected list of bindings are first argument') end
310
+			defs:map(func(i)
311
+				if !(type(i) == 'list') then error('Let: expected a binding entry') end
312
+				return self.SCALL_DISPATCH.define(self, i)
313
+			end)
314
+			body = args:copy()
315
+			body:remove(0)
316
+			body:map(func(i) return self:parse(i) end)
317
+			return node.new(EX.LIST, defs+body)
318
+		end
319
+	}
320
+	parse_datum = func(self, tt)
321
+		if type(tt) == 'map' then
322
+			return self.TT_PARSE_DATUM_DISPATCH[tt.type](self, tt)
323
+		else
324
+			list = []
325
+			for tok in tt do
326
+				list:insert(#list, self:parse_datum(tok))
327
+			end
328
+			return node.new(EX.LIT, list)
329
+		end
330
+	end,
331
+	TT_PARSE_DATUM_DISPATCH = {
332
+		[TOK.INT] = func(self, tok)
333
+			return node.new(EX.LIT, tok.value)
334
+		end,
335
+		[TOK.BOOL] = func(self, tok)
336
+			return node.new(EX.LIT, tok.value)
337
+		end,
338
+		[TOK.NAME] = func(self, tok)
339
+			return node.new(EX.LIT, tok.value)
340
+		end,
341
+		[TOK.QUOTE] = func(self, tok)
342
+			return self:parse(tok.quoting)
343
+		end
344
+	},
345
+	run = func(self)
346
+		tt = self.ttgen:generate()
347
+		list = []
348
+		while 1 do
349
+			if None == tt then break end
350
+			--if type(tt) == 'list' then
351
+				list:insert(#list, self:parse(tt))
352
+			--end
353
+			tt = self.ttgen:generate()
354
+		end
355
+		--print('In run, list is', list)
356
+		return node.new(EX.LIST, list)
357
+	end
358
+}
359
+
360
+converter = {
361
+	new = func(p)
362
+		return {parser=p, __index = converter}
363
+	end,
364
+	make = func(self, node)
365
+		--print('In make, node is a', EX[node.type], 'of value', node)
366
+		res = self.MAKE_DISPATCH[node.type](self, node)
367
+		--print('In make, returning', res)
368
+		if type(res) == "astnode" then ast.print(res) end
369
+		return res
370
+	end,
371
+	MAKE_DISPATCH = {
372
+		[EX.CALL] = func(self, node)
373
+			e = parse('f()').stmtlist[0].expr
374
+			e.expr.ident = node.value.name
375
+			args = node.value.args:copy():map(func(i) return self:make(i) end)
376
+			--print('In EX.CALL, replacement args are', args)
377
+			e.args = args
378
+			--print('In EX.CALL, args are', e.args)
379
+			return e
380
+		end,
381
+		[EX.ASSIGN] = func(self, node)
382
+			e = parse('a = b').stmtlist[0].expr
383
+			e.ident = node.value.name
384
+			e.value = self:make(node.value.value)
385
+			return e
386
+		end,
387
+		[EX.FUNCDECL] = func(self, node)
388
+			e = parse('func() None None end').stmtlist[0].expr
389
+			params = node.value.params
390
+			--print('In EX.FUNCDECL, params are', params)
391
+			e.args = params
392
+			--print('In EX.FUNCDECL, args are', e.args)
393
+			e.body.stmtlist = self:make(node.value.body)
394
+			return e
395
+		end,
396
+		[EX.SCOPE] = func(self, node)
397
+			e = parse('(func() None None end)()').stmtlist[0].expr
398
+			node.type = EX.LIST
399
+			e.expr.body.stmtlist = self:make(node)
400
+			node.type = EX.SCOPE
401
+			return e
402
+		end,
403
+		[EX.IFELSE] = func(self, node)
404
+			e = parse('(func() if None then return None else return None end end)()').stmtlist[0].expr
405
+			e.expr.body.stmtlist[0].cond = self:make(node.value.cond)
406
+			e.expr.body.stmtlist[0].iftrue.stmtlist[0].ret = self:make(node.value.ift)
407
+			e.expr.body.stmtlist[0].iffalse.stmtlist[0].ret = self:make(node.value.iff)
408
+			return e
409
+		end,
410
+		[EX.DATUM] = func(self, node) error('EX.DATUM: Not implemented') end,
411
+		[EX.LIT] = func(self, node)
412
+			if type(node.value) == 'list' then
413
+				e = parse('[None]').stmtlist[0].expr
414
+				e.list = node.value:copy():map(func(i) return self:make(i) end)
415
+			else
416
+				e = parse('None').stmtlist[0].expr
417
+				if type(node.value) == "int" then
418
+					e.littype = ast.LIT_INT
419
+					e.ival = node.value
420
+				end
421
+				if type(node.value) == "string" then
422
+					e.littype = ast.LIT_STRING
423
+					e.str = node.value
424
+				end
425
+			end
426
+			return e
427
+		end,
428
+		[EX.REF] = func(self, node)
429
+			e = parse('a').stmtlist[0].expr
430
+			e.ident = node.value
431
+			return e
432
+		end,
433
+		[EX.LIST] = func(self, node)
434
+			e = parse('func() None end').stmtlist[0].expr
435
+			l = node.value:copy()
436
+			l:map(func(i)
437
+				s = parse('None').stmtlist[0]
438
+				s.expr = self:make(i)
439
+				return s
440
+			end)
441
+			lastidx = (#l) - 1
442
+			r = parse('return None').stmtlist[0]
443
+			r.ret = l[lastidx].expr
444
+			l[lastidx] = r
445
+			--print('In EX.LIST, e is now' e)
446
+			e.body.stmtlist = l
447
+			return e.body.stmtlist
448
+		end
449
+	},
450
+	run = func(self)
451
+		list = self:make(self.parser:run())
452
+		res = parse('(func() None None end)()')
453
+		--print('In run, list is', list)
454
+		--for i in list do ast.print(i) end
455
+		res.stmtlist[0].expr.expr.body.stmtlist = list
456
+		return res
457
+	end
458
+}
459
+
460
+_G = debug.globals()
461
+_G['+'] = func(a, b) return a + b end
462
+_G['-'] = func(a, b) return a - b end
463
+_G['*'] = func(a, b) return a * b end
464
+_G['/'] = func(a, b) return a / b end
465
+_G['<'] = func(a, b) return a < b end
466
+_G['>'] = func(a, b) return a > b end
467
+_G['<='] = func(a, b) return a <= b end
468
+_G['>='] = func(a, b) return a >= b end
469
+_G['=='] = func(a, b) return a == b end
470
+_G['eq'] = _G['==']
471
+_G['or'] = func(a, b) return a || b end
472
+_G['and'] = func(a, b) return a && b end

+ 22
- 40
object.c View File

@@ -55,49 +55,15 @@ sol_object_t *sol_new_singlet(sol_state_t *state, const char *name) {
55 55
 		res->ops = &(state->SingletOps);
56 56
 		res->str = strdup(name);
57 57
 	}
58
-	return sol_incref(res);
58
+	return sol_incref(res); // XXX Segfault
59 59
 }
60 60
 
61 61
 // And, now, for the rest of the checked stuff...
62 62
 
63
-sol_object_t *sol_alloc_object(sol_state_t *state) {
64
-	sol_object_t *res = malloc(sizeof(sol_object_t));
65
-	if(!res) {
66
-		sol_set_error(state, state->OutOfMemory);
67
-		return sol_incref(state->None);
68
-	}
69
-	res->refcnt = 0;
70
-	res->ops = &(state->NullOps);
71
-	return sol_incref(res);
72
-}
73
-
74 63
 void sol_init_object(sol_state_t *state, sol_object_t *obj) {
75 64
 	if(obj->ops->init) obj->ops->init(state, obj);
76 65
 }
77 66
 
78
-sol_object_t *sol_obj_acquire(sol_object_t *obj) {
79
-	return sol_incref(obj);
80
-}
81
-
82
-void sol_obj_free(sol_object_t *obj) {
83
-	if(!obj) {
84
-		printf("WARNING: Attempt to free NULL\n");
85
-		return;
86
-	}
87
-	if(sol_decref(obj) <= 0) {
88
-		if(obj->refcnt < 0) {
89
-			printf("WARNING: Encountered refcnt < 0!\nObject %p type %d ref %d\n", obj, obj->type, obj->refcnt);
90
-		} else {
91
-			sol_obj_release(obj);
92
-		}
93
-	}
94
-}
95
-
96
-void sol_obj_release(sol_object_t *obj) {
97
-    if(obj->ops->free) obj->ops->free(NULL, obj);
98
-    free(obj);
99
-}
100
-
101 67
 sol_object_t *sol_new_int(sol_state_t *state, long i) {
102 68
 	sol_object_t *res = sol_alloc_object(state);
103 69
 	res->type = SOL_INTEGER;
@@ -549,7 +515,7 @@ size_t sol_stream_printf(sol_state_t *state, sol_object_t *stream, const char *f
549 515
 	va_list va;
550 516
 	size_t res;
551 517
 	if(!(stream->modes & MODE_WRITE)) {
552
-		sol_obj_free(sol_set_error_string(state, "Write to non-writable stream"));
518
+		if(state) sol_obj_free(sol_set_error_string(state, "Write to non-writable stream"));
553 519
 		return 0;
554 520
 	}
555 521
 	va_start(va, fmt);
@@ -558,11 +524,19 @@ size_t sol_stream_printf(sol_state_t *state, sol_object_t *stream, const char *f
558 524
 	return res;
559 525
 }
560 526
 
527
+size_t sol_stream_vprintf(sol_state_t *state, sol_object_t *stream, const char *fmt, va_list va) {
528
+	if(!(stream->modes & MODE_WRITE)) {
529
+		if(state) sol_obj_free(sol_set_error_string(state, "Write to non-writable stream"));
530
+		return 0;
531
+	}
532
+	return vfprintf(stream->stream, fmt, va);
533
+}
534
+
561 535
 size_t sol_stream_scanf(sol_state_t *state, sol_object_t *stream, const char *fmt, ...) {
562 536
 	va_list va;
563 537
 	size_t res;
564 538
 	if(!(stream->modes & MODE_READ)) {
565
-		sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
539
+		if(state) sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
566 540
 		return 0;
567 541
 	}
568 542
 	va_start(va, fmt);
@@ -573,7 +547,7 @@ size_t sol_stream_scanf(sol_state_t *state, sol_object_t *stream, const char *fm
573 547
 
574 548
 size_t sol_stream_fread(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz, size_t memb) {
575 549
 	if(!(stream->modes & MODE_READ)) {
576
-		sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
550
+		if(state) sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
577 551
 		return 0;
578 552
 	}
579 553
 	return fread(buffer, sz, memb, stream->stream);
@@ -581,7 +555,7 @@ size_t sol_stream_fread(sol_state_t *state, sol_object_t *stream, char *buffer,
581 555
 
582 556
 size_t sol_stream_fwrite(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz, size_t memb) {
583 557
 	if(!(stream->modes & MODE_WRITE)) {
584
-		sol_obj_free(sol_set_error_string(state, "Write to non-writable stream"));
558
+		if(state) sol_obj_free(sol_set_error_string(state, "Write to non-writable stream"));
585 559
 		return 0;
586 560
 	}
587 561
 	return fwrite(buffer, sz, memb, stream->stream);
@@ -589,12 +563,20 @@ size_t sol_stream_fwrite(sol_state_t *state, sol_object_t *stream, char *buffer,
589 563
 
590 564
 char *sol_stream_fgets(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz) {
591 565
 	if(!(stream->modes & MODE_READ)) {
592
-		sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
566
+		if(state) sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
593 567
 		return NULL;
594 568
 	}
595 569
 	return fgets(buffer, sz, stream->stream);
596 570
 }
597 571
 
572
+int sol_stream_fputc(sol_state_t *state, sol_object_t *stream, int ch) {
573
+	if(!(stream->modes & MODE_WRITE)) {
574
+		if(state) sol_obj_free(sol_set_error_string(state, "Write to non-writable stream"));
575
+		return 0;
576
+	}
577
+	return fputc(ch, stream->stream);
578
+}
579
+
598 580
 int sol_stream_feof(sol_state_t *state, sol_object_t *stream) {
599 581
 	return feof(stream->stream);
600 582
 }

+ 17
- 17
parser.output View File

@@ -61,7 +61,7 @@ Grammar
61 61
     1 program: stmt_list
62 62
 
63 63
     2 stmt_list: stmt_list stmt
64
-    3          | %empty
64
+    3          | /* empty */
65 65
 
66 66
     4 stmt: expr
67 67
     5     | IF expr THEN stmt_list END
@@ -164,17 +164,17 @@ Grammar
164 164
 
165 165
    85 paren_expr: LPAREN expr RPAREN
166 166
 
167
-   86 expr_list: %empty
167
+   86 expr_list: /* empty */
168 168
    87          | expr
169 169
    88          | expr_list COMMA
170 170
    89          | expr_list expr
171 171
 
172
-   90 ident_list: %empty
172
+   90 ident_list: /* empty */
173 173
    91           | IDENT
174 174
    92           | ident_list COMMA
175 175
    93           | ident_list IDENT
176 176
 
177
-   94 assoc_list: %empty
177
+   94 assoc_list: /* empty */
178 178
    95           | assoc_item
179 179
    96           | assoc_list COMMA
180 180
    97           | assoc_list assoc_item
@@ -309,7 +309,7 @@ State 0
309 309
     0 $accept: . program $end
310 310
     1 program: . stmt_list
311 311
     2 stmt_list: . stmt_list stmt
312
-    3          | . %empty
312
+    3          | .
313 313
 
314 314
     $default  reduce using rule 3 (stmt_list)
315 315
 
@@ -1122,7 +1122,7 @@ State 18
1122 1122
 State 19
1123 1123
 
1124 1124
    83 gen_expr: LBRACE . assoc_list RBRACE
1125
-   94 assoc_list: . %empty  [IDENT, RBRACE, LBRACKET, COMMA]
1125
+   94 assoc_list: .  [IDENT, RBRACE, LBRACKET, COMMA]
1126 1126
    95           | . assoc_item
1127 1127
    96           | . assoc_list COMMA
1128 1128
    97           | . assoc_list assoc_item
@@ -1325,7 +1325,7 @@ State 21
1325 1325
    83         | . LBRACE assoc_list RBRACE
1326 1326
    84         | . paren_expr
1327 1327
    85 paren_expr: . LPAREN expr RPAREN
1328
-   86 expr_list: . %empty  [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, LBRACKET, RBRACKET, COMMA, POUND]
1328
+   86 expr_list: .  [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, LBRACKET, RBRACKET, COMMA, POUND]
1329 1329
    87          | . expr
1330 1330
    88          | . expr_list COMMA
1331 1331
    89          | . expr_list expr
@@ -1742,7 +1742,7 @@ State 45
1742 1742
 State 46
1743 1743
 
1744 1744
    67 funcdecl_expr: FUNC LPAREN . ident_list RPAREN stmt_list END
1745
-   90 ident_list: . %empty  [IDENT, RPAREN, COMMA]
1745
+   90 ident_list: .  [IDENT, RPAREN, COMMA]
1746 1746
    91           | . IDENT
1747 1747
    92           | . ident_list COMMA
1748 1748
    93           | . ident_list IDENT
@@ -5353,7 +5353,7 @@ State 90
5353 5353
    83         | . LBRACE assoc_list RBRACE
5354 5354
    84         | . paren_expr
5355 5355
    85 paren_expr: . LPAREN expr RPAREN
5356
-   86 expr_list: . %empty  [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND]
5356
+   86 expr_list: .  [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND]
5357 5357
    87          | . expr
5358 5358
    88          | . expr_list COMMA
5359 5359
    89          | . expr_list expr
@@ -6408,7 +6408,7 @@ State 100
6408 6408
 State 101
6409 6409
 
6410 6410
     2 stmt_list: . stmt_list stmt
6411
-    3          | . %empty
6411
+    3          | .
6412 6412
     5 stmt: IF expr THEN . stmt_list END
6413 6413
     6     | IF expr THEN . stmt_list ELSE stmt_list END
6414 6414
 
@@ -6420,7 +6420,7 @@ State 101
6420 6420
 State 102
6421 6421
 
6422 6422
     2 stmt_list: . stmt_list stmt
6423
-    3          | . %empty
6423
+    3          | .
6424 6424
     7 stmt: WHILE expr DO . stmt_list END
6425 6425
 
6426 6426
     $default  reduce using rule 3 (stmt_list)
@@ -6541,7 +6541,7 @@ State 103
6541 6541
 State 104
6542 6542
 
6543 6543
    66 funcdecl_expr: FUNC IDENT LPAREN . ident_list RPAREN stmt_list END
6544
-   90 ident_list: . %empty  [IDENT, RPAREN, COMMA]
6544
+   90 ident_list: .  [IDENT, RPAREN, COMMA]
6545 6545
    91           | . IDENT
6546 6546
    92           | . ident_list COMMA
6547 6547
    93           | . ident_list IDENT
@@ -8099,7 +8099,7 @@ State 160
8099 8099
 State 161
8100 8100
 
8101 8101
     2 stmt_list: . stmt_list stmt
8102
-    3          | . %empty
8102
+    3          | .
8103 8103
    67 funcdecl_expr: FUNC LPAREN ident_list RPAREN . stmt_list END
8104 8104
 
8105 8105
     $default  reduce using rule 3 (stmt_list)
@@ -8235,7 +8235,7 @@ State 167
8235 8235
    83         | . LBRACE assoc_list RBRACE
8236 8236
    84         | . paren_expr
8237 8237
    85 paren_expr: . LPAREN expr RPAREN
8238
-   86 expr_list: . %empty  [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND]
8238
+   86 expr_list: .  [FUNC, NONE, IDENT, INT, FLOAT, STRING, MINUS, BNOT, LNOT, LBRACE, LPAREN, RPAREN, LBRACKET, COMMA, POUND]
8239 8239
    87          | . expr
8240 8240
    88          | . expr_list COMMA
8241 8241
    89          | . expr_list expr
@@ -8293,7 +8293,7 @@ State 167
8293 8293
 State 168
8294 8294
 
8295 8295
     2 stmt_list: . stmt_list stmt
8296
-    3          | . %empty
8296
+    3          | .
8297 8297
     6 stmt: IF expr THEN stmt_list ELSE . stmt_list END
8298 8298
 
8299 8299
     $default  reduce using rule 3 (stmt_list)
@@ -8318,7 +8318,7 @@ State 170
8318 8318
 State 171
8319 8319
 
8320 8320
     2 stmt_list: . stmt_list stmt
8321
-    3          | . %empty
8321
+    3          | .
8322 8322
     8 stmt: FOR IDENT IN expr DO . stmt_list END
8323 8323
 
8324 8324
     $default  reduce using rule 3 (stmt_list)
@@ -8329,7 +8329,7 @@ State 171
8329 8329
 State 172
8330 8330
 
8331 8331
     2 stmt_list: . stmt_list stmt
8332
-    3          | . %empty
8332
+    3          | .
8333 8333
    66 funcdecl_expr: FUNC IDENT LPAREN ident_list RPAREN . stmt_list END
8334 8334
 
8335 8335
     $default  reduce using rule 3 (stmt_list)

+ 955
- 754
parser.tab.c
File diff suppressed because it is too large
View File


+ 87
- 75
parser.tab.h View File

@@ -1,19 +1,19 @@
1
-/* A Bison parser, made by GNU Bison 3.0.2.  */
1
+/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
2 2
 
3 3
 /* Bison interface for Yacc-like parsers in C
4
-
5
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
6
-
4
+   
5
+      Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
6
+   
7 7
    This program is free software: you can redistribute it and/or modify
8 8
    it under the terms of the GNU General Public License as published by
9 9
    the Free Software Foundation, either version 3 of the License, or
10 10
    (at your option) any later version.
11
-
11
+   
12 12
    This program is distributed in the hope that it will be useful,
13 13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 15
    GNU General Public License for more details.
16
-
16
+   
17 17
    You should have received a copy of the GNU General Public License
18 18
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 19
 
@@ -26,13 +26,13 @@
26 26
    special exception, which will cause the skeleton and the resulting
27 27
    Bison output files to be licensed under the GNU General Public
28 28
    License without this special exception.
29
-
29
+   
30 30
    This special exception was added by the Free Software Foundation in
31 31
    version 2.2 of Bison.  */
32 32
 
33 33
 #ifndef YY_YY_PARSER_TAB_H_INCLUDED
34 34
 # define YY_YY_PARSER_TAB_H_INCLUDED
35
-/* Debug traces.  */
35
+/* Enabling traces.  */
36 36
 #ifndef YYDEBUG
37 37
 # define YYDEBUG 1
38 38
 #endif
@@ -40,94 +40,106 @@
40 40
 extern int yydebug;
41 41
 #endif
42 42
 
43
-/* Token type.  */
43
+/* Tokens.  */
44 44
 #ifndef YYTOKENTYPE
45 45
 # define YYTOKENTYPE
46
-  enum yytokentype
47
-  {
48
-    IF = 258,
49
-    THEN = 259,
50
-    ELSE = 260,
51
-    WHILE = 261,
52
-    FOR = 262,
53
-    IN = 263,
54
-    DO = 264,
55
-    FUNC = 265,
56
-    RETURN = 266,
57
-    BREAK = 267,
58
-    CONTINUE = 268,
59
-    END = 269,
60
-    NONE = 270,
61
-    IDENT = 271,
62
-    INT = 272,
63
-    FLOAT = 273,
64
-    STRING = 274,
65
-    PLUS = 275,
66
-    MINUS = 276,
67
-    STAR = 277,
68
-    SLASH = 278,
69
-    PERCENT = 279,
70
-    DSTAR = 280,
71
-    BAND = 281,
72
-    BOR = 282,
73
-    BXOR = 283,
74
-    BNOT = 284,
75
-    LAND = 285,
76
-    LOR = 286,
77
-    LNOT = 287,
78
-    ASSIGN = 288,
79
-    ASSIGNPLUS = 289,
80
-    ASSIGNMINUS = 290,
81
-    ASSIGNSTAR = 291,
82
-    ASSIGNSLASH = 292,
83
-    ASSIGNDSTAR = 293,
84
-    ASSIGNBAND = 294,
85
-    ASSIGNBOR = 295,
86
-    ASSIGNBXOR = 296,
87
-    EQUAL = 297,
88
-    LESS = 298,
89
-    GREATER = 299,
90
-    LESSEQ = 300,
91
-    GREATEREQ = 301,
92
-    RSHIFT = 302,
93
-    LSHIFT = 303,
94
-    LBRACE = 304,
95
-    RBRACE = 305,
96
-    LPAREN = 306,
97
-    RPAREN = 307,
98
-    LBRACKET = 308,
99
-    RBRACKET = 309,
100
-    DOT = 310,
101
-    COLON = 311,
102
-    SEMICOLON = 312,
103
-    COMMA = 313,
104
-    POUND = 314
105
-  };
46
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
47
+      know about them.  */
48
+   enum yytokentype {
49
+     IF = 258,
50
+     THEN = 259,
51
+     ELSE = 260,
52
+     WHILE = 261,
53
+     FOR = 262,
54
+     IN = 263,
55
+     DO = 264,
56
+     FUNC = 265,
57
+     RETURN = 266,
58
+     BREAK = 267,
59
+     CONTINUE = 268,
60
+     END = 269,
61
+     NONE = 270,
62
+     IDENT = 271,
63
+     INT = 272,
64
+     FLOAT = 273,
65
+     STRING = 274,
66
+     PLUS = 275,
67
+     MINUS = 276,
68
+     STAR = 277,
69
+     SLASH = 278,
70
+     PERCENT = 279,
71
+     DSTAR = 280,
72
+     BAND = 281,
73
+     BOR = 282,
74
+     BXOR = 283,
75
+     BNOT = 284,
76
+     LAND = 285,
77
+     LOR = 286,
78
+     LNOT = 287,
79
+     ASSIGN = 288,
80
+     ASSIGNPLUS = 289,
81
+     ASSIGNMINUS = 290,
82
+     ASSIGNSTAR = 291,
83
+     ASSIGNSLASH = 292,
84
+     ASSIGNDSTAR = 293,
85
+     ASSIGNBAND = 294,
86
+     ASSIGNBOR = 295,
87
+     ASSIGNBXOR = 296,
88
+     EQUAL = 297,
89
+     LESS = 298,
90
+     GREATER = 299,
91
+     LESSEQ = 300,
92
+     GREATEREQ = 301,
93
+     RSHIFT = 302,
94
+     LSHIFT = 303,
95
+     LBRACE = 304,
96
+     RBRACE = 305,
97
+     LPAREN = 306,
98
+     RPAREN = 307,
99
+     LBRACKET = 308,
100
+     RBRACKET = 309,
101
+     DOT = 310,
102
+     COLON = 311,
103
+     SEMICOLON = 312,
104
+     COMMA = 313,
105
+     POUND = 314
106
+   };
106 107
 #endif
107 108
 
108
-/* Value type.  */
109
+
109 110
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
110 111
 typedef int YYSTYPE;
111 112
 # define YYSTYPE_IS_TRIVIAL 1
113
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
112 114
 # define YYSTYPE_IS_DECLARED 1
113 115
 #endif
114 116
 
115
-/* Location type.  */
116 117
 #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
117
-typedef struct YYLTYPE YYLTYPE;
118
-struct YYLTYPE
118
+typedef struct YYLTYPE
119 119
 {
120 120
   int first_line;
121 121
   int first_column;
122 122
   int last_line;
123 123
   int last_column;
124
-};
124
+} YYLTYPE;
125
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
125 126
 # define YYLTYPE_IS_DECLARED 1
126 127
 # define YYLTYPE_IS_TRIVIAL 1
127 128
 #endif
128 129
 
129 130
 
130
-
131
+#ifdef YYPARSE_PARAM
132
+#if defined __STDC__ || defined __cplusplus
133
+int yyparse (void *YYPARSE_PARAM);
134
+#else
135
+int yyparse ();
136
+#endif
137
+#else /* ! YYPARSE_PARAM */
138
+#if defined __STDC__ || defined __cplusplus
131 139
 int yyparse (stmt_node **program);
140
+#else
141
+int yyparse ();
142
+#endif
143
+#endif /* ! YYPARSE_PARAM */
132 144
 
133 145
 #endif /* !YY_YY_PARSER_TAB_H_INCLUDED  */

+ 9
- 9
parser.y View File

@@ -55,15 +55,15 @@ stmt_list:
55 55
 ;
56 56
 
57 57
 stmt:
58
-  expr { $$ = NEW_ST(); AS_ST($$)->type = ST_EXPR; AS_ST($$)->expr = $1; }
59
-| IF expr THEN stmt_list END { $$ = NEW_ST(); AS_ST($$)->type = ST_IFELSE; AS_ST($$)->ifelse = NEW(ifelse_node); AS_ST($$)->ifelse->cond = $2; AS_ST($$)->ifelse->iftrue = $4; AS_ST($$)->ifelse->iffalse = NULL; }
60
-| IF expr THEN stmt_list ELSE stmt_list END { $$ = NEW_ST(); AS_ST($$)->type = ST_IFELSE; AS_ST($$)->ifelse = NEW(ifelse_node); AS_ST($$)->ifelse->cond = $2; AS_ST($$)->ifelse->iftrue = $4; AS_ST($$)->ifelse->iffalse = $6; }
61
-| WHILE expr DO stmt_list END { $$ = NEW_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(); 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
-| RETURN expr { $$ = NEW_ST(); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = $2; }
64
-| RETURN { $$ = NEW_ST(); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = NULL; }
65
-| BREAK { $$ = NEW_ST(); AS_ST($$)->type = ST_BREAK; }
66
-| CONTINUE { $$ = NEW_ST(); AS_ST($$)->type = ST_CONT; }
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
+| 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
+| 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; }
67 67
 | stmt SEMICOLON { $$ = $1; }
68 68
 ;
69 69
 

+ 30
- 6
runtime.c View File

@@ -450,6 +450,9 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
450 450
     switch(stmt->type) {
451 451
         case ST_EXPR:
452 452
             sol_obj_free(sol_eval(state, stmt->expr));
453
+			if(sol_has_error(state)) {
454
+				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
455
+			}
453 456
             break;
454 457
 
455 458
         case ST_IFELSE:
@@ -462,6 +465,9 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
462 465
             }
463 466
             sol_obj_free(value);
464 467
             sol_obj_free(vint);
468
+			if(sol_has_error(state)) {
469
+				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
470
+			}
465 471
             break;
466 472
 
467 473
         case ST_LOOP:
@@ -471,11 +477,19 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
471 477
                 sol_obj_free(value);
472 478
                 sol_obj_free(vint);
473 479
                 sol_exec(state, stmt->loop->loop);
474
-                if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) break;
480
+                if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
481
+					value = sol_incref(state->None);
482
+					vint = sol_new_int(state, 0);
483
+					continue;
484
+				}
485
+				state->sflag = SF_NORMAL;
475 486
                 value = sol_eval(state, stmt->loop->cond);
476 487
                 vint = sol_cast_int(state, value);
477 488
             }
478 489
             state->sflag = SF_NORMAL;
490
+			if(sol_has_error(state)) {
491
+				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
492
+			}
479 493
 			sol_obj_free(value);
480 494
 			sol_obj_free(vint);
481 495
             break;
@@ -503,13 +517,20 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
503 517
                 sol_state_assign_l_name(state, stmt->iter->var, item);
504 518
                 sol_exec(state, stmt->iter->loop);
505 519
 				sol_obj_free(item);
506
-                if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) break;
520
+                if(state->ret || state->sflag == SF_BREAKING || sol_has_error(state)) {
521
+					item = sol_incref(state->StopIteration);
522
+				}
523
+				state->sflag = SF_NORMAL;
507 524
                 item = iter->ops->call(state, list);
508 525
             }
509 526
             state->sflag = SF_NORMAL;
510
-			sol_obj_free(list);
527
+			if(sol_has_error(state)) {
528
+				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
529
+			}
511 530
 			sol_obj_free(iter);
512 531
 			sol_obj_free(value);
532
+			sol_obj_free(list);
533
+			sol_obj_free(item);
513 534
             break;
514 535
 
515 536
         case ST_LIST:
@@ -518,6 +539,9 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
518 539
                 if(curs->stmt) sol_exec(state, curs->stmt);
519 540
                 curs = curs->next;
520 541
             }
542
+            if(sol_has_error(state)) {
543
+				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
544
+			}
521 545
             break;
522 546
 
523 547
         case ST_RET:
@@ -526,6 +550,9 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
526 550
             } else {
527 551
                 state->ret = sol_incref(state->None);
528 552
             }
553
+            if(sol_has_error(state)) {
554
+				sol_add_traceback(state, sol_new_stmtnode(state, stmt));
555
+			}
529 556
             break;
530 557
 
531 558
         case ST_CONT:
@@ -594,7 +621,6 @@ sol_object_t *sol_f_func_call(sol_state_t *state, sol_object_t *args) {
594 621
 
595 622
 sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_node *body, char *name) {
596 623
     sol_object_t *obj = sol_alloc_object(state);
597
-    if(sol_has_error(state)) return sol_incref(state->None);
598 624
     obj->func = body;
599 625
     obj->args = identlist;
600 626
 	obj->fname = (name?strdup(name):NULL);
@@ -607,7 +633,6 @@ sol_object_t *sol_new_func(sol_state_t *state, identlist_node *identlist, stmt_n
607 633
 
608 634
 sol_object_t *sol_new_stmtnode(sol_state_t *state, stmt_node *stmt) {
609 635
 	sol_object_t *obj = sol_alloc_object(state);
610
-	if(sol_has_error(state)) return sol_incref(state->None);
611 636
 	obj->type = SOL_STMT;
612 637
 	obj->ops = &(state->ASTNodeOps);
613 638
 	obj->node = stmt;
@@ -616,7 +641,6 @@ sol_object_t *sol_new_stmtnode(sol_state_t *state, stmt_node *stmt) {
616 641
 
617 642
 sol_object_t *sol_new_exprnode(sol_state_t *state, expr_node *expr) {
618 643
 	sol_object_t *obj = sol_alloc_object(state);
619
-	if(sol_has_error(state)) return sol_incref(state->None);
620 644
 	obj->type = SOL_EXPR;
621 645
 	obj->ops = &(state->ASTNodeOps);
622 646
 	obj->node = expr;

+ 45
- 9
sol.h View File

@@ -6,6 +6,7 @@
6 6
 #endif
7 7
 
8 8
 #include <stdio.h>
9
+#include <stdarg.h>
9 10
 #include "dsl/dsl.h"
10 11
 
11 12
 #define VERSION "0.1a0"
@@ -156,6 +157,7 @@ typedef enum {SF_NORMAL, SF_BREAKING, SF_CONTINUING} sol_state_flag_t;
156 157
 typedef struct sol_tag_state_t {
157 158
 	sol_object_t *scopes; // A list of scope maps, innermost out, ending at the global scope
158 159
 	sol_object_t *ret; // Return value of this function, for early return
160
+	sol_object_t *traceback; // The last stack of statement (nodes) in the last error, or NULL
159 161
 	sol_state_flag_t sflag; // Used to implement break/continue
160 162
 	sol_object_t *error; // Some arbitrary error descriptor, None if no error
161 163
 	sol_object_t *None;
@@ -179,6 +181,9 @@ typedef struct sol_tag_state_t {
179 181
 	sol_object_t *modules;
180 182
 	sol_object_t *methods;
181 183
 	dsl_object_funcs obfuncs;
184
+#ifdef DEBUG_GC
185
+	dsl_seq *objects;
186
+#endif
182 187
 } sol_state_t;
183 188
 
184 189
 // state.c
@@ -201,6 +206,10 @@ sol_object_t *sol_set_error(sol_state_t *, sol_object_t *);
201 206
 sol_object_t *sol_set_error_string(sol_state_t *, const char *);
202 207
 void sol_clear_error(sol_state_t *);
203 208
 
209
+void sol_init_traceback(sol_state_t *);
210
+void sol_add_traceback(sol_state_t *, sol_object_t *);
211
+sol_object_t *sol_traceback(sol_state_t *);
212
+
204 213
 void sol_register_module(sol_state_t *, sol_object_t *, sol_object_t *);
205 214
 void sol_register_module_name(sol_state_t *, char *, sol_object_t *);
206 215
 sol_object_t *sol_get_module(sol_state_t *, sol_object_t *);
@@ -239,6 +248,8 @@ sol_object_t *sol_f_exec(sol_state_t *, sol_object_t *);
239 248
 sol_object_t *sol_f_eval(sol_state_t *, sol_object_t *);
240 249
 sol_object_t *sol_f_execfile(sol_state_t *, sol_object_t *);
241 250
 sol_object_t *sol_f_parse(sol_state_t *, sol_object_t *);
251
+sol_object_t *sol_f_ord(sol_state_t *, sol_object_t *);
252
+sol_object_t *sol_f_chr(sol_state_t *, sol_object_t *);
242 253
 
243 254
 sol_object_t *sol_f_debug_getref(sol_state_t *, sol_object_t *);
244 255
 sol_object_t *sol_f_debug_setref(sol_state_t *, sol_object_t *);
@@ -251,6 +262,8 @@ sol_object_t *sol_f_iter_str(sol_state_t *, sol_object_t *);
251 262
 sol_object_t *sol_f_iter_list(sol_state_t *, sol_object_t *);
252 263
 sol_object_t *sol_f_iter_map(sol_state_t *, sol_object_t *);
253 264
 
265
+sol_object_t *sol_f_ast_print(sol_state_t *, sol_object_t *);
266
+
254 267
 sol_object_t *sol_f_singlet_tostring(sol_state_t *, sol_object_t *);
255 268
 
256 269
 sol_object_t *sol_f_int_add(sol_state_t *, sol_object_t *);
@@ -293,6 +306,7 @@ sol_object_t *sol_f_str_repr(sol_state_t *, sol_object_t *);
293 306
 
294 307
 sol_object_t *sol_f_str_sub(sol_state_t *, sol_object_t *);
295 308
 sol_object_t *sol_f_str_split(sol_state_t *, sol_object_t *);
309
+sol_object_t *sol_f_str_find(sol_state_t *, sol_object_t *);
296 310
 
297 311
 sol_object_t *sol_f_list_add(sol_state_t *, sol_object_t *);
298 312
 sol_object_t *sol_f_list_mul(sol_state_t *, sol_object_t *);
@@ -316,6 +330,7 @@ sol_object_t *sol_f_map_call(sol_state_t *, sol_object_t *);
316 330
 sol_object_t *sol_f_map_len(sol_state_t *, sol_object_t *);
317 331
 sol_object_t *sol_f_map_iter(sol_state_t *, sol_object_t *);
318 332
 sol_object_t *sol_f_map_tostring(sol_state_t *, sol_object_t *);
333
+sol_object_t *sol_f_map_repr(sol_state_t *, sol_object_t *);
319 334
 
320 335
 sol_object_t *sol_f_mcell_tostring(sol_state_t *, sol_object_t *);
321 336
 
@@ -368,18 +383,12 @@ sol_object_t *sol_f_stream_read(sol_state_t *, sol_object_t *);
368 383
 sol_object_t *sol_f_stream_seek(sol_state_t *, sol_object_t *);
369 384
 sol_object_t *sol_f_stream_tell(sol_state_t *, sol_object_t *);
370 385
 sol_object_t *sol_f_stream_flush(sol_state_t *, sol_object_t *);
386
+sol_object_t *sol_f_stream_eof(sol_state_t *, sol_object_t *);
371 387
 
372 388
 sol_object_t *sol_f_stream_open(sol_state_t *, sol_object_t *);
373 389
 
374 390
 // object.c
375 391
 
376
-#define sol_incref(obj) (++((obj)->refcnt), obj)
377
-#define sol_decref(obj) (--((obj)->refcnt))
378
-
379
-sol_object_t *sol_obj_acquire(sol_object_t *);
380
-void sol_obj_free(sol_object_t *);
381
-void sol_obj_release(sol_object_t *);
382
-
383 392
 #define sol_is_singlet(obj) ((obj)->type == SOL_SINGLET)
384 393
 #define sol_is_none(state, obj) ((obj) == state->None)
385 394
 #define sol_is_oom(state, obj) ((obj) == state->OutOfMemory)
@@ -398,8 +407,6 @@ void sol_obj_release(sol_object_t *);
398 407
 
399 408
 #define sol_has_error(state) (!sol_is_none((state), (state)->error))
400 409
 
401
-sol_object_t *sol_alloc_object(sol_state_t *);
402
-
403 410
 sol_object_t *sol_new_singlet(sol_state_t *, const char *);
404 411
 sol_object_t *sol_new_int(sol_state_t *, long);
405 412
 sol_object_t *sol_new_float(sol_state_t *, double);
@@ -454,14 +461,18 @@ sol_object_t *sol_new_dysym(sol_state_t *, void *, dsl_seq *, sol_buftype_t);
454 461
 
455 462
 sol_object_t *sol_new_stream(sol_state_t *, FILE *, sol_modes_t);
456 463
 size_t sol_stream_printf(sol_state_t *, sol_object_t *, const char *, ...);
464
+size_t sol_stream_vprintf(sol_state_t *, sol_object_t *, const char *, va_list);
457 465
 size_t sol_stream_scanf(sol_state_t *, sol_object_t *, const char *, ...);
458 466
 size_t sol_stream_fread(sol_state_t *, sol_object_t *, char *, size_t, size_t);
459 467
 size_t sol_stream_fwrite(sol_state_t *, sol_object_t *, char *, size_t, size_t);
460 468
 char *sol_stream_fgets(sol_state_t *, sol_object_t *, char *, size_t);
469
+int sol_stream_fputc(sol_state_t *, sol_object_t *, int);
461 470
 #define sol_printf(state, ...) sol_stream_printf(state, sol_get_stdout(state), __VA_ARGS__)
471
+#define sol_vprintf(state, ...) sol_stream_vprintf(state, sol_get_stdout(state), __VA_ARGS__)
462 472
 #define sol_scanf(state, ...) sol_stream_scanf(state, sol_get_stdin(state, __VA_ARGS__)
463 473
 #define sol_fread(state, ...) sol_stream_fread(state, sol_get_stdin(state), __VA_ARGS__)
464 474
 #define sol_fwrite(state, ...) sol_stream_fwrite(state, sol_get_stdout(state), __VA_ARGS__)
475
+#define sol_putchar(state, ...) sol_stream_fputc(state, sol_get_stdout(state), __VA_ARGS__)
465 476
 int sol_stream_feof(sol_state_t *, sol_object_t *);
466 477
 int sol_stream_ferror(sol_state_t *, sol_object_t *);
467 478
 #define sol_stream_ready(state, stream) (!(sol_stream_feof((state), (stream)) || sol_stream_ferror((state), (stream))))
@@ -489,6 +500,31 @@ int sol_validate_map(sol_state_t *, sol_object_t *);
489 500
 
490 501
 sol_object_t *sol_util_call(sol_state_t *, sol_object_t *, int *, int, ...);
491 502
 
503
+// gc.c
504
+
505
+#ifdef DEBUG_GC
506
+
507
+sol_object_t *_int_sol_incref(const char *, sol_object_t *);
508
+void _int_sol_obj_free(const char *, sol_object_t *);
509
+#define sol_incref(obj) (_int_sol_incref(__func__, (obj)))
510
+#define sol_obj_free(obj) (_int_sol_obj_free(__func__, (obj)))
511
+
512
+#else
513
+
514
+#define sol_incref(obj) (++((obj)->refcnt), obj)
515
+void sol_obj_free(sol_object_t *);
516
+
517
+#endif
518
+
519
+#define sol_decref(obj) (--((obj)->refcnt))
520
+
521
+sol_object_t *sol_obj_acquire(sol_object_t *);
522
+void sol_obj_release(sol_object_t *);
523
+
524
+sol_object_t *sol_alloc_object(sol_state_t *);
525
+
526
+void sol_mm_finalize(sol_state_t *);
527
+
492 528
 #define AS_OBJ(x) ((sol_object_t *) (x))
493 529
 
494 530
 #endif

+ 2
- 2
solrun.c View File

@@ -41,10 +41,10 @@ int main(int argc, char **argv) {
41 41
 	
42 42
 	if(prgstream!=stdin) fclose(prgstream);
43 43
 
44
-    if(printtree) st_print(program);
44
+	sol_state_init(&state);
45
+    if(printtree) st_print(&state, program);
45 46
 
46 47
     if(program) {
47
-        sol_state_init(&state);
48 48
         sol_exec(&state, program);
49 49
 		if(sol_has_error(&state)) {
50 50
 			printf("Error: ");

+ 32
- 1
state.c View File

@@ -10,6 +10,7 @@ int sol_state_init(sol_state_t *state) {
10 10
 	state->OutOfMemory = NULL;
11 11
 	state->scopes = NULL;
12 12
 	state->error = NULL;
13
+	state->traceback = NULL;
13 14
 	state->ret = NULL;
14 15
 	state->sflag = SF_NORMAL;
15 16
 
@@ -102,6 +103,7 @@ int sol_state_init(sol_state_t *state) {
102 103
 	state->MapOps.len = sol_f_map_len;
103 104
 	state->MapOps.iter = sol_f_map_iter;
104 105
 	state->MapOps.tostring = sol_f_map_tostring;
106
+	state->MapOps.repr = sol_f_map_repr;
105 107
 	state->MapOps.free = sol_f_map_free;
106 108
 	
107 109
 	state->MCellOps.tname = "mcell";
@@ -178,6 +180,8 @@ int sol_state_init(sol_state_t *state) {
178 180
 	sol_map_set_name(state, globals, "eval", sol_new_cfunc(state, sol_f_eval));
179 181
 	sol_map_set_name(state, globals, "execfile", sol_new_cfunc(state, sol_f_execfile));
180 182
 	sol_map_set_name(state, globals, "parse", sol_new_cfunc(state, sol_f_parse));
183
+	sol_map_set_name(state, globals, "ord", sol_new_cfunc(state, sol_f_ord));
184
+	sol_map_set_name(state, globals, "chr", sol_new_cfunc(state, sol_f_chr));
181 185
 	
182 186
 	mod = sol_new_map(state);
183 187
 	sol_map_set_name(state, mod, "getref", sol_new_cfunc(state, sol_f_debug_getref));
@@ -240,7 +244,12 @@ int sol_state_init(sol_state_t *state) {
240 244
 	sol_map_set_name(state, mod, "OP_BNOT", sol_new_int(state, OP_BNOT));
241 245
 	sol_map_set_name(state, mod, "OP_LNOT", sol_new_int(state, OP_LNOT));
242 246
 	sol_map_set_name(state, mod, "OP_LEN", sol_new_int(state, OP_LEN));
247
+	sol_map_set_name(state, mod, "LIT_INT", sol_new_int(state, LIT_INT));
248
+	sol_map_set_name(state, mod, "LIT_FLOAT", sol_new_int(state, LIT_FLOAT));
249
+	sol_map_set_name(state, mod, "LIT_STRING", sol_new_int(state, LIT_STRING));
250
+	sol_map_set_name(state, mod, "LIT_NONE", sol_new_int(state, LIT_NONE));
243 251
 	sol_map_invert(state, mod);
252
+	sol_map_set_name(state, mod, "print", sol_new_cfunc(state, sol_f_ast_print));
244 253
 	sol_register_module_name(state, "ast", mod);
245 254
 	
246 255
 	btype = sol_new_map(state);
@@ -360,12 +369,14 @@ int sol_state_init(sol_state_t *state) {
360 369
 	sol_map_set_name(state, meths, "seek", sol_new_cfunc(state, sol_f_stream_seek));
361 370
 	sol_map_set_name(state, meths, "tell", sol_new_cfunc(state, sol_f_stream_tell));
362 371
 	sol_map_set_name(state, meths, "flush", sol_new_cfunc(state, sol_f_stream_flush));
372
+	sol_map_set_name(state, meths, "eof", sol_new_cfunc(state, sol_f_stream_eof));
363 373
 	sol_register_methods_name(state, "stream", meths);
364 374
 	sol_obj_free(meths);
365 375
 	
366 376
 	meths = sol_new_map(state);
367 377
 	sol_map_set_name(state, meths, "sub", sol_new_cfunc(state, sol_f_str_sub));
368 378
 	sol_map_set_name(state, meths, "split", sol_new_cfunc(state, sol_f_str_split));
379
+	sol_map_set_name(state, meths, "find", sol_new_cfunc(state, sol_f_str_find));
369 380
 	sol_register_methods_name(state, "string", meths);
370 381
 	sol_obj_free(meths);
371 382