compiledEval.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "console/console.h"
  24. #include "console/ast.h"
  25. #include "core/tAlgorithm.h"
  26. #include "core/strings/findMatch.h"
  27. #include "core/strings/stringUnit.h"
  28. #include "console/consoleInternal.h"
  29. #include "core/stream/fileStream.h"
  30. #include "console/compiler.h"
  31. #include "console/simBase.h"
  32. #include "console/telnetDebugger.h"
  33. #include "sim/netStringTable.h"
  34. #include "console/ICallMethod.h"
  35. #include "console/stringStack.h"
  36. #include "util/messaging/message.h"
  37. #include "core/frameAllocator.h"
  38. #include "console/codeInterpreter.h"
  39. #include "console/returnBuffer.h"
  40. #ifndef TORQUE_TGB_ONLY
  41. #include "materials/materialDefinition.h"
  42. #include "materials/materialManager.h"
  43. #endif
  44. using namespace Compiler;
  45. namespace Con
  46. {
  47. // Current script file name and root, these are registered as
  48. // console variables.
  49. extern StringTableEntry gCurrentFile;
  50. extern StringTableEntry gCurrentRoot;
  51. extern S32 gObjectCopyFailures;
  52. }
  53. namespace Con
  54. {
  55. const char *getNamespaceList(Namespace *ns)
  56. {
  57. U32 size = 1;
  58. Namespace * walk;
  59. for (walk = ns; walk; walk = walk->mParent)
  60. size += dStrlen(walk->mName) + 4;
  61. char *ret = Con::getReturnBuffer(size);
  62. ret[0] = 0;
  63. for (walk = ns; walk; walk = walk->mParent)
  64. {
  65. dStrcat(ret, walk->mName, size);
  66. if (walk->mParent)
  67. dStrcat(ret, " -> ", size);
  68. }
  69. return ret;
  70. }
  71. }
  72. //------------------------------------------------------------
  73. F64 consoleStringToNumber(const char *str, StringTableEntry file, U32 line)
  74. {
  75. F64 val = dAtof(str);
  76. if (val != 0)
  77. return val;
  78. else if (!dStricmp(str, "true"))
  79. return 1;
  80. else if (!dStricmp(str, "false"))
  81. return 0;
  82. else if (file)
  83. {
  84. Con::warnf(ConsoleLogEntry::General, "%s (%d): string always evaluates to 0.", file, line);
  85. return 0;
  86. }
  87. return 0;
  88. }
  89. //------------------------------------------------------------
  90. namespace Con
  91. {
  92. ReturnBuffer retBuffer;
  93. char *getReturnBuffer(U32 bufferSize)
  94. {
  95. return retBuffer.getBuffer(bufferSize);
  96. }
  97. char *getReturnBuffer(const char *stringToCopy)
  98. {
  99. U32 len = dStrlen(stringToCopy) + 1;
  100. char *ret = retBuffer.getBuffer(len);
  101. dMemcpy(ret, stringToCopy, len);
  102. return ret;
  103. }
  104. char* getReturnBuffer(const String& str)
  105. {
  106. const U32 size = str.size();
  107. char* ret = retBuffer.getBuffer(size);
  108. dMemcpy(ret, str.c_str(), size);
  109. return ret;
  110. }
  111. char* getReturnBuffer(const StringBuilder& str)
  112. {
  113. char* buffer = Con::getReturnBuffer(str.length() + 1);
  114. str.copy(buffer);
  115. buffer[str.length()] = '\0';
  116. return buffer;
  117. }
  118. char *getArgBuffer(U32 bufferSize)
  119. {
  120. return STR.getArgBuffer(bufferSize);
  121. }
  122. char *getFloatArg(F64 arg)
  123. {
  124. char *ret = STR.getArgBuffer(32);
  125. dSprintf(ret, 32, "%g", arg);
  126. return ret;
  127. }
  128. char *getIntArg(S32 arg)
  129. {
  130. char *ret = STR.getArgBuffer(32);
  131. dSprintf(ret, 32, "%d", arg);
  132. return ret;
  133. }
  134. char* getBoolArg(bool arg)
  135. {
  136. char *ret = STR.getArgBuffer(32);
  137. dSprintf(ret, 32, "%d", arg);
  138. return ret;
  139. }
  140. char *getStringArg(const char *arg)
  141. {
  142. U32 len = dStrlen(arg) + 1;
  143. char *ret = STR.getArgBuffer(len);
  144. dMemcpy(ret, arg, len);
  145. return ret;
  146. }
  147. char* getStringArg(const String& arg)
  148. {
  149. const U32 size = arg.size();
  150. char* ret = STR.getArgBuffer(size);
  151. dMemcpy(ret, arg.c_str(), size);
  152. return ret;
  153. }
  154. }
  155. //------------------------------------------------------------
  156. void ExprEvalState::setCurVarName(StringTableEntry name)
  157. {
  158. if (name[0] == '$')
  159. currentVariable = globalVars.lookup(name);
  160. else if (getStackDepth() > 0)
  161. currentVariable = getCurrentFrame().lookup(name);
  162. if (!currentVariable && gWarnUndefinedScriptVariables)
  163. Con::warnf(ConsoleLogEntry::Script, "Variable referenced before assignment: %s", name);
  164. }
  165. void ExprEvalState::setCurVarNameCreate(StringTableEntry name)
  166. {
  167. if (name[0] == '$')
  168. currentVariable = globalVars.add(name);
  169. else if (getStackDepth() > 0)
  170. currentVariable = getCurrentFrame().add(name);
  171. else
  172. {
  173. currentVariable = NULL;
  174. Con::warnf(ConsoleLogEntry::Script, "Accessing local variable in global scope... failed: %s", name);
  175. }
  176. }
  177. //------------------------------------------------------------
  178. S32 ExprEvalState::getIntVariable()
  179. {
  180. return currentVariable ? currentVariable->getIntValue() : 0;
  181. }
  182. F64 ExprEvalState::getFloatVariable()
  183. {
  184. return currentVariable ? currentVariable->getFloatValue() : 0;
  185. }
  186. const char *ExprEvalState::getStringVariable()
  187. {
  188. return currentVariable ? currentVariable->getStringValue() : "";
  189. }
  190. //------------------------------------------------------------
  191. void ExprEvalState::setIntVariable(S32 val)
  192. {
  193. AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!");
  194. currentVariable->setIntValue(val);
  195. }
  196. void ExprEvalState::setFloatVariable(F64 val)
  197. {
  198. AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!");
  199. currentVariable->setFloatValue(val);
  200. }
  201. void ExprEvalState::setStringVariable(const char *val)
  202. {
  203. AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!");
  204. currentVariable->setStringValue(val);
  205. }
  206. void ExprEvalState::setStringStackPtrVariable(StringStackPtr str)
  207. {
  208. AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!");
  209. currentVariable->setStringStackPtrValue(str);
  210. }
  211. void ExprEvalState::setCopyVariable()
  212. {
  213. if (copyVariable)
  214. {
  215. switch (copyVariable->value.type)
  216. {
  217. case ConsoleValue::TypeInternalInt:
  218. currentVariable->setIntValue(copyVariable->getIntValue());
  219. break;
  220. case ConsoleValue::TypeInternalFloat:
  221. currentVariable->setFloatValue(copyVariable->getFloatValue());
  222. break;
  223. default:
  224. currentVariable->setStringValue(copyVariable->getStringValue());
  225. break;
  226. }
  227. }
  228. }
  229. //------------------------------------------------------------
  230. ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
  231. {
  232. CodeInterpreter interpreter(this);
  233. return interpreter.exec(ip, functionName, thisNamespace, argc, argv, noCalls, packageName, setFrame);
  234. }
  235. //------------------------------------------------------------