Gorgon Game Engine
VirtualMachine.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <string>
5 #include <thread>
6 
7 #include "../Types.h"
8 #include "../Event.h"
9 #include "../Containers/Collection.h"
10 #include "../Containers/Hashmap.h"
11 
12 #include "Reflection.h"
13 #include "Runtime.h"
14 #include "Data.h"
15 #include "Exceptions.h"
16 #include "Instruction.h"
17 #include "Scope.h"
18 
19 
20 
21 namespace Gorgon {
22 
23  namespace Scripting {
24 
26  class Symbol {
27  public:
29  std::string namespc;
30 
32  SymbolType type;
33 
36 
37  // Name of the symbol is optimized out
38  // std::string name;
39  };
40 
42 
43 
46  public:
47 
49  explicit VirtualMachine(bool automaticreset=true, std::ostream &out=std::cout, std::istream &in=std::cin);
50 
52  }
53 
56  bool ExecuteStatement(const std::string &code, InputProvider::Dialect dialect = InputProvider::Programming);
57 
59  Data ExecuteFunction(const Function *fn, const std::vector<Data> &params, bool method);
60 
62  void Run();
63 
65  void Run(std::shared_ptr<ScopeInstance> scope);
66 
69  void Run(unsigned executiontarget);
70 
72  void Start(InputProvider &input);
73 
75  void Begin(InputProvider &input);
76 
79  void CompileCurrent();
80 
82  void AddLibrary(const Library &library);
83 
85  void RemoveLibrary(const Library &library);
86 
88  void UsingNamespace(const Namespace &name);
89 
91  void UsingNamespace(const std::string &name);
92 
94  void Jump(unsigned long line);
95 
98  void Jump(SourceMarker marker);
99 
102  void LongJump(SourceMarker marker);
103 
105  Data FindSymbol(const std::string &original, bool reference=false, bool allownull=false);
106 
107 
109  static VirtualMachine &Get() {
110  if(!activevms.Exists(std::this_thread::get_id())) {
111  throw std::runtime_error("No active VMs for this thread.");
112  }
113 
114  return activevms[std::this_thread::get_id()];
115  }
116 
118  static bool Exists() {
119  return activevms.Exists(std::this_thread::get_id());
120  }
121 
122  bool IsVariableSet(const std::string &name);
123 
124  Variable GetVariable(const std::string &name);
125 
126  void SetVariable(const std::string &name, Data data, bool ref=false);
127 
128  void UnsetVariable(const std::string &name);
129 
133 
137 
139  void SetOutput(std::ostream &out, bool deleteonchange=false);
140 
142  void SetInput(std::istream &in);
143 
145  std::ostream &GetOutput() const {
146  return *output;
147  }
148 
150  std::istream &GetInput() const {
151  return *input;
152  }
153 
155  void ResetOutput() {
156  if(deleteoutonchange) delete output;
157  deleteoutonchange=false;
158 
159  output=defoutput;
160  }
161 
163  void ResetInput() {
164  input=definput;
165  }
166 
169  void Activate() {
170  activevms.Add(std::this_thread::get_id(), this);
171  }
172 
175  unsigned GetScopeInstanceCount() const {
176  return (unsigned)scopeinstances.size();
177  }
178 
181  return *scopeinstances.back();
182  }
183 
186  return scopeinstances.front()->GetMarkerForNext();
187  }
188 
189 
192  return returnvalue;
193  }
194 
196  void Return(Data value=Data::Invalid()) {
197  if(scopeinstances.size()==0) {
198  throw std::runtime_error("No scope instance to return from.");
199  }
200  scopeinstances.back()->ReturnValue=value;
201  returnimmediately=true;
202  }
203 
207  void SetSpecialIdentifierHandler(std::function<Data(char,std::string)> handler) {
208  spechandler=handler;
209  }
210 
213  void Reset();
214 
216  Variable *getvarref(const std::string &var);
217 
220 
223 
224  private:
225  void execute(const Instruction* inst);
226  Data callfunction(const Function *fn, bool method, const std::vector<Value> &params);
227  Data callvariant(const Function *fn, const Function::Overload *variant, bool method, const std::vector<Value> &params);
228  Data getvalue(const Value &val, bool reference=false);
229  void functioncall(const Instruction *inst, bool memberonly, bool method);
230  void activatescopeinstance(std::shared_ptr<ScopeInstance> instance);
231  void addsymbol(const StaticMember &symbol);
232 
235 
236  std::string alllibnames;
237 
238  bool returnimmediately=false;
239 
240  //special identifier handler.
241  std::function<Data(char, std::string)> spechandler;
242 
243 
245  bool automaticreset;
246 
248  Data returnvalue=Data::Invalid();
249 
250  std::vector<std::shared_ptr<ScopeInstance>> scopeinstances;
252 
254  int highesttemp=0;
256  int tempbase = -1;
257 
258  std::ostream *output;
259  std::istream *input;
260 
261  std::ostream *defoutput;
262  std::istream *definput;
263 
264  bool deleteoutonchange=false;
265 
266  std::vector<Data> temporaries;
267 
268  std::shared_ptr<ScopeInstance> toplevel;
269 
270 
274  };
275 
276 
277  }
278 }
Gorgon::Scripting::VirtualMachine::FindSymbol
Data FindSymbol(const std::string &original, bool reference=false, bool allownull=false)
Finds the given symbol and resolves its value.
Definition: VirtualMachine.cpp:197
Gorgon::Scripting::Math
Library Math("Math", "Maths library.")
Definition: VirtualMachine.h:41
Gorgon::Scripting::VirtualMachine::Exists
static bool Exists()
Returns the current VM for this thread.
Definition: VirtualMachine.h:118
Scope.h
Gorgon::Scripting::VirtualMachine::GetScopeInstanceCount
unsigned GetScopeInstanceCount() const
Returns the number of active execution scopes.
Definition: VirtualMachine.h:175
Gorgon::Scripting::Type::ToString
virtual std::string ToString(const Data &) const =0
Converts a data of this type to string.
Gorgon::String::From
std::enable_if< decltype(gorgon__enum_tr_loc(T_()))::isupgradedenum, std::string >::type From(const T_ &e)
Definition: Enum.h:303
Gorgon::Scripting::VirtualMachine::Reset
void Reset()
Resets any runtime information that this VM has.
Gorgon::Resource::GID::Data
constexpr Type Data
Data resource.
Definition: GID.h:164
Gorgon::Scripting::InstructionType::FunctionCall
@ FunctionCall
Marks instruction as a regular function call.
Gorgon::Scripting::Type::InstanceMembers
const InstanceMemberList & InstanceMembers
Definition: Reflection.h:1410
Gorgon::Scripting::ScopeInstance
This is an instantiation of a scope.
Definition: Scope.h:223
Gorgon::Scripting::Value::SetLiteral
void SetLiteral(const Scripting::Type *type, Any value)
Definition: Instruction.h:95
Gorgon::Scripting::ReferenceCounter::Register
void Register(const Data &data)
Registers a new object of reference counting, this will set reference count to one.
Definition: Runtime.h:24
Gorgon::Scripting::VirtualMachine::LongJump
void LongJump(SourceMarker marker)
Changes current executing line.
Gorgon::Containers::Hashmap
This class is a reference based hashmap.
Definition: Hashmap.h:35
Gorgon::Scripting::ReferenceCounter
This class allows references to be counted and destroyed properly.
Definition: Runtime.h:19
Gorgon::Scripting::Data::ReferenceValue
std::enable_if< std::is_pointer< T_ >::value, T_ >::type ReferenceValue() const
Returns the value of this data in the requested format.
Definition: Data.h:112
Gorgon::Scripting::Scope
A new scope is created automatically when a new input source or a function like construct is created.
Definition: Scope.h:62
Gorgon::Any
This class can hold any other information providing type erasure.
Definition: Any.h:32
Gorgon::Scripting::VirtualMachine::References
ReferenceCounter References
This system allows objects of automatic lifetime.
Definition: VirtualMachine.h:222
Reflection.h
Gorgon::Scripting::Data::GetValue
std::enable_if<!std::is_pointer< T_ >::value, const typename std::remove_reference< T_ >::type & >::type GetValue() const
Returns the value of this data in the requested format.
Definition: Data.h:57
Gorgon::Scripting::Data
Data describes a piece of data.
Definition: Data.h:22
Gorgon::Graphics::Color::Black
constexpr RGBA Black
Definition: Color.h:653
Gorgon::Scripting::SourceMarker::GetSource
uintptr_t GetSource() const
Definition: Scope.h:44
Gorgon::Scripting::Type::InheritedSymbols
const Containers::Hashmap< std::string, const Type, nullptr, std::map, String::CaseInsensitiveLess > & InheritedSymbols
Inherited symbols.
Definition: Reflection.h:1408
Gorgon::Scripting::VirtualMachine::SetOutput
void SetOutput(std::ostream &out, bool deleteonchange=false)
Redirects the output stream to the given stream.
Definition: VirtualMachine.cpp:50
Gorgon::Scripting::Namespace::Members
const StaticMemberList & Members
List of static members.
Definition: Reflection.h:1148
Gorgon::Scripting::VirtualMachine::RemoveLibrary
void RemoveLibrary(const Library &library)
Removes a library.
Definition: VirtualMachine.cpp:40
Gorgon::Scripting::VirtualMachine::AddLibrary
void AddLibrary(const Library &library)
Includes a new library to be used in this virtual machine.
Definition: VirtualMachine.cpp:30
Gorgon::Scripting::VirtualMachine::IsVariableSet
bool IsVariableSet(const std::string &name)
Definition: VirtualMachine.cpp:401
Gorgon::Scripting::Variable::SetReferenceable
void SetReferenceable(const Data &value)
Sets the data contained in this variable.
Definition: Runtime.cpp:15
Gorgon::Scripting::Types::InstanceMember
const Scripting::Type & InstanceMember()
Gorgon::Scripting::InputProvider::Dialect
Dialect
Definition: Input.h:15
Gorgon::Scripting::VirtualMachine::GetVariable
Variable GetVariable(const std::string &name)
Definition: VirtualMachine.cpp:284
Gorgon::Scripting::InstructionType::Assignment
@ Assignment
Marks instruction as an assignment.
Gorgon::Scripting::VirtualMachine::Get
static VirtualMachine & Get()
Returns the current VM for this thread.
Definition: VirtualMachine.h:109
Gorgon::Scripting::Type::IsReferenceType
bool IsReferenceType() const
Returns whether this type is a reference type.
Definition: Reflection.h:1327
Gorgon::Utils::ASSERT_FALSE
void ASSERT_FALSE(const std::string &message, int skip=1, int depth=4)
Definition: Assert.h:192
Gorgon::Scripting::Types::Namespace
const Scripting::Type & Namespace()
Definition: Reflection.h:315
Gorgon::Scripting::Data::GetType
const Type & GetType() const
Returns the type of the data.
Definition: Data.h:173
Gorgon::Scripting::Keywords
Library Keywords
Definition: VirtualMachine.h:41
Gorgon::Scripting::VirtualMachine::AttachCommandConsole
void AttachCommandConsole()
Creates a new InputSource using a console input provider.
Gorgon::Scripting::SourceMarker
This class uniquely represents a source code line.
Definition: Scope.h:30
RuntimeFunction.h
This file contains classes that supports functions that are defined in runtime.
Gorgon::Scripting::VirtualMachine::VirtualMachine
VirtualMachine(bool automaticreset=true, std::ostream &out=std::cout, std::istream &in=std::cin)
Default constructor.
Definition: VirtualMachine.cpp:17
Gorgon::Scripting::Variable::Set
void Set(Any value)
Sets the data contained in this variable without changing its type.
Definition: Runtime.h:169
Gorgon::Scripting::Type
This class stores information about types.
Definition: Reflection.h:1165
Gorgon::Scripting::ParameterTemplateType
Type * ParameterTemplateType()
Definition: Runtime.cpp:8
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::Scripting::Library
This class represents a library.
Definition: Reflection.h:1596
Gorgon::Scripting::Symbol::type
SymbolType type
Type of the symbol.
Definition: VirtualMachine.h:32
Gorgon::Scripting::VirtualMachine::SetSpecialIdentifierHandler
void SetSpecialIdentifierHandler(std::function< Data(char, std::string)> handler)
Sets the handler for special identifiers.
Definition: VirtualMachine.h:207
Gorgon::Scripting::Value::Name
std::string Name
Used for variables and constants.
Definition: Instruction.h:84
Gorgon::Scripting::Namespace
Namespace contains other static members as members.
Definition: Reflection.h:1073
Gorgon::Scripting::Type::Assign
virtual void Assign(Data &l, const Data &r) const =0
Assigns the value of the second parameter to the first, reference types can ignore this function.
Gorgon::Scripting::VirtualMachine::Activate
void Activate()
Activate this VM for this thread.
Definition: VirtualMachine.h:169
Gorgon::Scripting::Data::IsReference
bool IsReference() const
Returns if this data contains a reference.
Definition: Data.cpp:212
Gorgon::Scripting::StaticMember
This is the base class for all static members.
Definition: Reflection.h:365
ASSERT
#define ASSERT(expression, message,...)
Replaces regular assert to allow messages and backtrace.
Definition: Assert.h:161
Gorgon::Scripting::Data::Invalid
static Data Invalid()
Constructs an invalid data object.
Definition: Data.h:27
Gorgon::Containers::Collection
Collection is a container for reference typed objects.
Definition: Collection.h:21
Gorgon::Scripting::InputProvider
Definition: Input.h:13
Gorgon::Scripting::Value::Literal
Data Literal
Used for literal values.
Definition: Instruction.h:87
Gorgon::String::ToLower
std::string ToLower(std::string str)
Converts the given string to lowercase.
Definition: String.h:416
Gorgon::Scripting::OptionList
std::vector< Any > OptionList
Definition: Reflection.h:114
Gorgon::Scripting::Symbol
Represents a symbol, can be a variable, type, function or constant.
Definition: VirtualMachine.h:26
Gorgon::Scripting::Types::Library
const Scripting::Type & Library()
Gorgon::Scripting::VirtualMachine::UsingNamespace
void UsingNamespace(const Namespace &name)
Imports symbols of a namespace to the list of global symbols.
Definition: VirtualMachine.cpp:1432
Gorgon::Scripting::ReferenceTag
@ ReferenceTag
Marks the object as a reference.
Definition: Reflection.h:61
Gorgon::Scripting::VirtualMachine::SetInput
void SetInput(std::istream &in)
Redirects input stream to the given stream.
Definition: VirtualMachine.cpp:57
Gorgon::Scripting::VirtualMachine::~VirtualMachine
~VirtualMachine()
Definition: VirtualMachine.h:51
VirtualMachine.h
Gorgon::Scripting::InputProvider::Programming
@ Programming
Definition: Input.h:17
Gorgon::Scripting::StaticMember::Function
@ Function
Function, functions can also be represented as data members.
Definition: Reflection.h:385
Gorgon::String::Extract
std::string Extract(std::string &original, const std::string &marker, bool trim=false)
Extracts the part of the string up to the given marker.
Definition: String.h:779
Gorgon::Scripting::VirtualMachine::DetachCommandConsole
bool DetachCommandConsole()
If there is an attached command console, this function detaches that console, stops execution and ret...
Gorgon::Scripting::Value
This class contains a parsed value.
Definition: Instruction.h:82
Gorgon::Scripting::ScopeInstance::FindSymbol
Data FindSymbol(const std::string &name, bool reference)
Tries to find the given symbol (including variables)
Definition: Scope.h:364
Gorgon::Scripting::Value::Result
Byte Result
Used for temporary results.
Definition: Instruction.h:93
Gorgon::Scripting::Function::Overload
Represents a function overload.
Definition: Reflection.h:588
Gorgon::Scripting::VirtualMachine::ResetInput
void ResetInput()
Resets the input stream to default stream that is given in the constructor.
Definition: VirtualMachine.h:163
Gorgon::Scripting::ConstTag
@ ConstTag
Marks a parameter or a function constant.
Definition: Reflection.h:95
Gorgon::Scripting::init_builtin
void init_builtin()
Definition: Builtin.cpp:113
Gorgon::Resource::GID::Type::Name
std::string Name() const
Return the name of a known GID.
Definition: GID.h:283
Gorgon::Scripting::Data::GetData
Any GetData() const
Returns the data contained in this data element.
Definition: Data.h:133
Gorgon::Scripting::Namespace::GetType
const Type & GetType(const std::string &name) const
Convenience function, returns the type with the given name.
Definition: Reflection.cpp:395
Gorgon::Scripting::SourceMarker::GetLine
unsigned long GetLine() const
Definition: Scope.h:46
Gorgon::Scripting::VirtualMachine::SetVariable
void SetVariable(const std::string &name, Data data, bool ref=false)
Definition: VirtualMachine.cpp:328
Runtime.h
This file contains classes that stores runtime and end programmer defined objects.
Gorgon::Scripting::InstructionType::MethodCall
@ MethodCall
Marks this instruction as a method call.
Gorgon::Scripting::VirtualMachine::Return
void Return(Data value=Data::Invalid())
Returns from the currently running script and sets return data to the given value.
Definition: VirtualMachine.h:196
Gorgon::Scripting::ValueType::Literal
@ Literal
This is a literal value.
Gorgon::Scripting::VirtualMachine::Libraries
const Containers::Collection< const Library > & Libraries
Allows read-only access to libraries.
Definition: VirtualMachine.h:219
Gorgon::GL::UBOBindingPoint::Type
Type
Definition: Shader.h:14
Gorgon::Any::Pointer
void * Pointer() const
Returns the pointer without type information.
Definition: Any.h:332
Gorgon::Scripting::VirtualMachine::ResetOutput
void ResetOutput()
Resets the output stream to default stream that is given in the constructor.
Definition: VirtualMachine.h:155
Gorgon::Scripting::Symbol::object
Any object
The object.
Definition: VirtualMachine.h:35
Gorgon::Scripting::VirtualMachine::Run
void Run()
This method starts the virtual machine.
Definition: VirtualMachine.cpp:95
Data.h
Gorgon::Scripting::Reflection
Library Reflection
Definition: Builtin.cpp:17
Gorgon::Scripting::VirtualMachine::GetMarkerForNext
SourceMarker GetMarkerForNext() const
Returns the code marker for the next line.
Definition: VirtualMachine.h:185
Gorgon::Scripting::VirtualMachine::GetReturnValue
Data GetReturnValue() const
Returns the data returned from the last executed script.
Definition: VirtualMachine.h:191
Gorgon::Scripting::FilesystemLib
Library & FilesystemLib()
Definition: Filesystem.cpp:49
Gorgon::Scripting::Integrals
Library Integrals
This library requires Initialize to be called.
Definition: VirtualMachine.h:41
Gorgon::Scripting::Data::IsConstant
bool IsConstant() const
Returns if this data is constant.
Definition: Data.h:160
Instruction.h
Gorgon::Scripting::ValueType::Identifier
@ Identifier
Marks this value as an identifier, either a constant or a variable.
Gorgon::Scripting::VirtualMachine::Start
void Start(InputProvider &input)
This method starts the virtual machine with the given input source.
Definition: VirtualMachine.cpp:61
Exceptions.h
Exceptions This file contains string related exceptions.
Gorgon::Scripting::VirtualMachine::GetInput
std::istream & GetInput() const
Returns the input stream.
Definition: VirtualMachine.h:150
Gorgon::Scripting::StreamInput
Reads lines from a stream.
Definition: Input.h:102
Gorgon::Scripting::InstructionType::Unknown
@ Unknown
This value is not valid.
Gorgon::Scripting::ValueType::Variable
@ Variable
This is a variable.
Gorgon::Scripting::InputProvider::GetName
std::string GetName() const
Definition: Input.h:35
Gorgon::Scripting::VirtualMachine::Jump
void Jump(unsigned long line)
Changes the current executing line.
Gorgon::Scripting::VirtualMachine::UnsetVariable
void UnsetVariable(const std::string &name)
Definition: VirtualMachine.cpp:395
Gorgon::Scripting::Types::Function
const Scripting::Type & Function()
Definition: Reflection.h:589
Gorgon::Scripting::Value::Type
ValueType Type
Type of this value.
Definition: Instruction.h:90
Gorgon::Scripting::VirtualMachine::ExecuteStatement
bool ExecuteStatement(const std::string &code, InputProvider::Dialect dialect=InputProvider::Programming)
Executes a single statement in this virtual machine.
Definition: VirtualMachine.cpp:1413
Gorgon::Scripting::InstructionType::Jump
@ Jump
Unconditionally jumps by the given offset. Offset should be in JumpOffset field.
Gorgon::Scripting::Function
Represents a function.
Definition: Reflection.h:557
Gorgon::Scripting::VirtualMachine::GetOutput
std::ostream & GetOutput() const
Returns the output stream.
Definition: VirtualMachine.h:145
Gorgon::Scripting::Types::Type
const Scripting::Type & Type()
Definition: Reflection.h:316
Gorgon::Scripting::Type::CanMorphTo
MorphType CanMorphTo(const Type &type) const
Check if it is possible to morph this type to the other.
Definition: Reflection.cpp:214
Gorgon::Scripting::VirtualMachine::Begin
void Begin(InputProvider &input)
This method begins a new execution scope without starting execution.
Definition: VirtualMachine.cpp:67
Gorgon::Scripting::VirtualMachine::getvarref
Variable * getvarref(const std::string &var)
Internal, returns pointer to the variable. Can return nullptr. Only searches in VM variables.
Definition: VirtualMachine.cpp:320
Gorgon::Scripting::VirtualMachine::CurrentScopeInstance
ScopeInstance & CurrentScopeInstance() const
Returns the current exection scope.
Definition: VirtualMachine.h:180
Gorgon::Scripting::Data::IsValid
bool IsValid() const
Returns if the data is in a valid state.
Definition: Data.h:152
Gorgon::Scripting::Instruction
A single instruction.
Definition: Instruction.h:150
Gorgon::Scripting::fixparameter
void fixparameter(Data &param, const Type &pdef, bool ref, const std::string &error)
Definition: VirtualMachine.cpp:176
Gorgon::Scripting::ReferenceCounter::Increase
void Increase(const Data &data)
Increases the reference count of the given object. If it is not registered, this request is ignored.
Definition: Runtime.h:47
Gorgon::Scripting::VirtualMachine
This class defines a virtual environment for scripts to run.
Definition: VirtualMachine.h:45
Gorgon::Containers::Hashmap::Find
Iterator Find(const K_ &key)
Finds the given key in the hashmap and returns iterator for it.
Definition: Hashmap.h:402
Gorgon::Scripting::VirtualMachine::ExecuteFunction
Data ExecuteFunction(const Function *fn, const std::vector< Data > &params, bool method)
Executes a function in the current scope.
Definition: VirtualMachine.cpp:1421
Gorgon::Scripting::Type::MorphTo
Data MorphTo(const Type &type, Data source, bool allowtypecast=true) const
Morphs the given data into the target type.
Definition: Reflection.cpp:123
Gorgon::Scripting::Symbol::namespc
std::string namespc
Namespace that this symbol is in. For variables, namespc could be local.
Definition: VirtualMachine.h:29
Gorgon::Scripting::Variable
This class represents a variable. It contains the data and the name of the variable.
Definition: Runtime.h:146
Gorgon::Scripting::VirtualMachine::CompileCurrent
void CompileCurrent()
Commands virtual machine to compile current execution scope.
Definition: VirtualMachine.cpp:415
Gorgon::Scripting::Member::GetName
std::string GetName() const
Returns the name of this member.
Definition: Reflection.h:325