浏览代码

work work

Tobias Waldekranz.com 8 年之前
父节点
当前提交
a4e6828dfc
共有 7 个文件被更改,包括 214 次插入50 次删除
  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
 #include "sym.h"
6
 #include "sym.h"
7
 #include "type.h"
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
 	struct tfield *f;
11
 	struct tfield *f;
12
 	struct node *arg;
12
 	struct node *arg;
13
-	int nargs = 0;
13
+	int fargs, nargs = 0;
14
 
14
 
15
 	for (f = func->type->func.args, arg = n->expr.args;
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
 			continue;
21
 			continue;
21
 
22
 
22
 		_e("%#N: %O argument is of type '%T', expected '%T'.\n",
23
 		_e("%#N: %O argument is of type '%T', expected '%T'.\n",
23
 		   n, nargs, arg->sym->type, f->type);
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
 int func_static_validate(const struct func *func, struct node *n)
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
 	switch (n->ntype) {
53
 	switch (n->ntype) {
35
 	case N_EXPR:
54
 	case N_EXPR:
37
 			_e("%#N: %N is not callable.\n", n, n);
56
 			_e("%#N: %N is not callable.\n", n, n);
38
 			return -EINVAL;
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
 	case N_IDENT:
62
 	case N_IDENT:
43
 		if (func->type->ttype == T_FUNC) {
63
 		if (func->type->ttype == T_FUNC) {
44
 			_e("%#N: %N is a function.\n", n, n);
64
 			_e("%#N: %N is a function.\n", n, n);
45
 			return -EINVAL;
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
 		break;
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
 	const char *name;
9
 	const char *name;
10
 	struct type *type;
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
 #endif	/* _FUNC_H */
19
 #endif	/* _FUNC_H */

+ 44 - 26
global.c

46
 	return ktype;
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
 	struct node *map = n->expr.args;
51
 	struct node *map = n->expr.args;
52
 
52
 
61
 	return 0;
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
 	if (n->expr.args->ntype != N_IDENT) {
66
 	if (n->expr.args->ntype != N_IDENT) {
74
 		_e("%#N: %N is not subscriptable.\n", n, n);
67
 		_e("%#N: %N is not subscriptable.\n", n, n);
75
 		return -EINVAL;
68
 		return -EINVAL;
96
 	return 0;
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
 	struct node *lval, *rval;
94
 	struct node *lval, *rval;
102
 
95
 
125
 	return -EINVAL;
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
 	struct node *lval;
123
 	struct node *lval;
131
 	int nargs = node_nargs(n);
124
 	int nargs = node_nargs(n);
153
 	.tdef = { .name = ":pid", .type = &t_u32 },
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
 /* time */
155
 /* time */
158
 
156
 
163
 	.tdef = { .name = ":time", .type = &t_s64 },
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
 static const struct func global_funcs[] = {
189
 static const struct func global_funcs[] = {
168
-	{ .name = ":block", .type = &t_void, },
190
+	{ .name = ":block", .type = &t_block_func, },
169
 
191
 
170
 	{ .name = "+", },
192
 	{ .name = "+", },
171
 	{ .name = "-", },
193
 	{ .name = "-", },
172
 	
194
 	
173
 	{
195
 	{
174
 		.name = ":assign",
196
 		.name = ":assign",
197
+		.type = &t_assign_func,
175
 		.type_infer = global_assign_type_infer,
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
 		.name = ":map",
202
 		.name = ":map",
203
+		/* .type = t_map_func, */
180
 		.type_infer = global_map_type_infer,
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
 	{ .name = "quantize", },
211
 	{ .name = "quantize", },
188
 	
212
 	
255
 	if (!func)
279
 	if (!func)
256
 		return -ENOENT;
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
 	n->sym = sym_alloc(st, n, func);
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
 	return 0;
288
 	return 0;
271
 }
289
 }
272
 
290
 

+ 2 - 2
ply.c

79
 		node_expr(":block",
79
 		node_expr(":block",
80
 			  node_expr(":assign",
80
 			  node_expr(":assign",
81
 				    node_ident("us"),
81
 				    node_ident("us"),
82
-				    node_expr("pid", NULL),
82
+				    node_expr("pid", NULL), node_num(0),
83
 				    NULL),
83
 				    NULL),
84
 			  node_expr(":assign",
84
 			  node_expr(":assign",
85
 				    node_expr(":map",
85
 				    node_expr(":map",
268
 	struct prog *prog = _prog;
268
 	struct prog *prog = _prog;
269
 
269
 
270
 	if (n->sym->func->type_infer)
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
 	return 0;
273
 	return 0;
274
 }
274
 }

+ 6 - 2
type.c

31
 	struct tfield *arg;
31
 	struct tfield *arg;
32
 
32
 
33
 	type_dump(t->func.type, NULL, fp);
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
 	if (!t->func.args) {
37
 	if (!t->func.args) {
37
-		__faint(fp, "void");
38
+		__faint(fp, t->func.vargs ? "..." : "void");
38
 		fputc(')', fp);
39
 		fputc(')', fp);
39
 		return;
40
 		return;
40
 	}
41
 	}
46
 		type_dump(arg->type, NULL, fp);
47
 		type_dump(arg->type, NULL, fp);
47
 	}
48
 	}
48
 
49
 
50
+	if (t->func.vargs)
51
+		__faint(fp, ", ...");
52
+
49
 	fputc(')', fp);
53
 	fputc(')', fp);
50
 }
54
 }
51
 
55
 

+ 17 - 0
type.h

122
 extern struct type t_sllong;
122
 extern struct type t_sllong;
123
 extern struct type t_ullong;
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
 #endif	/* _PLY_TYPE_H */
142
 #endif	/* _PLY_TYPE_H */

+ 90 - 0
utils.c

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
+}