87 #include "controller.h"
90 #include "cpp_programs.h"
91 #include "callbacks.h"
96 #include "../r_comp/decompiler.h"
97 #include "../r_comp/preprocessor.h"
104 using namespace std::chrono;
105 using namespace r_code;
109 dll_export Timestamp (*Now)();
114 unordered_map<std::string, uint16> _Opcodes;
121 bool Compile(std::istream &source_code,
const std::string& filePath, std::string &error,
bool compile_metadata) {
123 std::ostringstream preprocessed_code_out;
124 if (!r_exec::Preprocessor.process(&source_code, filePath, &preprocessed_code_out, error, compile_metadata ? &Metadata : NULL))
127 std::istringstream preprocessed_code_in(preprocessed_code_out.str());
129 if (!r_exec::Compiler.compile(&preprocessed_code_in, &Seed, &Metadata, error,
false)) {
131 std::streampos i = preprocessed_code_in.tellg();
132 std::cerr.write(preprocessed_code_in.str().c_str(), i);
133 std::cerr <<
" <- " << error << std::endl;
140 bool Compile(
const char *filename, std::string &error,
bool compile_metadata) {
142 std::ifstream source_code(filename, std::ios::binary | ios::in);
143 if (!source_code.good()) {
145 error =
"unable to load file ";
150 bool r = Compile(source_code, filename, error, compile_metadata);
155 bool Compile(
const char *filename, std::string &error) {
157 return Compile(filename, error,
false);
160 bool Compile(std::istream &source_code,
const std::string& filePath, std::string &error) {
162 return Compile(source_code, filePath, error,
false);
167 thread_ret TDecompiler::Decompile(
void *args) {
173 decompiler.init(&r_exec::Metadata);
175 vector<SysObject *> imported_objects;
178 image->
add_objects(_this->objects_, imported_objects);
179 image->object_names_.symbols_ = r_exec::Seed.object_names_.symbols_;
181 std::ostringstream decompiled_code;
182 decompiler.decompile(image, &decompiled_code, Utils::GetTimeReference(), imported_objects);
184 if (_this->ostream_id_ == 0) {
186 std::cout << _this->header_;
187 std::cout << decompiled_code.str();
190 PipeOStream::Get(_this->ostream_id_ - 1) << _this->header_;
191 PipeOStream::Get(_this->ostream_id_ - 1) << decompiled_code.str();
200 TDecompiler::TDecompiler(uint32 ostream_id, std::string header) :
_Object(), ostream_id_(ostream_id), header_(header), thread_(NULL), spawned_(0) {
202 objects_.reserve(ObjectsInitialSize);
205 TDecompiler::~TDecompiler() {
211 void TDecompiler::add_object(
Code *
object) {
213 objects_.push_back(
object);
219 for (o = objects.begin(); o != objects.end(); ++o)
220 objects_.push_back(*o);
223 void TDecompiler::add_objects(
const vector<
P<Code> > &objects) {
225 vector<P<Code> >::const_iterator o;
226 for (o = objects.begin(); o != objects.end(); ++o)
227 objects_.push_back(*o);
230 void TDecompiler::decompile() {
232 if (_Mem::Get()->get_reduction_core_count() == 0 && _Mem::Get()->get_time_core_count() == 0)
236 thread_ = Thread::New<_Thread>(Decompile,
this);
237 while (spawned_ == 0);
243 vector<PipeOStream *> PipeOStream::Streams_;
245 PipeOStream PipeOStream::NullStream_;
247 void PipeOStream::Open(uint8 count) {
250 for (uint8 i = 0; i < count; ++i) {
252 PipeOStream *p =
new PipeOStream();
255 Streams_.push_back(p);
260 void PipeOStream::Close() {
263 for (uint8 i = 0; i < Streams_.size(); ++i)
269 PipeOStream &PipeOStream::Get(uint8
id) {
272 if (
id < Streams_.size())
273 return *Streams_[id];
278 PipeOStream::PipeOStream() : std::ostream(NULL)
280 , pipe_read_(0), pipe_write_(0)
286 void PipeOStream::init() {
288 SECURITY_ATTRIBUTES saAttr;
289 saAttr.nLength =
sizeof(saAttr);
290 saAttr.bInheritHandle =
true;
291 saAttr.lpSecurityDescriptor = NULL;
293 CreatePipe(&pipe_read_, &pipe_write_, &saAttr, 0);
296 PROCESS_INFORMATION pi;
298 ZeroMemory(&si,
sizeof(si));
300 ZeroMemory(&pi,
sizeof(pi));
303 itoa((
int)pipe_read_, handle, 10);
304 std::string command(
"output_window.exe ");
305 command += std::string(handle);
308 const_cast<char *
>(command.c_str()),
320 PipeOStream::~PipeOStream() {
326 std::string stop(
"close_output_window");
328 CloseHandle(pipe_read_);
329 CloseHandle(pipe_write_);
333 PipeOStream &PipeOStream::operator <<(std::string &s) {
335 #ifdef WINDOWS // TODO: Implement for non-WINDOWS
339 uint32 to_write = s.length();
342 WriteFile(pipe_write_, s.c_str(), to_write, &written, NULL);
348 PipeOStream& PipeOStream::operator <<(
const char *s) {
354 uint32 to_write = strlen(s);
357 WriteFile(pipe_write_, s, to_write, &written, NULL);
365 uint16 RetrieveOpcode(
const char *name) {
367 return _Opcodes.find(name)->second;
371 unordered_map<uint16, set<string>> opcode_names;
372 unordered_map<std::string, r_comp::Class>::const_iterator it;
373 for (it = metadata.classes_.begin(); it != metadata.classes_.end(); ++it) {
375 _Opcodes[it->first] = it->second.atom_.asOpcode();
376 auto opcode = it->second.atom_.asOpcode();
377 if (opcode_names.find(opcode) == opcode_names.end())
379 opcode_names[opcode] = set<string>();
380 opcode_names[opcode].insert(it->first.c_str());
382 for (it = metadata.sys_classes_.begin(); it != metadata.sys_classes_.end(); ++it) {
384 _Opcodes[it->first] = it->second.atom_.asOpcode();
385 auto opcode = it->second.atom_.asOpcode();
386 if (opcode_names.find(opcode) == opcode_names.end())
388 opcode_names[opcode] = set<string>();
389 opcode_names[opcode].insert(it->first.c_str());
391 if (!r_code::SetOpcodeNames(opcode_names))
395 View::ViewOpcode_ = _Opcodes.find(
"view")->second;
397 Opcodes::View = _Opcodes.find(
"view")->second;
398 Opcodes::PgmView = _Opcodes.find(
"pgm_view")->second;
399 Opcodes::GrpView = _Opcodes.find(
"grp_view")->second;
401 Opcodes::TI = _Opcodes.find(
"ti")->second;
403 Opcodes::Ent = _Opcodes.find(
"ent")->second;
404 Opcodes::Ont = _Opcodes.find(
"ont")->second;
405 Opcodes::MkVal = _Opcodes.find(
"mk.val")->second;
407 Opcodes::Grp = _Opcodes.find(
"grp")->second;
409 Opcodes::Ptn = _Opcodes.find(
"ptn")->second;
410 Opcodes::AntiPtn = _Opcodes.find(
"|ptn")->second;
412 Opcodes::IPgm = _Opcodes.find(
"ipgm")->second;
413 Opcodes::ICppPgm = _Opcodes.find(
"icpp_pgm")->second;
415 Opcodes::Pgm = _Opcodes.find(
"pgm")->second;
416 Opcodes::AntiPgm = _Opcodes.find(
"|pgm")->second;
418 Opcodes::ICmd = _Opcodes.find(
"icmd")->second;
419 Opcodes::Cmd = _Opcodes.find(
"cmd")->second;
421 Opcodes::Fact = _Opcodes.find(
"fact")->second;
422 Opcodes::AntiFact = _Opcodes.find(
"|fact")->second;
424 Opcodes::Cst = _Opcodes.find(
"cst")->second;
425 Opcodes::Mdl = _Opcodes.find(
"mdl")->second;
427 Opcodes::ICst = _Opcodes.find(
"icst")->second;
428 Opcodes::IMdl = _Opcodes.find(
"imdl")->second;
430 Opcodes::Pred = _Opcodes.find(
"pred")->second;
431 Opcodes::Goal = _Opcodes.find(
"goal")->second;
433 Opcodes::Success = _Opcodes.find(
"success")->second;
435 Opcodes::MkGrpPair = _Opcodes.find(
"mk.grp_pair")->second;
437 Opcodes::MkRdx = _Opcodes.find(
"mk.rdx")->second;
438 Opcodes::Perf = _Opcodes.find(
"perf")->second;
440 Opcodes::MkNew = _Opcodes.find(
"mk.new")->second;
442 Opcodes::MkLowRes = _Opcodes.find(
"mk.low_res")->second;
443 Opcodes::MkLowSln = _Opcodes.find(
"mk.low_sln")->second;
444 Opcodes::MkHighSln = _Opcodes.find(
"mk.high_sln")->second;
445 Opcodes::MkLowAct = _Opcodes.find(
"mk.low_act")->second;
446 Opcodes::MkHighAct = _Opcodes.find(
"mk.high_act")->second;
447 Opcodes::MkSlnChg = _Opcodes.find(
"mk.sln_chg")->second;
448 Opcodes::MkActChg = _Opcodes.find(
"mk.act_chg")->second;
450 Opcodes::Sim = _Opcodes.find(
"sim")->second;
451 Opcodes::Id = _Opcodes.find(
"id")->second;
454 Opcodes::Inject = _Opcodes.find(
"_inj")->second;
455 Opcodes::Eject = _Opcodes.find(
"_eje")->second;
456 Opcodes::Mod = _Opcodes.find(
"_mod")->second;
457 Opcodes::Set = _Opcodes.find(
"_set")->second;
458 Opcodes::NewClass = _Opcodes.find(
"_new_class")->second;
459 Opcodes::DelClass = _Opcodes.find(
"_del_class")->second;
460 Opcodes::LDC = _Opcodes.find(
"_ldc")->second;
461 Opcodes::Swap = _Opcodes.find(
"_swp")->second;
462 Opcodes::Prb = _Opcodes.find(
"_prb")->second;
463 Opcodes::Stop = _Opcodes.find(
"_stop")->second;
465 Opcodes::Gtr = _Opcodes.find(
"gtr")->second;
466 Opcodes::Lsr = _Opcodes.find(
"lsr")->second;
467 Opcodes::Gte = _Opcodes.find(
"gte")->second;
468 Opcodes::Lse = _Opcodes.find(
"lse")->second;
469 Opcodes::Add = _Opcodes.find(
"add")->second;
470 Opcodes::Sub = _Opcodes.find(
"sub")->second;
471 Opcodes::Mul = _Opcodes.find(
"mul")->second;
472 Opcodes::Div = _Opcodes.find(
"div")->second;
474 Opcodes::Var = _Opcodes.find(
"var")->second;
477 uint16 operator_opcode = 0;
478 Operator::Register(operator_opcode++, now);
479 Operator::Register(operator_opcode++, rnd);
480 Operator::Register(operator_opcode++, equ);
481 Operator::Register(operator_opcode++, neq);
482 Operator::Register(operator_opcode++, gtr);
483 Operator::Register(operator_opcode++, lsr);
484 Operator::Register(operator_opcode++, gte);
485 Operator::Register(operator_opcode++, lse);
486 Operator::Register(operator_opcode++, add);
487 Operator::Register(operator_opcode++, sub);
488 Operator::Register(operator_opcode++, mul);
489 Operator::Register(operator_opcode++, div);
490 Operator::Register(operator_opcode++, dis);
491 Operator::Register(operator_opcode++, ln);
492 Operator::Register(operator_opcode++, exp);
493 Operator::Register(operator_opcode++, log);
494 Operator::Register(operator_opcode++, e10);
495 Operator::Register(operator_opcode++, syn);
496 Operator::Register(operator_opcode++, ins);
497 Operator::Register(operator_opcode++, red);
498 Operator::Register(operator_opcode++, fvw);
499 Operator::Register(operator_opcode++, is_sim);
500 Operator::Register(operator_opcode++, minimum);
501 Operator::Register(operator_opcode++, maximum);
502 Operator::Register(operator_opcode++,
id);
507 static bool Init(FunctionLibrary* userOperatorLibrary,
508 Timestamp (*time_base)()) {
512 if (!InitOpcodes(Metadata))
515 if (!userOperatorLibrary)
521 typedef uint16 (*OpcodeRetriever)(
const char *);
523 auto _Init = (UserInit)userOperatorLibrary->getFunction(
"Init");
527 typedef uint16 (*UserGetOperatorCount)();
528 auto GetOperatorCount = (UserGetOperatorCount)userOperatorLibrary->getFunction(
"GetOperatorCount");
529 if (!GetOperatorCount)
532 typedef void (*UserGetOperatorName)(
char *);
533 auto GetOperatorName = (UserGetOperatorName)userOperatorLibrary->getFunction(
"GetOperatorName");
534 if (!GetOperatorName)
537 Metadata.usr_classes_ = _Init(RetrieveOpcode);
539 typedef bool (*UserOperator)(
const Context &);
541 uint16 operatorCount = GetOperatorCount();
542 for (uint16 i = 0; i < operatorCount; ++i) {
545 memset(op_name, 0, 256);
546 GetOperatorName(op_name);
548 unordered_map<std::string, uint16>::iterator it = _Opcodes.find(op_name);
549 if (it == _Opcodes.end()) {
551 std::cerr <<
"Operator " << op_name <<
" is undefined" << std::endl;
554 auto op = (UserOperator)userOperatorLibrary->getFunction(op_name);
558 Operator::Register(it->second, op);
562 typedef uint16 (*UserGetProgramCount)();
563 auto GetProgramCount = (UserGetProgramCount)userOperatorLibrary->getFunction(
"GetProgramCount");
564 if (!GetProgramCount)
567 typedef void (*UserGetProgramName)(
char *);
568 auto GetProgramName = (UserGetProgramName)userOperatorLibrary->getFunction(
"GetProgramName");
572 typedef Controller *(*UserProgram)(
_View *);
574 uint16 programCount = GetProgramCount();
575 for (uint16 i = 0; i < programCount; ++i) {
578 memset(pgm_name, 0, 256);
579 GetProgramName(pgm_name);
581 std::string _pgm_name = pgm_name;
583 auto pgm = (UserProgram)userOperatorLibrary->getFunction(pgm_name);
587 CPPPrograms::Register(_pgm_name, pgm);
591 typedef uint16(*UserGetCallbackCount)();
592 auto GetCallbackCount = (UserGetCallbackCount)userOperatorLibrary->getFunction(
"GetCallbackCount");
593 if (!GetCallbackCount)
596 typedef void(*UserGetCallbackName)(
char *);
597 auto GetCallbackName = (UserGetCallbackName)userOperatorLibrary->getFunction(
"GetCallbackName");
598 if (!GetCallbackName)
601 typedef bool(*UserCallback)(microseconds, bool,
const char *, uint8,
Code **);
603 uint16 callbackCount = GetCallbackCount();
604 for (uint16 i = 0; i < callbackCount; ++i) {
606 char callback_name[256];
607 memset(callback_name, 0, 256);
608 GetCallbackName(callback_name);
610 std::string _callback_name = callback_name;
612 auto callback = (UserCallback)userOperatorLibrary->getFunction(callback_name);
616 Callbacks::Register(_callback_name, callback);
619 std::cout <<
"> user-defined operator library loaded" << std::endl;
624 bool Init(FunctionLibrary* userOperatorLibrary,
625 Timestamp (*time_base)(),
626 const char *seed_path) {
629 if (!Compile(seed_path, error,
true)) {
631 std::cerr << error << std::endl;
635 return Init(userOperatorLibrary, time_base);
638 bool Init(FunctionLibrary* userOperatorLibrary,
639 Timestamp (*time_base)(),
646 return Init(userOperatorLibrary, time_base);
649 uint16 GetOpcode(
const char *name) {
651 unordered_map<std::string, uint16>::iterator it = _Opcodes.find(name);
652 if (it == _Opcodes.end())
657 std::string GetAxiomName(
const uint16 index) {
659 return Compiler.getObjectName(index);
662 bool hasUserDefinedOperators(
const uint16 opcode) {
663 const std::vector<uint16> *usr_defined_opcodes = Metadata.usr_classes_.as_std();
664 return std::find(usr_defined_opcodes->begin(), usr_defined_opcodes->end(), opcode) != usr_defined_opcodes->end();
667 bool hasUserDefinedOperators(
const std::string class_name) {
668 if (_Opcodes.find(class_name) == _Opcodes.end()) {
671 return hasUserDefinedOperators(_Opcodes[class_name]);