-
Notifications
You must be signed in to change notification settings - Fork 3
/
branch_ops.c
148 lines (128 loc) · 3.16 KB
/
branch_ops.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
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
137
138
139
140
141
142
143
144
145
146
147
148
// struct for 'for' loops:
typedef struct {
DCLANG_INT limit;
DCLANG_INT step;
} forloop_info;
forloop_info fl_stack[3];
DCLANG_INT fl_ptr;
// array for 'times' loop max amounts:
DCLANG_INT times_info[3];
DCLANG_INT times_ptr;
// looping
void timesfunc()
{
return_stack[return_stack_ptr++] = iptr;
times_info[times_ptr++] = (DCLANG_INT) dclang_pop();
loop_counter[loop_counter_ptr++] = 0;
}
void _conttimes()
{
loop_counter[loop_counter_ptr - 1] += 1;
iptr = return_stack[return_stack_ptr - 1];
}
void exittimesfunc()
{
loop_counter[--loop_counter_ptr] = 0;
--return_stack_ptr;
--times_ptr;
}
void againfunc()
{
if (loop_counter[loop_counter_ptr - 1] < times_info[times_ptr - 1] - 1) {
_conttimes();
} else {
exittimesfunc();
}
}
/* these 'for' loops are more flexible, allowing from/to/step parameters. */
void forfunc()
{
return_stack[return_stack_ptr++] = iptr;
fl_stack[fl_ptr].step = (DCLANG_INT) dclang_pop();
loop_counter[loop_counter_ptr++] = (DCLANG_INT) dclang_pop();
fl_stack[fl_ptr++].limit = (DCLANG_INT) dclang_pop();
}
void _contfor()
{
loop_counter[loop_counter_ptr - 1] += fl_stack[fl_ptr - 1].step;
iptr = return_stack[return_stack_ptr - 1];
}
void exitforfunc()
{
--fl_ptr;
loop_counter[--loop_counter_ptr] = 0;
--return_stack_ptr;
}
void nextfunc()
{
if (fl_stack[fl_ptr - 1].step > 0) {
if (loop_counter[loop_counter_ptr - 1] < \
(fl_stack[fl_ptr - 1].limit \
- fl_stack[fl_ptr - 1].step)) {
_contfor();
} else {
exitforfunc();
}
} else {
if (loop_counter[loop_counter_ptr - 1] > \
(fl_stack[fl_ptr - 1].limit \
- fl_stack[fl_ptr - 1].step)) {
_contfor();
} else {
exitforfunc();
}
}
}
void ifunc()
{
push_no_check(loop_counter[loop_counter_ptr - 1]);
}
void jfunc()
{
push_no_check(loop_counter[loop_counter_ptr - 2]);
}
void kfunc()
{
push_no_check(loop_counter[loop_counter_ptr - 3]);
}
// jump if zero (false)
void jumpzfunc(DCLANG_FLT where)
{
DCLANG_INT truth = (DCLANG_INT) dclang_pop();
if (!truth) {
iptr = (uintptr_t) where;
}
}
// unconditional jump
void jumpufunc(DCLANG_FLT where)
{
iptr = (uintptr_t) where;
}
// if-else-endif
void iffunc()
{
// mark our location
return_stack[return_stack_ptr++] = iptr;
// set jump location for 'else'...w/o 'where' location
// will be filled in by 'else'
prog[iptr].function.with_param = jumpzfunc;
prog[iptr++].param = 0;
}
void elsefunc()
{
// get the last starting point of the 'if' clause
DCLANG_INT if_val = return_stack[--return_stack_ptr];
// mark out current location on the return stack
return_stack[return_stack_ptr++] = iptr;
// set the unconditional jump, but no 'where' yet
// (will be filled in later by 'endif')....
prog[iptr].function.with_param = jumpufunc;
prog[iptr++].param = 0;
// update old if val goto:
prog[if_val].param = iptr;
}
void endiffunc()
{
DCLANG_INT last_val = return_stack[--return_stack_ptr];
prog[last_val].param = iptr;
}