Tobias Waldekranz.com il y a 8 ans
Parent
commit
a4e6828dfc
7 fichiers modifiés avec 214 ajouts et 50 suppressions
  1. 50 17
      func.c
  2. 5 3
      func.h
  3. 44 26
      global.c
  4. 2 2
      ply.c
  5. 6 2
      type.c
  6. 17 0
      type.h
  7. 90 0
      utils.c

+ 50 - 17
func.c

@@ -6,30 +6,49 @@
6 6
 #include "sym.h"
7 7
 #include "type.h"
8 8
 
9
-int func_validate_expr(const struct func *func, struct node *n, int strict)
9
+static int func_validate_expr(const struct func *func, struct node *n, int strict)
10 10
 {
11 11
 	struct tfield *f;
12 12
 	struct node *arg;
13
-	int nargs = 0;
13
+	int fargs, nargs = 0;
14 14
 
15 15
 	for (f = func->type->func.args, arg = n->expr.args;
16
-	     f && arg; f++, arg = arg->next, nargs++) {
17
-		if ((!strict && (arg->sym->type->ttype == T_VOID))
18
-		    || (f->type->ttype == T_VOID)
19
-		    || type_compatible(arg->sym->type, f->type) )
16
+	     f && f->type && arg; f++, arg = arg->next, nargs++) {
17
+		if ((!strict && (f->type->ttype == T_VOID))
18
+		    || (!strict && !arg->sym->type)
19
+		    || (!strict && (arg->sym->type->ttype == T_VOID))
20
+		    || type_compatible(arg->sym->type, f->type))
20 21
 			continue;
21 22
 
22 23
 		_e("%#N: %O argument is of type '%T', expected '%T'.\n",
23 24
 		   n, nargs, arg->sym->type, f->type);
24 25
 	}
25 26
 
26
-	return 0;
27
+	if ((!f || !f->type) && !arg)
28
+		return 0;
29
+
30
+	nargs = node_nargs(n);
31
+	fargs = type_nargs(func->type);
32
+	if (f && f->type) {
33
+		_e("%#N: too few arguments to %N; expected%s %d, got %d.\n",
34
+		   n, n, func->type->func.vargs? " at least" : "", fargs, nargs);
35
+		return -EINVAL;
36
+	}
37
+
38
+	if (func->type->func.vargs)
39
+		return 0;
40
+
41
+	_e("%#N: too many arguments to %N; expected %d, got %d.\n",
42
+	   n, n, fargs, nargs);
43
+	return -EINVAL;
27 44
 }
28 45
 
29 46
 int func_static_validate(const struct func *func, struct node *n)
30 47
 {
31
-	if ((n->ntype == N_NUM) || (n->ntype == N_STRING)) {
32
-	}
48
+	int err = 0;
49
+
50
+	if (!func->type)
51
+		goto check_callback;
33 52
 
34 53
 	switch (n->ntype) {
35 54
 	case N_EXPR:
@@ -37,21 +56,35 @@ int func_static_validate(const struct func *func, struct node *n)
37 56
 			_e("%#N: %N is not callable.\n", n, n);
38 57
 			return -EINVAL;
39 58
 		}
40
-		return func_validate_expr(func, n, 0);
59
+		err = func_validate_expr(func, n, 0);
60
+		break;
41 61
 
42 62
 	case N_IDENT:
43 63
 		if (func->type->ttype == T_FUNC) {
44 64
 			_e("%#N: %N is a function.\n", n, n);
45 65
 			return -EINVAL;
46 66
 		}
47
-		/* fall-through */
48
-	case N_NUM:
49
-	case N_STRING:
50
-		/* ident, num, str. nothing to validate. just copy
51
-		 * type info to the symbol if statically known */
52
-		n->sym->type = func->type;
67
+		break;
68
+
69
+	default:
70
+		/* num, str. nothing to validate. */
53 71
 		break;
54 72
 	}
55 73
 
56
-	return 0;
74
+check_callback:
75
+	if (!err && func->static_validate)
76
+		err = func->static_validate(func, n);
77
+
78
+	return err;
79
+}
80
+
81
+struct type *func_return_type(const struct func *func)
82
+{
83
+	if (!func->type)
84
+		return NULL;
85
+
86
+	if (func->type->ttype == T_FUNC)
87
+		return func->type->func.type;
88
+
89
+	return func->type;
57 90
 }

+ 5 - 3
func.h

@@ -9,9 +9,11 @@ struct func {
9 9
 	const char *name;
10 10
 	struct type *type;
11 11
 
12
-	int (*static_verify)(struct node *);
13
-	
14
-	int (*type_infer)(struct prog *, struct node *);
12
+	int (*static_validate)(const struct func *, struct node *);
13
+	int (*type_infer)(const struct func *, struct node *);
15 14
 };
16 15
 
16
+int func_static_validate(const struct func *func, struct node *n);
17
+struct type *func_return_type(const struct func *func);
18
+
17 19
 #endif	/* _FUNC_H */

+ 44 - 26
global.c

@@ -46,7 +46,7 @@ static struct type *global_map_ktype(struct node *n)
46 46
 	return ktype;
47 47
 }
48 48
 
49
-static int global_map_type_infer(struct prog *prog, struct node *n)
49
+static int global_map_type_infer(const struct func *func, struct node *n)
50 50
 {
51 51
 	struct node *map = n->expr.args;
52 52
 
@@ -61,15 +61,8 @@ static int global_map_type_infer(struct prog *prog, struct node *n)
61 61
 	return 0;
62 62
 }
63 63
 
64
-static int global_map_static_verify(struct node *n)
64
+static int global_map_static_validate(const struct func *func, struct node *n)
65 65
 {
66
-	int nargs = node_nargs(n);
67
-
68
-	if (nargs < 2) {		
69
-		_e("%#N: map without key.\n", n);
70
-		return -EINVAL;
71
-	}
72
-
73 66
 	if (n->expr.args->ntype != N_IDENT) {
74 67
 		_e("%#N: %N is not subscriptable.\n", n, n);
75 68
 		return -EINVAL;
@@ -96,7 +89,7 @@ static int global_assign_type_infer_map(struct node *n)
96 89
 	return 0;
97 90
 }
98 91
 
99
-static int global_assign_type_infer(struct prog *prog, struct node *n)
92
+static int global_assign_type_infer(const struct func *func, struct node *n)
100 93
 {
101 94
 	struct node *lval, *rval;
102 95
 
@@ -125,7 +118,7 @@ static int global_assign_type_infer(struct prog *prog, struct node *n)
125 118
 	return -EINVAL;
126 119
 }
127 120
 
128
-static int global_assign_static_verify(struct node *n)
121
+static int global_assign_static_validate(const struct func *func, struct node *n)
129 122
 {
130 123
 	struct node *lval;
131 124
 	int nargs = node_nargs(n);
@@ -153,6 +146,11 @@ struct type t_pid = {
153 146
 	.tdef = { .name = ":pid", .type = &t_u32 },
154 147
 };
155 148
 
149
+struct type t_pid_func = {
150
+	.ttype = T_FUNC,
151
+
152
+	.func = { .type = &t_pid },
153
+};
156 154
 
157 155
 /* time */
158 156
 
@@ -163,26 +161,52 @@ struct type t_time = {
163 161
 	.tdef = { .name = ":time", .type = &t_s64 },
164 162
 };
165 163
 
164
+struct type t_time_func = {
165
+	.ttype = T_FUNC,
166
+
167
+	.func = { .type = &t_time },
168
+};
169
+
170
+struct type t_block_func = {
171
+	.ttype = T_FUNC,
172
+
173
+	.func = { .type = &t_void, .vargs = 1 },
174
+};
175
+
176
+struct tfield f_assign[] = {
177
+	{ .type = &t_void },
178
+	{ .type = &t_void },
179
+
180
+	{ .type = NULL }
181
+};
182
+
183
+struct type t_assign_func = {
184
+	.ttype = T_FUNC,
185
+
186
+	.func = { .type = &t_void, .args = f_assign },
187
+};
166 188
 
167 189
 static const struct func global_funcs[] = {
168
-	{ .name = ":block", .type = &t_void, },
190
+	{ .name = ":block", .type = &t_block_func, },
169 191
 
170 192
 	{ .name = "+", },
171 193
 	{ .name = "-", },
172 194
 	
173 195
 	{
174 196
 		.name = ":assign",
197
+		.type = &t_assign_func,
175 198
 		.type_infer = global_assign_type_infer,
176
-		.static_verify = global_assign_static_verify,
199
+		.static_validate = global_assign_static_validate,
177 200
 	},
178 201
 	{
179 202
 		.name = ":map",
203
+		/* .type = t_map_func, */
180 204
 		.type_infer = global_map_type_infer,
181
-		.static_verify = global_map_static_verify,
205
+		.static_validate = global_map_static_validate,
182 206
 	},
183 207
 
184
-	{ .name = "pid",  .type = &t_pid, },
185
-	{ .name = "time", .type = &t_time, },
208
+	{ .name = "pid",  .type = &t_pid_func, },
209
+	{ .name = "time", .type = &t_time_func, },
186 210
 
187 211
 	{ .name = "quantize", },
188 212
 	
@@ -255,18 +279,12 @@ int global_sym_alloc(struct prog *prog, struct node *n)
255 279
 	if (!func)
256 280
 		return -ENOENT;
257 281
 
258
-	if (func->static_verify) {
259
-		err = func->static_verify(n);
260
-		if (err)
261
-			return err;
262
-	}
282
+	err = func_static_validate(func, n);
283
+	if (err)
284
+		return err;
263 285
 
264 286
 	n->sym = sym_alloc(st, n, func);
265
-
266
-	if (func->type)
267
-		/* return type is static, fill it now */
268
-		n->sym->type = func->type;
269
-
287
+	n->sym->type = func_return_type(func);
270 288
 	return 0;
271 289
 }
272 290
 

+ 2 - 2
ply.c

@@ -79,7 +79,7 @@ struct ctx *ctx_get(void)
79 79
 		node_expr(":block",
80 80
 			  node_expr(":assign",
81 81
 				    node_ident("us"),
82
-				    node_expr("pid", NULL),
82
+				    node_expr("pid", NULL), node_num(0),
83 83
 				    NULL),
84 84
 			  node_expr(":assign",
85 85
 				    node_expr(":map",
@@ -268,7 +268,7 @@ int pass_type_infer(struct node *n, void *_prog)
268 268
 	struct prog *prog = _prog;
269 269
 
270 270
 	if (n->sym->func->type_infer)
271
-		return n->sym->func->type_infer(prog, n);
271
+		return n->sym->func->type_infer(n->sym->func, n);
272 272
 
273 273
 	return 0;
274 274
 }

+ 6 - 2
type.c

@@ -31,10 +31,11 @@ static void type_dump_func(struct type *t, const char *name, FILE *fp)
31 31
 	struct tfield *arg;
32 32
 
33 33
 	type_dump(t->func.type, NULL, fp);
34
-	fprintf(fp, " (*\e[1m%s\e[0m)(", name ? : "");
34
+	fprintf(fp, " %s(*\e[1m%s\e[0m)(",
35
+		t->func.aggregation ? "@" : "", name ? : "");
35 36
 
36 37
 	if (!t->func.args) {
37
-		__faint(fp, "void");
38
+		__faint(fp, t->func.vargs ? "..." : "void");
38 39
 		fputc(')', fp);
39 40
 		return;
40 41
 	}
@@ -46,6 +47,9 @@ static void type_dump_func(struct type *t, const char *name, FILE *fp)
46 47
 		type_dump(arg->type, NULL, fp);
47 48
 	}
48 49
 
50
+	if (t->func.vargs)
51
+		__faint(fp, ", ...");
52
+
49 53
 	fputc(')', fp);
50 54
 }
51 55
 

+ 17 - 0
type.h

@@ -122,4 +122,21 @@ extern struct type t_llong;
122 122
 extern struct type t_sllong;
123 123
 extern struct type t_ullong;
124 124
 
125
+
126
+/* helpers */
127
+
128
+static inline int type_nargs(struct type *t)
129
+{
130
+	struct tfield *f;
131
+	int nargs = 0;
132
+
133
+	if (!t->func.args)
134
+		return 0;
135
+
136
+	for (f = t->func.args; f->type; f++, nargs++);
137
+
138
+	return nargs;
139
+
140
+}
141
+
125 142
 #endif	/* _PLY_TYPE_H */

+ 90 - 0
utils.c

@@ -0,0 +1,90 @@
1
+#include <stdarg.h>
2
+#include <stdio.h>
3
+
4
+#include "node.h"
5
+#include "printxf.h"
6
+#include "sym.h"
7
+#include "type.h"
8
+
9
+struct ast_fprint_info {
10
+	FILE *fp;
11
+	int indent;
12
+};
13
+
14
+static int __ast_fprint_pre(struct node *n, void *_info)
15
+{
16
+	struct ast_fprint_info *info = _info;
17
+	struct node *arg;
18
+
19
+	if (n->prev)
20
+		fputc(' ', info->fp);
21
+
22
+	if (node_is_block(n->up)) {
23
+		info->indent += 4;
24
+		fprintf(info->fp, "\n%*s", info->indent, "");
25
+	}
26
+
27
+	if (n->ntype == N_EXPR)
28
+		fputc('(', info->fp);
29
+
30
+	fprintxf(NULL, info->fp,
31
+		 "%N%T", n, n->sym ? n->sym->type : NULL);
32
+
33
+	if ((n->ntype == N_EXPR) && n->expr.args)
34
+		fputc(' ', info->fp);
35
+
36
+	return 0;
37
+}
38
+
39
+static int __ast_fprint_post(struct node *n, void *_info)
40
+{
41
+	struct ast_fprint_info *info = _info;
42
+	struct node *c;
43
+
44
+	if (node_is_block(n))
45
+		fprintf(info->fp, "\n%*s", info->indent, "");
46
+
47
+	if (n->ntype == N_EXPR)
48
+		fputc(')', info->fp);
49
+
50
+	if (node_is_block(n->up))
51
+		info->indent -= 4;
52
+	
53
+	return 0;
54
+}
55
+
56
+void ast_fprint(FILE *fp, struct node *root)
57
+{
58
+	struct ast_fprint_info info = {
59
+		.fp = fp,
60
+	};
61
+
62
+	node_walk(root, __ast_fprint_pre, __ast_fprint_post, &info);
63
+	fputc('\n', fp);		
64
+}
65
+
66
+
67
+int order_vfprintxf(struct printxf *pxf, FILE *fp, const char *fmt, va_list ap)
68
+{
69
+	int arg = va_arg(ap, int);
70
+
71
+	switch (arg) {
72
+	case 1:
73
+		fputs("1st", fp);
74
+		return 3;
75
+	case 2:
76
+		fputs("2nd", fp);
77
+		return 3;
78
+	case 3:
79
+		fputs("3rd", fp);
80
+		return 3;
81
+	}
82
+
83
+	return fprintf(fp, "%dth", arg);
84
+}
85
+
86
+__attribute__((constructor))
87
+static void utils_init(void)
88
+{
89
+	printxf_default.vfprintxf['O'] = order_vfprintxf;
90
+}