#include <Gorgon/Scripting.h>
#include <Gorgon/Scripting/VirtualMachine.h>
#include <Gorgon/Scripting/Embedding.h>
#include <thread>
#include <iostream>
#include <Gorgon/Scripting/VirtualMachine.h>
#include <Gorgon/Scripting/Compilers.h>
#include <Gorgon/Filesystem/Iterator.h>
#include <Gorgon/Filesystem.h>
#include <Gorgon/Enum.h>
#include <Gorgon/Time.h>
#include <Gorgon/Geometry.h>
using namespace Gorgon::Scripting;
const std::string source = "";
namespace Gorgon { namespace Scripting { namespace Compilers {
extern bool showsvg__;
} } }
void togglesvg() {
Compilers::showsvg__=!Compilers::showsvg__;
}
void testfill(std::string &s) {
s+="abcdefg";
}
void testset(int &c) {
c='5';
}
void dumprefs() {
VirtualMachine::Get().References.list();
}
class NullTest {
};
NullTest *thisisnull() { return nullptr; }
void nonull(NullTest &n) {
std::cout<<"Cannot be null :"<<(&n)<<std::endl;
}
void allownull(NullTest *n) {
std::cout<<"Can be null :"<<n<<std::endl;
}
std::ostream &operator<<(std::ostream &out, const NullTest &n) {
out<<(&n);
return out;
}
void test() {
std::string scriptdir="../Source/Unit/Scripts";
Gorgon::Filesystem::Iterator dir(scriptdir);
for( ; dir.IsValid(); dir.Next()) {
std::ifstream file(scriptdir+"/"+dir.Current());
std::cout<<*dir<<std::endl;
std::string line;
bool outputmode=false;
std::string code;
std::string output;
while( std::getline(file, line) ) {
if(outputmode) {
output+=line+"\n";
}
else if(Gorgon::String::Trim(line)=="## OUTPUT ##") {
outputmode=true;
}
else {
code+=line+"\n";
}
}
std::cout<<output<<std::endl;
if(output!="") output=output.substr(0, output.length()-1);
std::stringstream codestream(code), outputstream(output), scriptoutput;
Gorgon::Scripting::StreamInput input(codestream, Gorgon::Scripting::InputProvider::Programming, dir.Current());
Gorgon::Scripting::VirtualMachine &vm=Gorgon::Scripting::VirtualMachine::Get();
//vm.SetOutput(scriptoutput);
vm.Begin(input);
vm.Run();
std::string line2;
while(std::getline(outputstream, line),std::getline(scriptoutput, line2)) {
//REQUIRE(line==line2);
}
//REQUIRE(outputstream.rdstate()==scriptoutput.rdstate());
}
}
std::vector<int> v(40);
Data SpecHandler(char c, std::string var) {
if(c=='!') {
return {Gorgon::Scripting::Types::String(), var};
}
else if(c=='%') {
if(Gorgon::String::To<int>(var)<40 && Gorgon::String::To<int>(var)>0) {
return {Gorgon::Scripting::Types::Int(), &v[Gorgon::String::To<int>(var)], true, false};
}
}
return {};
}
class evttest {
public:
evttest() : ev(*this) { }
evttest(const evttest &) = delete;
Gorgon::Event<evttest, int> ev;
};
enum class Day {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
DefineEnumStrings(Day,
{Day::Monday, "Monday"},
{Day::Tuesday, "Tuesday"},
{Day::Wednesday, "Wednesday"},
{Day::Thursday, "Thursday"},
{Day::Friday, "Friday"},
{Day::Saturday, "Saturday"},
{Day::Sunday, "Sunday"}
);
enum class Direction {
None = 0,
In = 1,
Out = 2,
InOut = 3,
};
DefineEnumStrings(Direction,
{Direction::None, "None"},
{Direction::In, "In"},
{Direction::Out, "Out"},
{Direction::InOut,"InOut"}
);
class imtest {
public:
imtest() = default;
imtest(std::string) { }
operator std::string() const { return Gorgon::String::Concat(a, ",", b); }
int a=0;
int b=0;
int getb() const { return b; }
void setb(int v) { b=v; }
bool operator ==(imtest l) const { return a==l.a && b==l.b; }
};
int main() {
VirtualMachine vm;
Gorgon::Geometry::InitializeScripting();
vm.AddLibrary(Gorgon::Geometry::LibGeometry);
vm.SetSpecialIdentifierHandler(SpecHandler);
std::cout<<Gorgon::Time::GetDate().ISODateTime()<<std::endl;
auto console = Gorgon::Utils::StdConsole();
auto reftyp=new Gorgon::Scripting::MappedReferenceType<evttest, ToEmptyString<evttest>>("reftype", "");
auto eventtype=new MappedEventType<
Gorgon::Event<evttest, int>, evttest, void, int
>(
"evt", "help", {
Parameter("int", "int", Types::Int())
}
);
reftyp->MapConstructor<>({});
reftyp->AddMembers({
new MappedROInstanceMember<evttest*, Gorgon::Event<evttest, int>>(&evttest::ev, "event", "", eventtype)
});
evttest a;
a.ev.Register([](int v){ std::cout<<"OK: "<<v<<std::endl; });
//test();
std::stringstream ss(source);
ConsoleInput streaminput={InputProvider::Programming};
Library mylib("GTTest", "");
auto mystr = new MappedValueType<std::string>("MyStr", "");
auto StringToMyStrConvert=[&mystr](Data data) {
return Data{mystr, data.GetValue<std::string>()};
};
auto MyStrToStringConvert=[&mystr](Data data) {
return Data{Types::String(), data.GetValue<std::string>()};
};
mystr->AddInheritance(Types::String(), StringToMyStrConvert, MyStrToStringConvert);
auto nulltype=new MappedReferenceType<NullTest>("NullTest", "");
auto myregenum = new MappedStringEnum<Day>("Day", "");
auto mybinenum = new MappedStringEnum<Direction>("Direction", "", Direction::In, true);
auto imtester = new MappedValueType<imtest>("imtest", "");
imtester->MapConstructor<>({});
imtester->AddMembers({
new MappedInstanceMember<imtest, int>(
&imtest::a, "a", "", Types::Int(), false, false
),
new MappedInstanceMember_Function(
&imtest::getb, &imtest::setb, "b", "", Types::Int(), imtester, true, false, false, true
)
});
mylib.AddMembers({
nulltype, reftyp, myregenum, mybinenum, imtester
});
mylib.AddMembers({
new Function("geta", "", nullptr,
{
MapFunction([&]{
return &a;
}, reftyp, {})
}
),
new Function("svg", "", nullptr,
{
MapFunction(&togglesvg, nullptr, {})
},
KeywordTag
),
new Function("thisisnull", "", nullptr,
{
MapFunction(&thisisnull, nulltype, {})
}
),
new Function("nonull", "", nullptr,
{
MapFunction(&nonull, nullptr, {
Parameter("v", "", nulltype)
})
}
),
new Function("allownull", "", nullptr,
{
MapFunction(&allownull, nullptr, {
Parameter("v", "", nulltype, AllowNullTag)
})
}
),
new Function("testfill", "", nullptr,
{
MapFunction(
testfill, nullptr,
{
Parameter("a", "", Types::String(), Gorgon::Scripting::ReferenceTag)
}
)
}
),
new Function("gen", "", nullptr,
{
MapFunction(
[]{
return std::string("abc");
}, mystr,
{ }
),
}
),
new Function("testset", "", nullptr,
{
MapFunction(
testset, nullptr,
{
Parameter("c","",Types::Int(), Gorgon::Scripting::ReferenceTag)
}
),
}
),
new Function("dumprefs", "", nullptr,
{
MapFunction(
dumprefs, nullptr,
{ }
),
}, KeywordTag
),
});
vm.AddLibrary(mylib);
std::cout<<std::endl<<std::endl;
console.SetBold();
console.SetColor(console.Yellow);
std::cout<<"OUTPUT: "<<std::endl;
console.Reset();
vm.Begin(streaminput);
vm.UsingNamespace(mylib);
vm.UsingNamespace(Reflection);
//Compilers::Disassemble(input, std::cout);
std::cout<<std::endl<<std::endl;
while(vm.GetScopeInstanceCount()) {
try {
vm.Run();
}
catch(const Gorgon::Scripting::ParseError &ex) {
std::cout<<std::endl<<std::endl;
console.SetBold();
console.SetColor(console.Yellow);
std::cout<<"ERROR: "<<std::endl;
console.Reset();
console.SetBold();
std::cout<<"At line "<<ex.GetLine()<<":"<<ex.Char+1;
console.SetBold(false);
console.SetColor(console.Red);
std::cout<<": "<<ex.GetType();
console.SetColor(console.Default);
std::cout<<": "<<ex.GetMessage()<<std::endl;
if(ex.GetDetails()!="") {
std::cout<<" > "<<ex.GetDetails()<<std::endl;
}
}
catch(const Exception &ex) {
std::cout<<std::endl<<std::endl;
console.SetBold();
console.SetColor(console.Yellow);
std::cout<<"SOURCE CODE: "<<std::endl;
console.Reset();
std::stringstream ss2(source);
std::string line;
int linenr=0;
while(std::getline(ss2, line)) {
linenr++;
if(linenr==ex.GetLine())
console.SetColor(console.Red);
console.SetBold();
std::cout<<std::setw(3)<<linenr<<" ";
console.SetBold(false);
std::cout<<line<<std::endl;
console.Reset();
}
std::cout<<std::endl<<std::endl;
std::cout<<std::endl<<std::endl;
console.SetBold();
console.SetColor(console.Yellow);
std::cout<<"ERROR: "<<std::endl;
console.Reset();
console.SetBold();
std::cout<<"At line "<<ex.GetLine();
console.SetBold(false);
console.SetColor(console.Red);
std::cout<<": "<<ex.GetType();
console.SetColor(console.Default);
std::cout<<": "<<ex.GetMessage()<<std::endl;
if(ex.GetDetails()!="") {
std::cout<<" > "<<ex.GetDetails()<<std::endl;
}
}
catch(const std::exception &ex) {
console.SetColor(console.Red);
console.SetBold();
std::cout<<ex.what()<<std::endl;
console.Reset();
std::cout<<std::endl<<std::endl;
}
}
std::cout<<std::endl<<std::endl;
console.SetBold();
console.SetColor(console.Yellow);
std::cout<<"SOURCE CODE: "<<std::endl;
console.Reset();
std::stringstream ss2(source);
std::string line;
int linenr=0;
while(std::getline(ss2, line)) {
linenr++;
console.SetBold();
std::cout<<std::setw(3)<<linenr<<" ";
console.SetBold(false);
std::cout<<line<<std::endl;
console.Reset();
}
std::cout<<std::endl<<std::endl;
std::cout<<std::endl<<std::endl;
console.SetColor(console.Green);
std::cout<<"Execution successful."<<std::endl<<std::endl;
Data ret=vm.GetReturnValue();
if(ret.IsValid()) {
std::cout<<"Return value: "<<ret<<std::endl;
}
console.Reset();
//std::cout<<vm.GetVariable("a")<<std::endl;
return 0;
}