src/Parser.cc

changeset 107
55c2bcd8ed5c
parent 106
9174be9ac686
child 108
6409ece8297c
equal deleted inserted replaced
106:9174be9ac686 107:55c2bcd8ed5c
176 176
177 case tkFuncdef: 177 case tkFuncdef:
178 ParseFuncdef(); 178 ParseFuncdef();
179 break; 179 break;
180 180
181 case tkSemicolon:
182 break;
183
181 default: 184 default:
182 { 185 {
183 // Check for labels 186 // Check for labels
184 Lexer::Token next; 187 Lexer::Token next;
185 188
204 // If nothing else, parse it as a statement 207 // If nothing else, parse it as a statement
205 mLexer->Skip (-1); 208 mLexer->Skip (-1);
206 DataBuffer* b = ParseStatement(); 209 DataBuffer* b = ParseStatement();
207 210
208 if (b == false) 211 if (b == false)
212 {
213 mLexer->GetNext();
209 Error ("unknown token `%1`", GetTokenString()); 214 Error ("unknown token `%1`", GetTokenString());
215 }
210 216
211 buffer()->MergeAndDestroy (b); 217 buffer()->MergeAndDestroy (b);
212 mLexer->MustGetNext (tkSemicolon); 218 mLexer->MustGetNext (tkSemicolon);
219 break;
213 } 220 }
214 break;
215 } 221 }
216 } 222 }
217 223
218 // =============================================================================== 224 // ===============================================================================
219 // Script file ended. Do some last checks and write the last things to main buffer 225 // Script file ended. Do some last checks and write the last things to main buffer
326 // 332 //
327 void BotscriptParser::ParseVar() 333 void BotscriptParser::ParseVar()
328 { 334 {
329 Variable* var = new Variable; 335 Variable* var = new Variable;
330 var->origin = mLexer->DescribeCurrentPosition(); 336 var->origin = mLexer->DescribeCurrentPosition();
337 var->isarray = false;
331 const bool isconst = mLexer->GetNext (tkConst); 338 const bool isconst = mLexer->GetNext (tkConst);
332 mLexer->MustGetAnyOf ({tkInt, tkStr, tkVoid}); 339 mLexer->MustGetAnyOf ({tkInt, tkStr, tkVoid});
333 340
334 EType vartype = (TokenIs (tkInt)) ? EIntType : 341 EType vartype = (TokenIs (tkInt)) ? EIntType :
335 (TokenIs (tkStr)) ? EStringType : 342 (TokenIs (tkStr)) ? EStringType :
336 EBoolType; 343 EBoolType;
337 344
338 mLexer->MustGetNext (tkSymbol); 345 mLexer->MustGetNext (tkSymbol);
339 String name = GetTokenString(); 346 String name = GetTokenString();
347
348 if (mLexer->GetNext (tkBracketStart))
349 {
350 mLexer->MustGetNext (tkBracketEnd);
351 var->isarray = true;
352
353 if (isconst)
354 Error ("arrays cannot be const");
355 }
340 356
341 for (Variable* var : SCOPE(0).globalVariables + SCOPE(0).localVariables) 357 for (Variable* var : SCOPE(0).globalVariables + SCOPE(0).localVariables)
342 { 358 {
343 if (var->name == name) 359 if (var->name == name)
344 Error ("Variable $%1 is already declared on this scope; declared at %2", 360 Error ("Variable $%1 is already declared on this scope; declared at %2",
366 var->value = expr.GetResult()->GetValue(); 382 var->value = expr.GetResult()->GetValue();
367 } 383 }
368 else 384 else
369 { 385 {
370 // TODO: might need a VM-wise oninit for this... 386 // TODO: might need a VM-wise oninit for this...
371 Error ("const variables must be constexpr for now"); 387 Error ("const variables must be constexpr");
372 } 388 }
373 } 389 }
374 390
375 // Assign an index for the variable if it is not constexpr. Constexpr 391 // Assign an index for the variable if it is not constexpr. Constexpr
376 // variables can simply be substituted out for their value when used 392 // variables can simply be substituted out for their value when used
987 if (curarg < comm->minargs) 1003 if (curarg < comm->minargs)
988 Error ("too few arguments passed to %1\n\tusage is: %2", 1004 Error ("too few arguments passed to %1\n\tusage is: %2",
989 comm->name, comm->GetSignature()); 1005 comm->name, comm->GetSignature());
990 1006
991 break; 1007 break;
992 curarg++;
993 } 1008 }
994 1009
995 if (curarg >= comm->args.Size()) 1010 if (curarg >= comm->args.Size())
996 Error ("too many arguments passed to %1\n\tusage is: %2", 1011 Error ("too many arguments (%3) passed to %1\n\tusage is: %2",
997 comm->name, comm->GetSignature()); 1012 comm->name, comm->GetSignature());
998 1013
999 r->MergeAndDestroy (ParseExpression (comm->args[curarg].type, true)); 1014 r->MergeAndDestroy (ParseExpression (comm->args[curarg].type, true));
1000 mLexer->MustGetNext (tkAny); 1015 mLexer->MustGetNext (tkAny);
1001 1016
1094 return (EAssignmentOperator) 0; 1109 return (EAssignmentOperator) 0;
1095 } 1110 }
1096 1111
1097 // ============================================================================ 1112 // ============================================================================
1098 // 1113 //
1114 struct AssignmentDataHeaderInfo
1115 {
1116 EAssignmentOperator op;
1117 EDataHeader local;
1118 EDataHeader global;
1119 EDataHeader array;
1120 };
1121
1122 const AssignmentDataHeaderInfo gAssignmentDataHeaders[] =
1123 {
1124 { EAssign, dhAssignLocalVar, dhAssignGlobalVar, dhAssignGlobalArray },
1125 { EAssignAdd, dhAddLocalVar, dhAddGlobalVar, dhAddGlobalArray },
1126 { EAssignSub, dhSubtractLocalVar, dhSubtractGlobalVar, dhSubtractGlobalArray },
1127 { EAssignMul, dhMultiplyLocalVar, dhMultiplyGlobalVar, dhMultiplyGlobalArray },
1128 { EAssignDiv, dhDivideLocalVar, dhDivideGlobalVar, dhDivideGlobalArray },
1129 { EAssignMod, dhModLocalVar, dhModGlobalVar, dhModGlobalArray },
1130 { EAssignIncrement, dhIncreaseLocalVar, dhIncreaseGlobalVar, dhIncreaseGlobalArray },
1131 { EAssignDecrement, dhDecreaseLocalVar, dhDecreaseGlobalVar, dhDecreaseGlobalArray },
1132 };
1133
1099 EDataHeader BotscriptParser::GetAssigmentDataHeader (EAssignmentOperator op, Variable* var) 1134 EDataHeader BotscriptParser::GetAssigmentDataHeader (EAssignmentOperator op, Variable* var)
1100 { 1135 {
1101 if (var->IsGlobal()) 1136 for (const auto& a : gAssignmentDataHeaders)
1102 { 1137 {
1103 switch (op) 1138 if (a.op != op)
1104 { 1139 continue;
1105 case EAssign: return dhAssignGlobalVar; 1140
1106 case EAssignAdd: return dhAddGlobalVar; 1141 if (var->isarray)
1107 case EAssignSub: return dhSubtractGlobalVar; 1142 return a.array;
1108 case EAssignMul: return dhMultiplyGlobalVar; 1143
1109 case EAssignDiv: return dhDivideGlobalVar; 1144 if (var->IsGlobal())
1110 case EAssignMod: return dhModGlobalVar; 1145 return a.global;
1111 case EAssignIncrement: return dhIncreaseGlobalVar; 1146
1112 case EAssignDecrement: return dhDecreaseGlobalVar; 1147 return a.local;
1113 } 1148 }
1114 } 1149
1115 1150 Error ("WTF: couldn't find data header for operator #%1", op);
1116 switch (op)
1117 {
1118 case EAssign: return dhAssignLocalVar;
1119 case EAssignAdd: return dhAddLocalVar;
1120 case EAssignSub: return dhSubtractLocalVar;
1121 case EAssignMul: return dhMultiplyLocalVar;
1122 case EAssignDiv: return dhDivideLocalVar;
1123 case EAssignMod: return dhModLocalVar;
1124 case EAssignIncrement: return dhIncreaseLocalVar;
1125 case EAssignDecrement: return dhDecreaseLocalVar;
1126 }
1127
1128 assert (false);
1129 return (EDataHeader) 0; 1151 return (EDataHeader) 0;
1130 } 1152 }
1131 1153
1132 // ============================================================================ 1154 // ============================================================================
1133 // 1155 //
1135 // by an assignment operator, followed by an expression value. Expects current 1157 // by an assignment operator, followed by an expression value. Expects current
1136 // token to be the name of the variable, and expects the variable to be given. 1158 // token to be the name of the variable, and expects the variable to be given.
1137 // 1159 //
1138 DataBuffer* BotscriptParser::ParseAssignment (Variable* var) 1160 DataBuffer* BotscriptParser::ParseAssignment (Variable* var)
1139 { 1161 {
1162 DataBuffer* retbuf = new DataBuffer;
1163 DataBuffer* arrayindex = null;
1164
1140 if (var->writelevel != Variable::WRITE_Mutable) 1165 if (var->writelevel != Variable::WRITE_Mutable)
1141 {
1142 Error ("cannot alter read-only variable $%1", var->name); 1166 Error ("cannot alter read-only variable $%1", var->name);
1167
1168 if (var->isarray)
1169 {
1170 mLexer->MustGetNext (tkBracketStart);
1171 Expression expr (this, mLexer, EIntType);
1172 expr.GetResult()->ConvertToBuffer();
1173 arrayindex = expr.GetResult()->GetBuffer()->Clone();
1174 mLexer->MustGetNext (tkBracketEnd);
1143 } 1175 }
1144 1176
1145 // Get an operator 1177 // Get an operator
1146 EAssignmentOperator oper = ParseAssignmentOperator(); 1178 EAssignmentOperator oper = ParseAssignmentOperator();
1147 DataBuffer* retbuf = new DataBuffer;
1148 1179
1149 if (mCurrentMode == ETopLevelMode) 1180 if (mCurrentMode == ETopLevelMode)
1150 Error ("can't alter variables at top level"); 1181 Error ("can't alter variables at top level");
1151 1182
1152 // Parse the right operand 1183 // Parse the right operand
1153 if (oper != EAssignIncrement && oper != EAssignDecrement) 1184 if (oper != EAssignIncrement && oper != EAssignDecrement)
1154 { 1185 {
1155 DataBuffer* expr = ParseExpression (var->type); 1186 DataBuffer* expr = ParseExpression (var->type);
1156 retbuf->MergeAndDestroy (expr); 1187 retbuf->MergeAndDestroy (expr);
1157 } 1188 }
1189
1190 if (var->isarray)
1191 retbuf->MergeAndDestroy (arrayindex);
1158 1192
1159 #if 0 1193 #if 0
1160 // <<= and >>= do not have data headers. Solution: expand them. 1194 // <<= and >>= do not have data headers. Solution: expand them.
1161 // a <<= b -> a = a << b 1195 // a <<= b -> a = a << b
1162 // a >>= b -> a = a >> b 1196 // a >>= b -> a = a >> b

mercurial