Tobias Waldekranz.com 8 years ago
parent
commit
0b66885440
5 changed files with 130 additions and 42 deletions
  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
 	const char *name;
9
 	const char *name;
10
 	struct type *type;
10
 	struct type *type;
11
 
11
 
12
+	int static_ret:1; 	/* return type is statically known */
13
+
12
 	int (*static_validate)(const struct func *, struct node *);
14
 	int (*static_validate)(const struct func *, struct node *);
13
 	int (*type_infer)(const struct func *, struct node *);
15
 	int (*type_infer)(const struct func *, struct node *);
14
 };
16
 };

+ 83 - 22
global.c

1
 #define _GNU_SOURCE 		/* asprintf */
1
 #define _GNU_SOURCE 		/* asprintf */
2
 #include <assert.h>
2
 #include <assert.h>
3
 #include <errno.h>
3
 #include <errno.h>
4
+#include <limits.h>
4
 #include <stdlib.h>
5
 #include <stdlib.h>
5
 #include <string.h>
6
 #include <string.h>
6
 
7
 
64
 static int global_map_static_validate(const struct func *func, struct node *n)
65
 static int global_map_static_validate(const struct func *func, struct node *n)
65
 {
66
 {
66
 	if (n->expr.args->ntype != N_IDENT) {
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
 		return -EINVAL;
70
 		return -EINVAL;
69
 	}
71
 	}
70
 
72
 
121
 static int global_assign_static_validate(const struct func *func, struct node *n)
123
 static int global_assign_static_validate(const struct func *func, struct node *n)
122
 {
124
 {
123
 	struct node *lval;
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
 	lval = n->expr.args;
127
 	lval = n->expr.args;
132
 
128
 
133
 	if (node_is_map(lval) || (lval->ntype == N_IDENT))
129
 	if (node_is_map(lval) || (lval->ntype == N_IDENT))
134
 		return 0;
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
 	return -EINVAL;
133
 	return -EINVAL;
138
 }
134
 }
139
 
135
 
173
 	.func = { .type = &t_void, .vargs = 1 },
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
 	{ .type = &t_void },
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
 	{ .type = &t_void },
186
 	{ .type = &t_void },
179
 
187
 
180
 	{ .type = NULL }
188
 	{ .type = NULL }
181
 };
189
 };
182
 
190
 
183
-struct type t_assign_func = {
191
+struct type t_1arg_func = {
184
 	.ttype = T_FUNC,
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
 static const struct func global_funcs[] = {
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
 		.type_infer = global_assign_type_infer,
216
 		.type_infer = global_assign_type_infer,
199
 		.static_validate = global_assign_static_validate,
217
 		.static_validate = global_assign_static_validate,
200
 	},
218
 	},
201
 	{
219
 	{
202
-		.name = ":map",
220
+		.name = "{}",
203
 		/* .type = t_map_func, */
221
 		/* .type = t_map_func, */
204
 		.type_infer = global_map_type_infer,
222
 		.type_infer = global_map_type_infer,
205
 		.static_validate = global_map_static_validate,
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
 	{ .name = NULL }
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
 static const struct func global_num_func = {
273
 static const struct func global_num_func = {
217
 	.name = ":num",
274
 	.name = ":num",
218
-	.type = &t_int,
219
 };
275
 };
220
 
276
 
221
 struct type t_string_array = {
277
 struct type t_string_array = {
233
 static const struct func global_string_func = {
289
 static const struct func global_string_func = {
234
 	.name = ":string",
290
 	.name = ":string",
235
 	.type = &t_string,
291
 	.type = &t_string,
292
+	.static_ret = 1,
236
 };
293
 };
237
 
294
 
238
 static const struct func global_ident_func = {
295
 static const struct func global_ident_func = {
284
 		return err;
341
 		return err;
285
 
342
 
286
 	n->sym = sym_alloc(st, n, func);
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
 	return 0;
349
 	return 0;
289
 }
350
 }
290
 
351
 

+ 22 - 5
node.c

1
 #include <assert.h>
1
 #include <assert.h>
2
 #include <ctype.h>
2
 #include <ctype.h>
3
+#include <errno.h>
3
 #include <inttypes.h>
4
 #include <inttypes.h>
4
 #include <search.h>
5
 #include <search.h>
5
 #include <stdarg.h>
6
 #include <stdarg.h>
20
 		fputs(n->ident.name, fp);
21
 		fputs(n->ident.name, fp);
21
 		break;
22
 		break;
22
 	case N_NUM:
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
 		break;
28
 		break;
25
 	case N_STRING:
29
 	case N_STRING:
26
 		fprintf(fp, "\"%s\"", n->string.data);
30
 		fprintf(fp, "\"%s\"", n->string.data);
101
 	if (!n || (n->ntype != N_EXPR))
105
 	if (!n || (n->ntype != N_EXPR))
102
 		return 0;
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
 	return n;
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
 	struct node *n = node_new(N_NUM);
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
 struct node *node_ident(char *name)
154
 struct node *node_ident(char *name)

+ 6 - 2
node.h

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

+ 17 - 13
ply.c

71
 
71
 
72
 	/* { 
72
 	/* { 
73
 	 * 	us = pid();
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
 	prog->ast =
78
 	prog->ast =
79
 		node_expr(":block",
79
 		node_expr(":block",
80
-			  node_expr(":assign",
80
+			  node_expr("=",
81
 				    node_ident("us"),
81
 				    node_ident("us"),
82
-				    node_expr("pid", NULL), node_num(0),
82
+				    node_expr("pid", NULL),
83
 				    NULL),
83
 				    NULL),
84
-			  node_expr(":assign",
85
-				    node_expr(":map",
84
+			  node_expr("=",
85
+				    node_expr("{}",
86
 					      node_ident("t"),
86
 					      node_ident("t"),
87
-					      node_num(0),
87
+					      node_num("0"),
88
 					      node_expr("pid", NULL),
88
 					      node_expr("pid", NULL),
89
 					      NULL),
89
 					      NULL),
90
 				    node_expr("time", NULL),
90
 				    node_expr("time", NULL),
91
 				    NULL),
91
 				    NULL),
92
-			  node_expr(":assign",
93
-				    node_expr(":map",
92
+			  node_expr("=",
93
+				    node_expr("{}",
94
 					      node_ident("reads"),
94
 					      node_ident("reads"),
95
 					      node_expr("pid", NULL),
95
 					      node_expr("pid", NULL),
96
 					      NULL),
96
 					      NULL),
110
 
110
 
111
 	/* TODO: k -> kret */
111
 	/* TODO: k -> kret */
112
 	prog->probe = "k:SyS_read2"; 
112
 	prog->probe = "k:SyS_read2"; 
113
-	/* { @times[pid()] = quantize(time() - t0) } */
113
+	/* { times[pid()] = quantize(time() - t[0, pid()]) } */
114
 	prog->ast =
114
 	prog->ast =
115
-		node_expr(":assign",
116
-			  node_expr(":map",
115
+		node_expr("=",
116
+			  node_expr("{}",
117
 				    node_ident("times"),
117
 				    node_ident("times"),
118
 				    node_expr("pid", NULL),
118
 				    node_expr("pid", NULL),
119
 				    NULL),
119
 				    NULL),
120
 			  node_expr("quantize",
120
 			  node_expr("quantize",
121
 				    node_expr("-",
121
 				    node_expr("-",
122
 					      node_expr("time", NULL),
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
 					      NULL),
128
 					      NULL),
125
 				    NULL),
129
 				    NULL),
126
 			  NULL);
130
 			  NULL);