-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbranch_ops.c
148 lines (128 loc) · 3.17 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_LONG limit;
DCLANG_LONG step;
} forloop_info;
forloop_info fl_stack[3];
DCLANG_LONG fl_ptr;
// array for 'times' loop max amounts:
DCLANG_LONG times_info[3];
DCLANG_LONG times_ptr;
// looping
void timesfunc()
{
return_stack[return_stack_ptr++] = iptr;
times_info[times_ptr++] = (DCLANG_LONG) 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_LONG) dclang_pop();
loop_counter[loop_counter_ptr++] = (DCLANG_LONG) dclang_pop();
fl_stack[fl_ptr++].limit = (DCLANG_LONG) 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_LONG truth = (DCLANG_LONG) 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_LONG 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_LONG last_val = return_stack[--return_stack_ptr];
prog[last_val].param = iptr;
}