-
Notifications
You must be signed in to change notification settings - Fork 1
/
make_prims.cc
136 lines (122 loc) · 3.55 KB
/
make_prims.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* -*-Mode: c++;-*-
Copyright (c) 2003-2010 John Plevyak, All Rights Reserved
*/
#include "plib.h"
static FILE *fp = 0;
static FILE *hfp = 0;
char *catstr(char *s, char *ss) {
int l = strlen(s) + strlen(ss) + 1;
char *x = (char *)MALLOC(l + 1);
strcpy(x, s);
strcat(x, ss);
return x;
}
struct Line {
char *name;
char *string;
char *nargs;
char *pos;
char *nres;
char *argtypes;
char *rettypes;
char *options;
int index;
};
#define forv_Line(_x, _y) forv_Vec(Line, _x, _y)
#define EOF_TOK ((char *)(intptr_t)-1)
typedef char *charp;
char *get(charp &p, int optnum = 0) {
while (*p && isspace(*p)) p++;
char *s = p;
if (optnum && (*p != '-' && !isdigit(*p))) return NULL;
if (*s == '{') {
while (*p && *p != '}') p++;
if (*p) p++;
} else if (*s == '"') {
p++;
while (*p && *p != '"') p++;
if (*p) p++;
} else
while (*p && !isspace(*p)) p++;
if (!*p) return EOF_TOK;
if (*s == ';') return NULL;
return dupstr(s, p);
}
void get_lines(char *b, Vec<Line *> &lines) {
int index = 0;
while (1) {
Line *l = new Line;
l->index = index++;
do {
while (*b && isspace(*b)) b++;
if (*b != '/') break;
while (*b && *b != '\n') b++;
} while (*b);
if ((l->name = get(b)) == EOF_TOK) return;
if ((l->string = get(b)) == EOF_TOK) return;
if ((l->nargs = get(b)) == EOF_TOK) return;
if ((l->pos = get(b)) == EOF_TOK) return;
if ((l->nres = get(b, 1)) == EOF_TOK) return;
if ((l->argtypes = get(b)) == EOF_TOK) return;
if ((l->rettypes = get(b)) == EOF_TOK) return;
if ((l->options = get(b)) == EOF_TOK) return;
lines.add(l);
}
}
void declare_data(Vec<Line *> &lines) {
forv_Line(l, lines) {
fprintf(hfp, "extern Prim *%s;\n", l->name);
fprintf(hfp, "#define P_%s %d\n", l->name, l->index);
}
}
void define_data(Vec<Line *> &lines) { forv_Line(l, lines) fprintf(fp, "Prim *%s = 0;\n", l->name); }
void build_data(Vec<Line *> &lines) {
forv_Line(l, lines) {
int nargs = 0;
char *rets = l->nres;
if (!rets) rets = (char *)"1";
fprintf(fp, " static PrimType %s_arg_types[] = %s;\n", l->name, l->argtypes);
fprintf(fp, " static PrimType %s_ret_types[] = %s;\n", l->name, l->rettypes);
fprintf(fp,
" %s = new Prim(%d, %s, \"%s\", %s, %s, %s, %s_arg_types, "
"%s_ret_types, %s);\n",
l->name, l->index, l->string, l->name, l->nargs, l->pos, rets, l->name, l->name,
l->options ? "PRIM_NON_FUNCTIONAL" : "0");
fprintf(fp, " n = (char*)if1->strings.put((char*)%s);\n", l->string);
nargs = atoi(l->nargs);
nargs -= 2;
if (nargs < 0) nargs = 0;
fprintf(fp, " p->prims.add(%s);\n", l->name);
fprintf(fp, " p->prim_map[%d][%s].put(n, %s);\n", nargs, l->pos, l->name);
}
}
int main(int argc, char *argv[]) {
int i = 1, len = 0;
char *buf = NULL;
Vec<Line *> lines;
cchar *fn = 0;
if (argc < 2)
fn = "prim_data.dat";
else
fn = argv[1];
if (argc < 1 || buf_read(fn, &buf, &len) < 0) {
printf("unable to read file '%s' %d", argv[i], argc);
exit(-1);
}
get_lines(buf, lines);
hfp = fopen("prim_data.h", "w");
fprintf(hfp, "#ifndef _prim_data_H\n");
fprintf(hfp, "#define _prim_data_H\n\n");
fprintf(hfp, "class Prim;\n\n");
declare_data(lines);
fprintf(hfp, "#endif\n");
fclose(hfp);
fp = fopen("prim_data.cc", "w");
fprintf(fp, "#include \"prim_data_incs.h\"\n\n");
define_data(lines);
fprintf(fp, "\nvoid prim_init(Primitives *p, IF1 *if1) {\n");
fprintf(fp, " char *n;\n");
build_data(lines);
fprintf(fp, "}\n");
fclose(fp);
}