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
|
#include "print.h"
#include "errloc.h"
#include "fn.h"
#include "lit.h"
#include "parse.h"
#include "prv.h"
#include "stmt.h"
#include "storage.h"
#include "type.h"
#include <stdlib.h>
#include <string.h>
static int entry(const struct lex *l, const struct tk *tk, struct print *pr,
struct prv *p)
{
size_t n = pr->nentries + 1;
struct prientry *entries;
const struct stentry *stentry = NULL;
const struct fn *fn = fn_cur(p);
const struct lit *lit = NULL;
if (tk->type == ID)
{
const struct type *t = NULL;
if ((t = type_find(fn, tk->s)))
{
if (t->type != C)
{
errloc(tk, "type \"%s\" not a constant", tk->s);
return -1;
}
else if (!(lit = lit_push(t->tk, p)))
return -1;
}
else if (!(stentry = fn_var(fn, tk)))
{
errloc(tk, "undefined reference to \"%s\"", tk->s);
return -1;
}
}
else if (tk->type == LIT && !(lit = lit_push(tk, p)))
return -1;
if (!(entries = realloc(pr->entries, n * sizeof *entries)))
{
perror("realloc(3)");
return -1;
}
pr->entries = entries;
pr->entries[pr->nentries++] = (struct prientry)
{
.tk = tk,
.lit = lit,
.entry = stentry
};
return 0;
}
void print_free(struct print *pr)
{
free(pr->entries);
}
int print(const struct lex *l, struct prv *p,
int (*fn)(const struct lex *, const struct prv *, const struct print *))
{
const struct tk *tk = p->stk + 1;
struct print pr = {0};
struct pos *pos = &p->pos[p->i];
int eof;
if (lex_eof(l, tk))
{
errloc(tk - 1, "incomplete %s statement", p->stk->s);
return -1;
}
for (;;)
if (entry(l, tk, &pr, p))
goto failure;
else if ((eof = lex_eof(l, ++tk)) || kw(tk->s))
break;
if (eof || strcmp(tk->s, "etc"))
pr.println = 1;
else if (!eof)
tk++;
if (fn(l, p, &pr))
goto failure;
pos->seq = pos->stseq = stmts;
pos->step = stmts->steps;
p->stk = tk;
return 1;
failure:
print_free(&pr);
return -1;
}
|