src/Parser.cc

changeset 106
9174be9ac686
parent 105
6dbac3305614
child 107
55c2bcd8ed5c
equal deleted inserted replaced
105:6dbac3305614 106:9174be9ac686
49 mNumEvents (0), 49 mNumEvents (0),
50 mCurrentMode (ETopLevelMode), 50 mCurrentMode (ETopLevelMode),
51 mStateSpawnDefined (false), 51 mStateSpawnDefined (false),
52 mGotMainLoop (false), 52 mGotMainLoop (false),
53 mScopeCursor (-1), 53 mScopeCursor (-1),
54 mCanElse (false) {} 54 mCanElse (false),
55 mHighestGlobalVarIndex (0),
56 mHighestStateVarIndex (0) {}
55 57
56 // ============================================================================ 58 // ============================================================================
57 // 59 //
58 BotscriptParser::~BotscriptParser() 60 BotscriptParser::~BotscriptParser()
59 { 61 {
75 if (mCurrentMode == ETopLevelMode) 77 if (mCurrentMode == ETopLevelMode)
76 Error ("%1-statements must not be defined at top level!", GetTokenString()); 78 Error ("%1-statements must not be defined at top level!", GetTokenString());
77 } 79 }
78 80
79 // ============================================================================ 81 // ============================================================================
80 // Main Parser code. Begins read of the script file, checks the syntax of it 82 //
83 // Main compiler code. Begins read of the script file, checks the syntax of it
81 // and writes the data to the object file via Objwriter - which also takes care 84 // and writes the data to the object file via Objwriter - which also takes care
82 // of necessary buffering so stuff is written in the correct order. 85 // of necessary buffering so stuff is written in the correct order.
86 //
83 void BotscriptParser::ParseBotscript (String fileName) 87 void BotscriptParser::ParseBotscript (String fileName)
84 { 88 {
85 // Lex and preprocess the file 89 // Lex and preprocess the file
86 mLexer->ProcessFile (fileName); 90 mLexer->ProcessFile (fileName);
87 PushScope(); 91 PushScope();
323 void BotscriptParser::ParseVar() 327 void BotscriptParser::ParseVar()
324 { 328 {
325 Variable* var = new Variable; 329 Variable* var = new Variable;
326 var->origin = mLexer->DescribeCurrentPosition(); 330 var->origin = mLexer->DescribeCurrentPosition();
327 const bool isconst = mLexer->GetNext (tkConst); 331 const bool isconst = mLexer->GetNext (tkConst);
328 const bool isglobal = true;
329 mLexer->MustGetAnyOf ({tkInt, tkStr, tkVoid}); 332 mLexer->MustGetAnyOf ({tkInt, tkStr, tkVoid});
330 333
331 EType vartype = (TokenIs (tkInt)) ? EIntType : 334 EType vartype = (TokenIs (tkInt)) ? EIntType :
332 (TokenIs (tkStr)) ? EStringType : 335 (TokenIs (tkStr)) ? EStringType :
333 EBoolType; 336 EBoolType;
334 337
335 mLexer->MustGetNext (tkSymbol); 338 mLexer->MustGetNext (tkSymbol);
336 String name = GetTokenString(); 339 String name = GetTokenString();
337
338 /*
339 * TODO
340 if (isglobal && mScopeStack[0].globalVariables.Size() >= gMaxGlobalVars)
341 Error ("too many global variables!");
342 */
343 340
344 for (Variable* var : SCOPE(0).globalVariables + SCOPE(0).localVariables) 341 for (Variable* var : SCOPE(0).globalVariables + SCOPE(0).localVariables)
345 { 342 {
346 if (var->name == name) 343 if (var->name == name)
347 Error ("Variable $%1 is already declared on this scope; declared at %2", 344 Error ("Variable $%1 is already declared on this scope; declared at %2",
393 if (IsInGlobalState()) 390 if (IsInGlobalState())
394 SCOPE(0).globalVariables << var; 391 SCOPE(0).globalVariables << var;
395 else 392 else
396 SCOPE(0).localVariables << var; 393 SCOPE(0).localVariables << var;
397 394
395 SuggestHighestVarIndex (IsInGlobalState(), var->index);
398 mLexer->MustGetNext (tkSemicolon); 396 mLexer->MustGetNext (tkSemicolon);
399 Print ("Declared %3 variable #%1 $%2\n", var->index, var->name, IsInGlobalState() ? "global" : "state-local"); 397 Print ("Declared %3 variable #%1 $%2\n", var->index, var->name, IsInGlobalState() ? "global" : "state-local");
400 } 398 }
401 399
402 // ============================================================================ 400 // ============================================================================
1357 // 1355 //
1358 // Write the compiled bytecode to a file 1356 // Write the compiled bytecode to a file
1359 // 1357 //
1360 void BotscriptParser::WriteToFile (String outfile) 1358 void BotscriptParser::WriteToFile (String outfile)
1361 { 1359 {
1362 FILE* fp = fopen (outfile, "w"); 1360 FILE* fp = fopen (outfile, "wb");
1363 1361
1364 if (fp == null) 1362 if (fp == null)
1365 Error ("couldn't open %1 for writing: %2", outfile, strerror (errno)); 1363 Error ("couldn't open %1 for writing: %2", outfile, strerror (errno));
1366 1364
1367 // First, resolve references 1365 // First, resolve references
1400 // 1398 //
1401 bool BotscriptParser::IsInGlobalState() const 1399 bool BotscriptParser::IsInGlobalState() const
1402 { 1400 {
1403 return mCurrentState.IsEmpty(); 1401 return mCurrentState.IsEmpty();
1404 } 1402 }
1403
1404 // ============================================================================
1405 //
1406 void BotscriptParser::SuggestHighestVarIndex (bool global, int index)
1407 {
1408 if (global)
1409 mHighestGlobalVarIndex = max (mHighestGlobalVarIndex, index);
1410 else
1411 mHighestStateVarIndex = max (mHighestStateVarIndex, index);
1412 }
1413
1414 // ============================================================================
1415 //
1416 int BotscriptParser::GetHighestVarIndex (bool global)
1417 {
1418 if (global)
1419 return mHighestGlobalVarIndex;
1420
1421 return mHighestStateVarIndex;
1422 }

mercurial