ScummVM API documentation
miniscript.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef MTROPOLIS_MINISCRIPT_H
23 #define MTROPOLIS_MINISCRIPT_H
24 
25 #include "mtropolis/data.h"
26 #include "mtropolis/runtime.h"
27 
28 namespace MTropolis {
29 
30 class MiniscriptThread;
31 struct MiniscriptStackValue;
32 struct SIMiniscriptInstructionFactory;
33 
34 bool miniscriptEvaluateTruth(const DynamicValue &value);
35 
37 public:
38  virtual ~MiniscriptInstruction();
39 
40  virtual MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const = 0;
41 };
42 
44 public:
46 
47  virtual uint registerGlobalGUIDIndex(uint32 guid) = 0;
48 };
49 
51 public:
52  struct LocalRef {
53  LocalRef();
54 
55  uint32 guid;
56  Common::String name;
58  };
59 
60  struct GlobalRef {
61  GlobalRef();
62 
63  uint32 guid;
65  };
66 
67  explicit MiniscriptReferences(const Common::Array<LocalRef> &localRefs, const Common::Array<GlobalRef> &globalRefs);
68 
69  void linkInternalReferences(ObjectLinkingScope *scope);
70  void visitInternalReferences(IStructuralReferenceVisitor *visitor);
71 
72  Common::WeakPtr<RuntimeObject> getRefByIndex(uint index) const;
73  Common::WeakPtr<RuntimeObject> getGlobalRefByIndex(uint index) const;
74 
75 private:
76  Common::Array<LocalRef> _localRefs;
77  Common::Array<GlobalRef> _globalRefs;
78 
79 };
80 
82 public:
83 
84  struct Attribute {
85  Common::String name;
86  };
87 
90 
91  const Common::Array<MiniscriptInstruction *> &getInstructions() const;
92  const Common::Array<Attribute> &getAttributes() const;
93 
94 private:
97  Common::Array<Attribute> _attributes;
98 };
99 
101 public:
102  static bool parse(const Data::MiniscriptProgram &programData, Common::SharedPtr<MiniscriptProgram> &outProgram, Common::SharedPtr<MiniscriptReferences> &outReferences);
103 
104  static SIMiniscriptInstructionFactory *resolveOpcode(uint16 opcode);
105 
106 private:
107  struct InstructionData {
108  InstructionData();
109 
110  uint16 opcode;
111  uint16 flags;
112  size_t pdPosition;
113  SIMiniscriptInstructionFactory *instrFactory;
114  Common::Array<uint8> contents;
115  };
116 };
117 
118 namespace MiniscriptInstructions {
120  private:
121  virtual MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
122  };
123 
124  class Set : public MiniscriptInstruction {
125  private:
126  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
127  };
128 
129  class Send : public MiniscriptInstruction {
130  public:
131  explicit Send(const Event &evt, const MessageFlags &messageFlags);
132 
133  private:
134  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
135 
136  Event _evt;
137  MessageFlags _messageFlags;
138  };
139 
141  private:
142  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
143 
144  protected:
145  virtual MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const = 0;
146  };
147 
148  class Add : public BinaryArithInstruction {
149  private:
150  MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
151  };
152 
153  class Sub : public BinaryArithInstruction {
154  private:
155  MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
156  };
157 
158  class Mul : public BinaryArithInstruction {
159  private:
160  MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
161  };
162 
163  class Div : public BinaryArithInstruction {
164  private:
165  MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
166  };
167 
168  class Pow : public BinaryArithInstruction {
169  private:
170  MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
171  };
172 
174  private:
175  MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
176  };
177 
179  private:
180  MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
181  };
182 
183  class And : public MiniscriptInstruction {
184  private:
185  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
186  };
187 
188  class Or : public MiniscriptInstruction {
189  private:
190  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
191  };
192 
193  class Neg : public MiniscriptInstruction {
194  private:
195  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
196  };
197 
198  class Not : public MiniscriptInstruction {
199  private:
200  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
201  };
202 
204  protected:
205  virtual bool compareFloat(double a, double b) const = 0;
206 
207  private:
208  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
209  };
210 
212  protected:
213  virtual bool resolve(bool isEqual) const = 0;
214 
215  private:
216  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
217  };
218 
220  private:
221  bool resolve(bool isEqual) const override { return isEqual; };
222  };
223 
225  private:
226  bool resolve(bool isEqual) const override { return !isEqual; };
227  };
228 
230  private:
231  bool compareFloat(double a, double b) const override { return a <= b; }
232  };
233 
235  private:
236  bool compareFloat(double a, double b) const override { return a < b; }
237  };
238 
240  private:
241  bool compareFloat(double a, double b) const override { return a >= b; }
242  };
243 
245  private:
246  bool compareFloat(double a, double b) const override { return a > b; }
247  };
248 
250  public:
251  enum BuiltinFunctionID {
252  kSin = 1,
253  kCos = 2,
254  kRandom = 3,
255  kSqrt = 4,
256  kTan = 5,
257  kAbs = 6,
258  kSign = 7,
259  kArctangent = 8,
260  kExp = 9,
261  kLn = 10,
262  kLog = 11,
263  kCosH = 12,
264  kSinH = 13,
265  kTanH = 14,
266  kRect2Polar = 15,
267  kPolar2Rect = 16,
268  kTrunc = 17,
269  kRound = 18,
270  kNum2Str = 19,
271  kStr2Num = 20,
272  };
273 
274  explicit BuiltinFunc(BuiltinFunctionID bfid);
275 
276  private:
277  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
278 
279  MiniscriptInstructionOutcome executeFunction(MiniscriptThread *thread, DynamicValue *returnValue) const;
280  MiniscriptInstructionOutcome executeSimpleNumericInstruction(MiniscriptThread *thread, DynamicValue *returnValue) const;
281  MiniscriptInstructionOutcome executeRectToPolar(MiniscriptThread *thread, DynamicValue *returnValue) const;
282  MiniscriptInstructionOutcome executePolarToRect(MiniscriptThread *thread, DynamicValue *returnValue) const;
283  MiniscriptInstructionOutcome executeNum2Str(MiniscriptThread *thread, DynamicValue *returnValue) const;
284  MiniscriptInstructionOutcome executeStr2Num(MiniscriptThread *thread, DynamicValue *returnValue) const;
285 
286  BuiltinFunctionID _funcID;
287  };
288 
290  private:
291  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
292  };
293 
295  private:
296  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
297  };
298 
300  private:
301  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
302  };
303 
305  };
306 
308  public:
309  GetChild(uint32 attribute, bool isLValue, bool isIndexed);
310 
311  private:
312  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
313  MiniscriptInstructionOutcome readRValueAttrib(MiniscriptThread *thread, DynamicValue &valueSrcDest, const Common::String &attrib) const;
314  MiniscriptInstructionOutcome readRValueAttribIndexed(MiniscriptThread *thread, DynamicValue &valueSrcDest, const Common::String &attrib, const DynamicValue &index) const;
315 
316  uint32 _attribute;
317  bool _isLValue;
318  bool _isIndexed;
319  };
320 
322  private:
323  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
324  };
325 
327  private:
328  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
329  };
330 
332  public:
333  enum DataType {
334  kDataTypeNull,
335  kDataTypeDouble,
336  kDataTypeBool,
337  kDataTypeLocalRef,
338  kDataTypeGlobalRef,
339  kDataTypeLabel,
340  };
341 
342  struct Label {
343  uint32 superGroup;
344  uint32 id;
345  };
346 
347  PushValue(DataType dataType, const void *value, bool isLValue);
348  ~PushValue();
349 
350  private:
351  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
352 
353  union ValueUnion {
354  ValueUnion();
355 
356  bool b;
357  double f;
358  uint32 ref;
359  Label lbl;
360  };
361 
362  DataType _dataType;
363  ValueUnion _value;
364  //bool _isLValue;
365  };
366 
368  public:
369  explicit PushGlobal(uint32 globalID, bool isLValue);
370 
371  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
372 
373  private:
374  enum {
375  kGlobalRefElement = 1,
376  kGlobalRefModifier = 2,
377  kGlobalRefSource = 3,
378  kGlobalRefIncomingData = 4,
379  kGlobalRefMouse = 5,
380  kGlobalRefTicks = 6,
381  kGlobalRefScene = 7,
382  kGlobalRefSharedScene = 8,
383  kGlobalRefSection = 9,
384  kGlobalRefProject = 10,
385  kGlobalRefActiveScene = 11,
386  };
387 
388  MiniscriptInstructionOutcome executeFindFilteredParent(MiniscriptThread *thread, DynamicValue &result) const;
389 
390  uint32 _globalID;
391  bool _isLValue;
392  };
393 
395  public:
396  explicit PushString(const Common::String &str);
397 
398  private:
399  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
400 
401  Common::String _str;
402  };
403 
404  class Jump : public MiniscriptInstruction {
405  public:
406  Jump(uint32 instrOffset, bool isConditional);
407 
408  private:
409  MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
410 
411  uint32 _instrOffset;
412  bool _isConditional;
413  };
414 } // End of namespace MiniscriptInstructions
415 
416 
418  DynamicValue value;
419 };
420 
422 public:
424 
425  void error(const Common::String &message);
426 
427  const Common::SharedPtr<MiniscriptProgram> &getProgram() const;
428  const Common::SharedPtr<MiniscriptReferences> &getRefs() const;
429  Modifier *getModifier() const;
430  const Common::SharedPtr<MessageProperties> &getMessageProperties() const;
431  Runtime *getRuntime() const;
432 
433  void pushValue(const DynamicValue &value);
434  void popValues(size_t count);
435  size_t getStackSize() const;
436  MiniscriptStackValue &getStackValueFromTop(size_t offset);
437  MiniscriptInstructionOutcome dereferenceRValue(size_t offset);
438 
439  void jumpOffset(size_t offset);
440 
441  bool evaluateTruthOfResult(bool &isTrue);
442 
443  void createWriteIncomingDataProxy(DynamicValueWriteProxy &proxy);
444 
445  void retryInstruction();
446 
448  CORO_DEFINE_RETURN_TYPE(void);
449  CORO_DEFINE_PARAMS_1(Common::SharedPtr<MiniscriptThread>, thread);
450  };
451 
452 private:
453  struct IncomingDataWriteInterface {
454  static MiniscriptInstructionOutcome write(MiniscriptThread *thread, const DynamicValue &dest, void *objectRef, uintptr ptrOrOffset);
455  static MiniscriptInstructionOutcome refAttrib(MiniscriptThread *thread, DynamicValueWriteProxy &proxy, void *objectRef, uintptr ptrOrOffset, const Common::String &attrib);
456  static MiniscriptInstructionOutcome refAttribIndexed(MiniscriptThread *thread, DynamicValueWriteProxy &proxy, void *objectRef, uintptr ptrOrOffset, const Common::String &attrib, const DynamicValue &index);
457  };
458 
459  MiniscriptInstructionOutcome runNextInstruction();
460 
461  VThreadState resume(MiniscriptThread *thread);
462 
463  MiniscriptInstructionOutcome tryLoadVariable(MiniscriptStackValue &stackValue);
464 
468 
469  Modifier *_modifier;
470  Runtime *_runtime;
472 
473  size_t _currentInstruction;
474  bool _failed;
475 };
476 
477 MiniscriptInstructionOutcome miniscriptIgnoreFailure(MiniscriptInstructionOutcome outcome);
478 
479 } // End of namespace MTropolis
480 
481 #endif
Definition: runtime.h:816
Definition: miniscript.h:81
Definition: str.h:59
Definition: miniscript.h:178
Definition: miniscript.h:198
Definition: ptr.h:115
Definition: array.h:52
Definition: miniscript.h:183
Definition: miniscript.h:173
Definition: miniscript.h:158
Definition: miniscript.h:404
Definition: runtime.h:1575
Definition: runtime.h:488
Definition: data.h:1033
Definition: miniscript.h:153
Definition: runtime.h:3035
Definition: miniscript.h:193
Definition: miniscript.h:421
Definition: runtime.h:544
Definition: miniscript.h:163
Definition: miniscript.h:234
Definition: runtime.h:369
Definition: runtime.h:1307
Definition: runtime.h:2118
Definition: miniscript.h:148
Definition: miniscript.h:50
Definition: miniscript.h:168
Definition: miniscript.h:417
Definition: miniscript.h:84
Definition: miniscript.h:100
Definition: miniscript.h:188
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: miniscript.h:129
Definition: actions.h:25
Definition: miniscript.h:36
Definition: ptr.h:159
Definition: miniscript.h:124