src/Parser.cc

changeset 99
44c0c7f31ae8
parent 98
ea02b78a737a
child 100
e0392814ee31
equal deleted inserted replaced
98:ea02b78a737a 99:44c0c7f31ae8
897 // 897 //
898 void BotscriptParser::ParseFuncdef() 898 void BotscriptParser::ParseFuncdef()
899 { 899 {
900 CommandInfo* comm = new CommandInfo; 900 CommandInfo* comm = new CommandInfo;
901 901
902 // Return value
903 mLexer->MustGetAnyOf ({tkInt, tkVoid, tkBool, tkStr});
904 comm->returnvalue = GetTypeByName (mLexer->GetToken()->text); // TODO
905 assert (comm->returnvalue != -1);
906
902 // Number 907 // Number
903 mLexer->MustGetNext (tkNumber); 908 mLexer->MustGetNext (tkNumber);
904 comm->number = mLexer->GetToken()->text.ToLong(); 909 comm->number = mLexer->GetToken()->text.ToLong();
905 mLexer->MustGetNext (tkColon); 910 mLexer->MustGetNext (tkColon);
906 911
907 // Name 912 // Name
908 mLexer->MustGetNext (tkSymbol); 913 mLexer->MustGetNext (tkSymbol);
909 comm->name = mLexer->GetToken()->text; 914 comm->name = mLexer->GetToken()->text;
910 mLexer->MustGetNext (tkColon); 915
911 916 // Arguments
912 // Return value 917 mLexer->MustGetNext (tkParenStart);
913 mLexer->MustGetAnyOf ({tkInt, tkVoid, tkBool, tkStr}); 918 comm->minargs = 0;
914 comm->returnvalue = GetTypeByName (mLexer->GetToken()->text); // TODO 919
915 assert (comm->returnvalue != -1); 920 while (mLexer->PeekNextType (tkParenEnd) == false)
916 mLexer->MustGetNext (tkColon); 921 {
917 922 if (comm->args.IsEmpty() == false)
918 // Num args 923 mLexer->MustGetNext (tkComma);
919 mLexer->MustGetNext (tkNumber); 924
920 comm->numargs = mLexer->GetToken()->text.ToLong();
921 mLexer->MustGetNext (tkColon);
922
923 // Max args
924 mLexer->MustGetNext (tkNumber);
925 comm->maxargs = mLexer->GetToken()->text.ToLong();
926
927 // Argument types
928 int curarg = 0;
929
930 while (curarg < comm->maxargs)
931 {
932 CommandArgument arg; 925 CommandArgument arg;
933 mLexer->MustGetNext (tkColon);
934 mLexer->MustGetAnyOf ({tkInt, tkBool, tkStr}); 926 mLexer->MustGetAnyOf ({tkInt, tkBool, tkStr});
935 EType type = GetTypeByName (mLexer->GetToken()->text); 927 EType type = GetTypeByName (mLexer->GetToken()->text); // TODO
936 assert (type != -1 && type != EVoidType); 928 assert (type != -1 && type != EVoidType);
937 arg.type = type; 929 arg.type = type;
938 930
939 mLexer->MustGetNext (tkParenStart);
940 mLexer->MustGetNext (tkSymbol); 931 mLexer->MustGetNext (tkSymbol);
941 arg.name = mLexer->GetToken()->text; 932 arg.name = mLexer->GetToken()->text;
942 933
943 // If this is an optional parameter, we need the default value. 934 // If this is an optional parameter, we need the default value.
944 if (curarg >= comm->numargs) 935 if (comm->minargs < comm->args.Size() || mLexer->PeekNextType (tkAssign))
945 { 936 {
946 mLexer->MustGetNext (tkAssign); 937 mLexer->MustGetNext (tkAssign);
947 938
948 switch (type) 939 switch (type)
949 { 940 {
951 case EBoolType: 942 case EBoolType:
952 mLexer->MustGetNext (tkNumber); 943 mLexer->MustGetNext (tkNumber);
953 break; 944 break;
954 945
955 case EStringType: 946 case EStringType:
956 mLexer->MustGetNext (tkString); 947 Error ("string arguments cannot have default values");
957 break;
958 948
959 case EUnknownType: 949 case EUnknownType:
960 case EVoidType: 950 case EVoidType:
961 break; 951 break;
962 } 952 }
963 953
964 arg.defvalue = mLexer->GetToken()->text.ToLong(); 954 arg.defvalue = mLexer->GetToken()->text.ToLong();
965 } 955 }
966 956 else
967 mLexer->MustGetNext (tkParenEnd); 957 comm->minargs++;
958
968 comm->args << arg; 959 comm->args << arg;
969 curarg++; 960 }
970 } 961
971 962 mLexer->MustGetNext (tkParenEnd);
972 mLexer->MustGetNext (tkSemicolon); 963 mLexer->MustGetNext (tkSemicolon);
973 AddCommandDefinition (comm); 964 AddCommandDefinition (comm);
974 } 965 }
975 966
976 // ============================================================================ 967 // ============================================================================
985 mLexer->MustGetNext (tkParenStart); 976 mLexer->MustGetNext (tkParenStart);
986 mLexer->MustGetNext(); 977 mLexer->MustGetNext();
987 978
988 int curarg = 0; 979 int curarg = 0;
989 980
990 while (1) 981 for (;;)
991 { 982 {
992 if (TokenIs (tkParenEnd)) 983 if (TokenIs (tkParenEnd))
993 { 984 {
994 if (curarg < comm->numargs) 985 if (curarg < comm->minargs)
995 Error ("too few arguments passed to %1\n\tusage is: %2", 986 Error ("too few arguments passed to %1\n\tusage is: %2",
996 comm->name, comm->GetSignature()); 987 comm->name, comm->GetSignature());
997 988
998 break; 989 break;
999 curarg++; 990 curarg++;
1000 } 991 }
1001 992
1002 if (curarg >= comm->maxargs) 993 if (curarg >= comm->args.Size())
1003 Error ("too many arguments passed to %1\n\tusage is: %2", 994 Error ("too many arguments passed to %1\n\tusage is: %2",
1004 comm->name, comm->GetSignature()); 995 comm->name, comm->GetSignature());
1005 996
1006 r->MergeAndDestroy (ParseExpression (comm->args[curarg].type, true)); 997 r->MergeAndDestroy (ParseExpression (comm->args[curarg].type, true));
1007 mLexer->MustGetNext(); 998 mLexer->MustGetNext();
1008 999
1009 if (curarg < comm->numargs - 1) 1000 if (curarg < comm->minargs - 1)
1010 { 1001 {
1011 mLexer->TokenMustBe (tkComma); 1002 mLexer->TokenMustBe (tkComma);
1012 mLexer->MustGetNext(); 1003 mLexer->MustGetNext();
1013 } 1004 }
1014 else if (curarg < comm->maxargs - 1) 1005 else if (curarg < comm->args.Size() - 1)
1015 { 1006 {
1016 // Can continue, but can terminate as well. 1007 // Can continue, but can terminate as well.
1017 if (TokenIs (tkParenEnd)) 1008 if (TokenIs (tkParenEnd))
1018 { 1009 {
1019 curarg++; 1010 curarg++;
1028 1019
1029 curarg++; 1020 curarg++;
1030 } 1021 }
1031 1022
1032 // If the script skipped any optional arguments, fill in defaults. 1023 // If the script skipped any optional arguments, fill in defaults.
1033 while (curarg < comm->maxargs) 1024 while (curarg < comm->args.Size())
1034 { 1025 {
1035 r->WriteDWord (dhPushNumber); 1026 r->WriteDWord (dhPushNumber);
1036 r->WriteDWord (comm->args[curarg].defvalue); 1027 r->WriteDWord (comm->args[curarg].defvalue);
1037 curarg++; 1028 curarg++;
1038 } 1029 }
1039 1030
1040 r->WriteDWord (dhCommand); 1031 r->WriteDWord (dhCommand);
1041 r->WriteDWord (comm->number); 1032 r->WriteDWord (comm->number);
1042 r->WriteDWord (comm->maxargs); 1033 r->WriteDWord (comm->args.Size());
1043 1034
1044 return r; 1035 return r;
1045 } 1036 }
1046 1037
1047 // ============================================================================ 1038 // ============================================================================

mercurial