1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** $Id: vc_expr_invoke.cpp 4327 2010-07-24 19:30:53Z firebrand_kh $
11 //**
12 //** Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //** This program is free software; you can redistribute it and/or
15 //** modify it under the terms of the GNU General Public License
16 //** as published by the Free Software Foundation; either version 2
17 //** of the License, or (at your option) any later version.
18 //**
19 //** This program is distributed in the hope that it will be useful,
20 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 //** GNU General Public License for more details.
23 //**
24 //**************************************************************************
25
26 // HEADER FILES ------------------------------------------------------------
27
28 #include "vc_local.h"
29
30 // MACROS ------------------------------------------------------------------
31
32 // TYPES -------------------------------------------------------------------
33
34 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
35
36 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
37
38 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
39
40 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
41
42 // PUBLIC DATA DEFINITIONS -------------------------------------------------
43
44 // PRIVATE DATA DEFINITIONS ------------------------------------------------
45
46 // CODE --------------------------------------------------------------------
47
48 //==========================================================================
49 //
50 // VBaseInvocation::VBaseInvocation
51 //
52 //==========================================================================
53
VBaseInvocation(VName AName,int ANumArgs,VExpression ** AArgs,const TLocation & ALoc)54 VBaseInvocation::VBaseInvocation(VName AName, int ANumArgs, VExpression** AArgs,
55 const TLocation& ALoc)
56 : VExpression(ALoc)
57 , Name(AName)
58 , NumArgs(ANumArgs)
59 {
60 guard(VBaseInvocation::VBaseInvocation);
61 for (int i = 0; i < NumArgs; i++)
62 {
63 Args[i] = AArgs[i];
64 }
65 unguard;
66 }
67
68 //==========================================================================
69 //
70 // VBaseInvocation::~VBaseInvocation
71 //
72 //==========================================================================
73
~VBaseInvocation()74 VBaseInvocation::~VBaseInvocation()
75 {
76 guard(VBaseInvocation::~VBaseInvocation);
77 for (int i = 0; i < NumArgs; i++)
78 {
79 delete Args[i];
80 Args[i] = NULL;
81 }
82 unguard;
83 }
84
85 //==========================================================================
86 //
87 // VBaseInvocation::DoResolve
88 //
89 //==========================================================================
90
DoResolve(VEmitContext & ec)91 VExpression* VBaseInvocation::DoResolve(VEmitContext& ec)
92 {
93 guard(VBaseInvocation::DoResolve);
94 if (!ec.SelfClass)
95 {
96 ParseError(Loc, ":: not in method");
97 delete this;
98 return NULL;
99 }
100 VMethod* Func = ec.SelfClass->ParentClass->FindMethod(Name);
101 if (!Func)
102 {
103 ParseError(Loc, "No such method %s", *Name);
104 delete this;
105 return NULL;
106 }
107
108 VExpression* e = new VInvocation(NULL, Func, NULL, false,
109 true, Loc, NumArgs, Args);
110 NumArgs = 0;
111 delete this;
112 return e->Resolve(ec);
113 unguard;
114 }
115
116 //==========================================================================
117 //
118 // VBaseInvocation::Emit
119 //
120 //==========================================================================
121
Emit(VEmitContext &)122 void VBaseInvocation::Emit(VEmitContext&)
123 {
124 guard(VBaseInvocation::Emit);
125 ParseError(Loc, "Should not happen");
126 unguard;
127 }
128
129 //==========================================================================
130 //
131 // VCastOrInvocation::VCastOrInvocation
132 //
133 //==========================================================================
134
VCastOrInvocation(VName AName,const TLocation & ALoc,int ANumArgs,VExpression ** AArgs)135 VCastOrInvocation::VCastOrInvocation(VName AName, const TLocation& ALoc, int ANumArgs,
136 VExpression** AArgs)
137 : VExpression(ALoc)
138 , Name(AName)
139 , NumArgs(ANumArgs)
140 {
141 for (int i = 0; i < NumArgs; i++)
142 Args[i] = AArgs[i];
143 }
144
145 //==========================================================================
146 //
147 // VCastOrInvocation::~VCastOrInvocation
148 //
149 //==========================================================================
150
~VCastOrInvocation()151 VCastOrInvocation::~VCastOrInvocation()
152 {
153 for (int i = 0; i < NumArgs; i++)
154 {
155 if (Args[i])
156 {
157 delete Args[i];
158 Args[i] = NULL;
159 }
160 }
161 }
162
163 //==========================================================================
164 //
165 // VCastOrInvocation::DoResolve
166 //
167 //==========================================================================
168
DoResolve(VEmitContext & ec)169 VExpression* VCastOrInvocation::DoResolve(VEmitContext& ec)
170 {
171 VClass* Class = VMemberBase::StaticFindClass(Name);
172 if (Class)
173 {
174 if (NumArgs != 1 || !Args[0])
175 {
176 ParseError(Loc, "Dynamic cast requires 1 argument");
177 delete this;
178 return NULL;
179 }
180 VExpression* e = new VDynamicCast(Class, Args[0], Loc);
181 NumArgs = 0;
182 delete this;
183 return e->Resolve(ec);
184 }
185
186 if (ec.SelfClass)
187 {
188 VMethod* M = ec.SelfClass->FindMethod(Name);
189 if (M)
190 {
191 if (M->Flags & FUNC_Iterator)
192 {
193 ParseError(Loc, "Iterator methods can only be used in foreach statements");
194 delete this;
195 return NULL;
196 }
197 VExpression* e = new VInvocation(NULL, M, NULL,
198 false, false, Loc, NumArgs, Args);
199 NumArgs = 0;
200 delete this;
201 return e->Resolve(ec);
202 }
203 VField* field = ec.SelfClass->FindField(Name, Loc, ec.SelfClass);
204 if (field && field->Type.Type == TYPE_Delegate)
205 {
206 VExpression* e = new VInvocation(NULL, field->Func, field,
207 false, false, Loc, NumArgs, Args);
208 NumArgs = 0;
209 delete this;
210 return e->Resolve(ec);
211 }
212 }
213
214 ParseError(Loc, "Unknown method %s", *Name);
215 delete this;
216 return NULL;
217 }
218
219 //==========================================================================
220 //
221 // VCastOrInvocation::ResolveIterator
222 //
223 //==========================================================================
224
ResolveIterator(VEmitContext & ec)225 VExpression* VCastOrInvocation::ResolveIterator(VEmitContext& ec)
226 {
227 VMethod* M = ec.SelfClass->FindMethod(Name);
228 if (!M)
229 {
230 ParseError(Loc, "Unknown method %s", *Name);
231 delete this;
232 return NULL;
233 }
234 if (!(M->Flags & FUNC_Iterator))
235 {
236 ParseError(Loc, "%s is not an iterator method", *Name);
237 delete this;
238 return NULL;
239 }
240
241 VExpression* e = new VInvocation(NULL, M, NULL, false, false, Loc,
242 NumArgs, Args);
243 NumArgs = 0;
244 delete this;
245 return e->Resolve(ec);
246 }
247
248 //==========================================================================
249 //
250 // VCastOrInvocation::Emit
251 //
252 //==========================================================================
253
Emit(VEmitContext &)254 void VCastOrInvocation::Emit(VEmitContext&)
255 {
256 ParseError(Loc, "Should not happen");
257 }
258
259 //==========================================================================
260 //
261 // VDotInvocation::VDotInvocation
262 //
263 //==========================================================================
264
VDotInvocation(VExpression * ASelfExpr,VName AMethodName,const TLocation & ALoc,int ANumArgs,VExpression ** AArgs)265 VDotInvocation::VDotInvocation(VExpression* ASelfExpr, VName AMethodName,
266 const TLocation& ALoc, int ANumArgs, VExpression** AArgs)
267 : VExpression(ALoc)
268 , SelfExpr(ASelfExpr)
269 , MethodName(AMethodName)
270 , NumArgs(ANumArgs)
271 {
272 for (int i = 0; i < NumArgs; i++)
273 Args[i] = AArgs[i];
274 }
275
276 //==========================================================================
277 //
278 // VDotInvocation::~VDotInvocation
279 //
280 //==========================================================================
281
~VDotInvocation()282 VDotInvocation::~VDotInvocation()
283 {
284 if (SelfExpr)
285 {
286 delete SelfExpr;
287 SelfExpr = NULL;
288 }
289 for (int i = 0; i < NumArgs; i++)
290 {
291 delete Args[i];
292 Args[i] = NULL;
293 }
294 }
295
296 //==========================================================================
297 //
298 // VDotInvocation::DoResolve
299 //
300 //==========================================================================
301
DoResolve(VEmitContext & ec)302 VExpression* VDotInvocation::DoResolve(VEmitContext& ec)
303 {
304 if (SelfExpr)
305 SelfExpr = SelfExpr->Resolve(ec);
306 if (!SelfExpr)
307 {
308 delete this;
309 return NULL;
310 }
311
312 if (SelfExpr->Type.Type == TYPE_DynamicArray)
313 {
314 if (MethodName == NAME_Insert)
315 {
316 if (NumArgs == 1)
317 {
318 // Default count is 1
319 Args[1] = new VIntLiteral(1, Loc);
320 NumArgs = 2;
321 }
322 if (NumArgs != 2)
323 {
324 ParseError(Loc, "Insert requires 1 or 2 arguments");
325 delete this;
326 return NULL;
327 }
328 VExpression* e = new VDynArrayInsert(SelfExpr, Args[0], Args[1], Loc);
329 SelfExpr = NULL;
330 NumArgs = 0;
331 delete this;
332 return e->Resolve(ec);
333 }
334
335 if (MethodName == NAME_Remove)
336 {
337 if (NumArgs == 1)
338 {
339 // Default count is 1
340 Args[1] = new VIntLiteral(1, Loc);
341 NumArgs = 2;
342 }
343 if (NumArgs != 2)
344 {
345 ParseError(Loc, "Insert requires 1 or 2 arguments");
346 delete this;
347 return NULL;
348 }
349 VExpression* e = new VDynArrayRemove(SelfExpr, Args[0], Args[1], Loc);
350 SelfExpr = NULL;
351 NumArgs = 0;
352 delete this;
353 return e->Resolve(ec);
354 }
355
356 ParseError(Loc, "Invalid operation on dynamic array");
357 delete this;
358 return NULL;
359 }
360
361 if (SelfExpr->Type.Type != TYPE_Reference)
362 {
363 ParseError(Loc, "Object reference expected left side of .");
364 delete this;
365 return NULL;
366 }
367
368 VMethod* M = SelfExpr->Type.Class->FindMethod(MethodName);
369 if (M)
370 {
371 if (M->Flags & FUNC_Iterator)
372 {
373 ParseError(Loc, "Iterator methods can only be used in foreach statements");
374 delete this;
375 return NULL;
376 }
377 VExpression* e = new VInvocation(SelfExpr, M, NULL, true,
378 false, Loc, NumArgs, Args);
379 SelfExpr = NULL;
380 NumArgs = 0;
381 delete this;
382 return e->Resolve(ec);
383 }
384
385 VField* field = SelfExpr->Type.Class->FindField(MethodName, Loc,
386 ec.SelfClass);
387 if (field && field->Type.Type == TYPE_Delegate)
388 {
389 VExpression* e = new VInvocation(SelfExpr, field->Func, field, true,
390 false, Loc, NumArgs, Args);
391 SelfExpr = NULL;
392 NumArgs = 0;
393 delete this;
394 return e->Resolve(ec);
395 }
396
397 ParseError(Loc, "No such method %s", *MethodName);
398 delete this;
399 return NULL;
400 }
401
402 //==========================================================================
403 //
404 // VDotInvocation::ResolveIterator
405 //
406 //==========================================================================
407
ResolveIterator(VEmitContext & ec)408 VExpression* VDotInvocation::ResolveIterator(VEmitContext& ec)
409 {
410 if (SelfExpr)
411 SelfExpr = SelfExpr->Resolve(ec);
412 if (!SelfExpr)
413 {
414 delete this;
415 return NULL;
416 }
417
418 if (SelfExpr->Type.Type != TYPE_Reference)
419 {
420 ParseError(Loc, "Object reference expected left side of .");
421 delete this;
422 return NULL;
423 }
424
425 VMethod* M = SelfExpr->Type.Class->FindMethod(MethodName);
426 if (!M)
427 {
428 ParseError(Loc, "No such method %s", *MethodName);
429 delete this;
430 return NULL;
431 }
432 if (!(M->Flags & FUNC_Iterator))
433 {
434 ParseError(Loc, "%s is not an iterator method", *MethodName);
435 delete this;
436 return NULL;
437 }
438
439 VExpression* e = new VInvocation(SelfExpr, M, NULL, true,
440 false, Loc, NumArgs, Args);
441 SelfExpr = NULL;
442 NumArgs = 0;
443 delete this;
444 return e->Resolve(ec);
445 }
446
447 //==========================================================================
448 //
449 // VDotInvocation::Emit
450 //
451 //==========================================================================
452
Emit(VEmitContext &)453 void VDotInvocation::Emit(VEmitContext&)
454 {
455 ParseError(Loc, "Should not happen");
456 }
457
458 //==========================================================================
459 //
460 // VInvocation::VInvocation
461 //
462 //==========================================================================
463
VInvocation(VExpression * ASelfExpr,VMethod * AFunc,VField * ADelegateField,bool AHaveSelf,bool ABaseCall,const TLocation & ALoc,int ANumArgs,VExpression ** AArgs)464 VInvocation::VInvocation(VExpression* ASelfExpr, VMethod* AFunc, VField* ADelegateField,
465 bool AHaveSelf, bool ABaseCall, const TLocation& ALoc, int ANumArgs,
466 VExpression** AArgs)
467 : VExpression(ALoc)
468 , SelfExpr(ASelfExpr)
469 , Func(AFunc)
470 , DelegateField(ADelegateField)
471 , HaveSelf(AHaveSelf)
472 , BaseCall(ABaseCall)
473 , NumArgs(ANumArgs)
474 , CallerState(NULL)
475 , MultiFrameState(false)
476 {
477 guard(VInvocation::VInvocation);
478 for (int i = 0; i < NumArgs; i++)
479 {
480 Args[i] = AArgs[i];
481 }
482 unguard;
483 }
484
485 //==========================================================================
486 //
487 // VInvocation::~VInvocation
488 //
489 //==========================================================================
490
~VInvocation()491 VInvocation::~VInvocation()
492 {
493 guard(VInvocation::~VInvocation);
494 if (SelfExpr)
495 {
496 delete SelfExpr;
497 SelfExpr = NULL;
498 }
499 for (int i = 0; i < NumArgs; i++)
500 {
501 delete Args[i];
502 Args[i] = NULL;
503 }
504 unguard;
505 }
506
507 //==========================================================================
508 //
509 // VInvocation::DoResolve
510 //
511 //==========================================================================
512
DoResolve(VEmitContext & ec)513 VExpression* VInvocation::DoResolve(VEmitContext& ec)
514 {
515 guard(VInvocation::DoResolve);
516 if (ec.Package->Name == NAME_decorate)
517 {
518 CheckDecorateParams(ec);
519 }
520
521 // Resolve arguments
522 bool ArgsOk = true;
523 for (int i = 0; i < NumArgs; i++)
524 {
525 if (Args[i])
526 {
527 Args[i] = Args[i]->Resolve(ec);
528 if (!Args[i])
529 {
530 ArgsOk = false;
531 }
532 }
533 }
534 if (!ArgsOk)
535 {
536 delete this;
537 return NULL;
538 }
539
540 CheckParams(ec);
541
542 Type = Func->ReturnType;
543 if (Type.Type == TYPE_Byte || Type.Type == TYPE_Bool)
544 Type = VFieldType(TYPE_Int);
545 if (Func->Flags & FUNC_Spawner)
546 Type.Class = Args[0]->Type.Class;
547 return this;
548 unguard;
549 }
550
551 //==========================================================================
552 //
553 // VInvocation::Emit
554 //
555 //==========================================================================
556
Emit(VEmitContext & ec)557 void VInvocation::Emit(VEmitContext& ec)
558 {
559 guard(VInvocation::Emit);
560 if (SelfExpr)
561 {
562 SelfExpr->Emit(ec);
563 }
564
565 bool DirectCall = BaseCall || (Func->Flags & FUNC_Final);
566
567 if (Func->Flags & FUNC_Static)
568 {
569 if (HaveSelf)
570 {
571 ParseError(Loc, "Invalid static function call");
572 }
573 }
574 else
575 {
576 if (!HaveSelf)
577 {
578 if (ec.CurrentFunc->Flags & FUNC_Static)
579 {
580 ParseError(Loc, "An object is required to call non-static methods");
581 }
582 ec.AddStatement(OPC_LocalValue0);
583 }
584 }
585
586 vint32 SelfOffset = 1;
587 for (int i = 0; i < NumArgs; i++)
588 {
589 if (!Args[i])
590 {
591 switch (Func->ParamTypes[i].Type)
592 {
593 case TYPE_Int:
594 case TYPE_Byte:
595 case TYPE_Bool:
596 case TYPE_Float:
597 case TYPE_Name:
598 ec.EmitPushNumber(0);
599 SelfOffset++;
600 break;
601
602 case TYPE_String:
603 case TYPE_Pointer:
604 case TYPE_Reference:
605 case TYPE_Class:
606 case TYPE_State:
607 ec.AddStatement(OPC_PushNull);
608 SelfOffset++;
609 break;
610
611 case TYPE_Vector:
612 ec.EmitPushNumber(0);
613 ec.EmitPushNumber(0);
614 ec.EmitPushNumber(0);
615 SelfOffset += 3;
616 break;
617
618 default:
619 ParseError(Loc, "Bad optional parameter type");
620 break;
621 }
622 ec.EmitPushNumber(0);
623 SelfOffset++;
624 }
625 else
626 {
627 Args[i]->Emit(ec);
628 if (Args[i]->Type.Type == TYPE_Vector)
629 SelfOffset += 3;
630 else
631 SelfOffset++;
632 if (Func->ParamFlags[i] & FPARM_Optional)
633 {
634 ec.EmitPushNumber(1);
635 SelfOffset++;
636 }
637 }
638 }
639
640 if (DirectCall)
641 {
642 ec.AddStatement(OPC_Call, Func);
643 }
644 else if (DelegateField)
645 {
646 ec.AddStatement(OPC_DelegateCall, DelegateField, SelfOffset);
647 }
648 else
649 {
650 ec.AddStatement(OPC_VCall, Func, SelfOffset);
651 }
652 unguard;
653 }
654
655 //==========================================================================
656 //
657 // VInvocation::CheckParams
658 //
659 //==========================================================================
660
CheckParams(VEmitContext & ec)661 void VInvocation::CheckParams(VEmitContext& ec)
662 {
663 guard(VInvocation::CheckParams);
664 // Determine parameter count.
665 int argsize = 0;
666 int max_params;
667 int num_needed_params = Func->NumParams;
668 if (Func->Flags & FUNC_VarArgs)
669 {
670 max_params = VMethod::MAX_PARAMS - 1;
671 }
672 else
673 {
674 max_params = Func->NumParams;
675 }
676
677 for (int i = 0; i < NumArgs; i++)
678 {
679 if (i < num_needed_params)
680 {
681 if (!Args[i])
682 {
683 if (!(Func->ParamFlags[i] & FPARM_Optional))
684 {
685 ParseError(Loc, "Bad expresion");
686 }
687 argsize += Func->ParamTypes[i].GetStackSize();
688 }
689 else
690 {
691 if (ec.Package->Name == NAME_decorate)
692 {
693 switch (Func->ParamTypes[i].Type)
694 {
695 case TYPE_Int:
696 if (Args[i]->IsFloatConst())
697 {
698 int Val = int(Args[i]->GetFloatConst());
699 TLocation Loc = Args[i]->Loc;
700 delete Args[i];
701 Args[i] = NULL;
702 Args[i] = new VIntLiteral(Val, Loc);
703 Args[i] = Args[i]->Resolve(ec);
704 }
705 else if (Args[i]->Type.Type == TYPE_Float)
706 {
707 VExpression* TmpArgs[1];
708 TmpArgs[0] = Args[i];
709 Args[i] = new VInvocation(NULL,
710 ec.SelfClass->FindMethodChecked("ftoi"), NULL,
711 false, false, Args[i]->Loc, 1, TmpArgs);
712 Args[i] = Args[i]->Resolve(ec);
713 }
714 break;
715
716 case TYPE_Float:
717 if (Args[i]->IsIntConst())
718 {
719 int Val = Args[i]->GetIntConst();
720 TLocation Loc = Args[i]->Loc;
721 delete Args[i];
722 Args[i] = NULL;
723 Args[i] = new VFloatLiteral(Val, Loc);
724 Args[i] = Args[i]->Resolve(ec);
725 }
726 else if (Args[i]->Type.Type == TYPE_Int)
727 {
728 VExpression* TmpArgs[1];
729 TmpArgs[0] = Args[i];
730 Args[i] = new VInvocation(NULL,
731 ec.SelfClass->FindMethodChecked("itof"), NULL,
732 false, false, Args[i]->Loc, 1, TmpArgs);
733 Args[i] = Args[i]->Resolve(ec);
734 }
735 break;
736 }
737 }
738 if (Func->ParamFlags[i] & FPARM_Out)
739 {
740 if (!Args[i]->Type.Equals(Func->ParamTypes[i]))
741 {
742 //FIXME This should be error.
743 if (!Func->ParamFlags[NumArgs] & FPARM_Optional)
744 {
745 Args[i]->Type.CheckMatch(Args[i]->Loc, Func->ParamTypes[i]);
746 //ParseError(Args[i]->Loc, "Out parameter types must be equal");
747 }
748 }
749 Args[i]->RequestAddressOf();
750 }
751 else
752 {
753 if (!Func->ParamFlags[NumArgs] & FPARM_Optional)
754 {
755 Args[i]->Type.CheckMatch(Args[i]->Loc, Func->ParamTypes[i]);
756 }
757 }
758 argsize += Args[i]->Type.GetStackSize();
759 }
760 }
761 else if (!Args[i])
762 {
763 if (!Args[i]->Type.Equals(Func->ParamTypes[i]))
764 {
765 ParseError(Loc, "Bad expresion");
766 }
767 }
768 else
769 {
770 argsize += Args[i]->Type.GetStackSize();
771 }
772 }
773 if (NumArgs > max_params)
774 {
775 ParseError(Loc, "Incorrect number of arguments, need %d, got %d.", max_params, NumArgs);
776 }
777 while (NumArgs < num_needed_params)
778 {
779 if (Func->ParamFlags[NumArgs] & FPARM_Optional)
780 {
781 Args[NumArgs] = NULL;
782 NumArgs++;
783 }
784 else
785 {
786 ParseError(Loc, "Incorrect argument count %d, should be %d",
787 NumArgs, num_needed_params);
788 break;
789 }
790 }
791
792 if (Func->Flags & FUNC_VarArgs)
793 {
794 Args[NumArgs++] = new VIntLiteral(argsize / 4 - num_needed_params, Loc);
795 }
796 unguard;
797 }
798
799 //==========================================================================
800 //
801 // VInvocation::CheckDecorateParams
802 //
803 //==========================================================================
804
CheckDecorateParams(VEmitContext & ec)805 void VInvocation::CheckDecorateParams(VEmitContext& ec)
806 {
807 guard(VInvocation::CheckDecorateParams);
808 int max_params;
809 int num_needed_params = Func->NumParams;
810 if (Func->Flags & FUNC_VarArgs)
811 {
812 max_params = VMethod::MAX_PARAMS - 1;
813 }
814 else
815 {
816 max_params = Func->NumParams;
817 }
818
819 for (int i = 0; i < NumArgs; i++)
820 {
821 if (i >= num_needed_params)
822 {
823 continue;
824 }
825 if (!Args[i])
826 {
827 continue;
828 }
829 switch (Func->ParamTypes[i].Type)
830 {
831 case TYPE_Name:
832 if (Args[i]->IsDecorateSingleName())
833 {
834 VDecorateSingleName* E = (VDecorateSingleName*)Args[i];
835 Args[i] = new VNameLiteral(*E->Name, E->Loc);
836 delete E;
837 E = NULL;
838 }
839 else if (Args[i]->IsStrConst())
840 {
841 VStr Val = Args[i]->GetStrConst(ec.Package);
842 TLocation ALoc = Args[i]->Loc;
843 delete Args[i];
844 Args[i] = NULL;
845 Args[i] = new VNameLiteral(*Val, ALoc);
846 }
847 break;
848
849 case TYPE_String:
850 if (Args[i]->IsDecorateSingleName())
851 {
852 VDecorateSingleName* E = (VDecorateSingleName*)Args[i];
853 Args[i] = new VStringLiteral(ec.Package->FindString(*E->Name), E->Loc);
854 delete E;
855 E = NULL;
856 }
857 break;
858
859 case TYPE_Class:
860 if (Args[i]->IsDecorateSingleName())
861 {
862 VDecorateSingleName* E = (VDecorateSingleName*)Args[i];
863 Args[i] = new VStringLiteral(ec.Package->FindString(*E->Name), E->Loc);
864 delete E;
865 E = NULL;
866 }
867 if (Args[i]->IsStrConst())
868 {
869 VStr CName = Args[i]->GetStrConst(ec.Package);
870 TLocation ALoc = Args[i]->Loc;
871 VClass* Cls = VClass::FindClassNoCase(*CName);
872 if (!Cls)
873 {
874 ParseWarning(ALoc, "No such class %s", *CName);
875 delete Args[i];
876 Args[i] = NULL;
877 Args[i] = new VNoneLiteral(ALoc);
878 }
879 else if (Func->ParamTypes[i].Class &&
880 !Cls->IsChildOf(Func->ParamTypes[i].Class))
881 {
882 ParseWarning(ALoc, "Class %s is not a descendant of %s",
883 *CName, Func->ParamTypes[i].Class->GetName());
884 delete Args[i];
885 Args[i] = NULL;
886 Args[i] = new VNoneLiteral(ALoc);
887 }
888 else
889 {
890 delete Args[i];
891 Args[i] = NULL;
892 Args[i] = new VClassConstant(Cls, ALoc);
893 }
894 }
895 break;
896
897 case TYPE_State:
898 if (Args[i]->IsIntConst())
899 {
900 int Offs = Args[i]->GetIntConst();
901 TLocation ALoc = Args[i]->Loc;
902 if (Offs < 0)
903 {
904 ParseError(ALoc, "Negative state jumps are not allowed");
905 }
906 else if (Offs == 0)
907 {
908 // 0 means no state
909 delete Args[i];
910 Args[i] = NULL;
911 Args[i] = new VNoneLiteral(ALoc);
912 }
913 else
914 {
915 check(CallerState);
916 VState* S = CallerState->GetPlus(Offs, true);
917 if (!S)
918 {
919 ParseError(ALoc, "Bad state jump offset");
920 }
921 else
922 {
923 delete Args[i];
924 Args[i] = NULL;
925 Args[i] = new VStateConstant(S, ALoc);
926 }
927 }
928 }
929 else if (Args[i]->IsStrConst())
930 {
931 VStr Lbl = Args[i]->GetStrConst(ec.Package);
932 TLocation ALoc = Args[i]->Loc;
933 int DCol = Lbl.IndexOf("::");
934 if (DCol >= 0)
935 {
936 // Jump to a specific parent class state, resolve it and
937 // pass value directly.
938 VStr ClassName(Lbl, 0, DCol);
939 VClass* CheckClass;
940 if (ClassName.ICmp("Super"))
941 {
942 CheckClass = ec.SelfClass->ParentClass;
943 }
944 else
945 {
946 CheckClass = VClass::FindClassNoCase(*ClassName);
947 if (!CheckClass)
948 {
949 ParseError(ALoc, "No such class %s", *ClassName);
950 }
951 else if (!ec.SelfClass->IsChildOf(CheckClass))
952 {
953 ParseError(ALoc, "%s is not a subclass of %s",
954 ec.SelfClass->GetName(), CheckClass->GetName());
955 CheckClass = NULL;
956 }
957 }
958 if (CheckClass)
959 {
960 VStr LblName(Lbl, DCol + 2, Lbl.Length() - DCol - 2);
961 TArray<VName> Names;
962 VMemberBase::StaticSplitStateLabel(LblName, Names);
963 VStateLabel* StLbl = CheckClass->FindStateLabel(Names, true);
964 if (!StLbl)
965 {
966 ParseError(ALoc, "No such state %s", *Lbl);
967 }
968 else
969 {
970 delete Args[i];
971 Args[i] = NULL;
972 Args[i] = new VStateConstant(StLbl->State, ALoc);
973 }
974 }
975 }
976 else
977 {
978 // It's a virtual state jump
979 VExpression* TmpArgs[1];
980 TmpArgs[0] = Args[i];
981 Args[i] = new VInvocation(NULL,
982 ec.SelfClass->FindMethodChecked("FindJumpState"),
983 NULL, false, false, Args[i]->Loc, 1, TmpArgs);
984 }
985 }
986 break;
987 }
988 }
989 unguard;
990 }
991