AERA
init.cpp
1 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
2 //_/_/
3 //_/_/ AERA
4 //_/_/ Autocatalytic Endogenous Reflective Architecture
5 //_/_/
6 //_/_/ Copyright (c) 2018-2025 Jeff Thompson
7 //_/_/ Copyright (c) 2018-2025 Kristinn R. Thorisson
8 //_/_/ Copyright (c) 2018-2025 Icelandic Institute for Intelligent Machines
9 //_/_/ http://www.iiim.is
10 //_/_/
11 //_/_/ Copyright (c) 2010-2012 Eric Nivel
12 //_/_/ Center for Analysis and Design of Intelligent Agents
13 //_/_/ Reykjavik University, Menntavegur 1, 102 Reykjavik, Iceland
14 //_/_/ http://cadia.ru.is
15 //_/_/
16 //_/_/ Part of this software was developed by Eric Nivel
17 //_/_/ in the HUMANOBS EU research project, which included
18 //_/_/ the following parties:
19 //_/_/
20 //_/_/ Autonomous Systems Laboratory
21 //_/_/ Technical University of Madrid, Spain
22 //_/_/ http://www.aslab.org/
23 //_/_/
24 //_/_/ Communicative Machines
25 //_/_/ Edinburgh, United Kingdom
26 //_/_/ http://www.cmlabs.com/
27 //_/_/
28 //_/_/ Istituto Dalle Molle di Studi sull'Intelligenza Artificiale
29 //_/_/ University of Lugano and SUPSI, Switzerland
30 //_/_/ http://www.idsia.ch/
31 //_/_/
32 //_/_/ Institute of Cognitive Sciences and Technologies
33 //_/_/ Consiglio Nazionale delle Ricerche, Italy
34 //_/_/ http://www.istc.cnr.it/
35 //_/_/
36 //_/_/ Dipartimento di Ingegneria Informatica
37 //_/_/ University of Palermo, Italy
38 //_/_/ http://diid.unipa.it/roboticslab/
39 //_/_/
40 //_/_/
41 //_/_/ --- HUMANOBS Open-Source BSD License, with CADIA Clause v 1.0 ---
42 //_/_/
43 //_/_/ Redistribution and use in source and binary forms, with or without
44 //_/_/ modification, is permitted provided that the following conditions
45 //_/_/ are met:
46 //_/_/ - Redistributions of source code must retain the above copyright
47 //_/_/ and collaboration notice, this list of conditions and the
48 //_/_/ following disclaimer.
49 //_/_/ - Redistributions in binary form must reproduce the above copyright
50 //_/_/ notice, this list of conditions and the following disclaimer
51 //_/_/ in the documentation and/or other materials provided with
52 //_/_/ the distribution.
53 //_/_/
54 //_/_/ - Neither the name of its copyright holders nor the names of its
55 //_/_/ contributors may be used to endorse or promote products
56 //_/_/ derived from this software without specific prior
57 //_/_/ written permission.
58 //_/_/
59 //_/_/ - CADIA Clause: The license granted in and to the software
60 //_/_/ under this agreement is a limited-use license.
61 //_/_/ The software may not be used in furtherance of:
62 //_/_/ (i) intentionally causing bodily injury or severe emotional
63 //_/_/ distress to any person;
64 //_/_/ (ii) invading the personal privacy or violating the human
65 //_/_/ rights of any person; or
66 //_/_/ (iii) committing or preparing for any act of war.
67 //_/_/
68 //_/_/ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
69 //_/_/ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
70 //_/_/ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
71 //_/_/ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72 //_/_/ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
73 //_/_/ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
74 //_/_/ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
75 //_/_/ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
76 //_/_/ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
77 //_/_/ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
78 //_/_/ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
79 //_/_/ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
80 //_/_/ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
81 //_/_/ OF SUCH DAMAGE.
82 //_/_/
83 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
84 
85 #include <algorithm>
86 #include "init.h"
87 #include "controller.h"
88 #include "object.h"
89 #include "operator.h"
90 #include "cpp_programs.h"
91 #include "callbacks.h"
92 #include "opcodes.h"
93 #include "overlay.h"
94 #include "mem.h"
95 
96 #include "../r_comp/decompiler.h"
97 #include "../r_comp/preprocessor.h"
98 
99 #ifdef WINDOWS
100 #include <process.h>
101 #endif
102 
103 using namespace std;
104 using namespace std::chrono;
105 using namespace r_code;
106 
107 namespace r_exec {
108 
109 dll_export Timestamp (*Now)();
110 
111 dll_export r_comp::Metadata Metadata;
112 dll_export r_comp::Image Seed;
113 
114 unordered_map<std::string, uint16> _Opcodes;
115 
116 dll_export r_comp::Compiler Compiler;
117 r_exec_dll r_comp::Preprocessor Preprocessor;
118 
120 
121 bool Compile(std::istream &source_code, const std::string& filePath, std::string &error, bool compile_metadata) {
122 
123  std::ostringstream preprocessed_code_out;
124  if (!r_exec::Preprocessor.process(&source_code, filePath, &preprocessed_code_out, error, compile_metadata ? &Metadata : NULL))
125  return false;
126 
127  std::istringstream preprocessed_code_in(preprocessed_code_out.str());
128 
129  if (!r_exec::Compiler.compile(&preprocessed_code_in, &Seed, &Metadata, error, false)) {
130 
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;
134  return false;
135  }
136 
137  return true;
138 }
139 
140 bool Compile(const char *filename, std::string &error, bool compile_metadata) {
141 
142  std::ifstream source_code(filename, std::ios::binary | ios::in);
143  if (!source_code.good()) {
144 
145  error = "unable to load file ";
146  error += filename;
147  return false;
148  }
149 
150  bool r = Compile(source_code, filename, error, compile_metadata);
151  source_code.close();
152  return r;
153 }
154 
155 bool Compile(const char *filename, std::string &error) {
156 
157  return Compile(filename, error, false);
158 }
159 
160 bool Compile(std::istream &source_code, const std::string& filePath, std::string &error) {
161 
162  return Compile(source_code, filePath, error, false);
163 }
164 
166 
167 thread_ret TDecompiler::Decompile(void *args) {
168 
169  P<TDecompiler> _this = (TDecompiler *)args;
170  _this->spawned_ = 1;
171 
172  r_comp::Decompiler decompiler;
173  decompiler.init(&r_exec::Metadata);
174 
175  vector<SysObject *> imported_objects;
176 
177  r_comp::Image *image = new r_comp::Image();
178  image->add_objects(_this->objects_, imported_objects);
179  image->object_names_.symbols_ = r_exec::Seed.object_names_.symbols_;
180 
181  std::ostringstream decompiled_code;
182  decompiler.decompile(image, &decompiled_code, Utils::GetTimeReference(), imported_objects);
183 
184  if (_this->ostream_id_ == 0) {
185 
186  std::cout << _this->header_;
187  std::cout << decompiled_code.str();
188  } else {
189 
190  PipeOStream::Get(_this->ostream_id_ - 1) << _this->header_;
191  PipeOStream::Get(_this->ostream_id_ - 1) << decompiled_code.str();
192  }
193 
194  if (!_this->thread_)
195  // We're running in diagnostic time without a thread. Just return.
196  return 0;
197  thread_ret_val(0);
198 }
199 
200 TDecompiler::TDecompiler(uint32 ostream_id, std::string header) : _Object(), ostream_id_(ostream_id), header_(header), thread_(NULL), spawned_(0) {
201 
202  objects_.reserve(ObjectsInitialSize);
203 }
204 
205 TDecompiler::~TDecompiler() {
206 
207  if (thread_)
208  delete thread_;
209 }
210 
211 void TDecompiler::add_object(Code *object) {
212 
213  objects_.push_back(object);
214 }
215 
216 void TDecompiler::add_objects(const r_code::list<P<Code> > &objects) {
217 
218  r_code::list<P<Code> >::const_iterator o;
219  for (o = objects.begin(); o != objects.end(); ++o)
220  objects_.push_back(*o);
221 }
222 
223 void TDecompiler::add_objects(const vector<P<Code> > &objects) {
224 
225  vector<P<Code> >::const_iterator o;
226  for (o = objects.begin(); o != objects.end(); ++o)
227  objects_.push_back(*o);
228 }
229 
230 void TDecompiler::decompile() {
231 
232  if (_Mem::Get()->get_reduction_core_count() == 0 && _Mem::Get()->get_time_core_count() == 0)
233  // We are running in diagnostic time with deterministic execution. Call Decompile in the current thread.
234  Decompile(this);
235  else {
236  thread_ = Thread::New<_Thread>(Decompile, this);
237  while (spawned_ == 0);
238  }
239 }
240 
242 
243 vector<PipeOStream *> PipeOStream::Streams_;
244 
245 PipeOStream PipeOStream::NullStream_;
246 
247 void PipeOStream::Open(uint8 count) {
248 
249 #ifdef WINDOWS
250  for (uint8 i = 0; i < count; ++i) {
251 
252  PipeOStream *p = new PipeOStream();
253  p->init();
254 
255  Streams_.push_back(p);
256  }
257 #endif
258 }
259 
260 void PipeOStream::Close() {
261 
262 #ifdef WINDOWS
263  for (uint8 i = 0; i < Streams_.size(); ++i)
264  delete Streams_[i];
265  Streams_.clear();
266 #endif
267 }
268 
269 PipeOStream &PipeOStream::Get(uint8 id) {
270 
271 #ifdef WINDOWS
272  if (id < Streams_.size())
273  return *Streams_[id];
274 #endif
275  return NullStream_;
276 }
277 
278 PipeOStream::PipeOStream() : std::ostream(NULL)
279 #ifdef WINDOWS
280  , pipe_read_(0), pipe_write_(0)
281 #endif
282 {
283 }
284 
285 #ifdef WINDOWS
286 void PipeOStream::init() {
287 
288  SECURITY_ATTRIBUTES saAttr;
289  saAttr.nLength = sizeof(saAttr);
290  saAttr.bInheritHandle = true;
291  saAttr.lpSecurityDescriptor = NULL;
292 
293  CreatePipe(&pipe_read_, &pipe_write_, &saAttr, 0);
294 
295  STARTUPINFO si;
296  PROCESS_INFORMATION pi;
297 
298  ZeroMemory(&si, sizeof(si));
299  si.cb = sizeof(si);
300  ZeroMemory(&pi, sizeof(pi));
301 
302  char handle[255];
303  itoa((int)pipe_read_, handle, 10);
304  std::string command("output_window.exe ");
305  command += std::string(handle);
306 
307  CreateProcess(NULL, // no module name (use command line)
308  const_cast<char *>(command.c_str()), // command line
309  NULL, // process handle not inheritable
310  NULL, // thread handle not inheritable
311  true, // handle inheritance
312  CREATE_NEW_CONSOLE, // creation flags
313  NULL, // use parent's environment block
314  NULL, // use parent's starting directory
315  &si, // pointer to STARTUPINFO structure
316  &pi); // pointer to PROCESS_INFORMATION structure
317 }
318 #endif
319 
320 PipeOStream::~PipeOStream() {
321 
322 #ifdef WINDOWS
323  if (pipe_read_ == 0)
324  return;
325 
326  std::string stop("close_output_window");
327  *this << stop;
328  CloseHandle(pipe_read_);
329  CloseHandle(pipe_write_);
330 #endif
331 }
332 
333 PipeOStream &PipeOStream::operator <<(std::string &s) {
334 
335 #ifdef WINDOWS // TODO: Implement for non-WINDOWS
336  if (pipe_read_ == 0)
337  return *this;
338 
339  uint32 to_write = s.length();
340  uint32 written;
341 
342  WriteFile(pipe_write_, s.c_str(), to_write, &written, NULL);
343 #endif
344 
345  return *this;
346 }
347 
348 PipeOStream& PipeOStream::operator <<(const char *s) {
349 
350 #ifdef WINDOWS
351  if (pipe_read_ == 0)
352  return *this;
353 
354  uint32 to_write = strlen(s);
355  uint32 written;
356 
357  WriteFile(pipe_write_, s, to_write, &written, NULL);
358 #endif
359 
360  return *this;
361 }
362 
364 
365 uint16 RetrieveOpcode(const char *name) {
366 
367  return _Opcodes.find(name)->second;
368 }
369 
370 bool InitOpcodes(const r_comp::Metadata& metadata) {
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) {
374 
375  _Opcodes[it->first] = it->second.atom_.asOpcode();
376  auto opcode = it->second.atom_.asOpcode();
377  if (opcode_names.find(opcode) == opcode_names.end())
378  // No existing entry for the opcode.
379  opcode_names[opcode] = set<string>();
380  opcode_names[opcode].insert(it->first.c_str());
381  }
382  for (it = metadata.sys_classes_.begin(); it != metadata.sys_classes_.end(); ++it) {
383 
384  _Opcodes[it->first] = it->second.atom_.asOpcode();
385  auto opcode = it->second.atom_.asOpcode();
386  if (opcode_names.find(opcode) == opcode_names.end())
387  // No existing entry for the opcode.
388  opcode_names[opcode] = set<string>();
389  opcode_names[opcode].insert(it->first.c_str());
390  }
391  if (!r_code::SetOpcodeNames(opcode_names))
392  return false;
393 
394  // load class Opcodes.
395  View::ViewOpcode_ = _Opcodes.find("view")->second;
396 
397  Opcodes::View = _Opcodes.find("view")->second;
398  Opcodes::PgmView = _Opcodes.find("pgm_view")->second;
399  Opcodes::GrpView = _Opcodes.find("grp_view")->second;
400 
401  Opcodes::TI = _Opcodes.find("ti")->second;
402 
403  Opcodes::Ent = _Opcodes.find("ent")->second;
404  Opcodes::Ont = _Opcodes.find("ont")->second;
405  Opcodes::MkVal = _Opcodes.find("mk.val")->second;
406 
407  Opcodes::Grp = _Opcodes.find("grp")->second;
408 
409  Opcodes::Ptn = _Opcodes.find("ptn")->second;
410  Opcodes::AntiPtn = _Opcodes.find("|ptn")->second;
411 
412  Opcodes::IPgm = _Opcodes.find("ipgm")->second;
413  Opcodes::ICppPgm = _Opcodes.find("icpp_pgm")->second;
414 
415  Opcodes::Pgm = _Opcodes.find("pgm")->second;
416  Opcodes::AntiPgm = _Opcodes.find("|pgm")->second;
417 
418  Opcodes::ICmd = _Opcodes.find("icmd")->second;
419  Opcodes::Cmd = _Opcodes.find("cmd")->second;
420 
421  Opcodes::Fact = _Opcodes.find("fact")->second;
422  Opcodes::AntiFact = _Opcodes.find("|fact")->second;
423 
424  Opcodes::Cst = _Opcodes.find("cst")->second;
425  Opcodes::Mdl = _Opcodes.find("mdl")->second;
426 
427  Opcodes::ICst = _Opcodes.find("icst")->second;
428  Opcodes::IMdl = _Opcodes.find("imdl")->second;
429 
430  Opcodes::Pred = _Opcodes.find("pred")->second;
431  Opcodes::Goal = _Opcodes.find("goal")->second;
432 
433  Opcodes::Success = _Opcodes.find("success")->second;
434 
435  Opcodes::MkGrpPair = _Opcodes.find("mk.grp_pair")->second;
436 
437  Opcodes::MkRdx = _Opcodes.find("mk.rdx")->second;
438  Opcodes::Perf = _Opcodes.find("perf")->second;
439 
440  Opcodes::MkNew = _Opcodes.find("mk.new")->second;
441 
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;
449 
450  Opcodes::Sim = _Opcodes.find("sim")->second;
451  Opcodes::Id = _Opcodes.find("id")->second;
452 
453  // load executive function Opcodes.
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;
464 
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;
473 
474  Opcodes::Var = _Opcodes.find("var")->second;
475 
476  // load std operators.
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);
503 
504  return true;
505 }
506 
507 static bool Init(FunctionLibrary* userOperatorLibrary,
508  Timestamp (*time_base)()) {
509 
510  Now = time_base;
511 
512  if (!InitOpcodes(Metadata))
513  return false;
514 
515  if (!userOperatorLibrary) // when no rMem is used.
516  return true;
517 
518  // load usr operators and c++ programs.
519 
520  // Operators.
521  typedef uint16 (*OpcodeRetriever)(const char *);
522  typedef r_code::resized_vector<uint16> (*UserInit)(OpcodeRetriever);
523  auto _Init = (UserInit)userOperatorLibrary->getFunction("Init");
524  if (!_Init)
525  return false;
526 
527  typedef uint16 (*UserGetOperatorCount)();
528  auto GetOperatorCount = (UserGetOperatorCount)userOperatorLibrary->getFunction("GetOperatorCount");
529  if (!GetOperatorCount)
530  return false;
531 
532  typedef void (*UserGetOperatorName)(char *);
533  auto GetOperatorName = (UserGetOperatorName)userOperatorLibrary->getFunction("GetOperatorName");
534  if (!GetOperatorName)
535  return false;
536 
537  Metadata.usr_classes_ = _Init(RetrieveOpcode);
538 
539  typedef bool (*UserOperator)(const Context &);
540 
541  uint16 operatorCount = GetOperatorCount();
542  for (uint16 i = 0; i < operatorCount; ++i) {
543 
544  char op_name[256];
545  memset(op_name, 0, 256);
546  GetOperatorName(op_name);
547 
548  unordered_map<std::string, uint16>::iterator it = _Opcodes.find(op_name);
549  if (it == _Opcodes.end()) {
550 
551  std::cerr << "Operator " << op_name << " is undefined" << std::endl;
552  exit(-1);
553  }
554  auto op = (UserOperator)userOperatorLibrary->getFunction(op_name);
555  if (!op)
556  return false;
557 
558  Operator::Register(it->second, op);
559  }
560 
561  // C++ programs.
562  typedef uint16 (*UserGetProgramCount)();
563  auto GetProgramCount = (UserGetProgramCount)userOperatorLibrary->getFunction("GetProgramCount");
564  if (!GetProgramCount)
565  return false;
566 
567  typedef void (*UserGetProgramName)(char *);
568  auto GetProgramName = (UserGetProgramName)userOperatorLibrary->getFunction("GetProgramName");
569  if (!GetProgramName)
570  return false;
571 
572  typedef Controller *(*UserProgram)(_View *);
573 
574  uint16 programCount = GetProgramCount();
575  for (uint16 i = 0; i < programCount; ++i) {
576 
577  char pgm_name[256];
578  memset(pgm_name, 0, 256);
579  GetProgramName(pgm_name);
580 
581  std::string _pgm_name = pgm_name;
582 
583  auto pgm = (UserProgram)userOperatorLibrary->getFunction(pgm_name);
584  if (!pgm)
585  return false;
586 
587  CPPPrograms::Register(_pgm_name, pgm);
588  }
589 
590  // Callbacks.
591  typedef uint16(*UserGetCallbackCount)();
592  auto GetCallbackCount = (UserGetCallbackCount)userOperatorLibrary->getFunction("GetCallbackCount");
593  if (!GetCallbackCount)
594  return false;
595 
596  typedef void(*UserGetCallbackName)(char *);
597  auto GetCallbackName = (UserGetCallbackName)userOperatorLibrary->getFunction("GetCallbackName");
598  if (!GetCallbackName)
599  return false;
600 
601  typedef bool(*UserCallback)(microseconds, bool, const char *, uint8, Code **);
602 
603  uint16 callbackCount = GetCallbackCount();
604  for (uint16 i = 0; i < callbackCount; ++i) {
605 
606  char callback_name[256];
607  memset(callback_name, 0, 256);
608  GetCallbackName(callback_name);
609 
610  std::string _callback_name = callback_name;
611 
612  auto callback = (UserCallback)userOperatorLibrary->getFunction(callback_name);
613  if (!callback)
614  return false;
615 
616  Callbacks::Register(_callback_name, callback);
617  }
618 
619  std::cout << "> user-defined operator library loaded" << std::endl;
620 
621  return true;
622 }
623 
624 bool Init(FunctionLibrary* userOperatorLibrary,
625  Timestamp (*time_base)(),
626  const char *seed_path) {
627 
628  std::string error;
629  if (!Compile(seed_path, error, true)) {
630 
631  std::cerr << error << std::endl;
632  return false;
633  }
634 
635  return Init(userOperatorLibrary, time_base);
636 }
637 
638 bool Init(FunctionLibrary* userOperatorLibrary,
639  Timestamp (*time_base)(),
640  const r_comp::Metadata &metadata,
641  const r_comp::Image &seed) {
642 
643  Metadata = metadata;
644  Seed = seed;
645 
646  return Init(userOperatorLibrary, time_base);
647 }
648 
649 uint16 GetOpcode(const char *name) {
650 
651  unordered_map<std::string, uint16>::iterator it = _Opcodes.find(name);
652  if (it == _Opcodes.end())
653  return 0xFFFF;
654  return it->second;
655 }
656 
657 std::string GetAxiomName(const uint16 index) {
658 
659  return Compiler.getObjectName(index);
660 }
661 
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();
665 }
666 
667 bool hasUserDefinedOperators(const std::string class_name) {
668  if (_Opcodes.find(class_name) == _Opcodes.end()) {
669  return false;
670  }
671  return hasUserDefinedOperators(_Opcodes[class_name]);
672 }
673 
674 }
r_code::resized_vector< uint16 >
r_comp::Preprocessor
Definition: preprocessor.h:181
r_code::_View
Definition: r_code/object.h:164
r_comp::Image::add_objects
void add_objects(r_code::list< P< r_code::Code > > &objects, bool include_invalidated=false)
Definition: segments.cpp:491
r_comp::Compiler
Definition: compiler.h:97
core::P
Definition: base.h:103
r_code::Code
Definition: r_code/object.h:224
r_comp::Decompiler
Definition: decompiler.h:98
core::_Object
Definition: base.h:131
r_comp::Image
Definition: segments.h:177
r_code::list
Definition: list.h:99
r_comp::Metadata
Definition: segments.h:109