1 /* 2 * OpenClonk, http://www.openclonk.org 3 * 4 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ 5 * Copyright (c) 2009-2016, The OpenClonk Team and contributors 6 * 7 * Distributed under the terms of the ISC license; see accompanying file 8 * "COPYING" for details. 9 * 10 * "Clonk" is a registered trademark of Matthes Bender, used with permission. 11 * See accompanying file "TRADEMARK" for details. 12 * 13 * To redistribute this file separately, substitute the full license texts 14 * for the above references. 15 */ 16 17 #ifndef INC_C4Aul 18 #define INC_C4Aul 19 20 #include "object/C4Id.h" 21 #include "script/C4StringTable.h" 22 #include "script/C4Value.h" 23 #include "script/C4ValueMap.h" 24 25 // consts 26 #define C4AUL_MAX_Identifier 100 // max length of function identifiers 27 28 // warning flags 29 enum class C4AulWarningId 30 { 31 #define DIAG(id, text, enabled) id, 32 #include "C4AulWarnings.h" 33 #undef DIAG 34 WarningCount 35 }; 36 37 extern const char *C4AulWarningIDs[]; 38 extern const char *C4AulWarningMessages[]; 39 40 // generic C4Aul error class 41 class C4AulError : public std::exception 42 { 43 protected: 44 StdCopyStrBuf sMessage; 45 46 public: 47 ~C4AulError() override = default; // destructor 48 const char *what() const noexcept override; 49 }; 50 51 // parse error 52 class C4AulParseError : public C4AulError 53 { 54 C4AulParseError() = default; 55 public: 56 C4AulParseError(C4ScriptHost *pScript, const char *pMsg); // constructor 57 C4AulParseError(class C4AulParse * state, const char *pMsg); // constructor 58 C4AulParseError(C4AulScriptFunc * Fn, const char *SPos, const char *pMsg); 59 }; 60 61 // execution error 62 class C4AulExecError : public C4AulError 63 { 64 public: 65 C4AulExecError(const char *szError); 66 }; 67 68 class C4AulFuncMap 69 { 70 public: 71 C4AulFuncMap(); 72 ~C4AulFuncMap(); 73 C4AulFunc * GetFirstFunc(const char * Name); 74 C4AulFunc * GetNextSNFunc(const C4AulFunc * After); 75 private: 76 enum { HashSize = 1025 }; 77 C4AulFunc * Funcs[HashSize]; 78 int FuncCnt{0}; 79 static unsigned int Hash(const char * Name); 80 protected: 81 void Add(C4AulFunc * func); 82 void Remove(C4AulFunc * func); 83 friend class C4AulFunc; 84 friend class C4ScriptHost; 85 }; 86 87 // user text file to which scripts can write using FileWrite(). 88 // actually just writes to an internal buffer 89 class C4AulUserFile 90 { 91 StdCopyStrBuf sContents; 92 int32_t handle; 93 94 public: C4AulUserFile(int32_t handle)95 C4AulUserFile(int32_t handle) : handle(handle) {} Write(const char * data,size_t data_length)96 void Write(const char *data, size_t data_length) { sContents.Append(data, data_length); } 97 GetFileContents()98 const char *GetFileContents() { return sContents.getData(); } GrabFileContents()99 StdStrBuf GrabFileContents() { StdStrBuf r; r.Take(sContents); return r; } GetFileLength()100 size_t GetFileLength() { return sContents.getLength(); } GetHandle()101 int32_t GetHandle() const { return handle; } 102 }; 103 104 class C4AulErrorHandler 105 { 106 public: 107 virtual ~C4AulErrorHandler(); 108 virtual void OnError(const char *msg) = 0; 109 virtual void OnWarning(const char *msg) = 0; 110 }; 111 112 // holds all C4AulScripts 113 class C4AulScriptEngine: public C4PropListStaticMember 114 { 115 protected: 116 C4AulFuncMap FuncLookUp; GetFirstFunc(const char * Name)117 C4AulFunc * GetFirstFunc(const char * Name) 118 { return FuncLookUp.GetFirstFunc(Name); } GetNextSNFunc(const C4AulFunc * After)119 C4AulFunc * GetNextSNFunc(const C4AulFunc * After) 120 { return FuncLookUp.GetNextSNFunc(After); } 121 C4ScriptHost *Child0, *ChildL; // tree structure 122 123 // all open user files 124 // user files aren't saved - they are just open temporary e.g. during game saving 125 std::list<C4AulUserFile> UserFiles; 126 std::vector<C4Value> OwnedPropLists; 127 128 C4AulErrorHandler *ErrorHandler; 129 130 public: 131 int warnCnt{0}, errCnt{0}; // number of warnings/errors 132 int lineCnt{0}; // line count parsed 133 134 C4ValueMapNames GlobalNamedNames; 135 C4ValueMapData GlobalNamed; 136 137 // global constants (such as "static const C4D_Structure = 2;") 138 // cannot share var lists, because it's so closely tied to the data lists 139 // constants are used by the Parser only, anyway, so it's not 140 // necessary to pollute the global var list here 141 C4ValueMapNames GlobalConstNames; 142 C4ValueMapData GlobalConsts; 143 144 C4Effect * pGlobalEffects = nullptr; 145 146 C4AulScriptEngine(); // constructor 147 ~C4AulScriptEngine() override; // destructor 148 void Clear(); // clear data 149 void Link(C4DefList *rDefs); // link and parse all scripts 150 void ReLink(C4DefList *rDefs); // unlink, link and parse all scripts GetPropList()151 C4PropListStatic * GetPropList() { return this; } 152 bool ReloadScript(const char *szScript, const char *szLanguage); // search script and reload, if found 153 154 // For the list of functions in the PropertyDlg 155 std::list<const char*> GetFunctionNames(C4PropList *); 156 157 void RegisterGlobalConstant(const char *szName, const C4Value &rValue); // creates a new constants or overwrites an old one 158 bool GetGlobalConstant(const char *szName, C4Value *pTargetValue); // check if a constant exists; assign value to pTargetValue if not nullptr 159 160 void Denumerate(C4ValueNumbers *) override; 161 void UnLink(); // called when a script is being reloaded (clears string table) 162 163 // Compile scenario script data (without strings and constants) 164 void CompileFunc(StdCompiler *pComp, bool fScenarioSection, C4ValueNumbers * numbers); 165 166 // Handle user files 167 int32_t CreateUserFile(); // create new file and return handle 168 void CloseUserFile(int32_t handle); // close user file given by handle 169 C4AulUserFile *GetUserFile(int32_t handle); // get user file given by handle 170 171 void RegisterErrorHandler(C4AulErrorHandler *handler); 172 void UnregisterErrorHandler(C4AulErrorHandler *handler); GetErrorHandler()173 C4AulErrorHandler *GetErrorHandler() const 174 { 175 return ErrorHandler; 176 } 177 178 friend class C4AulFunc; 179 friend class C4AulProfiler; 180 friend class C4ScriptHost; 181 friend class C4AulParse; 182 friend class C4AulCompiler; 183 friend class C4AulDebug; 184 }; 185 186 extern C4AulScriptEngine ScriptEngine; 187 void InitCoreFunctionMap(C4AulScriptEngine *pEngine); 188 189 #endif 190