#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
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
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
{\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
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
\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
\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
TK_NextToken();\r
if(tk_Token != TK_LPAREN)\r
{\r
- PC_AppendPushVal(tk_SpecialValue);\r
+ PC_AppendPushVal(specialValue);\r
}\r
else\r
{\r
}\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
}\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
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
}\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
}\r
TK_TokenMustBe(TK_RBRACE, ERR_MISSING_RBRACE_ARR);\r
TK_NextToken();\r
- return entry;\r
}\r
\r
//==========================================================================\r