-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjmpchain.c
104 lines (78 loc) · 1.68 KB
/
jmpchain.c
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
#include <stdlib.h>
#include "jmpchain.h"
#include "parse.h"
#include "instr.h"
void yyerror(const char *);
typedef struct chain_node {
int stype;
int bchain;
int cchain;
} chain_node_t;
typedef struct jmpchain {
int csptr;
chain_node_t array[JMPCHAIN_SIZE];
parser_t *p;
} jmpchain_t;
int jmpchain_get_csptr(jmpchain_t *j)
{
return j->csptr;
}
static chain_node_t* jmpchain_get_node(jmpchain_t *j, int sptr)
{
return &j->array[sptr];
}
static void jmpchain_set_node(jmpchain_t *j, chain_node_t *n)
{
j->array[j->csptr] = *n;
}
void jmpchain_nestin(jmpchain_t *j, int st)
{
j->csptr++;
chain_node_t n;
n.stype = st;
n.bchain = -1;
n.cchain = -1;
jmpchain_set_node(j, &n);
}
void jmpchain_break(jmpchain_t *j, int jc)
{
parser_t *p = j->p;
if (j->csptr > 0) {
parser_set_instr(p, parser_get_pc(p), jc, 0, j->array[j->csptr].bchain);
parser_inc_pc(p);
j->array[j->csptr].bchain = parser_get_pc(p) - 1;
}
else
yyerror("Illigal use of break statement");
}
void jmpchain_nestout(jmpchain_t *j, int contp)
{
parser_t *p = j->p;
parser_back_patching(p, j->array[j->csptr].cchain, contp);
parser_back_patching(p, j->array[j->csptr].bchain, parser_get_pc(j->p));
j->csptr--;
}
void jmpchain_conti(jmpchain_t *j)
{
parser_t *p = j->p;
int i;
for (i = j->csptr; i > 0 && j->array[i].stype == 0; i--);
if (i <= 0)
yyerror("Illegal use of the continue");
else {
int pc = parser_get_pc(p);
parser_set_instr(p, pc, JUMP, 0, j->array[i].cchain);
j->array[i].cchain = pc;
parser_inc_pc(j->p);
}
}
int jmpchain_init(jmpchain_t **j, parser_t *p)
{
*j = malloc(sizeof(jmpchain_t));
(*j)->csptr = 0;
(*j)->p = p;
}
void jmpchain_free(jmpchain_t *j)
{
free(j);
}