-
Notifications
You must be signed in to change notification settings - Fork 2
/
parse.h
206 lines (166 loc) · 6.13 KB
/
parse.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
#ifndef _PARSE_H_
#define _PARSE_H_
#include <stdio.h>
extern int compilerErrorTotal;
extern char compilerSyntaxError;
enum { V_INT=1, V_FLOAT, V_STRING };
/*
* namelists and stringspaces are encoded with a 2-byte length followed by
* the name or string.
* program chunks reference variables by index; if a program encounters
* a variable index that is greater than the number of locals, this index
* is referenced as a global variable (after subtracting off the number
* of local variables). Global variables can be defined anywhere.
*/
typedef struct {
int type; // this type is the type of the variable
union {
int intData;
float floatData;
int stringData; /* offset into program's string space */
};
} Value;
#ifdef BUILDING_DLL
typedef struct {
int line;
const char* file;
} Reference;
#endif
#define V_LOCAL 1
#define V_GLOBAL 2
#define V_IMPORT 3
#define V_EXPORT 4
typedef struct {
int name; /* offset into program or procedure's namelist */
int* references;
int numRefs;
Value value;
int type; // this type is where it was declared
int arrayLen; // OBSOLETE, kept for compatibility with Sfall Script Editor
int declared;
const char* fdeclared;
int uses;
int initialized; // 1 if this variable is explicitly initialized
} Variable;
typedef struct {
Variable *variables;
int numVariables;
} VariableList;
typedef struct {
int token;
const char* file;
int lineNum;
Value value;
int column;
} Node;
typedef struct {
Node *nodes;
int numNodes;
} NodeList;
#define P_TIMED 0x01
#define P_CONDITIONAL 0x02
#define P_IMPORT 0x04
#define P_EXPORT 0x08
#define P_CRITICAL 0x10
#define P_PURE 0x20
#define P_INLINE 0x40
typedef struct {
int name; /* offset into main program's namelist */
int type; /* timed, conditional, or system procedure */
union {
int time;
NodeList condition;
};
char *namelist; /* this program's namelist */
int numArgs;
int defined;
VariableList variables;
int* references;
int numRefs;
int uses;
int declared;
const char* fdeclared;
int start;
const char* fstart;
int end;
const char* fend;
NodeList nodes;
int minArgs; // minimum number of arguments for call
int deftype; // set to 1 if this has been define (and not just declared)
int stringifiedName; // offset into program's string space, this used when procedure is referenced via stringify operator
} Procedure;
typedef struct {
Procedure *procedures;
int numProcedures;
} ProcedureList;
#include <setjmp.h>
typedef struct {
ProcedureList procedures;
VariableList variables;
VariableList externals; // all variables either exported from this module,
// or imported to this module
char *stringspace; /* this program's string space */
char *namelist; /* this program's global namelist */
jmp_buf env;
//jmp_buf stmtEnv;
} Program;
#include "lex.h"
extern void parse(InputStream *, const char *);
extern void dumpProgram(Program *);
extern void parseStatement(Procedure *p);
extern void parseStatementNoSemicolon(Procedure *p);
extern void parseExpression(Procedure *p, NodeList *nodes);
extern void parseExpGroup(Procedure *p, NodeList *nodes, int num);
extern void emitOp(Procedure *p, NodeList *nodes, int token);
extern void emitInt(Procedure *p, NodeList *nodes, int i);
extern void emitNode(Procedure *p, NodeList *n, LexData *data);
extern int outputStr(const char *s);
extern int parseOutput(const char *format, ...);
extern void parseMessageAtNode(const Node* node, const char *format, ...);
extern void parseWarningAtNode(const Node* node, const char *format, ...);
extern void parseWarning(const char *format, ...);
extern void parseErrorAtNode(const Node* node, const char *format, ...);
extern void parseError(const char *format, ...);
extern void parseSemanticError(const char *format, ...);
extern void CloneLexData(LexData *dest, LexData *source);
extern void GenTmpVar(Procedure *p, LexData* lex);
extern void parseLibArgs(Procedure *, NodeList*, int, int);
extern int expectToken(int expectToken);
extern void freeCurrentProgram(void);
extern char *getName(int offset, char *namelist);
extern int addVariable(VariableList *var, char **namelist, int type, char *name);
extern int findVariableIndex(char *var, VariableList *v, char *namelist);
#define P_GLOBAL 0x80000000
#define P_LOCAL 0x40000000
#define P_PROCEDURE 0x20000000
#define P_EXTERN 0x10000000
#define P_STRINGIFY 0x08000000
#include "opcodes.h"
// write out num expressions with opcode x
#define WEXP(x, num) i++; i = writeNumExpression(n, i, num, f); writeOp(x, f)
#define WEXPPROC(x, num) i++; i = writeNumExpressionProc(n, i, num, f); writeOp(x, f)
// make a case for token T_x, write out opcode O_x and num expressions
// use this one to write an 'statement' type opcode/lib function
#define EXP(x, num) case T_##x: WEXP(O_##x, num); break
// this is like above, but can take procedures as arguments
#define EXPPROC(x, num) case T_##x: WEXPPROC(O_##x, num); break
// use this one to write out a library function/opcode that can be
// used in both a statement and expression context, when that opcode/function
// is being used as a statement (for the expression case, just use EXP/EXPPROC)
#define EXPST(x, num) case T_##x: WEXP(O_##x, num); writeOp(O_POP, f); break
#define EXPSTPROC(x, num) case T_##x: WEXPPROC(O_##x, num); writeOp(O_POP, f); break
// write out opcode O_x for token T_x; assumes the output file handle is 'f'.
#define ST(x) case T_##x: i++; writeOp(O_##x, f); break
// parse N expressions, separated by commas.
// assumes input procedure pointer is 'p', and
// all nodes are going into that procedure's node list.
// Use this one to parse statements
#define PARSE(t, n) case T_##t: parseLibArgs(p, nodes, n, 0); break
// Use this one to parse statements with procedures at specific arguments
#define PARSEPROC(t, n, ps) case T_##t: parseLibArgs(p, nodes, n, ps); break
// use this one to parse expressions
#define PARSEEXP(t, n) case T_##t: \
emitOp(p, nodes, T_##t); \
parseLibArgs(p, nodes, n, 0); \
break
#endif