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 d870d39..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
@@ -310,6 +312,11 @@ static tokenType_t AssignOps[] =
        TK_MULASSIGN,\r
        TK_DIVASSIGN,\r
        TK_MODASSIGN,\r
+       TK_ANDASSIGN,\r
+       TK_EORASSIGN,\r
+       TK_ORASSIGN,\r
+       TK_LSASSIGN,\r
+       TK_RSASSIGN,\r
        TK_NONE\r
 };\r
 \r
@@ -327,6 +334,7 @@ static struct ScriptTypes ScriptCounts[] =
        { "lightning",          LIGHTNING_SCRIPTS_BASE,         0 },\r
        { "disconnect",         DISCONNECT_SCRIPTS_BASE,        0 },\r
        { "unloading",          UNLOADING_SCRIPTS_BASE,         0 },\r
+       { "return",                     RETURN_SCRIPTS_BASE,            0 },\r
        { NULL,                         -1,                                                     0 }\r
 };\r
 \r
@@ -615,6 +623,7 @@ static void OuterScript(void)
                case TK_WHITERETURN:\r
                case TK_LIGHTNING:\r
                case TK_UNLOADING:\r
+               case TK_RETURN:\r
                        ERR_Error(ERR_UNCLOSED_WITH_ARGS, YES);\r
                        break;\r
 \r
@@ -643,6 +652,10 @@ static void OuterScript(void)
                scriptType = ENTER_SCRIPTS_BASE;\r
                break;\r
 \r
+       case TK_RETURN:\r
+               scriptType = RETURN_SCRIPTS_BASE;\r
+               break;\r
+\r
        case TK_PICKUP:         // [BC]\r
                scriptType = PICKUP_SCRIPTS_BASE;\r
                break;\r
@@ -684,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
@@ -849,7 +869,7 @@ static void OuterFunction(void)
 \r
        TK_TokenMustBe(TK_LBRACE, ERR_MISSING_LBRACE);\r
        TK_NextToken();\r
-       do ; while(ProcessStatement(STMT_SCRIPT) == YES);\r
+       do {} while(ProcessStatement(STMT_SCRIPT) == YES);\r
 \r
        if(pc_LastAppendedCommand != PCD_RETURNVOID &&\r
           pc_LastAppendedCommand != PCD_RETURNVAL)\r
@@ -1079,7 +1099,11 @@ static void OuterWorldVar(boolean isGlobal)
                                        while(tk_Token == TK_LBRACKET);\r
                                }\r
                                sym = SY_InsertGlobal(tk_String, isGlobal ? SY_GLOBALARRAY : SY_WORLDARRAY);\r
-                               sym->info.var.index = index;\r
+                               sym->info.array.index = index;\r
+                               sym->info.array.ndim = 1;\r
+                               sym->info.array.size = 0x7fffffff;      // not used\r
+                               memset(sym->info.array.dimensions, 0, sizeof(sym->info.array.dimensions));\r
+\r
                                if (isGlobal)\r
                                        pa_GlobalArrayCount++;\r
                                else\r
@@ -1121,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
@@ -1160,23 +1192,22 @@ static void OuterDefine(boolean force)
        int value;\r
        symbolNode_t *sym;\r
 \r
-       // Don't define inside an import\r
+       MS_Message(MSG_DEBUG, "---- OuterDefine %s----\n",\r
+               force ? "(forced) " : "");\r
+       TK_NextTokenMustBe(TK_IDENTIFIER, ERR_INVALID_IDENTIFIER);\r
+       sym = SY_InsertGlobalUnique(tk_String, SY_CONSTANT);\r
+       TK_NextToken();\r
+       value = EvalConstExpression();\r
+       MS_Message(MSG_DEBUG, "Constant value: %d\n", value);\r
+       sym->info.constant.value = value;\r
+       // Defines inside an import are deleted when the import is popped.\r
        if(ImportMode != IMPORT_Importing || force)\r
        {\r
-               MS_Message(MSG_DEBUG, "---- OuterDefine %s----\n",\r
-                       force ? "(forced) " : "");\r
-               TK_NextTokenMustBe(TK_IDENTIFIER, ERR_INVALID_IDENTIFIER);\r
-               sym = SY_InsertGlobalUnique(tk_String, SY_CONSTANT);\r
-               TK_NextToken();\r
-               value = EvalConstExpression();\r
-               MS_Message(MSG_DEBUG, "Constant value: %d\n", value);\r
-               sym->info.constant.value = value;\r
+               sym->info.constant.fileDepth = 0;\r
        }\r
        else\r
        {\r
-               TK_NextToken();\r
-               TK_NextToken();\r
-               EvalConstExpression();\r
+               sym->info.constant.fileDepth = TK_GetDepth();\r
        }\r
 }\r
 \r
@@ -1239,6 +1270,7 @@ static boolean ProcessStatement(statement_t owner)
                ERR_Exit(ERR_STATEMENT_OVERFLOW, YES);\r
        }\r
        StatementHistory[StatementIndex++] = owner;\r
+       StatementLevel += AdjustStmtLevel[owner];\r
        switch(tk_Token)\r
        {\r
                case TK_INT:\r
@@ -1248,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
@@ -1359,10 +1398,12 @@ static boolean ProcessStatement(statement_t owner)
                        break;\r
                default:\r
                        StatementIndex--;\r
+                       StatementLevel -= AdjustStmtLevel[owner];\r
                        return NO;\r
                        break;\r
        }\r
        StatementIndex--;\r
+       StatementLevel -= AdjustStmtLevel[owner];\r
        return YES;\r
 }\r
 \r
@@ -1374,12 +1415,12 @@ static boolean ProcessStatement(statement_t owner)
 \r
 static void LeadingCompoundStatement(statement_t owner)\r
 {\r
-       StatementLevel += AdjustStmtLevel[owner];\r
+       //StatementLevel += AdjustStmtLevel[owner];\r
        TK_NextToken(); // Eat the TK_LBRACE\r
-       do ; while(ProcessStatement(owner) == YES);\r
+       do {} while(ProcessStatement(owner) == YES);\r
        TK_TokenMustBe(TK_RBRACE, ERR_INVALID_STATEMENT);\r
        TK_NextToken();\r
-       StatementLevel -= AdjustStmtLevel[owner];\r
+       //StatementLevel -= AdjustStmtLevel[owner];\r
 }\r
 \r
 //==========================================================================\r
@@ -1433,7 +1474,7 @@ static void LeadingVarDeclare(void)
                if(tk_Token == TK_LBRACKET)\r
                {\r
                        ERR_Error(ERR_ARRAY_MAPVAR_ONLY, YES);\r
-                       do ; while(TK_NextToken() != TK_COMMA && tk_Token != TK_SEMICOLON);\r
+                       do {} while(TK_NextToken() != TK_COMMA && tk_Token != TK_SEMICOLON);\r
                }\r
                else if(tk_Token == TK_ASSIGN)\r
                {\r
@@ -1534,7 +1575,7 @@ static void LeadingLineSpecial(boolean executewait)
                PC_AppendCmd(PCD_LSPEC1+(argCount-1));\r
                if(pc_NoShrink)\r
                {\r
-                       PC_AppendLong(specialValue);\r
+                       PC_AppendInt(specialValue);\r
                }\r
                else\r
                {\r
@@ -1547,33 +1588,33 @@ static void LeadingLineSpecial(boolean executewait)
        }\r
        else\r
        {\r
-               boolean uselongform;\r
+               boolean useintform;\r
 \r
                if(pc_NoShrink)\r
                {\r
                        PC_AppendCmd(PCD_LSPEC1DIRECT+(argCount-1));\r
-                       PC_AppendLong(specialValue);\r
-                       uselongform = YES;\r
+                       PC_AppendInt(specialValue);\r
+                       useintform = YES;\r
                }\r
                else\r
                {\r
-                       uselongform = NO;\r
+                       useintform = NO;\r
                        for (i = 0; i < argCount; i++)\r
                        {\r
-                               if ((unsigned int)argSave[i] > 255)\r
+                               if ((U_INT)argSave[i] > 255)\r
                                {\r
-                                       uselongform = YES;\r
+                                       useintform = YES;\r
                                        break;\r
                                }\r
                        }\r
-                       PC_AppendCmd((argCount-1)+(uselongform?PCD_LSPEC1DIRECT:PCD_LSPEC1DIRECTB));\r
+                       PC_AppendCmd((argCount-1)+(useintform?PCD_LSPEC1DIRECT:PCD_LSPEC1DIRECTB));\r
                        PC_AppendByte(specialValue);\r
                }\r
-               if (uselongform)\r
+               if (useintform)\r
                {\r
                        for (i = 0; i < argCount; i++)\r
                        {\r
-                               PC_AppendLong(argSave[i]);\r
+                               PC_AppendInt(argSave[i]);\r
                        }\r
                }\r
                else\r
@@ -1586,9 +1627,84 @@ static void LeadingLineSpecial(boolean executewait)
                if(executewait)\r
                {\r
                        PC_AppendCmd(PCD_SCRIPTWAITDIRECT);\r
-                       PC_AppendLong(argSave[0]);\r
+                       PC_AppendInt(argSave[0]);\r
+               }\r
+       }\r
+       TK_NextToken();\r
+}\r
+\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
@@ -1729,7 +1845,7 @@ static void ProcessInternFunc(symbolNode_t *sym)
                                                }\r
                                                else\r
                                                {\r
-                                                       PC_AppendLong(EvalConstExpression());\r
+                                                       PC_AppendInt(EvalConstExpression());\r
                                                }\r
                                        }\r
                                        else\r
@@ -1742,7 +1858,7 @@ static void ProcessInternFunc(symbolNode_t *sym)
                                                        }\r
                                                        else\r
                                                        {\r
-                                                               PC_AppendLong(0);\r
+                                                               PC_AppendInt(0);\r
                                                        }\r
                                                }\r
                                                else\r
@@ -1774,16 +1890,16 @@ static void ProcessInternFunc(symbolNode_t *sym)
                                                        switch (sym->type)\r
                                                        {\r
                                                        case SY_SCRIPTVAR:\r
-                                                               PC_AppendLong(sym->info.var.index | OUTVAR_SCRIPT_SPEC);\r
+                                                               PC_AppendInt(sym->info.var.index | OUTVAR_SCRIPT_SPEC);\r
                                                                break;\r
                                                        case SY_MAPVAR:\r
-                                                               PC_AppendLong(sym->info.var.index | OUTVAR_MAP_SPEC);\r
+                                                               PC_AppendInt(sym->info.var.index | OUTVAR_MAP_SPEC);\r
                                                                break;\r
                                                        case SY_WORLDVAR:\r
-                                                               PC_AppendLong(sym->info.var.index | OUTVAR_WORLD_SPEC);\r
+                                                               PC_AppendInt(sym->info.var.index | OUTVAR_WORLD_SPEC);\r
                                                                break;\r
                                                        case SY_GLOBALVAR:\r
-                                                               PC_AppendLong(sym->info.var.index | OUTVAR_GLOBAL_SPEC);\r
+                                                               PC_AppendInt(sym->info.var.index | OUTVAR_GLOBAL_SPEC);\r
                                                                break;\r
                                                        default:\r
                                                                ERR_Error (ERR_PARM_MUST_BE_VAR, YES);\r
@@ -1824,7 +1940,7 @@ static void ProcessInternFunc(symbolNode_t *sym)
                        }\r
                        else\r
                        {\r
-                               PC_AppendLong(0);\r
+                               PC_AppendInt(0);\r
                        }\r
                }\r
                else\r
@@ -1845,7 +1961,7 @@ static void ProcessInternFunc(symbolNode_t *sym)
        }\r
        else if (specialDirect)\r
        {\r
-               boolean uselongform = NO;\r
+               boolean useintform = NO;\r
                pcd_t shortpcd;\r
 \r
                switch (sym->info.internFunc.directCommand)\r
@@ -1857,29 +1973,29 @@ static void ProcessInternFunc(symbolNode_t *sym)
                        shortpcd = PCD_RANDOMDIRECTB;\r
                        break;\r
                default:\r
-                       uselongform = YES;\r
+                       useintform = YES;\r
                        shortpcd = PCD_NOP;\r
                        break;\r
                }\r
 \r
-               if (!uselongform)\r
+               if (!useintform)\r
                {\r
                        for (i = 0; i < argCount; i++)\r
                        {\r
-                               if ((unsigned int)argSave[i] > 255)\r
+                               if ((U_INT)argSave[i] > 255)\r
                                {\r
-                                       uselongform = YES;\r
+                                       useintform = YES;\r
                                        break;\r
                                }\r
                        }\r
                }\r
 \r
-               if (uselongform)\r
+               if (useintform)\r
                {\r
                        PC_AppendCmd(sym->info.internFunc.directCommand);\r
                        for (i = 0; i < argCount; i++)\r
                        {\r
-                               PC_AppendLong (argSave[i]);\r
+                               PC_AppendInt (argSave[i]);\r
                        }\r
                }\r
                else\r
@@ -1992,7 +2108,7 @@ static void ProcessScriptFunc(symbolNode_t *sym, boolean discardReturn)
        }\r
        if (pc_NoShrink)\r
        {\r
-               PC_AppendLong(sym->info.scriptFunc.funcNumber);\r
+               PC_AppendInt(sym->info.scriptFunc.funcNumber);\r
        }\r
        else\r
        {\r
@@ -2037,6 +2153,15 @@ static void BuildPrintString(void)
                        case 'f': // [RH] fixed point\r
                                printCmd = PCD_PRINTFIXED;\r
                                break;\r
+                       case 'k': // [GRB] key binding\r
+                               printCmd = PCD_PRINTBIND;\r
+                               break;\r
+                       case 'b': // [RH] binary integer\r
+                               printCmd = PCD_PRINTBINARY;\r
+                               break;\r
+                       case 'x': // [RH] hexadecimal integer\r
+                               printCmd = PCD_PRINTHEX;\r
+                               break;\r
                        default:\r
                                printCmd = PCD_PRINTSTRING;\r
                                ERR_Error(ERR_UNKNOWN_PRTYPE, YES);\r
@@ -2262,7 +2387,7 @@ static void LeadingIf(void)
        TK_TokenMustBe(TK_RPAREN, ERR_MISSING_RPAREN);\r
        PC_AppendCmd(PCD_IFNOTGOTO);\r
        jumpAddrPtr1 = pc_Address;\r
-       PC_SkipLong();\r
+       PC_SkipInt();\r
        TK_NextToken();\r
        if(ProcessStatement(STMT_IF) == NO)\r
        {\r
@@ -2272,18 +2397,18 @@ static void LeadingIf(void)
        {\r
                PC_AppendCmd(PCD_GOTO);\r
                jumpAddrPtr2 = pc_Address;\r
-               PC_SkipLong();\r
-               PC_WriteLong(pc_Address, jumpAddrPtr1);\r
+               PC_SkipInt();\r
+               PC_WriteInt(pc_Address, jumpAddrPtr1);\r
                TK_NextToken();\r
                if(ProcessStatement(STMT_ELSE) == NO)\r
                {\r
                        ERR_Error(ERR_INVALID_STATEMENT, YES);\r
                }\r
-               PC_WriteLong(pc_Address, jumpAddrPtr2);\r
+               PC_WriteInt(pc_Address, jumpAddrPtr2);\r
        }\r
        else\r
        {\r
-               PC_WriteLong(pc_Address, jumpAddrPtr1);\r
+               PC_WriteInt(pc_Address, jumpAddrPtr1);\r
        }\r
 }\r
 \r
@@ -2303,7 +2428,7 @@ static void LeadingFor(void)
        MS_Message(MSG_DEBUG, "---- LeadingFor ----\n");\r
        TK_NextTokenMustBe(TK_LPAREN, ERR_MISSING_LPAREN);\r
        TK_NextToken();\r
-       if(ProcessStatement(STMT_FOR) == NO)\r
+       if(ProcessStatement(STMT_IF) == NO)\r
        {\r
                ERR_Error(ERR_INVALID_STATEMENT, YES);\r
        }\r
@@ -2313,29 +2438,29 @@ static void LeadingFor(void)
        TK_NextToken();\r
        PC_AppendCmd(PCD_IFGOTO);\r
        ifgotoAddr = pc_Address;\r
-       PC_SkipLong();\r
+       PC_SkipInt();\r
        PC_AppendCmd(PCD_GOTO);\r
        gotoAddr = pc_Address;\r
-       PC_SkipLong();\r
+       PC_SkipInt();\r
        incAddr = pc_Address;\r
        forSemicolonHack = TRUE;\r
-       if(ProcessStatement(STMT_FOR) == NO)\r
+       if(ProcessStatement(STMT_IF) == NO)\r
        {\r
                ERR_Error(ERR_INVALID_STATEMENT, YES);\r
        }\r
        forSemicolonHack = FALSE;\r
        PC_AppendCmd(PCD_GOTO);\r
-       PC_AppendLong(exprAddr);\r
-       PC_WriteLong(pc_Address,ifgotoAddr);\r
+       PC_AppendInt(exprAddr);\r
+       PC_WriteInt(pc_Address,ifgotoAddr);\r
        if(ProcessStatement(STMT_FOR) == NO)\r
        {\r
                ERR_Error(ERR_INVALID_STATEMENT, YES);\r
        }\r
        PC_AppendCmd(PCD_GOTO);\r
-       PC_AppendLong(incAddr);\r
+       PC_AppendInt(incAddr);\r
        WriteContinues(incAddr);\r
        WriteBreaks();\r
-       PC_WriteLong(pc_Address,gotoAddr);\r
+       PC_WriteInt(pc_Address,gotoAddr);\r
 }\r
 \r
 //==========================================================================\r
@@ -2359,16 +2484,16 @@ static void LeadingWhileUntil(void)
        TK_TokenMustBe(TK_RPAREN, ERR_MISSING_RPAREN);\r
        PC_AppendCmd(stmtToken == TK_WHILE ? PCD_IFNOTGOTO : PCD_IFGOTO);\r
        outAddrPtr = pc_Address;\r
-       PC_SkipLong();\r
+       PC_SkipInt();\r
        TK_NextToken();\r
        if(ProcessStatement(STMT_WHILEUNTIL) == NO)\r
        {\r
                ERR_Error(ERR_INVALID_STATEMENT, YES);\r
        }\r
        PC_AppendCmd(PCD_GOTO);\r
-       PC_AppendLong(topAddr);\r
+       PC_AppendInt(topAddr);\r
 \r
-       PC_WriteLong(pc_Address, outAddrPtr);\r
+       PC_WriteInt(pc_Address, outAddrPtr);\r
 \r
        WriteContinues(topAddr);\r
        WriteBreaks();\r
@@ -2407,7 +2532,7 @@ static void LeadingDo(void)
        TK_TokenMustBe(TK_RPAREN, ERR_MISSING_RPAREN);\r
        TK_NextTokenMustBe(TK_SEMICOLON, ERR_MISSING_SEMICOLON);\r
        PC_AppendCmd(stmtToken == TK_WHILE ? PCD_IFGOTO : PCD_IFNOTGOTO);\r
-       PC_AppendLong(topAddr);\r
+       PC_AppendInt(topAddr);\r
        WriteContinues(exprAddr);\r
        WriteBreaks();\r
        TK_NextToken();\r
@@ -2435,7 +2560,7 @@ static void LeadingSwitch(void)
 \r
        PC_AppendCmd(PCD_GOTO);\r
        switcherAddrPtr = pc_Address;\r
-       PC_SkipLong();\r
+       PC_SkipInt();\r
 \r
        TK_NextToken();\r
        if(ProcessStatement(STMT_SWITCH) == NO)\r
@@ -2445,9 +2570,9 @@ static void LeadingSwitch(void)
 \r
        PC_AppendCmd(PCD_GOTO);\r
        outAddrPtr = pc_Address;\r
-       PC_SkipLong();\r
+       PC_SkipInt();\r
 \r
-       PC_WriteLong(pc_Address, switcherAddrPtr);\r
+       PC_WriteInt(pc_Address, switcherAddrPtr);\r
        defaultAddress = 0;\r
 \r
        if(pc_HexenCase)\r
@@ -2460,8 +2585,8 @@ static void LeadingSwitch(void)
                                continue;\r
                        }\r
                        PC_AppendCmd(PCD_CASEGOTO);\r
-                       PC_AppendLong(cInfo->value);\r
-                       PC_AppendLong(cInfo->address);\r
+                       PC_AppendInt(cInfo->value);\r
+                       PC_AppendInt(cInfo->address);\r
                }\r
        }\r
        else if(CaseIndex != 0)\r
@@ -2486,14 +2611,14 @@ static void LeadingSwitch(void)
                        PC_AppendCmd(PCD_CASEGOTOSORTED);\r
                        if(pc_Address%4 != 0)\r
                        { // Align to a 4-byte boundary\r
-                               U_LONG pad = 0;\r
+                               U_INT pad = 0;\r
                                PC_Append((void *)&pad, 4-(pc_Address%4));\r
                        }\r
-                       PC_AppendLong(maxCase - minCase);\r
+                       PC_AppendInt(maxCase - minCase);\r
                        for(; minCase < maxCase; ++minCase)\r
                        {\r
-                               PC_AppendLong(minCase->value);\r
-                               PC_AppendLong(minCase->address);\r
+                               PC_AppendInt(minCase->value);\r
+                               PC_AppendInt(minCase->address);\r
                        }\r
                }\r
        }\r
@@ -2502,10 +2627,10 @@ static void LeadingSwitch(void)
        if(defaultAddress != 0)\r
        {\r
                PC_AppendCmd(PCD_GOTO);\r
-               PC_AppendLong(defaultAddress);\r
+               PC_AppendInt(defaultAddress);\r
        }\r
 \r
-       PC_WriteLong(pc_Address, outAddrPtr);\r
+       PC_WriteInt(pc_Address, outAddrPtr);\r
 \r
        WriteBreaks();\r
 }\r
@@ -2633,7 +2758,7 @@ static void LeadingBreak(void)
        TK_NextTokenMustBe(TK_SEMICOLON, ERR_MISSING_SEMICOLON);\r
        PC_AppendCmd(PCD_GOTO);\r
        PushBreak();\r
-       PC_SkipLong();\r
+       PC_SkipInt();\r
        TK_NextToken();\r
 }\r
 \r
@@ -2664,7 +2789,7 @@ static void WriteBreaks(void)
 {\r
        while(BreakIndex && BreakInfo[BreakIndex-1].level > StatementLevel)\r
        {\r
-               PC_WriteLong(pc_Address, BreakInfo[--BreakIndex].addressPtr);\r
+               PC_WriteInt(pc_Address, BreakInfo[--BreakIndex].addressPtr);\r
        }\r
 }\r
 \r
@@ -2703,7 +2828,7 @@ static void LeadingContinue(void)
        TK_NextTokenMustBe(TK_SEMICOLON, ERR_MISSING_SEMICOLON);\r
        PC_AppendCmd(PCD_GOTO);\r
        PushContinue();\r
-       PC_SkipLong();\r
+       PC_SkipInt();\r
        TK_NextToken();\r
 }\r
 \r
@@ -2738,7 +2863,7 @@ static void WriteContinues(int address)
        }\r
        while(ContinueInfo[ContinueIndex-1].level > StatementLevel)\r
        {\r
-               PC_WriteLong(address, ContinueInfo[--ContinueIndex].addressPtr);\r
+               PC_WriteInt(address, ContinueInfo[--ContinueIndex].addressPtr);\r
        }\r
 }\r
 \r
@@ -2845,7 +2970,7 @@ static void LeadingVarAssign(symbolNode_t *sym)
                        PC_AppendCmd(GetIncDecPCD(tk_Token, sym->type));\r
                        if (pc_NoShrink)\r
                        {\r
-                               PC_AppendLong(sym->info.var.index);\r
+                               PC_AppendInt(sym->info.var.index);\r
                        }\r
                        else\r
                        {\r
@@ -2902,21 +3027,28 @@ static pcd_t GetAssignPCD(tokenType_t token, symbolType_t symbol)
        static tokenType_t tokenLookup[] =\r
        {\r
                TK_ASSIGN, TK_ADDASSIGN, TK_SUBASSIGN,\r
-               TK_MULASSIGN, TK_DIVASSIGN, TK_MODASSIGN\r
+               TK_MULASSIGN, TK_DIVASSIGN, TK_MODASSIGN,\r
+               TK_ANDASSIGN, TK_EORASSIGN, TK_ORASSIGN,\r
+               TK_LSASSIGN, TK_RSASSIGN\r
        };\r
        static symbolType_t symbolLookup[] =\r
        {\r
                SY_SCRIPTVAR, SY_MAPVAR, SY_WORLDVAR, SY_GLOBALVAR, SY_MAPARRAY,\r
                SY_WORLDARRAY, SY_GLOBALARRAY\r
        };\r
-       static pcd_t assignmentLookup[6][7] =\r
+       static pcd_t assignmentLookup[11][7] =\r
        {\r
                { PCD_ASSIGNSCRIPTVAR, PCD_ASSIGNMAPVAR, PCD_ASSIGNWORLDVAR, PCD_ASSIGNGLOBALVAR, PCD_ASSIGNMAPARRAY, PCD_ASSIGNWORLDARRAY, PCD_ASSIGNGLOBALARRAY },\r
                { PCD_ADDSCRIPTVAR, PCD_ADDMAPVAR, PCD_ADDWORLDVAR, PCD_ADDGLOBALVAR, PCD_ADDMAPARRAY, PCD_ADDWORLDARRAY, PCD_ADDGLOBALARRAY },\r
                { PCD_SUBSCRIPTVAR, PCD_SUBMAPVAR, PCD_SUBWORLDVAR, PCD_SUBGLOBALVAR, PCD_SUBMAPARRAY, PCD_SUBWORLDARRAY, PCD_SUBGLOBALARRAY },\r
                { PCD_MULSCRIPTVAR, PCD_MULMAPVAR, PCD_MULWORLDVAR, PCD_MULGLOBALVAR, PCD_MULMAPARRAY, PCD_MULWORLDARRAY, PCD_MULGLOBALARRAY },\r
                { PCD_DIVSCRIPTVAR, PCD_DIVMAPVAR, PCD_DIVWORLDVAR, PCD_DIVGLOBALVAR, PCD_DIVMAPARRAY, PCD_DIVWORLDARRAY, PCD_DIVGLOBALARRAY },\r
-               { PCD_MODSCRIPTVAR, PCD_MODMAPVAR, PCD_MODWORLDVAR, PCD_MODGLOBALVAR, PCD_MODMAPARRAY, PCD_MODWORLDARRAY, PCD_MODGLOBALARRAY }\r
+               { PCD_MODSCRIPTVAR, PCD_MODMAPVAR, PCD_MODWORLDVAR, PCD_MODGLOBALVAR, PCD_MODMAPARRAY, PCD_MODWORLDARRAY, PCD_MODGLOBALARRAY },\r
+               { PCD_ANDSCRIPTVAR, PCD_ANDMAPVAR, PCD_ANDWORLDVAR, PCD_ANDGLOBALVAR, PCD_ANDMAPARRAY, PCD_ANDWORLDARRAY, PCD_ANDGLOBALARRAY },\r
+               { PCD_EORSCRIPTVAR, PCD_EORMAPVAR, PCD_EORWORLDVAR, PCD_EORGLOBALVAR, PCD_EORMAPARRAY, PCD_EORWORLDARRAY, PCD_EORGLOBALARRAY },\r
+               { PCD_ORSCRIPTVAR, PCD_ORMAPVAR, PCD_ORWORLDVAR, PCD_ORGLOBALVAR, PCD_ORMAPARRAY, PCD_ORWORLDARRAY, PCD_ORGLOBALARRAY },\r
+               { PCD_LSSCRIPTVAR, PCD_LSMAPVAR, PCD_LSWORLDVAR, PCD_LSGLOBALVAR, PCD_LSMAPARRAY, PCD_LSWORLDARRAY, PCD_LSGLOBALARRAY },\r
+               { PCD_RSSCRIPTVAR, PCD_RSMAPVAR, PCD_RSWORLDVAR, PCD_RSGLOBALVAR, PCD_RSMAPARRAY, PCD_RSWORLDARRAY, PCD_RSGLOBALARRAY }\r
        };\r
 \r
        for(i = 0; i < ARRAY_SIZE(tokenLookup); ++i)\r
@@ -3126,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
@@ -3136,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
@@ -3155,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
+               if (specialValue >= 0)\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_AppendLong(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
@@ -3244,6 +3395,11 @@ static void ExprFactor(void)
                ExprFactor();\r
                PC_AppendCmd(PCD_NEGATELOGICAL);\r
                break;\r
+       case TK_TILDE:\r
+               TK_NextToken();\r
+               ExprFactor();\r
+               PC_AppendCmd(PCD_NEGATEBINARY);\r
+               break;\r
        case TK_INC:\r
        case TK_DEC:\r
                opToken = tk_Token;\r
@@ -3409,6 +3565,10 @@ static void ConstExprFactor(void)
                        tk_Token != TK_SEMICOLON &&\r
                        tk_Token != TK_RPAREN)\r
                {\r
+                       if(tk_Token == TK_EOF)\r
+                       {\r
+                               ERR_Exit(ERR_EOF, YES);\r
+                       }\r
                        TK_NextToken();\r
                }\r
                break;\r
@@ -3698,7 +3858,7 @@ static void ParseArrayIndices(symbolNode_t *sym, int requiredIndices)
                        }\r
                }\r
                EvalExpression();\r
-               if(i < sym->info.array.ndim - 1)\r
+               if(i < sym->info.array.ndim - 1 && sym->info.array.dimensions[i] > 1)\r
                {\r
                        PC_AppendPushVal(sym->info.array.dimensions[i]);\r
                        PC_AppendCmd(PCD_MULTIPLY);\r
@@ -3712,10 +3872,10 @@ static void ParseArrayIndices(symbolNode_t *sym, int requiredIndices)
                TK_NextToken();\r
        }\r
        // if there were unspecified indices, multiply the offset by their sizes [JB]\r
-       if(requiredIndices < sym->info.array.ndim)\r
+       if(requiredIndices < sym->info.array.ndim - 1)\r
        {\r
                int i, mult = 1;\r
-               for(i = 0; i < sym->info.array.ndim - requiredIndices; ++i)\r
+               for(i = 0; i < sym->info.array.ndim - requiredIndices - 1; ++i)\r
                {\r
                        mult *= sym->info.array.dimensions[sym->info.array.ndim - 2 - i];\r
                }\r
@@ -3727,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
@@ -3742,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
@@ -3764,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
@@ -3797,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
@@ -3929,7 +4095,7 @@ static void UnspeculateFunction(symbolNode_t *sym)
 \r
                        if(pc_NoShrink)\r
                        {\r
-                               PC_WriteLong(sym->info.scriptFunc.funcNumber, fillin->address);\r
+                               PC_WriteInt(sym->info.scriptFunc.funcNumber, fillin->address);\r
                        }\r
                        else\r
                        {\r