-
Notifications
You must be signed in to change notification settings - Fork 7
/
DBC.h
459 lines (423 loc) · 9.35 KB
/
DBC.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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
// DBC.h: DBC/MF DragonBASIC compiler header file
//
// Copyright (C) 2015 Ulrich Hecht
// Source code reconstructed with permission from DBC/MF executable version
// 1.4.5, Copyright (C) Jeff Massung
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
// Ulrich Hecht
#ifndef _DBCF_H
#define _DBCF_H
#include <stdio.h>
enum obj_t {
OBJ_IDENT = 0,
OBJ_SUB = 1,
OBJ_ARR = 2,
OBJ_CMD = 3,
OBJ_ROP = 4,
OBJ_OP = 5,
OBJ_NUM = 6,
OBJ_DIR = 7,
OBJ_STR = 8,
OBJ_EOL = 10,
OBJ_EOT = 11,
OBJ_PATH = 12,
};
enum vartype_t {
VAR_SCALAR = 0,
VAR_ARRAY = 1,
VAR_FIXEDP = 2,
};
enum error_t {
ERR_NONE = 0,
ERR_WOT = 1,
ERR_UNKNOWN_CFLAG = 2,
ERR_NO_SOURCE = 3,
ERR_OPEN_FAIL = 4,
ERR_WRITE_OBJ = 5,
ERR_UNK_DIR = 6,
ERR_UNK_TOK = 7,
ERR_SYNTAX = 8,
ERR_NOTOKEN = 9,
ERR_TOO_MANY_PROTO_ARGS = 10,
ERR_DUP_IDENT = 11,
ERR_UNK_IDENT = 12,
ERR_NEED_LVAL = 13,
ERR_NEED_RVAL = 14,
ERR_TOO_FEW_ARGS = 15,
ERR_TOO_MANY_ARGS = 16,
ERR_STACK_OVER = 17,
ERR_STACK_UNDER = 18,
ERR_UNTERM_CONTROL = 19,
ERR_TERM_MISMATCH = 20,
ERR_EXPR = 21,
ERR_SEGMENT = 22,
ERR_NOT_ARRAY = 23,
ERR_ARRAY = 24,
ERR_TYPE_MISMATCH = 25,
ERR_TYPED_SUB = 26,
ERR_ILLEGAL_OP = 27,
ERR_RETVAL = 28,
ERR_UNREACHABLE = 29,
ERR_WITHOUT = 30,
ERR_NOT_FOUND = 31,
ERR_SET_FOLDER = 32,
ERR_LAUNCH = 33,
};
class TIN
{
public:
~TIN();
TIN(const char *text);
TIN *unused(char *text);
TIN *addCode(const char *code);
void writeCodeToFile(FILE *fp);
TIN *vunused;
TIN *next;
char text[256];
};
class Subroutine
{
public:
Subroutine(const char *ident, bool is_function, enum vartype_t rtype);
~Subroutine();
Subroutine *findByIdent(const char *ident);
void addArgument(const char *name, enum vartype_t vtype);
void addLocal(const char *name, enum vartype_t vtype);
TIN *declareTinLocals(TIN *tin);
char ident[168];
bool is_function;
enum vartype_t ret_vtype;
int num_args;
int arg_vtype[16];
Subroutine *next;
char arg_name[16][168];
int num_locals;
int local_vtype[32];
char local_name[32][168];
bool can_be_naked;
TIN *tin_start;
bool is_inline;
bool has_regvar;
};
enum segment_t {
SEG_TOP = 0x1,
SEG_SUB = 0x2,
SEG_INTR = 0x4,
};
enum cmd_t {
CMD_RESET = 0,
CMD_LEAVE = 1,
CMD_WHILE = 2,
CMD_LOOP = 3,
CMD_REPEAT = 4,
CMD_UNTIL = 5,
CMD_FOR = 6,
CMD_NEXT = 7,
CMD_IF = 8,
CMD_THEN = 9,
CMD_ELSE = 10,
CMD_SELECT = 11,
CMD_CASE = 12,
CMD_DEFAULT = 13,
CMD_END = 14,
CMD_TO = 15,
CMD_DOWNTO = 16,
CMD_STEP = 17,
CMD_RETURN = 18,
CMD_FUNCTION = 19,
CMD_SUB = 20,
CMD_PROTOTYPE = 21,
CMD_DIM = 22,
CMD_AS = 23,
CMD_TYPE = 24,
CMD_READ = 25,
CMD_RESTORE = 26,
CMD_DATA = 27,
CMD_MAP = 28,
CMD_INTERRUPT = 29,
CMD_EXIT = 30,
CMD_INC = 31,
CMD_DEC = 32,
CMD_LOCAL = 33,
CMD_DATAB,
CMD_DATAH,
CMD_READB,
CMD_READH,
CMD_IWRAM,
CMD_GOTO,
CMD_INLINE,
CMD_SWI,
CMD_REGISTER,
};
struct LoopStackEntry {
int line_no;
enum cmd_t cmd;
};
class LoopStack
{
public:
LoopStack();
int getStackPtr();
bool addEntry(enum cmd_t cmd, int line_no);
char popEntry(enum cmd_t *cmd_p, int *line_no_p);
void checkEmpty();
private:
struct LoopStackEntry stack[16];
int stack_ptr;
};
class Variable
{
public:
Variable(const char *ident, enum vartype_t vtype);
~Variable();
Variable *findByIdent(const char *ident);
Variable *prependNew(const char *ident, enum vartype_t vtype);
char ident[256];
int vtype;
Variable *next;
bool is_regvar;
};
enum op_t {
OP_OPAREN = 0,
OP_LNOT = 1,
OP_NAND = 2,
OP_OR = 3,
OP_AND = 4,
OP_NOR = 5,
OP_XOR = 6,
OP_BNOT = 7,
OP_EQ = 8,
OP_NE = 9,
OP_LT = 10,
OP_GT = 11,
OP_LE = 12,
OP_GE = 13,
OP_SL = 14,
OP_SR = 15,
OP_PLUS = 16,
OP_MINUS = 17,
OP_MULT = 18,
OP_DIV = 19,
OP_MOD = 20,
OP_UMINUS = 21,
};
class Compiler;
class Expression
{
public:
Expression(TIN *tin_head, Compiler *c);
void compileOperation(int num_ops, const char *tin_op,
enum vartype_t vtype);
void addOperand(enum vartype_t vtype);
void enqueueOperation(enum op_t op);
void compileNextOperation();
void compileScalarOp();
void compileArrayOp();
void compileFixedPointOp();
enum vartype_t compileAllOps();
private:
op_t operation[64];
vartype_t operand[64];
int operation_idx;
int operand_idx;
TIN *tin_head;
Compiler *comp;
};
enum directive_t {
DIR_REGISTER = 0,
DIR_TITLE = 1,
DIR_INCLUDE = 2,
DIR_IMPORT = 3,
DIR_BITMAP = 4,
DIR_PALETTE = 5,
DIR_SOUND = 6,
DIR_MUSIC = 7,
DIR_CONSTANT = 8,
DIR_REQUIRES = 9,
DIR_MAP = 10,
};
enum rop_t {
ROP_CPAREN = 0,
ROP_CBRACK = 1,
ROP_PERIOD = 2,
ROP_COLON = 3,
ROP_COMMA = 4,
ROP_BANG = 5,
};
class BasicObject
{
public:
BasicObject(enum obj_t otype, int line_no);
BasicObject(enum directive_t dir, int obj_idx);
BasicObject(enum cmd_t cmd, int obj_idx);
BasicObject(enum rop_t rop, int obj_idx);
BasicObject(enum op_t op, int obj_idx);
BasicObject(int val, int line_no);
BasicObject(const BasicObject &bobj);
~BasicObject();
void append(BasicObject *new_bobj);
enum obj_t otype;
enum vartype_t vtype;
union {
int numeric;
char symbolic[256];
} val;
int line_no;
BasicObject *next;
};
class Symbol
{
public:
static Symbol *newInitialSymbolList();
Symbol(const char *ident, Symbol *next);
~Symbol();
void appendBasicObj(const BasicObject *bobj);
BasicObject *getBasicObj(const char *ident);
private:
char ident[168];
BasicObject *basic_obj_head;
Symbol *next;
};
class Parser
{
public:
Parser(const char *filename, Symbol *symbol_list);
~Parser();
char getChar();
char skipNewline();
BasicObject *parseNext();
BasicObject *parseToken();
BasicObject *parseDecimal();
BasicObject *parseDirective();
BasicObject *parseComment();
BasicObject *parseString(const char delim);
BasicObject *parseHex();
BasicObject *parseBinary();
BasicObject *parseOperator();
void parseAll();
BasicObject *retrieveNextBasicObject();
BasicObject *consumeNextBasicObj();
BasicObject *getObjectWithType(enum obj_t otype,
const char * human_type);
bool checkNextBasicObjType(enum obj_t otype);
bool requireRop(enum rop_t rop);
bool getNextCmd(enum cmd_t expected);
void insertBasicObjectList(BasicObject *bobj);
void addNewSymbol(const char *name);
void appendNextBasicObjCopyToSymbolList();
char filename[256];
BasicObject *cur_basic_obj;
Symbol *symbol_head;
private:
int cur_line;
char *text;
char *text_ptr;
BasicObject *basic_obj_head;
bool is_subparser;
};
class Compiler
{
public:
Compiler();
~Compiler();
void parseFile(const char *filename);
int writeOutput(const char *filename);
void emitTin(const char *fmt, ...);
void doSubroutine(BasicObject *bobj, bool is_function, bool emit_code);
void doArgs(bool emit_code);
void addSubArgument(const char *ident, enum vartype_t vtype);
void addSubLocal(const char *ident, enum vartype_t vtype);
void addVariable(const char *ident, enum vartype_t vtype);
void addNewSub(const char *ident, bool is_function,
enum vartype_t vtype);
void checkNotSegment(int seg_mask, const char *human_seg);
void compile();
void compileBasicObject(BasicObject *bobj);
void doDirective(BasicObject *bobj);
void doDirRegister();
void doDirTitle();
void doDirRequires();
void doDirInclude();
void doDirImport();
void doDirBitmap();
void doDirMap();
void doDirPalette();
void doDirSound();
void doDirMusic();
void doDirConstant();
void doCommand(BasicObject *bobj);
void doCmdPrototype();
void doCmdWhile();
void doCmdLoop();
void doCmdRepeat();
void doCmdUntil();
void doCmdFor();
void doCmdNext();
void doCmdDim();
void doCmdLocal();
void doCmdReturn(bool epilog);
void doCmdMap();
void doCmdData(unsigned int size);
void doCmdRead(unsigned int size);
void doCmdRestore();
void doCmdSub();
void doCmdFunction();
void doCmdIf();
void doCmdElse();
void doCmdEndIf();
void doCmdSelect();
void doCmdCase();
void doCmdDefault();
void doCmdEnd();
void doCmdReset();
void doCmdInterrupt();
void doCmdExit();
void doCmdInc();
void doCmdDec();
void doCmdGoto();
void doCmdSwi();
void doLabel(BasicObject *bobj);
void doLval(BasicObject *bobj);
void doLvalNotSub(BasicObject *bobj, bool array);
void doRvalFunction(BasicObject *bobj);
void doRvalArray(BasicObject *bobj);
void doAssign(BasicObject *bobj);
void doRval(BasicObject *bobj);
enum vartype_t compileExpression();
void doOperand(BasicObject *bobj);
void callSubroutine(Subroutine *sub);
void subNotLeaf() {
if (sub_head)
sub_head->can_be_naked = false;
}
Parser *parser;
int line_no;
private:
TIN *tin_head;
TIN *tin_tail;
Subroutine *sub_head;
Variable *var_head;
Variable *sub_args_head;
Variable *sub_locals_head;
enum segment_t cur_seg;
LoopStack loop_stack;
bool is_top_level;
};
#endif