-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathstack.h
236 lines (218 loc) · 11.8 KB
/
stack.h
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
** This file is part of the Matrix Brandy Basic VI Interpreter.
** Copyright (C) 2000-2014 David Daniels
** Copyright (C) 2018-2024 Michael McConnell and contributors
**
** Brandy is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2, or (at your option)
** any later version.
**
** Brandy is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Brandy; see the file COPYING. If not, write to
** the Free Software Foundation, 59 Temple Place - Suite 330,
** Boston, MA 02111-1307, USA.
**
**
** This file contains the definitions of functions concerned with
** manipulating the Basic stack
*/
#ifndef __stack_h
#define __stack_h
#include "common.h"
#include "basicdefs.h"
extern void *alloc_stackmem(size_t);
extern void *alloc_stackstrmem(int32);
extern void free_stackmem(void);
extern void push_lvalue(int32, pointers);
extern void push_int(int32);
extern void push_int64(int64);
extern void push_uint8(uint8);
extern void push_float(float64);
extern void push_string(basicstring);
extern void push_strtemp(int32, char *);
extern void push_dolstring(int32, char *);
extern void push_array(basicarray *, int32);
extern void push_arraytemp(basicarray *, int32);
extern void push_pointer(void *);
extern void push_proc(char *, int32);
extern void push_fn(char *, int32);
extern void push_gosub(void);
extern void push_while(byte *);
extern void push_repeat(void);
extern void push_intfor(lvalue, byte *, int32, int32, boolean);
extern void push_int64for(lvalue, byte *, int64, int64, boolean);
extern void push_floatfor(lvalue, byte *, float64, float64, boolean);
extern void push_data(byte *);
extern void push_error(errorblock);
extern void push_varyint(int64);
extern size_t *make_opstack(void);
extern sigjmp_buf *make_restart(void);
extern boolean safestack(void);
extern lvalue pop_lvalue(void);
extern int64 pop_anyint(void);
extern uint8 pop_uint8(void);
extern int32 pop_int(void);
extern int64 pop_int64(void);
extern int32 pop_anynum32(void);
extern int64 pop_anynum64(void);
extern float64 pop_anynumfp(void);
extern float80 pop_anynumld(void);
extern float64 pop_float(void);
extern basicstring pop_string(void);
extern basicarray *pop_array(void);
extern basicarray pop_arraytemp(void);
extern fnprocinfo pop_proc(void);
extern fnprocinfo pop_fn(void);
extern gosubinfo pop_gosub(void);
extern stack_while *get_while(void);
extern stack_repeat *get_repeat(void);
extern stack_for *get_for(void);
extern void pop_while(void);
extern void pop_repeat(void);
extern void pop_for(void);
extern byte *pop_data(void);
extern errorblock pop_error(void);
extern void save_int(lvalue, int32);
extern void save_uint8(lvalue, uint8);
extern void save_int64(lvalue, int64);
extern void save_float(lvalue, float64);
extern void save_string(lvalue, basicstring);
extern void save_array(lvalue);
extern void save_retint(lvalue, lvalue, int32);
extern void save_retuint8(lvalue, lvalue, uint8);
extern void save_retint64(lvalue, lvalue, int64);
extern void save_retfloat(lvalue, lvalue, float64);
extern void save_retstring(lvalue, lvalue, basicstring);
extern void restore_parameters(int32);
extern void empty_stack(stackitem);
extern stackitem stack_unwindlocal(void);
extern void reset_stack(byte *);
extern void init_stack(void);
extern void clear_stack(void);
extern void *alloc_local(int32);
#ifdef DEBUG
extern void debug_show_stackitemtype(int32);
#endif
/* LARGEST_ENTRY is the size of the largest string or numeric entry on the stack */
#define LARGEST_ENTRY sizeof(basicstring)
#define ALIGNSIZE(type) (ALIGN(sizeof(type)))
/*
** 'IS_SAFESTACK' returns TRUE if it is safe to move the Basic stack.
** At the moment this is only allowed if the stack is empty, that is,
** the only thing on it is the operator stack and the program is not
** in a procedure or function
*/
#define IS_SAFESTACK (basicvars.procstack==NIL && basicvars.stacktop.intsp->itemtype==STACK_OPSTACK)
/* The following macros are used to speed up operations on the BASIC stack */
#define is8or32int(x) ((x == STACK_INT) || (x == STACK_UINT8))
#define GET_TOPITEM (basicvars.stacktop.intsp->itemtype)
#define TOPITEMISINT ((basicvars.stacktop.intsp->itemtype == STACK_INT) || (basicvars.stacktop.intsp->itemtype == STACK_UINT8) || (basicvars.stacktop.intsp->itemtype == STACK_INT64))
#define IS_NUMERIC(x) ((x == STACK_INT) || (x == STACK_UINT8) || (x == STACK_INT64) || (x == STACK_FLOAT))
#define TOPITEMISNUM ((basicvars.stacktop.intsp->itemtype == STACK_INT) || (basicvars.stacktop.intsp->itemtype == STACK_UINT8) || (basicvars.stacktop.intsp->itemtype == STACK_INT64) || (basicvars.stacktop.intsp->itemtype == STACK_FLOAT))
#define TOPITEMISNUMARRAY ((basicvars.stacktop.intsp->itemtype == STACK_INTARRAY) || (basicvars.stacktop.intsp->itemtype == STACK_UINT8ARRAY) || (basicvars.stacktop.intsp->itemtype == STACK_INT64ARRAY) || (basicvars.stacktop.intsp->itemtype == STACK_FLOATARRAY))
#define TOPITEMISNUMARRTEMP ((basicvars.stacktop.intsp->itemtype == STACK_IATEMP) || (basicvars.stacktop.intsp->itemtype == STACK_U8ATEMP) || (basicvars.stacktop.intsp->itemtype == STACK_I64ATEMP) || (basicvars.stacktop.intsp->itemtype == STACK_FATEMP))
#define TOPITEMISFOR ((basicvars.stacktop.intsp->itemtype == STACK_INTFOR) || (basicvars.stacktop.intsp->itemtype == STACK_INT64FOR) || (basicvars.stacktop.intsp->itemtype == STACK_FLOATFOR))
#define PUSH_INT(x) basicvars.stacktop.bytesp-=ALIGN(sizeof(stack_int)); \
basicvars.stacktop.intsp->itemtype = STACK_INT; \
basicvars.stacktop.intsp->intvalue = (x);
#define PUSH_UINT8(x) basicvars.stacktop.bytesp-=ALIGN(sizeof(stack_uint8)); \
basicvars.stacktop.uint8sp->itemtype = STACK_UINT8; \
basicvars.stacktop.uint8sp->uint8value = (x);
#define PUSH_INT64(x) basicvars.stacktop.bytesp-=ALIGN(sizeof(stack_int64)); \
basicvars.stacktop.int64sp->itemtype = STACK_INT64; \
basicvars.stacktop.int64sp->int64value = (x);
#define PUSH_FLOAT(x) basicvars.stacktop.bytesp-=ALIGN(sizeof(stack_float)); \
basicvars.stacktop.floatsp->itemtype = STACK_FLOAT; \
basicvars.stacktop.floatsp->floatvalue = (x);
#define PUSH_STRING(x) basicvars.stacktop.bytesp-=ALIGN(sizeof(stack_string)); \
basicvars.stacktop.stringsp->itemtype = STACK_STRING; \
basicvars.stacktop.stringsp->descriptor = (x);
#define INCR_INT(x) basicvars.stacktop.intsp->intvalue+=(x)
#define INCR_FLOAT(x) basicvars.stacktop.floatsp->floatvalue+=(x)
#define DECR_INT(x) basicvars.stacktop.intsp->intvalue-=(x)
#define DECR_FLOAT(x) basicvars.stacktop.floatsp->floatvalue-=(x)
#define INTDIV_INT(x) basicvars.stacktop.intsp->intvalue/=(x)
#define INTDIV_UINT8(x) basicvars.stacktop.uint8sp->uint8value/=(x)
#define INTDIV_INT64(x) basicvars.stacktop.int64sp->int64value/=(x)
#define DIV_FLOAT(x) basicvars.stacktop.floatsp->floatvalue/=(x)
#define INTMOD_INT(x) basicvars.stacktop.intsp->intvalue%=(x)
#define INTMOD_UINT8(x) basicvars.stacktop.uint8sp->uint8value%=(x)
#define INTMOD_INT64(x) basicvars.stacktop.int64sp->int64value%=(x)
#define AND_INT(x) basicvars.stacktop.intsp->intvalue&=(x)
#define AND_UINT8(x) basicvars.stacktop.uint8sp->uint8value&=(x)
#define AND_INT64(x) basicvars.stacktop.int64sp->int64value&=(x)
#define OR_INT(x) basicvars.stacktop.intsp->intvalue|=(x)
#define OR_UINT8(x) basicvars.stacktop.uint8sp->uint8value|=(x)
#define OR_INT64(x) basicvars.stacktop.int64sp->int64value|=(x)
#define EOR_INT(x) basicvars.stacktop.intsp->intvalue^=(x)
#define EOR_UINT8(x) basicvars.stacktop.uint8sp->uint8value^=(x)
#define EOR_INT64(x) basicvars.stacktop.int64sp->int64value^=(x)
#define NEGATE_INT basicvars.stacktop.intsp->intvalue = -basicvars.stacktop.intsp->intvalue
#define NEGATE_INT64 basicvars.stacktop.int64sp->int64value = -basicvars.stacktop.int64sp->int64value
#define NEGATE_FLOAT basicvars.stacktop.floatsp->floatvalue = -basicvars.stacktop.floatsp->floatvalue
#define NOT_INT basicvars.stacktop.intsp->intvalue = ~basicvars.stacktop.intsp->intvalue
#define NOT_UINT8 basicvars.stacktop.uint8sp->uint8value = ~basicvars.stacktop.uint8sp->uint8value
#define NOT_INT64 basicvars.stacktop.int64sp->int64value = ~basicvars.stacktop.int64sp->int64value
#define ABS_INT basicvars.stacktop.intsp->intvalue = abs(basicvars.stacktop.intsp->intvalue)
#define ABS_INT64 basicvars.stacktop.int64sp->int64value = llabs(basicvars.stacktop.int64sp->int64value)
#define ABS_FLOAT basicvars.stacktop.floatsp->floatvalue = fabs(basicvars.stacktop.floatsp->floatvalue)
#define CPEQ_INT(x) basicvars.stacktop.intsp->intvalue = \
(basicvars.stacktop.intsp->intvalue==(x) ? BASTRUE : BASFALSE)
#define CPEQ_UINT8(x) basicvars.stacktop.uint8sp->uint8value = \
(basicvars.stacktop.uint8sp->uint8value==(x) ? BASTRUE : BASFALSE)
#define CPEQ_INT64(x) basicvars.stacktop.int64sp->int64value = \
(basicvars.stacktop.int64sp->int64value==(x) ? BASTRUE : BASFALSE)
#define CPNE_INT(x) basicvars.stacktop.intsp->intvalue = \
(basicvars.stacktop.intsp->intvalue!=(x) ? BASTRUE : BASFALSE)
#define CPNE_UINT8(x) basicvars.stacktop.uint8sp->uint8value = \
(basicvars.stacktop.uint8sp->uint8value!=(x) ? BASTRUE : BASFALSE)
#define CPNE_INT64(x) basicvars.stacktop.int64sp->int64value = \
(basicvars.stacktop.int64sp->int64value!=(x) ? BASTRUE : BASFALSE)
#define CPGT_INT(x) basicvars.stacktop.intsp->intvalue = \
(basicvars.stacktop.intsp->intvalue>(x) ? BASTRUE : BASFALSE)
#define CPGT_UINT8(x) basicvars.stacktop.uint8sp->uint8value = \
(basicvars.stacktop.uint8sp->uint8value>(x) ? BASTRUE : BASFALSE)
#define CPGT_INT64(x) basicvars.stacktop.int64sp->int64value = \
(basicvars.stacktop.int64sp->int64value>(x) ? BASTRUE : BASFALSE)
#define CPLT_INT(x) basicvars.stacktop.intsp->intvalue = \
(basicvars.stacktop.intsp->intvalue<(x) ? BASTRUE : BASFALSE)
#define CPLT_UINT8(x) basicvars.stacktop.uint8sp->uint8value = \
(basicvars.stacktop.uint8sp->uint8value<(x) ? BASTRUE : BASFALSE)
#define CPLT_INT64(x) basicvars.stacktop.int64sp->int64value = \
(basicvars.stacktop.int64sp->int64value<(x) ? BASTRUE : BASFALSE)
#define CPGE_INT(x) basicvars.stacktop.intsp->intvalue = \
(basicvars.stacktop.intsp->intvalue>=(x) ? BASTRUE : BASFALSE)
#define CPGE_UINT8(x) basicvars.stacktop.uint8sp->uint8value = \
(basicvars.stacktop.uint8sp->uint8value>=(x) ? BASTRUE : BASFALSE)
#define CPGE_INT64(x) basicvars.stacktop.int64sp->int64value = \
(basicvars.stacktop.int64sp->int64value>=(x) ? BASTRUE : BASFALSE)
#define CPLE_INT(x) basicvars.stacktop.intsp->intvalue = \
(basicvars.stacktop.intsp->intvalue<=(x) ? BASTRUE : BASFALSE)
#define CPLE_UINT8(x) basicvars.stacktop.uint8sp->uint8value = \
(basicvars.stacktop.uint8sp->uint8value<=(x) ? BASTRUE : BASFALSE)
#define CPLE_INT64(x) basicvars.stacktop.int64sp->int64value = \
(basicvars.stacktop.int64sp->int64value<=(x) ? BASTRUE : BASFALSE)
/*
** If the debug version of the code is being used, replace some
** of the macros with calls to their equivalent functions as these
** produce debugging output if the DEBUG macro is defined
*/
#ifdef DEBUG
#undef PUSH_INT
#undef PUSH_INT64
#undef PUSH_UINT8
#undef PUSH_FLOAT
#undef PUSH_STRING
#define PUSH_INT(x) push_int(x)
#define PUSH_INT64(x) push_int64(x)
#define PUSH_UINT8(x) push_uint8(x)
#define PUSH_FLOAT(x) push_float(x)
#define PUSH_STRING(x) push_string(x)
#endif
#endif