Tobias Waldekranz.com 8 jaren geleden
bovenliggende
commit
0b66885440
5 gewijzigde bestanden met toevoegingen van 130 en 42 verwijderingen
  1. 2 0
      func.h
  2. 83 22
      global.c
  3. 22 5
      node.c
  4. 6 2
      node.h
  5. 17 13
      ply.c

+ 2 - 0
func.h

@@ -9,6 +9,8 @@ struct func {
9 9
 	const char *name;
10 10
 	struct type *type;
11 11
 
12
+	int static_ret:1; 	/* return type is statically known */
13
+
12 14
 	int (*static_validate)(const struct func *, struct node *);
13 15
 	int (*type_infer)(const struct func *, struct node *);
14 16
 };

+ 83 - 22
global.c

@@ -1,6 +1,7 @@
1 1
 #define _GNU_SOURCE 		/* asprintf */
2 2
 #include <assert.h>
3 3
 #include <errno.h>
4
+#include <limits.h>
4 5
 #include <stdlib.h>
5 6
 #include <string.h>
6 7
 
@@ -64,7 +65,8 @@ static int global_map_type_infer(const struct func *func, struct node *n)
64 65
 static int global_map_static_validate(const struct func *func, struct node *n)
65 66
 {
66 67
 	if (n->expr.args->ntype != N_IDENT) {
67
-		_e("%#N: %N is not subscriptable.\n", n, n);
68
+		_e("%#N: trying to lookup a key in %N, which is not a map.\n",
69
+		   n, n);
68 70
 		return -EINVAL;
69 71
 	}
70 72
 
@@ -121,19 +123,13 @@ static int global_assign_type_infer(const struct func *func, struct node *n)
121 123
 static int global_assign_static_validate(const struct func *func, struct node *n)
122 124
 {
123 125
 	struct node *lval;
124
-	int nargs = node_nargs(n);
125
-
126
-	if (nargs != 2) {
127
-		_e("%#N: expected 2 arguments, %d given.\n", n, nargs);
128
-		return -EINVAL;
129
-	}
130 126
 
131 127
 	lval = n->expr.args;
132 128
 
133 129
 	if (node_is_map(lval) || (lval->ntype == N_IDENT))
134 130
 		return 0;
135 131
 
136
-	_e("%#N: %N is not assignable.\n", n, lval);
132
+	_e("%#N: can't assign a value to %N.\n", n, lval);
137 133
 	return -EINVAL;
138 134
 }
139 135
 
@@ -173,49 +169,109 @@ struct type t_block_func = {
173 169
 	.func = { .type = &t_void, .vargs = 1 },
174 170
 };
175 171
 
176
-struct tfield f_assign[] = {
172
+struct tfield f_2args[] = {
173
+	{ .type = &t_void },
177 174
 	{ .type = &t_void },
175
+
176
+	{ .type = NULL }
177
+};
178
+
179
+struct type t_2args_func = {
180
+	.ttype = T_FUNC,
181
+
182
+	.func = { .type = &t_void, .args = f_2args },
183
+};
184
+
185
+struct tfield f_1arg[] = {
178 186
 	{ .type = &t_void },
179 187
 
180 188
 	{ .type = NULL }
181 189
 };
182 190
 
183
-struct type t_assign_func = {
191
+struct type t_1arg_func = {
184 192
 	.ttype = T_FUNC,
185 193
 
186
-	.func = { .type = &t_void, .args = f_assign },
194
+	.func = { .type = &t_void, .args = f_1arg },
187 195
 };
188 196
 
189 197
 static const struct func global_funcs[] = {
190
-	{ .name = ":block", .type = &t_block_func, },
198
+	{
199
+		.name = ":block",
200
+		.type = &t_block_func,
201
+		.static_ret = 1,
202
+	},
191 203
 
192
-	{ .name = "+", },
193
-	{ .name = "-", },
204
+	{
205
+		.name = "+",
206
+		.type = &t_2args_func,
207
+	},
208
+	{
209
+		.name = "-",
210
+		.type = &t_2args_func,
211
+	},
194 212
 	
195 213
 	{
196
-		.name = ":assign",
197
-		.type = &t_assign_func,
214
+		.name = "=",
215
+		.type = &t_2args_func,
198 216
 		.type_infer = global_assign_type_infer,
199 217
 		.static_validate = global_assign_static_validate,
200 218
 	},
201 219
 	{
202
-		.name = ":map",
220
+		.name = "{}",
203 221
 		/* .type = t_map_func, */
204 222
 		.type_infer = global_map_type_infer,
205 223
 		.static_validate = global_map_static_validate,
206 224
 	},
207 225
 
208
-	{ .name = "pid",  .type = &t_pid_func, },
209
-	{ .name = "time", .type = &t_time_func, },
226
+	{
227
+		.name = "pid",
228
+		.type = &t_pid_func,
229
+		.static_ret = 1,
230
+	},
231
+	{
232
+		.name = "time",
233
+		.type = &t_time_func,
234
+		.static_ret = 1,
235
+	},
210 236
 
211
-	{ .name = "quantize", },
237
+	{
238
+		.name = "quantize",
239
+		.type = &t_1arg_func,
240
+	},
212 241
 	
213 242
 	{ .name = NULL }
214 243
 };
215 244
 
245
+static struct type *global_num_type(struct node *n)
246
+{
247
+	if (n->num.unsignd) {
248
+		if (n->num.u64 <= INT_MAX)
249
+			return &t_int;
250
+		else if (n->num.u64 <= UINT_MAX)
251
+			return &t_uint;
252
+		else if (n->num.u64 <= LONG_MAX)
253
+			return &t_long;
254
+		else if (n->num.u64 <= ULONG_MAX)
255
+			return &t_ulong;
256
+		else if (n->num.u64 <= LLONG_MAX)
257
+			return &t_llong;
258
+		else if (n->num.u64 <= ULLONG_MAX)
259
+			return &t_ullong;
260
+	} else {
261
+		if (n->num.s64 >= INT_MIN && n->num.s64 <= INT_MAX)
262
+			return &t_int;
263
+		else if (n->num.s64 >= LONG_MIN && n->num.s64 <= LONG_MAX)
264
+			return &t_long;
265
+		else if (n->num.s64 >= LLONG_MIN && n->num.s64 <= LLONG_MAX)
266
+			return &t_llong;
267
+	}
268
+
269
+	assert(0);
270
+	return NULL;
271
+}
272
+
216 273
 static const struct func global_num_func = {
217 274
 	.name = ":num",
218
-	.type = &t_int,
219 275
 };
220 276
 
221 277
 struct type t_string_array = {
@@ -233,6 +289,7 @@ struct type t_string = {
233 289
 static const struct func global_string_func = {
234 290
 	.name = ":string",
235 291
 	.type = &t_string,
292
+	.static_ret = 1,
236 293
 };
237 294
 
238 295
 static const struct func global_ident_func = {
@@ -284,7 +341,11 @@ int global_sym_alloc(struct prog *prog, struct node *n)
284 341
 		return err;
285 342
 
286 343
 	n->sym = sym_alloc(st, n, func);
287
-	n->sym->type = func_return_type(func);
344
+
345
+	if (n->ntype == N_NUM)
346
+		n->sym->type = global_num_type(n);
347
+	else if (func->static_ret)
348
+		n->sym->type = func_return_type(func);
288 349
 	return 0;
289 350
 }
290 351
 

+ 22 - 5
node.c

@@ -1,5 +1,6 @@
1 1
 #include <assert.h>
2 2
 #include <ctype.h>
3
+#include <errno.h>
3 4
 #include <inttypes.h>
4 5
 #include <search.h>
5 6
 #include <stdarg.h>
@@ -20,7 +21,10 @@ void node_print(struct node *n, FILE *fp)
20 21
 		fputs(n->ident.name, fp);
21 22
 		break;
22 23
 	case N_NUM:
23
-		fprintf(fp, "%"PRId64, n->num.num);
24
+		if (n->num.unsignd)
25
+			fprintf(fp, "%"PRIu64, n->num.u64);
26
+		else
27
+			fprintf(fp, "%"PRId64, n->num.s64);
24 28
 		break;
25 29
 	case N_STRING:
26 30
 		fprintf(fp, "\"%s\"", n->string.data);
@@ -101,7 +105,7 @@ int node_is_map(struct node *n)
101 105
 	if (!n || (n->ntype != N_EXPR))
102 106
 		return 0;
103 107
 
104
-	return !strcmp(n->expr.func, ":map");
108
+	return !strcmp(n->expr.func, "{}");
105 109
 }
106 110
 
107 111
 
@@ -126,12 +130,25 @@ struct node *node_string(char *data)
126 130
 	return n;
127 131
 }
128 132
 
129
-struct node *node_num(int64_t num)
133
+struct node *node_num(const char *numstr)
130 134
 {
131 135
 	struct node *n = node_new(N_NUM);
132 136
 
133
-	n->num.num = num;
134
-	return n;
137
+	if (numstr[0] == '-')
138
+		numstr++;
139
+	else
140
+		n->num.unsignd = 1;
141
+		
142
+	errno = 0;
143
+	n->num.u64 = strtoull(numstr, NULL, 0);
144
+	if (!errno) {
145
+		if (!n->num.unsignd)
146
+			n->num.s64 = -n->num.u64;
147
+		return n;
148
+	}
149
+
150
+	assert(0);
151
+	return NULL;
135 152
 }
136 153
 
137 154
 struct node *node_ident(char *name)

+ 6 - 2
node.h

@@ -30,7 +30,11 @@ struct node {
30 30
 			char *name;
31 31
 		} ident;
32 32
 		struct {
33
-			int64_t num;
33
+			union {
34
+				 int64_t s64;
35
+				uint64_t u64;
36
+			};
37
+			int unsignd:1;
34 38
 		} num;
35 39
 		struct {
36 40
 			char *data;
@@ -49,7 +53,7 @@ int node_replace(struct node *n, struct node *new);
49 53
 
50 54
 /* constructors */
51 55
 struct node *node_string(char *data);
52
-struct node *node_num   (int64_t num);
56
+struct node *node_num   (const char *numstr);
53 57
 struct node *node_ident (char *name);
54 58
 struct node *node_append(struct node *n, struct node *arg);
55 59
 struct node *node_expr  (char *func, ...);

+ 17 - 13
ply.c

@@ -71,26 +71,26 @@ struct ctx *ctx_get(void)
71 71
 
72 72
 	/* { 
73 73
 	 * 	us = pid();
74
-	 * 	@t[0] = time();
75
-	 * 	@reads[pid()] = quantize(arg2);
74
+	 * 	t[0, pid()] = time();
75
+	 * 	reads[pid()] = quantize(arg2);
76 76
 	 * }
77 77
 	 */
78 78
 	prog->ast =
79 79
 		node_expr(":block",
80
-			  node_expr(":assign",
80
+			  node_expr("=",
81 81
 				    node_ident("us"),
82
-				    node_expr("pid", NULL), node_num(0),
82
+				    node_expr("pid", NULL),
83 83
 				    NULL),
84
-			  node_expr(":assign",
85
-				    node_expr(":map",
84
+			  node_expr("=",
85
+				    node_expr("{}",
86 86
 					      node_ident("t"),
87
-					      node_num(0),
87
+					      node_num("0"),
88 88
 					      node_expr("pid", NULL),
89 89
 					      NULL),
90 90
 				    node_expr("time", NULL),
91 91
 				    NULL),
92
-			  node_expr(":assign",
93
-				    node_expr(":map",
92
+			  node_expr("=",
93
+				    node_expr("{}",
94 94
 					      node_ident("reads"),
95 95
 					      node_expr("pid", NULL),
96 96
 					      NULL),
@@ -110,17 +110,21 @@ struct ctx *ctx_get(void)
110 110
 
111 111
 	/* TODO: k -> kret */
112 112
 	prog->probe = "k:SyS_read2"; 
113
-	/* { @times[pid()] = quantize(time() - t0) } */
113
+	/* { times[pid()] = quantize(time() - t[0, pid()]) } */
114 114
 	prog->ast =
115
-		node_expr(":assign",
116
-			  node_expr(":map",
115
+		node_expr("=",
116
+			  node_expr("{}",
117 117
 				    node_ident("times"),
118 118
 				    node_expr("pid", NULL),
119 119
 				    NULL),
120 120
 			  node_expr("quantize",
121 121
 				    node_expr("-",
122 122
 					      node_expr("time", NULL),
123
-					      node_ident("t0"),
123
+					      node_expr("{}",
124
+							node_ident("t"),
125
+							node_num("0"),
126
+							node_expr("pid", NULL),
127
+							NULL),
124 128
 					      NULL),
125 129
 				    NULL),
126 130
 			  NULL);