From 991b02552d74ace528195d66405b1670b2393ccc Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Sat, 11 Apr 2026 09:38:51 +0100 Subject: [PATCH 1/7] multiple changes and cleanups --- Engine/source/console/console.h | 386 +-- Engine/source/console/consoleInternal.cpp | 4 +- Engine/source/console/consoleInternal.h | 2 +- Engine/source/console/torquescript/CMDgram.h | 88 +- Engine/source/console/torquescript/CMDgram.y | 167 +- .../source/console/torquescript/CMDscan.cpp | 977 +++---- Engine/source/console/torquescript/CMDscan.l | 434 ++-- .../source/console/torquescript/astNodes.cpp | 125 +- .../source/console/torquescript/cmdgram.cpp | 2268 ++++++++--------- .../console/torquescript/compiledEval.cpp | 162 +- Engine/source/console/torquescript/compiler.h | 1 + 11 files changed, 2429 insertions(+), 2185 deletions(-) diff --git a/Engine/source/console/console.h b/Engine/source/console/console.h index 82f953eb1..8733df39f 100644 --- a/Engine/source/console/console.h +++ b/Engine/source/console/console.h @@ -120,12 +120,12 @@ typedef const char *StringTableEntry; enum ConsoleValueType { - cvNULL = -5, - cvInteger = -4, - cvFloat = -3, - cvString = -2, - cvSTEntry = -1, - cvConsoleValueType = 0 + cvNULL = -5, + cvInteger = -4, + cvFloat = -3, + cvString = -2, ///< Heap-allocated, owned (dMalloc/dFree) + cvSTEntry = -1, ///< StringTable pointer, NOT owned + cvConsoleValueType = 0 ///< First valid engine console type ID }; class ConsoleValue @@ -148,6 +148,7 @@ public: EnumTable* enumTable; }; }; +#pragma warning(pop) S32 type; U32 bufferLen; @@ -160,7 +161,10 @@ public: TORQUE_FORCEINLINE void cleanupData() { - if (type <= cvString && bufferLen > 0) + // Only cvString strings are heap-allocated and owned by this value. + // cvSTEntry points into the StringTable (managed externally). + // Numeric types use the f/i union fields — s is not valid for them. + if (type == ConsoleValueType::cvString && bufferLen > 0) { dFree(s); bufferLen = 0; @@ -176,57 +180,38 @@ public: bufferLen = 0; } - ConsoleValue(const ConsoleValue& ref) + ConsoleValue(const ConsoleValue& other) + : type(ConsoleValueType::cvSTEntry) + , bufferLen(0) { - type = ConsoleValueType::cvSTEntry; s = const_cast(StringTable->EmptyString()); - bufferLen = 0; - - switch (ref.type) - { - case cvNULL: - std::cout << "Ref already cleared!"; - break; - case cvInteger: - setInt(ref.i); - break; - case cvFloat: - setFloat(ref.f); - break; - case cvSTEntry: - setStringTableEntry(ref.s); - break; - case cvString: - setString(ref.s); - break; - default: - setConsoleData(ref.type, ref.dataPtr, ref.enumTable); - break; - } + copyFrom(other); } - ConsoleValue& operator=(const ConsoleValue& ref) + /// Move constructor — steals the heap buffer rather than copying it. + /// After the move, `other` is left as an empty-string value. + ConsoleValue(ConsoleValue&& other) noexcept + : type(other.type) + , bufferLen(other.bufferLen) { - switch (ref.type) + transferFrom(other); + } + + ConsoleValue& operator=(const ConsoleValue& other) + { + if (this != &other) + copyFrom(other); + return *this; + } + + ConsoleValue& operator=(ConsoleValue&& other) noexcept + { + if (this != &other) { - case cvNULL: - std::cout << "Ref already cleared!"; - break; - case cvInteger: - setInt(ref.i); - break; - case cvFloat: - setFloat(ref.f); - break; - case cvSTEntry: - setStringTableEntry(ref.s); - break; - case cvString: - setString(ref.s); - break; - default: - setConsoleData(ref.type, ref.dataPtr, ref.enumTable); - break; + cleanupData(); + type = other.type; + bufferLen = other.bufferLen; + transferFrom(other); } return *this; } @@ -243,75 +228,105 @@ public: TORQUE_FORCEINLINE F64 getFloat() const { - if (type == ConsoleValueType::cvFloat) + switch (type) + { + case ConsoleValueType::cvFloat: return f; - if (type == ConsoleValueType::cvInteger) - return i; - if (type == ConsoleValueType::cvSTEntry) - return s == StringTable->EmptyString() ? 0.0f : dAtof(s); - if (type == ConsoleValueType::cvString) - return dStrcmp(s, "") == 0 ? 0.0f : dAtof(s); - return dAtof(getConsoleData()); + case ConsoleValueType::cvInteger: + return static_cast(i); + case ConsoleValueType::cvSTEntry: + return (s == StringTable->EmptyString()) ? 0.0 : dAtof(s); + case ConsoleValueType::cvString: + return (s[0] == '\0') ? 0.0 : dAtof(s); + case ConsoleValueType::cvNULL: + return 0.0; + default: + return dAtof(getConsoleData()); + } } TORQUE_FORCEINLINE S64 getInt() const { - if (type == ConsoleValueType::cvInteger) + switch (type) + { + case ConsoleValueType::cvInteger: return i; - if (type == ConsoleValueType::cvFloat) - return f; - if (type == ConsoleValueType::cvSTEntry) - return s == StringTable->EmptyString() ? 0 : dAtoi(s); - if (type == ConsoleValueType::cvString) - return dStrcmp(s, "") == 0 ? 0 : dAtoi(s); - - return dAtoi(getConsoleData()); - } - - TORQUE_FORCEINLINE const char* getString() const - { - if (isStringType()) - return s; - if (isNumberType()) - return convertToBuffer(); - return getConsoleData(); - } - - TORQUE_FORCEINLINE operator const char* () const - { - return getString(); + case ConsoleValueType::cvFloat: + return static_cast(f); + case ConsoleValueType::cvSTEntry: + return (s == StringTable->EmptyString()) ? S64(0) : static_cast(dAtoi(s)); + case ConsoleValueType::cvString: + return (s[0] == '\0') ? S64(0) : static_cast(dAtoi(s)); + case ConsoleValueType::cvNULL: + return 0; + default: + return static_cast(dAtoi(getConsoleData())); + } } TORQUE_FORCEINLINE bool getBool() const { - if (type == ConsoleValueType::cvInteger) - return (bool)i; - if (type == ConsoleValueType::cvFloat) - return (bool)f; - if (type == ConsoleValueType::cvSTEntry) - return s == StringTable->EmptyString() ? false : dAtob(s); - if (type == ConsoleValueType::cvString) - return dStrcmp(s, "") == 0 ? false : dAtob(s); - return dAtob(getConsoleData()); + switch (type) + { + case ConsoleValueType::cvInteger: + return (i != 0); + case ConsoleValueType::cvFloat: + return (f != 0.0); + case ConsoleValueType::cvSTEntry: + return (s != StringTable->EmptyString()) && dAtob(s); + case ConsoleValueType::cvString: + return (s[0] != '\0') && dAtob(s); + case ConsoleValueType::cvNULL: + return false; + default: + return dAtob(getConsoleData()); + } } - TORQUE_FORCEINLINE void setFloat(const F64 val) + TORQUE_FORCEINLINE const char* getString() const + { + switch (type) + { + case ConsoleValueType::cvSTEntry: + case ConsoleValueType::cvString: + return s; + case ConsoleValueType::cvNULL: + return StringTable->EmptyString(); + case ConsoleValueType::cvFloat: + case ConsoleValueType::cvInteger: + return convertToBuffer(); + default: + return getConsoleData(); + } + } + + TORQUE_FORCEINLINE operator const char* () const { return getString(); } + + TORQUE_FORCEINLINE void setFloat(F64 val) { cleanupData(); type = ConsoleValueType::cvFloat; f = val; + // bufferLen is already 0 after cleanupData — correct for non-string types } - TORQUE_FORCEINLINE void setInt(const S64 val) + TORQUE_FORCEINLINE void setInt(S64 val) { cleanupData(); type = ConsoleValueType::cvInteger; i = val; } + TORQUE_FORCEINLINE void setBool(bool val) + { + cleanupData(); + type = ConsoleValueType::cvInteger; + i = val ? S64(1) : S64(0); + } + TORQUE_FORCEINLINE void setString(const char* val) { - setString(val, val != NULL ? dStrlen(val) : 0); + setString(val, val ? static_cast(dStrlen(val)) : 0); } TORQUE_FORCEINLINE void setString(const char* val, S32 len) @@ -321,67 +336,83 @@ public: setEmptyString(); return; } - cleanupData(); - type = ConsoleValueType::cvString; - - s = (char*)dMalloc(len + 1); - - bufferLen = len + 1; + bufferLen = static_cast(len) + 1u; // allocation size, always > 0 + s = static_cast(dMalloc(bufferLen)); s[len] = '\0'; - dStrcpy(s, val, len + 1); + dMemcpy(s, val, static_cast(len)); } - TORQUE_FORCEINLINE void setStringRef(const char* ref, S32 len) + /// Transfer ownership of a dMalloc'd buffer to this value. + /// + /// @param ownedBuf Buffer allocated with dMalloc. Must have a null + /// terminator at ownedBuf[len]. This value will call + /// dFree(ownedBuf) when it is cleaned up. + /// @param len String length NOT including the null terminator. + /// If len == 0 the buffer still gets freed correctly + /// because bufferLen is stored as len+1. + TORQUE_FORCEINLINE void setStringOwned(char* ownedBuf, S32 len) { cleanupData(); type = ConsoleValueType::cvString; - s = (char*)std::move(ref); - bufferLen = len; + bufferLen = static_cast(len) + 1; // always > 0 → cleanupData will free + s = ownedBuf; } - TORQUE_FORCEINLINE void setBool(const bool val) + /// @deprecated Use setStringOwned(). Kept so existing call sites compile. + /// The old name "Ref" implied a non-owning borrow, which was + /// the opposite of the actual semantics. + TORQUE_FORCEINLINE void setStringRef(const char* ownedBuf, S32 len) { - cleanupData(); - type = ConsoleValueType::cvInteger; - i = (int)val; + setStringOwned(const_cast(ownedBuf), len); } TORQUE_FORCEINLINE void setStringTableEntry(StringTableEntry val) { cleanupData(); type = ConsoleValueType::cvSTEntry; - s = (char*)(StringTable->insert(val)); - bufferLen = 0; + // StringTable::insert accepts NULL and returns EmptyString + s = const_cast(StringTable->insert(val ? val : "")); + bufferLen = 0; // NOT owned — StringTable manages this memory } TORQUE_FORCEINLINE void setEmptyString() { - setStringTableEntry(StringTable->EmptyString()); + // cleanupData already sets s = EmptyString and type = cvNULL. + // We then promote the type to cvSTEntry so queries return a valid + // empty string rather than having to special-case cvNULL everywhere. + cleanupData(); + type = ConsoleValueType::cvSTEntry; } - TORQUE_FORCEINLINE void setConsoleData(S32 inConsoleType, void* inDataPtr, const EnumTable* inEnumTable) + TORQUE_FORCEINLINE void setConsoleData(S32 inType, void* inDataPtr, const EnumTable* inEnumTable) { cleanupData(); - type = inConsoleType; + type = inType; dataPtr = inDataPtr; enumTable = const_cast(inEnumTable); - }; - - TORQUE_FORCEINLINE S32 getType() const - { - return type; + bufferLen = 0; } - TORQUE_FORCEINLINE bool isStringType() const + TORQUE_FORCEINLINE void setFastFloat(F64 val) { type = ConsoleValueType::cvFloat; f = val; } + TORQUE_FORCEINLINE F64 getFastFloat() const { return f; } + + TORQUE_FORCEINLINE void setFastInt(S64 val) { type = ConsoleValueType::cvInteger; i = val; } + TORQUE_FORCEINLINE S64 getFastInt() const { return i; } + + TORQUE_FORCEINLINE S32 getType() const { return type; } + + TORQUE_FORCEINLINE bool isStringType() const { - return type == ConsoleValueType::cvString || type == ConsoleValueType::cvSTEntry; + return type == ConsoleValueType::cvString + || type == ConsoleValueType::cvSTEntry; } - TORQUE_FORCEINLINE bool isNumberType() const + TORQUE_FORCEINLINE bool isNumberType() const { - return type == ConsoleValueType::cvFloat || type == ConsoleValueType::cvInteger; + return type == ConsoleValueType::cvFloat + || type == ConsoleValueType::cvInteger; } TORQUE_FORCEINLINE bool isConsoleType() const @@ -391,40 +422,89 @@ public: TORQUE_FORCEINLINE S32 getConsoleType() const { - if(type >= ConsoleValueType::cvConsoleValueType) - { - return type; - } - else - { - return NULL; - } - } - - TORQUE_FORCEINLINE void setFastFloat(F64 flt) - { - type = ConsoleValueType::cvFloat; - f = flt; - } - - TORQUE_FORCEINLINE F64 getFastFloat() const - { - return f; - } - - TORQUE_FORCEINLINE void setFastInt(S64 flt) - { - type = ConsoleValueType::cvInteger; - i = flt; - } - - TORQUE_FORCEINLINE S64 getFastInt() const - { - return i; + return (type >= ConsoleValueType::cvConsoleValueType) ? type : 0; } static void init(); static void resetConversionBuffer(); + +private: + /// Deep-copy from `other` into `this` (assumes `this` has already been + /// cleaned up or is freshly constructed). + void copyFrom(const ConsoleValue& other) + { + switch (other.type) + { + case ConsoleValueType::cvNULL: + // Another value was already cleaned up. Treat as empty string. + // Do NOT assert here — cvNULL is a valid transient state that can + // appear e.g. when an entry is moved out of. + setEmptyString(); + break; + + case ConsoleValueType::cvInteger: + setInt(other.i); + break; + + case ConsoleValueType::cvFloat: + setFloat(other.f); + break; + + case ConsoleValueType::cvSTEntry: + // s already points into StringTable — just share the pointer. + setStringTableEntry(other.s); + break; + + case ConsoleValueType::cvString: + { + // bufferLen == allocation size (len+1), so string length == bufferLen-1. + // Guard defensively: if somehow bufferLen is 0 (pre-fix bug state), + // fall back to dStrlen. + S32 strLen = (other.bufferLen > 0) + ? static_cast(other.bufferLen) - 1 + : static_cast(dStrlen(other.s)); + setString(other.s, strLen); + break; + } + + default: + setConsoleData(other.type, other.dataPtr, other.enumTable); + break; + } + } + + /// Steal the payload from `other` (which must already have its type and + /// bufferLen copied into `this`), then leave `other` in a safe empty state. + /// Called only from move constructor / move assignment after copying type. + TORQUE_FORCEINLINE void transferFrom(ConsoleValue& other) noexcept + { + // Copy the right union field based on the type we already copied. + switch (type) + { + case ConsoleValueType::cvFloat: + f = other.f; + break; + case ConsoleValueType::cvInteger: + i = other.i; + break; + case ConsoleValueType::cvString: + case ConsoleValueType::cvSTEntry: + case ConsoleValueType::cvNULL: + s = other.s; + break; + default: + dataPtr = other.dataPtr; + enumTable = other.enumTable; + break; + } + + // Leave `other` as a valid empty-string value. + // Critically: if we stole a cvString buffer, other must NOT keep a + // non-zero bufferLen, or its destructor will double-free. + other.s = const_cast(StringTable->EmptyString()); + other.type = ConsoleValueType::cvSTEntry; + other.bufferLen = 0; + } }; // Transparently converts ConsoleValue[] to const char** diff --git a/Engine/source/console/consoleInternal.cpp b/Engine/source/console/consoleInternal.cpp index d3e877430..fbbd28193 100644 --- a/Engine/source/console/consoleInternal.cpp +++ b/Engine/source/console/consoleInternal.cpp @@ -672,13 +672,13 @@ Namespace::Entry::Entry() mPackage = StringTable->EmptyString(); mToolOnly = false; VECTOR_SET_ASSOCIATION(mArgFlags); - VECTOR_SET_ASSOCIATION(mDefaultValues); + VECTOR_SET_ASSOCIATION(mDefaultOffsets); } void Namespace::Entry::clear() { mArgFlags.clear(); - mDefaultValues.clear(); + mDefaultOffsets.clear(); if (mModule) { diff --git a/Engine/source/console/consoleInternal.h b/Engine/source/console/consoleInternal.h index 041c4cffa..735e9da58 100644 --- a/Engine/source/console/consoleInternal.h +++ b/Engine/source/console/consoleInternal.h @@ -132,7 +132,7 @@ public: // Offsets to get default values for arguments. Vector mArgFlags; - Vector mDefaultValues; + Vector mDefaultOffsets; /// If it's a script function, this is the line of the declaration in code. /// @note 0 for functions read from legacy DSOs that have no line number information. diff --git a/Engine/source/console/torquescript/CMDgram.h b/Engine/source/console/torquescript/CMDgram.h index 41a5ffbf5..f18b8dc1c 100644 --- a/Engine/source/console/torquescript/CMDgram.h +++ b/Engine/source/console/torquescript/CMDgram.h @@ -81,51 +81,45 @@ extern int CMDdebug; rwSWITCHSTR = 282, /* rwSWITCHSTR */ rwCASEOR = 283, /* rwCASEOR */ rwPACKAGE = 284, /* rwPACKAGE */ - rwNAMESPACE = 285, /* rwNAMESPACE */ - rwCLASS = 286, /* rwCLASS */ - rwASSERT = 287, /* rwASSERT */ - ILLEGAL_TOKEN = 288, /* ILLEGAL_TOKEN */ - CHRCONST = 289, /* CHRCONST */ - INTCONST = 290, /* INTCONST */ - TTAG = 291, /* TTAG */ - VAR = 292, /* VAR */ - IDENT = 293, /* IDENT */ - TYPEIDENT = 294, /* TYPEIDENT */ - DOCBLOCK = 295, /* DOCBLOCK */ - STRATOM = 296, /* STRATOM */ - TAGATOM = 297, /* TAGATOM */ - FLTCONST = 298, /* FLTCONST */ - opINTNAME = 299, /* opINTNAME */ - opINTNAMER = 300, /* opINTNAMER */ - opMINUSMINUS = 301, /* opMINUSMINUS */ - opPLUSPLUS = 302, /* opPLUSPLUS */ - STMT_SEP = 303, /* STMT_SEP */ - opSHL = 304, /* opSHL */ - opSHR = 305, /* opSHR */ - opPLASN = 306, /* opPLASN */ - opMIASN = 307, /* opMIASN */ - opMLASN = 308, /* opMLASN */ - opDVASN = 309, /* opDVASN */ - opMODASN = 310, /* opMODASN */ - opANDASN = 311, /* opANDASN */ - opXORASN = 312, /* opXORASN */ - opORASN = 313, /* opORASN */ - opSLASN = 314, /* opSLASN */ - opSRASN = 315, /* opSRASN */ - opCAT = 316, /* opCAT */ - opEQ = 317, /* opEQ */ - opNE = 318, /* opNE */ - opGE = 319, /* opGE */ - opLE = 320, /* opLE */ - opAND = 321, /* opAND */ - opOR = 322, /* opOR */ - opSTREQ = 323, /* opSTREQ */ - opCOLONCOLON = 324, /* opCOLONCOLON */ - opMDASN = 325, /* opMDASN */ - opNDASN = 326, /* opNDASN */ - opNTASN = 327, /* opNTASN */ - opSTRNE = 328, /* opSTRNE */ - UNARY = 329 /* UNARY */ + rwASSERT = 285, /* rwASSERT */ + ILLEGAL_TOKEN = 286, /* ILLEGAL_TOKEN */ + CHRCONST = 287, /* CHRCONST */ + INTCONST = 288, /* INTCONST */ + TTAG = 289, /* TTAG */ + VAR = 290, /* VAR */ + IDENT = 291, /* IDENT */ + TYPEIDENT = 292, /* TYPEIDENT */ + DOCBLOCK = 293, /* DOCBLOCK */ + STRATOM = 294, /* STRATOM */ + TAGATOM = 295, /* TAGATOM */ + FLTCONST = 296, /* FLTCONST */ + opINTNAME = 297, /* opINTNAME */ + opINTNAMER = 298, /* opINTNAMER */ + opMINUSMINUS = 299, /* opMINUSMINUS */ + opPLUSPLUS = 300, /* opPLUSPLUS */ + opSHL = 301, /* opSHL */ + opSHR = 302, /* opSHR */ + opPLASN = 303, /* opPLASN */ + opMIASN = 304, /* opMIASN */ + opMLASN = 305, /* opMLASN */ + opDVASN = 306, /* opDVASN */ + opMODASN = 307, /* opMODASN */ + opANDASN = 308, /* opANDASN */ + opXORASN = 309, /* opXORASN */ + opORASN = 310, /* opORASN */ + opSLASN = 311, /* opSLASN */ + opSRASN = 312, /* opSRASN */ + opCAT = 313, /* opCAT */ + opEQ = 314, /* opEQ */ + opNE = 315, /* opNE */ + opGE = 316, /* opGE */ + opLE = 317, /* opLE */ + opAND = 318, /* opAND */ + opOR = 319, /* opOR */ + opSTREQ = 320, /* opSTREQ */ + opSTRNE = 321, /* opSTRNE */ + opCOLONCOLON = 322, /* opCOLONCOLON */ + UNARY = 323 /* UNARY */ }; typedef enum yytokentype yytoken_kind_t; #endif @@ -134,7 +128,7 @@ extern int CMDdebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 87 "CMDgram.y" +#line 107 "CMDgram.y" Token< char > c; Token< int > i; @@ -152,7 +146,7 @@ union YYSTYPE AssignDecl asn; IfStmtNode* ifnode; -#line 156 "CMDgram.h" +#line 150 "CMDgram.h" }; typedef union YYSTYPE YYSTYPE; diff --git a/Engine/source/console/torquescript/CMDgram.y b/Engine/source/console/torquescript/CMDgram.y index c081cb82c..ff4f00b87 100644 --- a/Engine/source/console/torquescript/CMDgram.y +++ b/Engine/source/console/torquescript/CMDgram.y @@ -46,20 +46,28 @@ struct Token }; %} + %{ - /* Reserved Word Definitions */ + /* Reserved word token definitions */ %} + %token rwDEFINE rwENDDEF rwDECLARE rwDECLARESINGLETON %token rwBREAK rwELSE rwCONTINUE rwGLOBAL %token rwIF rwNIL rwRETURN rwWHILE rwDO %token rwENDIF rwENDWHILE rwENDFOR rwDEFAULT %token rwFOR rwFOREACH rwFOREACHSTR rwIN rwDATABLOCK rwSWITCH rwCASE rwSWITCHSTR -%token rwCASEOR rwPACKAGE rwNAMESPACE rwCLASS +%token rwCASEOR rwPACKAGE %token rwASSERT %token ILLEGAL_TOKEN +// NOTE: rwNAMESPACE and rwCLASS were declared here previously but had no +// lexer rules and appeared in no grammar productions. They have been +// removed. If namespace/class syntax is added in future, add both the +// token declaration AND the lexer rule at the same time. + %{ - /* Constants and Identifier Definitions */ + /* Constant and identifier token definitions */ %} + %token CHRCONST %token INTCONST %token TTAG @@ -72,16 +80,28 @@ struct Token %token FLTCONST %{ - /* Operator Definitions */ + /* Operator token definitions */ %} + %token '+' '-' '*' '/' '<' '>' '=' '.' '|' '&' '%' %token '(' ')' ',' ':' ';' '{' '}' '^' '~' '!' '@' %token opINTNAME opINTNAMER %token opMINUSMINUS opPLUSPLUS -%token STMT_SEP + +// NOTE: STMT_SEP was declared here but never returned by the lexer and never +// used in any grammar production. Removed to prevent confusion. + %token opSHL opSHR opPLASN opMIASN opMLASN opDVASN opMODASN opANDASN %token opXORASN opORASN opSLASN opSRASN opCAT -%token opEQ opNE opGE opLE opAND opOR opSTREQ +%token opEQ opNE opGE opLE opAND opOR + +// FIX: opSTREQ and opSTRNE must be declared with their semantic type . +// Previously opSTRNE was only mentioned in the %left precedence line, which +// does declare it as a token but gives it no type — causing a silent type +// mismatch when used in grammar rules (even if $2 isn't used in the action, +// the generated parser code is technically undefined behaviour). +%token opSTREQ opSTRNE + %token opCOLONCOLON %union { @@ -143,8 +163,13 @@ struct Token %type var_list_decl %type assign_op_struct +// Operator precedence — lowest to highest. +// FIX: opMDASN, opNDASN, opNTASN were listed here but were never defined +// as tokens anywhere and were never returned by the lexer. They appear to +// be leftovers from an earlier revision. Removed to prevent compiler +// warnings about undeclared token names. %left '[' -%right opMODASN opANDASN opXORASN opPLASN opMIASN opMLASN opDVASN opMDASN opNDASN opNTASN opORASN opSLASN opSRASN '=' +%right opMODASN opANDASN opXORASN opPLASN opMIASN opMLASN opDVASN opORASN opSLASN opSRASN '=' %left '?' ':' %left opOR %left opAND @@ -229,17 +254,19 @@ stmt ; fn_decl_stmt + // Global function : rwDEFINE IDENT '(' var_list_decl ')' '{' statement_list '}' { $$ = FunctionDeclStmtNode::alloc( $1.lineNumber, $2.value, NULL, $4, $7 ); } - | rwDEFINE IDENT opCOLONCOLON IDENT '(' var_list_decl ')' '{' statement_list '}' - { $$ = FunctionDeclStmtNode::alloc( $1.lineNumber, $4.value, $2.value, $6, $9 ); } + // Namespaced method: function Namespace::name(...) { } + | rwDEFINE IDENT opCOLONCOLON IDENT '(' var_list_decl ')' '{' statement_list '}' + { $$ = FunctionDeclStmtNode::alloc( $1.lineNumber, $4.value, $2.value, $6, $9 ); } ; var_list_decl : - { $$ = NULL; } + { $$ = NULL; } | var_list - { $$ = $1; } + { $$ = $1; } ; var_list @@ -249,27 +276,31 @@ var_list { $$ = $1; ((StmtNode*)($1))->append((StmtNode*)$3 ); } ; +// Parameter declaration forms: +// +// %var — required parameter +// %var ? — optional parameter, evaluates to "" / 0 when absent +// %var = expr — optional parameter with default value +// %var ? = expr — same as above; the '?' makes the optionality explicit +// +// NOTE: the default `expr` can be any valid expression, including function +// calls and variable references. At present these are evaluated once at +// declaration time (global scope). The planned codelet change (see +// FunctionDeclStmtNode::compileStmt in ast.cpp) will evaluate them at +// each call site instead — no grammar change is required for that fix. param - : VAR - { - $$ = VarNode::allocParam($1.lineNumber, $1.value, NULL); - } - | VAR '?' - { - $$ = VarNode::allocParam($1.lineNumber, $1.value, NULL); - } - | VAR '=' expr - { - $$ = VarNode::allocParam($1.lineNumber, $1.value, $3); - } - | VAR '?' '=' expr - { - $$ = VarNode::allocParam($1.lineNumber, $1.value, $4); - } - ; + : VAR + { $$ = VarNode::allocParam($1.lineNumber, $1.value, NULL); } + | VAR '?' + { $$ = VarNode::allocParam($1.lineNumber, $1.value, NULL); } + | VAR '=' expr + { $$ = VarNode::allocParam($1.lineNumber, $1.value, $3); } + | VAR '?' '=' expr + { $$ = VarNode::allocParam($1.lineNumber, $1.value, $4); } + ; datablock_decl - : rwDATABLOCK class_name_expr '(' expr parent_block ')' '{' slot_assign_list_opt '}' ';' + : rwDATABLOCK class_name_expr '(' expr parent_block ')' '{' slot_assign_list_opt '}' ';' { $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $4, NULL, $5.value, $8, NULL, true, false, false); } ; @@ -341,6 +372,9 @@ switch_stmt { $$ = $6; $6->propagateSwitchExpr($3, true); } ; +// NOTE: propagateSwitchExpr builds a recursive OR expression tree that is +// O(n) deep for n cases. Large switch statements (100+ cases) can overflow +// the compiler stack. case_block : rwCASE case_expr ':' statement_list { $$ = IfStmtNode::alloc( $1.lineNumber, $2, $4, NULL, false); } @@ -352,9 +386,9 @@ case_block case_expr : expr - { $$ = $1;} + { $$ = $1; } | case_expr rwCASEOR expr - { ($1)->append($3); $$=$1; } + { ($1)->append($3); $$ = $1; } ; if_stmt @@ -389,7 +423,7 @@ for_stmt | rwFOR '(' ';' ';' ')' stmt_block { $$ = LoopStmtNode::alloc($1.lineNumber, NULL, NULL, NULL, $6, false); } ; - + foreach_stmt : rwFOREACH '(' VAR rwIN expr ')' stmt_block { $$ = IterStmtNode::alloc( $1.lineNumber, $3.value, $5, $7, false ); } @@ -455,6 +489,12 @@ expr { $$ = StreqExprNode::alloc( $1->dbgLineNumber, $1, $3, true); } | expr opSTRNE expr { $$ = StreqExprNode::alloc( $1->dbgLineNumber, $1, $3, false); } + // The '@' operator covers four cases via token value encoding in the lexer: + // '@' → value 0 (plain concatenation) + // NL → value '\n' + // TAB → value '\t' + // SPC → value ' ' + // The appendChar is stored in $2.value and forwarded to StrcatExprNode. | expr '@' expr { $$ = StrcatExprNode::alloc( $1->dbgLineNumber, $1, $3, $2.value); } | '!' expr @@ -482,23 +522,6 @@ expr | VAR '[' aidx_expr ']' { $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, $3 ); } ; -/* - | rwDEFINE '(' var_list_decl ')' '{' statement_list '}' - { - const U32 bufLen = 64; - UTF8 buffer[bufLen]; - dSprintf(buffer, bufLen, "__anonymous_function%d", gAnonFunctionID++); - StringTableEntry fName = StringTable->insert(buffer); - StmtNode *fndef = FunctionDeclStmtNode::alloc($1.lineNumber, fName, NULL, $3, $6); - - if(!gAnonFunctionList) - gAnonFunctionList = fndef; - else - gAnonFunctionList->append(fndef); - - $$ = StrConstNode::alloc( $1.lineNumber, (UTF8*)fName, false ); - } -*/ slot_acc : expr '.' IDENT @@ -509,9 +532,9 @@ slot_acc intslot_acc : expr opINTNAME class_name_expr - { $$.lineNumber = $1->dbgLineNumber; $$.object = $1; $$.slotExpr = $3; $$.recurse = false; } + { $$.lineNumber = $1->dbgLineNumber; $$.object = $1; $$.slotExpr = $3; $$.recurse = false; } | expr opINTNAMER class_name_expr - { $$.lineNumber = $1->dbgLineNumber; $$.object = $1; $$.slotExpr = $3; $$.recurse = true; } + { $$.lineNumber = $1->dbgLineNumber; $$.object = $1; $$.slotExpr = $3; $$.recurse = true; } ; class_name_expr @@ -552,7 +575,7 @@ stmt_expr : funcall_expr { $$ = $1; } | assert_expr - { $$ = $1; } + { $$ = $1; } | object_decl { $$ = $1; } | VAR '=' expr @@ -572,18 +595,18 @@ stmt_expr ; funcall_expr + // Global function call: name(args) : IDENT '(' expr_list_decl ')' - { $$ = FuncCallExprNode::alloc( $1.lineNumber, $1.value, NULL, $3, false); } + { $$ = FuncCallExprNode::alloc( $1.lineNumber, $1.value, NULL, $3, false); } + // Static/namespace call: Namespace::name(args) | IDENT opCOLONCOLON IDENT '(' expr_list_decl ')' - { $$ = FuncCallExprNode::alloc( $1.lineNumber, $3.value, $1.value, $5, false); } + { $$ = FuncCallExprNode::alloc( $1.lineNumber, $3.value, $1.value, $5, false); } + // Method call: object.method(args) + // The object expression is prepended to the arg list so that exec() can + // find it as callArgv[1] (the implicit 'this'). | expr '.' IDENT '(' expr_list_decl ')' { $1->append($5); $$ = FuncCallExprNode::alloc( $1->dbgLineNumber, $3.value, NULL, $1, true); } ; -/* - | expr '(' expr_list_decl ')' - { $$ = FuncPointerCallExprNode::alloc( $1->dbgLineNumber, $1, $3); } - ; -*/ assert_expr : rwASSERT '(' expr ')' @@ -591,7 +614,7 @@ assert_expr | rwASSERT '(' expr ',' STRATOM ')' { $$ = AssertCallExprNode::alloc( $1.lineNumber, $3, $5.value ); } ; - + expr_list_decl : { $$ = NULL; } @@ -605,7 +628,7 @@ expr_list | expr_list ',' expr { ($1)->append($3); $$ = $1; } ; - + slot_assign_list_opt : { $$ = NULL; } @@ -633,50 +656,58 @@ slot_assign { $$ = SlotAssignNode::alloc( $1.lineNumber, NULL, $4, $2.value, $7, $1.value); } ; +// Array index expressions. Multiple comma-separated indices get +// concatenated with '_' separators at runtime (e.g. arr[1,2] → "arr_1_2"). aidx_expr : expr { $$ = $1; } | aidx_expr ',' expr { $$ = CommaCatExprNode::alloc( $1->dbgLineNumber, $1, $3); } ; + %% int -yyreport_syntax_error (const yypcontext_t *ctx) +yyreport_syntax_error(const yypcontext_t *ctx) { int ret = 0; String output; - const YYLTYPE *loc = yypcontext_location (ctx); + const YYLTYPE *loc = yypcontext_location(ctx); output += "syntax error: "; yysymbol_kind_t nxt = yypcontext_token(ctx); if (nxt != YYSYMBOL_YYEMPTY) - output += String::ToString("unexpected: %s at column: %d", yysymbol_name(nxt), loc->first_column); + output += String::ToString("unexpected: %s at column: %d", + yysymbol_name(nxt), loc->first_column); enum { TOKENMAX = 10 }; yysymbol_kind_t expected[TOKENMAX]; int exp = yypcontext_expected_tokens(ctx, expected, TOKENMAX); if (exp < 0) + { ret = exp; + } else { for (int i = 0; i < exp; ++i) - output += String::ToString("%s %s", i == 0 ? ": expected" : "or", yysymbol_name(expected[i])); + output += String::ToString("%s %s", + i == 0 ? ": expected" : "or", + yysymbol_name(expected[i])); } - if (lines.size() > 0) + if (lines.size() > 0) { output += "\n"; for (int i = 0; i < lines.size(); i++) { int line = lines.size() - i; - output += String::ToString("%5d | ", loc->first_line - (line-1)) + lines[i] + "\n"; + output += String::ToString("%5d | ", loc->first_line - (line - 1)) + + lines[i] + "\n"; } output += String::ToString("%5s | %*s", "", loc->first_column, "^"); } yyerror("%s", output.c_str()); - return ret; } diff --git a/Engine/source/console/torquescript/CMDscan.cpp b/Engine/source/console/torquescript/CMDscan.cpp index 4497cb961..2094fb8e0 100644 --- a/Engine/source/console/torquescript/CMDscan.cpp +++ b/Engine/source/console/torquescript/CMDscan.cpp @@ -630,8 +630,8 @@ static void yynoreturn yy_fatal_error ( const char* msg ); (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 94 -#define YY_END_OF_BUFFER 95 +#define YY_NUM_RULES 93 +#define YY_END_OF_BUFFER 94 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -639,33 +639,32 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[225] = +static const flex_int16_t yy_accept[217] = { 0, - 0, 0, 95, 93, 1, 5, 4, 51, 93, 93, - 58, 57, 93, 41, 42, 45, 43, 56, 44, 50, - 46, 90, 90, 52, 53, 47, 61, 48, 38, 36, - 88, 88, 88, 88, 39, 40, 59, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, - 88, 54, 49, 55, 60, 1, 5, 0, 9, 0, - 6, 0, 0, 17, 87, 25, 12, 26, 0, 7, - 0, 23, 16, 21, 15, 22, 31, 91, 37, 3, - 24, 0, 90, 0, 0, 14, 19, 11, 8, 10, - 20, 88, 33, 88, 88, 27, 88, 88, 88, 88, + 0, 0, 94, 92, 1, 5, 4, 51, 92, 92, + 58, 57, 92, 41, 42, 45, 43, 56, 44, 50, + 46, 89, 89, 52, 53, 47, 61, 48, 38, 36, + 87, 87, 87, 87, 39, 40, 59, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 54, 49, 55, 60, 1, 5, 0, 9, 0, + 6, 0, 0, 17, 86, 25, 12, 26, 0, 7, + 0, 23, 16, 21, 15, 22, 31, 90, 37, 3, + 24, 0, 89, 0, 0, 14, 19, 11, 8, 10, + 20, 87, 33, 87, 87, 27, 87, 87, 87, 87, - 88, 88, 69, 88, 88, 88, 88, 70, 62, 88, - 88, 63, 88, 88, 88, 88, 88, 88, 28, 13, - 18, 92, 87, 0, 32, 3, 3, 91, 0, 91, - 89, 29, 30, 35, 34, 88, 88, 88, 88, 88, - 88, 88, 88, 73, 88, 88, 76, 88, 88, 88, - 88, 88, 88, 92, 0, 3, 2, 88, 88, 79, - 88, 88, 88, 66, 88, 88, 88, 88, 88, 88, - 88, 88, 85, 88, 3, 0, 88, 64, 88, 88, - 88, 86, 88, 88, 88, 88, 88, 88, 88, 68, - 0, 67, 88, 88, 88, 88, 88, 88, 88, 65, + 87, 87, 69, 87, 87, 87, 87, 70, 62, 87, + 63, 87, 87, 87, 87, 87, 87, 28, 13, 18, + 91, 86, 0, 32, 3, 3, 90, 0, 90, 88, + 29, 30, 35, 34, 87, 87, 87, 87, 87, 87, + 87, 87, 73, 87, 76, 87, 87, 87, 87, 87, + 87, 91, 0, 3, 2, 87, 87, 79, 87, 87, + 87, 66, 87, 87, 87, 87, 87, 87, 87, 84, + 87, 3, 0, 87, 64, 87, 87, 87, 85, 87, + 87, 87, 87, 87, 87, 68, 0, 67, 87, 87, + 87, 87, 87, 87, 65, 87, 81, 0, 87, 87, - 88, 81, 0, 88, 88, 82, 72, 88, 88, 83, - 88, 80, 0, 74, 88, 71, 75, 88, 88, 0, - 78, 84, 77, 0 + 82, 72, 87, 83, 87, 80, 0, 74, 87, 71, + 75, 87, 0, 78, 77, 0 } ; static const YY_CHAR yy_ec[256] = @@ -681,9 +680,9 @@ static const YY_CHAR yy_ec[256] = 33, 33, 37, 38, 33, 33, 33, 39, 33, 33, 40, 41, 42, 43, 33, 1, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 33, 53, 54, 55, 56, - 57, 58, 33, 59, 60, 61, 62, 33, 63, 39, - 33, 33, 64, 65, 66, 67, 1, 1, 1, 1, + 48, 49, 50, 51, 52, 33, 53, 54, 33, 55, + 56, 57, 33, 58, 59, 60, 61, 33, 62, 39, + 33, 33, 63, 64, 65, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -700,7 +699,7 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 } ; -static const YY_CHAR yy_meta[68] = +static const YY_CHAR yy_meta[67] = { 0, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 5, @@ -708,120 +707,117 @@ static const YY_CHAR yy_meta[68] = 5, 5, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 1, 1, 1, 1 + 8, 8, 1, 1, 1, 1 } ; -static const flex_int16_t yy_base[239] = +static const flex_int16_t yy_base[231] = { 0, - 0, 0, 348, 349, 345, 0, 349, 61, 63, 51, - 53, 65, 66, 349, 349, 322, 64, 349, 66, 60, - 68, 76, 80, 324, 349, 60, 320, 77, 349, 349, - 0, 309, 306, 313, 349, 349, 316, 279, 279, 54, - 61, 283, 59, 38, 62, 277, 291, 286, 62, 274, - 281, 349, 89, 349, 349, 329, 0, 306, 349, 111, - 349, 325, 100, 349, 307, 349, 349, 349, 112, 349, - 323, 349, 349, 349, 301, 349, 349, 107, 349, 307, - 349, 110, 114, 121, 0, 349, 300, 349, 349, 349, - 299, 0, 0, 292, 292, 349, 260, 271, 258, 261, + 0, 0, 339, 340, 336, 0, 340, 60, 62, 50, + 52, 64, 65, 340, 340, 313, 63, 340, 65, 59, + 67, 75, 79, 315, 340, 59, 311, 76, 340, 340, + 0, 300, 297, 304, 340, 340, 307, 271, 271, 49, + 60, 274, 65, 63, 279, 268, 281, 276, 58, 265, + 271, 340, 73, 340, 340, 319, 0, 296, 340, 107, + 340, 315, 105, 340, 297, 340, 340, 340, 76, 340, + 313, 340, 340, 340, 291, 340, 340, 109, 340, 297, + 340, 111, 115, 122, 0, 340, 290, 340, 340, 340, + 289, 0, 0, 282, 282, 340, 251, 261, 249, 252, - 255, 266, 0, 254, 259, 253, 255, 0, 0, 255, - 246, 0, 262, 246, 250, 253, 242, 251, 349, 349, - 349, 281, 280, 279, 349, 0, 139, 119, 125, 128, - 0, 349, 349, 0, 0, 251, 254, 249, 235, 251, - 250, 245, 232, 243, 244, 241, 0, 235, 225, 236, - 224, 236, 229, 261, 260, 146, 152, 221, 226, 0, - 226, 232, 214, 0, 227, 230, 212, 212, 227, 211, - 215, 222, 0, 219, 155, 248, 204, 0, 208, 209, - 208, 0, 215, 208, 201, 208, 201, 208, 204, 0, - 224, 0, 159, 156, 151, 158, 148, 160, 153, 0, + 246, 256, 0, 245, 249, 244, 246, 0, 0, 238, + 0, 253, 238, 242, 244, 234, 242, 340, 340, 340, + 272, 271, 270, 340, 0, 136, 124, 126, 130, 0, + 340, 340, 0, 0, 242, 245, 240, 227, 242, 241, + 236, 224, 234, 235, 0, 227, 218, 228, 217, 228, + 221, 253, 252, 148, 155, 214, 218, 0, 218, 224, + 207, 0, 219, 222, 205, 220, 205, 208, 215, 0, + 212, 157, 241, 198, 0, 190, 170, 162, 0, 169, + 160, 158, 152, 156, 152, 0, 178, 0, 134, 135, + 124, 132, 119, 123, 0, 110, 155, 161, 109, 109, - 139, 186, 157, 144, 142, 0, 174, 124, 126, 0, - 112, 349, 160, 0, 115, 349, 0, 88, 76, 162, - 0, 0, 0, 349, 170, 178, 182, 190, 194, 198, - 202, 210, 118, 214, 222, 230, 238, 246 + 0, 146, 78, 0, 66, 340, 163, 0, 66, 340, + 0, 60, 165, 0, 0, 340, 173, 181, 185, 193, + 197, 201, 205, 213, 97, 217, 225, 233, 241, 249 } ; -static const flex_int16_t yy_def[239] = +static const flex_int16_t yy_def[231] = { 0, - 224, 1, 224, 224, 224, 225, 224, 224, 226, 227, - 227, 224, 228, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 229, 229, 229, 229, 224, 224, 224, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 224, 224, 224, 224, 224, 225, 224, 224, 226, - 224, 226, 230, 224, 231, 224, 224, 224, 228, 224, - 228, 224, 224, 224, 224, 224, 224, 224, 224, 232, - 224, 224, 224, 224, 233, 224, 224, 224, 224, 224, - 224, 229, 229, 229, 229, 224, 229, 229, 229, 229, + 216, 1, 216, 216, 216, 217, 216, 216, 218, 219, + 219, 216, 220, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 221, 221, 221, 221, 216, 216, 216, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 216, 216, 216, 216, 216, 217, 216, 216, 218, + 216, 218, 222, 216, 223, 216, 216, 216, 220, 216, + 220, 216, 216, 216, 216, 216, 216, 216, 216, 224, + 216, 216, 216, 216, 225, 216, 216, 216, 216, 216, + 216, 221, 221, 221, 221, 216, 221, 221, 221, 221, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 224, 224, - 224, 234, 231, 231, 224, 232, 235, 224, 224, 224, - 233, 224, 224, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 234, 234, 236, 224, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 236, 224, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 224, 229, 229, 229, 229, 229, 229, 229, 229, 229, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 216, 216, 216, + 226, 223, 223, 216, 224, 227, 216, 216, 216, 225, + 216, 216, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 226, 226, 228, 216, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 228, 216, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 216, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 229, 221, 221, - 229, 229, 237, 229, 229, 229, 229, 229, 229, 229, - 229, 224, 238, 229, 229, 224, 229, 229, 229, 238, - 229, 229, 229, 0, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224 + 221, 221, 221, 221, 221, 216, 230, 221, 221, 216, + 221, 221, 230, 221, 221, 0, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216 } ; -static const flex_int16_t yy_nxt[417] = +static const flex_int16_t yy_nxt[407] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 31, 31, 31, 31, 31, 31, 32, 31, 33, 34, 31, 35, 4, 36, 37, 38, 39, 40, 41, 42, 43, 31, - 31, 44, 31, 31, 31, 45, 46, 47, 48, 49, - 50, 31, 51, 52, 53, 54, 55, 58, 61, 63, - 63, 63, 63, 67, 64, 70, 66, 73, 78, 78, - 79, 75, 87, 88, 59, 80, 108, 74, 68, 76, - 77, 81, 82, 109, 83, 83, 82, 99, 83, 83, + 31, 44, 31, 31, 45, 46, 47, 48, 49, 50, + 31, 51, 52, 53, 54, 55, 58, 61, 63, 63, + 63, 63, 67, 64, 70, 66, 73, 78, 78, 79, + 75, 87, 88, 59, 80, 70, 74, 68, 76, 77, + 81, 82, 99, 83, 83, 82, 118, 83, 83, 90, - 90, 91, 105, 62, 101, 110, 71, 84, 102, 111, - 100, 84, 119, 115, 85, 106, 61, 103, 63, 63, - 107, 70, 131, 84, 116, 78, 78, 84, 128, 128, - 82, 223, 83, 83, 129, 222, 129, 128, 128, 130, - 130, 157, 157, 130, 130, 84, 130, 130, 157, 157, - 84, 62, 71, 120, 157, 157, 126, 157, 157, 157, - 157, 84, 157, 157, 157, 157, 84, 221, 219, 176, - 57, 218, 57, 57, 57, 57, 57, 57, 60, 217, - 216, 60, 60, 60, 60, 60, 65, 215, 65, 65, - 69, 214, 212, 69, 69, 69, 69, 69, 92, 211, + 91, 130, 62, 101, 100, 71, 84, 102, 105, 114, + 84, 108, 61, 85, 215, 103, 71, 109, 214, 115, + 106, 212, 84, 63, 63, 107, 84, 78, 78, 127, + 127, 82, 211, 83, 83, 128, 119, 128, 155, 155, + 129, 129, 127, 127, 129, 129, 84, 62, 129, 129, + 155, 155, 210, 125, 209, 84, 208, 155, 155, 155, + 155, 206, 84, 155, 155, 155, 155, 155, 155, 205, + 204, 84, 173, 57, 203, 57, 57, 57, 57, 57, + 57, 60, 202, 201, 60, 60, 60, 60, 60, 65, + 200, 65, 65, 69, 199, 198, 69, 69, 69, 69, - 210, 92, 122, 209, 208, 122, 123, 123, 207, 123, - 126, 206, 205, 126, 126, 126, 126, 126, 154, 154, - 204, 154, 156, 156, 156, 156, 156, 156, 156, 156, - 175, 175, 175, 175, 175, 175, 175, 175, 213, 213, - 213, 203, 213, 213, 213, 213, 220, 220, 220, 220, - 220, 220, 220, 220, 202, 201, 200, 199, 198, 197, - 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, - 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, - 155, 155, 174, 173, 172, 171, 170, 169, 168, 167, - 166, 165, 164, 163, 162, 161, 160, 159, 158, 124, + 69, 92, 197, 196, 92, 121, 195, 194, 121, 122, + 122, 193, 122, 125, 192, 191, 125, 125, 125, 125, + 125, 152, 152, 190, 152, 154, 154, 154, 154, 154, + 154, 154, 154, 172, 172, 172, 172, 172, 172, 172, + 172, 207, 207, 207, 189, 207, 207, 207, 207, 213, + 213, 213, 213, 213, 213, 213, 213, 188, 187, 186, + 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, + 175, 174, 153, 153, 171, 170, 169, 168, 167, 166, + 165, 164, 163, 162, 161, 160, 159, 158, 157, 156, + 123, 123, 153, 151, 150, 149, 148, 147, 146, 145, - 124, 155, 153, 152, 151, 150, 149, 148, 147, 146, - 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, - 135, 134, 133, 132, 127, 125, 69, 124, 60, 121, - 56, 118, 117, 114, 113, 112, 104, 98, 97, 96, - 95, 94, 93, 89, 86, 72, 56, 224, 3, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 144, 143, 142, 141, 140, 139, 138, 137, 136, 135, + 134, 133, 132, 131, 126, 124, 69, 123, 60, 120, + 56, 117, 116, 113, 112, 111, 110, 104, 98, 97, + 96, 95, 94, 93, 89, 86, 72, 56, 216, 3, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224 + 216, 216, 216, 216, 216, 216 } ; -static const flex_int16_t yy_chk[417] = +static const flex_int16_t yy_chk[407] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -829,56 +825,55 @@ static const flex_int16_t yy_chk[417] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 8, 9, 10, - 10, 11, 11, 12, 10, 13, 11, 17, 20, 20, - 21, 19, 26, 26, 8, 21, 44, 17, 12, 19, - 19, 21, 22, 44, 22, 22, 23, 40, 23, 23, + 1, 1, 1, 1, 1, 1, 8, 9, 10, 10, + 11, 11, 12, 10, 13, 11, 17, 20, 20, 21, + 19, 26, 26, 8, 21, 69, 17, 12, 19, 19, + 21, 22, 40, 22, 22, 23, 53, 23, 23, 28, - 28, 28, 43, 9, 41, 45, 13, 22, 41, 45, - 40, 23, 53, 49, 22, 43, 60, 41, 63, 63, - 43, 69, 233, 22, 49, 78, 78, 23, 82, 82, - 83, 219, 83, 83, 84, 218, 84, 128, 128, 84, - 84, 127, 127, 129, 129, 83, 130, 130, 156, 156, - 128, 60, 69, 53, 157, 157, 127, 175, 175, 203, - 203, 83, 213, 213, 220, 220, 128, 215, 211, 157, - 225, 209, 225, 225, 225, 225, 225, 225, 226, 208, - 207, 226, 226, 226, 226, 226, 227, 205, 227, 227, - 228, 204, 202, 228, 228, 228, 228, 228, 229, 201, + 28, 225, 9, 41, 40, 13, 22, 41, 43, 49, + 23, 44, 60, 22, 212, 41, 69, 44, 209, 49, + 43, 205, 22, 63, 63, 43, 23, 78, 78, 82, + 82, 83, 203, 83, 83, 84, 53, 84, 126, 126, + 84, 84, 127, 127, 128, 128, 83, 60, 129, 129, + 154, 154, 202, 126, 200, 127, 199, 155, 155, 172, + 172, 197, 83, 198, 198, 207, 207, 213, 213, 196, + 194, 127, 155, 217, 193, 217, 217, 217, 217, 217, + 217, 218, 192, 191, 218, 218, 218, 218, 218, 219, + 190, 219, 219, 220, 189, 187, 220, 220, 220, 220, - 199, 229, 230, 198, 197, 230, 231, 231, 196, 231, - 232, 195, 194, 232, 232, 232, 232, 232, 234, 234, - 193, 234, 235, 235, 235, 235, 235, 235, 235, 235, - 236, 236, 236, 236, 236, 236, 236, 236, 237, 237, - 237, 191, 237, 237, 237, 237, 238, 238, 238, 238, - 238, 238, 238, 238, 189, 188, 187, 186, 185, 184, - 183, 181, 180, 179, 177, 176, 174, 172, 171, 170, - 169, 168, 167, 166, 165, 163, 162, 161, 159, 158, - 155, 154, 153, 152, 151, 150, 149, 148, 146, 145, - 144, 143, 142, 141, 140, 139, 138, 137, 136, 124, + 220, 221, 185, 184, 221, 222, 183, 182, 222, 223, + 223, 181, 223, 224, 180, 178, 224, 224, 224, 224, + 224, 226, 226, 177, 226, 227, 227, 227, 227, 227, + 227, 227, 227, 228, 228, 228, 228, 228, 228, 228, + 228, 229, 229, 229, 176, 229, 229, 229, 229, 230, + 230, 230, 230, 230, 230, 230, 230, 174, 173, 171, + 169, 168, 167, 166, 165, 164, 163, 161, 160, 159, + 157, 156, 153, 152, 151, 150, 149, 148, 147, 146, + 144, 143, 142, 141, 140, 139, 138, 137, 136, 135, + 123, 122, 121, 117, 116, 115, 114, 113, 112, 110, - 123, 122, 118, 117, 116, 115, 114, 113, 111, 110, 107, 106, 105, 104, 102, 101, 100, 99, 98, 97, 95, 94, 91, 87, 80, 75, 71, 65, 62, 58, - 56, 51, 50, 48, 47, 46, 42, 39, 38, 37, - 34, 33, 32, 27, 24, 16, 5, 3, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 56, 51, 50, 48, 47, 46, 45, 42, 39, 38, + 37, 34, 33, 32, 27, 24, 16, 5, 3, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224 + 216, 216, 216, 216, 216, 216 } ; /* Table of booleans, true if rule could match eol. */ -static const flex_int32_t yy_rule_can_match_eol[95] = +static const flex_int32_t yy_rule_can_match_eol[94] = { 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; @@ -952,6 +947,19 @@ static int Sc_ScanIdent(); #endif Vector lines; +static S32 gCachedLineContextCount = -1; // -1 = needs refresh + +static S32 getLineContextCount() +{ + if (gCachedLineContextCount < 0) + gCachedLineContextCount = Con::getIntVariable("$scriptErrorLineCount", 10); + return gCachedLineContextCount; +} + +void CMDFlushLineContextCache() +{ + gCachedLineContextCount = -1; +} // Install our own input code... #undef CMDgetc @@ -961,24 +969,26 @@ int CMDgetc(); #ifndef isatty inline int isatty(int) { return 0; } #endif + static int yycolumn = 1; -// Wrap our getc, so that lex doesn't try to do its own buffering/file IO. -#define YY_INPUT(buf,result,max_size) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = CMDgetc()) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; yycolumn = 1;\ - result = n; \ + +#define YY_INPUT(buf, result, max_size) \ + { \ + int c = '*', n; \ + for (n = 0; n < max_size && \ + (c = CMDgetc()) != EOF && c != '\n'; ++n) \ + buf[n] = (char)c; \ + if (c == '\n') { buf[n++] = (char)c; yycolumn = 1; } \ + result = n; \ } -#define YY_USER_ACTION do { \ - CMDlloc.first_line = CMDlloc.last_line = yylineno; \ - CMDlloc.first_column = yycolumn; CMDlloc.last_column = yycolumn + yyleng - 1; \ - yycolumn += yyleng; \ - } while(0); +#define YY_USER_ACTION \ + do { \ + CMDlloc.first_line = CMDlloc.last_line = yylineno; \ + CMDlloc.first_column = yycolumn; \ + CMDlloc.last_column = yycolumn + yyleng - 1; \ + yycolumn += yyleng; \ + } while (0); // File state void CMDSetScanBuffer(const char *sb, const char *fn); @@ -989,8 +999,8 @@ void CMDerror(const char * s, ...); // Reset the parser. void CMDrestart(FILE *in); -#line 992 "CMDscan.cpp" -#line 993 "CMDscan.cpp" +#line 1002 "CMDscan.cpp" +#line 1003 "CMDscan.cpp" #define INITIAL 0 @@ -1205,11 +1215,10 @@ YY_DECL } { -#line 113 "CMDscan.l" +#line 128 "CMDscan.l" -#line 115 "CMDscan.l" - ; -#line 1212 "CMDscan.cpp" + +#line 1221 "CMDscan.cpp" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -1236,13 +1245,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 225 ) + if ( yy_current_state >= 217 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 349 ); + while ( yy_base[yy_current_state] != 340 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -1278,33 +1287,37 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 116 "CMDscan.l" -{ } +#line 130 "CMDscan.l" +{ /* consume whitespace */ } YY_BREAK case 2: /* rule 2 can match eol */ YY_RULE_SETUP -#line 117 "CMDscan.l" -{ return(Sc_ScanDocBlock()); } +#line 132 "CMDscan.l" +{ return Sc_ScanDocBlock(); } YY_BREAK case 3: YY_RULE_SETUP -#line 118 "CMDscan.l" -; +#line 133 "CMDscan.l" +{ /* line comment — discard */ } YY_BREAK case 4: YY_RULE_SETUP -#line 119 "CMDscan.l" -; +#line 134 "CMDscan.l" +{ /* bare CR — discard */ } YY_BREAK case 5: /* rule 5 can match eol */ YY_RULE_SETUP -#line 120 "CMDscan.l" -{ +#line 136 "CMDscan.l" +{ yycolumn = 1; - lines.push_back(String::ToString("%s", yytext+1)); - if (lines.size() > Con::getIntVariable("$scriptErrorLineCount", 10)) + + // Push the line text (everything after the newline) into the error + // context buffer, then trim to the configured maximum. + lines.push_back(String::ToString("%s", yytext + 1)); + S32 maxLines = getLineContextCount(); + while (lines.size() > maxLines) lines.erase(lines.begin()); yyless(1); @@ -1312,399 +1325,417 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 128 "CMDscan.l" -{ return(Sc_ScanString(STRATOM)); } +#line 149 "CMDscan.l" +{ return Sc_ScanString(STRATOM); } YY_BREAK case 7: YY_RULE_SETUP -#line 129 "CMDscan.l" -{ return(Sc_ScanString(TAGATOM)); } +#line 150 "CMDscan.l" +{ return Sc_ScanString(TAGATOM); } YY_BREAK case 8: YY_RULE_SETUP -#line 130 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opEQ, yylineno ); return opEQ; } +#line 152 "CMDscan.l" +{ CMDlval.i = MakeToken(opEQ, yylineno); return opEQ; } YY_BREAK case 9: YY_RULE_SETUP -#line 131 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opNE, yylineno ); return opNE; } +#line 153 "CMDscan.l" +{ CMDlval.i = MakeToken(opNE, yylineno); return opNE; } YY_BREAK case 10: YY_RULE_SETUP -#line 132 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opGE, yylineno ); return opGE; } +#line 154 "CMDscan.l" +{ CMDlval.i = MakeToken(opGE, yylineno); return opGE; } YY_BREAK case 11: YY_RULE_SETUP -#line 133 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opLE, yylineno ); return opLE; } +#line 155 "CMDscan.l" +{ CMDlval.i = MakeToken(opLE, yylineno); return opLE; } YY_BREAK case 12: YY_RULE_SETUP -#line 134 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opAND, yylineno ); return opAND; } +#line 156 "CMDscan.l" +{ CMDlval.i = MakeToken(opAND, yylineno); return opAND; } YY_BREAK case 13: YY_RULE_SETUP -#line 135 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opOR, yylineno ); return opOR; } +#line 157 "CMDscan.l" +{ CMDlval.i = MakeToken(opOR, yylineno); return opOR; } YY_BREAK case 14: YY_RULE_SETUP -#line 136 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opCOLONCOLON, yylineno ); return opCOLONCOLON; } +#line 158 "CMDscan.l" +{ CMDlval.i = MakeToken(opCOLONCOLON, yylineno); return opCOLONCOLON; } YY_BREAK case 15: YY_RULE_SETUP -#line 137 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opMINUSMINUS, yylineno ); return opMINUSMINUS; } +#line 159 "CMDscan.l" +{ CMDlval.i = MakeToken(opMINUSMINUS, yylineno); return opMINUSMINUS; } YY_BREAK case 16: YY_RULE_SETUP -#line 138 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opPLUSPLUS, yylineno ); return opPLUSPLUS; } +#line 160 "CMDscan.l" +{ CMDlval.i = MakeToken(opPLUSPLUS, yylineno); return opPLUSPLUS; } YY_BREAK case 17: YY_RULE_SETUP -#line 139 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSTREQ, yylineno ); return opSTREQ; } +#line 161 "CMDscan.l" +{ CMDlval.i = MakeToken(opSTREQ, yylineno); return opSTREQ; } YY_BREAK case 18: YY_RULE_SETUP -#line 140 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSTRNE, yylineno ); return opSTRNE; } +#line 162 "CMDscan.l" +{ CMDlval.i = MakeToken(opSTRNE, yylineno); return opSTRNE; } YY_BREAK case 19: YY_RULE_SETUP -#line 141 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSHL, yylineno ); return opSHL; } +#line 163 "CMDscan.l" +{ CMDlval.i = MakeToken(opSHL, yylineno); return opSHL; } YY_BREAK case 20: YY_RULE_SETUP -#line 142 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSHR, yylineno ); return opSHR; } +#line 164 "CMDscan.l" +{ CMDlval.i = MakeToken(opSHR, yylineno); return opSHR; } YY_BREAK case 21: YY_RULE_SETUP -#line 143 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opPLASN, yylineno ); return opPLASN; } +#line 165 "CMDscan.l" +{ CMDlval.i = MakeToken(opPLASN, yylineno); return opPLASN; } YY_BREAK case 22: YY_RULE_SETUP -#line 144 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opMIASN, yylineno ); return opMIASN; } +#line 166 "CMDscan.l" +{ CMDlval.i = MakeToken(opMIASN, yylineno); return opMIASN; } YY_BREAK case 23: YY_RULE_SETUP -#line 145 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opMLASN, yylineno ); return opMLASN; } +#line 167 "CMDscan.l" +{ CMDlval.i = MakeToken(opMLASN, yylineno); return opMLASN; } YY_BREAK case 24: YY_RULE_SETUP -#line 146 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opDVASN, yylineno ); return opDVASN; } +#line 168 "CMDscan.l" +{ CMDlval.i = MakeToken(opDVASN, yylineno); return opDVASN; } YY_BREAK case 25: YY_RULE_SETUP -#line 147 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opMODASN, yylineno ); return opMODASN; } +#line 169 "CMDscan.l" +{ CMDlval.i = MakeToken(opMODASN, yylineno); return opMODASN; } YY_BREAK case 26: YY_RULE_SETUP -#line 148 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opANDASN, yylineno ); return opANDASN; } +#line 170 "CMDscan.l" +{ CMDlval.i = MakeToken(opANDASN, yylineno); return opANDASN; } YY_BREAK case 27: YY_RULE_SETUP -#line 149 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opXORASN, yylineno ); return opXORASN; } +#line 171 "CMDscan.l" +{ CMDlval.i = MakeToken(opXORASN, yylineno); return opXORASN; } YY_BREAK case 28: YY_RULE_SETUP -#line 150 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opORASN, yylineno ); return opORASN; } +#line 172 "CMDscan.l" +{ CMDlval.i = MakeToken(opORASN, yylineno); return opORASN; } YY_BREAK case 29: YY_RULE_SETUP -#line 151 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSLASN, yylineno ); return opSLASN; } +#line 173 "CMDscan.l" +{ CMDlval.i = MakeToken(opSLASN, yylineno); return opSLASN; } YY_BREAK case 30: YY_RULE_SETUP -#line 152 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSRASN, yylineno ); return opSRASN; } +#line 174 "CMDscan.l" +{ CMDlval.i = MakeToken(opSRASN, yylineno); return opSRASN; } YY_BREAK case 31: YY_RULE_SETUP -#line 153 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opINTNAME, yylineno ); return opINTNAME; } +#line 175 "CMDscan.l" +{ CMDlval.i = MakeToken(opINTNAME, yylineno); return opINTNAME; } YY_BREAK case 32: YY_RULE_SETUP -#line 154 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opINTNAMER, yylineno ); return opINTNAMER; } +#line 176 "CMDscan.l" +{ CMDlval.i = MakeToken(opINTNAMER, yylineno); return opINTNAMER; } YY_BREAK + +// String concatenation operators. All four return the '@' token; the +// distinguishing data is the separator character stored in the token value. +// The grammar rule expr '@' expr uses $2.value as the appendChar +// argument to StrcatExprNode — so plain '@' gets 0 (no separator), +// NL/TAB/SPC get their respective ASCII codes. + case 33: YY_RULE_SETUP -#line 155 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( '\n', yylineno ); return '@'; } +#line 184 "CMDscan.l" +{ CMDlval.i = MakeToken('\n', yylineno); return '@'; } YY_BREAK case 34: YY_RULE_SETUP -#line 156 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( '\t', yylineno ); return '@'; } +#line 185 "CMDscan.l" +{ CMDlval.i = MakeToken('\t', yylineno); return '@'; } YY_BREAK case 35: YY_RULE_SETUP -#line 157 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( ' ', yylineno ); return '@'; } +#line 186 "CMDscan.l" +{ CMDlval.i = MakeToken(' ', yylineno); return '@'; } YY_BREAK case 36: YY_RULE_SETUP -#line 158 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( 0, yylineno ); return '@'; } +#line 187 "CMDscan.l" +{ CMDlval.i = MakeToken(0, yylineno); return '@'; } YY_BREAK case 37: YY_RULE_SETUP -#line 159 "CMDscan.l" -{ /* this comment stops syntax highlighting from getting messed up when editing the lexer in TextPad */ - int c = 0, l; - for ( ; ; ) - { - l = c; - c = yyinput(); - - // Is this an open comment? - if ( c == EOF ) - { - CMDerror( "unexpected end of file found in comment" ); - break; - } - - // Did we find the end of the comment? - else if ( l == '*' && c == '/' ) - break; - } - } - YY_BREAK -case 38: -#line 179 "CMDscan.l" -case 39: -#line 180 "CMDscan.l" -case 40: -#line 181 "CMDscan.l" -case 41: -#line 182 "CMDscan.l" -case 42: -#line 183 "CMDscan.l" -case 43: -#line 184 "CMDscan.l" -case 44: -#line 185 "CMDscan.l" -case 45: -#line 186 "CMDscan.l" -case 46: -#line 187 "CMDscan.l" -case 47: -#line 188 "CMDscan.l" -case 48: #line 189 "CMDscan.l" +{ + // Block comment — consume until '*/' + int c = 0, prev = 0; + for (;;) + { + prev = c; + c = yyinput(); + if (c == EOF) + { + CMDerror("unexpected end of file inside block comment"); + break; + } + if (prev == '*' && c == '/') + break; + } +} + YY_BREAK + +// Single-character punctuation tokens. + +case 38: +#line 209 "CMDscan.l" +case 39: +#line 210 "CMDscan.l" +case 40: +#line 211 "CMDscan.l" +case 41: +#line 212 "CMDscan.l" +case 42: +#line 213 "CMDscan.l" +case 43: +#line 214 "CMDscan.l" +case 44: +#line 215 "CMDscan.l" +case 45: +#line 216 "CMDscan.l" +case 46: +#line 217 "CMDscan.l" +case 47: +#line 218 "CMDscan.l" +case 48: +#line 219 "CMDscan.l" case 49: -#line 190 "CMDscan.l" +#line 220 "CMDscan.l" case 50: -#line 191 "CMDscan.l" +#line 221 "CMDscan.l" case 51: -#line 192 "CMDscan.l" +#line 222 "CMDscan.l" case 52: -#line 193 "CMDscan.l" +#line 223 "CMDscan.l" case 53: -#line 194 "CMDscan.l" +#line 224 "CMDscan.l" case 54: -#line 195 "CMDscan.l" +#line 225 "CMDscan.l" case 55: -#line 196 "CMDscan.l" +#line 226 "CMDscan.l" case 56: -#line 197 "CMDscan.l" +#line 227 "CMDscan.l" case 57: -#line 198 "CMDscan.l" +#line 228 "CMDscan.l" case 58: -#line 199 "CMDscan.l" +#line 229 "CMDscan.l" case 59: -#line 200 "CMDscan.l" +#line 230 "CMDscan.l" case 60: -#line 201 "CMDscan.l" +#line 231 "CMDscan.l" case 61: YY_RULE_SETUP -#line 201 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( CMDtext[ 0 ], yylineno ); return CMDtext[ 0 ]; } +#line 231 "CMDscan.l" +{ CMDlval.i = MakeToken(CMDtext[0], yylineno); return CMDtext[0]; } YY_BREAK + +// Reserved words — must be listed before {ID} to take priority. +// NOTE: "namespace" and "class" are intentionally NOT listed here. +// rwNAMESPACE and rwCLASS were previously declared as grammar tokens but +// had no productions that used them and no lexer rules that produced them. +// They have been removed from the grammar. The words "namespace" and +// "class" therefore lex as plain IDENT tokens and can be used as object +// names or field names in script without causing parse errors. If you add +// syntax that consumes those keywords, add both the lexer rule and the +// grammar token declaration at the same time. + case 62: YY_RULE_SETUP -#line 202 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwIN, yylineno ); return(rwIN); } +#line 243 "CMDscan.l" +{ CMDlval.i = MakeToken(rwIN, yylineno); return rwIN; } YY_BREAK case 63: YY_RULE_SETUP -#line 203 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwCASEOR, yylineno ); return(rwCASEOR); } +#line 244 "CMDscan.l" +{ CMDlval.i = MakeToken(rwCASEOR, yylineno); return rwCASEOR; } YY_BREAK case 64: YY_RULE_SETUP -#line 204 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwBREAK, yylineno ); return(rwBREAK); } +#line 245 "CMDscan.l" +{ CMDlval.i = MakeToken(rwBREAK, yylineno); return rwBREAK; } YY_BREAK case 65: YY_RULE_SETUP -#line 205 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwRETURN, yylineno ); return(rwRETURN); } +#line 246 "CMDscan.l" +{ CMDlval.i = MakeToken(rwRETURN, yylineno); return rwRETURN; } YY_BREAK case 66: YY_RULE_SETUP -#line 206 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwELSE, yylineno ); return(rwELSE); } +#line 247 "CMDscan.l" +{ CMDlval.i = MakeToken(rwELSE, yylineno); return rwELSE; } YY_BREAK case 67: YY_RULE_SETUP -#line 207 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwASSERT, yylineno ); return(rwASSERT); } +#line 248 "CMDscan.l" +{ CMDlval.i = MakeToken(rwASSERT, yylineno); return rwASSERT; } YY_BREAK case 68: YY_RULE_SETUP -#line 208 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwWHILE, yylineno ); return(rwWHILE); } +#line 249 "CMDscan.l" +{ CMDlval.i = MakeToken(rwWHILE, yylineno); return rwWHILE; } YY_BREAK case 69: YY_RULE_SETUP -#line 209 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDO, yylineno ); return(rwDO); } +#line 250 "CMDscan.l" +{ CMDlval.i = MakeToken(rwDO, yylineno); return rwDO; } YY_BREAK case 70: YY_RULE_SETUP -#line 210 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwIF, yylineno ); return(rwIF); } +#line 251 "CMDscan.l" +{ CMDlval.i = MakeToken(rwIF, yylineno); return rwIF; } YY_BREAK case 71: YY_RULE_SETUP -#line 211 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwFOREACHSTR, yylineno ); return(rwFOREACHSTR); } +#line 252 "CMDscan.l" +{ CMDlval.i = MakeToken(rwFOREACHSTR, yylineno); return rwFOREACHSTR; } YY_BREAK case 72: YY_RULE_SETUP -#line 212 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwFOREACH, yylineno ); return(rwFOREACH); } +#line 253 "CMDscan.l" +{ CMDlval.i = MakeToken(rwFOREACH, yylineno); return rwFOREACH; } YY_BREAK case 73: YY_RULE_SETUP -#line 213 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwFOR, yylineno ); return(rwFOR); } +#line 254 "CMDscan.l" +{ CMDlval.i = MakeToken(rwFOR, yylineno); return rwFOR; } YY_BREAK case 74: YY_RULE_SETUP -#line 214 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwCONTINUE, yylineno ); return(rwCONTINUE); } +#line 255 "CMDscan.l" +{ CMDlval.i = MakeToken(rwCONTINUE, yylineno); return rwCONTINUE; } YY_BREAK case 75: YY_RULE_SETUP -#line 215 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDEFINE, yylineno ); return(rwDEFINE); } +#line 256 "CMDscan.l" +{ CMDlval.i = MakeToken(rwDEFINE, yylineno); return rwDEFINE; } YY_BREAK case 76: YY_RULE_SETUP -#line 216 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDECLARE, yylineno ); return(rwDECLARE); } +#line 257 "CMDscan.l" +{ CMDlval.i = MakeToken(rwDECLARE, yylineno); return rwDECLARE; } YY_BREAK case 77: YY_RULE_SETUP -#line 217 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDECLARESINGLETON, yylineno ); return(rwDECLARESINGLETON); } +#line 258 "CMDscan.l" +{ CMDlval.i = MakeToken(rwDECLARESINGLETON, yylineno); return rwDECLARESINGLETON; } YY_BREAK case 78: YY_RULE_SETUP -#line 218 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDATABLOCK, yylineno ); return(rwDATABLOCK); } +#line 259 "CMDscan.l" +{ CMDlval.i = MakeToken(rwDATABLOCK, yylineno); return rwDATABLOCK; } YY_BREAK case 79: YY_RULE_SETUP -#line 219 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwCASE, yylineno ); return(rwCASE); } +#line 260 "CMDscan.l" +{ CMDlval.i = MakeToken(rwCASE, yylineno); return rwCASE; } YY_BREAK case 80: YY_RULE_SETUP -#line 220 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwSWITCHSTR, yylineno ); return(rwSWITCHSTR); } +#line 261 "CMDscan.l" +{ CMDlval.i = MakeToken(rwSWITCHSTR, yylineno); return rwSWITCHSTR; } YY_BREAK case 81: YY_RULE_SETUP -#line 221 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwSWITCH, yylineno ); return(rwSWITCH); } +#line 262 "CMDscan.l" +{ CMDlval.i = MakeToken(rwSWITCH, yylineno); return rwSWITCH; } YY_BREAK case 82: YY_RULE_SETUP -#line 222 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDEFAULT, yylineno ); return(rwDEFAULT); } +#line 263 "CMDscan.l" +{ CMDlval.i = MakeToken(rwDEFAULT, yylineno); return rwDEFAULT; } YY_BREAK case 83: YY_RULE_SETUP -#line 223 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwPACKAGE, yylineno ); return(rwPACKAGE); } +#line 264 "CMDscan.l" +{ CMDlval.i = MakeToken(rwPACKAGE, yylineno); return rwPACKAGE; } YY_BREAK + +// Boolean literals — return INTCONST so the parser treats them as integers. + case 84: YY_RULE_SETUP -#line 224 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwNAMESPACE, yylineno ); return(rwNAMESPACE); } +#line 268 "CMDscan.l" +{ CMDlval.i = MakeToken(1, yylineno); return INTCONST; } YY_BREAK case 85: YY_RULE_SETUP -#line 225 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( 1, yylineno ); return INTCONST; } +#line 269 "CMDscan.l" +{ CMDlval.i = MakeToken(0, yylineno); return INTCONST; } YY_BREAK case 86: YY_RULE_SETUP -#line 226 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( 0, yylineno ); return INTCONST; } +#line 271 "CMDscan.l" +{ return Sc_ScanVar(); } YY_BREAK case 87: YY_RULE_SETUP -#line 227 "CMDscan.l" -{ return(Sc_ScanVar()); } +#line 272 "CMDscan.l" +{ return Sc_ScanIdent(); } YY_BREAK case 88: YY_RULE_SETUP -#line 229 "CMDscan.l" -{ return Sc_ScanIdent(); } +#line 273 "CMDscan.l" +{ return Sc_ScanHex(); } YY_BREAK case 89: YY_RULE_SETUP -#line 230 "CMDscan.l" -return(Sc_ScanHex()); +#line 274 "CMDscan.l" +{ CMDtext[CMDleng] = 0; + CMDlval.i = MakeToken(dAtoi(CMDtext), yylineno); + return INTCONST; } YY_BREAK case 90: YY_RULE_SETUP -#line 231 "CMDscan.l" -{ CMDtext[CMDleng] = 0; CMDlval.i = MakeToken< int >( dAtoi(CMDtext), yylineno ); return INTCONST; } +#line 277 "CMDscan.l" +{ return Sc_ScanNum(); } YY_BREAK case 91: YY_RULE_SETUP -#line 232 "CMDscan.l" -return Sc_ScanNum(); +#line 278 "CMDscan.l" +{ return ILLEGAL_TOKEN; } YY_BREAK case 92: YY_RULE_SETUP -#line 233 "CMDscan.l" -return(ILLEGAL_TOKEN); +#line 279 "CMDscan.l" +{ return ILLEGAL_TOKEN; } YY_BREAK case 93: YY_RULE_SETUP -#line 234 "CMDscan.l" -return(ILLEGAL_TOKEN); - YY_BREAK -case 94: -YY_RULE_SETUP -#line 235 "CMDscan.l" +#line 280 "CMDscan.l" ECHO; YY_BREAK -#line 1707 "CMDscan.cpp" +#line 1738 "CMDscan.cpp" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -2001,7 +2032,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 225 ) + if ( yy_current_state >= 217 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; @@ -2029,11 +2060,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 225 ) + if ( yy_current_state >= 217 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 224); + yy_is_jam = (yy_current_state == 216); return yy_is_jam ? 0 : yy_current_state; } @@ -2680,7 +2711,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 235 "CMDscan.l" +#line 280 "CMDscan.l" static const char *scanBuffer; @@ -2688,48 +2719,69 @@ static const char *fileName; static int scanIndex; extern YYLTYPE CMDlloc; -const char * CMDGetCurrentFile() +const char* CMDGetCurrentFile() { return fileName; } +int CMDGetCurrentLine() { return yylineno; } + +void CMDSetScanBuffer(const char* sb, const char* fn) { - return fileName; + scanBuffer = sb; + fileName = fn; + scanIndex = 0; + yylineno = 1; + gCachedLineContextCount = -1; // re-read $scriptErrorLineCount for each file + lines.clear(); } -int CMDGetCurrentLine() +int CMDgetc() { - return yylineno; + int c = scanBuffer[scanIndex]; + if (c) + scanIndex++; + else + c = -1; // EOF sentinel expected by YY_INPUT + return c; +} + +int CMDwrap() +{ + return 1; } extern bool gConsoleSyntaxError; -void CMDerror(const char *format, ...) +void CMDerror(const char* format, ...) { Compiler::gSyntaxError = true; const int BUFMAX = 1024; char tempBuf[BUFMAX]; va_list args; - va_start( args, format ); + va_start(args, format); #ifdef TORQUE_OS_WIN - _vsnprintf( tempBuf, BUFMAX, format, args ); + _vsnprintf(tempBuf, BUFMAX, format, args); #else - vsnprintf( tempBuf, BUFMAX, format, args ); + vsnprintf(tempBuf, BUFMAX, format, args); #endif va_end(args); - if(fileName) + if (fileName) { - Con::errorf(ConsoleLogEntry::Script, "%s Line: %d - %s", fileName, yylineno, tempBuf); - // Update the script-visible error buffer. - const char *prevStr = Con::getVariable("$ScriptError"); + Con::errorf(ConsoleLogEntry::Script, "%s Line: %d - %s", + fileName, yylineno, tempBuf); + + // Append to the script-visible error string and bump the hash so + // listeners know a new error arrived. + const char* prevStr = Con::getVariable("$ScriptError"); if (prevStr[0]) - dSprintf(tempBuf, sizeof(tempBuf), "%s\n%s Line: %d - Syntax error.", prevStr, fileName, yylineno); + dSprintf(tempBuf, sizeof(tempBuf), "%s\n%s Line: %d - Syntax error.", + prevStr, fileName, yylineno); else - dSprintf(tempBuf, sizeof(tempBuf), "%s Line: %d - Syntax error.", fileName, yylineno); + dSprintf(tempBuf, sizeof(tempBuf), "%s Line: %d - Syntax error.", + fileName, yylineno); Con::setVariable("$ScriptError", tempBuf); - // We also need to mark that we came up with a new error. - static S32 sScriptErrorHash=1000; + static S32 sScriptErrorHash = 1000; Con::setIntVariable("$ScriptErrorHash", sScriptErrorHash++); - } else { @@ -2737,30 +2789,6 @@ void CMDerror(const char *format, ...) } } -void CMDSetScanBuffer(const char *sb, const char *fn) -{ - scanBuffer = sb; - fileName = fn; - scanIndex = 0; - yylineno = 1; - lines.clear(); -} - -int CMDgetc() -{ - int ret = scanBuffer[scanIndex]; - if(ret) - scanIndex++; - else - ret = -1; - return ret; -} - -int CMDwrap() -{ - return 1; -} - static int Sc_ScanVar() { // Truncate the temp buffer... @@ -2773,63 +2801,60 @@ static int Sc_ScanVar() static int charConv(int in) { - switch(in) + switch (in) { - case 'r': - return '\r'; - case 'n': - return '\n'; - case 't': - return '\t'; - default: - return in; + case 'r': return '\r'; + case 'n': return '\n'; + case 't': return '\t'; + default: return in; } } static int getHexDigit(char c) { - if(c >= '0' && c <= '9') - return c - '0'; - if(c >= 'A' && c <= 'F') - return c - 'A' + 10; - if(c >= 'a' && c <= 'f') - return c - 'a' + 10; + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; return -1; } static int Sc_ScanDocBlock() { - S32 len = dStrlen(CMDtext); - char* text = (char *) consoleAlloc(len + 1); - S32 line = yylineno; + S32 len = dStrlen(CMDtext); + char* text = (char*)consoleAlloc(len + 1); + S32 line = yylineno; - for( S32 i = 0, j = 0; j <= len; j++ ) + for (S32 i = 0, j = 0; j <= len; j++) { - if( ( j <= (len - 2) ) && ( CMDtext[j] == '/' ) && ( CMDtext[j + 1] == '/' ) && ( CMDtext[j + 2] == '/' ) ) + // Strip leading '///' on each doc line. + if ((j <= (len - 2)) && + CMDtext[j] == '/' && + CMDtext[j + 1] == '/' && + CMDtext[j + 2] == '/') { j += 2; continue; } - - if( CMDtext[j] == '\r' ) - continue; - + if (CMDtext[j] == '\r') continue; text[i++] = CMDtext[j]; } - CMDlval.str = MakeToken< char* >( text, line ); - return(DOCBLOCK); + CMDlval.str = MakeToken(text, line); + return DOCBLOCK; } static int Sc_ScanString(int ret) { - CMDtext[CMDleng - 1] = 0; - if(!collapseEscape(CMDtext+1)) - return -1; + // CMDtext arrives as "content" or 'content' (with quotes). + // Replace the closing quote with a null terminator so collapseEscape + // can work on the interior without seeing the delimiter. + CMDtext[CMDleng - 1] = '\0'; + if (!collapseEscape(CMDtext + 1)) + return -1; - dsize_t bufferLen = dStrlen( CMDtext ); - char* buffer = ( char* ) consoleAlloc( bufferLen ); - dStrcpy( buffer, CMDtext + 1, bufferLen ); + dsize_t allocSize = dStrlen(CMDtext); // = 1 + content_len (see above) + char* buffer = (char*)consoleAlloc(allocSize); + dStrcpy(buffer, CMDtext + 1, allocSize); // skip the opening quote CMDlval.str = MakeToken< char* >( buffer, yylineno ); return ret; @@ -2837,22 +2862,35 @@ static int Sc_ScanString(int ret) static int Sc_ScanIdent() { - ConsoleBaseType *type; - CMDtext[CMDleng] = 0; - if((type = ConsoleBaseType::getTypeByName(CMDtext)) != NULL) + // Check if the identifier is a registered engine type name (e.g. "Point3F"). + ConsoleBaseType* type = ConsoleBaseType::getTypeByName(CMDtext); + if (type) { - /* It's a type */ - CMDlval.i = MakeToken< int >( type->getTypeID(), yylineno ); + CMDlval.i = MakeToken(type->getTypeID(), yylineno); return TYPEIDENT; } - /* It's an identifier */ - CMDlval.s = MakeToken< StringTableEntry >( StringTable->insert(CMDtext), yylineno ); + CMDlval.s = MakeToken(StringTable->insert(CMDtext), yylineno); return IDENT; } +static int Sc_ScanNum() +{ + CMDtext[CMDleng] = 0; + CMDlval.f = MakeToken(dAtof(CMDtext), yylineno); + return FLTCONST; +} + +static int Sc_ScanHex() +{ + S32 val = 0; + dSscanf(CMDtext, "%x", &val); + CMDlval.i = MakeToken(val, yylineno); + return INTCONST; +} + void expandEscape(char *dest, const char *src) { U8 c; @@ -3020,21 +3058,6 @@ bool collapseEscape(char *buf) return true; } -static int Sc_ScanNum() -{ - CMDtext[CMDleng] = 0; - CMDlval.f = MakeToken< double >( dAtof(CMDtext), yylineno ); - return(FLTCONST); -} - -static int Sc_ScanHex() -{ - S32 val = 0; - dSscanf(CMDtext, "%x", &val); - CMDlval.i = MakeToken< int >( val, yylineno ); - return INTCONST; -} - void CMD_reset() { CMDrestart(NULL); diff --git a/Engine/source/console/torquescript/CMDscan.l b/Engine/source/console/torquescript/CMDscan.l index aa3a72733..af26df93d 100644 --- a/Engine/source/console/torquescript/CMDscan.l +++ b/Engine/source/console/torquescript/CMDscan.l @@ -56,6 +56,19 @@ static int Sc_ScanIdent(); #endif Vector lines; +static S32 gCachedLineContextCount = -1; // -1 = needs refresh + +static S32 getLineContextCount() +{ + if (gCachedLineContextCount < 0) + gCachedLineContextCount = Con::getIntVariable("$scriptErrorLineCount", 10); + return gCachedLineContextCount; +} + +void CMDFlushLineContextCache() +{ + gCachedLineContextCount = -1; +} // Install our own input code... #undef CMDgetc @@ -65,24 +78,26 @@ int CMDgetc(); #ifndef isatty inline int isatty(int) { return 0; } #endif + static int yycolumn = 1; -// Wrap our getc, so that lex doesn't try to do its own buffering/file IO. -#define YY_INPUT(buf,result,max_size) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = CMDgetc()) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; yycolumn = 1;\ - result = n; \ + +#define YY_INPUT(buf, result, max_size) \ + { \ + int c = '*', n; \ + for (n = 0; n < max_size && \ + (c = CMDgetc()) != EOF && c != '\n'; ++n) \ + buf[n] = (char)c; \ + if (c == '\n') { buf[n++] = (char)c; yycolumn = 1; } \ + result = n; \ } -#define YY_USER_ACTION do { \ - CMDlloc.first_line = CMDlloc.last_line = yylineno; \ - CMDlloc.first_column = yycolumn; CMDlloc.last_column = yycolumn + yyleng - 1; \ - yycolumn += yyleng; \ - } while(0); +#define YY_USER_ACTION \ + do { \ + CMDlloc.first_line = CMDlloc.last_line = yylineno; \ + CMDlloc.first_column = yycolumn; \ + CMDlloc.last_column = yycolumn + yyleng - 1; \ + yycolumn += yyleng; \ + } while (0); // File state void CMDSetScanBuffer(const char *sb, const char *fn); @@ -111,69 +126,85 @@ SPACE [ \t\v\f] HEXDIGIT [a-fA-F0-9] %% - ; -{SPACE}+ { } -("///"([^/\n\r][^\n\r]*)?[\n\r]+)+ { return(Sc_ScanDocBlock()); } -"//"[^\n\r]* ; -[\r] ; -\n.* { + +{SPACE}+ { /* consume whitespace */ } + +("///"([^/\n\r][^\n\r]*)?[\n\r]+)+ { return Sc_ScanDocBlock(); } +"//"[^\n\r]* { /* line comment — discard */ } +[\r] { /* bare CR — discard */ } + +\n.* { yycolumn = 1; - lines.push_back(String::ToString("%s", yytext+1)); - if (lines.size() > Con::getIntVariable("$scriptErrorLineCount", 10)) + + // Push the line text (everything after the newline) into the error + // context buffer, then trim to the configured maximum. + lines.push_back(String::ToString("%s", yytext + 1)); + S32 maxLines = getLineContextCount(); + while (lines.size() > maxLines) lines.erase(lines.begin()); yyless(1); } -\"(\\.|[^\\"\n\r])*\" { return(Sc_ScanString(STRATOM)); } -\'(\\.|[^\\'\n\r])*\' { return(Sc_ScanString(TAGATOM)); } -"==" { CMDlval.i = MakeToken< int >( opEQ, yylineno ); return opEQ; } -"!=" { CMDlval.i = MakeToken< int >( opNE, yylineno ); return opNE; } -">=" { CMDlval.i = MakeToken< int >( opGE, yylineno ); return opGE; } -"<=" { CMDlval.i = MakeToken< int >( opLE, yylineno ); return opLE; } -"&&" { CMDlval.i = MakeToken< int >( opAND, yylineno ); return opAND; } -"||" { CMDlval.i = MakeToken< int >( opOR, yylineno ); return opOR; } -"::" { CMDlval.i = MakeToken< int >( opCOLONCOLON, yylineno ); return opCOLONCOLON; } -"--" { CMDlval.i = MakeToken< int >( opMINUSMINUS, yylineno ); return opMINUSMINUS; } -"++" { CMDlval.i = MakeToken< int >( opPLUSPLUS, yylineno ); return opPLUSPLUS; } -"$=" { CMDlval.i = MakeToken< int >( opSTREQ, yylineno ); return opSTREQ; } -"!$=" { CMDlval.i = MakeToken< int >( opSTRNE, yylineno ); return opSTRNE; } -"<<" { CMDlval.i = MakeToken< int >( opSHL, yylineno ); return opSHL; } -">>" { CMDlval.i = MakeToken< int >( opSHR, yylineno ); return opSHR; } -"+=" { CMDlval.i = MakeToken< int >( opPLASN, yylineno ); return opPLASN; } -"-=" { CMDlval.i = MakeToken< int >( opMIASN, yylineno ); return opMIASN; } -"*=" { CMDlval.i = MakeToken< int >( opMLASN, yylineno ); return opMLASN; } -"/=" { CMDlval.i = MakeToken< int >( opDVASN, yylineno ); return opDVASN; } -"%=" { CMDlval.i = MakeToken< int >( opMODASN, yylineno ); return opMODASN; } -"&=" { CMDlval.i = MakeToken< int >( opANDASN, yylineno ); return opANDASN; } -"^=" { CMDlval.i = MakeToken< int >( opXORASN, yylineno ); return opXORASN; } -"|=" { CMDlval.i = MakeToken< int >( opORASN, yylineno ); return opORASN; } -"<<=" { CMDlval.i = MakeToken< int >( opSLASN, yylineno ); return opSLASN; } -">>=" { CMDlval.i = MakeToken< int >( opSRASN, yylineno ); return opSRASN; } -"->" { CMDlval.i = MakeToken< int >( opINTNAME, yylineno ); return opINTNAME; } -"-->" { CMDlval.i = MakeToken< int >( opINTNAMER, yylineno ); return opINTNAMER; } -"NL" { CMDlval.i = MakeToken< int >( '\n', yylineno ); return '@'; } -"TAB" { CMDlval.i = MakeToken< int >( '\t', yylineno ); return '@'; } -"SPC" { CMDlval.i = MakeToken< int >( ' ', yylineno ); return '@'; } -"@" { CMDlval.i = MakeToken< int >( 0, yylineno ); return '@'; } -"/*" { /* this comment stops syntax highlighting from getting messed up when editing the lexer in TextPad */ - int c = 0, l; - for ( ; ; ) - { - l = c; - c = yyinput(); - // Is this an open comment? - if ( c == EOF ) - { - CMDerror( "unexpected end of file found in comment" ); - break; - } +\"(\\.|[^\\"\n\r])*\" { return Sc_ScanString(STRATOM); } +\'(\\.|[^\\'\n\r])*\' { return Sc_ScanString(TAGATOM); } - // Did we find the end of the comment? - else if ( l == '*' && c == '/' ) - break; - } +"==" { CMDlval.i = MakeToken(opEQ, yylineno); return opEQ; } +"!=" { CMDlval.i = MakeToken(opNE, yylineno); return opNE; } +">=" { CMDlval.i = MakeToken(opGE, yylineno); return opGE; } +"<=" { CMDlval.i = MakeToken(opLE, yylineno); return opLE; } +"&&" { CMDlval.i = MakeToken(opAND, yylineno); return opAND; } +"||" { CMDlval.i = MakeToken(opOR, yylineno); return opOR; } +"::" { CMDlval.i = MakeToken(opCOLONCOLON, yylineno); return opCOLONCOLON; } +"--" { CMDlval.i = MakeToken(opMINUSMINUS, yylineno); return opMINUSMINUS; } +"++" { CMDlval.i = MakeToken(opPLUSPLUS, yylineno); return opPLUSPLUS; } +"$=" { CMDlval.i = MakeToken(opSTREQ, yylineno); return opSTREQ; } +"!$=" { CMDlval.i = MakeToken(opSTRNE, yylineno); return opSTRNE; } +"<<" { CMDlval.i = MakeToken(opSHL, yylineno); return opSHL; } +">>" { CMDlval.i = MakeToken(opSHR, yylineno); return opSHR; } +"+=" { CMDlval.i = MakeToken(opPLASN, yylineno); return opPLASN; } +"-=" { CMDlval.i = MakeToken(opMIASN, yylineno); return opMIASN; } +"*=" { CMDlval.i = MakeToken(opMLASN, yylineno); return opMLASN; } +"/=" { CMDlval.i = MakeToken(opDVASN, yylineno); return opDVASN; } +"%=" { CMDlval.i = MakeToken(opMODASN, yylineno); return opMODASN; } +"&=" { CMDlval.i = MakeToken(opANDASN, yylineno); return opANDASN; } +"^=" { CMDlval.i = MakeToken(opXORASN, yylineno); return opXORASN; } +"|=" { CMDlval.i = MakeToken(opORASN, yylineno); return opORASN; } +"<<=" { CMDlval.i = MakeToken(opSLASN, yylineno); return opSLASN; } +">>=" { CMDlval.i = MakeToken(opSRASN, yylineno); return opSRASN; } +"->" { CMDlval.i = MakeToken(opINTNAME, yylineno); return opINTNAME; } +"-->" { CMDlval.i = MakeToken(opINTNAMER, yylineno); return opINTNAMER; } +%{ +// String concatenation operators. All four return the '@' token; the +// distinguishing data is the separator character stored in the token value. +// The grammar rule expr '@' expr uses $2.value as the appendChar +// argument to StrcatExprNode — so plain '@' gets 0 (no separator), +// NL/TAB/SPC get their respective ASCII codes. +%} +"NL" { CMDlval.i = MakeToken('\n', yylineno); return '@'; } +"TAB" { CMDlval.i = MakeToken('\t', yylineno); return '@'; } +"SPC" { CMDlval.i = MakeToken(' ', yylineno); return '@'; } +"@" { CMDlval.i = MakeToken(0, yylineno); return '@'; } + +"/*" { + // Block comment — consume until '*/' + int c = 0, prev = 0; + for (;;) + { + prev = c; + c = yyinput(); + if (c == EOF) + { + CMDerror("unexpected end of file inside block comment"); + break; } + if (prev == '*' && c == '/') + break; + } +} +%{ +// Single-character punctuation tokens. +%} "?" | "[" | "]" | @@ -197,40 +228,55 @@ HEXDIGIT [a-fA-F0-9] "%" | "^" | "~" | -"=" { CMDlval.i = MakeToken< int >( CMDtext[ 0 ], yylineno ); return CMDtext[ 0 ]; } -"in" { CMDlval.i = MakeToken< int >( rwIN, yylineno ); return(rwIN); } -"or" { CMDlval.i = MakeToken< int >( rwCASEOR, yylineno ); return(rwCASEOR); } -"break" { CMDlval.i = MakeToken< int >( rwBREAK, yylineno ); return(rwBREAK); } -"return" { CMDlval.i = MakeToken< int >( rwRETURN, yylineno ); return(rwRETURN); } -"else" { CMDlval.i = MakeToken< int >( rwELSE, yylineno ); return(rwELSE); } -"assert" { CMDlval.i = MakeToken< int >( rwASSERT, yylineno ); return(rwASSERT); } -"while" { CMDlval.i = MakeToken< int >( rwWHILE, yylineno ); return(rwWHILE); } -"do" { CMDlval.i = MakeToken< int >( rwDO, yylineno ); return(rwDO); } -"if" { CMDlval.i = MakeToken< int >( rwIF, yylineno ); return(rwIF); } -"foreach$" { CMDlval.i = MakeToken< int >( rwFOREACHSTR, yylineno ); return(rwFOREACHSTR); } -"foreach" { CMDlval.i = MakeToken< int >( rwFOREACH, yylineno ); return(rwFOREACH); } -"for" { CMDlval.i = MakeToken< int >( rwFOR, yylineno ); return(rwFOR); } -"continue" { CMDlval.i = MakeToken< int >( rwCONTINUE, yylineno ); return(rwCONTINUE); } -"function" { CMDlval.i = MakeToken< int >( rwDEFINE, yylineno ); return(rwDEFINE); } -"new" { CMDlval.i = MakeToken< int >( rwDECLARE, yylineno ); return(rwDECLARE); } -"singleton" { CMDlval.i = MakeToken< int >( rwDECLARESINGLETON, yylineno ); return(rwDECLARESINGLETON); } -"datablock" { CMDlval.i = MakeToken< int >( rwDATABLOCK, yylineno ); return(rwDATABLOCK); } -"case" { CMDlval.i = MakeToken< int >( rwCASE, yylineno ); return(rwCASE); } -"switch$" { CMDlval.i = MakeToken< int >( rwSWITCHSTR, yylineno ); return(rwSWITCHSTR); } -"switch" { CMDlval.i = MakeToken< int >( rwSWITCH, yylineno ); return(rwSWITCH); } -"default" { CMDlval.i = MakeToken< int >( rwDEFAULT, yylineno ); return(rwDEFAULT); } -"package" { CMDlval.i = MakeToken< int >( rwPACKAGE, yylineno ); return(rwPACKAGE); } -"namespace" { CMDlval.i = MakeToken< int >( rwNAMESPACE, yylineno ); return(rwNAMESPACE); } -"true" { CMDlval.i = MakeToken< int >( 1, yylineno ); return INTCONST; } -"false" { CMDlval.i = MakeToken< int >( 0, yylineno ); return INTCONST; } -{VAR} { return(Sc_ScanVar()); } +"=" { CMDlval.i = MakeToken(CMDtext[0], yylineno); return CMDtext[0]; } +%{ +// Reserved words — must be listed before {ID} to take priority. +// NOTE: "namespace" and "class" are intentionally NOT listed here. +// rwNAMESPACE and rwCLASS were previously declared as grammar tokens but +// had no productions that used them and no lexer rules that produced them. +// They have been removed from the grammar. The words "namespace" and +// "class" therefore lex as plain IDENT tokens and can be used as object +// names or field names in script without causing parse errors. If you add +// syntax that consumes those keywords, add both the lexer rule and the +// grammar token declaration at the same time. +%} +"in" { CMDlval.i = MakeToken(rwIN, yylineno); return rwIN; } +"or" { CMDlval.i = MakeToken(rwCASEOR, yylineno); return rwCASEOR; } +"break" { CMDlval.i = MakeToken(rwBREAK, yylineno); return rwBREAK; } +"return" { CMDlval.i = MakeToken(rwRETURN, yylineno); return rwRETURN; } +"else" { CMDlval.i = MakeToken(rwELSE, yylineno); return rwELSE; } +"assert" { CMDlval.i = MakeToken(rwASSERT, yylineno); return rwASSERT; } +"while" { CMDlval.i = MakeToken(rwWHILE, yylineno); return rwWHILE; } +"do" { CMDlval.i = MakeToken(rwDO, yylineno); return rwDO; } +"if" { CMDlval.i = MakeToken(rwIF, yylineno); return rwIF; } +"foreach$" { CMDlval.i = MakeToken(rwFOREACHSTR, yylineno); return rwFOREACHSTR; } +"foreach" { CMDlval.i = MakeToken(rwFOREACH, yylineno); return rwFOREACH; } +"for" { CMDlval.i = MakeToken(rwFOR, yylineno); return rwFOR; } +"continue" { CMDlval.i = MakeToken(rwCONTINUE, yylineno); return rwCONTINUE; } +"function" { CMDlval.i = MakeToken(rwDEFINE, yylineno); return rwDEFINE; } +"new" { CMDlval.i = MakeToken(rwDECLARE, yylineno); return rwDECLARE; } +"singleton" { CMDlval.i = MakeToken(rwDECLARESINGLETON, yylineno); return rwDECLARESINGLETON; } +"datablock" { CMDlval.i = MakeToken(rwDATABLOCK, yylineno); return rwDATABLOCK; } +"case" { CMDlval.i = MakeToken(rwCASE, yylineno); return rwCASE; } +"switch$" { CMDlval.i = MakeToken(rwSWITCHSTR, yylineno); return rwSWITCHSTR; } +"switch" { CMDlval.i = MakeToken(rwSWITCH, yylineno); return rwSWITCH; } +"default" { CMDlval.i = MakeToken(rwDEFAULT, yylineno); return rwDEFAULT; } +"package" { CMDlval.i = MakeToken(rwPACKAGE, yylineno); return rwPACKAGE; } +%{ +// Boolean literals — return INTCONST so the parser treats them as integers. +%} +"true" { CMDlval.i = MakeToken(1, yylineno); return INTCONST; } +"false" { CMDlval.i = MakeToken(0, yylineno); return INTCONST; } -{ID} { return Sc_ScanIdent(); } -0[xX]{HEXDIGIT}+ return(Sc_ScanHex()); -{INTEGER} { CMDtext[CMDleng] = 0; CMDlval.i = MakeToken< int >( dAtoi(CMDtext), yylineno ); return INTCONST; } -{FLOAT} return Sc_ScanNum(); -{ILID} return(ILLEGAL_TOKEN); -. return(ILLEGAL_TOKEN); +{VAR} { return Sc_ScanVar(); } +{ID} { return Sc_ScanIdent(); } +0[xX]{HEXDIGIT}+ { return Sc_ScanHex(); } +{INTEGER} { CMDtext[CMDleng] = 0; + CMDlval.i = MakeToken(dAtoi(CMDtext), yylineno); + return INTCONST; } +{FLOAT} { return Sc_ScanNum(); } +{ILID} { return ILLEGAL_TOKEN; } +. { return ILLEGAL_TOKEN; } %% static const char *scanBuffer; @@ -238,48 +284,69 @@ static const char *fileName; static int scanIndex; extern YYLTYPE CMDlloc; -const char * CMDGetCurrentFile() +const char* CMDGetCurrentFile() { return fileName; } +int CMDGetCurrentLine() { return yylineno; } + +void CMDSetScanBuffer(const char* sb, const char* fn) { - return fileName; + scanBuffer = sb; + fileName = fn; + scanIndex = 0; + yylineno = 1; + gCachedLineContextCount = -1; // re-read $scriptErrorLineCount for each file + lines.clear(); } -int CMDGetCurrentLine() +int CMDgetc() { - return yylineno; + int c = scanBuffer[scanIndex]; + if (c) + scanIndex++; + else + c = -1; // EOF sentinel expected by YY_INPUT + return c; +} + +int CMDwrap() +{ + return 1; } extern bool gConsoleSyntaxError; -void CMDerror(const char *format, ...) +void CMDerror(const char* format, ...) { Compiler::gSyntaxError = true; const int BUFMAX = 1024; char tempBuf[BUFMAX]; va_list args; - va_start( args, format ); + va_start(args, format); #ifdef TORQUE_OS_WIN - _vsnprintf( tempBuf, BUFMAX, format, args ); + _vsnprintf(tempBuf, BUFMAX, format, args); #else - vsnprintf( tempBuf, BUFMAX, format, args ); + vsnprintf(tempBuf, BUFMAX, format, args); #endif va_end(args); - if(fileName) + if (fileName) { - Con::errorf(ConsoleLogEntry::Script, "%s Line: %d - %s", fileName, yylineno, tempBuf); - // Update the script-visible error buffer. - const char *prevStr = Con::getVariable("$ScriptError"); + Con::errorf(ConsoleLogEntry::Script, "%s Line: %d - %s", + fileName, yylineno, tempBuf); + + // Append to the script-visible error string and bump the hash so + // listeners know a new error arrived. + const char* prevStr = Con::getVariable("$ScriptError"); if (prevStr[0]) - dSprintf(tempBuf, sizeof(tempBuf), "%s\n%s Line: %d - Syntax error.", prevStr, fileName, yylineno); + dSprintf(tempBuf, sizeof(tempBuf), "%s\n%s Line: %d - Syntax error.", + prevStr, fileName, yylineno); else - dSprintf(tempBuf, sizeof(tempBuf), "%s Line: %d - Syntax error.", fileName, yylineno); + dSprintf(tempBuf, sizeof(tempBuf), "%s Line: %d - Syntax error.", + fileName, yylineno); Con::setVariable("$ScriptError", tempBuf); - // We also need to mark that we came up with a new error. - static S32 sScriptErrorHash=1000; + static S32 sScriptErrorHash = 1000; Con::setIntVariable("$ScriptErrorHash", sScriptErrorHash++); - } else { @@ -287,30 +354,6 @@ void CMDerror(const char *format, ...) } } -void CMDSetScanBuffer(const char *sb, const char *fn) -{ - scanBuffer = sb; - fileName = fn; - scanIndex = 0; - yylineno = 1; - lines.clear(); -} - -int CMDgetc() -{ - int ret = scanBuffer[scanIndex]; - if(ret) - scanIndex++; - else - ret = -1; - return ret; -} - -int CMDwrap() -{ - return 1; -} - static int Sc_ScanVar() { // Truncate the temp buffer... @@ -323,63 +366,60 @@ static int Sc_ScanVar() static int charConv(int in) { - switch(in) + switch (in) { - case 'r': - return '\r'; - case 'n': - return '\n'; - case 't': - return '\t'; - default: - return in; + case 'r': return '\r'; + case 'n': return '\n'; + case 't': return '\t'; + default: return in; } } static int getHexDigit(char c) { - if(c >= '0' && c <= '9') - return c - '0'; - if(c >= 'A' && c <= 'F') - return c - 'A' + 10; - if(c >= 'a' && c <= 'f') - return c - 'a' + 10; + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; return -1; } static int Sc_ScanDocBlock() { - S32 len = dStrlen(CMDtext); - char* text = (char *) consoleAlloc(len + 1); - S32 line = yylineno; + S32 len = dStrlen(CMDtext); + char* text = (char*)consoleAlloc(len + 1); + S32 line = yylineno; - for( S32 i = 0, j = 0; j <= len; j++ ) + for (S32 i = 0, j = 0; j <= len; j++) { - if( ( j <= (len - 2) ) && ( CMDtext[j] == '/' ) && ( CMDtext[j + 1] == '/' ) && ( CMDtext[j + 2] == '/' ) ) + // Strip leading '///' on each doc line. + if ((j <= (len - 2)) && + CMDtext[j] == '/' && + CMDtext[j + 1] == '/' && + CMDtext[j + 2] == '/') { j += 2; continue; } - - if( CMDtext[j] == '\r' ) - continue; - + if (CMDtext[j] == '\r') continue; text[i++] = CMDtext[j]; } - CMDlval.str = MakeToken< char* >( text, line ); - return(DOCBLOCK); + CMDlval.str = MakeToken(text, line); + return DOCBLOCK; } static int Sc_ScanString(int ret) { - CMDtext[CMDleng - 1] = 0; - if(!collapseEscape(CMDtext+1)) - return -1; + // CMDtext arrives as "content" or 'content' (with quotes). + // Replace the closing quote with a null terminator so collapseEscape + // can work on the interior without seeing the delimiter. + CMDtext[CMDleng - 1] = '\0'; + if (!collapseEscape(CMDtext + 1)) + return -1; - dsize_t bufferLen = dStrlen( CMDtext ); - char* buffer = ( char* ) consoleAlloc( bufferLen ); - dStrcpy( buffer, CMDtext + 1, bufferLen ); + dsize_t allocSize = dStrlen(CMDtext); // = 1 + content_len (see above) + char* buffer = (char*)consoleAlloc(allocSize); + dStrcpy(buffer, CMDtext + 1, allocSize); // skip the opening quote CMDlval.str = MakeToken< char* >( buffer, yylineno ); return ret; @@ -387,22 +427,35 @@ static int Sc_ScanString(int ret) static int Sc_ScanIdent() { - ConsoleBaseType *type; - CMDtext[CMDleng] = 0; - if((type = ConsoleBaseType::getTypeByName(CMDtext)) != NULL) + // Check if the identifier is a registered engine type name (e.g. "Point3F"). + ConsoleBaseType* type = ConsoleBaseType::getTypeByName(CMDtext); + if (type) { - /* It's a type */ - CMDlval.i = MakeToken< int >( type->getTypeID(), yylineno ); + CMDlval.i = MakeToken(type->getTypeID(), yylineno); return TYPEIDENT; } - /* It's an identifier */ - CMDlval.s = MakeToken< StringTableEntry >( StringTable->insert(CMDtext), yylineno ); + CMDlval.s = MakeToken(StringTable->insert(CMDtext), yylineno); return IDENT; } +static int Sc_ScanNum() +{ + CMDtext[CMDleng] = 0; + CMDlval.f = MakeToken(dAtof(CMDtext), yylineno); + return FLTCONST; +} + +static int Sc_ScanHex() +{ + S32 val = 0; + dSscanf(CMDtext, "%x", &val); + CMDlval.i = MakeToken(val, yylineno); + return INTCONST; +} + void expandEscape(char *dest, const char *src) { U8 c; @@ -570,21 +623,6 @@ bool collapseEscape(char *buf) return true; } -static int Sc_ScanNum() -{ - CMDtext[CMDleng] = 0; - CMDlval.f = MakeToken< double >( dAtof(CMDtext), yylineno ); - return(FLTCONST); -} - -static int Sc_ScanHex() -{ - S32 val = 0; - dSscanf(CMDtext, "%x", &val); - CMDlval.i = MakeToken< int >( val, yylineno ); - return INTCONST; -} - void CMD_reset() { CMDrestart(NULL); diff --git a/Engine/source/console/torquescript/astNodes.cpp b/Engine/source/console/torquescript/astNodes.cpp index c20a0b975..5a4dcda6f 100644 --- a/Engine/source/console/torquescript/astNodes.cpp +++ b/Engine/source/console/torquescript/astNodes.cpp @@ -178,15 +178,23 @@ U32 ReturnStmtNode::compileStmt(CodeStream& codeStream, U32 ip) ExprNode* IfStmtNode::getSwitchOR(ExprNode* left, ExprNode* list, bool string) { - ExprNode* nextExpr = (ExprNode*)list->getNext(); - ExprNode* test; + ExprNode* result; if (string) - test = StreqExprNode::alloc(left->dbgLineNumber, left, list, true); + result = StreqExprNode::alloc(left->dbgLineNumber, left, list, true); else - test = IntBinaryExprNode::alloc(left->dbgLineNumber, opEQ, left, list); - if (!nextExpr) - return test; - return IntBinaryExprNode::alloc(test->dbgLineNumber, opOR, test, getSwitchOR(left, nextExpr, string)); + result = IntBinaryExprNode::alloc(left->dbgLineNumber, opEQ, left, list); + + for (ExprNode* walk = (ExprNode*)list->getNext(); walk; walk = (ExprNode*)walk->getNext()) + { + ExprNode* nextExpr; + if (string) + nextExpr = StreqExprNode::alloc(left->dbgLineNumber, left, list, true); + else + nextExpr = IntBinaryExprNode::alloc(left->dbgLineNumber, opEQ, left, list); + + result = IntBinaryExprNode::alloc(result->dbgLineNumber, opOR, result, nextExpr); + } + return result; } void IfStmtNode::propagateSwitchExpr(ExprNode* left, bool string) @@ -405,11 +413,14 @@ U32 ConditionalExprNode::compile(CodeStream& codeStream, U32 ip, TypeReq type) TypeReq ConditionalExprNode::getPreferredType() { - // We can't make it calculate a type based on subsequent expressions as the expression - // could be a string, or just numbers. To play it safe, stringify anything that deals with - // a conditional, and let the interpreter cast as needed to other types safely. - // - // See: Regression Test 7 in ScriptTest. It has a string result in the else portion of the ?: ternary. + TypeReq trueType = trueExpr->getPreferredType(); + TypeReq falseType = falseExpr->getPreferredType(); + + // Both numeric and the same → keep numeric + if (trueType == falseType && trueType != TypeReqNone) + return trueType; + + // One is numeric, other is string/none → string (can't avoid conversion) return TypeReqString; } @@ -874,7 +885,7 @@ U32 ConstantNode::compile(CodeStream& codeStream, U32 ip, TypeReq type) case TypeReqNone: break; } - return ip; + return codeStream.tell(); } TypeReq ConstantNode::getPreferredType() @@ -1498,16 +1509,6 @@ TypeReq ObjectDeclNode::getPreferredType() U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip) { - // OP_FUNC_DECL - // func name - // namespace - // package - // hasBody? - // func end ip - // argc - // ident array[argc] - // code - // OP_RETURN_VOID setCurrentStringTable(&getFunctionStringTable()); setCurrentFloatTable(&getFunctionFloatTable()); @@ -1523,53 +1524,52 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip) } CodeBlock::smInFunction = true; - precompileIdent(fnName); precompileIdent(nameSpace); precompileIdent(package); - CodeBlock::smInFunction = false; - setCurrentStringTable(&getGlobalStringTable()); - // check for argument setup - for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext()) - { - if (walk->defaultValue) - { - TypeReq walkType = walk->defaultValue->getPreferredType(); - if (walkType == TypeReqNone) - walkType = TypeReqString; - - ip = walk->defaultValue->compile(codeStream, ip, walkType); - } - } - setCurrentStringTable(&getFunctionStringTable()); - + // ------------------------------------------------------------------------- + // Layout (all relative to the first word after OP_FUNC_DECL): + // +0,+1 fnName STE + // +2,+3 nameSpace STE + // +4,+5 package STE + // +6 hasBody | (lineNumber << 1) + // +7 endIp (patched after codelets) + // +8 argc + // +9 local variable count (patched after body) + // +10 .. +10+argc-1 register mappings + // +10+argc .. +10+2*argc-1 arg flags + // +10+2*argc .. +10+3*argc-1 default codelet IPs (patched below) + // ------------------------------------------------------------------------- codeStream.emit(OP_FUNC_DECL); codeStream.emitSTE(fnName); codeStream.emitSTE(nameSpace); codeStream.emitSTE(package); codeStream.emit(U32(bool(stmts != NULL) ? 1 : 0) + U32(dbgLineNumber << 1)); - const U32 endIp = codeStream.emit(0); + const U32 endIpSlot = codeStream.emit(0); // patched after codelets codeStream.emit(argc); - const U32 localNumVarsIP = codeStream.emit(0); + const U32 localVarCountSlot = codeStream.emit(0); // patched after body + // Register mappings (one per arg, in declaration order). for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext()) { - StringTableEntry name = walk->varName; - codeStream.emit(getFuncVars(dbgLineNumber)->lookup(name, dbgLineNumber)); + codeStream.emit(getFuncVars(dbgLineNumber)->lookup(walk->varName, dbgLineNumber)); } - // check for argument setup + // Arg flags (bit 0x1 = this argument has a default expression). for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext()) { - U32 flags = 0; - if (walk->defaultValue) flags |= 0x1; - - codeStream.emit(flags); + codeStream.emit(walk->defaultValue ? 1 : 0); } + // Default codelet IP slots — emit 0 placeholders, patched after the body + Vector defaultOffsetSlots; + defaultOffsetSlots.setSize(argc); + for (S32 i = 0; i < argc; i++) + defaultOffsetSlots[i] = codeStream.emit(0); + CodeBlock::smInFunction = true; ip = compileBlock(stmts, codeStream, ip); @@ -1579,9 +1579,32 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip) CodeBlock::smInFunction = false; codeStream.emit(OP_RETURN_VOID); + codeStream.patch(localVarCountSlot, getFuncVars(dbgLineNumber)->count()); - codeStream.patch(localNumVarsIP, getFuncVars(dbgLineNumber)->count()); - codeStream.patch(endIp, codeStream.tell()); + S32 argIdx = 0; + for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext(), ++argIdx) + { + if (walk->defaultValue) + { + // Record where this codelet begins and patch the header slot. + const U32 codeletStart = codeStream.tell(); + codeStream.patch(defaultOffsetSlots[argIdx], codeletStart); + + // Compile the default expression, preferring its natural type. + // Fall back to string if the type is indeterminate. + TypeReq walkType = walk->defaultValue->getPreferredType(); + if (walkType == TypeReqNone) + walkType = TypeReqString; + + ip = walk->defaultValue->compile(codeStream, ip, walkType); + + // Terminate the codelet. exec() handles this by taking the + // stack top as its return value and exiting the interpreter loop. + codeStream.emit(OP_DEFAULT_END); + } + } + + codeStream.patch(endIpSlot, codeStream.tell()); setCurrentStringTable(&getGlobalStringTable()); setCurrentFloatTable(&getGlobalFloatTable()); diff --git a/Engine/source/console/torquescript/cmdgram.cpp b/Engine/source/console/torquescript/cmdgram.cpp index 798ff0169..0d7599090 100644 --- a/Engine/source/console/torquescript/cmdgram.cpp +++ b/Engine/source/console/torquescript/cmdgram.cpp @@ -120,15 +120,15 @@ struct Token U32 lineNumber; }; -#line 49 "CMDgram.y" +#line 50 "CMDgram.y" - /* Reserved Word Definitions */ -#line 60 "CMDgram.y" + /* Reserved word token definitions */ +#line 67 "CMDgram.y" - /* Constants and Identifier Definitions */ -#line 74 "CMDgram.y" + /* Constant and identifier token definitions */ +#line 82 "CMDgram.y" - /* Operator Definitions */ + /* Operator token definitions */ #line 134 "CMDgram.c" @@ -188,118 +188,112 @@ enum yysymbol_kind_t YYSYMBOL_rwSWITCHSTR = 27, /* rwSWITCHSTR */ YYSYMBOL_rwCASEOR = 28, /* rwCASEOR */ YYSYMBOL_rwPACKAGE = 29, /* rwPACKAGE */ - YYSYMBOL_rwNAMESPACE = 30, /* rwNAMESPACE */ - YYSYMBOL_rwCLASS = 31, /* rwCLASS */ - YYSYMBOL_rwASSERT = 32, /* rwASSERT */ - YYSYMBOL_ILLEGAL_TOKEN = 33, /* ILLEGAL_TOKEN */ - YYSYMBOL_CHRCONST = 34, /* CHRCONST */ - YYSYMBOL_INTCONST = 35, /* INTCONST */ - YYSYMBOL_TTAG = 36, /* TTAG */ - YYSYMBOL_VAR = 37, /* VAR */ - YYSYMBOL_IDENT = 38, /* IDENT */ - YYSYMBOL_TYPEIDENT = 39, /* TYPEIDENT */ - YYSYMBOL_DOCBLOCK = 40, /* DOCBLOCK */ - YYSYMBOL_STRATOM = 41, /* STRATOM */ - YYSYMBOL_TAGATOM = 42, /* TAGATOM */ - YYSYMBOL_FLTCONST = 43, /* FLTCONST */ - YYSYMBOL_44_ = 44, /* '+' */ - YYSYMBOL_45_ = 45, /* '-' */ - YYSYMBOL_46_ = 46, /* '*' */ - YYSYMBOL_47_ = 47, /* '/' */ - YYSYMBOL_48_ = 48, /* '<' */ - YYSYMBOL_49_ = 49, /* '>' */ - YYSYMBOL_50_ = 50, /* '=' */ - YYSYMBOL_51_ = 51, /* '.' */ - YYSYMBOL_52_ = 52, /* '|' */ - YYSYMBOL_53_ = 53, /* '&' */ - YYSYMBOL_54_ = 54, /* '%' */ - YYSYMBOL_55_ = 55, /* '(' */ - YYSYMBOL_56_ = 56, /* ')' */ - YYSYMBOL_57_ = 57, /* ',' */ - YYSYMBOL_58_ = 58, /* ':' */ - YYSYMBOL_59_ = 59, /* ';' */ - YYSYMBOL_60_ = 60, /* '{' */ - YYSYMBOL_61_ = 61, /* '}' */ - YYSYMBOL_62_ = 62, /* '^' */ - YYSYMBOL_63_ = 63, /* '~' */ - YYSYMBOL_64_ = 64, /* '!' */ - YYSYMBOL_65_ = 65, /* '@' */ - YYSYMBOL_opINTNAME = 66, /* opINTNAME */ - YYSYMBOL_opINTNAMER = 67, /* opINTNAMER */ - YYSYMBOL_opMINUSMINUS = 68, /* opMINUSMINUS */ - YYSYMBOL_opPLUSPLUS = 69, /* opPLUSPLUS */ - YYSYMBOL_STMT_SEP = 70, /* STMT_SEP */ - YYSYMBOL_opSHL = 71, /* opSHL */ - YYSYMBOL_opSHR = 72, /* opSHR */ - YYSYMBOL_opPLASN = 73, /* opPLASN */ - YYSYMBOL_opMIASN = 74, /* opMIASN */ - YYSYMBOL_opMLASN = 75, /* opMLASN */ - YYSYMBOL_opDVASN = 76, /* opDVASN */ - YYSYMBOL_opMODASN = 77, /* opMODASN */ - YYSYMBOL_opANDASN = 78, /* opANDASN */ - YYSYMBOL_opXORASN = 79, /* opXORASN */ - YYSYMBOL_opORASN = 80, /* opORASN */ - YYSYMBOL_opSLASN = 81, /* opSLASN */ - YYSYMBOL_opSRASN = 82, /* opSRASN */ - YYSYMBOL_opCAT = 83, /* opCAT */ - YYSYMBOL_opEQ = 84, /* opEQ */ - YYSYMBOL_opNE = 85, /* opNE */ - YYSYMBOL_opGE = 86, /* opGE */ - YYSYMBOL_opLE = 87, /* opLE */ - YYSYMBOL_opAND = 88, /* opAND */ - YYSYMBOL_opOR = 89, /* opOR */ - YYSYMBOL_opSTREQ = 90, /* opSTREQ */ - YYSYMBOL_opCOLONCOLON = 91, /* opCOLONCOLON */ - YYSYMBOL_92_ = 92, /* '[' */ - YYSYMBOL_opMDASN = 93, /* opMDASN */ - YYSYMBOL_opNDASN = 94, /* opNDASN */ - YYSYMBOL_opNTASN = 95, /* opNTASN */ - YYSYMBOL_96_ = 96, /* '?' */ - YYSYMBOL_opSTRNE = 97, /* opSTRNE */ - YYSYMBOL_UNARY = 98, /* UNARY */ - YYSYMBOL_99_ = 99, /* ']' */ - YYSYMBOL_YYACCEPT = 100, /* $accept */ - YYSYMBOL_start = 101, /* start */ - YYSYMBOL_decl_list = 102, /* decl_list */ - YYSYMBOL_decl = 103, /* decl */ - YYSYMBOL_package_decl = 104, /* package_decl */ - YYSYMBOL_fn_decl_list = 105, /* fn_decl_list */ - YYSYMBOL_statement_list = 106, /* statement_list */ - YYSYMBOL_stmt = 107, /* stmt */ - YYSYMBOL_fn_decl_stmt = 108, /* fn_decl_stmt */ - YYSYMBOL_var_list_decl = 109, /* var_list_decl */ - YYSYMBOL_var_list = 110, /* var_list */ - YYSYMBOL_param = 111, /* param */ - YYSYMBOL_datablock_decl = 112, /* datablock_decl */ - YYSYMBOL_object_decl = 113, /* object_decl */ - YYSYMBOL_parent_block = 114, /* parent_block */ - YYSYMBOL_object_name = 115, /* object_name */ - YYSYMBOL_object_args = 116, /* object_args */ - YYSYMBOL_object_declare_block = 117, /* object_declare_block */ - YYSYMBOL_object_decl_list = 118, /* object_decl_list */ - YYSYMBOL_stmt_block = 119, /* stmt_block */ - YYSYMBOL_switch_stmt = 120, /* switch_stmt */ - YYSYMBOL_case_block = 121, /* case_block */ - YYSYMBOL_case_expr = 122, /* case_expr */ - YYSYMBOL_if_stmt = 123, /* if_stmt */ - YYSYMBOL_while_stmt = 124, /* while_stmt */ - YYSYMBOL_for_stmt = 125, /* for_stmt */ - YYSYMBOL_foreach_stmt = 126, /* foreach_stmt */ - YYSYMBOL_expression_stmt = 127, /* expression_stmt */ - YYSYMBOL_expr = 128, /* expr */ - YYSYMBOL_slot_acc = 129, /* slot_acc */ - YYSYMBOL_intslot_acc = 130, /* intslot_acc */ - YYSYMBOL_class_name_expr = 131, /* class_name_expr */ - YYSYMBOL_assign_op_struct = 132, /* assign_op_struct */ - YYSYMBOL_stmt_expr = 133, /* stmt_expr */ - YYSYMBOL_funcall_expr = 134, /* funcall_expr */ - YYSYMBOL_assert_expr = 135, /* assert_expr */ - YYSYMBOL_expr_list_decl = 136, /* expr_list_decl */ - YYSYMBOL_expr_list = 137, /* expr_list */ - YYSYMBOL_slot_assign_list_opt = 138, /* slot_assign_list_opt */ - YYSYMBOL_slot_assign_list = 139, /* slot_assign_list */ - YYSYMBOL_slot_assign = 140, /* slot_assign */ - YYSYMBOL_aidx_expr = 141 /* aidx_expr */ + YYSYMBOL_rwASSERT = 30, /* rwASSERT */ + YYSYMBOL_ILLEGAL_TOKEN = 31, /* ILLEGAL_TOKEN */ + YYSYMBOL_CHRCONST = 32, /* CHRCONST */ + YYSYMBOL_INTCONST = 33, /* INTCONST */ + YYSYMBOL_TTAG = 34, /* TTAG */ + YYSYMBOL_VAR = 35, /* VAR */ + YYSYMBOL_IDENT = 36, /* IDENT */ + YYSYMBOL_TYPEIDENT = 37, /* TYPEIDENT */ + YYSYMBOL_DOCBLOCK = 38, /* DOCBLOCK */ + YYSYMBOL_STRATOM = 39, /* STRATOM */ + YYSYMBOL_TAGATOM = 40, /* TAGATOM */ + YYSYMBOL_FLTCONST = 41, /* FLTCONST */ + YYSYMBOL_42_ = 42, /* '+' */ + YYSYMBOL_43_ = 43, /* '-' */ + YYSYMBOL_44_ = 44, /* '*' */ + YYSYMBOL_45_ = 45, /* '/' */ + YYSYMBOL_46_ = 46, /* '<' */ + YYSYMBOL_47_ = 47, /* '>' */ + YYSYMBOL_48_ = 48, /* '=' */ + YYSYMBOL_49_ = 49, /* '.' */ + YYSYMBOL_50_ = 50, /* '|' */ + YYSYMBOL_51_ = 51, /* '&' */ + YYSYMBOL_52_ = 52, /* '%' */ + YYSYMBOL_53_ = 53, /* '(' */ + YYSYMBOL_54_ = 54, /* ')' */ + YYSYMBOL_55_ = 55, /* ',' */ + YYSYMBOL_56_ = 56, /* ':' */ + YYSYMBOL_57_ = 57, /* ';' */ + YYSYMBOL_58_ = 58, /* '{' */ + YYSYMBOL_59_ = 59, /* '}' */ + YYSYMBOL_60_ = 60, /* '^' */ + YYSYMBOL_61_ = 61, /* '~' */ + YYSYMBOL_62_ = 62, /* '!' */ + YYSYMBOL_63_ = 63, /* '@' */ + YYSYMBOL_opINTNAME = 64, /* opINTNAME */ + YYSYMBOL_opINTNAMER = 65, /* opINTNAMER */ + YYSYMBOL_opMINUSMINUS = 66, /* opMINUSMINUS */ + YYSYMBOL_opPLUSPLUS = 67, /* opPLUSPLUS */ + YYSYMBOL_opSHL = 68, /* opSHL */ + YYSYMBOL_opSHR = 69, /* opSHR */ + YYSYMBOL_opPLASN = 70, /* opPLASN */ + YYSYMBOL_opMIASN = 71, /* opMIASN */ + YYSYMBOL_opMLASN = 72, /* opMLASN */ + YYSYMBOL_opDVASN = 73, /* opDVASN */ + YYSYMBOL_opMODASN = 74, /* opMODASN */ + YYSYMBOL_opANDASN = 75, /* opANDASN */ + YYSYMBOL_opXORASN = 76, /* opXORASN */ + YYSYMBOL_opORASN = 77, /* opORASN */ + YYSYMBOL_opSLASN = 78, /* opSLASN */ + YYSYMBOL_opSRASN = 79, /* opSRASN */ + YYSYMBOL_opCAT = 80, /* opCAT */ + YYSYMBOL_opEQ = 81, /* opEQ */ + YYSYMBOL_opNE = 82, /* opNE */ + YYSYMBOL_opGE = 83, /* opGE */ + YYSYMBOL_opLE = 84, /* opLE */ + YYSYMBOL_opAND = 85, /* opAND */ + YYSYMBOL_opOR = 86, /* opOR */ + YYSYMBOL_opSTREQ = 87, /* opSTREQ */ + YYSYMBOL_opSTRNE = 88, /* opSTRNE */ + YYSYMBOL_opCOLONCOLON = 89, /* opCOLONCOLON */ + YYSYMBOL_90_ = 90, /* '[' */ + YYSYMBOL_91_ = 91, /* '?' */ + YYSYMBOL_UNARY = 92, /* UNARY */ + YYSYMBOL_93_ = 93, /* ']' */ + YYSYMBOL_YYACCEPT = 94, /* $accept */ + YYSYMBOL_start = 95, /* start */ + YYSYMBOL_decl_list = 96, /* decl_list */ + YYSYMBOL_decl = 97, /* decl */ + YYSYMBOL_package_decl = 98, /* package_decl */ + YYSYMBOL_fn_decl_list = 99, /* fn_decl_list */ + YYSYMBOL_statement_list = 100, /* statement_list */ + YYSYMBOL_stmt = 101, /* stmt */ + YYSYMBOL_fn_decl_stmt = 102, /* fn_decl_stmt */ + YYSYMBOL_var_list_decl = 103, /* var_list_decl */ + YYSYMBOL_var_list = 104, /* var_list */ + YYSYMBOL_param = 105, /* param */ + YYSYMBOL_datablock_decl = 106, /* datablock_decl */ + YYSYMBOL_object_decl = 107, /* object_decl */ + YYSYMBOL_parent_block = 108, /* parent_block */ + YYSYMBOL_object_name = 109, /* object_name */ + YYSYMBOL_object_args = 110, /* object_args */ + YYSYMBOL_object_declare_block = 111, /* object_declare_block */ + YYSYMBOL_object_decl_list = 112, /* object_decl_list */ + YYSYMBOL_stmt_block = 113, /* stmt_block */ + YYSYMBOL_switch_stmt = 114, /* switch_stmt */ + YYSYMBOL_case_block = 115, /* case_block */ + YYSYMBOL_case_expr = 116, /* case_expr */ + YYSYMBOL_if_stmt = 117, /* if_stmt */ + YYSYMBOL_while_stmt = 118, /* while_stmt */ + YYSYMBOL_for_stmt = 119, /* for_stmt */ + YYSYMBOL_foreach_stmt = 120, /* foreach_stmt */ + YYSYMBOL_expression_stmt = 121, /* expression_stmt */ + YYSYMBOL_expr = 122, /* expr */ + YYSYMBOL_slot_acc = 123, /* slot_acc */ + YYSYMBOL_intslot_acc = 124, /* intslot_acc */ + YYSYMBOL_class_name_expr = 125, /* class_name_expr */ + YYSYMBOL_assign_op_struct = 126, /* assign_op_struct */ + YYSYMBOL_stmt_expr = 127, /* stmt_expr */ + YYSYMBOL_funcall_expr = 128, /* funcall_expr */ + YYSYMBOL_assert_expr = 129, /* assert_expr */ + YYSYMBOL_expr_list_decl = 130, /* expr_list_decl */ + YYSYMBOL_expr_list = 131, /* expr_list */ + YYSYMBOL_slot_assign_list_opt = 132, /* slot_assign_list_opt */ + YYSYMBOL_slot_assign_list = 133, /* slot_assign_list */ + YYSYMBOL_slot_assign = 134, /* slot_assign */ + YYSYMBOL_aidx_expr = 135 /* aidx_expr */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; @@ -630,10 +624,10 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 2932 +#define YYLAST 2813 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 100 +#define YYNTOKENS 94 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 42 /* YYNRULES -- Number of rules. */ @@ -642,7 +636,7 @@ union yyalloc #define YYNSTATES 386 /* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 329 +#define YYMAXUTOK 323 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM @@ -659,16 +653,16 @@ static const yytype_int8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 64, 2, 2, 2, 54, 53, 2, - 55, 56, 46, 44, 57, 45, 51, 47, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 58, 59, - 48, 50, 49, 96, 65, 2, 2, 2, 2, 2, + 2, 2, 2, 62, 2, 2, 2, 52, 51, 2, + 53, 54, 44, 42, 55, 43, 49, 45, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 56, 57, + 46, 48, 47, 91, 63, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 92, 2, 99, 62, 2, 2, 2, 2, 2, + 2, 90, 2, 93, 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 60, 52, 61, 63, 2, 2, 2, + 2, 2, 2, 58, 50, 59, 61, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -685,33 +679,33 @@ static const yytype_int8 yytranslate[] = 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 66, + 35, 36, 37, 38, 39, 40, 41, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 93, 94, 95, 97, 98 + 87, 88, 89, 92 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 167, 167, 173, 174, 179, 181, 183, 188, 193, - 195, 201, 202, 207, 208, 209, 210, 211, 212, 213, - 215, 217, 219, 221, 223, 225, 227, 232, 234, 240, - 241, 246, 248, 253, 257, 261, 265, 272, 277, 279, - 281, 283, 285, 287, 293, 294, 300, 301, 307, 308, - 314, 315, 317, 319, 324, 326, 331, 333, 338, 340, - 345, 347, 349, 354, 356, 361, 363, 368, 370, 375, - 377, 379, 381, 383, 385, 387, 389, 394, 396, 401, - 406, 408, 410, 412, 414, 416, 418, 420, 422, 424, - 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, - 446, 448, 450, 452, 454, 456, 458, 460, 462, 464, - 466, 468, 470, 472, 474, 476, 478, 480, 482, 504, - 506, 511, 513, 518, 520, 525, 527, 529, 531, 533, - 535, 537, 539, 541, 543, 545, 547, 552, 554, 556, + 0, 192, 192, 198, 199, 204, 206, 208, 213, 218, + 220, 226, 227, 232, 233, 234, 235, 236, 237, 238, + 240, 242, 244, 246, 248, 250, 252, 258, 261, 267, + 268, 273, 275, 292, 294, 296, 298, 303, 308, 310, + 312, 314, 316, 318, 324, 325, 331, 332, 338, 339, + 345, 346, 348, 350, 355, 357, 362, 364, 369, 371, + 379, 381, 383, 388, 390, 395, 397, 402, 404, 409, + 411, 413, 415, 417, 419, 421, 423, 428, 430, 435, + 440, 442, 444, 446, 448, 450, 452, 454, 456, 458, + 460, 462, 464, 466, 468, 470, 472, 474, 476, 478, + 480, 482, 484, 486, 488, 490, 498, 500, 502, 504, + 506, 508, 510, 512, 514, 516, 518, 520, 522, 527, + 529, 534, 536, 541, 543, 548, 550, 552, 554, 556, 558, 560, 562, 564, 566, 568, 570, 575, 577, 579, - 589, 591, 597, 598, 603, 605, 611, 612, 617, 619, - 624, 626, 628, 630, 632, 637, 639 + 581, 583, 585, 587, 589, 591, 593, 599, 602, 607, + 612, 614, 620, 621, 626, 628, 634, 635, 640, 642, + 647, 649, 651, 653, 655, 662, 664 }; #endif @@ -733,16 +727,15 @@ yysymbol_name (yysymbol_kind_t yysymbol) "rwGLOBAL", "rwIF", "rwNIL", "rwRETURN", "rwWHILE", "rwDO", "rwENDIF", "rwENDWHILE", "rwENDFOR", "rwDEFAULT", "rwFOR", "rwFOREACH", "rwFOREACHSTR", "rwIN", "rwDATABLOCK", "rwSWITCH", "rwCASE", - "rwSWITCHSTR", "rwCASEOR", "rwPACKAGE", "rwNAMESPACE", "rwCLASS", - "rwASSERT", "ILLEGAL_TOKEN", "CHRCONST", "INTCONST", "TTAG", "VAR", - "IDENT", "TYPEIDENT", "DOCBLOCK", "STRATOM", "TAGATOM", "FLTCONST", - "'+'", "'-'", "'*'", "'/'", "'<'", "'>'", "'='", "'.'", "'|'", "'&'", - "'%'", "'('", "')'", "','", "':'", "';'", "'{'", "'}'", "'^'", "'~'", - "'!'", "'@'", "opINTNAME", "opINTNAMER", "opMINUSMINUS", "opPLUSPLUS", - "STMT_SEP", "opSHL", "opSHR", "opPLASN", "opMIASN", "opMLASN", "opDVASN", - "opMODASN", "opANDASN", "opXORASN", "opORASN", "opSLASN", "opSRASN", - "opCAT", "opEQ", "opNE", "opGE", "opLE", "opAND", "opOR", "opSTREQ", - "opCOLONCOLON", "'['", "opMDASN", "opNDASN", "opNTASN", "'?'", "opSTRNE", + "rwSWITCHSTR", "rwCASEOR", "rwPACKAGE", "rwASSERT", "ILLEGAL_TOKEN", + "CHRCONST", "INTCONST", "TTAG", "VAR", "IDENT", "TYPEIDENT", "DOCBLOCK", + "STRATOM", "TAGATOM", "FLTCONST", "'+'", "'-'", "'*'", "'/'", "'<'", + "'>'", "'='", "'.'", "'|'", "'&'", "'%'", "'('", "')'", "','", "':'", + "';'", "'{'", "'}'", "'^'", "'~'", "'!'", "'@'", "opINTNAME", + "opINTNAMER", "opMINUSMINUS", "opPLUSPLUS", "opSHL", "opSHR", "opPLASN", + "opMIASN", "opMLASN", "opDVASN", "opMODASN", "opANDASN", "opXORASN", + "opORASN", "opSLASN", "opSRASN", "opCAT", "opEQ", "opNE", "opGE", "opLE", + "opAND", "opOR", "opSTREQ", "opSTRNE", "opCOLONCOLON", "'['", "'?'", "UNARY", "']'", "$accept", "start", "decl_list", "decl", "package_decl", "fn_decl_list", "statement_list", "stmt", "fn_decl_stmt", "var_list_decl", "var_list", "param", "datablock_decl", "object_decl", @@ -758,7 +751,7 @@ yysymbol_name (yysymbol_kind_t yysymbol) } #endif -#define YYPACT_NINF (-315) +#define YYPACT_NINF (-301) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) @@ -772,45 +765,45 @@ yysymbol_name (yysymbol_kind_t yysymbol) STATE-NUM. */ static const yytype_int16 yypact[] = { - -315, 22, 144, -315, -11, -20, -20, -14, 45, 41, - 762, 51, 413, 53, 55, 63, -20, 68, 69, 98, - 83, -315, 92, -26, 37, -315, -315, -315, -315, 1140, - 1140, 1140, 1140, 1140, -315, -315, -315, -315, -315, -315, - -315, -315, -315, -315, -315, 84, 2603, 457, -315, 85, - -315, -315, 39, -315, 1140, 91, 97, -315, -315, 1140, - -315, -315, -315, 1253, -315, 1140, -315, -315, 140, 804, - 119, 125, 108, 1140, 1140, 107, 1140, 1140, 1140, -315, - -315, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, - 1140, 1140, -315, 1140, 132, -30, -30, 1307, -30, -30, - -315, 1140, 1140, 1140, 1140, 1140, 1140, 134, 1140, 1140, - 1140, 1140, 1140, -20, -20, 1140, 1140, 1140, 1140, 1140, - 1140, 1140, 1140, 1140, 1140, 1140, 846, -315, 137, 139, - 1361, 27, 1140, 1415, -315, 1469, 538, 120, 888, 1523, - 160, 165, 1140, 1577, 1631, 188, 1145, 1199, 2603, 2603, - 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, - -42, 2603, 136, 138, 141, -315, 94, 94, -30, -30, - 256, 256, 34, 2744, 2802, -30, 2773, 2860, -315, -315, - 221, 221, 2831, 2831, 256, 256, 2715, 2686, 2860, 1685, - 2860, 1140, 2603, -36, 142, 143, -315, 148, -315, 1140, - 135, 2603, 135, 413, 413, -315, -315, 1140, 930, 1739, - 972, 1140, 1140, 1793, 145, 146, 14, -315, -315, 153, - 1140, -315, 1140, 535, -315, 1140, 1140, 1140, 1140, 1140, - 44, 1140, 147, 149, 137, 137, 105, 172, 154, 154, - 209, -315, 1847, 413, 1901, 1014, 1056, 1955, 2009, 2063, - 159, 193, 193, 164, -315, 168, 2117, 2603, 1140, -315, - 2603, 169, 174, -32, 2657, -315, 2603, 1140, -315, -315, - 179, 135, -315, 1140, 180, 181, 413, -315, -315, 413, - 413, 2171, 413, 2225, 1098, 413, 413, 178, 1140, 185, - 190, -315, -315, -315, 2603, -315, -315, -315, 2603, 648, - 194, 154, 138, 195, 196, -315, -315, -315, 413, -315, - 413, 413, 2279, -315, -315, 2, 67, 2603, -315, -315, - -315, -315, 184, 93, 93, -315, -315, -315, 413, 208, - -21, 219, 198, 2, -315, 1140, -315, 693, 200, 202, - 203, 25, 93, 212, -315, 1140, 1140, 1140, -4, 204, - -315, 2603, 207, -315, 93, -315, -315, 210, 25, -315, - 2333, 2387, 1, 1140, 1140, -315, 218, -315, 220, -315, - -315, -315, 229, 2441, 17, -315, -315, 1140, -315, 232, - 738, 2495, 1140, -315, 2549, -315 + -301, 27, 146, -301, -6, 2, 2, -4, 3, -21, + 754, 19, 417, 22, 36, 39, 2, 42, 44, 20, + 51, -301, 34, 2688, -18, -301, -301, -301, -301, 1114, + 1114, 1114, 1114, 1114, -301, -301, -301, -301, -301, -301, + -301, -301, -301, -301, -301, 49, 2469, 2720, -301, 53, + -301, -301, -16, -301, 1114, 65, 70, -301, -301, 1114, + -301, -301, -301, 1219, -301, 1114, -301, -301, 37, 794, + 91, 97, 80, 1114, 1114, 78, 1114, 1114, 1114, -301, + -301, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1114, -301, 1114, 101, 29, 29, 1269, 29, 29, + -301, 1114, 1114, 1114, 1114, 1114, 1114, 102, 1114, 1114, + 1114, 1114, 1114, 2, 2, 1114, 1114, 1114, 1114, 1114, + 1114, 1114, 1114, 1114, 1114, 1114, 834, -301, 105, 106, + 1319, 6, 1114, 1369, -301, 1419, 548, 88, 874, 1469, + 124, 125, 1114, 1519, 1569, 147, 1119, 1169, 2469, 2469, + 2469, 2469, 2469, 2469, 2469, 2469, 2469, 2469, 2469, 2469, + -35, 2469, 100, 108, 103, -301, 289, 289, 29, 29, + 56, 56, -20, 207, 2641, 29, 455, 275, -301, -301, + 258, 258, 2669, 2669, 56, 56, 2613, 2566, 275, 275, + 1619, 1114, 2469, -29, 115, 117, -301, 121, -301, 1114, + 132, 2469, 132, 417, 417, -301, -301, 1114, 914, 1669, + 954, 1114, 1114, 1719, 119, 133, 15, -301, -301, 153, + 1114, -301, 1114, 2734, -301, 1114, 1114, 1114, 1114, 1114, + -7, 1114, 145, 136, 105, 105, 104, 162, 148, 148, + 192, -301, 1769, 417, 1819, 994, 1034, 1869, 1919, 1969, + 150, 179, 179, 149, -301, 158, 2019, 2469, 1114, -301, + 2469, 160, 166, -30, 2519, -301, 2469, 1114, -301, -301, + 167, 132, -301, 1114, 168, 173, 417, -301, -301, 417, + 417, 2069, 417, 2119, 1074, 417, 417, 174, 1114, 157, + 176, -301, -301, -301, 2469, -301, -301, -301, 2469, 628, + 175, 148, 108, 178, 188, -301, -301, -301, 417, -301, + 417, 417, 2169, -301, -301, 66, 1, 2469, -301, -301, + -301, -301, 201, 159, 159, -301, -301, -301, 417, 212, + -26, 225, 203, 66, -301, 1114, -301, 671, 205, 211, + 210, 111, 159, 214, -301, 1114, 1114, 1114, -25, 222, + -301, 2469, 204, -301, 159, -301, -301, 224, 111, -301, + 2219, 2269, -27, 1114, 1114, -301, 208, -301, 223, -301, + -301, -301, 237, 2319, -24, -301, -301, 1114, -301, 238, + 714, 2369, 1114, -301, 2419, -301 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -836,8 +829,8 @@ static const yytype_uint8 yydefact[] = 128, 129, 130, 131, 132, 133, 134, 135, 136, 165, 0, 154, 0, 153, 0, 81, 86, 87, 88, 89, 94, 95, 119, 85, 84, 83, 82, 106, 121, 122, - 101, 102, 98, 99, 96, 97, 103, 100, 104, 0, - 105, 0, 145, 33, 0, 30, 31, 0, 124, 46, + 101, 102, 98, 99, 96, 97, 103, 100, 104, 105, + 0, 0, 145, 33, 0, 30, 31, 0, 124, 46, 44, 47, 44, 0, 0, 56, 12, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 9, 150, 0, 0, 24, 0, 118, 147, 0, 152, 152, 0, 0, @@ -862,11 +855,11 @@ static const yytype_uint8 yydefact[] = /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -315, -315, -315, -315, -315, -315, -260, -1, -132, 50, - -315, 52, -315, -221, -193, -120, -216, -227, -53, -199, - -315, -245, -315, -315, -315, -315, -315, -315, 283, -315, - -315, 0, -45, -2, -315, -315, -188, -180, -315, -25, - -314, -225 + -301, -301, -301, -301, -301, -301, -260, -1, -131, 52, + -301, 58, -301, -196, -187, -111, -222, -300, -46, -199, + -301, -245, -301, -301, -301, -301, -301, -301, 283, -301, + -301, 0, -45, -2, -301, -301, -96, -182, -301, -11, + -299, -225 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -884,665 +877,641 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 49, 36, 127, 263, 240, 241, 56, 290, 299, 239, - 49, 230, 202, 217, 231, 222, 72, 4, 53, 350, - 250, 107, 3, 275, 78, 222, 329, 52, 350, 346, - 5, 6, 5, 6, 60, 54, 113, 114, 261, 262, - 330, 331, 79, 80, 278, 57, 363, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 223, 222, 20, - 232, 337, 21, 61, 23, 24, 91, 297, 26, 27, - 28, 347, 29, 30, 222, 253, 352, 305, 301, 236, - 306, 307, 31, 309, 254, 322, 313, 314, 364, 227, - 32, 33, 93, 302, 128, 335, 59, 343, 5, 6, - 372, 225, 339, 339, 58, 265, 65, 367, 69, 325, - 70, 326, 327, 178, 179, 380, 379, 329, 71, 199, - 357, 339, 362, 73, 74, 336, 228, 368, 94, 344, - 129, 330, 331, 339, 49, 206, 75, 357, 76, 374, - 103, 104, 77, 100, -79, 107, 131, 4, 110, 5, - 6, 7, 132, 8, 137, 9, 140, 10, 11, 12, - 113, 114, 141, 142, 13, 14, 15, 145, 16, 17, - 164, 18, 172, 19, 193, 207, 20, 197, 259, 21, - 22, 23, 24, 211, 25, 26, 27, 28, 212, 29, - 30, 4, 224, 237, 255, 225, 226, 267, 233, 31, - 234, 49, 49, 235, 271, 251, 252, 32, 33, 268, - 272, 273, 5, 6, 7, 287, 8, 276, 9, 288, - 10, 11, 12, 291, 292, 295, 366, 13, 14, 15, - 296, 16, 17, 288, 18, 300, 303, 304, 315, 20, - 338, 49, 21, 22, 23, 24, 318, 25, 26, 27, - 28, 319, 29, 30, 321, 323, 324, 348, 345, 349, - 354, 355, 31, 365, 356, 101, 102, 103, 104, 369, - 32, 33, 107, 359, 49, 110, 375, 49, 49, 377, - 49, 376, 382, 49, 49, 270, 269, 113, 114, 358, - 333, 0, 0, 63, 0, 0, 0, 49, 206, 0, - 101, 102, 103, 104, 0, 0, 49, 107, 49, 49, - 110, 0, 95, 96, 97, 98, 99, 0, 0, 0, - 0, 112, 113, 114, 0, 0, 49, 115, 116, 0, - 0, 0, 0, 0, 0, 49, 206, 130, 0, 0, - 0, 0, 133, 0, 0, 0, 123, 0, 135, 0, - 49, 206, 139, 125, 0, 0, 143, 144, 0, 146, + 49, 36, 127, 263, 240, 241, 56, 290, 299, 230, + 49, 5, 6, 60, 217, 239, 72, 275, 4, 231, + 222, 202, 346, 363, 343, 222, 250, 3, 222, 335, + 52, 222, 59, 227, 350, 93, 20, 128, 53, 21, + 61, 23, 24, 350, 278, 26, 27, 28, 225, 29, + 30, 137, 265, 57, 368, 54, 75, 336, 223, 31, + 58, 337, 232, 297, 347, 364, 372, 32, 33, 379, + 228, 94, 65, 129, 253, 69, 352, 305, 107, 322, + 306, 307, 77, 309, 301, 254, 313, 314, 236, 70, + 329, 302, 71, 113, 114, 73, 199, 74, 101, 102, + 103, 104, 330, 331, 76, 107, 100, 367, 110, 325, + -79, 326, 327, 178, 179, 380, 5, 6, 131, 112, + 113, 114, 362, 132, 115, 116, 140, 339, 339, 344, + 261, 262, 141, 142, 49, 206, 145, 164, 172, 374, + 193, 207, 197, 123, 124, 357, 339, 211, 212, 4, + 4, 5, 6, 7, 224, 8, 226, 9, 339, 10, + 11, 12, 357, 225, 5, 6, 13, 14, 15, 233, + 16, 17, 234, 18, 235, 19, 20, 251, 259, 21, + 22, 23, 24, 329, 25, 26, 27, 28, 237, 29, + 30, 252, 255, 267, 268, 330, 331, 271, 272, 31, + 276, 49, 49, 273, 287, 288, 291, 32, 33, 5, + 6, 7, 292, 8, 295, 9, 318, 10, 11, 12, + 296, 300, 303, 366, 13, 14, 15, 304, 16, 17, + 288, 18, 315, 321, 20, 319, 323, 21, 22, 23, + 24, 49, 25, 26, 27, 28, 324, 29, 30, 101, + 102, 103, 104, 105, 106, 338, 107, 31, 109, 110, + 345, 348, 349, 354, 375, 32, 33, 111, 355, 356, + 112, 113, 114, 359, 49, 115, 116, 49, 49, 365, + 49, 369, 376, 49, 49, 377, 382, 270, 117, 118, + 119, 120, 269, 63, 123, 124, 358, 49, 206, 0, + 101, 102, 103, 104, 333, 0, 49, 107, 49, 49, + 110, 0, 95, 96, 97, 98, 99, 101, 102, 103, + 104, 0, 113, 114, 107, 0, 49, 110, 0, 0, + 0, 0, 0, 103, 104, 49, 206, 130, 107, 113, + 114, 110, 133, 115, 116, 0, 0, 0, 135, 0, + 49, 206, 139, 113, 114, 0, 143, 144, 0, 146, 147, 148, 0, 0, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 0, 161, 0, 49, 206, 0, 0, 0, 0, 166, 167, 168, 169, 170, 171, 0, 173, 174, 175, 176, 177, 0, 0, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 192, - 0, 0, 0, 0, 201, 201, 0, 0, 5, 6, - 7, 209, 8, 0, 9, 213, 10, 11, 12, 0, - 0, 0, 0, 13, 14, 15, 0, 16, 17, 0, - 18, 0, 0, 0, 0, 20, 0, 0, 21, 22, - 23, 24, 0, 25, 26, 27, 28, 0, 29, 30, - 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, - 0, 0, 0, 66, 161, 0, 32, 33, 0, 0, + 0, 0, 0, 0, 201, 201, 0, 0, 0, 0, + 0, 209, 5, 6, 7, 213, 8, 0, 9, 0, + 10, 11, 12, 0, 0, 0, 0, 13, 14, 15, + 0, 16, 17, 0, 18, 0, 0, 20, 0, 0, + 21, 22, 23, 24, 0, 25, 26, 27, 28, 0, + 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, + 31, 0, 0, 0, 161, 66, 0, 0, 32, 33, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, - 242, 244, 0, 247, 248, 249, 0, 0, 0, 0, - 0, 0, 0, 256, 0, 257, 0, 126, 260, 161, - 161, 159, 264, 0, 266, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 79, 80, 0, 281, 283, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 0, 294, 0, 5, 6, 7, 0, 8, 0, 9, - 298, 10, 11, 12, 0, 0, 161, 0, 13, 14, - 15, 0, 16, 17, 0, 18, 0, 312, 0, 0, - 20, 317, 0, 21, 22, 23, 24, 0, 25, 26, - 27, 28, 0, 29, 30, 258, 0, 0, 0, 0, - 0, 0, 0, 31, 0, 0, 0, 0, 0, 205, - 0, 32, 33, 79, 80, 0, 0, 0, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 351, 0, + 242, 244, 0, 247, 248, 249, 0, 101, 102, 103, + 104, 105, 106, 256, 107, 257, 109, 110, 260, 161, + 161, 159, 264, 0, 266, 0, 0, 0, 112, 113, + 114, 0, 0, 115, 116, 0, 0, 0, 281, 283, + 0, 0, 0, 0, 0, 0, 117, 118, 119, 120, + 0, 294, 123, 124, 0, 0, 0, 0, 0, 0, + 298, 0, 0, 5, 6, 7, 161, 8, 0, 9, + 0, 10, 11, 12, 0, 0, 0, 312, 13, 14, + 15, 317, 16, 17, 0, 18, 0, 0, 20, 0, + 0, 21, 22, 23, 24, 0, 25, 26, 27, 28, + 0, 29, 30, 0, 0, 0, 0, 0, 0, 0, + 0, 31, 0, 0, 0, 0, 0, 205, 0, 32, + 33, 0, 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 360, 361, - 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 373, 159, 0, 0, - 0, 0, 0, 5, 6, 7, 0, 8, 0, 9, - 381, 10, 11, 12, 0, 384, 0, 0, 13, 14, - 15, 0, 16, 17, 0, 18, 0, 0, 0, 0, - 20, 0, 0, 21, 22, 23, 24, 0, 25, 26, - 27, 28, 0, 29, 30, 0, 0, 0, 5, 6, - 7, 0, 8, 31, 9, 0, 10, 11, 12, 320, - 0, 32, 33, 13, 14, 15, 0, 16, 17, 0, - 18, 0, 0, 0, 0, 20, 0, 0, 21, 22, - 23, 24, 0, 25, 26, 27, 28, 0, 29, 30, - 0, 0, 0, 5, 6, 7, 0, 8, 31, 9, - 0, 10, 11, 12, 353, 0, 32, 33, 13, 14, - 15, 0, 16, 17, 0, 18, 0, 5, 6, 60, - 20, 0, 0, 21, 22, 23, 24, 0, 25, 26, - 27, 28, 0, 29, 30, 0, 0, 0, 0, 0, - 0, 0, 0, 31, 20, 0, 0, 21, 61, 23, - 24, 32, 33, 26, 27, 28, 0, 29, 30, 5, + 159, 0, 0, 5, 6, 7, 0, 8, 0, 9, + 0, 10, 11, 12, 0, 0, 373, 159, 13, 14, + 15, 0, 16, 17, 0, 18, 0, 0, 20, 0, + 381, 21, 22, 23, 24, 384, 25, 26, 27, 28, + 0, 29, 30, 0, 0, 0, 5, 6, 7, 0, + 8, 31, 9, 0, 10, 11, 12, 320, 0, 32, + 33, 13, 14, 15, 0, 16, 17, 0, 18, 0, + 0, 20, 0, 0, 21, 22, 23, 24, 0, 25, + 26, 27, 28, 0, 29, 30, 0, 0, 0, 5, + 6, 7, 0, 8, 31, 9, 0, 10, 11, 12, + 353, 0, 32, 33, 13, 14, 15, 0, 16, 17, + 0, 18, 0, 0, 20, 0, 0, 21, 22, 23, + 24, 0, 25, 26, 27, 28, 0, 29, 30, 5, + 6, 60, 0, 0, 0, 0, 0, 31, 0, 0, + 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, + 0, 0, 0, 0, 20, 0, 0, 21, 61, 23, + 24, 0, 0, 26, 27, 28, 0, 29, 30, 5, 6, 60, 0, 0, 0, 0, 0, 31, 0, 0, 0, 62, 0, 0, 0, 32, 33, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, - 61, 23, 24, 0, 0, 26, 27, 28, 0, 29, - 30, 5, 6, 60, 0, 0, 0, 0, 0, 31, - 0, 0, 0, 138, 0, 0, 0, 32, 33, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, - 0, 21, 61, 23, 24, 0, 0, 26, 27, 28, - 0, 29, 30, 5, 6, 60, 0, 0, 0, 0, - 0, 31, 0, 0, 0, 0, 191, 0, 0, 32, - 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 20, 0, 0, 21, 61, 23, 24, 0, 0, 26, - 27, 28, 0, 29, 30, 5, 6, 60, 0, 0, - 0, 0, 0, 31, 0, 0, 0, 208, 0, 0, - 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 20, 0, 0, 21, 61, 23, 24, 0, - 0, 26, 27, 28, 0, 29, 30, 5, 6, 60, - 0, 0, 0, 0, 0, 31, 243, 0, 0, 0, - 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 20, 0, 0, 21, 61, 23, + 24, 0, 0, 26, 27, 28, 0, 29, 30, 5, + 6, 60, 0, 0, 0, 0, 0, 31, 0, 0, + 0, 138, 0, 0, 0, 32, 33, 0, 0, 0, + 0, 0, 0, 0, 20, 0, 0, 21, 61, 23, + 24, 0, 0, 26, 27, 28, 0, 29, 30, 5, + 6, 60, 0, 0, 0, 0, 0, 31, 0, 0, + 0, 0, 191, 0, 0, 32, 33, 0, 0, 0, + 0, 0, 0, 0, 20, 0, 0, 21, 61, 23, + 24, 0, 0, 26, 27, 28, 0, 29, 30, 5, + 6, 60, 0, 0, 0, 0, 0, 31, 0, 0, + 0, 208, 0, 0, 0, 32, 33, 0, 0, 0, + 0, 0, 0, 0, 20, 0, 0, 21, 61, 23, + 24, 0, 0, 26, 27, 28, 0, 29, 30, 5, + 6, 60, 0, 0, 0, 0, 0, 31, 243, 0, + 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, 61, 23, 24, 0, 0, 26, 27, 28, 0, 29, 30, 5, 6, 60, 0, 0, 0, 0, 0, 31, 0, 0, 0, 246, 0, 0, 0, 32, 33, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, - 61, 23, 24, 0, 0, 26, 27, 28, 0, 29, - 30, 5, 6, 60, 0, 0, 0, 0, 0, 31, - 280, 0, 0, 0, 0, 0, 0, 32, 33, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, - 0, 21, 61, 23, 24, 0, 0, 26, 27, 28, - 0, 29, 30, 5, 6, 60, 0, 0, 0, 0, - 0, 31, 282, 0, 0, 0, 0, 0, 0, 32, - 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 20, 0, 0, 21, 61, 23, 24, 0, 0, 26, - 27, 28, 0, 29, 30, 5, 6, 60, 0, 0, - 0, 0, 0, 31, 311, 0, 0, 0, 0, 0, - 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 20, 0, 0, 21, 61, 23, 24, 0, - 0, 26, 27, 28, 0, 29, 30, 0, 0, 101, - 102, 103, 104, 105, 106, 31, 107, 108, 109, 110, - 0, 218, 219, 32, 33, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 0, 220, 0, 221, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, - 0, 0, 134, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, + 0, 0, 0, 0, 20, 0, 0, 21, 61, 23, + 24, 0, 0, 26, 27, 28, 0, 29, 30, 5, + 6, 60, 0, 0, 0, 0, 0, 31, 280, 0, + 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, + 0, 0, 0, 0, 20, 0, 0, 21, 61, 23, + 24, 0, 0, 26, 27, 28, 0, 29, 30, 5, + 6, 60, 0, 0, 0, 0, 0, 31, 282, 0, + 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, + 0, 0, 0, 0, 20, 0, 0, 21, 61, 23, + 24, 0, 0, 26, 27, 28, 0, 29, 30, 5, + 6, 60, 0, 0, 0, 0, 0, 31, 311, 0, + 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, + 0, 0, 0, 0, 20, 0, 0, 21, 61, 23, + 24, 0, 0, 26, 27, 28, 0, 29, 30, 0, + 0, 101, 102, 103, 104, 105, 106, 31, 107, 108, + 109, 110, 0, 218, 219, 32, 33, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 220, 0, 221, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 0, 134, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, 0, 165, 0, 0, 0, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 198, 0, 0, - 0, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 0, 0, 0, 124, 125, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 0, 203, 0, 0, 0, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 204, 0, 0, 0, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, - 0, 0, 210, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 198, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 203, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 204, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 0, 210, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, 0, 214, 0, 0, 0, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 215, 0, 0, - 0, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 0, 0, 0, 124, 125, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 0, 0, 0, 229, 0, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 0, 0, 0, 245, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, - 0, 237, 0, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 215, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 229, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 0, 245, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 237, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, 0, 277, 0, 0, 0, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 279, 0, 0, - 0, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 0, 0, 0, 124, 125, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 0, 0, 0, 0, 284, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 285, 0, 0, 0, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 286, - 0, 0, 0, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 279, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 0, 284, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 285, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 286, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, 0, 0, 293, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 308, 0, 0, - 0, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 0, 0, 0, 124, 125, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 0, 310, 0, 0, 0, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 328, 0, 0, 0, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, - 0, 0, 370, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 308, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 310, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 328, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 0, 370, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, 0, 0, 371, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 0, 0, 0, - 378, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 0, 0, 0, 124, 125, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 0, 0, 0, 0, 383, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 0, 0, 0, 385, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, - 0, 0, 0, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 0, 378, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 0, 383, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 0, 385, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, 0, 0, 0, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, - 101, 102, 103, 104, 105, 106, 0, 107, 108, 109, - 110, 117, 118, 119, 120, 121, 122, 123, 111, 0, - 0, 112, 113, 114, 125, 0, 0, 115, 116, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 117, 118, 119, 120, 121, 0, 123, 111, 0, 0, - 112, 113, 114, 125, 0, 0, 115, 116, 101, 102, - 103, 104, 105, 106, 0, 107, 0, 109, 110, 117, - 118, 119, 120, 0, 0, 123, 111, 0, 0, 112, - 113, 114, 125, 0, 0, 115, 116, 101, 102, 103, - 104, 105, 106, 0, 107, 0, 109, 110, 117, 118, - 119, 120, 0, 0, 123, 0, 0, 0, 112, 113, - 114, 125, 0, 0, 115, 116, 101, 102, 103, 104, - 105, 106, 0, 107, 0, 0, 110, 117, 118, 119, - 120, 0, 0, 123, 0, 0, 0, 112, 113, 114, - 125, 0, 0, 115, 116, 101, 102, 103, 104, 105, - 106, 0, 107, 0, 0, 110, 117, 118, 119, 120, - 0, 0, 123, 0, 0, 0, 112, 113, 114, 125, - 0, 0, 115, 116, 101, 102, 103, 104, 0, 0, - 0, 107, 0, 0, 110, 0, 0, 119, 120, 0, - 0, 123, 0, 0, 0, 0, 113, 114, 125, 0, - 0, 115, 116 + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 0, 0, + 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, + 109, 110, 0, 0, 0, 0, 0, 0, 0, 111, + 0, 0, 112, 113, 114, 0, 0, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 118, 119, 120, 121, 122, 123, 124, 101, 102, + 103, 104, 105, 106, 0, 107, 108, 109, 110, 0, + 0, 0, 0, 0, 0, 0, 111, 0, 0, 112, + 113, 114, 0, 0, 115, 116, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, + 120, 121, 0, 123, 124, 101, 102, 103, 104, 105, + 106, 0, 107, 108, 109, 110, 0, 0, 0, 0, + 0, 0, 0, 111, 0, 0, 112, 113, 114, 0, + 0, 115, 116, 101, 102, 103, 104, 105, 106, 0, + 107, 0, 0, 110, 117, 118, 119, 120, 0, 0, + 123, 124, 0, 0, 112, 113, 114, 0, 0, 115, + 116, 101, 102, 103, 104, 105, 106, 0, 107, 0, + 0, 110, 117, 118, 119, 120, 0, 0, 123, 124, + 0, 0, 112, 113, 114, 0, 78, 115, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 119, 120, 79, 80, 123, 124, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 126, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, + 0, 0, 258, 0, 0, 0, 79, 80, 0, 0, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 79, 80, 0, 0, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90 }; static const yytype_int16 yycheck[] = { - 2, 2, 47, 228, 203, 204, 6, 252, 268, 202, - 12, 191, 132, 145, 50, 57, 16, 3, 38, 333, - 213, 51, 0, 239, 50, 57, 24, 38, 342, 50, - 5, 6, 5, 6, 7, 55, 66, 67, 226, 227, - 38, 39, 68, 69, 243, 59, 50, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 99, 57, 32, - 96, 321, 35, 36, 37, 38, 92, 99, 41, 42, - 43, 92, 45, 46, 57, 61, 336, 276, 271, 199, - 279, 280, 55, 282, 216, 301, 285, 286, 92, 55, - 63, 64, 55, 273, 55, 28, 55, 324, 5, 6, - 99, 57, 323, 324, 59, 61, 55, 352, 55, 308, - 55, 310, 311, 113, 114, 375, 99, 24, 55, 92, - 341, 342, 347, 55, 55, 58, 92, 354, 91, 328, - 91, 38, 39, 354, 136, 136, 38, 358, 55, 364, - 46, 47, 50, 59, 59, 51, 55, 3, 54, 5, - 6, 7, 55, 9, 14, 11, 37, 13, 14, 15, - 66, 67, 37, 55, 20, 21, 22, 60, 24, 25, - 38, 27, 38, 29, 37, 55, 32, 38, 223, 35, - 36, 37, 38, 23, 40, 41, 42, 43, 23, 45, - 46, 3, 56, 58, 41, 57, 55, 50, 56, 55, - 57, 203, 204, 55, 99, 60, 60, 63, 64, 60, - 38, 57, 5, 6, 7, 56, 9, 8, 11, 26, - 13, 14, 15, 59, 56, 56, 19, 20, 21, 22, - 56, 24, 25, 26, 27, 56, 56, 56, 60, 32, - 56, 243, 35, 36, 37, 38, 61, 40, 41, 42, - 43, 61, 45, 46, 60, 60, 60, 38, 50, 61, - 60, 59, 55, 59, 61, 44, 45, 46, 47, 59, - 63, 64, 51, 61, 276, 54, 58, 279, 280, 50, - 282, 61, 50, 285, 286, 235, 234, 66, 67, 342, - 315, -1, -1, 10, -1, -1, -1, 299, 299, -1, - 44, 45, 46, 47, -1, -1, 308, 51, 310, 311, - 54, -1, 29, 30, 31, 32, 33, -1, -1, -1, - -1, 65, 66, 67, -1, -1, 328, 71, 72, -1, - -1, -1, -1, -1, -1, 337, 337, 54, -1, -1, - -1, -1, 59, -1, -1, -1, 90, -1, 65, -1, - 352, 352, 69, 97, -1, -1, 73, 74, -1, 76, + 2, 2, 47, 228, 203, 204, 6, 252, 268, 191, + 12, 5, 6, 7, 145, 202, 16, 239, 3, 48, + 55, 132, 48, 48, 324, 55, 213, 0, 55, 28, + 36, 55, 53, 53, 333, 53, 30, 53, 36, 33, + 34, 35, 36, 342, 243, 39, 40, 41, 55, 43, + 44, 14, 59, 57, 354, 53, 36, 56, 93, 53, + 57, 321, 91, 93, 90, 90, 93, 61, 62, 93, + 90, 89, 53, 89, 59, 53, 336, 276, 49, 301, + 279, 280, 48, 282, 271, 216, 285, 286, 199, 53, + 24, 273, 53, 64, 65, 53, 90, 53, 42, 43, + 44, 45, 36, 37, 53, 49, 57, 352, 52, 308, + 57, 310, 311, 113, 114, 375, 5, 6, 53, 63, + 64, 65, 347, 53, 68, 69, 35, 323, 324, 328, + 226, 227, 35, 53, 136, 136, 58, 36, 36, 364, + 35, 53, 36, 87, 88, 341, 342, 23, 23, 3, + 3, 5, 6, 7, 54, 9, 53, 11, 354, 13, + 14, 15, 358, 55, 5, 6, 20, 21, 22, 54, + 24, 25, 55, 27, 53, 29, 30, 58, 223, 33, + 34, 35, 36, 24, 38, 39, 40, 41, 56, 43, + 44, 58, 39, 48, 58, 36, 37, 93, 36, 53, + 8, 203, 204, 55, 54, 26, 57, 61, 62, 5, + 6, 7, 54, 9, 54, 11, 59, 13, 14, 15, + 54, 54, 54, 19, 20, 21, 22, 54, 24, 25, + 26, 27, 58, 58, 30, 59, 58, 33, 34, 35, + 36, 243, 38, 39, 40, 41, 58, 43, 44, 42, + 43, 44, 45, 46, 47, 54, 49, 53, 51, 52, + 48, 36, 59, 58, 56, 61, 62, 60, 57, 59, + 63, 64, 65, 59, 276, 68, 69, 279, 280, 57, + 282, 57, 59, 285, 286, 48, 48, 235, 81, 82, + 83, 84, 234, 10, 87, 88, 342, 299, 299, -1, + 42, 43, 44, 45, 315, -1, 308, 49, 310, 311, + 52, -1, 29, 30, 31, 32, 33, 42, 43, 44, + 45, -1, 64, 65, 49, -1, 328, 52, -1, -1, + -1, -1, -1, 44, 45, 337, 337, 54, 49, 64, + 65, 52, 59, 68, 69, -1, -1, -1, 65, -1, + 352, 352, 69, 64, 65, -1, 73, 74, -1, 76, 77, 78, -1, -1, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, -1, 93, -1, 380, 380, -1, -1, -1, -1, 101, 102, 103, 104, 105, 106, -1, 108, 109, 110, 111, 112, -1, -1, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - -1, -1, -1, -1, 131, 132, -1, -1, 5, 6, - 7, 138, 9, -1, 11, 142, 13, 14, 15, -1, - -1, -1, -1, 20, 21, 22, -1, 24, 25, -1, - 27, -1, -1, -1, -1, 32, -1, -1, 35, 36, - 37, 38, -1, 40, 41, 42, 43, -1, 45, 46, - -1, -1, -1, -1, -1, -1, -1, -1, 55, -1, - -1, -1, -1, 60, 191, -1, 63, 64, -1, -1, + -1, -1, -1, -1, 131, 132, -1, -1, -1, -1, + -1, 138, 5, 6, 7, 142, 9, -1, 11, -1, + 13, 14, 15, -1, -1, -1, -1, 20, 21, 22, + -1, 24, 25, -1, 27, -1, -1, 30, -1, -1, + 33, 34, 35, 36, -1, 38, 39, 40, 41, -1, + 43, 44, -1, -1, -1, -1, -1, -1, -1, -1, + 53, -1, -1, -1, 191, 58, -1, -1, 61, 62, -1, -1, 199, -1, -1, -1, -1, -1, -1, -1, - 207, 208, -1, 210, 211, 212, -1, -1, -1, -1, - -1, -1, -1, 220, -1, 222, -1, 50, 225, 226, - 227, 228, 229, -1, 231, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 68, 69, -1, 245, 246, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - -1, 258, -1, 5, 6, 7, -1, 9, -1, 11, - 267, 13, 14, 15, -1, -1, 273, -1, 20, 21, - 22, -1, 24, 25, -1, 27, -1, 284, -1, -1, - 32, 288, -1, 35, 36, 37, 38, -1, 40, 41, - 42, 43, -1, 45, 46, 50, -1, -1, -1, -1, - -1, -1, -1, 55, -1, -1, -1, -1, -1, 61, - -1, 63, 64, 68, 69, -1, -1, -1, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 335, -1, + 207, 208, -1, 210, 211, 212, -1, 42, 43, 44, + 45, 46, 47, 220, 49, 222, 51, 52, 225, 226, + 227, 228, 229, -1, 231, -1, -1, -1, 63, 64, + 65, -1, -1, 68, 69, -1, -1, -1, 245, 246, + -1, -1, -1, -1, -1, -1, 81, 82, 83, 84, + -1, 258, 87, 88, -1, -1, -1, -1, -1, -1, + 267, -1, -1, 5, 6, 7, 273, 9, -1, 11, + -1, 13, 14, 15, -1, -1, -1, 284, 20, 21, + 22, 288, 24, 25, -1, 27, -1, -1, 30, -1, + -1, 33, 34, 35, 36, -1, 38, 39, 40, 41, + -1, 43, 44, -1, -1, -1, -1, -1, -1, -1, + -1, 53, -1, -1, -1, -1, -1, 59, -1, 61, + 62, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, -1, -1, -1, -1, -1, -1, -1, 345, 346, - 347, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 363, 364, -1, -1, - -1, -1, -1, 5, 6, 7, -1, 9, -1, 11, - 377, 13, 14, 15, -1, 382, -1, -1, 20, 21, - 22, -1, 24, 25, -1, 27, -1, -1, -1, -1, - 32, -1, -1, 35, 36, 37, 38, -1, 40, 41, - 42, 43, -1, 45, 46, -1, -1, -1, 5, 6, - 7, -1, 9, 55, 11, -1, 13, 14, 15, 61, - -1, 63, 64, 20, 21, 22, -1, 24, 25, -1, - 27, -1, -1, -1, -1, 32, -1, -1, 35, 36, - 37, 38, -1, 40, 41, 42, 43, -1, 45, 46, - -1, -1, -1, 5, 6, 7, -1, 9, 55, 11, - -1, 13, 14, 15, 61, -1, 63, 64, 20, 21, - 22, -1, 24, 25, -1, 27, -1, 5, 6, 7, - 32, -1, -1, 35, 36, 37, 38, -1, 40, 41, - 42, 43, -1, 45, 46, -1, -1, -1, -1, -1, - -1, -1, -1, 55, 32, -1, -1, 35, 36, 37, - 38, 63, 64, 41, 42, 43, -1, 45, 46, 5, - 6, 7, -1, -1, -1, -1, -1, 55, -1, -1, - -1, 59, -1, -1, -1, 63, 64, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 32, -1, -1, 35, - 36, 37, 38, -1, -1, 41, 42, 43, -1, 45, - 46, 5, 6, 7, -1, -1, -1, -1, -1, 55, - -1, -1, -1, 59, -1, -1, -1, 63, 64, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 32, -1, - -1, 35, 36, 37, 38, -1, -1, 41, 42, 43, - -1, 45, 46, 5, 6, 7, -1, -1, -1, -1, - -1, 55, -1, -1, -1, -1, 60, -1, -1, 63, - 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 32, -1, -1, 35, 36, 37, 38, -1, -1, 41, - 42, 43, -1, 45, 46, 5, 6, 7, -1, -1, - -1, -1, -1, 55, -1, -1, -1, 59, -1, -1, - -1, 63, 64, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 32, -1, -1, 35, 36, 37, 38, -1, - -1, 41, 42, 43, -1, 45, 46, 5, 6, 7, - -1, -1, -1, -1, -1, 55, 56, -1, -1, -1, - -1, -1, -1, 63, 64, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 32, -1, -1, 35, 36, 37, - 38, -1, -1, 41, 42, 43, -1, 45, 46, 5, - 6, 7, -1, -1, -1, -1, -1, 55, -1, -1, - -1, 59, -1, -1, -1, 63, 64, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 32, -1, -1, 35, - 36, 37, 38, -1, -1, 41, 42, 43, -1, 45, - 46, 5, 6, 7, -1, -1, -1, -1, -1, 55, - 56, -1, -1, -1, -1, -1, -1, 63, 64, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 32, -1, - -1, 35, 36, 37, 38, -1, -1, 41, 42, 43, - -1, 45, 46, 5, 6, 7, -1, -1, -1, -1, - -1, 55, 56, -1, -1, -1, -1, -1, -1, 63, - 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 32, -1, -1, 35, 36, 37, 38, -1, -1, 41, - 42, 43, -1, 45, 46, 5, 6, 7, -1, -1, - -1, -1, -1, 55, 56, -1, -1, -1, -1, -1, - -1, 63, 64, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 32, -1, -1, 35, 36, 37, 38, -1, - -1, 41, 42, 43, -1, 45, 46, -1, -1, 44, - 45, 46, 47, 48, 49, 55, 51, 52, 53, 54, - -1, 56, 57, 63, 64, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, -1, 57, -1, 59, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, -1, - -1, -1, 59, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, 56, -1, -1, -1, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, + 347, -1, -1, 5, 6, 7, -1, 9, -1, 11, + -1, 13, 14, 15, -1, -1, 363, 364, 20, 21, + 22, -1, 24, 25, -1, 27, -1, -1, 30, -1, + 377, 33, 34, 35, 36, 382, 38, 39, 40, 41, + -1, 43, 44, -1, -1, -1, 5, 6, 7, -1, + 9, 53, 11, -1, 13, 14, 15, 59, -1, 61, + 62, 20, 21, 22, -1, 24, 25, -1, 27, -1, + -1, 30, -1, -1, 33, 34, 35, 36, -1, 38, + 39, 40, 41, -1, 43, 44, -1, -1, -1, 5, + 6, 7, -1, 9, 53, 11, -1, 13, 14, 15, + 59, -1, 61, 62, 20, 21, 22, -1, 24, 25, + -1, 27, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, 38, 39, 40, 41, -1, 43, 44, 5, + 6, 7, -1, -1, -1, -1, -1, 53, -1, -1, + -1, -1, -1, -1, -1, 61, 62, -1, -1, -1, + -1, -1, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, -1, 39, 40, 41, -1, 43, 44, 5, + 6, 7, -1, -1, -1, -1, -1, 53, -1, -1, + -1, 57, -1, -1, -1, 61, 62, -1, -1, -1, + -1, -1, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, -1, 39, 40, 41, -1, 43, 44, 5, + 6, 7, -1, -1, -1, -1, -1, 53, -1, -1, + -1, 57, -1, -1, -1, 61, 62, -1, -1, -1, + -1, -1, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, -1, 39, 40, 41, -1, 43, 44, 5, + 6, 7, -1, -1, -1, -1, -1, 53, -1, -1, + -1, -1, 58, -1, -1, 61, 62, -1, -1, -1, + -1, -1, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, -1, 39, 40, 41, -1, 43, 44, 5, + 6, 7, -1, -1, -1, -1, -1, 53, -1, -1, + -1, 57, -1, -1, -1, 61, 62, -1, -1, -1, + -1, -1, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, -1, 39, 40, 41, -1, 43, 44, 5, + 6, 7, -1, -1, -1, -1, -1, 53, 54, -1, + -1, -1, -1, -1, -1, 61, 62, -1, -1, -1, + -1, -1, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, -1, 39, 40, 41, -1, 43, 44, 5, + 6, 7, -1, -1, -1, -1, -1, 53, -1, -1, + -1, 57, -1, -1, -1, 61, 62, -1, -1, -1, + -1, -1, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, -1, 39, 40, 41, -1, 43, 44, 5, + 6, 7, -1, -1, -1, -1, -1, 53, 54, -1, + -1, -1, -1, -1, -1, 61, 62, -1, -1, -1, + -1, -1, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, -1, 39, 40, 41, -1, 43, 44, 5, + 6, 7, -1, -1, -1, -1, -1, 53, 54, -1, + -1, -1, -1, -1, -1, 61, 62, -1, -1, -1, + -1, -1, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, -1, 39, 40, 41, -1, 43, 44, 5, + 6, 7, -1, -1, -1, -1, -1, 53, 54, -1, + -1, -1, -1, -1, -1, 61, 62, -1, -1, -1, + -1, -1, -1, -1, 30, -1, -1, 33, 34, 35, + 36, -1, -1, 39, 40, 41, -1, 43, 44, -1, + -1, 42, 43, 44, 45, 46, 47, 53, 49, 50, + 51, 52, -1, 54, 55, 61, 62, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, 56, -1, -1, - -1, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, 86, 87, 88, - 89, 90, -1, -1, -1, -1, -1, 96, 97, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, 56, -1, -1, -1, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, 56, -1, -1, -1, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, -1, - -1, -1, 59, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, 56, -1, -1, -1, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, 55, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, 56, -1, -1, - -1, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, 86, 87, 88, - 89, 90, -1, -1, -1, -1, -1, 96, 97, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, -1, -1, 58, -1, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, -1, -1, -1, 59, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, -1, - -1, 58, -1, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, 56, -1, -1, -1, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, 56, -1, -1, - -1, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, 86, 87, 88, - 89, 90, -1, -1, -1, -1, -1, 96, 97, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, -1, -1, -1, 59, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, 56, -1, -1, -1, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, 56, - -1, -1, -1, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, -1, -1, -1, 59, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, 56, -1, -1, - -1, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, 86, 87, 88, - 89, 90, -1, -1, -1, -1, -1, 96, 97, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, 56, -1, -1, -1, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, 56, -1, -1, -1, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, -1, - -1, -1, 59, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, -1, -1, -1, 59, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, -1, -1, -1, - 59, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, 86, 87, 88, - 89, 90, -1, -1, -1, -1, -1, 96, 97, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, -1, -1, -1, 59, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, -1, -1, -1, 59, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, -1, - -1, -1, -1, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, -1, -1, -1, -1, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, - 44, 45, 46, 47, 48, 49, -1, 51, 52, 53, - 54, 84, 85, 86, 87, 88, 89, 90, 62, -1, - -1, 65, 66, 67, 97, -1, -1, 71, 72, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - 84, 85, 86, 87, 88, -1, 90, 62, -1, -1, - 65, 66, 67, 97, -1, -1, 71, 72, 44, 45, - 46, 47, 48, 49, -1, 51, -1, 53, 54, 84, - 85, 86, 87, -1, -1, 90, 62, -1, -1, 65, - 66, 67, 97, -1, -1, 71, 72, 44, 45, 46, - 47, 48, 49, -1, 51, -1, 53, 54, 84, 85, - 86, 87, -1, -1, 90, -1, -1, -1, 65, 66, - 67, 97, -1, -1, 71, 72, 44, 45, 46, 47, - 48, 49, -1, 51, -1, -1, 54, 84, 85, 86, - 87, -1, -1, 90, -1, -1, -1, 65, 66, 67, - 97, -1, -1, 71, 72, 44, 45, 46, 47, 48, - 49, -1, 51, -1, -1, 54, 84, 85, 86, 87, - -1, -1, 90, -1, -1, -1, 65, 66, 67, 97, - -1, -1, 71, 72, 44, 45, 46, 47, -1, -1, - -1, 51, -1, -1, 54, -1, -1, 86, 87, -1, - -1, 90, -1, -1, -1, -1, 66, 67, 97, -1, - -1, 71, 72 + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, 56, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, 56, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, 54, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, 57, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, + 91, 42, 43, 44, 45, 46, 47, -1, 49, 50, + 51, 52, -1, -1, -1, -1, -1, -1, -1, 60, + -1, -1, 63, 64, 65, -1, -1, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 82, 83, 84, 85, 86, 87, 88, 42, 43, + 44, 45, 46, 47, -1, 49, 50, 51, 52, -1, + -1, -1, -1, -1, -1, -1, 60, -1, -1, 63, + 64, 65, -1, -1, 68, 69, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 81, 82, 83, + 84, 85, -1, 87, 88, 42, 43, 44, 45, 46, + 47, -1, 49, 50, 51, 52, -1, -1, -1, -1, + -1, -1, -1, 60, -1, -1, 63, 64, 65, -1, + -1, 68, 69, 42, 43, 44, 45, 46, 47, -1, + 49, -1, -1, 52, 81, 82, 83, 84, -1, -1, + 87, 88, -1, -1, 63, 64, 65, -1, -1, 68, + 69, 42, 43, 44, 45, 46, 47, -1, 49, -1, + -1, 52, 81, 82, 83, 84, -1, -1, 87, 88, + -1, -1, 63, 64, 65, -1, 48, 68, 69, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 83, 84, 66, 67, 87, 88, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 48, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 90, -1, + -1, -1, 48, -1, -1, -1, 66, 67, -1, -1, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 66, 67, -1, -1, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 101, 102, 0, 3, 5, 6, 7, 9, 11, + 0, 95, 96, 0, 3, 5, 6, 7, 9, 11, 13, 14, 15, 20, 21, 22, 24, 25, 27, 29, - 32, 35, 36, 37, 38, 40, 41, 42, 43, 45, - 46, 55, 63, 64, 103, 104, 107, 108, 112, 113, - 120, 123, 124, 125, 126, 127, 128, 129, 130, 133, - 134, 135, 38, 38, 55, 131, 131, 59, 59, 55, - 7, 36, 59, 128, 133, 55, 60, 107, 119, 55, - 55, 55, 131, 55, 55, 38, 55, 50, 50, 68, - 69, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 92, 132, 55, 91, 128, 128, 128, 128, 128, - 59, 44, 45, 46, 47, 48, 49, 51, 52, 53, - 54, 62, 65, 66, 67, 71, 72, 84, 85, 86, - 87, 88, 89, 90, 96, 97, 50, 132, 55, 91, - 128, 55, 55, 128, 59, 128, 106, 14, 59, 128, - 37, 37, 55, 128, 128, 60, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 141, 128, 136, 137, 38, 56, 128, 128, 128, 128, - 128, 128, 38, 128, 128, 128, 128, 128, 131, 131, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 60, 128, 37, 109, 110, 111, 38, 56, 92, - 115, 128, 115, 56, 56, 61, 107, 55, 59, 128, - 59, 23, 23, 128, 56, 56, 105, 108, 56, 57, - 57, 59, 57, 99, 56, 57, 55, 55, 92, 58, - 137, 50, 96, 56, 57, 55, 115, 58, 114, 114, - 119, 119, 128, 56, 128, 59, 59, 128, 128, 128, - 114, 60, 60, 61, 108, 41, 128, 128, 50, 132, - 128, 136, 136, 141, 128, 61, 128, 50, 60, 111, - 109, 99, 38, 57, 116, 116, 8, 56, 119, 56, - 56, 128, 56, 128, 59, 56, 56, 56, 26, 121, - 121, 59, 56, 59, 128, 56, 56, 99, 128, 106, - 56, 114, 137, 56, 56, 119, 119, 119, 56, 119, - 56, 56, 128, 119, 119, 60, 122, 128, 61, 61, - 61, 60, 116, 60, 60, 119, 119, 119, 56, 24, - 38, 39, 138, 139, 140, 28, 58, 106, 56, 113, - 117, 118, 139, 117, 119, 50, 50, 92, 38, 61, - 140, 128, 106, 61, 60, 59, 61, 113, 118, 61, - 128, 128, 141, 50, 92, 59, 19, 121, 117, 59, - 59, 59, 99, 128, 141, 58, 61, 50, 59, 99, - 106, 128, 50, 59, 128, 59 + 30, 33, 34, 35, 36, 38, 39, 40, 41, 43, + 44, 53, 61, 62, 97, 98, 101, 102, 106, 107, + 114, 117, 118, 119, 120, 121, 122, 123, 124, 127, + 128, 129, 36, 36, 53, 125, 125, 57, 57, 53, + 7, 34, 57, 122, 127, 53, 58, 101, 113, 53, + 53, 53, 125, 53, 53, 36, 53, 48, 48, 66, + 67, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 90, 126, 53, 89, 122, 122, 122, 122, 122, + 57, 42, 43, 44, 45, 46, 47, 49, 50, 51, + 52, 60, 63, 64, 65, 68, 69, 81, 82, 83, + 84, 85, 86, 87, 88, 91, 48, 126, 53, 89, + 122, 53, 53, 122, 57, 122, 100, 14, 57, 122, + 35, 35, 53, 122, 122, 58, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 135, 122, 130, 131, 36, 54, 122, 122, 122, 122, + 122, 122, 36, 122, 122, 122, 122, 122, 125, 125, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 58, 122, 35, 103, 104, 105, 36, 54, 90, + 109, 122, 109, 54, 54, 59, 101, 53, 57, 122, + 57, 23, 23, 122, 54, 54, 99, 102, 54, 55, + 55, 57, 55, 93, 54, 55, 53, 53, 90, 56, + 131, 48, 91, 54, 55, 53, 109, 56, 108, 108, + 113, 113, 122, 54, 122, 57, 57, 122, 122, 122, + 108, 58, 58, 59, 102, 39, 122, 122, 48, 126, + 122, 130, 130, 135, 122, 59, 122, 48, 58, 105, + 103, 93, 36, 55, 110, 110, 8, 54, 113, 54, + 54, 122, 54, 122, 57, 54, 54, 54, 26, 115, + 115, 57, 54, 57, 122, 54, 54, 93, 122, 100, + 54, 108, 131, 54, 54, 113, 113, 113, 54, 113, + 54, 54, 122, 113, 113, 58, 116, 122, 59, 59, + 59, 58, 110, 58, 58, 113, 113, 113, 54, 24, + 36, 37, 132, 133, 134, 28, 56, 100, 54, 107, + 111, 112, 133, 111, 113, 48, 48, 90, 36, 59, + 134, 122, 100, 59, 58, 57, 59, 107, 112, 59, + 122, 122, 135, 48, 90, 57, 19, 115, 111, 57, + 57, 57, 93, 122, 135, 56, 59, 48, 57, 93, + 100, 122, 48, 57, 122, 57 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_uint8 yyr1[] = { - 0, 100, 101, 102, 102, 103, 103, 103, 104, 105, - 105, 106, 106, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 108, 108, 109, - 109, 110, 110, 111, 111, 111, 111, 112, 113, 113, - 113, 113, 113, 113, 114, 114, 115, 115, 116, 116, - 117, 117, 117, 117, 118, 118, 119, 119, 120, 120, - 121, 121, 121, 122, 122, 123, 123, 124, 124, 125, - 125, 125, 125, 125, 125, 125, 125, 126, 126, 127, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 129, - 129, 130, 130, 131, 131, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 133, 133, 133, - 133, 133, 133, 133, 133, 133, 133, 134, 134, 134, - 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, - 140, 140, 140, 140, 140, 141, 141 + 0, 94, 95, 96, 96, 97, 97, 97, 98, 99, + 99, 100, 100, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 102, 102, 103, + 103, 104, 104, 105, 105, 105, 105, 106, 107, 107, + 107, 107, 107, 107, 108, 108, 109, 109, 110, 110, + 111, 111, 111, 111, 112, 112, 113, 113, 114, 114, + 115, 115, 115, 116, 116, 117, 117, 118, 118, 119, + 119, 119, 119, 119, 119, 119, 119, 120, 120, 121, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, + 123, 124, 124, 125, 125, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 128, 128, 128, + 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, + 134, 134, 134, 134, 134, 135, 135 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ @@ -2212,969 +2181,961 @@ yyreduce: switch (yyn) { case 2: /* start: decl_list */ -#line 168 "CMDgram.y" +#line 193 "CMDgram.y" { } -#line 2218 "CMDgram.c" +#line 2187 "CMDgram.c" break; case 3: /* decl_list: %empty */ -#line 173 "CMDgram.y" +#line 198 "CMDgram.y" { (yyval.stmt) = nil; } -#line 2224 "CMDgram.c" +#line 2193 "CMDgram.c" break; case 4: /* decl_list: decl_list decl */ -#line 175 "CMDgram.y" +#line 200 "CMDgram.y" { if(!Script::gStatementList) { Script::gStatementList = (yyvsp[0].stmt); } else { Script::gStatementList->append((yyvsp[0].stmt)); } } -#line 2230 "CMDgram.c" +#line 2199 "CMDgram.c" break; case 5: /* decl: stmt */ -#line 180 "CMDgram.y" +#line 205 "CMDgram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2236 "CMDgram.c" +#line 2205 "CMDgram.c" break; case 6: /* decl: fn_decl_stmt */ -#line 182 "CMDgram.y" +#line 207 "CMDgram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2242 "CMDgram.c" +#line 2211 "CMDgram.c" break; case 7: /* decl: package_decl */ -#line 184 "CMDgram.y" +#line 209 "CMDgram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2248 "CMDgram.c" +#line 2217 "CMDgram.c" break; case 8: /* package_decl: rwPACKAGE IDENT '{' fn_decl_list '}' ';' */ -#line 189 "CMDgram.y" +#line 214 "CMDgram.y" { (yyval.stmt) = (yyvsp[-2].stmt); for(StmtNode *walk = ((yyvsp[-2].stmt));walk;walk = walk->getNext() ) walk->setPackage((yyvsp[-4].s).value); } -#line 2254 "CMDgram.c" +#line 2223 "CMDgram.c" break; case 9: /* fn_decl_list: fn_decl_stmt */ -#line 194 "CMDgram.y" +#line 219 "CMDgram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2260 "CMDgram.c" +#line 2229 "CMDgram.c" break; case 10: /* fn_decl_list: fn_decl_list fn_decl_stmt */ -#line 196 "CMDgram.y" +#line 221 "CMDgram.y" { (yyval.stmt) = (yyvsp[-1].stmt); ((yyvsp[-1].stmt))->append((yyvsp[0].stmt)); } -#line 2266 "CMDgram.c" +#line 2235 "CMDgram.c" break; case 11: /* statement_list: %empty */ -#line 201 "CMDgram.y" +#line 226 "CMDgram.y" { (yyval.stmt) = nil; } -#line 2272 "CMDgram.c" +#line 2241 "CMDgram.c" break; case 12: /* statement_list: statement_list stmt */ -#line 203 "CMDgram.y" +#line 228 "CMDgram.y" { if(!(yyvsp[-1].stmt)) { (yyval.stmt) = (yyvsp[0].stmt); } else { ((yyvsp[-1].stmt))->append((yyvsp[0].stmt)); (yyval.stmt) = (yyvsp[-1].stmt); } } -#line 2278 "CMDgram.c" +#line 2247 "CMDgram.c" break; case 19: /* stmt: rwBREAK ';' */ -#line 214 "CMDgram.y" +#line 239 "CMDgram.y" { (yyval.stmt) = BreakStmtNode::alloc( (yyvsp[-1].i).lineNumber ); } -#line 2284 "CMDgram.c" +#line 2253 "CMDgram.c" break; case 20: /* stmt: rwCONTINUE ';' */ -#line 216 "CMDgram.y" +#line 241 "CMDgram.y" { (yyval.stmt) = ContinueStmtNode::alloc( (yyvsp[-1].i).lineNumber ); } -#line 2290 "CMDgram.c" +#line 2259 "CMDgram.c" break; case 21: /* stmt: rwRETURN ';' */ -#line 218 "CMDgram.y" +#line 243 "CMDgram.y" { (yyval.stmt) = ReturnStmtNode::alloc( (yyvsp[-1].i).lineNumber, NULL ); } -#line 2296 "CMDgram.c" +#line 2265 "CMDgram.c" break; case 22: /* stmt: rwRETURN expr ';' */ -#line 220 "CMDgram.y" +#line 245 "CMDgram.y" { (yyval.stmt) = ReturnStmtNode::alloc( (yyvsp[-2].i).lineNumber, (yyvsp[-1].expr) ); } -#line 2302 "CMDgram.c" +#line 2271 "CMDgram.c" break; case 23: /* stmt: expression_stmt ';' */ -#line 222 "CMDgram.y" +#line 247 "CMDgram.y" { (yyval.stmt) = (yyvsp[-1].stmt); } -#line 2308 "CMDgram.c" +#line 2277 "CMDgram.c" break; case 24: /* stmt: TTAG '=' expr ';' */ -#line 224 "CMDgram.y" +#line 249 "CMDgram.y" { (yyval.stmt) = TTagSetStmtNode::alloc( (yyvsp[-3].s).lineNumber, (yyvsp[-3].s).value, (yyvsp[-1].expr), NULL ); } -#line 2314 "CMDgram.c" +#line 2283 "CMDgram.c" break; case 25: /* stmt: TTAG '=' expr ',' expr ';' */ -#line 226 "CMDgram.y" +#line 251 "CMDgram.y" { (yyval.stmt) = TTagSetStmtNode::alloc( (yyvsp[-5].s).lineNumber, (yyvsp[-5].s).value, (yyvsp[-3].expr), (yyvsp[-1].expr) ); } -#line 2320 "CMDgram.c" +#line 2289 "CMDgram.c" break; case 26: /* stmt: DOCBLOCK */ -#line 228 "CMDgram.y" +#line 253 "CMDgram.y" { (yyval.stmt) = StrConstNode::alloc( (yyvsp[0].str).lineNumber, (yyvsp[0].str).value, false, true ); } -#line 2326 "CMDgram.c" +#line 2295 "CMDgram.c" break; case 27: /* fn_decl_stmt: rwDEFINE IDENT '(' var_list_decl ')' '{' statement_list '}' */ -#line 233 "CMDgram.y" +#line 259 "CMDgram.y" { (yyval.stmt) = FunctionDeclStmtNode::alloc( (yyvsp[-7].i).lineNumber, (yyvsp[-6].s).value, NULL, (yyvsp[-4].var), (yyvsp[-1].stmt) ); } -#line 2332 "CMDgram.c" +#line 2301 "CMDgram.c" break; case 28: /* fn_decl_stmt: rwDEFINE IDENT opCOLONCOLON IDENT '(' var_list_decl ')' '{' statement_list '}' */ -#line 235 "CMDgram.y" - { (yyval.stmt) = FunctionDeclStmtNode::alloc( (yyvsp[-9].i).lineNumber, (yyvsp[-6].s).value, (yyvsp[-8].s).value, (yyvsp[-4].var), (yyvsp[-1].stmt) ); } -#line 2338 "CMDgram.c" +#line 262 "CMDgram.y" + { (yyval.stmt) = FunctionDeclStmtNode::alloc( (yyvsp[-9].i).lineNumber, (yyvsp[-6].s).value, (yyvsp[-8].s).value, (yyvsp[-4].var), (yyvsp[-1].stmt) ); } +#line 2307 "CMDgram.c" break; case 29: /* var_list_decl: %empty */ -#line 240 "CMDgram.y" - { (yyval.var) = NULL; } -#line 2344 "CMDgram.c" +#line 267 "CMDgram.y" + { (yyval.var) = NULL; } +#line 2313 "CMDgram.c" break; case 30: /* var_list_decl: var_list */ -#line 242 "CMDgram.y" - { (yyval.var) = (yyvsp[0].var); } -#line 2350 "CMDgram.c" +#line 269 "CMDgram.y" + { (yyval.var) = (yyvsp[0].var); } +#line 2319 "CMDgram.c" break; case 31: /* var_list: param */ -#line 247 "CMDgram.y" +#line 274 "CMDgram.y" { (yyval.var) = (yyvsp[0].var); } -#line 2356 "CMDgram.c" +#line 2325 "CMDgram.c" break; case 32: /* var_list: var_list ',' param */ -#line 249 "CMDgram.y" +#line 276 "CMDgram.y" { (yyval.var) = (yyvsp[-2].var); ((StmtNode*)((yyvsp[-2].var)))->append((StmtNode*)(yyvsp[0].var) ); } -#line 2362 "CMDgram.c" +#line 2331 "CMDgram.c" break; case 33: /* param: VAR */ -#line 254 "CMDgram.y" - { - (yyval.var) = VarNode::allocParam((yyvsp[0].s).lineNumber, (yyvsp[0].s).value, NULL); - } -#line 2370 "CMDgram.c" +#line 293 "CMDgram.y" + { (yyval.var) = VarNode::allocParam((yyvsp[0].s).lineNumber, (yyvsp[0].s).value, NULL); } +#line 2337 "CMDgram.c" break; case 34: /* param: VAR '?' */ -#line 258 "CMDgram.y" - { - (yyval.var) = VarNode::allocParam((yyvsp[-1].s).lineNumber, (yyvsp[-1].s).value, NULL); - } -#line 2378 "CMDgram.c" +#line 295 "CMDgram.y" + { (yyval.var) = VarNode::allocParam((yyvsp[-1].s).lineNumber, (yyvsp[-1].s).value, NULL); } +#line 2343 "CMDgram.c" break; case 35: /* param: VAR '=' expr */ -#line 262 "CMDgram.y" - { - (yyval.var) = VarNode::allocParam((yyvsp[-2].s).lineNumber, (yyvsp[-2].s).value, (yyvsp[0].expr)); - } -#line 2386 "CMDgram.c" +#line 297 "CMDgram.y" + { (yyval.var) = VarNode::allocParam((yyvsp[-2].s).lineNumber, (yyvsp[-2].s).value, (yyvsp[0].expr)); } +#line 2349 "CMDgram.c" break; case 36: /* param: VAR '?' '=' expr */ -#line 266 "CMDgram.y" - { - (yyval.var) = VarNode::allocParam((yyvsp[-3].s).lineNumber, (yyvsp[-3].s).value, (yyvsp[0].expr)); - } -#line 2394 "CMDgram.c" +#line 299 "CMDgram.y" + { (yyval.var) = VarNode::allocParam((yyvsp[-3].s).lineNumber, (yyvsp[-3].s).value, (yyvsp[0].expr)); } +#line 2355 "CMDgram.c" break; case 37: /* datablock_decl: rwDATABLOCK class_name_expr '(' expr parent_block ')' '{' slot_assign_list_opt '}' ';' */ -#line 273 "CMDgram.y" +#line 304 "CMDgram.y" { (yyval.stmt) = ObjectDeclNode::alloc( (yyvsp[-9].i).lineNumber, (yyvsp[-8].expr), (yyvsp[-6].expr), NULL, (yyvsp[-5].s).value, (yyvsp[-2].slist), NULL, true, false, false); } -#line 2400 "CMDgram.c" +#line 2361 "CMDgram.c" break; case 38: /* object_decl: rwDECLARE class_name_expr '(' object_name parent_block object_args ')' '{' object_declare_block '}' */ -#line 278 "CMDgram.y" +#line 309 "CMDgram.y" { (yyval.od) = ObjectDeclNode::alloc( (yyvsp[-9].i).lineNumber, (yyvsp[-8].expr), (yyvsp[-6].expr), (yyvsp[-4].expr), (yyvsp[-5].s).value, (yyvsp[-1].odcl).slots, (yyvsp[-1].odcl).decls, false, false, false); } -#line 2406 "CMDgram.c" +#line 2367 "CMDgram.c" break; case 39: /* object_decl: rwDECLARE class_name_expr '(' object_name parent_block object_args ')' */ -#line 280 "CMDgram.y" +#line 311 "CMDgram.y" { (yyval.od) = ObjectDeclNode::alloc( (yyvsp[-6].i).lineNumber, (yyvsp[-5].expr), (yyvsp[-3].expr), (yyvsp[-1].expr), (yyvsp[-2].s).value, NULL, NULL, false, false, false); } -#line 2412 "CMDgram.c" +#line 2373 "CMDgram.c" break; case 40: /* object_decl: rwDECLARE class_name_expr '(' '[' object_name ']' parent_block object_args ')' '{' object_declare_block '}' */ -#line 282 "CMDgram.y" +#line 313 "CMDgram.y" { (yyval.od) = ObjectDeclNode::alloc( (yyvsp[-11].i).lineNumber, (yyvsp[-10].expr), (yyvsp[-7].expr), (yyvsp[-4].expr), (yyvsp[-5].s).value, (yyvsp[-1].odcl).slots, (yyvsp[-1].odcl).decls, false, true, false); } -#line 2418 "CMDgram.c" +#line 2379 "CMDgram.c" break; case 41: /* object_decl: rwDECLARE class_name_expr '(' '[' object_name ']' parent_block object_args ')' */ -#line 284 "CMDgram.y" +#line 315 "CMDgram.y" { (yyval.od) = ObjectDeclNode::alloc( (yyvsp[-8].i).lineNumber, (yyvsp[-7].expr), (yyvsp[-4].expr), (yyvsp[-1].expr), (yyvsp[-2].s).value, NULL, NULL, false, true, false); } -#line 2424 "CMDgram.c" +#line 2385 "CMDgram.c" break; case 42: /* object_decl: rwDECLARESINGLETON class_name_expr '(' object_name parent_block object_args ')' '{' object_declare_block '}' */ -#line 286 "CMDgram.y" +#line 317 "CMDgram.y" { (yyval.od) = ObjectDeclNode::alloc( (yyvsp[-9].i).lineNumber, (yyvsp[-8].expr), (yyvsp[-6].expr), (yyvsp[-4].expr), (yyvsp[-5].s).value, (yyvsp[-1].odcl).slots, (yyvsp[-1].odcl).decls, false, false, true); } -#line 2430 "CMDgram.c" +#line 2391 "CMDgram.c" break; case 43: /* object_decl: rwDECLARESINGLETON class_name_expr '(' object_name parent_block object_args ')' */ -#line 288 "CMDgram.y" +#line 319 "CMDgram.y" { (yyval.od) = ObjectDeclNode::alloc( (yyvsp[-6].i).lineNumber, (yyvsp[-5].expr), (yyvsp[-3].expr), (yyvsp[-1].expr), (yyvsp[-2].s).value, NULL, NULL, false, false, true); } -#line 2436 "CMDgram.c" +#line 2397 "CMDgram.c" break; case 44: /* parent_block: %empty */ -#line 293 "CMDgram.y" +#line 324 "CMDgram.y" { (yyval.s).value = NULL; } -#line 2442 "CMDgram.c" +#line 2403 "CMDgram.c" break; case 45: /* parent_block: ':' IDENT */ -#line 295 "CMDgram.y" +#line 326 "CMDgram.y" { (yyval.s) = (yyvsp[0].s); } -#line 2448 "CMDgram.c" +#line 2409 "CMDgram.c" break; case 46: /* object_name: %empty */ -#line 300 "CMDgram.y" +#line 331 "CMDgram.y" { (yyval.expr) = StrConstNode::alloc( CodeBlock::smCurrentParser->getCurrentLine(), "", false); } -#line 2454 "CMDgram.c" +#line 2415 "CMDgram.c" break; case 47: /* object_name: expr */ -#line 302 "CMDgram.y" +#line 333 "CMDgram.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 2460 "CMDgram.c" +#line 2421 "CMDgram.c" break; case 48: /* object_args: %empty */ -#line 307 "CMDgram.y" +#line 338 "CMDgram.y" { (yyval.expr) = NULL; } -#line 2466 "CMDgram.c" +#line 2427 "CMDgram.c" break; case 49: /* object_args: ',' expr_list */ -#line 309 "CMDgram.y" +#line 340 "CMDgram.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 2472 "CMDgram.c" +#line 2433 "CMDgram.c" break; case 50: /* object_declare_block: %empty */ -#line 314 "CMDgram.y" +#line 345 "CMDgram.y" { (yyval.odcl).slots = NULL; (yyval.odcl).decls = NULL; } -#line 2478 "CMDgram.c" +#line 2439 "CMDgram.c" break; case 51: /* object_declare_block: slot_assign_list */ -#line 316 "CMDgram.y" +#line 347 "CMDgram.y" { (yyval.odcl).slots = (yyvsp[0].slist); (yyval.odcl).decls = NULL; } -#line 2484 "CMDgram.c" +#line 2445 "CMDgram.c" break; case 52: /* object_declare_block: object_decl_list */ -#line 318 "CMDgram.y" +#line 349 "CMDgram.y" { (yyval.odcl).slots = NULL; (yyval.odcl).decls = (yyvsp[0].od); } -#line 2490 "CMDgram.c" +#line 2451 "CMDgram.c" break; case 53: /* object_declare_block: slot_assign_list object_decl_list */ -#line 320 "CMDgram.y" +#line 351 "CMDgram.y" { (yyval.odcl).slots = (yyvsp[-1].slist); (yyval.odcl).decls = (yyvsp[0].od); } -#line 2496 "CMDgram.c" +#line 2457 "CMDgram.c" break; case 54: /* object_decl_list: object_decl ';' */ -#line 325 "CMDgram.y" +#line 356 "CMDgram.y" { (yyval.od) = (yyvsp[-1].od); } -#line 2502 "CMDgram.c" +#line 2463 "CMDgram.c" break; case 55: /* object_decl_list: object_decl_list object_decl ';' */ -#line 327 "CMDgram.y" +#line 358 "CMDgram.y" { (yyvsp[-2].od)->append((yyvsp[-1].od)); (yyval.od) = (yyvsp[-2].od); } -#line 2508 "CMDgram.c" +#line 2469 "CMDgram.c" break; case 56: /* stmt_block: '{' statement_list '}' */ -#line 332 "CMDgram.y" +#line 363 "CMDgram.y" { (yyval.stmt) = (yyvsp[-1].stmt); } -#line 2514 "CMDgram.c" +#line 2475 "CMDgram.c" break; case 57: /* stmt_block: stmt */ -#line 334 "CMDgram.y" +#line 365 "CMDgram.y" { (yyval.stmt) = (yyvsp[0].stmt); } -#line 2520 "CMDgram.c" +#line 2481 "CMDgram.c" break; case 58: /* switch_stmt: rwSWITCH '(' expr ')' '{' case_block '}' */ -#line 339 "CMDgram.y" +#line 370 "CMDgram.y" { (yyval.stmt) = (yyvsp[-1].ifnode); (yyvsp[-1].ifnode)->propagateSwitchExpr((yyvsp[-4].expr), false); } -#line 2526 "CMDgram.c" +#line 2487 "CMDgram.c" break; case 59: /* switch_stmt: rwSWITCHSTR '(' expr ')' '{' case_block '}' */ -#line 341 "CMDgram.y" +#line 372 "CMDgram.y" { (yyval.stmt) = (yyvsp[-1].ifnode); (yyvsp[-1].ifnode)->propagateSwitchExpr((yyvsp[-4].expr), true); } -#line 2532 "CMDgram.c" +#line 2493 "CMDgram.c" break; case 60: /* case_block: rwCASE case_expr ':' statement_list */ -#line 346 "CMDgram.y" +#line 380 "CMDgram.y" { (yyval.ifnode) = IfStmtNode::alloc( (yyvsp[-3].i).lineNumber, (yyvsp[-2].expr), (yyvsp[0].stmt), NULL, false); } -#line 2538 "CMDgram.c" +#line 2499 "CMDgram.c" break; case 61: /* case_block: rwCASE case_expr ':' statement_list rwDEFAULT ':' statement_list */ -#line 348 "CMDgram.y" +#line 382 "CMDgram.y" { (yyval.ifnode) = IfStmtNode::alloc( (yyvsp[-6].i).lineNumber, (yyvsp[-5].expr), (yyvsp[-3].stmt), (yyvsp[0].stmt), false); } -#line 2544 "CMDgram.c" +#line 2505 "CMDgram.c" break; case 62: /* case_block: rwCASE case_expr ':' statement_list case_block */ -#line 350 "CMDgram.y" +#line 384 "CMDgram.y" { (yyval.ifnode) = IfStmtNode::alloc( (yyvsp[-4].i).lineNumber, (yyvsp[-3].expr), (yyvsp[-1].stmt), (yyvsp[0].ifnode), true); } -#line 2550 "CMDgram.c" +#line 2511 "CMDgram.c" break; case 63: /* case_expr: expr */ -#line 355 "CMDgram.y" - { (yyval.expr) = (yyvsp[0].expr);} -#line 2556 "CMDgram.c" +#line 389 "CMDgram.y" + { (yyval.expr) = (yyvsp[0].expr); } +#line 2517 "CMDgram.c" break; case 64: /* case_expr: case_expr rwCASEOR expr */ -#line 357 "CMDgram.y" - { ((yyvsp[-2].expr))->append((yyvsp[0].expr)); (yyval.expr)=(yyvsp[-2].expr); } -#line 2562 "CMDgram.c" +#line 391 "CMDgram.y" + { ((yyvsp[-2].expr))->append((yyvsp[0].expr)); (yyval.expr) = (yyvsp[-2].expr); } +#line 2523 "CMDgram.c" break; case 65: /* if_stmt: rwIF '(' expr ')' stmt_block */ -#line 362 "CMDgram.y" +#line 396 "CMDgram.y" { (yyval.stmt) = IfStmtNode::alloc((yyvsp[-4].i).lineNumber, (yyvsp[-2].expr), (yyvsp[0].stmt), NULL, false); } -#line 2568 "CMDgram.c" +#line 2529 "CMDgram.c" break; case 66: /* if_stmt: rwIF '(' expr ')' stmt_block rwELSE stmt_block */ -#line 364 "CMDgram.y" +#line 398 "CMDgram.y" { (yyval.stmt) = IfStmtNode::alloc((yyvsp[-6].i).lineNumber, (yyvsp[-4].expr), (yyvsp[-2].stmt), (yyvsp[0].stmt), false); } -#line 2574 "CMDgram.c" +#line 2535 "CMDgram.c" break; case 67: /* while_stmt: rwWHILE '(' expr ')' stmt_block */ -#line 369 "CMDgram.y" +#line 403 "CMDgram.y" { (yyval.stmt) = LoopStmtNode::alloc((yyvsp[-4].i).lineNumber, nil, (yyvsp[-2].expr), nil, (yyvsp[0].stmt), false); } -#line 2580 "CMDgram.c" +#line 2541 "CMDgram.c" break; case 68: /* while_stmt: rwDO stmt_block rwWHILE '(' expr ')' */ -#line 371 "CMDgram.y" +#line 405 "CMDgram.y" { (yyval.stmt) = LoopStmtNode::alloc((yyvsp[-3].i).lineNumber, nil, (yyvsp[-1].expr), nil, (yyvsp[-4].stmt), true); } -#line 2586 "CMDgram.c" +#line 2547 "CMDgram.c" break; case 69: /* for_stmt: rwFOR '(' expr ';' expr ';' expr ')' stmt_block */ -#line 376 "CMDgram.y" +#line 410 "CMDgram.y" { (yyval.stmt) = LoopStmtNode::alloc((yyvsp[-8].i).lineNumber, (yyvsp[-6].expr), (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].stmt), false); } -#line 2592 "CMDgram.c" +#line 2553 "CMDgram.c" break; case 70: /* for_stmt: rwFOR '(' expr ';' expr ';' ')' stmt_block */ -#line 378 "CMDgram.y" +#line 412 "CMDgram.y" { (yyval.stmt) = LoopStmtNode::alloc((yyvsp[-7].i).lineNumber, (yyvsp[-5].expr), (yyvsp[-3].expr), NULL, (yyvsp[0].stmt), false); } -#line 2598 "CMDgram.c" +#line 2559 "CMDgram.c" break; case 71: /* for_stmt: rwFOR '(' expr ';' ';' expr ')' stmt_block */ -#line 380 "CMDgram.y" +#line 414 "CMDgram.y" { (yyval.stmt) = LoopStmtNode::alloc((yyvsp[-7].i).lineNumber, (yyvsp[-5].expr), NULL, (yyvsp[-2].expr), (yyvsp[0].stmt), false); } -#line 2604 "CMDgram.c" +#line 2565 "CMDgram.c" break; case 72: /* for_stmt: rwFOR '(' expr ';' ';' ')' stmt_block */ -#line 382 "CMDgram.y" +#line 416 "CMDgram.y" { (yyval.stmt) = LoopStmtNode::alloc((yyvsp[-6].i).lineNumber, (yyvsp[-4].expr), NULL, NULL, (yyvsp[0].stmt), false); } -#line 2610 "CMDgram.c" +#line 2571 "CMDgram.c" break; case 73: /* for_stmt: rwFOR '(' ';' expr ';' expr ')' stmt_block */ -#line 384 "CMDgram.y" +#line 418 "CMDgram.y" { (yyval.stmt) = LoopStmtNode::alloc((yyvsp[-7].i).lineNumber, NULL, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].stmt), false); } -#line 2616 "CMDgram.c" +#line 2577 "CMDgram.c" break; case 74: /* for_stmt: rwFOR '(' ';' expr ';' ')' stmt_block */ -#line 386 "CMDgram.y" +#line 420 "CMDgram.y" { (yyval.stmt) = LoopStmtNode::alloc((yyvsp[-6].i).lineNumber, NULL, (yyvsp[-3].expr), NULL, (yyvsp[0].stmt), false); } -#line 2622 "CMDgram.c" +#line 2583 "CMDgram.c" break; case 75: /* for_stmt: rwFOR '(' ';' ';' expr ')' stmt_block */ -#line 388 "CMDgram.y" +#line 422 "CMDgram.y" { (yyval.stmt) = LoopStmtNode::alloc((yyvsp[-6].i).lineNumber, NULL, NULL, (yyvsp[-2].expr), (yyvsp[0].stmt), false); } -#line 2628 "CMDgram.c" +#line 2589 "CMDgram.c" break; case 76: /* for_stmt: rwFOR '(' ';' ';' ')' stmt_block */ -#line 390 "CMDgram.y" +#line 424 "CMDgram.y" { (yyval.stmt) = LoopStmtNode::alloc((yyvsp[-5].i).lineNumber, NULL, NULL, NULL, (yyvsp[0].stmt), false); } -#line 2634 "CMDgram.c" +#line 2595 "CMDgram.c" break; case 77: /* foreach_stmt: rwFOREACH '(' VAR rwIN expr ')' stmt_block */ -#line 395 "CMDgram.y" +#line 429 "CMDgram.y" { (yyval.stmt) = IterStmtNode::alloc( (yyvsp[-6].i).lineNumber, (yyvsp[-4].s).value, (yyvsp[-2].expr), (yyvsp[0].stmt), false ); } -#line 2640 "CMDgram.c" +#line 2601 "CMDgram.c" break; case 78: /* foreach_stmt: rwFOREACHSTR '(' VAR rwIN expr ')' stmt_block */ -#line 397 "CMDgram.y" +#line 431 "CMDgram.y" { (yyval.stmt) = IterStmtNode::alloc( (yyvsp[-6].i).lineNumber, (yyvsp[-4].s).value, (yyvsp[-2].expr), (yyvsp[0].stmt), true ); } -#line 2646 "CMDgram.c" +#line 2607 "CMDgram.c" break; case 79: /* expression_stmt: stmt_expr */ -#line 402 "CMDgram.y" +#line 436 "CMDgram.y" { (yyval.stmt) = (yyvsp[0].expr); } -#line 2652 "CMDgram.c" +#line 2613 "CMDgram.c" break; case 80: /* expr: stmt_expr */ -#line 407 "CMDgram.y" +#line 441 "CMDgram.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 2658 "CMDgram.c" +#line 2619 "CMDgram.c" break; case 81: /* expr: '(' expr ')' */ -#line 409 "CMDgram.y" +#line 443 "CMDgram.y" { (yyval.expr) = (yyvsp[-1].expr); } -#line 2664 "CMDgram.c" +#line 2625 "CMDgram.c" break; case 82: /* expr: expr '^' expr */ -#line 411 "CMDgram.y" +#line 445 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2670 "CMDgram.c" +#line 2631 "CMDgram.c" break; case 83: /* expr: expr '%' expr */ -#line 413 "CMDgram.y" +#line 447 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2676 "CMDgram.c" +#line 2637 "CMDgram.c" break; case 84: /* expr: expr '&' expr */ -#line 415 "CMDgram.y" +#line 449 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2682 "CMDgram.c" +#line 2643 "CMDgram.c" break; case 85: /* expr: expr '|' expr */ -#line 417 "CMDgram.y" +#line 451 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2688 "CMDgram.c" +#line 2649 "CMDgram.c" break; case 86: /* expr: expr '+' expr */ -#line 419 "CMDgram.y" +#line 453 "CMDgram.y" { (yyval.expr) = FloatBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2694 "CMDgram.c" +#line 2655 "CMDgram.c" break; case 87: /* expr: expr '-' expr */ -#line 421 "CMDgram.y" +#line 455 "CMDgram.y" { (yyval.expr) = FloatBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2700 "CMDgram.c" +#line 2661 "CMDgram.c" break; case 88: /* expr: expr '*' expr */ -#line 423 "CMDgram.y" +#line 457 "CMDgram.y" { (yyval.expr) = FloatBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2706 "CMDgram.c" +#line 2667 "CMDgram.c" break; case 89: /* expr: expr '/' expr */ -#line 425 "CMDgram.y" +#line 459 "CMDgram.y" { (yyval.expr) = FloatBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2712 "CMDgram.c" +#line 2673 "CMDgram.c" break; case 90: /* expr: '-' expr */ -#line 427 "CMDgram.y" +#line 461 "CMDgram.y" { (yyval.expr) = FloatUnaryExprNode::alloc( (yyvsp[-1].i).lineNumber, (yyvsp[-1].i).value, (yyvsp[0].expr)); } -#line 2718 "CMDgram.c" +#line 2679 "CMDgram.c" break; case 91: /* expr: '*' expr */ -#line 429 "CMDgram.y" +#line 463 "CMDgram.y" { (yyval.expr) = TTagDerefNode::alloc( (yyvsp[-1].i).lineNumber, (yyvsp[0].expr) ); } -#line 2724 "CMDgram.c" +#line 2685 "CMDgram.c" break; case 92: /* expr: TTAG */ -#line 431 "CMDgram.y" +#line 465 "CMDgram.y" { (yyval.expr) = TTagExprNode::alloc( (yyvsp[0].s).lineNumber, (yyvsp[0].s).value ); } -#line 2730 "CMDgram.c" +#line 2691 "CMDgram.c" break; case 93: /* expr: expr '?' expr ':' expr */ -#line 433 "CMDgram.y" +#line 467 "CMDgram.y" { (yyval.expr) = ConditionalExprNode::alloc( (yyvsp[-4].expr)->dbgLineNumber, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2736 "CMDgram.c" +#line 2697 "CMDgram.c" break; case 94: /* expr: expr '<' expr */ -#line 435 "CMDgram.y" +#line 469 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2742 "CMDgram.c" +#line 2703 "CMDgram.c" break; case 95: /* expr: expr '>' expr */ -#line 437 "CMDgram.y" +#line 471 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2748 "CMDgram.c" +#line 2709 "CMDgram.c" break; case 96: /* expr: expr opGE expr */ -#line 439 "CMDgram.y" +#line 473 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2754 "CMDgram.c" +#line 2715 "CMDgram.c" break; case 97: /* expr: expr opLE expr */ -#line 441 "CMDgram.y" +#line 475 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2760 "CMDgram.c" +#line 2721 "CMDgram.c" break; case 98: /* expr: expr opEQ expr */ -#line 443 "CMDgram.y" +#line 477 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2766 "CMDgram.c" +#line 2727 "CMDgram.c" break; case 99: /* expr: expr opNE expr */ -#line 445 "CMDgram.y" +#line 479 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2772 "CMDgram.c" +#line 2733 "CMDgram.c" break; case 100: /* expr: expr opOR expr */ -#line 447 "CMDgram.y" +#line 481 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2778 "CMDgram.c" +#line 2739 "CMDgram.c" break; case 101: /* expr: expr opSHL expr */ -#line 449 "CMDgram.y" +#line 483 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2784 "CMDgram.c" +#line 2745 "CMDgram.c" break; case 102: /* expr: expr opSHR expr */ -#line 451 "CMDgram.y" +#line 485 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2790 "CMDgram.c" +#line 2751 "CMDgram.c" break; case 103: /* expr: expr opAND expr */ -#line 453 "CMDgram.y" +#line 487 "CMDgram.y" { (yyval.expr) = IntBinaryExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-1].i).value, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2796 "CMDgram.c" +#line 2757 "CMDgram.c" break; case 104: /* expr: expr opSTREQ expr */ -#line 455 "CMDgram.y" +#line 489 "CMDgram.y" { (yyval.expr) = StreqExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-2].expr), (yyvsp[0].expr), true); } -#line 2802 "CMDgram.c" +#line 2763 "CMDgram.c" break; case 105: /* expr: expr opSTRNE expr */ -#line 457 "CMDgram.y" +#line 491 "CMDgram.y" { (yyval.expr) = StreqExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-2].expr), (yyvsp[0].expr), false); } -#line 2808 "CMDgram.c" +#line 2769 "CMDgram.c" break; case 106: /* expr: expr '@' expr */ -#line 459 "CMDgram.y" +#line 499 "CMDgram.y" { (yyval.expr) = StrcatExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-2].expr), (yyvsp[0].expr), (yyvsp[-1].i).value); } -#line 2814 "CMDgram.c" +#line 2775 "CMDgram.c" break; case 107: /* expr: '!' expr */ -#line 461 "CMDgram.y" +#line 501 "CMDgram.y" { (yyval.expr) = IntUnaryExprNode::alloc((yyvsp[-1].i).lineNumber, (yyvsp[-1].i).value, (yyvsp[0].expr)); } -#line 2820 "CMDgram.c" +#line 2781 "CMDgram.c" break; case 108: /* expr: '~' expr */ -#line 463 "CMDgram.y" +#line 503 "CMDgram.y" { (yyval.expr) = IntUnaryExprNode::alloc((yyvsp[-1].i).lineNumber, (yyvsp[-1].i).value, (yyvsp[0].expr)); } -#line 2826 "CMDgram.c" +#line 2787 "CMDgram.c" break; case 109: /* expr: TAGATOM */ -#line 465 "CMDgram.y" +#line 505 "CMDgram.y" { (yyval.expr) = StrConstNode::alloc( (yyvsp[0].str).lineNumber, (yyvsp[0].str).value, true); } -#line 2832 "CMDgram.c" +#line 2793 "CMDgram.c" break; case 110: /* expr: FLTCONST */ -#line 467 "CMDgram.y" +#line 507 "CMDgram.y" { (yyval.expr) = FloatNode::alloc( (yyvsp[0].f).lineNumber, (yyvsp[0].f).value ); } -#line 2838 "CMDgram.c" +#line 2799 "CMDgram.c" break; case 111: /* expr: INTCONST */ -#line 469 "CMDgram.y" +#line 509 "CMDgram.y" { (yyval.expr) = IntNode::alloc( (yyvsp[0].i).lineNumber, (yyvsp[0].i).value ); } -#line 2844 "CMDgram.c" +#line 2805 "CMDgram.c" break; case 112: /* expr: rwBREAK */ -#line 471 "CMDgram.y" +#line 511 "CMDgram.y" { (yyval.expr) = ConstantNode::alloc( (yyvsp[0].i).lineNumber, StringTable->insert("break")); } -#line 2850 "CMDgram.c" +#line 2811 "CMDgram.c" break; case 113: /* expr: slot_acc */ -#line 473 "CMDgram.y" +#line 513 "CMDgram.y" { (yyval.expr) = SlotAccessNode::alloc( (yyvsp[0].slot).lineNumber, (yyvsp[0].slot).object, (yyvsp[0].slot).array, (yyvsp[0].slot).slotName ); } -#line 2856 "CMDgram.c" +#line 2817 "CMDgram.c" break; case 114: /* expr: intslot_acc */ -#line 475 "CMDgram.y" +#line 515 "CMDgram.y" { (yyval.expr) = InternalSlotAccessNode::alloc( (yyvsp[0].intslot).lineNumber, (yyvsp[0].intslot).object, (yyvsp[0].intslot).slotExpr, (yyvsp[0].intslot).recurse); } -#line 2862 "CMDgram.c" +#line 2823 "CMDgram.c" break; case 115: /* expr: IDENT */ -#line 477 "CMDgram.y" +#line 517 "CMDgram.y" { (yyval.expr) = ConstantNode::alloc( (yyvsp[0].s).lineNumber, (yyvsp[0].s).value ); } -#line 2868 "CMDgram.c" +#line 2829 "CMDgram.c" break; case 116: /* expr: STRATOM */ -#line 479 "CMDgram.y" +#line 519 "CMDgram.y" { (yyval.expr) = StrConstNode::alloc( (yyvsp[0].str).lineNumber, (yyvsp[0].str).value, false); } -#line 2874 "CMDgram.c" +#line 2835 "CMDgram.c" break; case 117: /* expr: VAR */ -#line 481 "CMDgram.y" +#line 521 "CMDgram.y" { (yyval.expr) = (ExprNode*)VarNode::alloc( (yyvsp[0].s).lineNumber, (yyvsp[0].s).value, NULL); } -#line 2880 "CMDgram.c" +#line 2841 "CMDgram.c" break; case 118: /* expr: VAR '[' aidx_expr ']' */ -#line 483 "CMDgram.y" +#line 523 "CMDgram.y" { (yyval.expr) = (ExprNode*)VarNode::alloc( (yyvsp[-3].s).lineNumber, (yyvsp[-3].s).value, (yyvsp[-1].expr) ); } -#line 2886 "CMDgram.c" +#line 2847 "CMDgram.c" break; case 119: /* slot_acc: expr '.' IDENT */ -#line 505 "CMDgram.y" +#line 528 "CMDgram.y" { (yyval.slot).lineNumber = (yyvsp[-2].expr)->dbgLineNumber; (yyval.slot).object = (yyvsp[-2].expr); (yyval.slot).slotName = (yyvsp[0].s).value; (yyval.slot).array = NULL; } -#line 2892 "CMDgram.c" +#line 2853 "CMDgram.c" break; case 120: /* slot_acc: expr '.' IDENT '[' aidx_expr ']' */ -#line 507 "CMDgram.y" +#line 530 "CMDgram.y" { (yyval.slot).lineNumber = (yyvsp[-5].expr)->dbgLineNumber; (yyval.slot).object = (yyvsp[-5].expr); (yyval.slot).slotName = (yyvsp[-3].s).value; (yyval.slot).array = (yyvsp[-1].expr); } -#line 2898 "CMDgram.c" +#line 2859 "CMDgram.c" break; case 121: /* intslot_acc: expr opINTNAME class_name_expr */ -#line 512 "CMDgram.y" - { (yyval.intslot).lineNumber = (yyvsp[-2].expr)->dbgLineNumber; (yyval.intslot).object = (yyvsp[-2].expr); (yyval.intslot).slotExpr = (yyvsp[0].expr); (yyval.intslot).recurse = false; } -#line 2904 "CMDgram.c" +#line 535 "CMDgram.y" + { (yyval.intslot).lineNumber = (yyvsp[-2].expr)->dbgLineNumber; (yyval.intslot).object = (yyvsp[-2].expr); (yyval.intslot).slotExpr = (yyvsp[0].expr); (yyval.intslot).recurse = false; } +#line 2865 "CMDgram.c" break; case 122: /* intslot_acc: expr opINTNAMER class_name_expr */ -#line 514 "CMDgram.y" - { (yyval.intslot).lineNumber = (yyvsp[-2].expr)->dbgLineNumber; (yyval.intslot).object = (yyvsp[-2].expr); (yyval.intslot).slotExpr = (yyvsp[0].expr); (yyval.intslot).recurse = true; } -#line 2910 "CMDgram.c" +#line 537 "CMDgram.y" + { (yyval.intslot).lineNumber = (yyvsp[-2].expr)->dbgLineNumber; (yyval.intslot).object = (yyvsp[-2].expr); (yyval.intslot).slotExpr = (yyvsp[0].expr); (yyval.intslot).recurse = true; } +#line 2871 "CMDgram.c" break; case 123: /* class_name_expr: IDENT */ -#line 519 "CMDgram.y" +#line 542 "CMDgram.y" { (yyval.expr) = ConstantNode::alloc( (yyvsp[0].s).lineNumber, (yyvsp[0].s).value ); } -#line 2916 "CMDgram.c" +#line 2877 "CMDgram.c" break; case 124: /* class_name_expr: '(' expr ')' */ -#line 521 "CMDgram.y" +#line 544 "CMDgram.y" { (yyval.expr) = (yyvsp[-1].expr); } -#line 2922 "CMDgram.c" +#line 2883 "CMDgram.c" break; case 125: /* assign_op_struct: opPLUSPLUS */ -#line 526 "CMDgram.y" +#line 549 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[0].i).lineNumber; (yyval.asn).token = opPLUSPLUS; (yyval.asn).expr = FloatNode::alloc( (yyvsp[0].i).lineNumber, 1 ); } -#line 2928 "CMDgram.c" +#line 2889 "CMDgram.c" break; case 126: /* assign_op_struct: opMINUSMINUS */ -#line 528 "CMDgram.y" +#line 551 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[0].i).lineNumber; (yyval.asn).token = opMINUSMINUS; (yyval.asn).expr = FloatNode::alloc( (yyvsp[0].i).lineNumber, 1 ); } -#line 2934 "CMDgram.c" +#line 2895 "CMDgram.c" break; case 127: /* assign_op_struct: opPLASN expr */ -#line 530 "CMDgram.y" +#line 553 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[-1].i).lineNumber; (yyval.asn).token = '+'; (yyval.asn).expr = (yyvsp[0].expr); } -#line 2940 "CMDgram.c" +#line 2901 "CMDgram.c" break; case 128: /* assign_op_struct: opMIASN expr */ -#line 532 "CMDgram.y" +#line 555 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[-1].i).lineNumber; (yyval.asn).token = '-'; (yyval.asn).expr = (yyvsp[0].expr); } -#line 2946 "CMDgram.c" +#line 2907 "CMDgram.c" break; case 129: /* assign_op_struct: opMLASN expr */ -#line 534 "CMDgram.y" +#line 557 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[-1].i).lineNumber; (yyval.asn).token = '*'; (yyval.asn).expr = (yyvsp[0].expr); } -#line 2952 "CMDgram.c" +#line 2913 "CMDgram.c" break; case 130: /* assign_op_struct: opDVASN expr */ -#line 536 "CMDgram.y" +#line 559 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[-1].i).lineNumber; (yyval.asn).token = '/'; (yyval.asn).expr = (yyvsp[0].expr); } -#line 2958 "CMDgram.c" +#line 2919 "CMDgram.c" break; case 131: /* assign_op_struct: opMODASN expr */ -#line 538 "CMDgram.y" +#line 561 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[-1].i).lineNumber; (yyval.asn).token = '%'; (yyval.asn).expr = (yyvsp[0].expr); } -#line 2964 "CMDgram.c" +#line 2925 "CMDgram.c" break; case 132: /* assign_op_struct: opANDASN expr */ -#line 540 "CMDgram.y" +#line 563 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[-1].i).lineNumber; (yyval.asn).token = '&'; (yyval.asn).expr = (yyvsp[0].expr); } -#line 2970 "CMDgram.c" +#line 2931 "CMDgram.c" break; case 133: /* assign_op_struct: opXORASN expr */ -#line 542 "CMDgram.y" +#line 565 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[-1].i).lineNumber; (yyval.asn).token = '^'; (yyval.asn).expr = (yyvsp[0].expr); } -#line 2976 "CMDgram.c" +#line 2937 "CMDgram.c" break; case 134: /* assign_op_struct: opORASN expr */ -#line 544 "CMDgram.y" +#line 567 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[-1].i).lineNumber; (yyval.asn).token = '|'; (yyval.asn).expr = (yyvsp[0].expr); } -#line 2982 "CMDgram.c" +#line 2943 "CMDgram.c" break; case 135: /* assign_op_struct: opSLASN expr */ -#line 546 "CMDgram.y" +#line 569 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[-1].i).lineNumber; (yyval.asn).token = opSHL; (yyval.asn).expr = (yyvsp[0].expr); } -#line 2988 "CMDgram.c" +#line 2949 "CMDgram.c" break; case 136: /* assign_op_struct: opSRASN expr */ -#line 548 "CMDgram.y" +#line 571 "CMDgram.y" { (yyval.asn).lineNumber = (yyvsp[-1].i).lineNumber; (yyval.asn).token = opSHR; (yyval.asn).expr = (yyvsp[0].expr); } -#line 2994 "CMDgram.c" +#line 2955 "CMDgram.c" break; case 137: /* stmt_expr: funcall_expr */ -#line 553 "CMDgram.y" +#line 576 "CMDgram.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 3000 "CMDgram.c" +#line 2961 "CMDgram.c" break; case 138: /* stmt_expr: assert_expr */ -#line 555 "CMDgram.y" +#line 578 "CMDgram.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 3006 "CMDgram.c" +#line 2967 "CMDgram.c" break; case 139: /* stmt_expr: object_decl */ -#line 557 "CMDgram.y" +#line 580 "CMDgram.y" { (yyval.expr) = (yyvsp[0].od); } -#line 3012 "CMDgram.c" +#line 2973 "CMDgram.c" break; case 140: /* stmt_expr: VAR '=' expr */ -#line 559 "CMDgram.y" +#line 582 "CMDgram.y" { (yyval.expr) = AssignExprNode::alloc( (yyvsp[-2].s).lineNumber, (yyvsp[-2].s).value, NULL, (yyvsp[0].expr)); } -#line 3018 "CMDgram.c" +#line 2979 "CMDgram.c" break; case 141: /* stmt_expr: VAR '[' aidx_expr ']' '=' expr */ -#line 561 "CMDgram.y" +#line 584 "CMDgram.y" { (yyval.expr) = AssignExprNode::alloc( (yyvsp[-5].s).lineNumber, (yyvsp[-5].s).value, (yyvsp[-3].expr), (yyvsp[0].expr)); } -#line 3024 "CMDgram.c" +#line 2985 "CMDgram.c" break; case 142: /* stmt_expr: VAR assign_op_struct */ -#line 563 "CMDgram.y" +#line 586 "CMDgram.y" { (yyval.expr) = AssignOpExprNode::alloc( (yyvsp[-1].s).lineNumber, (yyvsp[-1].s).value, NULL, (yyvsp[0].asn).expr, (yyvsp[0].asn).token); } -#line 3030 "CMDgram.c" +#line 2991 "CMDgram.c" break; case 143: /* stmt_expr: VAR '[' aidx_expr ']' assign_op_struct */ -#line 565 "CMDgram.y" +#line 588 "CMDgram.y" { (yyval.expr) = AssignOpExprNode::alloc( (yyvsp[-4].s).lineNumber, (yyvsp[-4].s).value, (yyvsp[-2].expr), (yyvsp[0].asn).expr, (yyvsp[0].asn).token); } -#line 3036 "CMDgram.c" +#line 2997 "CMDgram.c" break; case 144: /* stmt_expr: slot_acc assign_op_struct */ -#line 567 "CMDgram.y" +#line 590 "CMDgram.y" { (yyval.expr) = SlotAssignOpNode::alloc( (yyvsp[-1].slot).lineNumber, (yyvsp[-1].slot).object, (yyvsp[-1].slot).slotName, (yyvsp[-1].slot).array, (yyvsp[0].asn).token, (yyvsp[0].asn).expr); } -#line 3042 "CMDgram.c" +#line 3003 "CMDgram.c" break; case 145: /* stmt_expr: slot_acc '=' expr */ -#line 569 "CMDgram.y" +#line 592 "CMDgram.y" { (yyval.expr) = SlotAssignNode::alloc( (yyvsp[-2].slot).lineNumber, (yyvsp[-2].slot).object, (yyvsp[-2].slot).array, (yyvsp[-2].slot).slotName, (yyvsp[0].expr)); } -#line 3048 "CMDgram.c" +#line 3009 "CMDgram.c" break; case 146: /* stmt_expr: slot_acc '=' '{' expr_list '}' */ -#line 571 "CMDgram.y" +#line 594 "CMDgram.y" { (yyval.expr) = SlotAssignNode::alloc( (yyvsp[-4].slot).lineNumber, (yyvsp[-4].slot).object, (yyvsp[-4].slot).array, (yyvsp[-4].slot).slotName, (yyvsp[-1].expr)); } -#line 3054 "CMDgram.c" +#line 3015 "CMDgram.c" break; case 147: /* funcall_expr: IDENT '(' expr_list_decl ')' */ -#line 576 "CMDgram.y" - { (yyval.expr) = FuncCallExprNode::alloc( (yyvsp[-3].s).lineNumber, (yyvsp[-3].s).value, NULL, (yyvsp[-1].expr), false); } -#line 3060 "CMDgram.c" +#line 600 "CMDgram.y" + { (yyval.expr) = FuncCallExprNode::alloc( (yyvsp[-3].s).lineNumber, (yyvsp[-3].s).value, NULL, (yyvsp[-1].expr), false); } +#line 3021 "CMDgram.c" break; case 148: /* funcall_expr: IDENT opCOLONCOLON IDENT '(' expr_list_decl ')' */ -#line 578 "CMDgram.y" - { (yyval.expr) = FuncCallExprNode::alloc( (yyvsp[-5].s).lineNumber, (yyvsp[-3].s).value, (yyvsp[-5].s).value, (yyvsp[-1].expr), false); } -#line 3066 "CMDgram.c" +#line 603 "CMDgram.y" + { (yyval.expr) = FuncCallExprNode::alloc( (yyvsp[-5].s).lineNumber, (yyvsp[-3].s).value, (yyvsp[-5].s).value, (yyvsp[-1].expr), false); } +#line 3027 "CMDgram.c" break; case 149: /* funcall_expr: expr '.' IDENT '(' expr_list_decl ')' */ -#line 580 "CMDgram.y" +#line 608 "CMDgram.y" { (yyvsp[-5].expr)->append((yyvsp[-1].expr)); (yyval.expr) = FuncCallExprNode::alloc( (yyvsp[-5].expr)->dbgLineNumber, (yyvsp[-3].s).value, NULL, (yyvsp[-5].expr), true); } -#line 3072 "CMDgram.c" +#line 3033 "CMDgram.c" break; case 150: /* assert_expr: rwASSERT '(' expr ')' */ -#line 590 "CMDgram.y" +#line 613 "CMDgram.y" { (yyval.expr) = AssertCallExprNode::alloc( (yyvsp[-3].i).lineNumber, (yyvsp[-1].expr), NULL ); } -#line 3078 "CMDgram.c" +#line 3039 "CMDgram.c" break; case 151: /* assert_expr: rwASSERT '(' expr ',' STRATOM ')' */ -#line 592 "CMDgram.y" +#line 615 "CMDgram.y" { (yyval.expr) = AssertCallExprNode::alloc( (yyvsp[-5].i).lineNumber, (yyvsp[-3].expr), (yyvsp[-1].str).value ); } -#line 3084 "CMDgram.c" +#line 3045 "CMDgram.c" break; case 152: /* expr_list_decl: %empty */ -#line 597 "CMDgram.y" +#line 620 "CMDgram.y" { (yyval.expr) = NULL; } -#line 3090 "CMDgram.c" +#line 3051 "CMDgram.c" break; case 153: /* expr_list_decl: expr_list */ -#line 599 "CMDgram.y" +#line 622 "CMDgram.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 3096 "CMDgram.c" +#line 3057 "CMDgram.c" break; case 154: /* expr_list: expr */ -#line 604 "CMDgram.y" +#line 627 "CMDgram.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 3102 "CMDgram.c" +#line 3063 "CMDgram.c" break; case 155: /* expr_list: expr_list ',' expr */ -#line 606 "CMDgram.y" +#line 629 "CMDgram.y" { ((yyvsp[-2].expr))->append((yyvsp[0].expr)); (yyval.expr) = (yyvsp[-2].expr); } -#line 3108 "CMDgram.c" +#line 3069 "CMDgram.c" break; case 156: /* slot_assign_list_opt: %empty */ -#line 611 "CMDgram.y" +#line 634 "CMDgram.y" { (yyval.slist) = NULL; } -#line 3114 "CMDgram.c" +#line 3075 "CMDgram.c" break; case 157: /* slot_assign_list_opt: slot_assign_list */ -#line 613 "CMDgram.y" +#line 636 "CMDgram.y" { (yyval.slist) = (yyvsp[0].slist); } -#line 3120 "CMDgram.c" +#line 3081 "CMDgram.c" break; case 158: /* slot_assign_list: slot_assign */ -#line 618 "CMDgram.y" +#line 641 "CMDgram.y" { (yyval.slist) = (yyvsp[0].slist); } -#line 3126 "CMDgram.c" +#line 3087 "CMDgram.c" break; case 159: /* slot_assign_list: slot_assign_list slot_assign */ -#line 620 "CMDgram.y" +#line 643 "CMDgram.y" { (yyvsp[-1].slist)->append((yyvsp[0].slist)); (yyval.slist) = (yyvsp[-1].slist); } -#line 3132 "CMDgram.c" +#line 3093 "CMDgram.c" break; case 160: /* slot_assign: IDENT '=' expr ';' */ -#line 625 "CMDgram.y" +#line 648 "CMDgram.y" { (yyval.slist) = SlotAssignNode::alloc( (yyvsp[-3].s).lineNumber, NULL, NULL, (yyvsp[-3].s).value, (yyvsp[-1].expr)); } -#line 3138 "CMDgram.c" +#line 3099 "CMDgram.c" break; case 161: /* slot_assign: TYPEIDENT IDENT '=' expr ';' */ -#line 627 "CMDgram.y" +#line 650 "CMDgram.y" { (yyval.slist) = SlotAssignNode::alloc( (yyvsp[-4].i).lineNumber, NULL, NULL, (yyvsp[-3].s).value, (yyvsp[-1].expr), (yyvsp[-4].i).value); } -#line 3144 "CMDgram.c" +#line 3105 "CMDgram.c" break; case 162: /* slot_assign: rwDATABLOCK '=' expr ';' */ -#line 629 "CMDgram.y" +#line 652 "CMDgram.y" { (yyval.slist) = SlotAssignNode::alloc( (yyvsp[-3].i).lineNumber, NULL, NULL, StringTable->insert("datablock"), (yyvsp[-1].expr)); } -#line 3150 "CMDgram.c" +#line 3111 "CMDgram.c" break; case 163: /* slot_assign: IDENT '[' aidx_expr ']' '=' expr ';' */ -#line 631 "CMDgram.y" +#line 654 "CMDgram.y" { (yyval.slist) = SlotAssignNode::alloc( (yyvsp[-6].s).lineNumber, NULL, (yyvsp[-4].expr), (yyvsp[-6].s).value, (yyvsp[-1].expr)); } -#line 3156 "CMDgram.c" +#line 3117 "CMDgram.c" break; case 164: /* slot_assign: TYPEIDENT IDENT '[' aidx_expr ']' '=' expr ';' */ -#line 633 "CMDgram.y" +#line 656 "CMDgram.y" { (yyval.slist) = SlotAssignNode::alloc( (yyvsp[-7].i).lineNumber, NULL, (yyvsp[-4].expr), (yyvsp[-6].s).value, (yyvsp[-1].expr), (yyvsp[-7].i).value); } -#line 3162 "CMDgram.c" +#line 3123 "CMDgram.c" break; case 165: /* aidx_expr: expr */ -#line 638 "CMDgram.y" +#line 663 "CMDgram.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 3168 "CMDgram.c" +#line 3129 "CMDgram.c" break; case 166: /* aidx_expr: aidx_expr ',' expr */ -#line 640 "CMDgram.y" +#line 665 "CMDgram.y" { (yyval.expr) = CommaCatExprNode::alloc( (yyvsp[-2].expr)->dbgLineNumber, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 3174 "CMDgram.c" +#line 3135 "CMDgram.c" break; -#line 3178 "CMDgram.c" +#line 3139 "CMDgram.c" default: break; } @@ -3377,45 +3338,50 @@ yyreturnlab: return yyresult; } -#line 642 "CMDgram.y" +#line 668 "CMDgram.y" int -yyreport_syntax_error (const yypcontext_t *ctx) +yyreport_syntax_error(const yypcontext_t *ctx) { int ret = 0; String output; - const YYLTYPE *loc = yypcontext_location (ctx); + const YYLTYPE *loc = yypcontext_location(ctx); output += "syntax error: "; yysymbol_kind_t nxt = yypcontext_token(ctx); if (nxt != YYSYMBOL_YYEMPTY) - output += String::ToString("unexpected: %s at column: %d", yysymbol_name(nxt), loc->first_column); + output += String::ToString("unexpected: %s at column: %d", + yysymbol_name(nxt), loc->first_column); enum { TOKENMAX = 10 }; yysymbol_kind_t expected[TOKENMAX]; int exp = yypcontext_expected_tokens(ctx, expected, TOKENMAX); if (exp < 0) + { ret = exp; + } else { for (int i = 0; i < exp; ++i) - output += String::ToString("%s %s", i == 0 ? ": expected" : "or", yysymbol_name(expected[i])); + output += String::ToString("%s %s", + i == 0 ? ": expected" : "or", + yysymbol_name(expected[i])); } - if (lines.size() > 0) + if (lines.size() > 0) { output += "\n"; for (int i = 0; i < lines.size(); i++) { int line = lines.size() - i; - output += String::ToString("%5d | ", loc->first_line - (line-1)) + lines[i] + "\n"; + output += String::ToString("%5d | ", loc->first_line - (line - 1)) + + lines[i] + "\n"; } output += String::ToString("%5s | %*s", "", loc->first_column, "^"); } yyerror("%s", output.c_str()); - return ret; } diff --git a/Engine/source/console/torquescript/compiledEval.cpp b/Engine/source/console/torquescript/compiledEval.cpp index 9f34b99b7..f89f906bc 100644 --- a/Engine/source/console/torquescript/compiledEval.cpp +++ b/Engine/source/console/torquescript/compiledEval.cpp @@ -562,6 +562,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi U32 iterDepth = 0; ConsoleValue returnValue; + const bool isCodelet = (!argv && setFrame == -2); incRefCount(); F64* curFloatTable; @@ -615,24 +616,102 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi Script::gEvalState.moveConsoleValue(reg, (value)); } - if (wantedArgc < fnArgc) + // ----------------------------------------------------------------------- + // Handle missing arguments. + // + // For each absent arg that carries a default (argFlags bit 0x1), we + // execute its codelet — a small bytecode expression compiled after the + // function body that ends with OP_DEFAULT_END. + // + // The codelet is run in its own minimal frame via a nested exec() call. + // + // If the default offset is 0, the argument had no default expression and + // the register keeps its zero-initialised value. + // ----------------------------------------------------------------------- + if (wantedArgc < S32(fnArgc)) { Namespace::Entry* temp = thisNamespace->lookup(thisFunctionName); - for (; i < fnArgc; i++) + + // Offset into the header where arg flags begin. + const U32 flagBase = ip + 10 + fnArgc; + // Offset into the header where default codelet IPs begin. + const U32 offsetBase = ip + 10 + 2 * fnArgc; + + for (; i < S32(fnArgc); i++) { - S32 reg = code[ip + (2 + 6 + 1 + 1) + i]; - if (temp->mArgFlags[i] & 0x1) + const S32 reg = code[ip + 10 + i]; + const U32 argFlags = code[flagBase + i]; + + if (argFlags & 0x1) // argument has a default expression { - ConsoleValue& value = temp->mDefaultValues[i]; - Script::gEvalState.moveConsoleValue(reg, (value)); + const U32 codeletIp = (temp != NULL) + ? temp->mDefaultOffsets[i] + : code[offsetBase + i]; + + if (codeletIp != 0) + { + // Execute the default codelet. + // argv=NULL → uses globalStrings / globalFloats (correct, + // since codelets are compiled into those tables). + // argc=0 → pushes a frame with 0 locals. + // setFrame=-2 → reference to the codelet frame. + Con::EvalResult result = exec( + codeletIp, + NULL, // functionName + NULL, // thisNamespace + 0, // argc + NULL, // argv ← signals non-function (codelet) call + false, // noCalls + NULL, // packageName + -2 // setFrame + ); + + Script::gEvalState.moveConsoleValue(reg, result.value); + } + // codeletIp == 0: no default; register stays at its zero value. } } } - ip = ip + fnArgc + (2 + 6 + 1 + 1) + fnArgc; + // ----------------------------------------------------------------------- + // Advance ip to the start of the function BODY. + // + // The header now contains 3*fnArgc words after the fixed 10-word prefix: + // fnArgc words for register mappings + // fnArgc words for arg flags + // fnArgc words for default codelet IPs ← new + // + // Old: ip + 10 + 2*fnArgc + // New: ip + 10 + 3*fnArgc + // ----------------------------------------------------------------------- + ip = ip + 10 + 3 * fnArgc; + curFloatTable = functionFloats; curStringTable = functionStrings; curStringTableLen = functionStringsMaxLen; + } + else if (isCodelet) + { + // ---- Codelet path ---------------------------------------------------- + // + // The codelet was compiled into functionStrings/functionFloats (see + // compileStmt). + // + // functionStrings lives for the lifetime of the CodeBlock, which is + // always at least as long as any call to a function it contains. + curStringTable = functionStrings; + curFloatTable = functionFloats; + curStringTableLen = functionStringsMaxLen; + + // Push a minimal empty frame. The codelet contains only an expression; + // it has no local variables of its own. + Script::gEvalState.pushFrame(NULL, NULL, 0); + popFrame = true; + + // setFrame has served its purpose as a mode signal. Reset it so the + // telnet debugger guard `if (telDebuggerOn && setFrame < 0)` fires + // correctly (codelets should not push a telnet stack frame). + setFrame = -1; } else { @@ -727,6 +806,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi switch (instruction) { case OP_FUNC_DECL: + { if (!noCalls) { fnName = CodeToSTE(code, ip); @@ -739,7 +819,9 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi ns = Namespace::global(); else ns = Namespace::find(fnNamespace, fnPackage); - ns->addFunction(fnName, this, hasBody ? ip : 0);// if no body, set the IP to 0 + + ns->addFunction(fnName, this, hasBody ? ip : 0); + if (curNSDocBlock) { if (fnNamespace == StringTable->lookup(nsDocBlockClass)) @@ -751,46 +833,49 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi curNSDocBlock = NULL; } } - - U32 fnArgc = code[ip + 2 + 6]; - - // Compute pointer to the register mapping like exec() does. - U32 readPtr = ip + 2 + 6 + 1; // points to the slot after argc (localNumVarsIP) - readPtr += 1; // skip localNumVarsIP - readPtr += fnArgc; // skip register mapping + const U32 fnArgc = code[ip + 8]; Namespace::Entry* temp = ns->lookup(fnName); - temp->mArgFlags.setSize(fnArgc); - temp->mDefaultValues.setSize(fnArgc); + temp->mDefaultOffsets.setSize(fnArgc); + + // Arg flags: ip + 10 + fnArgc + // Codelet IPs: ip + 10 + 2*fnArgc + const U32 flagBase = ip + 10 + fnArgc; + const U32 offsetBase = ip + 10 + 2 * fnArgc; - // Read flags sequentially for (U32 fa = 0; fa < fnArgc; ++fa) { - temp->mArgFlags[fa] = code[readPtr++]; + temp->mArgFlags[fa] = code[flagBase + fa]; + temp->mDefaultOffsets[fa] = code[offsetBase + fa]; } - // this might seem weird but because of the order - // the stack accumulates consoleValues we cant be sure - // all args have a console value, and we need to pop - // the stack, do this in reverse order. - for (S32 fa = S32(fnArgc - 1); fa >= 0; fa--) - { - if (temp->mArgFlags[fa] & 0x1) - { - temp->mDefaultValues[fa] = stack[_STK--]; - } - } + // No stack pops: mDefaultValues is gone. Namespace::relinkPackages(); - // If we had a docblock, it's definitely not valid anymore, so clear it out. curFNDocBlock = NULL; - - //Con::printf("Adding function %s::%s (%d)", fnNamespace, fnName, ip); } + + // Jump past header + body + codelets. endIp is at code[ip + 7]. ip = code[ip + 7]; break; + } + + case OP_DEFAULT_END: + { + returnValue = stack[_STK]; + _STK--; + + while (iterDepth > 0) + { + iterStack[--_ITER].mIsStringIter = false; + --iterDepth; + _STK--; + } + + goto execFinished; + } case OP_CREATE_OBJECT: { @@ -2331,10 +2416,13 @@ execFinished: } else { - delete[] const_cast(globalStrings); - delete[] globalFloats; - globalStrings = NULL; - globalFloats = NULL; + if (!isCodelet) + { + delete[] const_cast(globalStrings); + delete[] globalFloats; + globalStrings = NULL; + globalFloats = NULL; + } } if (Con::getCurrentScriptModuleName()) diff --git a/Engine/source/console/torquescript/compiler.h b/Engine/source/console/torquescript/compiler.h index 74737c773..4b997b5d4 100644 --- a/Engine/source/console/torquescript/compiler.h +++ b/Engine/source/console/torquescript/compiler.h @@ -54,6 +54,7 @@ namespace Compiler enum CompiledInstructions { OP_FUNC_DECL, + OP_DEFAULT_END, OP_CREATE_OBJECT, OP_ADD_OBJECT, OP_END_OBJECT, From 0fd3c6b013b0fef312022dd595e402732476e932 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 14 Apr 2026 15:24:04 -0500 Subject: [PATCH 2/7] Allow Player class derivatives to override NumTableActionAnims the player class (and resource derivatives, contain a mix of hardcoded animation names, as well as scriptable ones that can be tripped via playthread/setActionThread. to determine if an animation within the stored vector is hardcoded or a scripted oneoff for that mesh, theres a demarcation at NumTableActionAnims for the up to 512 animation slots available. when deriving from player, we must therefore allow that entry to be overridden for any class which adds additional hardcoded animations therefore this introduces a datablock-level entry for the marked slot. --- Engine/source/T3D/player.cpp | 17 +++++++++-------- Engine/source/T3D/player.h | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index 0ccb13828..b91208221 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -461,6 +461,7 @@ PlayerData::PlayerData() physicsPlayerType = StringTable->EmptyString(); mControlMap = StringTable->EmptyString(); + mDynamicAnimsStart = NumTableActionAnims; dMemset( actionList, 0, sizeof(actionList) ); } @@ -512,7 +513,7 @@ bool PlayerData::preload(bool server, String &errorStr) // Extract ground transform velocity from animations // Get the named ones first so they can be indexed directly. ActionAnimation *dp = &actionList[0]; - for (S32 i = 0; i < NumTableActionAnims; i++,dp++) + for (S32 i = 0; i < mDynamicAnimsStart; i++,dp++) { ActionAnimationDef *sp = &ActionAnimationList[i]; dp->name = sp->name; @@ -690,7 +691,7 @@ bool PlayerData::isTableSequence(S32 seq) { // The sequences from the table must already have // been loaded for this to work. - for (S32 i = 0; i < NumTableActionAnims; i++) + for (S32 i = 0; i < mDynamicAnimsStart; i++) if (actionList[i].sequence == seq) return true; return false; @@ -2801,7 +2802,7 @@ void Player::updateMove(const Move* move) // Cancel any script driven animations if we are going to move. if (moveVec.x + moveVec.y + moveVec.z != 0.0f && - (mActionAnimation.action >= PlayerData::NumTableActionAnims + (mActionAnimation.action >= mDataBlock->mDynamicAnimsStart || mActionAnimation.action == PlayerData::LandAnim)) mActionAnimation.action = PlayerData::NullAnimation; } @@ -3711,7 +3712,7 @@ bool Player::inSittingAnim() U32 action = mActionAnimation.action; if (mActionAnimation.thread && action < mDataBlock->actionCount) { const char * name = mDataBlock->actionList[action].name; - if (!dStricmp(name, "Sitting") || !dStricmp(name, "Scoutroot")) + if (name && (!dStricmp(name, "Sitting") || !dStricmp(name, "Scoutroot"))) return true; } return false; @@ -3956,7 +3957,7 @@ void Player::updateActionThread() if (mMountPending) mMountPending = (isMounted() ? 0 : (mMountPending - 1)); - if (isServerObject() && (mActionAnimation.action >= PlayerData::NumTableActionAnims) && mActionAnimation.atEnd) + if (isServerObject() && (mActionAnimation.action >= mDataBlock->mDynamicAnimsStart) && mActionAnimation.atEnd) { //The scripting language will get a call back when a script animation has finished... // example: When the chat menu animations are done playing... @@ -4057,7 +4058,7 @@ void Player::pickActionAnimation() // Go into root position unless something was set explicitly // from a script. if (mActionAnimation.action != PlayerData::RootAnim && - mActionAnimation.action < PlayerData::NumTableActionAnims) + mActionAnimation.action < mDataBlock->mDynamicAnimsStart) setActionThread(PlayerData::RootAnim,true,false,false); return; } @@ -5956,7 +5957,7 @@ void Player::getMuzzlePointAI(U32 imageSlot, Point3F* point) // If we are in one of the standard player animations, adjust the // muzzle to point in the direction we are looking. - if (mActionAnimation.action < PlayerData::NumTableActionAnims) + if (mActionAnimation.action < mDataBlock->mDynamicAnimsStart) { MatrixF xmat; xmat.set(EulerF(mHead.x, 0, 0)); @@ -6340,7 +6341,7 @@ U32 Player::packUpdate(NetConnection *con, U32 mask, BitStream *stream) if (stream->writeFlag(mask & ActionMask && mActionAnimation.action != PlayerData::NullAnimation && - mActionAnimation.action >= PlayerData::NumTableActionAnims)) { + mActionAnimation.action >= mDataBlock->mDynamicAnimsStart)) { stream->writeInt(mActionAnimation.action,PlayerData::ActionAnimBits); stream->writeFlag(mActionAnimation.holdAtEnd); stream->writeFlag(mActionAnimation.atEnd); diff --git a/Engine/source/T3D/player.h b/Engine/source/T3D/player.h index 05277a208..35f69ef41 100644 --- a/Engine/source/T3D/player.h +++ b/Engine/source/T3D/player.h @@ -295,7 +295,7 @@ struct PlayerData: public ShapeBaseData /*protected AssetPtrCallback < already i ActionAnimBits = 9, NullAnimation = (1 << ActionAnimBits) - 1 }; - + int mDynamicAnimsStart; static ActionAnimationDef ActionAnimationList[NumTableActionAnims]; ActionAnimation actionList[NumActionAnims]; U32 actionCount; @@ -402,9 +402,9 @@ protected: class Player: public ShapeBase { +public: typedef ShapeBase Parent; -public: enum Pose { StandPose = 0, SprintPose, From 7d72d38ae01b11e085bd99f3fa3804ba6aac3249 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Fri, 17 Apr 2026 06:59:24 -0500 Subject: [PATCH 3/7] correct element gui resizing drift add minimal padding to counteract floating point flurrer when rounding due to changes in parent element scale revisit the aspect maintining resizer math to correct a few failures with live editing the values. --- Engine/source/gui/core/guiControl.cpp | 66 +++++++++++---------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/Engine/source/gui/core/guiControl.cpp b/Engine/source/gui/core/guiControl.cpp index bf9eec103..5d69de601 100644 --- a/Engine/source/gui/core/guiControl.cpp +++ b/Engine/source/gui/core/guiControl.cpp @@ -1382,6 +1382,8 @@ void GuiControl::parentResized(const RectI &oldParentRect, const RectI &newParen S32 deltaX = newParentRect.extent.x - oldParentRect.extent.x; S32 deltaY = newParentRect.extent.y - oldParentRect.extent.y; + F32 nudgeX = (deltaX > 0) ? -0.001f : 0.001f; + F32 nudgeY = (deltaY > 0) ? -0.001f : 0.001f; if (mHorizSizing == horizResizeCenter) newPosition.x = (newParentRect.extent.x - getWidth()) >> 1; @@ -1391,40 +1393,34 @@ void GuiControl::parentResized(const RectI &oldParentRect, const RectI &newParen newPosition.x += deltaX; else if (mHorizSizing == horizResizeRelative && oldParentRect.extent.x != 0) { - S32 newLeft = mRoundToNearest( ( F32( newPosition.x ) / F32( oldParentRect.extent.x ) ) * F32( newParentRect.extent.x ) ); - S32 newWidth = mRoundToNearest( ( F32( newExtent.x ) / F32( oldParentRect.extent.x ) ) * F32( newParentRect.extent.x ) ); + S32 newLeft = mRoundToNearest( ( F32( newPosition.x ) / F32( oldParentRect.extent.x ) ) * F32( newParentRect.extent.x ) + nudgeX); + S32 newWidth = mRoundToNearest( ( F32( newExtent.x ) / F32( oldParentRect.extent.x ) ) * F32( newParentRect.extent.x ) + nudgeX); newPosition.x = newLeft; newExtent.x = newWidth; } else if (mHorizSizing == horizResizeAspectLeft && oldParentRect.extent.x != 0) { - S32 newLeft = mRoundToNearest((F32(newPosition.x) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); - S32 newWidth = mRoundToNearest((F32(newExtent.x) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); + F32 heightRatio = F32(newParentRect.extent.y) / F32(oldParentRect.extent.y); + S32 newWidth = mRoundToNearest(F32(newExtent.x) * heightRatio + nudgeX); - newPosition.x = newLeft; + S32 newRight = newPosition.x + newExtent.x + deltaX; + newPosition.x = newRight - newWidth; newExtent.x = newWidth; } else if (mHorizSizing == horizResizeAspectRight && oldParentRect.extent.x != 0) { - S32 newLeft = mRoundToNearest((F32(newPosition.x) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); - S32 newWidth = mRoundToNearest((F32(newExtent.x) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); //origional aspect ratio corrected width - S32 rWidth = mRoundToNearest((F32(newExtent.x) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); //parent aspect ratio relative width - - S32 offset = rWidth - newWidth; // account for change in relative width - newLeft += offset; - newPosition.x = newLeft; + F32 heightRatio = F32(newParentRect.extent.y) / F32(oldParentRect.extent.y); + S32 newWidth = mRoundToNearest(F32(newExtent.x) * heightRatio + nudgeX); newExtent.x = newWidth; } else if (mHorizSizing == horizResizeAspectCenter && oldParentRect.extent.x != 0) { - S32 newLeft = mRoundToNearest((F32(newPosition.x) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); - S32 newWidth = mRoundToNearest((F32(newExtent.x) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); //origional aspect ratio corrected width - S32 rWidth = mRoundToNearest((F32(newExtent.x) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); //parent aspect ratio relative width - - S32 offset = rWidth - newWidth; // account for change in relative width - newLeft += offset/2; - newPosition.x = newLeft; + F32 heightRatio = F32(newParentRect.extent.y) / F32(oldParentRect.extent.y); + S32 newWidth = mRoundToNearest(F32(newExtent.x) * heightRatio + nudgeX); + S32 center = newPosition.x + (newExtent.x >> 1); + center += deltaX >> 1; + newPosition.x = center - (newWidth >> 1); newExtent.x = newWidth; } @@ -1436,40 +1432,32 @@ void GuiControl::parentResized(const RectI &oldParentRect, const RectI &newParen newPosition.y += deltaY; else if(mVertSizing == vertResizeRelative && oldParentRect.extent.y != 0) { - S32 newTop = mRoundToNearest( ( F32( newPosition.y ) / F32( oldParentRect.extent.y ) ) * F32( newParentRect.extent.y ) ); - S32 newHeight = mRoundToNearest( ( F32( newExtent.y ) / F32( oldParentRect.extent.y ) ) * F32( newParentRect.extent.y ) ); + S32 newHeight = mRoundToNearest( ( F32( newExtent.y ) / F32( oldParentRect.extent.y ) ) * F32( newParentRect.extent.y ) + nudgeY ); + S32 newTop = mRoundToNearest( ( F32( newPosition.y ) / F32( oldParentRect.extent.y ) ) * F32( newParentRect.extent.y ) + nudgeY ); newPosition.y = newTop; newExtent.y = newHeight; } else if (mVertSizing == vertResizeAspectTop && oldParentRect.extent.y != 0) { - S32 newTop = mRoundToNearest((F32(newPosition.y) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); - S32 newHeight = mRoundToNearest((F32(newExtent.y) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); - - newPosition.y = newTop; + F32 widthRatio = F32(newParentRect.extent.x) / F32(oldParentRect.extent.x); + S32 newHeight = mRoundToNearest(F32(newExtent.y) * widthRatio + nudgeY); + newPosition.y += deltaY; newExtent.y = newHeight; } else if (mVertSizing == vertResizeAspectBottom && oldParentRect.extent.y != 0) { - S32 newTop = mRoundToNearest((F32(newPosition.y) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); - S32 newHeight = mRoundToNearest((F32(newExtent.y) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); //origional aspect ratio corrected hieght - S32 rHeight = mRoundToNearest((F32(newExtent.y) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); //parent aspect ratio relative hieght - - S32 offset = rHeight - newHeight; // account for change in relative hieght - newTop += offset; - newPosition.y = newTop; + F32 widthRatio = F32(newParentRect.extent.x) / F32(oldParentRect.extent.x); + S32 newHeight = mRoundToNearest(F32(newExtent.y) * widthRatio + nudgeY); newExtent.y = newHeight; } else if (mVertSizing == vertResizeAspectCenter && oldParentRect.extent.y != 0) { - S32 newTop = mRoundToNearest((F32(newPosition.y) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); - S32 newHeight = mRoundToNearest((F32(newExtent.y) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); //origional aspect ratio corrected hieght - S32 rHeight = mRoundToNearest((F32(newExtent.y) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); //parent aspect ratio relative hieght - - S32 offset = rHeight - newHeight; // account for change in relative hieght - newTop += offset / 2; - newPosition.y = newTop; + F32 widthRatio = F32(newParentRect.extent.x) / F32(oldParentRect.extent.x); + S32 newHeight = mRoundToNearest(F32(newExtent.y) * widthRatio + nudgeY); + S32 center = newPosition.y + (newExtent.y >> 1); + center += deltaY >> 1; + newPosition.y = center - (newHeight >> 1); newExtent.y = newHeight; } From defbaea2fe3015fd2c6ef135ff988b71e4005f97 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 19 Apr 2026 02:18:05 -0500 Subject: [PATCH 4/7] Implements misc fixes for the particle editor and particlesList inspector field - Clicking the [...] button from the Particle Emitter tab now opens to the Particle tab *and* properly selects the particle data to be edited - Selecting an emitter object in the map and opening the particle editor now selects the Particle Data to be edited - Selecting a new Particle Data for a particles slot on a Particle Emitter in the editor now correctly updates the values and updates the field display - Made it so if clicking [...] button on the ParticleEmitterData or other similar fields for objects, it will now open to the Particle editor instead of the Datablock editor --- Engine/source/T3D/fx/particle.cpp | 109 +++++++++++++----- Engine/source/T3D/fx/particleInspectors.h | 2 + .../datablockEditor/datablockEditor.tscript | 28 +++++ .../guis/particleEditor.ed.tscript | 4 +- .../game/tools/particleEditor/main.tscript | 22 ++++ .../scripts/particleEmitterEditor.ed.tscript | 22 ++-- .../scripts/particleParticleEditor.ed.tscript | 3 +- 7 files changed, 145 insertions(+), 45 deletions(-) diff --git a/Engine/source/T3D/fx/particle.cpp b/Engine/source/T3D/fx/particle.cpp index 8186853b8..b9d9e874d 100644 --- a/Engine/source/T3D/fx/particle.cpp +++ b/Engine/source/T3D/fx/particle.cpp @@ -907,6 +907,9 @@ GuiControl* GuiInspectorTypeParticleDataList::constructEditControl() mNewParticleBtn->registerObject(); mNewParticleBtn->_setBitmap(StringTable->insert("ToolsModule:iconAdd_image")); mNewParticleBtn->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiDefaultProfile"); + mNewParticleBtn->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + mNewParticleBtn->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + mNewParticleBtn->setDataField(StringTable->insert("tooltip"), NULL, "Add new particle slot"); mNewParticleBtn->setHorizSizing(horizResizeRight); mNewParticleBtn->mMakeIconSquare = true; mNewParticleBtn->mFitBitmapToButton = true; @@ -914,7 +917,7 @@ GuiControl* GuiInspectorTypeParticleDataList::constructEditControl() char szBuffer[512]; dSprintf(szBuffer, sizeof(szBuffer), "ParticleEditor.addParticleSlot(%s, %s);", - mNewParticleBtn->getIdString(), mInspector->getInspectObject()->getIdString()); + this->getIdString(), mInspector->getInspectObject()->getIdString()); mNewParticleBtn->setField("Command", szBuffer); GuiContainer* newBtnCtnr = new GuiContainer(); @@ -924,39 +927,16 @@ GuiControl* GuiInspectorTypeParticleDataList::constructEditControl() mStack->addObject(newBtnCtnr); - //Particle 0 - mParticleSlot0Ctrl = _buildParticleEntryField(0); - - mStack->addObject(mParticleSlot0Ctrl); - - //Now the non-default entries if we already have some - Parent::updateValue(); - const char* data = getData(); - - if (data != NULL && !String::isEmpty(data)) - { - U32 particlesCount = StringUnit::getUnitCount(data, " "); - for (U32 i=1; i < particlesCount; i++) - { - GuiControl* particleSlotCtrl = _buildParticleEntryField(i); - mStack->addObject(particleSlotCtrl); - } - } + _rebuildParticleEntryList(); _registerEditControl(mStack); - //constructEditControlChildren(retCtrl, getWidth()); - - //retCtrl->addObject(mScriptValue); - - /*char szBuffer[512]; - dSprintf(szBuffer, 512, "setClipboard(%d.getText());", mScriptValue->getId()); - mCopyButton->setField("Command", szBuffer); - addObject(mCopyButton);*/ - mUseHeightOverride = true; mHeightOverride = (mStack->getCount() * 23) + 6; + //Now the non-default entries if we already have some + //Parent::updateValue(); + return mStack; } @@ -980,7 +960,7 @@ GuiControl* GuiInspectorTypeParticleDataList::_buildParticleEntryField(const S32 char szBuffer[512]; dSprintf(szBuffer, sizeof(szBuffer), "ParticleEditor.changeParticleSlot(%s, %s, %d);", - listBtn->getIdString(), mInspector->getInspectObject()->getIdString(), index); + this->getIdString(), mInspector->getInspectObject()->getIdString(), index); listBtn->setField("Command", szBuffer); if (mField && index != -1) @@ -1001,6 +981,9 @@ GuiControl* GuiInspectorTypeParticleDataList::_buildParticleEntryField(const S32 editSlotBtn->registerObject(); editSlotBtn->setText(StringTable->insert("...")); editSlotBtn->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiButtonProfile"); + editSlotBtn->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + editSlotBtn->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + editSlotBtn->setDataField(StringTable->insert("tooltip"), NULL, "Edit this particle"); editSlotBtn->setHorizSizing(horizResizeRight); editSlotBtn->setInternalName("editBtn"); editSlotBtn->setPosition(editExtent.x - 40, 0); @@ -1019,6 +1002,9 @@ GuiControl* GuiInspectorTypeParticleDataList::_buildParticleEntryField(const S32 deleteSlotBtn->registerObject(); deleteSlotBtn->_setBitmap(StringTable->insert("ToolsModule:iconCancel_image")); deleteSlotBtn->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiDefaultProfile"); + deleteSlotBtn->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + deleteSlotBtn->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + deleteSlotBtn->setDataField(StringTable->insert("tooltip"), NULL, "Delete this particle slot"); deleteSlotBtn->setHorizSizing(horizResizeRight); deleteSlotBtn->setInternalName("deleteBtn"); deleteSlotBtn->mMakeIconSquare = true; @@ -1062,6 +1048,38 @@ void GuiInspectorTypeParticleDataList::_populateMenu(GuiPopUpMenuCtrlEx* menu) menu->sort(); } +void GuiInspectorTypeParticleDataList::_rebuildParticleEntryList() +{ + const char* data = getData(); + + //whoops it's misaligned, force a rebuild + mParticleSlot0Ctrl = NULL; + + for (U32 i = 0; i < mParticleSlotList.size(); i++) + { + mStack->removeObject(mParticleSlotList[i]); + mParticleSlotList[i]->deleteObject(); + } + mParticleSlotList.clear(); + + //Particle 0 + mParticleSlot0Ctrl = _buildParticleEntryField(0); + mStack->addObject(mParticleSlot0Ctrl); + mParticleSlotList.push_back(mParticleSlot0Ctrl); + + if (data != NULL && !String::isEmpty(data)) + { + U32 particlesCount = StringUnit::getUnitCount(data, " "); + + for (U32 i = 1; i < particlesCount; i++) + { + GuiControl* particleSlotCtrl = _buildParticleEntryField(i); + mStack->addObject(particleSlotCtrl); + mParticleSlotList.push_back(particleSlotCtrl); + } + } +} + bool GuiInspectorTypeParticleDataList::updateRects() { S32 rowSize = 18; @@ -1109,14 +1127,43 @@ bool GuiInspectorTypeParticleDataList::updateRects() mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); + mUseHeightOverride = true; mHeightOverride = (mStack->getCount() * 23) + 6; - //mCopyButton->resize(Point2I(mProfile->mTextOffset.x, rowSize + 3), Point2I(45, 15)); - //mPasteButton->resize(Point2I(mProfile->mTextOffset.x, rowSize + rowSize + 6), Point2I(45, 15)); + RectI bnds = getBounds(); + setBounds(bnds.point.x, bnds.point.y, bnds.extent.x, mHeightOverride); return true; } +void GuiInspectorTypeParticleDataList::updateValue() +{ + const char* data = getData(); + + if (data != NULL && !String::isEmpty(data)) + { + U32 particlesCount = StringUnit::getUnitCount(data, " "); + + if (particlesCount != mParticleSlotList.size()) + { + _rebuildParticleEntryList(); + } + else + { + for (U32 i = 0; i < particlesCount; i++) + { + GuiButtonCtrl* listBtn = dynamic_cast(mParticleSlotList[i]->getObject(0)); + if (!listBtn) //This *really* shouldn't happen + continue; + + const char* particleName = StringUnit::getUnit(data, i, " "); + listBtn->setText(particleName); + } + } + } + + updateRects(); +} void GuiInspectorTypeParticleDataList::consoleInit() { diff --git a/Engine/source/T3D/fx/particleInspectors.h b/Engine/source/T3D/fx/particleInspectors.h index d6784d0b5..152df20c8 100644 --- a/Engine/source/T3D/fx/particleInspectors.h +++ b/Engine/source/T3D/fx/particleInspectors.h @@ -33,8 +33,10 @@ public: GuiControl* constructEditControl() override; bool updateRects() override; + void updateValue() override; void _populateMenu(GuiPopUpMenuCtrlEx* menu); GuiControl* _buildParticleEntryField(const S32& index); + void _rebuildParticleEntryList(); }; #endif diff --git a/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript b/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript index 5e590f34e..07424420b 100644 --- a/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript +++ b/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript @@ -111,6 +111,19 @@ function DatablockEditorPlugin::onExitMission( %this ) function DatablockEditorPlugin::openDatablock( %this, %datablock ) { + //We want to do a special-case catch here for any datablock types that have their own unique editor. + //The main culprit is the particle editor, but this could be expanded later + if(%datablock.isMemberOfClass("ParticleData") || + %datablock.isMemberOfClass("ParticleEmitterData") || + %datablock.isMemberOfClass("ExplosionData") || + %datablock.isMemberOfClass("RibbonData") || + %datablock.isMemberOfClass("afxZodiacData") || + %datablock.isMemberOfClass("afxChoreographerData")) + { + EditorGui.setEditor( ParticleEditorPlugin ); + return; + } + EditorGui.setEditor( DatablockEditorPlugin ); %this.selectDatablock( %datablock ); DatablockEditorTreeTabBook.selectedPage = 0; @@ -631,6 +644,21 @@ function DatablockEditorPlugin::deleteDatablock( %this ) //--------------------------------------------------------------------------------------------- function DatablockEditorPlugin::createNewDatablockOfType(%this, %class, %inheritFrom) { + //We want to do a special-case catch here for any datablock types that have their own unique editor. + //The main culprit is the particle editor, but this could be expanded later + if(%class.isMemberOfClass("ParticleData") || + %class.isMemberOfClass("ParticleEmitterData") || + %class.isMemberOfClass("ExplosionData") || + %class.isMemberOfClass("RibbonData") || + %class.isMemberOfClass("afxZodiacData") || + %class.isMemberOfClass("afxChoreographerData")) + { + EditorGui.setEditor( ParticleEditorPlugin ); + + ParticleEditorPlugin::createNewDatablockOfType(%class, %inheritFrom); + return; + } + $DATABLOCK_EDITOR_NEWDB_CLASS = %class; $DATABLOCK_EDITOR_NEWDB_INHERITFROM = %inheritFrom; diff --git a/Templates/BaseGame/game/tools/particleEditor/guis/particleEditor.ed.tscript b/Templates/BaseGame/game/tools/particleEditor/guis/particleEditor.ed.tscript index c8faf01e1..f9a2f2961 100644 --- a/Templates/BaseGame/game/tools/particleEditor/guis/particleEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/particleEditor/guis/particleEditor.ed.tscript @@ -51,8 +51,6 @@ function ParticleEditor::initEditor( %this ) if(exec("./PETabTemplate.gui")) { - echo("MADE A NEW TAB PAGE: " @ $guiContent); - $guiContent.text = %groupName; $guiContent.typesList = %typesList; $guiContent.setName(%editorName); @@ -199,7 +197,7 @@ function ParticleEditor::open(%this, %datablock) for(%t=0; %t < %typesListCount; %t++) { %type = getWord(%typesList, %t); - + if( %datablock.isMemberOfClass( %type ) ) { PE_TabBook.selectPage(%i); diff --git a/Templates/BaseGame/game/tools/particleEditor/main.tscript b/Templates/BaseGame/game/tools/particleEditor/main.tscript index 00f89bbe0..9494ae604 100644 --- a/Templates/BaseGame/game/tools/particleEditor/main.tscript +++ b/Templates/BaseGame/game/tools/particleEditor/main.tscript @@ -113,6 +113,19 @@ function ParticleEditorPlugin::onActivated( %this ) EditorGuiStatusBar.setInfo( "Particle editor." ); EditorGuiStatusBar.setSelection( "" ); + // Try to start with the object selected in the world editor + %count = EWorldEditor.getSelectionSize(); + for (%i = 0; %i < %count; %i++) + { + %obj = EWorldEditor.getSelectedObject(%i); + %datablock = ParticleEditor.getObjectParticleData(%obj); + if (%datablock !$= "" && isObject(%datablock)) + { + ParticleEditor.open(%datablock); + break; + } + } + Parent::onActivated( %this ); } @@ -213,3 +226,12 @@ function ParticleEditor::registerParticleEdType(%this, %groupName, %typesList, % PE_ParticleDataTypes.add(%groupName, %typesList TAB %editorName); } +//------------------------------------------------------------------------------ +function ParticleEditor::getObjectParticleData( %this, %obj ) +{ + %datablock = ""; + if ( %obj.isMemberOfClass( "ParticleEmitterNode" ) ) + %datablock = %obj.emitter; + + return %datablock; +} diff --git a/Templates/BaseGame/game/tools/particleEditor/scripts/particleEmitterEditor.ed.tscript b/Templates/BaseGame/game/tools/particleEditor/scripts/particleEmitterEditor.ed.tscript index 7ab62ac70..c5555f9af 100644 --- a/Templates/BaseGame/game/tools/particleEditor/scripts/particleEmitterEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/particleEditor/scripts/particleEmitterEditor.ed.tscript @@ -122,7 +122,6 @@ function PE_EmitterEditor::selectObject(%this, %obj) && %obj.getName() $= %this-->popupMenu.text ) return; - //FIXME: disregards particle tab dirty state if( %this.dirty ) { if( PE_ParticleEditor.dirty ) @@ -483,6 +482,8 @@ function ParticleEditor::addParticleSlot(%this, %field, %emitterObj) %action.oldValue = %emitterObj.particles; ParticleEditor.submitUndo( %action ); + + %field.apply(%action.newValue); } function ParticleEditor::changeParticleSlot(%this, %field, %emitterObj, %slotIdx) @@ -495,7 +496,6 @@ function ParticleEditor::changeParticleSlot(%this, %field, %emitterObj, %slotIdx foreach( %obj in DatablockGroup ) { - echo(%typesList); %typesListCount = getWordCount(%typesList); for(%i=0; %i < %typesListCount; %i++) { @@ -552,7 +552,7 @@ function ParticleEditor::changeParticleSlot(%this, %field, %emitterObj, %slotIdx } } - ContextedDropdownListGui.show(%listSet, "Edit Particle Slot[" @ %slotIdx @ "]", "ParticleEditor.editSlot = " @ %slotIdx @ ";ParticleEditor.updateParticleSlot", %field); + ContextedDropdownListGui.show(%listSet, "Edit Particle Slot[" @ %slotIdx @ "]", "ParticleEditor.fieldObj = " @ %field @ ";ParticleEditor.editSlot = " @ %slotIdx @ ";ParticleEditor.updateParticleSlot", %field); %particleData = getWord(%emitterObj.particles, %slotIdx); if(%particleData !$= "") { @@ -562,10 +562,10 @@ function ParticleEditor::changeParticleSlot(%this, %field, %emitterObj, %slotIdx function ParticleEditor::updateParticleSlot(%this, %newParticle) { - if(ParticleEditor.editSlot $= "") + if(ParticleEditor.editSlot $= "" || !isObject(%newParticle)) return; - %updatedParticlesList = setWord(PE_EmitterEditor.currEmitter.particles, ParticleEditor.editSlot, %newParticle); + %updatedParticlesList = setWord(PE_EmitterEditor.currEmitter.particles, ParticleEditor.editSlot, %newParticle.getName()); %action = ParticleEditor.createUndo(ActionUpdateActiveEmitter, "Edit Active Emitter Particle Slot"); %action.emitter = PE_EmitterEditor.currEmitter; @@ -575,16 +575,19 @@ function ParticleEditor::updateParticleSlot(%this, %newParticle) ParticleEditor.submitUndo( %action ); - ParticleEditor.editSlot = ""; + ParticleEditor.fieldObj.apply(%action.newValue); - //%field.apply(%updatedParticlesList, %slotIdx); - //%this-->inspector.refresh(); + ParticleEditor.editSlot = ""; + ParticleEditor.fieldObj = ""; } function ParticleEditor::editParticleSlot(%this, %field, %emitterObj, %slotIdx) { %particleName = getWord(%emitterObj.particles, %slotIdx); + ParticleEditor.editSlot = ""; + ParticleEditor.fieldObj = ""; + ParticleEditor.open(%particleName); } @@ -600,6 +603,5 @@ function ParticleEditor::clearParticleSlot(%this, %field, %emitterObj, %slotIdx) ParticleEditor.submitUndo( %action ); - //%field.apply(%updatedParticlesList, %slotIdx); - //%this-->inspector.refresh(); + %field.apply(%action.newValue); } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript b/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript index 43dc020f0..1b950a979 100644 --- a/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript @@ -74,7 +74,8 @@ function PE_ParticleEditor::updateVizNode(%this) function PE_ParticleEditor::selectObject(%this, %obj) { // Bail if the user selected the same particle. - if( %obj == %this.currParticle ) + if( isObject(%obj ) + && %obj.getName() $= %this-->popupMenu.text ) return; // Load new particle if we're not in a dirty state From 95afee693734ba407a197493fd92e2c2f8dbbc0a Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 19 Apr 2026 11:52:44 -0500 Subject: [PATCH 5/7] AssetImportConfig::loadImportConfig safety if no Settings* passed, report and skip trying to apply them to a nonexisent object --- Engine/source/T3D/assets/assetImporter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index ec0fd1f89..7abdaeeb5 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -238,6 +238,11 @@ void AssetImportConfig::initPersistFields() void AssetImportConfig::loadImportConfig(Settings* configSettings, String configName) { + if (!configSettings) + { + Con::errorf("AssetImportConfig::loadImportConfig - No config settings!"); + return; + } //General DuplicateAutoResolution = configSettings->value(String(configName + "/General/DuplicateAutoResolution").c_str()); WarningsAsErrors = dAtob(configSettings->value(String(configName + "/General/WarningsAsErrors").c_str())); From f6f06121abf4b133d14eb694706866101eb4283a Mon Sep 17 00:00:00 2001 From: JeffR Date: Tue, 21 Apr 2026 01:22:26 -0500 Subject: [PATCH 6/7] Misc fixes associated to looseAssetFiles handling and lookups for LevelAssets - Adds proper marking of Load status for levelAsset, so if no mis file is defined then the asset fails to load and has proper error code - Adjusts the get*Path() util methods for getting stuff like postFXPrefix or decal files to have a fallback if one isn't currently defined in the assetDef, as it could be a broken link but the file does exist - Adjusts saving logic of level so it will properly update the levelAsset for postfx prefix or decal files so if they were added after creation of the assetdef, they're saved and updated as expected - Adjusts the setter methods for the *File fields to correctly separate the File variable and Path variable to make things behave more clearly and consistently. - Keeps checks for *.mis.decals file pattern, but shifts new creations of decals files to just be *.decals to better match other level-associated files like *.nav or *.forest --- Engine/source/T3D/assets/LevelAsset.cpp | 84 ++++++++++++++++--- Engine/source/T3D/decal/decalManager.cpp | 8 +- .../scripts/assetTypes/level.tscript | 2 +- .../scripts/projectImporter.tscript | 4 + .../scripts/menuHandlers.ed.tscript | 36 +++++--- 5 files changed, 108 insertions(+), 26 deletions(-) diff --git a/Engine/source/T3D/assets/LevelAsset.cpp b/Engine/source/T3D/assets/LevelAsset.cpp index 47d4ad231..9b4877090 100644 --- a/Engine/source/T3D/assets/LevelAsset.cpp +++ b/Engine/source/T3D/assets/LevelAsset.cpp @@ -186,6 +186,13 @@ void LevelAsset::loadAsset() { // Ensure the image-file is expanded. mLevelPath = getOwned() ? expandAssetFilePath(mLevelFile) : mLevelPath; + + if (mLevelPath == StringTable->EmptyString()) + { + mLoadedState = AssetErrCode::BadFileReference; + return; + } + mPostFXPresetPath = getOwned() ? expandAssetFilePath(mPostFXPresetFile) : mPostFXPresetPath; mDecalsPath = getOwned() ? expandAssetFilePath(mDecalsFile) : mDecalsPath; mForestPath = getOwned() ? expandAssetFilePath(mForestFile) : mForestPath; @@ -198,6 +205,8 @@ void LevelAsset::loadAsset() mPreviewImageAssetId = previewImageAssetId; mPreviewImageAsset = mPreviewImageAssetId; } + + mLoadedState = AssetErrCode::Ok; } // @@ -248,7 +257,7 @@ void LevelAsset::setEditorFile(const char* pEditorFile) return; // Update. - mEditorFile = getOwned() ? expandAssetFilePath(pEditorFile) : pEditorFile; + mEditorFile = pEditorFile; // Refresh the asset. refreshAsset(); @@ -267,7 +276,7 @@ void LevelAsset::setBakedSceneFile(const char* pBakedSceneFile) return; // Update. - mBakedSceneFile = getOwned() ? expandAssetFilePath(pBakedSceneFile) : pBakedSceneFile; + mBakedSceneFile = pBakedSceneFile; // Refresh the asset. refreshAsset(); @@ -286,7 +295,7 @@ void LevelAsset::setPostFXPresetFile(const char* pPostFXPresetFile) return; // Update. - mPostFXPresetFile = getOwned() ? expandAssetFilePath(pPostFXPresetFile) : pPostFXPresetFile; + mPostFXPresetFile = pPostFXPresetFile; // Refresh the asset. refreshAsset(); @@ -305,7 +314,7 @@ void LevelAsset::setDecalsFile(const char* pDecalsFile) return; // Update. - mDecalsFile = getOwned() ? expandAssetFilePath(pDecalsFile) : pDecalsFile; + mDecalsFile = pDecalsFile; // Refresh the asset. refreshAsset(); @@ -324,7 +333,7 @@ void LevelAsset::setForestFile(const char* pForestFile) return; // Update. - mForestFile = getOwned() ? expandAssetFilePath(pForestFile) : pForestFile; + mForestFile = pForestFile; // Refresh the asset. refreshAsset(); @@ -343,7 +352,7 @@ void LevelAsset::setNavmeshFile(const char* pNavmeshFile) return; // Update. - mNavmeshFile = getOwned() ? expandAssetFilePath(pNavmeshFile) : pNavmeshFile; + mNavmeshFile = pNavmeshFile; // Refresh the asset. refreshAsset(); @@ -398,35 +407,88 @@ DefineEngineMethod(LevelAsset, getPreviewImagePath, const char*, (), , "Gets the full path of the asset's defined preview image file.\n" "@return The string result of the level preview image path") { - return object->getPreviewImagePath(); + String previewPath = object->getPreviewImagePath(); + if (previewPath.isEmpty() || !Torque::FS::IsFile(previewPath)) + { + Torque::Path levelPath = object->getLevelPath(); + previewPath = String(levelPath.getPath() + "/" + levelPath.getFileName()) + ".png"; + } + + char* returnBuffer = Con::getReturnBuffer(previewPath.size()); + dSprintf(returnBuffer, 256, "%s", previewPath.c_str()); + + return returnBuffer; } DefineEngineMethod(LevelAsset, getPostFXPresetPath, const char*, (), , "Gets the full path of the asset's defined postFX preset file.\n" "@return The string result of the postFX preset path") { - return object->getPostFXPresetPath(); + String pfxPath = object->getPostFXPresetPath(); + if (pfxPath.isEmpty() || !Torque::FS::IsFile(pfxPath)) + { + Torque::Path levelPath = object->getLevelPath(); + pfxPath = String(levelPath.getPath() + "/" + levelPath.getFileName()) + ".postfxpreset.tscript"; + } + + char* returnBuffer = Con::getReturnBuffer(pfxPath.size()); + dSprintf(returnBuffer, 256, "%s", pfxPath.c_str()); + + return returnBuffer; } DefineEngineMethod(LevelAsset, getDecalsPath, const char*, (), , "Gets the full path of the asset's defined decal file.\n" "@return The string result of the decal path") { - return object->getDecalsPath(); + String decalPath = object->getDecalsPath(); + if (decalPath.isEmpty() || !Torque::FS::IsFile(decalPath)) + { + Torque::Path levelPath = object->getLevelPath(); + decalPath = String(levelPath.getPath() + levelPath.getFileName()) + ".decals"; + + if (!Torque::FS::IsFile(decalPath)) //Legacy pattern support if it kept the '.mis' sub extension in there + decalPath = String(levelPath.getFullPath()) + ".decals"; + } + + char* returnBuffer = Con::getReturnBuffer(decalPath.size()); + dSprintf(returnBuffer, 256, "%s", decalPath.c_str()); + + return returnBuffer; } DefineEngineMethod(LevelAsset, getForestPath, const char*, (), , "Gets the full path of the asset's defined forest file.\n" "@return The string result of the forest path") { - return object->getForestPath(); + String forestPath = object->getForestPath(); + if (forestPath.isEmpty() || !Torque::FS::IsFile(forestPath)) + { + Torque::Path levelPath = object->getLevelPath(); + forestPath = String(levelPath.getPath() + "/" + levelPath.getFileName()) + ".forest"; + } + + char* returnBuffer = Con::getReturnBuffer(forestPath.size()); + dSprintf(returnBuffer, 256, "%s", forestPath.c_str()); + + return returnBuffer; } DefineEngineMethod(LevelAsset, getNavmeshPath, const char*, (), , "Gets the full path of the asset's defined navmesh file.\n" "@return The string result of the navmesh path") { - return object->getNavmeshPath(); + String navPath = object->getNavmeshPath(); + if (navPath.isEmpty() || !Torque::FS::IsFile(navPath)) + { + Torque::Path levelPath = object->getLevelPath(); + navPath = String(levelPath.getPath() + "/" + levelPath.getFileName()) + ".nav"; + } + + char* returnBuffer = Con::getReturnBuffer(navPath.size()); + dSprintf(returnBuffer, 256, "%s", navPath.c_str()); + + return returnBuffer; } DefineEngineMethod(LevelAsset, loadDependencies, void, (), , diff --git a/Engine/source/T3D/decal/decalManager.cpp b/Engine/source/T3D/decal/decalManager.cpp index 7a21cd5e0..4a2ad8c35 100644 --- a/Engine/source/T3D/decal/decalManager.cpp +++ b/Engine/source/T3D/decal/decalManager.cpp @@ -1457,7 +1457,7 @@ bool DecalManager::_createDataFile() if(dot) *dot = '\0'; - dSprintf( fileName, sizeof(fileName), "%s.mis.decals", missionName ); + dSprintf( fileName, sizeof(fileName), "%s.decals", missionName ); mDataFileName = StringTable->insert( fileName ); @@ -1572,8 +1572,8 @@ DefineEngineFunction( decalManagerSave, void, ( String decalSaveFile ), ( "" ), "@param decalSaveFile Filename to save the decals to.\n" "@tsexample\n" "// Set the filename to save the decals in. If no filename is set, then the\n" - "// decals will default to .mis.decals\n" - "%fileName = \"./missionDecals.mis.decals\";\n" + "// decals will default to .decals\n" + "%fileName = \"./missionDecals.decals\";\n" "// Inform the decal manager to save the decals for the active mission.\n" "decalManagerSave( %fileName );\n" "@endtsexample\n" @@ -1603,7 +1603,7 @@ DefineEngineFunction( decalManagerLoad, bool, ( const char* fileName ),, "false if it could not.\n" "@tsexample\n" "// Set the filename to load the decals from.\n" - "%fileName = \"./missionDecals.mis.decals\";\n" + "%fileName = \"./missionDecals.decals\";\n" "// Inform the decal manager to load the decals from the entered filename.\n" "decalManagerLoad( %fileName );\n" "@endtsexample\n" diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript index 89ff5992a..29e3ad3e4 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript @@ -29,7 +29,7 @@ function LevelAsset::onCreateNew(%this) AssetName = %assetName; versionId = 1; LevelFile = %assetName @ %misExtension; - DecalsFile = %assetName @ ".mis.decals"; + DecalsFile = %assetName @ ".decals"; PostFXPresetFile = %assetName @ ".postfxpreset." @ $TorqueScriptFileExtension; ForestFile = %assetName @ ".forest"; NavmeshFile = %assetName @ ".nav"; diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index 4e993cb4a..4c51a5f99 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -2004,6 +2004,10 @@ function beginLevelImport() { %asset.decalsFile = %fileBase @ ".decal"; } + else if(isFile(%filePath @ "/" @ %fileBase @ "decal")) + { + %asset.decalsFile = %fileBase @ "decal"; + } else if(isFile(%filePath @ "/" @ %fileBase @ "mis.decal")) { %asset.decalsFile = %fileBase @ "mis.decal"; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript index 8b0dddd22..a791a98b3 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript @@ -361,20 +361,36 @@ function EditorSaveMission() %obj.onSaveMission( $Server::MissionFile ); } - //We'll sanity check that we have a valid file association to our level asset first + //Force a refresh of the associated paths if they're valid files when we save out the assetDef %presetFile = $Server::LevelAsset.getPostFXPresetPath(); - - if(!isFile(%presetFile)) + if(isFile(%presetFile)) { - //if it isn't valid, we'll fabricate a new one just to be sure - $Server::LevelAsset.PostFXPresetFile = fileBase($Server::LevelAsset.getLevelPath()) @ $PostFXManager::fileExtension; - - $Server::LevelAsset.saveAsset(); - $Server::LevelAsset.refresh(); - - %presetFile = $Server::LevelAsset.getPostFXPresetPath(); + $Server::LevelAsset.postFXPresetFile = fileName(%presetFile); } + %decalsFile = $Server::LevelAsset.getDecalsPath(); + if(isFile(%decalsFile)) + { + echo("==================================================================="); + echo("DECALS FILE BE: " @ fileName(%decalsFile)); + $Server::LevelAsset.decalsFile = fileName(%decalsFile); + } + + %forestFile = $Server::LevelAsset.getForestPath(); + if(isFile(%forestFile)) + { + $Server::LevelAsset.forestFile = fileName(%forestFile); + } + + %navMeshFile = $Server::LevelAsset.getNavmeshPath(); + if(isFile(%navMeshFile)) + { + $Server::LevelAsset.navmeshFile = fileName(%navMeshFile); + } + + $Server::LevelAsset.saveAsset(); + $Server::LevelAsset.refresh(); + //Save out the PostFX config PostFXManager::savePresetHandler( %presetFile ); From e12f8472cddca9375e8f83a77664ddd9332569b8 Mon Sep 17 00:00:00 2001 From: JeffR Date: Tue, 21 Apr 2026 01:28:23 -0500 Subject: [PATCH 7/7] Removed unnecessary debug lines --- .../game/tools/worldEditor/scripts/menuHandlers.ed.tscript | 2 -- 1 file changed, 2 deletions(-) diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript index a791a98b3..88d7ad3b4 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript @@ -371,8 +371,6 @@ function EditorSaveMission() %decalsFile = $Server::LevelAsset.getDecalsPath(); if(isFile(%decalsFile)) { - echo("==================================================================="); - echo("DECALS FILE BE: " @ fileName(%decalsFile)); $Server::LevelAsset.decalsFile = fileName(%decalsFile); }