~ppsspp/ppsspp/ppsspp-1.2.2

« back to all changes in this revision

Viewing changes to ext/armips/Parser/DirectivesParser.cpp

  • Committer: Sérgio Benjamim
  • Date: 2016-04-25 02:30:18 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20160425023018-wk3rd7nu30fejjzz
1.2.2 source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "stdafx.h"
 
2
#include "DirectivesParser.h"
 
3
#include "Core/Common.h"
 
4
#include "Commands/CDirectiveFile.h"
 
5
#include "Commands/CDirectiveData.h"
 
6
#include "Commands/CDirectiveConditional.h"
 
7
#include "Commands/CDirectiveMessage.h"
 
8
#include "Commands/CDirectiveArea.h"
 
9
#include "Commands/CAssemblerLabel.h"
 
10
#include "Commands/CommandSequence.h"
 
11
#include "Archs/MIPS/Mips.h"
 
12
#include "Archs/ARM/Arm.h"
 
13
#include "Core/Expression.h"
 
14
#include "Util/Util.h"
 
15
 
 
16
#include "Tokenizer.h"
 
17
#include "ExpressionParser.h"
 
18
#include <initializer_list>
 
19
#include <algorithm>
 
20
#include "Parser.h"
 
21
 
 
22
CAssemblerCommand* parseDirectiveOpen(Parser& parser, int flags)
 
23
{
 
24
        std::vector<Expression> list;
 
25
        if (parser.parseExpressionList(list,2,3) == false)
 
26
                return nullptr;
 
27
 
 
28
        u64 memoryAddress;
 
29
        std::wstring inputName, outputName;
 
30
 
 
31
        if (list[0].evaluateString(inputName,false) == false)
 
32
                return nullptr;
 
33
 
 
34
        if (list.back().evaluateInteger(memoryAddress) == false)
 
35
                return nullptr;
 
36
 
 
37
        if (list.size() == 3)
 
38
        {
 
39
                if (list[1].evaluateString(outputName,false) == false)
 
40
                        return nullptr;
 
41
                
 
42
                CDirectiveFile* file = new CDirectiveFile();
 
43
                file->initCopy(inputName,outputName,memoryAddress);
 
44
                return file;
 
45
        } else {
 
46
                CDirectiveFile* file = new CDirectiveFile();
 
47
                file->initOpen(inputName,memoryAddress);
 
48
                return file;
 
49
        }
 
50
}
 
51
 
 
52
CAssemblerCommand* parseDirectiveCreate(Parser& parser, int flags)
 
53
{
 
54
        std::vector<Expression> list;
 
55
        if (parser.parseExpressionList(list,2,2) == false)
 
56
                return nullptr;
 
57
 
 
58
        u64 memoryAddress;
 
59
        std::wstring inputName, outputName;
 
60
 
 
61
        if (list[0].evaluateString(inputName,false) == false)
 
62
                return nullptr;
 
63
 
 
64
        if (list.back().evaluateInteger(memoryAddress) == false)
 
65
                return nullptr;
 
66
 
 
67
        CDirectiveFile* file = new CDirectiveFile();
 
68
        file->initCreate(inputName,memoryAddress);
 
69
        return file;
 
70
}
 
71
 
 
72
CAssemblerCommand* parseDirectiveClose(Parser& parser, int flags)
 
73
{
 
74
        CDirectiveFile* file = new CDirectiveFile();
 
75
        file->initClose();
 
76
        return file;
 
77
}
 
78
 
 
79
CAssemblerCommand* parseDirectiveIncbin(Parser& parser, int flags)
 
80
{
 
81
        std::vector<Expression> list;
 
82
        if (parser.parseExpressionList(list,1,3) == false)
 
83
                return nullptr;
 
84
        
 
85
        std::wstring fileName;
 
86
        if (list[0].evaluateString(fileName,false) == false)
 
87
                return nullptr;
 
88
 
 
89
        CDirectiveIncbin* incbin = new CDirectiveIncbin(fileName);
 
90
        if (list.size() >= 2)
 
91
                incbin->setStart(list[1]);
 
92
 
 
93
        if (list.size() == 3)
 
94
                incbin->setSize(list[2]);
 
95
 
 
96
        return incbin;
 
97
}
 
98
 
 
99
CAssemblerCommand* parseDirectivePosition(Parser& parser, int flags)
 
100
{
 
101
        const Token& start = parser.peekToken();
 
102
 
 
103
        std::vector<Expression> list;
 
104
        if (parser.parseExpressionList(list,1,1) == false)
 
105
                return nullptr;
 
106
 
 
107
        u64 position;
 
108
        if (list[0].evaluateInteger(position) == false)
 
109
        {
 
110
                parser.printError(start,L"Invalid ram address");
 
111
                return nullptr;
 
112
        }
 
113
 
 
114
        switch (flags & DIRECTIVE_USERMASK)
 
115
        {
 
116
        case DIRECTIVE_POS_PHYSICAL:
 
117
                return new CDirectivePosition(CDirectivePosition::Physical,position);
 
118
        case DIRECTIVE_POS_VIRTUAL:
 
119
                return new CDirectivePosition(CDirectivePosition::Virtual,position);
 
120
        }
 
121
 
 
122
        return nullptr;
 
123
}
 
124
 
 
125
CAssemblerCommand* parseDirectiveAlignFill(Parser& parser, int flags)
 
126
{
 
127
        std::vector<Expression> list;
 
128
        if (parser.parseExpressionList(list,1,2) == false)
 
129
                return nullptr;
 
130
 
 
131
        CDirectiveAlignFill::Mode mode;
 
132
        switch (flags & DIRECTIVE_USERMASK)
 
133
        {
 
134
        case DIRECTIVE_FILE_ALIGN:
 
135
                mode = CDirectiveAlignFill::Align;
 
136
                break;
 
137
        case DIRECTIVE_FILE_FILL:
 
138
                mode = CDirectiveAlignFill::Fill;
 
139
                break;
 
140
        default:
 
141
                return nullptr;
 
142
        }
 
143
 
 
144
        if (list.size() == 2)
 
145
                return new CDirectiveAlignFill(list[0],list[1],mode);
 
146
        else
 
147
                return new CDirectiveAlignFill(list[0],mode);
 
148
}
 
149
 
 
150
CAssemblerCommand* parseDirectiveHeaderSize(Parser& parser, int flags)
 
151
{
 
152
        const Token& start = parser.peekToken();
 
153
 
 
154
        std::vector<Expression> list;
 
155
        if (parser.parseExpressionList(list,1,1) == false)
 
156
                return nullptr;
 
157
 
 
158
        u64 size;
 
159
        if (list[0].evaluateInteger(size) == false)
 
160
        {
 
161
                parser.printError(start,L"Invalid header size");
 
162
                return nullptr;
 
163
        }
 
164
 
 
165
        return new CDirectiveHeaderSize(size);
 
166
}
 
167
 
 
168
CAssemblerCommand* parseDirectiveObjImport(Parser& parser, int flags)
 
169
{
 
170
        std::vector<Expression> list;
 
171
        if (parser.parseExpressionList(list,1,2) == false)
 
172
                return nullptr;
 
173
 
 
174
        std::wstring fileName;
 
175
        if (list[0].evaluateString(fileName,true) == false)
 
176
                return nullptr;
 
177
 
 
178
        if (list.size() == 2)
 
179
        {
 
180
                std::wstring ctorName;
 
181
                if (list[1].evaluateIdentifier(ctorName) == false)
 
182
                        return nullptr;
 
183
 
 
184
                return new DirectiveObjImport(fileName,ctorName);
 
185
        }
 
186
        
 
187
        return new DirectiveObjImport(fileName);
 
188
}
 
189
 
 
190
CAssemblerCommand* parseDirectiveConditional(Parser& parser, int flags)
 
191
{
 
192
        ConditionType type;
 
193
        std::wstring name;
 
194
        Expression exp;
 
195
 
 
196
        const Token& start = parser.peekToken();
 
197
        ConditionalResult condResult = ConditionalResult::Unknown;
 
198
        switch (flags)
 
199
        {
 
200
        case DIRECTIVE_COND_IF:
 
201
                type = ConditionType::IF;
 
202
                exp = parser.parseExpression();
 
203
                if (exp.isLoaded() == false)
 
204
                {
 
205
                        parser.printError(start,L"Invalid condition");
 
206
                        return new DummyCommand();
 
207
                }
 
208
 
 
209
                if (exp.isConstExpression())
 
210
                {
 
211
                        ExpressionValue result = exp.evaluate();
 
212
                        if (result.isInt())
 
213
                                condResult = result.intValue != 0 ? ConditionalResult::True : ConditionalResult::False;
 
214
                }
 
215
                break;
 
216
        case DIRECTIVE_COND_IFDEF:
 
217
                type = ConditionType::IFDEF;
 
218
                if (parser.parseIdentifier(name) == false)
 
219
                        return nullptr;         
 
220
                break;
 
221
        case DIRECTIVE_COND_IFNDEF:
 
222
                type = ConditionType::IFNDEF;
 
223
                if (parser.parseIdentifier(name) == false)
 
224
                        return nullptr;
 
225
                break;
 
226
        }
 
227
 
 
228
        parser.pushConditionalResult(condResult);
 
229
        CAssemblerCommand* ifBlock = parser.parseCommandSequence(L'.', {L".else", L".elseif", L".elseifdef", L".elseifndef", L".endif"});
 
230
        parser.popConditionalResult();
 
231
 
 
232
        // update the file info so that else commands get the right line number
 
233
        parser.updateFileInfo();
 
234
 
 
235
        CAssemblerCommand* elseBlock = nullptr;
 
236
        const Token &next = parser.nextToken();
 
237
        const std::wstring stringValue = next.getStringValue();
 
238
 
 
239
        if (stringValue == L".else")
 
240
        {
 
241
                ConditionalResult elseResult = condResult;
 
242
                switch (condResult)
 
243
                {
 
244
                case ConditionalResult::True:
 
245
                        elseResult = ConditionalResult::False;
 
246
                        break;
 
247
                case ConditionalResult::False:
 
248
                        elseResult = ConditionalResult::True;
 
249
                        break;
 
250
                }
 
251
 
 
252
                parser.pushConditionalResult(elseResult);
 
253
                elseBlock = parser.parseCommandSequence(L'.', {L".endif"});
 
254
                parser.popConditionalResult();
 
255
 
 
256
                parser.eatToken();      // eat .endif
 
257
        } else if (stringValue == L".elseif")
 
258
        {
 
259
                elseBlock = parseDirectiveConditional(parser,DIRECTIVE_COND_IF);
 
260
        } else if (stringValue == L".elseifdef")
 
261
        {
 
262
                elseBlock = parseDirectiveConditional(parser,DIRECTIVE_COND_IFDEF);
 
263
        } else if (stringValue == L".elseifndef")
 
264
        {
 
265
                elseBlock = parseDirectiveConditional(parser,DIRECTIVE_COND_IFNDEF);
 
266
        } else if (stringValue != L".endif")
 
267
        {
 
268
                return nullptr;
 
269
        }
 
270
 
 
271
        // for true or false blocks, there's no need to create a conditional command
 
272
        if (condResult == ConditionalResult::True)
 
273
        {
 
274
                delete elseBlock;
 
275
                return ifBlock;
 
276
        } 
 
277
        
 
278
        if (condResult == ConditionalResult::False)
 
279
        {
 
280
                delete ifBlock;
 
281
                if (elseBlock != nullptr)
 
282
                        return elseBlock;
 
283
                else
 
284
                        return new DummyCommand();
 
285
        }
 
286
 
 
287
        CDirectiveConditional* cond;
 
288
        if (exp.isLoaded())
 
289
                cond = new CDirectiveConditional(type,exp);
 
290
        else if (name.size() != 0)
 
291
                cond = new CDirectiveConditional(type,name);
 
292
        else
 
293
                cond = new CDirectiveConditional(type);
 
294
 
 
295
        cond->setContent(ifBlock,elseBlock);
 
296
        return cond;
 
297
}
 
298
 
 
299
CAssemblerCommand* parseDirectiveTable(Parser& parser, int flags)
 
300
{
 
301
        const Token& start = parser.peekToken();
 
302
 
 
303
        std::vector<Expression> list;
 
304
        if (parser.parseExpressionList(list,1,2) == false)
 
305
                return nullptr;
 
306
 
 
307
        std::wstring fileName;
 
308
        if (list[0].evaluateString(fileName,true) == false)
 
309
        {
 
310
                parser.printError(start,L"Invalid file name");
 
311
                return nullptr;
 
312
        }
 
313
 
 
314
        TextFile::Encoding encoding = TextFile::GUESS;
 
315
        if (list.size() == 2)
 
316
        {
 
317
                std::wstring encodingName;
 
318
                if (list[1].evaluateString(encodingName,true) == false)
 
319
                {
 
320
                        parser.printError(start,L"Invalid encoding name");
 
321
                        return nullptr;
 
322
                }
 
323
 
 
324
                encoding = getEncodingFromString(encodingName);
 
325
        }
 
326
 
 
327
        return new TableCommand(fileName,encoding);
 
328
}
 
329
 
 
330
CAssemblerCommand* parseDirectiveData(Parser& parser, int flags)
 
331
{
 
332
        bool terminate = false;
 
333
        if (flags & DIRECTIVE_DATA_TERMINATION)
 
334
        {
 
335
                terminate = true;
 
336
                flags &= ~DIRECTIVE_DATA_TERMINATION;
 
337
        }
 
338
 
 
339
        std::vector<Expression> list;
 
340
        if (parser.parseExpressionList(list,1,-1) == false)
 
341
                return nullptr;
 
342
        
 
343
        CDirectiveData* data = new CDirectiveData();
 
344
        switch (flags & DIRECTIVE_USERMASK)
 
345
        {
 
346
        case DIRECTIVE_DATA_8:
 
347
                data->setNormal(list,1,false);
 
348
                break;
 
349
        case DIRECTIVE_DATA_16:
 
350
                data->setNormal(list,2,false);
 
351
                break;
 
352
        case DIRECTIVE_DATA_32:
 
353
                data->setNormal(list,4,false);
 
354
                break;
 
355
        case DIRECTIVE_DATA_ASCII:
 
356
                data->setNormal(list,1,true);
 
357
                break;
 
358
        case DIRECTIVE_DATA_SJIS:
 
359
                data->setSjis(list,terminate);
 
360
                break;
 
361
        case DIRECTIVE_DATA_CUSTOM:
 
362
                data->setCustom(list,terminate);
 
363
                break;
 
364
        }
 
365
        
 
366
        return data;
 
367
}
 
368
 
 
369
CAssemblerCommand* parseDirectivePsx(Parser& parser, int flags)
 
370
{
 
371
        Arch = &Mips;
 
372
        Mips.SetLoadDelay(false,0);
 
373
        Mips.SetVersion(MARCH_PSX);
 
374
        return new ArchitectureCommand(L".psx",L"");
 
375
}
 
376
 
 
377
CAssemblerCommand* parseDirectivePs2(Parser& parser, int flags)
 
378
{
 
379
        Arch = &Mips;
 
380
        Mips.SetLoadDelay(false,0);
 
381
        Mips.SetVersion(MARCH_PS2);
 
382
        return new ArchitectureCommand(L".ps2",L"");
 
383
}
 
384
 
 
385
CAssemblerCommand* parseDirectivePsp(Parser& parser, int flags)
 
386
{
 
387
        Arch = &Mips;
 
388
        Mips.SetLoadDelay(false,0);
 
389
        Mips.SetVersion(MARCH_PSP);
 
390
        return new ArchitectureCommand(L".psp",L"");
 
391
}
 
392
 
 
393
CAssemblerCommand* parseDirectiveN64(Parser& parser, int flags)
 
394
{
 
395
        Arch = &Mips;
 
396
        Mips.SetLoadDelay(false, 0);
 
397
        Mips.SetVersion(MARCH_N64);
 
398
        return new ArchitectureCommand(L".n64", L"");
 
399
}
 
400
 
 
401
CAssemblerCommand* parseDirectiveArmArch(Parser& parser, int flags)
 
402
{
 
403
        Arch = &Arm;
 
404
 
 
405
        switch (flags)
 
406
        {
 
407
        case DIRECTIVE_ARM_GBA:
 
408
                Arm.SetThumbMode(true);
 
409
                Arm.setVersion(AARCH_GBA);
 
410
                return new ArchitectureCommand(L".gba\n.thumb", L".thumb");
 
411
        case DIRECTIVE_ARM_NDS:
 
412
                Arm.SetThumbMode(false);
 
413
                Arm.setVersion(AARCH_NDS);
 
414
                return new ArchitectureCommand(L".nds\n.arm", L".arm");
 
415
        case DIRECTIVE_ARM_3DS:
 
416
                Arm.SetThumbMode(false);
 
417
                Arm.setVersion(AARCH_3DS);
 
418
                return new ArchitectureCommand(L".3ds\n.arm", L".arm");
 
419
        case DIRECTIVE_ARM_BIG:
 
420
                Arm.SetThumbMode(false);
 
421
                Arm.setVersion(AARCH_BIG);
 
422
                return new ArchitectureCommand(L".arm.big\n.arm", L".arm");
 
423
        case DIRECTIVE_ARM_LITTLE:
 
424
                Arm.SetThumbMode(false);
 
425
                Arm.setVersion(AARCH_LITTLE);
 
426
                return new ArchitectureCommand(L".arm.little\n.arm", L".arm");
 
427
        }
 
428
 
 
429
        return nullptr;
 
430
}
 
431
 
 
432
CAssemblerCommand* parseDirectiveArea(Parser& parser, int flags)
 
433
{
 
434
        std::vector<Expression> parameters;
 
435
        if (parser.parseExpressionList(parameters,1,2) == false)
 
436
                return nullptr;
 
437
        
 
438
        CDirectiveArea* area = new CDirectiveArea(parameters[0]);
 
439
        if (parameters.size() == 2)
 
440
                area->setFillExpression(parameters[1]);
 
441
 
 
442
        CAssemblerCommand* content = parser.parseCommandSequence(L'.', {L".endarea"});
 
443
        parser.eatToken();
 
444
 
 
445
        area->setContent(content);
 
446
        return area;
 
447
}
 
448
 
 
449
CAssemblerCommand* parseDirectiveErrorWarning(Parser& parser, int flags)
 
450
{
 
451
        const Token &tok = parser.nextToken();
 
452
 
 
453
        if (tok.type != TokenType::Identifier && tok.type != TokenType::String)
 
454
                return nullptr;
 
455
 
 
456
        std::wstring stringValue = tok.getStringValue();
 
457
        std::transform(stringValue.begin(),stringValue.end(),stringValue.begin(),::towlower);
 
458
 
 
459
        if (stringValue == L"on")
 
460
        {       
 
461
                Logger::setErrorOnWarning(true);
 
462
                return new DummyCommand();
 
463
        } else if (stringValue == L"off")
 
464
        {
 
465
                Logger::setErrorOnWarning(false);
 
466
                return new DummyCommand();
 
467
        }
 
468
 
 
469
        return nullptr;
 
470
}
 
471
 
 
472
CAssemblerCommand* parseDirectiveRelativeInclude(Parser& parser, int flags)
 
473
{
 
474
        const Token &tok = parser.nextToken();
 
475
 
 
476
        if (tok.type != TokenType::Identifier && tok.type != TokenType::String)
 
477
                return nullptr;
 
478
 
 
479
        std::wstring stringValue = tok.getStringValue();
 
480
        std::transform(stringValue.begin(),stringValue.end(),stringValue.begin(),::towlower);
 
481
 
 
482
        if (stringValue == L"on")
 
483
        {       
 
484
                Global.relativeInclude = true;
 
485
                return new DummyCommand();
 
486
        } else if (stringValue == L"off")
 
487
        {
 
488
                Global.relativeInclude = false;
 
489
                return new DummyCommand();
 
490
        }
 
491
 
 
492
        return nullptr;
 
493
}
 
494
 
 
495
CAssemblerCommand* parseDirectiveNocash(Parser& parser, int flags)
 
496
{
 
497
        const Token &tok = parser.nextToken();
 
498
 
 
499
        if (tok.type != TokenType::Identifier && tok.type != TokenType::String)
 
500
                return nullptr;
 
501
 
 
502
        std::wstring stringValue = tok.getStringValue();
 
503
        std::transform(stringValue.begin(),stringValue.end(),stringValue.begin(),::towlower);
 
504
 
 
505
        if (stringValue == L"on")
 
506
        {       
 
507
                Global.nocash = true;
 
508
                return new DummyCommand();
 
509
        } else if (stringValue == L"off")
 
510
        {
 
511
                Global.nocash = false;
 
512
                return new DummyCommand();
 
513
        }
 
514
 
 
515
        return nullptr;
 
516
}
 
517
 
 
518
CAssemblerCommand* parseDirectiveSym(Parser& parser, int flags)
 
519
{
 
520
        const Token &tok = parser.nextToken();
 
521
 
 
522
        if (tok.type != TokenType::Identifier && tok.type != TokenType::String)
 
523
                return nullptr;
 
524
 
 
525
        std::wstring stringValue = tok.getStringValue();
 
526
        std::transform(stringValue.begin(),stringValue.end(),stringValue.begin(),::towlower);
 
527
 
 
528
        if (stringValue == L"on")
 
529
                return new CDirectiveSym(true);
 
530
        else if (stringValue == L"off")
 
531
                return new CDirectiveSym(false);
 
532
        else
 
533
                return nullptr;
 
534
}
 
535
 
 
536
CAssemblerCommand* parseDirectiveDefineLabel(Parser& parser, int flags)
 
537
{
 
538
        const Token& tok = parser.nextToken();
 
539
        if (tok.type != TokenType::Identifier)
 
540
                return nullptr;
 
541
 
 
542
        if (parser.nextToken().type != TokenType::Comma)
 
543
                return nullptr;
 
544
 
 
545
        Expression value = parser.parseExpression();
 
546
        if (value.isLoaded() == false)
 
547
                return nullptr;
 
548
 
 
549
        const std::wstring stringValue = tok.getStringValue();
 
550
        if (Global.symbolTable.isValidSymbolName(stringValue) == false)
 
551
        {
 
552
                parser.printError(tok,L"Invalid label name \"%s\"",stringValue);
 
553
                return nullptr;
 
554
        }
 
555
 
 
556
        return new CAssemblerLabel(stringValue,value);
 
557
}
 
558
 
 
559
CAssemblerCommand* parseDirectiveFunction(Parser& parser, int flags)
 
560
{
 
561
        std::vector<Expression> parameters;
 
562
        if (parser.parseExpressionList(parameters,1,1) == false)
 
563
                return nullptr;
 
564
        
 
565
        std::wstring name;
 
566
        if (parameters[0].evaluateIdentifier(name) == false)
 
567
                return nullptr;
 
568
 
 
569
        CDirectiveFunction* func = new CDirectiveFunction(name);
 
570
        CAssemblerCommand* seq = parser.parseCommandSequence(L'.', {L".endfunc",L".endfunction",L".func",L".function"});
 
571
 
 
572
        const std::wstring stringValue = parser.peekToken().getStringValue();
 
573
        if (stringValue == L".endfunc" ||
 
574
                stringValue == L".endfunction")
 
575
        {
 
576
                parser.eatToken();
 
577
        }
 
578
 
 
579
        func->setContent(seq);
 
580
        return func;
 
581
}
 
582
 
 
583
CAssemblerCommand* parseDirectiveMessage(Parser& parser, int flags)
 
584
{
 
585
        Expression exp = parser.parseExpression();
 
586
        
 
587
        switch (flags)
 
588
        {
 
589
        case DIRECTIVE_MSG_WARNING:
 
590
                return new CDirectiveMessage(CDirectiveMessage::Type::Warning,exp);
 
591
        case DIRECTIVE_MSG_ERROR:
 
592
                return new CDirectiveMessage(CDirectiveMessage::Type::Error,exp);
 
593
        case DIRECTIVE_MSG_NOTICE:
 
594
                return new CDirectiveMessage(CDirectiveMessage::Type::Notice,exp);
 
595
        }
 
596
 
 
597
        return nullptr;
 
598
}
 
599
 
 
600
CAssemblerCommand* parseDirectiveInclude(Parser& parser, int flags)
 
601
{
 
602
        const Token& start = parser.peekToken();
 
603
 
 
604
        std::vector<Expression> parameters;
 
605
        if (parser.parseExpressionList(parameters,1,2) == false)
 
606
                return nullptr;
 
607
 
 
608
        std::wstring fileName;
 
609
        if (parameters[0].evaluateString(fileName,true) == false)
 
610
                return nullptr;
 
611
 
 
612
        fileName = getFullPathName(fileName);
 
613
 
 
614
        TextFile::Encoding encoding = TextFile::GUESS;
 
615
        if (parameters.size() == 2)
 
616
        {
 
617
                std::wstring encodingName;
 
618
                if (parameters[1].evaluateString(encodingName,true) == false
 
619
                        && parameters[1].evaluateIdentifier(encodingName) == false)
 
620
                        return nullptr;
 
621
                
 
622
                encoding = getEncodingFromString(encodingName);
 
623
        }
 
624
 
 
625
        // don't include the file if it's inside a false block
 
626
        if (parser.isInsideTrueBlock() == false)
 
627
                return new DummyCommand();
 
628
 
 
629
        if (fileExists(fileName) == false)
 
630
        {
 
631
                parser.printError(start,L"Included file \"%s\" does not exist",fileName);
 
632
                return nullptr;
 
633
        }
 
634
 
 
635
        TextFile f;
 
636
        if (f.open(fileName,TextFile::Read,encoding) == false)
 
637
        {
 
638
                parser.printError(start,L"Could not open included file \"%s\"",fileName);
 
639
                return nullptr;
 
640
        }
 
641
 
 
642
        return parser.parseFile(f);
 
643
}
 
644
 
 
645
const DirectiveMap directives = {
 
646
        { L".open",                             { &parseDirectiveOpen,                          DIRECTIVE_NOTINMEMORY } },
 
647
        { L".openfile",                 { &parseDirectiveOpen,                          DIRECTIVE_NOTINMEMORY } },
 
648
        { L".create",                   { &parseDirectiveCreate,                        DIRECTIVE_NOTINMEMORY } },
 
649
        { L".createfile",               { &parseDirectiveCreate,                        DIRECTIVE_NOTINMEMORY } },
 
650
        { L".close",                    { &parseDirectiveClose,                         DIRECTIVE_NOTINMEMORY } },
 
651
        { L".closefile",                { &parseDirectiveClose,                         DIRECTIVE_NOTINMEMORY } },
 
652
        { L".incbin",                   { &parseDirectiveIncbin,                        0 } },
 
653
        { L".import",                   { &parseDirectiveIncbin,                        0 } },
 
654
        { L".org",                              { &parseDirectivePosition,                      DIRECTIVE_POS_VIRTUAL } },
 
655
        { L"org",                               { &parseDirectivePosition,                      DIRECTIVE_POS_VIRTUAL } },
 
656
        { L".orga",                             { &parseDirectivePosition,                      DIRECTIVE_POS_PHYSICAL } },
 
657
        { L"orga",                              { &parseDirectivePosition,                      DIRECTIVE_POS_PHYSICAL } },
 
658
        { L".align",                    { &parseDirectiveAlignFill,                     DIRECTIVE_FILE_ALIGN } },
 
659
        { L".fill",                             { &parseDirectiveAlignFill,                     DIRECTIVE_FILE_FILL } },
 
660
        { L"defs",                              { &parseDirectiveAlignFill,                     DIRECTIVE_FILE_FILL } },
 
661
        { L".headersize",               { &parseDirectiveHeaderSize,            0 } },
 
662
 
 
663
        { L".if",                               { &parseDirectiveConditional,           DIRECTIVE_COND_IF } },
 
664
        { L".ifdef",                    { &parseDirectiveConditional,           DIRECTIVE_COND_IFDEF } },
 
665
        { L".ifndef",                   { &parseDirectiveConditional,           DIRECTIVE_COND_IFNDEF } },
 
666
 
 
667
        { L".loadtable",                { &parseDirectiveTable,                         0 } },
 
668
        { L".table",                    { &parseDirectiveTable,                         0 } },
 
669
        { L".byte",                             { &parseDirectiveData,                          DIRECTIVE_DATA_8 } },
 
670
        { L".halfword",                 { &parseDirectiveData,                          DIRECTIVE_DATA_16 } },
 
671
        { L".word",                             { &parseDirectiveData,                          DIRECTIVE_DATA_32 } },
 
672
        { L".db",                               { &parseDirectiveData,                          DIRECTIVE_DATA_8 } },
 
673
        { L".dh",                               { &parseDirectiveData,                          DIRECTIVE_DATA_16|DIRECTIVE_NOCASHOFF } },
 
674
        { L".dw",                               { &parseDirectiveData,                          DIRECTIVE_DATA_32|DIRECTIVE_NOCASHOFF } },
 
675
        { L".dw",                               { &parseDirectiveData,                          DIRECTIVE_DATA_16|DIRECTIVE_NOCASHON } },
 
676
        { L".dd",                               { &parseDirectiveData,                          DIRECTIVE_DATA_32|DIRECTIVE_NOCASHON } },
 
677
        { L".dcb",                              { &parseDirectiveData,                          DIRECTIVE_DATA_8 } },
 
678
        { L".dcw",                              { &parseDirectiveData,                          DIRECTIVE_DATA_16 } },
 
679
        { L".dcd",                              { &parseDirectiveData,                          DIRECTIVE_DATA_32 } },
 
680
        { L"db",                                { &parseDirectiveData,                          DIRECTIVE_DATA_8 } },
 
681
        { L"dh",                                { &parseDirectiveData,                          DIRECTIVE_DATA_16|DIRECTIVE_NOCASHOFF } },
 
682
        { L"dw",                                { &parseDirectiveData,                          DIRECTIVE_DATA_32|DIRECTIVE_NOCASHOFF } },
 
683
        { L"dw",                                { &parseDirectiveData,                          DIRECTIVE_DATA_16|DIRECTIVE_NOCASHON } },
 
684
        { L"dd",                                { &parseDirectiveData,                          DIRECTIVE_DATA_32|DIRECTIVE_NOCASHON } },
 
685
        { L"dcb",                               { &parseDirectiveData,                          DIRECTIVE_DATA_8 } },
 
686
        { L"dcw",                               { &parseDirectiveData,                          DIRECTIVE_DATA_16 } },
 
687
        { L"dcd",                               { &parseDirectiveData,                          DIRECTIVE_DATA_32 } },
 
688
        { L".ascii",                    { &parseDirectiveData,                          DIRECTIVE_DATA_ASCII } },
 
689
        { L".string",                   { &parseDirectiveData,                          DIRECTIVE_DATA_CUSTOM|DIRECTIVE_DATA_TERMINATION } },
 
690
        { L".str",                              { &parseDirectiveData,                          DIRECTIVE_DATA_CUSTOM|DIRECTIVE_DATA_TERMINATION } },
 
691
        { L".stringn",                  { &parseDirectiveData,                          DIRECTIVE_DATA_CUSTOM } },
 
692
        { L".strn",                             { &parseDirectiveData,                          DIRECTIVE_DATA_CUSTOM } },
 
693
        { L".sjis",                             { &parseDirectiveData,                          DIRECTIVE_DATA_SJIS|DIRECTIVE_DATA_TERMINATION } },
 
694
        { L".sjisn",                    { &parseDirectiveData,                          DIRECTIVE_DATA_SJIS } },
 
695
 
 
696
        { L".psx",                              { &parseDirectivePsx,                           0 } },
 
697
        { L".ps2",                              { &parseDirectivePs2,                           0 } },
 
698
        { L".psp",                              { &parseDirectivePsp,                           0 } },
 
699
        { L".n64",                              { &parseDirectiveN64,                           0 } },
 
700
 
 
701
        { L".gba",                              { &parseDirectiveArmArch,                       DIRECTIVE_ARM_GBA } },
 
702
        { L".nds",                              { &parseDirectiveArmArch,                       DIRECTIVE_ARM_NDS } },
 
703
        { L".3ds",                              { &parseDirectiveArmArch,                       DIRECTIVE_ARM_3DS } },
 
704
        { L".arm.big",                  { &parseDirectiveArmArch,                       DIRECTIVE_ARM_BIG } },
 
705
        { L".arm.little",               { &parseDirectiveArmArch,                       DIRECTIVE_ARM_LITTLE } },
 
706
        
 
707
        { L".area",                             { &parseDirectiveArea,                          0 } },
 
708
 
 
709
        { L".importobj",                { &parseDirectiveObjImport,                     0 } },
 
710
        { L".importlib",                { &parseDirectiveObjImport,                     0 } },
 
711
 
 
712
        { L".erroronwarning",   { &parseDirectiveErrorWarning,          0 } },
 
713
        { L".relativeinclude",  { &parseDirectiveRelativeInclude,       0 } },
 
714
        { L".nocash",                   { &parseDirectiveNocash,                        0 } },
 
715
        { L".sym",                              { &parseDirectiveSym,                           0 } },
 
716
        
 
717
        { L".definelabel",              { &parseDirectiveDefineLabel,           0 } },
 
718
        { L".function",                 { &parseDirectiveFunction,                      0 } },
 
719
        { L".func",                             { &parseDirectiveFunction,                      0 } },
 
720
        
 
721
        { L".warning",                  { &parseDirectiveMessage,                       DIRECTIVE_MSG_WARNING } },
 
722
        { L".error",                    { &parseDirectiveMessage,                       DIRECTIVE_MSG_ERROR } },
 
723
        { L".notice",                   { &parseDirectiveMessage,                       DIRECTIVE_MSG_NOTICE } },
 
724
 
 
725
        { L".include",                  { &parseDirectiveInclude,                       0 } },
 
726
};