src/Parser.cc

changeset 112
def56932f938
parent 111
87d9ebd3ef34
child 114
6cbeb9f8350f
equal deleted inserted replaced
111:87d9ebd3ef34 112:def56932f938
38 #define SCOPE(n) (mScopeStack[mScopeCursor - n]) 38 #define SCOPE(n) (mScopeStack[mScopeCursor - n])
39 39
40 // ============================================================================ 40 // ============================================================================
41 // 41 //
42 BotscriptParser::BotscriptParser() : 42 BotscriptParser::BotscriptParser() :
43 mReadOnly (false), 43 mIsReadOnly (false),
44 mMainBuffer (new DataBuffer), 44 mMainBuffer (new DataBuffer),
45 mOnEnterBuffer (new DataBuffer), 45 mOnEnterBuffer (new DataBuffer),
46 mMainLoopBuffer (new DataBuffer), 46 mMainLoopBuffer (new DataBuffer),
47 mLexer (new Lexer), 47 mLexer (new Lexer),
48 mNumStates (0), 48 mNumStates (0),
88 { 88 {
89 // Lex and preprocess the file 89 // Lex and preprocess the file
90 mLexer->ProcessFile (fileName); 90 mLexer->ProcessFile (fileName);
91 PushScope(); 91 PushScope();
92 92
93 while (mLexer->GetNext()) 93 while (mLexer->Next())
94 { 94 {
95 // Check if else is potentically valid 95 // Check if else is potentically valid
96 if (TokenIs (TK_Else) && mCanElse == false) 96 if (TokenIs (TK_Else) && mCanElse == false)
97 Error ("else without preceding if"); 97 Error ("else without preceding if");
98 98
99 if (TokenIs (TK_Else) == false) 99 if (TokenIs (TK_Else) == false)
100 mCanElse = false; 100 mCanElse = false;
101 101
102 switch (mLexer->GetToken()->type) 102 switch (mLexer->Token()->type)
103 { 103 {
104 case TK_State: 104 case TK_State:
105 ParseStateBlock(); 105 ParseStateBlock();
106 break; 106 break;
107 107
193 mLexer->Skip (-1); 193 mLexer->Skip (-1);
194 DataBuffer* b = ParseStatement(); 194 DataBuffer* b = ParseStatement();
195 195
196 if (b == false) 196 if (b == false)
197 { 197 {
198 mLexer->GetNext(); 198 mLexer->Next();
199 Error ("unknown token `%1`", GetTokenString()); 199 Error ("unknown token `%1`", GetTokenString());
200 } 200 }
201 201
202 buffer()->MergeAndDestroy (b); 202 buffer()->MergeAndDestroy (b);
203 mLexer->MustGetNext (TK_Semicolon); 203 mLexer->MustGetNext (TK_Semicolon);
307 void BotscriptParser::ParseVar() 307 void BotscriptParser::ParseVar()
308 { 308 {
309 Variable* var = new Variable; 309 Variable* var = new Variable;
310 var->origin = mLexer->DescribeCurrentPosition(); 310 var->origin = mLexer->DescribeCurrentPosition();
311 var->isarray = false; 311 var->isarray = false;
312 const bool isconst = mLexer->GetNext (TK_Const); 312 const bool isconst = mLexer->Next (TK_Const);
313 mLexer->MustGetAnyOf ({TK_Int,TK_Str,TK_Void}); 313 mLexer->MustGetAnyOf ({TK_Int,TK_Str,TK_Void});
314 314
315 DataType vartype = (TokenIs (TK_Int)) ? TYPE_Int : 315 DataType vartype = (TokenIs (TK_Int)) ? TYPE_Int :
316 (TokenIs (TK_Str)) ? TYPE_String : 316 (TokenIs (TK_Str)) ? TYPE_String :
317 TYPE_Bool; 317 TYPE_Bool;
318 318
319 mLexer->MustGetNext (TK_Symbol); 319 mLexer->MustGetNext (TK_Symbol);
320 String name = GetTokenString(); 320 String name = GetTokenString();
321 321
322 if (mLexer->GetNext (TK_BracketStart)) 322 if (mLexer->Next (TK_BracketStart))
323 { 323 {
324 mLexer->MustGetNext (TK_BracketEnd); 324 mLexer->MustGetNext (TK_BracketEnd);
325 var->isarray = true; 325 var->isarray = true;
326 326
327 if (isconst) 327 if (isconst)
348 mLexer->MustGetNext (TK_Assign); 348 mLexer->MustGetNext (TK_Assign);
349 Expression expr (this, mLexer, vartype); 349 Expression expr (this, mLexer, vartype);
350 350
351 // If the expression was constexpr, we know its value and thus 351 // If the expression was constexpr, we know its value and thus
352 // can store it in the variable. 352 // can store it in the variable.
353 if (expr.GetResult()->IsConstexpr()) 353 if (expr.Result()->IsConstexpr())
354 { 354 {
355 var->writelevel = WRITE_Constexpr; 355 var->writelevel = WRITE_Constexpr;
356 var->value = expr.GetResult()->GetValue(); 356 var->value = expr.Result()->Value();
357 } 357 }
358 else 358 else
359 { 359 {
360 // TODO: might need a VM-wise oninit for this... 360 // TODO: might need a VM-wise oninit for this...
361 Error ("const variables must be constexpr"); 361 Error ("const variables must be constexpr");
575 Error ("case label outside switch"); 575 Error ("case label outside switch");
576 576
577 // Get a literal value for the case block. Zandronum does not support 577 // Get a literal value for the case block. Zandronum does not support
578 // expressions here. 578 // expressions here.
579 mLexer->MustGetNext (TK_Number); 579 mLexer->MustGetNext (TK_Number);
580 int num = mLexer->GetToken()->text.ToLong(); 580 int num = mLexer->Token()->text.ToLong();
581 mLexer->MustGetNext (TK_Colon); 581 mLexer->MustGetNext (TK_Colon);
582 582
583 for (const CaseInfo& info : SCOPE(0).cases) 583 for (const CaseInfo& info : SCOPE(0).cases)
584 if (info.number == num) 584 if (info.number == num)
585 Error ("multiple case %1 labels in one switch", num); 585 Error ("multiple case %1 labels in one switch", num);
805 // Data header must be written before mode is changed because 805 // Data header must be written before mode is changed because
806 // onenter and mainloop go into special buffers, and we want 806 // onenter and mainloop go into special buffers, and we want
807 // the closing data headers into said buffers too. 807 // the closing data headers into said buffers too.
808 buffer()->WriteDWord (dataheader); 808 buffer()->WriteDWord (dataheader);
809 mCurrentMode = PARSERMODE_TopLevel; 809 mCurrentMode = PARSERMODE_TopLevel;
810 mLexer->GetNext (TK_Semicolon); 810 mLexer->Next (TK_Semicolon);
811 } 811 }
812 812
813 // ============================================================================= 813 // =============================================================================
814 // 814 //
815 void BotscriptParser::ParseEventdef() 815 void BotscriptParser::ParseEventdef()
818 818
819 mLexer->MustGetNext (TK_Number); 819 mLexer->MustGetNext (TK_Number);
820 e->number = GetTokenString().ToLong(); 820 e->number = GetTokenString().ToLong();
821 mLexer->MustGetNext (TK_Colon); 821 mLexer->MustGetNext (TK_Colon);
822 mLexer->MustGetNext (TK_Symbol); 822 mLexer->MustGetNext (TK_Symbol);
823 e->name = mLexer->GetToken()->text; 823 e->name = mLexer->Token()->text;
824 mLexer->MustGetNext (TK_ParenStart); 824 mLexer->MustGetNext (TK_ParenStart);
825 mLexer->MustGetNext (TK_ParenEnd); 825 mLexer->MustGetNext (TK_ParenEnd);
826 mLexer->MustGetNext (TK_Semicolon); 826 mLexer->MustGetNext (TK_Semicolon);
827 AddEvent (e); 827 AddEvent (e);
828 } 828 }
834 CommandInfo* comm = new CommandInfo; 834 CommandInfo* comm = new CommandInfo;
835 comm->origin = mLexer->DescribeCurrentPosition(); 835 comm->origin = mLexer->DescribeCurrentPosition();
836 836
837 // Return value 837 // Return value
838 mLexer->MustGetAnyOf ({TK_Int,TK_Void,TK_Bool,TK_Str}); 838 mLexer->MustGetAnyOf ({TK_Int,TK_Void,TK_Bool,TK_Str});
839 comm->returnvalue = GetTypeByName (mLexer->GetToken()->text); // TODO 839 comm->returnvalue = GetTypeByName (mLexer->Token()->text); // TODO
840 assert (comm->returnvalue != -1); 840 assert (comm->returnvalue != -1);
841 841
842 // Number 842 // Number
843 mLexer->MustGetNext (TK_Number); 843 mLexer->MustGetNext (TK_Number);
844 comm->number = mLexer->GetToken()->text.ToLong(); 844 comm->number = mLexer->Token()->text.ToLong();
845 mLexer->MustGetNext (TK_Colon); 845 mLexer->MustGetNext (TK_Colon);
846 846
847 // Name 847 // Name
848 mLexer->MustGetNext (TK_Symbol); 848 mLexer->MustGetNext (TK_Symbol);
849 comm->name = mLexer->GetToken()->text; 849 comm->name = mLexer->Token()->text;
850 850
851 // Arguments 851 // Arguments
852 mLexer->MustGetNext (TK_ParenStart); 852 mLexer->MustGetNext (TK_ParenStart);
853 comm->minargs = 0; 853 comm->minargs = 0;
854 854
857 if (comm->args.IsEmpty() == false) 857 if (comm->args.IsEmpty() == false)
858 mLexer->MustGetNext (TK_Comma); 858 mLexer->MustGetNext (TK_Comma);
859 859
860 CommandArgument arg; 860 CommandArgument arg;
861 mLexer->MustGetAnyOf ({TK_Int,TK_Bool,TK_Str}); 861 mLexer->MustGetAnyOf ({TK_Int,TK_Bool,TK_Str});
862 DataType type = GetTypeByName (mLexer->GetToken()->text); // TODO 862 DataType type = GetTypeByName (mLexer->Token()->text); // TODO
863 assert (type != -1 && type != TYPE_Void); 863 assert (type != -1 && type != TYPE_Void);
864 arg.type = type; 864 arg.type = type;
865 865
866 mLexer->MustGetNext (TK_Symbol); 866 mLexer->MustGetNext (TK_Symbol);
867 arg.name = mLexer->GetToken()->text; 867 arg.name = mLexer->Token()->text;
868 868
869 // If this is an optional parameter, we need the default value. 869 // If this is an optional parameter, we need the default value.
870 if (comm->minargs < comm->args.Size() || mLexer->PeekNextType (TK_Assign)) 870 if (comm->minargs < comm->args.Size() || mLexer->PeekNextType (TK_Assign))
871 { 871 {
872 mLexer->MustGetNext (TK_Assign); 872 mLexer->MustGetNext (TK_Assign);
884 case TYPE_Unknown: 884 case TYPE_Unknown:
885 case TYPE_Void: 885 case TYPE_Void:
886 break; 886 break;
887 } 887 }
888 888
889 arg.defvalue = mLexer->GetToken()->text.ToLong(); 889 arg.defvalue = mLexer->Token()->text.ToLong();
890 } 890 }
891 else 891 else
892 comm->minargs++; 892 comm->minargs++;
893 893
894 comm->args << arg; 894 comm->args << arg;
973 // 973 //
974 String BotscriptParser::ParseFloat() 974 String BotscriptParser::ParseFloat()
975 { 975 {
976 mLexer->TokenMustBe (TK_Number); 976 mLexer->TokenMustBe (TK_Number);
977 String floatstring = GetTokenString(); 977 String floatstring = GetTokenString();
978 Lexer::Token tok; 978 Lexer::TokenInfo tok;
979 979
980 // Go after the decimal point 980 // Go after the decimal point
981 if (mLexer->PeekNext (&tok) && tok.type ==TK_Dot) 981 if (mLexer->PeekNext (&tok) && tok.type ==TK_Dot)
982 { 982 {
983 mLexer->Skip(); 983 mLexer->Skip();
993 // 993 //
994 // Parses an assignment operator. 994 // Parses an assignment operator.
995 // 995 //
996 AssignmentOperator BotscriptParser::ParseAssignmentOperator() 996 AssignmentOperator BotscriptParser::ParseAssignmentOperator()
997 { 997 {
998 const List<TokenType> tokens = 998 const List<ETokenType> tokens =
999 { 999 {
1000 TK_Assign, 1000 TK_Assign,
1001 TK_AddAssign, 1001 TK_AddAssign,
1002 TK_SubAssign, 1002 TK_SubAssign,
1003 TK_MultiplyAssign, 1003 TK_MultiplyAssign,
1007 TK_DoubleMinus, 1007 TK_DoubleMinus,
1008 }; 1008 };
1009 1009
1010 mLexer->MustGetAnyOf (tokens); 1010 mLexer->MustGetAnyOf (tokens);
1011 1011
1012 switch (mLexer->GetTokenType()) 1012 switch (mLexer->TokenType())
1013 { 1013 {
1014 case TK_Assign: return ASSIGNOP_Assign; 1014 case TK_Assign: return ASSIGNOP_Assign;
1015 case TK_AddAssign: return ASSIGNOP_Add; 1015 case TK_AddAssign: return ASSIGNOP_Add;
1016 case TK_SubAssign: return ASSIGNOP_Subtract; 1016 case TK_SubAssign: return ASSIGNOP_Subtract;
1017 case TK_MultiplyAssign: return ASSIGNOP_Multiply; 1017 case TK_MultiplyAssign: return ASSIGNOP_Multiply;
1084 1084
1085 if (var->isarray) 1085 if (var->isarray)
1086 { 1086 {
1087 mLexer->MustGetNext (TK_BracketStart); 1087 mLexer->MustGetNext (TK_BracketStart);
1088 Expression expr (this, mLexer, TYPE_Int); 1088 Expression expr (this, mLexer, TYPE_Int);
1089 expr.GetResult()->ConvertToBuffer(); 1089 expr.Result()->ConvertToBuffer();
1090 arrayindex = expr.GetResult()->GetBuffer()->Clone(); 1090 arrayindex = expr.Result()->Buffer()->Clone();
1091 mLexer->MustGetNext (TK_BracketEnd); 1091 mLexer->MustGetNext (TK_BracketEnd);
1092 } 1092 }
1093 1093
1094 // Get an operator 1094 // Get an operator
1095 AssignmentOperator oper = ParseAssignmentOperator(); 1095 AssignmentOperator oper = ParseAssignmentOperator();
1167 // hehe 1167 // hehe
1168 if (fromhere == true) 1168 if (fromhere == true)
1169 mLexer->Skip (-1); 1169 mLexer->Skip (-1);
1170 1170
1171 Expression expr (this, mLexer, reqtype); 1171 Expression expr (this, mLexer, reqtype);
1172 expr.GetResult()->ConvertToBuffer(); 1172 expr.Result()->ConvertToBuffer();
1173 1173
1174 // The buffer will be destroyed once the function ends so we need to 1174 // The buffer will be destroyed once the function ends so we need to
1175 // clone it now. 1175 // clone it now.
1176 return expr.GetResult()->GetBuffer()->Clone(); 1176 return expr.Result()->Buffer()->Clone();
1177 } 1177 }
1178 1178
1179 // ============================================================================ 1179 // ============================================================================
1180 // 1180 //
1181 DataBuffer* BotscriptParser::ParseStatement() 1181 DataBuffer* BotscriptParser::ParseStatement()
1182 { 1182 {
1183 // If it's a variable, expect assignment. 1183 // If it's a variable, expect assignment.
1184 if (mLexer->GetNext (TK_DollarSign)) 1184 if (mLexer->Next (TK_DollarSign))
1185 { 1185 {
1186 mLexer->MustGetNext (TK_Symbol); 1186 mLexer->MustGetNext (TK_Symbol);
1187 Variable* var = FindVariable (GetTokenString()); 1187 Variable* var = FindVariable (GetTokenString());
1188 1188
1189 if (var == null) 1189 if (var == null)
1220 info->casecursor++; 1220 info->casecursor++;
1221 } 1221 }
1222 1222
1223 // ============================================================================ 1223 // ============================================================================
1224 // 1224 //
1225 bool BotscriptParser::TokenIs (TokenType a) 1225 bool BotscriptParser::TokenIs (ETokenType a)
1226 { 1226 {
1227 return (mLexer->GetTokenType() == a); 1227 return (mLexer->TokenType() == a);
1228 } 1228 }
1229 1229
1230 // ============================================================================ 1230 // ============================================================================
1231 // 1231 //
1232 String BotscriptParser::GetTokenString() 1232 String BotscriptParser::GetTokenString()
1233 { 1233 {
1234 return mLexer->GetToken()->text; 1234 return mLexer->Token()->text;
1235 } 1235 }
1236 1236
1237 // ============================================================================ 1237 // ============================================================================
1238 // 1238 //
1239 String BotscriptParser::DescribePosition() const 1239 String BotscriptParser::DescribePosition() const
1240 { 1240 {
1241 Lexer::Token* tok = mLexer->GetToken(); 1241 Lexer::TokenInfo* tok = mLexer->Token();
1242 return tok->file + ":" + String (tok->line) + ":" + String (tok->column); 1242 return tok->file + ":" + String (tok->line) + ":" + String (tok->column);
1243 } 1243 }
1244 1244
1245 // ============================================================================ 1245 // ============================================================================
1246 // 1246 //
1312 1312
1313 if (fp == null) 1313 if (fp == null)
1314 Error ("couldn't open %1 for writing: %2", outfile, strerror (errno)); 1314 Error ("couldn't open %1 for writing: %2", outfile, strerror (errno));
1315 1315
1316 // First, resolve references 1316 // First, resolve references
1317 for (MarkReference* ref : mMainBuffer->GetReferences()) 1317 for (MarkReference* ref : mMainBuffer->References())
1318 for (int i = 0; i < 4; ++i) 1318 for (int i = 0; i < 4; ++i)
1319 mMainBuffer->GetBuffer()[ref->pos + i] = (ref->target->pos >> (8 * i)) & 0xFF; 1319 mMainBuffer->Buffer()[ref->pos + i] = (ref->target->pos >> (8 * i)) & 0xFF;
1320 1320
1321 // Then, dump the main buffer to the file 1321 // Then, dump the main buffer to the file
1322 fwrite (mMainBuffer->GetBuffer(), 1, mMainBuffer->GetWrittenSize(), fp); 1322 fwrite (mMainBuffer->Buffer(), 1, mMainBuffer->WrittenSize(), fp);
1323 Print ("-- %1 byte%s1 written to %2\n", mMainBuffer->GetWrittenSize(), outfile); 1323 Print ("-- %1 byte%s1 written to %2\n", mMainBuffer->WrittenSize(), outfile);
1324 fclose (fp); 1324 fclose (fp);
1325 } 1325 }
1326 1326
1327 // ============================================================================ 1327 // ============================================================================
1328 // 1328 //

mercurial