OSDN Git Service

- Add TEXFLAG_ADDOFFSET definition, so that all the flags for Line_SetTextureOffset...
[zandronum/zandronum-acc.git] / parse.c
diff --git a/parse.c b/parse.c
index 40d9a4e..f59daa2 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -12,6 +12,7 @@
 #include <ctype.h>\r
 #include <malloc.h>\r
 #include <stdio.h>\r
+#include <assert.h>\r
 \r
 #include "common.h"\r
 #include "parse.h"\r
@@ -93,6 +94,7 @@ static boolean ProcessStatement(statement_t owner);
 static void LeadingCompoundStatement(statement_t owner);\r
 static void LeadingVarDeclare(void);\r
 static void LeadingLineSpecial(boolean executewait);\r
+static void LeadingFunction();\r
 static void LeadingIdentifier(void);\r
 static void BuildPrintString(void);\r
 static void PrintCharArray(void);\r
@@ -695,6 +697,13 @@ static void OuterScript(void)
                scriptNumber += NET_SCRIPT_FLAG;\r
                TK_NextToken();\r
        }\r
+       // [BB] If NET and CLIENTSIDE are specified, this construction can only parse\r
+       // "NET CLIENTSIDE" but not "CLIENTSIDE NET".\r
+       if(tk_Token == TK_CLIENTSIDE)\r
+       {\r
+               scriptNumber += CLIENTSIDE_SCRIPT_FLAG;\r
+               TK_NextToken();\r
+       }\r
        CountScript(scriptType);\r
        PC_AddScript(scriptNumber + scriptType, ScriptVarCount);\r
        pc_LastAppendedCommand = PCD_NOP;\r
@@ -1136,8 +1145,16 @@ static void OuterSpecialDef(void)
        {\r
                do\r
                {\r
-                       TK_NextTokenMustBe(TK_NUMBER, ERR_MISSING_SPEC_VAL);\r
-                       special = tk_Number;\r
+                       if (TK_NextToken() == TK_MINUS)\r
+                       {\r
+                               TK_NextTokenMustBe(TK_NUMBER, ERR_MISSING_SPEC_VAL);\r
+                               special = -tk_Number;\r
+                       }\r
+                       else\r
+                       {\r
+                               TK_TokenMustBe(TK_NUMBER, ERR_MISSING_SPEC_VAL);\r
+                               special = tk_Number;\r
+                       }\r
                        TK_NextTokenMustBe(TK_COLON, ERR_MISSING_SPEC_COLON);\r
                        TK_NextTokenMustBe(TK_IDENTIFIER, ERR_INVALID_IDENTIFIER);\r
                        sym = SY_InsertGlobalUnique(tk_String, SY_SPECIAL);\r
@@ -1263,7 +1280,14 @@ static boolean ProcessStatement(statement_t owner)
                        LeadingVarDeclare();\r
                        break;\r
                case TK_LINESPECIAL:\r
-                       LeadingLineSpecial(NO);\r
+                       if (tk_SpecialValue >= 0)\r
+                       {\r
+                               LeadingLineSpecial(NO);\r
+                       }\r
+                       else\r
+                       {\r
+                               LeadingFunction();\r
+                       }\r
                        break;\r
                case TK_ACSEXECUTEWAIT:\r
                        tk_SpecialArgCount = 1 | (5<<16);\r
@@ -1611,6 +1635,81 @@ static void LeadingLineSpecial(boolean executewait)
 \r
 //==========================================================================\r
 //\r
+// LeadingLineSpecial\r
+//\r
+//==========================================================================\r
+\r
+static void LeadingFunction()\r
+{\r
+       int i;\r
+       int argCount;\r
+       int argCountMin;\r
+       int argCountMax;\r
+       int specialValue;\r
+\r
+       MS_Message(MSG_DEBUG, "---- LeadingFunction ----\n");\r
+       argCountMin = tk_SpecialArgCount & 0xffff;\r
+       argCountMax = tk_SpecialArgCount >> 16;\r
+       specialValue = -tk_SpecialValue;\r
+       TK_NextTokenMustBe(TK_LPAREN, ERR_MISSING_LPAREN);\r
+       i = 0;\r
+       if(argCountMax > 0)\r
+       {\r
+               if(TK_NextToken() == TK_CONST)\r
+               {\r
+                       // Just skip const declarators\r
+                       TK_NextTokenMustBe(TK_COLON, ERR_MISSING_COLON);\r
+               }\r
+               else\r
+               {\r
+                       TK_Undo();\r
+               }\r
+               do\r
+               {\r
+                       if(i == argCountMax)\r
+                       {\r
+                               ERR_Error(ERR_BAD_ARG_COUNT, YES);\r
+                               i = argCountMax+1;\r
+                       }\r
+                       TK_NextToken();\r
+                       EvalExpression();\r
+                       if(i < argCountMax)\r
+                       {\r
+                               i++;\r
+                       }\r
+               } while(tk_Token == TK_COMMA);\r
+               if(i < argCountMin)\r
+               {\r
+                       ERR_Error(ERR_BAD_ARG_COUNT, YES);\r
+                       TK_SkipPast(TK_SEMICOLON);\r
+                       return;\r
+               }\r
+               argCount = i;\r
+       }\r
+       else\r
+       {\r
+               argCount = 0;\r
+               TK_NextToken ();\r
+       }\r
+       TK_TokenMustBe(TK_RPAREN, ERR_MISSING_RPAREN);\r
+       TK_NextTokenMustBe(TK_SEMICOLON, ERR_MISSING_SEMICOLON);\r
+       PC_AppendCmd(PCD_CALLFUNC);\r
+       if(pc_NoShrink)\r
+       {\r
+               PC_AppendInt(argCount);\r
+               PC_AppendInt(specialValue);\r
+       }\r
+       else\r
+       {\r
+               PC_AppendByte((U_BYTE)argCount);\r
+               PC_AppendWord((U_WORD)specialValue);\r
+       }\r
+       PC_AppendCmd(PCD_DROP);\r
+       TK_NextToken();\r
+}\r
+\r
+//==========================================================================\r
+//\r
 // LeadingIdentifier\r
 //\r
 //==========================================================================\r
@@ -3159,9 +3258,9 @@ static void ExprLevX(int level)
 \r
 static void ExprLineSpecial(void)\r
 {\r
-       U_BYTE specialValue = tk_SpecialValue;\r
        int argCountMin = tk_SpecialArgCount & 0xffff;\r
        int argCountMax = tk_SpecialArgCount >> 16;\r
+       int specialValue = tk_SpecialValue;\r
 \r
        // There are two ways to use a special in an expression:\r
        // 1. The special name by itself returns the special's number.\r
@@ -3169,7 +3268,7 @@ static void ExprLineSpecial(void)
        TK_NextToken();\r
        if(tk_Token != TK_LPAREN)\r
        {\r
-               PC_AppendPushVal(tk_SpecialValue);\r
+               PC_AppendPushVal(specialValue);\r
        }\r
        else\r
        {\r
@@ -3188,23 +3287,42 @@ static void ExprLineSpecial(void)
                }\r
                if(argCount < argCountMin || argCount > argCountMax)\r
                {\r
-                       ERR_Error(ERR_BAD_LSPEC_ARG_COUNT, YES);\r
+                       ERR_Error(specialValue >=0? ERR_BAD_LSPEC_ARG_COUNT : ERR_BAD_ARG_COUNT, YES);\r
                        return;\r
                }\r
-               for(; argCount < 5; ++argCount)\r
-               {\r
-                       PC_AppendPushVal(0);\r
-               }\r
-               TK_TokenMustBe(TK_RPAREN, ERR_MISSING_RPAREN);\r
-               TK_NextToken();\r
-               PC_AppendCmd(PCD_LSPEC5RESULT);\r
-               if(pc_NoShrink)\r
+               if (specialValue >= 0)\r
                {\r
-                       PC_AppendInt(specialValue);\r
+                       for(; argCount < 5; ++argCount)\r
+                       {\r
+                               PC_AppendPushVal(0);\r
+                       }\r
+                       TK_TokenMustBe(TK_RPAREN, ERR_MISSING_RPAREN);\r
+                       TK_NextToken();\r
+                       PC_AppendCmd(PCD_LSPEC5RESULT);\r
+                       if(pc_NoShrink)\r
+                       {\r
+                               PC_AppendInt(specialValue);\r
+                       }\r
+                       else\r
+                       {\r
+                               PC_AppendByte((U_BYTE)specialValue);\r
+                       }\r
                }\r
                else\r
                {\r
-                       PC_AppendByte(specialValue);\r
+                       TK_TokenMustBe(TK_RPAREN, ERR_MISSING_RPAREN);\r
+                       TK_NextToken();\r
+                       PC_AppendCmd(PCD_CALLFUNC);\r
+                       if(pc_NoShrink)\r
+                       {\r
+                               PC_AppendInt(argCount);\r
+                               PC_AppendInt(-specialValue);\r
+                       }\r
+                       else\r
+                       {\r
+                               PC_AppendByte((U_BYTE)argCount);\r
+                               PC_AppendWord((U_WORD)-specialValue);\r
+                       }\r
                }\r
        }\r
 }\r
@@ -3769,12 +3887,13 @@ static void ParseArrayIndices(symbolNode_t *sym, int requiredIndices)
        }\r
 }\r
 \r
-static int *ProcessArrayLevel(int level, int *entry, int ndim,\r
+static void ProcessArrayLevel(int level, int *entry, int ndim,\r
        int dims[MAX_ARRAY_DIMS], int muls[MAX_ARRAY_DIMS], char *name)\r
 {\r
+       int warned_too_many = NO;\r
        int i;\r
 \r
-       for(i = 0; i < dims[level-1]; ++i)\r
+       for(i = 0; ; ++i)\r
        {\r
                if(tk_Token == TK_COMMA)\r
                {\r
@@ -3784,14 +3903,7 @@ static int *ProcessArrayLevel(int level, int *entry, int ndim,
                else if(tk_Token == TK_RBRACE)\r
                {\r
                        TK_NextToken();\r
-                       if(level > 1)\r
-                       {\r
-                               return entry + muls[level-2] - i;\r
-                       }\r
-                       else\r
-                       {\r
-                               return entry + (muls[0]*dims[0]) - i;\r
-                       }\r
+                       return;\r
                }\r
                else\r
                {\r
@@ -3806,15 +3918,28 @@ static int *ProcessArrayLevel(int level, int *entry, int ndim,
                                }\r
                                else\r
                                {\r
-                                       *entry++ = EvalConstExpression();\r
+                                       int val;\r
+\r
+                                       if (i >= dims[level - 1] && !warned_too_many)\r
+                                       {\r
+                                               warned_too_many = YES;\r
+                                               ERR_Error(ERR_TOO_MANY_ARRAY_INIT, YES);\r
+                                       }\r
+                                       val = EvalConstExpression();\r
                                        ArrayHasStrings |= pa_ConstExprIsString;\r
+                                       if (i < dims[level - 1])\r
+                                       {\r
+                                               entry[i] = val;\r
+                                       }\r
                                }\r
                        }\r
                        else\r
                        {\r
                                TK_TokenMustBe(TK_LBRACE, ERR_MISSING_LBRACE_ARR);\r
                                TK_NextToken();\r
-                               entry = ProcessArrayLevel(level+1, entry, ndim, dims, muls, name);\r
+                               ProcessArrayLevel(level+1, entry, ndim, dims, muls, name);\r
+                               assert(level > 0);\r
+                               entry += muls[level-1];\r
                        }\r
                        if(i < dims[level-1]-1)\r
                        {\r
@@ -3839,7 +3964,6 @@ static int *ProcessArrayLevel(int level, int *entry, int ndim,
        }\r
        TK_TokenMustBe(TK_RBRACE, ERR_MISSING_RBRACE_ARR);\r
        TK_NextToken();\r
-       return entry;\r
 }\r
 \r
 //==========================================================================\r