87 #include <experimental/filesystem>
88 #include "preprocessor.h"
90 #include "../submodules/CoreLibrary/CoreLibrary/utils.h"
91 namespace fs = std::experimental::filesystem;
94 using namespace r_code;
98 unordered_map<std::string, RepliMacro *> RepliStruct::RepliMacros_;
99 unordered_map<std::string, int32> RepliStruct::Counters_;
100 std::list<RepliCondition *> RepliStruct::Conditions_;
101 uint32 RepliStruct::GlobalLine_ = 1;
102 vector<std::string> RepliStruct::LoadedFilePaths_;
104 RepliStruct::RepliStruct(RepliStruct::Type type) {
110 RepliStruct::~RepliStruct() {
114 void RepliStruct::reset() {
116 std::list<RepliStruct*>::const_iterator arg;
117 for (arg = args_.begin(); arg != args_.end();) {
119 switch ((*arg)->type_) {
120 case RepliStruct::Atom:
121 case RepliStruct::Structure:
122 case RepliStruct::Development:
123 case RepliStruct::Set:
124 arg = args_.erase(arg);
132 uint32 RepliStruct::getIndent(std::istream *stream) {
135 while (!stream->eof()) {
136 switch (stream->get()) {
140 stream->seekg(-1, std::ios_base::cur);
146 stream->seekg(-1, std::ios_base::cur);
153 int32 RepliStruct::parse(std::istream *stream,
const std::string& file_path, uint32 &cur_indent, uint32 &prev_indent, int32 param_expect) {
155 char c = 0, lastc = 0, lastcc, tc;
156 std::string str, label;
157 RepliStruct* sub_struct;
159 int32 param_count = 0;
160 int32 return_indent = 0;
162 bool in_comment =
false;
163 bool expect_set =
false;
165 while (!stream->eof()) {
171 if (!in_comment && c ==
'\"') {
182 if (c == 10 || c == 13) {
184 error_ +=
"Newline is not permitted in a string. ";
192 if (in_comment)
continue;
194 error_ +=
"Tabs chars are not permitted. ";
197 if (in_comment)
continue;
199 sub_struct =
new RepliStruct(Directive);
200 sub_struct->parent_ =
this;
201 args_.push_back(sub_struct);
202 if (!sub_struct->parseDirective(stream, file_path, cur_indent, prev_indent))
204 if (sub_struct->cmd_.compare(
"!load") == 0)
206 sub_struct->filePath_ = file_path;
209 error_ +=
"Directive not allowed inside a structure. ";
218 if ((lastc ==
'.') && (lastcc ==
'.'))
224 while ((!stream->eof()) && (stream->peek() < 32))
225 if (stream->get() == 10)
228 prev_indent = cur_indent;
229 cur_indent = getIndent(stream);
231 if (cur_indent > prev_indent) {
235 sub_struct =
new RepliStruct(Set);
236 sub_struct->parent_ =
this;
237 sub_struct->label_ = label;
239 args_.push_back(sub_struct);
240 return_indent = sub_struct->parse(stream, file_path, cur_indent, prev_indent);
242 if (return_indent < 0)
244 if ((param_expect > 0) && (++param_count == param_expect))
246 if (return_indent > 0)
247 return (return_indent - 1);
251 sub_struct =
new RepliStruct(Structure);
252 args_.push_back(sub_struct);
253 return_indent = sub_struct->parse(stream, file_path, cur_indent, prev_indent);
255 if (return_indent < 0)
257 if ((param_expect > 0) && (++param_count == param_expect))
259 if (return_indent > 0)
260 return (return_indent - 1);
263 else if (cur_indent < prev_indent) {
264 if (str.size() > 0) {
265 if ((cmd_.size() > 0) || (type_ == Set)) {
266 sub_struct =
new RepliStruct(
Atom);
267 sub_struct->parent_ =
this;
268 args_.push_back(sub_struct);
269 sub_struct->cmd_ = str;
271 if ((param_expect > 0) && (++param_count == param_expect))
280 return prev_indent - cur_indent - 1;
284 if (str.size() > 0) {
285 if ((cmd_.size() > 0) || (type_ == Set) || (type_ == Root)) {
286 sub_struct =
new RepliStruct(
Atom);
287 sub_struct->parent_ =
this;
288 args_.push_back(sub_struct);
289 sub_struct->cmd_ = str;
291 if ((param_expect > 0) && (++param_count == param_expect))
305 if (in_comment)
continue;
307 if (str.size() > 0) {
308 if ((cmd_.size() > 0) || (type_ == Set) || (type_ == Development)) {
309 sub_struct =
new RepliStruct(
Atom);
310 sub_struct->parent_ =
this;
311 args_.push_back(sub_struct);
312 sub_struct->cmd_ = str;
314 if ((param_expect > 0) && (++param_count == param_expect))
324 if (in_comment)
continue;
326 if (str.size() > 0) {
331 else if ((cmd_.size() > 0) || (type_ == Set)) {
332 sub_struct =
new RepliStruct(
Atom);
333 sub_struct->parent_ =
this;
334 args_.push_back(sub_struct);
335 sub_struct->cmd_ = str;
337 if ((param_expect > 0) && (++param_count == param_expect))
345 sub_struct =
new RepliStruct(Structure);
346 sub_struct->label_ = label;
348 sub_struct->parent_ =
this;
349 args_.push_back(sub_struct);
350 return_indent = sub_struct->parse(stream, file_path, cur_indent, prev_indent);
351 if (return_indent < 0)
353 if ((param_expect > 0) && (++param_count == param_expect))
355 if (return_indent > 0)
356 return (return_indent - 1);
359 if (in_comment)
continue;
361 if (stream->peek() ==
':') {
363 while ((!stream->eof()) && ((c = stream->get()) > 32))
367 if (str.size() > 0) {
368 if ((cmd_.size() > 0) || (type_ == Set)) {
369 sub_struct =
new RepliStruct(
Atom);
370 sub_struct->parent_ =
this;
371 args_.push_back(sub_struct);
372 sub_struct->cmd_ = str;
374 if ((param_expect > 0) && (++param_count == param_expect))
384 if (in_comment)
continue;
386 if (str.size() > 0) {
391 else if ((cmd_.size() > 0) || (type_ == Set)) {
392 sub_struct =
new RepliStruct(
Atom);
393 sub_struct->parent_ =
this;
394 args_.push_back(sub_struct);
395 sub_struct->cmd_ = str;
397 if ((param_expect > 0) && (++param_count == param_expect))
405 sub_struct =
new RepliStruct(Development);
406 sub_struct->label_ = label;
408 sub_struct->parent_ =
this;
409 args_.push_back(sub_struct);
410 return_indent = sub_struct->parse(stream, file_path, cur_indent, prev_indent);
411 if (return_indent < 0)
413 if ((param_expect > 0) && (++param_count == param_expect))
415 if (return_indent > 0)
416 return (return_indent - 1);
419 if (in_comment)
continue;
421 if (stream->peek() ==
':') {
423 while ((!stream->eof()) && ((c = stream->get()) > 32))
427 if (str.size() > 0) {
428 if ((cmd_.size() > 0) || (type_ == Set) || (type_ == Development)) {
429 sub_struct =
new RepliStruct(
Atom);
430 sub_struct->parent_ =
this;
431 args_.push_back(sub_struct);
432 sub_struct->cmd_ = str;
434 if ((param_expect > 0) && (++param_count == param_expect))
444 if (in_comment)
continue;
445 if (stream->peek() ==
'[') {
454 if (in_comment)
continue;
459 if (stream->peek() ==
']') {
462 if (((tc = stream->peek()) < 32) || (tc ==
';'))
466 if ((lastc !=
':') && (lastc > 32)) {
472 sub_struct =
new RepliStruct(Set);
473 sub_struct->parent_ =
this;
474 sub_struct->label_ = label;
475 args_.push_back(sub_struct);
480 if (str.size() > 0) {
481 if ((cmd_.size() > 0) || (type_ == Set)) {
482 sub_struct =
new RepliStruct(
Atom);
483 sub_struct->parent_ =
this;
484 args_.push_back(sub_struct);
485 sub_struct->cmd_ = str;
487 if ((param_expect > 0) && (++param_count == param_expect))
495 sub_struct =
new RepliStruct(Set);
496 sub_struct->parent_ =
this;
497 sub_struct->label_ = label;
499 args_.push_back(sub_struct);
500 return_indent = sub_struct->parse(stream, file_path, cur_indent, prev_indent);
501 if (return_indent < 0)
503 if ((param_expect > 0) && (++param_count == param_expect))
505 if (return_indent > 0)
506 return (return_indent - 1);
510 if (in_comment)
continue;
512 if (str.size() > 0) {
513 if ((cmd_.size() > 0) || (type_ == Set)) {
514 sub_struct =
new RepliStruct(
Atom);
515 sub_struct->parent_ =
this;
516 args_.push_back(sub_struct);
517 sub_struct->cmd_ = str;
519 if ((param_expect > 0) && (++param_count == param_expect))
529 if (in_comment)
continue;
538 bool RepliStruct::parseDirective(std::istream *stream,
const std::string& file_path, uint32 &cur_indent, uint32 &prev_indent) {
540 std::string str =
"!";
545 while ((!stream->eof()) && ((c = stream->peek()) > 32))
546 str += stream->get();
548 error_ +=
"Error in directive formatting, end of file reached unexpectedly. ";
552 unsigned int param_count = 0;
554 if (str.compare(
"!def") == 0)
556 else if (str.compare(
"!counter") == 0)
558 else if (str.compare(
"!undef") == 0)
560 else if (str.compare(
"!ifdef") == 0) {
564 else if (str.compare(
"!ifundef") == 0) {
568 else if (str.compare(
"!else") == 0) {
572 else if (str.compare(
"!endif") == 0) {
576 else if (str.compare(
"!class") == 0)
578 else if (str.compare(
"!op") == 0)
580 else if (str.compare(
"!dfn") == 0)
582 else if (str.compare(
"!load") == 0)
585 error_ +=
"Unknown directive: '" + str +
"'. ";
590 if (param_count == 0) {
592 while ((!stream->eof()) && (stream->peek() > 13))
595 while ((!stream->eof()) && (stream->peek() < 32))
596 if (stream->get() == 10)
601 if (parse(stream, file_path, cur_indent, prev_indent, param_count) != 0) {
602 error_ +=
"Error parsing the arguments for directive '" + cmd_ +
"'. ";
610 int32 RepliStruct::process() {
612 int32 changes = 0, count;
613 RepliStruct *structure, *new_struct, *temp_struct;
615 RepliCondition* cond;
616 std::string load_error;
619 if (Counters_.find(cmd_) != Counters_.end()) {
621 cmd_ = std::to_string(Counters_[cmd_]++);
625 if (RepliMacros_.find(cmd_) != RepliMacros_.end()) {
627 macro = RepliMacros_[cmd_];
628 new_struct = macro->expandMacro(
this);
629 if (new_struct != NULL) {
635 error_ = macro->error_;
641 if (args_.size() == 0)
644 for (std::list<RepliStruct*>::iterator iter(args_.begin()), iterEnd(args_.end()); iter != iterEnd; ++iter) {
648 if (structure->type_ == Condition) {
649 if (structure->cmd_.compare(
"!ifdef") == 0) {
650 cond =
new RepliCondition(structure->args_.front()->cmd_,
false);
651 Conditions_.push_back(cond);
653 else if (structure->cmd_.compare(
"!ifundef") == 0) {
654 cond =
new RepliCondition(structure->args_.front()->cmd_,
true);
655 Conditions_.push_back(cond);
657 else if (structure->cmd_.compare(
"!else") == 0) {
659 Conditions_.back()->reverse();
661 else if (structure->cmd_.compare(
"!endif") == 0) {
662 Conditions_.pop_back();
668 for (std::list<RepliCondition*>::const_iterator iCon(Conditions_.begin()), iConEnd(Conditions_.end()); iCon != iConEnd; ++iCon) {
671 if (!((*iCon)->isActive(RepliMacros_, Counters_)))
675 if (structure->type_ == Directive) {
676 if (structure->cmd_.compare(
"!counter") == 0) {
678 if (structure->args_.size() > 1)
679 Counters_[structure->args_.front()->cmd_] = atoi(structure->args_.back()->cmd_.c_str());
681 Counters_[structure->args_.front()->cmd_] = 0;
683 else if (structure->cmd_.compare(
"!def") == 0) {
685 while ((count = structure->args_.back()->process()) > 0)
690 macro =
new RepliMacro(structure->args_.front()->cmd_, structure->args_.front(), structure->args_.back());
691 RepliMacros_[macro->name_] = macro;
693 else if (structure->cmd_.compare(
"!undef") == 0) {
695 RepliMacros_.erase(RepliMacros_.find(structure->args_.front()->cmd_));
696 Counters_.erase(Counters_.find(structure->args_.front()->cmd_));
698 else if (structure->cmd_.compare(
"!load") == 0) {
700 fs::path loadPath = fs::path(structure->args_.front()->cmd_);
701 if (loadPath.is_relative()) {
703 fs::path containingDirectory = fs::path(structure->filePath_).parent_path();
704 loadPath = containingDirectory / loadPath;
707 new_struct = loadReplicodeFile(loadPath.string());
708 if (new_struct == NULL) {
709 structure->error_ +=
"Load: File '" + loadPath.string() +
"' cannot be read! ";
712 else if ((load_error = new_struct->printError()).size() > 0) {
713 structure->error_ = load_error;
719 temp_struct = (*iter);
721 args_.insert(++iter, new_struct->args_.begin(), new_struct->args_.end());
725 iter = args_.begin();
726 iterEnd = args_.end();
727 while ((*iter) != temp_struct) iter++;
730 args_.remove(temp_struct);
731 if (iter != iterEnd) {
733 temp_struct = (*iter);
734 iter = args_.begin();
735 iterEnd = args_.end();
736 while ((*iter) != temp_struct) iter++;
743 if (RepliMacros_.find(structure->cmd_) != RepliMacros_.end()) {
745 macro = RepliMacros_[structure->cmd_];
746 new_struct = macro->expandMacro(structure);
747 if (new_struct != NULL) {
748 *structure = *new_struct;
753 structure->error_ = macro->error_;
760 for (std::list<RepliStruct*>::iterator iter2(structure->args_.begin()), iter2End(structure->args_.end()); iter2 != iter2End; ++iter2) {
761 if ((count = (*iter2)->process()) > 0)
769 if (Counters_.find(structure->cmd_) != Counters_.end()) {
771 structure->cmd_ = std::to_string(Counters_[structure->cmd_]++);
783 RepliStruct *RepliStruct::loadReplicodeFile(
const std::string &filename) {
786 if (isFileLoaded(filename)) {
792 LoadedFilePaths_.push_back(filename);
794 std::ifstream load_stream(filename.c_str(), std::ios::binary | ios::in);
795 if (load_stream.bad() || load_stream.fail() || load_stream.eof()) {
796 new_root->error_ +=
"Load: File '" + filename +
"' cannot be read! ";
802 if (new_root->parse(&load_stream, filename, a, b) < 0) {
805 if (!load_stream.eof())
806 new_root->error_ =
"Code structure error: Unmatched ) or ].\n";
811 bool RepliStruct::isFileLoaded(
const std::string& file_path) {
812 for (
auto loaded_file_path = LoadedFilePaths_.begin();
813 loaded_file_path != LoadedFilePaths_.end();
814 ++loaded_file_path) {
815 if (fs::equivalent(file_path, *loaded_file_path))
822 std::string RepliStruct::print()
const {
824 #if 1 // Just use a stringstream.
838 for (std::list<RepliStruct*>::const_iterator iter(args_.begin()), iterEnd(args_.end()); iter != iterEnd; ++iter)
839 str +=
" " + (*iter)->print();
840 if (type_ == Structure)
841 return label_ +
"(" + str +
")" + tail_;
842 else if (type_ == Development)
843 return label_ +
"{" + str +
"}" + tail_;
847 for (std::list<RepliStruct*>::const_iterator iter(args_.begin()), last(args_.end()), iterEnd(last--); iter != iterEnd; ++iter) {
848 str += (*iter)->print();
852 return label_ +
"[" + str +
"]" + tail_;
854 for (std::list<RepliStruct*>::const_iterator iter(args_.begin()), iterEnd(args_.end()); iter != iterEnd; ++iter)
855 str += (*iter)->print() +
"\n";
864 std::ostream &operator<<(std::ostream &os, RepliStruct *structure) {
866 return operator<<(os, *structure);
869 std::ostream &operator<<(std::ostream &os,
const RepliStruct &structure) {
871 switch (structure.type_) {
872 case RepliStruct::Atom:
873 return os << structure.cmd_;
874 case RepliStruct::Directive:
875 case RepliStruct::Condition:
877 case RepliStruct::Structure:
878 case RepliStruct::Development:
879 if (structure.type_ == RepliStruct::Structure)
880 os << structure.label_ <<
"(";
881 else if (structure.type_ == RepliStruct::Development)
882 os << structure.label_ <<
"{";
883 os << structure.cmd_;
884 for (std::list<RepliStruct*>::const_iterator iter(structure.args_.begin()), iterEnd(structure.args_.end()); iter != iterEnd; ++iter)
885 os <<
" " << (*iter);
886 if (structure.type_ == RepliStruct::Structure)
887 os <<
")" << structure.tail_;
888 else if (structure.type_ == RepliStruct::Development)
889 os <<
"}" << structure.tail_;
891 case RepliStruct::Set:
892 os << structure.label_ <<
"[";
893 if (structure.args_.size() > 0) {
894 for (std::list<RepliStruct*>::const_iterator iter(structure.args_.begin()), last(structure.args_.end()), iterEnd(last--); iter != iterEnd; ++iter) {
900 os <<
"]" << structure.tail_;
902 case RepliStruct::Root:
903 for (std::list<RepliStruct*>::const_iterator iter(structure.args_.begin()), iterEnd(structure.args_.end()); iter != iterEnd; ++iter)
904 os << (*iter) << std::endl;
912 RepliStruct *RepliStruct::clone()
const {
914 RepliStruct* new_struct =
new RepliStruct(type_);
915 new_struct->cmd_ = cmd_;
916 new_struct->label_ = label_;
917 new_struct->tail_ = tail_;
918 new_struct->parent_ = parent_;
919 new_struct->error_ = error_;
920 new_struct->line_ = line_;
921 for (std::list<RepliStruct*>::const_iterator iter(args_.begin()), iterEnd(args_.end()); iter != iterEnd; ++iter)
922 new_struct->args_.push_back((*iter)->clone());
926 std::string RepliStruct::printError()
const {
928 std::stringstream str_error;
929 if (error_.size() > 0) {
930 std::string com = cmd_;
931 RepliStruct* structure = parent_;
932 while ((cmd_.size() == 0) && (structure != NULL)) {
933 com = structure->cmd_;
934 structure = structure->parent_;
937 str_error <<
"Error";
939 str_error <<
"Error in structure '" << com <<
"'";
941 str_error <<
" line " << line_;
942 str_error <<
": " << error_ << std::endl;
944 for (std::list<RepliStruct*>::const_iterator iter(args_.begin()), iterEnd(args_.end()); iter != iterEnd; ++iter)
945 str_error << (*iter)->printError();
946 return str_error.str();
949 RepliMacro::RepliMacro(
const std::string &name, RepliStruct *src, RepliStruct *dest) {
956 RepliMacro::~RepliMacro() {
963 uint32 RepliMacro::argCount() {
967 return src_->args_.size();
970 RepliStruct *RepliMacro::expandMacro(RepliStruct *old_struct) {
973 error_ +=
"Macro '" + name_ +
"' source not defined. ";
977 error_ +=
"Macro '" + name_ +
"' destination not defined. ";
980 if (old_struct == NULL) {
981 error_ +=
"Macro '" + name_ +
"' cannot expand empty structure. ";
984 if (old_struct->cmd_.compare(name_) != 0) {
985 error_ +=
"Macro '" + name_ +
"' cannot expand structure with different name '" + old_struct->cmd_ +
"'. ";
989 if ((src_->args_.size() > 0) && (src_->args_.size() != old_struct->args_.size())) {
990 error_ +=
"Macro '" + name_ +
"' requires " + std::to_string(src_->args_.size()) +
" arguments, cannot expand structure with " + std::to_string(old_struct->args_.size()) +
" arguments. ";
994 RepliStruct* new_struct;
997 if ((src_->args_.size() == 0) && (old_struct->args_.size() > 0)) {
998 new_struct = old_struct->clone();
999 new_struct->cmd_ = dest_->cmd_;
1000 new_struct->label_ = old_struct->label_;
1004 new_struct = dest_->clone();
1005 new_struct->label_ = old_struct->label_;
1008 RepliStruct *find_struct;
1010 std::list<RepliStruct*>::const_iterator i_old(old_struct->args_.begin());
1011 for (std::list<RepliStruct*>::const_iterator i_src(src_->args_.begin()), i_src_end(src_->args_.end()); i_src != i_src_end; ++i_src, ++i_old) {
1014 find_struct = new_struct->findAtom((*i_src)->cmd_);
1015 if (find_struct != NULL) {
1017 *find_struct = *(*i_old);
1024 RepliStruct *RepliStruct::findAtom(
const std::string &name) {
1026 RepliStruct* structure;
1027 for (std::list<RepliStruct*>::iterator iter(args_.begin()), iterEnd(args_.end()); iter != iterEnd; ++iter) {
1028 switch ((*iter)->type_) {
1030 if ((*iter)->cmd_.compare(name) == 0)
1036 structure = (*iter)->findAtom(name);
1037 if (structure != NULL)
1049 RepliCondition::RepliCondition(
const std::string &name,
bool reversed) {
1052 reversed_ = reversed;
1055 RepliCondition::~RepliCondition() {
1058 void RepliCondition::reverse() {
1060 reversed_ = !reversed_;
1063 bool RepliCondition::isActive(unordered_map<std::string, RepliMacro *> &repli_macros, unordered_map<std::string, int32> &counters) {
1065 bool found_it = (repli_macros.find(name_) != repli_macros.end());
1068 found_it = (counters.find(name_) != counters.end());
1078 Preprocessor::Preprocessor() {
1080 root_ =
new RepliStruct(RepliStruct::Root);
1083 Preprocessor::~Preprocessor() {
1088 bool Preprocessor::process(std::istream *stream,
1089 const std::string& file_path,
1090 std::ostringstream *out_stream,
1092 Metadata *metadata) {
1097 RepliStruct::LoadedFilePaths_.push_back(file_path);
1101 uint32 a = 0, b = 0;
1102 if (root_->parse(stream, file_path, a, b) < 0) {
1104 error = root_->printError();
1107 if (!stream->eof()) {
1109 error =
"Code structure error: Unmatched ) or ].\n";
1115 int32 pass = 0, total = 0, count;
1116 while ((count = root_->process()) > 0) {
1124 error = root_->printError();
1129 *out_stream << root_;
1132 initialize(metadata);
1134 error = root_->printError();
1135 return (error.size() == 0);
1138 bool Preprocessor::isTemplateClass(RepliStruct *s) {
1140 for (std::list<RepliStruct *>::iterator j(s->args_.begin()); j != s->args_.end(); ++j) {
1144 switch ((*j)->type_) {
1145 case RepliStruct::Atom:
1146 if ((*j)->cmd_ ==
":~")
1149 case RepliStruct::Structure:
1150 case RepliStruct::Development:
1151 case RepliStruct::Set:
1152 if (isTemplateClass(*j))
1162 bool Preprocessor::isSet(std::string class_name) {
1164 for (std::list<RepliStruct *>::iterator i(root_->args_.begin()); i != root_->args_.end(); ++i) {
1166 if ((*i)->type_ != RepliStruct::Directive || (*i)->cmd_ !=
"!class")
1168 RepliStruct *s = *(*i)->args_.begin();
1169 if (s->cmd_ == class_name)
1171 if (s->cmd_ == class_name +
"[]")
1177 void Preprocessor::instantiateClass(RepliStruct *tpl_class, std::list<RepliStruct *> &tpl_args, std::string &instantiated_class_name) {
1179 static uint32 LastClassID = 0;
1181 std::string sset =
"[]";
1182 instantiated_class_name = tpl_class->cmd_;
1183 instantiated_class_name = instantiated_class_name.substr(0, instantiated_class_name.length() - sset.length());
1185 instantiated_class_name += std::to_string(LastClassID++);
1187 vector<StructureMember> members;
1188 std::list<RepliStruct *> _tpl_args;
1189 for (std::list<RepliStruct *>::reverse_iterator i = tpl_args.rbegin(); i != tpl_args.rend(); ++i)
1190 _tpl_args.push_back(*i);
1191 getMembers(tpl_class, members, _tpl_args,
true);
1193 metadata_->class_names_[class_opcode_] = instantiated_class_name;
1194 metadata_->classes_by_opcodes_[class_opcode_] = metadata_->classes_[instantiated_class_name] = Class(Atom::SSet(class_opcode_, members.size()), instantiated_class_name, members);
1198 void Preprocessor::getMember(vector<StructureMember> &members, RepliStruct *m, std::list<RepliStruct *> &tpl_args,
bool instantiate) {
1204 case RepliStruct::Set:
1205 name = m->label_.substr(0, m->label_.length() - 1);
1206 if (m->args_.size() == 0)
1207 members.push_back(StructureMember(&Compiler::read_set, name));
1210 type = (*m->args_.begin())->cmd_.substr(2, m->cmd_.length() - 1);
1212 members.push_back(StructureMember(&Compiler::read_set, name, type, StructureMember::I_SET));
1213 else if (type == Class::Type)
1214 members.push_back(StructureMember(&Compiler::read_set, name, type, StructureMember::I_DCLASS));
1216 members.push_back(StructureMember(&Compiler::read_set, name, type, StructureMember::I_EXPRESSION));
1219 case RepliStruct::Atom:
1220 if (m->cmd_ ==
"nil")
1222 p = m->cmd_.find(
':');
1223 name = m->cmd_.substr(0, p);
1224 type = m->cmd_.substr(p + 1, m->cmd_.length());
1226 members.push_back(StructureMember(&Compiler::read_any, name));
1227 else if (type ==
"nb")
1228 members.push_back(StructureMember(&Compiler::read_number, name));
1229 else if (type ==
"ts")
1230 members.push_back(StructureMember(&Compiler::read_timestamp, name));
1231 else if (type ==
"us")
1232 members.push_back(StructureMember(&Compiler::read_duration, name));
1233 else if (type ==
"bl")
1234 members.push_back(StructureMember(&Compiler::read_boolean, name));
1235 else if (type ==
"st")
1236 members.push_back(StructureMember(&Compiler::read_string, name));
1237 else if (type ==
"did")
1238 members.push_back(StructureMember(&Compiler::read_device, name));
1239 else if (type ==
"fid")
1240 members.push_back(StructureMember(&Compiler::read_function, name));
1241 else if (type ==
"nid")
1242 members.push_back(StructureMember(&Compiler::read_node, name));
1243 else if (type == Class::Expression)
1244 members.push_back(StructureMember(&Compiler::read_expression, name));
1245 else if (type ==
"~") {
1247 RepliStruct *_m = tpl_args.back();
1248 tpl_args.pop_back();
1249 switch (_m->type_) {
1250 case RepliStruct::Structure: {
1251 std::string instantiated_class_name;
1252 instantiateClass(template_classes_.find(_m->cmd_)->second, _m->args_, instantiated_class_name);
1253 members.push_back(StructureMember(&Compiler::read_set, _m->label_.substr(0, _m->label_.length() - 1), instantiated_class_name, StructureMember::I_CLASS));
1256 getMember(members, _m, tpl_args,
true);
1259 }
else if (type == Class::Type)
1260 members.push_back(StructureMember(&Compiler::read_class, name));
1262 members.push_back(StructureMember(&Compiler::read_expression, name, type));
1264 case RepliStruct::Structure: {
1265 RepliStruct *template_class = template_classes_.find(m->cmd_)->second;
1268 std::string instantiated_class_name;
1269 instantiateClass(template_class, m->args_, instantiated_class_name);
1270 members.push_back(StructureMember(&Compiler::read_set, m->label_.substr(0, m->label_.length() - 1), instantiated_class_name, StructureMember::I_CLASS));
1273 for (std::list<RepliStruct *>::reverse_iterator i = m->args_.rbegin(); i != m->args_.rend(); ++i)
1274 tpl_args.push_back(*i);
1275 getMembers(template_class, members, tpl_args,
false);
1278 }
case RepliStruct::Development:
1279 getMembers(m, members, tpl_args, instantiate);
1286 void Preprocessor::getMembers(RepliStruct *s, vector<StructureMember> &members, std::list<RepliStruct *> &tpl_args,
bool instantiate) {
1288 for (std::list<RepliStruct *>::iterator j(s->args_.begin()); j != s->args_.end(); ++j)
1289 getMember(members, *j, tpl_args, instantiate);
1292 ReturnType Preprocessor::getReturnType(RepliStruct *s) {
1294 if (s->tail_ ==
":nb")
1296 else if (s->tail_ ==
":ts")
1298 else if (s->tail_ ==
":us")
1300 else if (s->tail_ ==
":bl")
1302 else if (s->tail_ ==
":st")
1304 else if (s->tail_ ==
":nid")
1306 else if (s->tail_ ==
":did")
1308 else if (s->tail_ ==
":fid")
1310 else if (s->tail_ ==
":[]")
1315 void Preprocessor::initialize(Metadata *metadata) {
1317 metadata_ = metadata;
1320 uint16 function_opcode = 0;
1321 uint16 operator_opcode = 0;
1323 vector<StructureMember> r_xpr;
1324 metadata->classes_[std::string(Class::Expression)] = Class(Atom::Object(class_opcode_, 0), Class::Expression, r_xpr);
1326 vector<StructureMember> r_type;
1327 metadata->classes_[std::string(Class::Type)] = Class(Atom::Object(class_opcode_, 0), Class::Type, r_type);
1330 for (std::list<RepliStruct *>::iterator i(root_->args_.begin()); i != root_->args_.end(); ++i) {
1332 if ((*i)->type_ != RepliStruct::Directive)
1335 RepliStruct *s = *(*i)->args_.begin();
1336 vector<StructureMember> members;
1337 if ((*i)->cmd_ ==
"!class") {
1339 std::string sset =
"[]";
1340 std::string class_name = s->cmd_;
1341 size_t p = class_name.find(sset);
1342 ClassType class_type = (p == std::string::npos ? T_CLASS : T_SET);
1343 if (class_type == T_SET)
1344 class_name = class_name.substr(0, class_name.length() - sset.length());
1346 if (isTemplateClass(s)) {
1348 template_classes_[class_name] = s;
1352 std::list<RepliStruct *> tpl_args;
1353 getMembers(s, members, tpl_args,
false);
1356 if (class_name ==
"grp")
1357 atom = Atom::Group(class_opcode_, members.size());
1358 else if (class_name ==
"ipgm")
1359 atom = Atom::InstantiatedProgram(class_opcode_, members.size());
1360 else if (class_name ==
"icpp_pgm")
1361 atom = Atom::InstantiatedCPPProgram(class_opcode_, members.size());
1362 else if (class_name ==
"cst")
1363 atom = Atom::CompositeState(class_opcode_, members.size());
1364 else if (class_name ==
"mdl")
1365 atom = Atom::Model(class_opcode_, members.size());
1366 else if (class_name.find(
"mk.") != string::npos)
1367 atom = Atom::Marker(class_opcode_, members.size());
1369 atom = Atom::Object(class_opcode_, members.size());
1371 if (class_type == T_CLASS) {
1373 std::string base_class = s->args_.front()->cmd_;
1374 if (base_class ==
"_obj" || base_class ==
"_grp" || base_class ==
"_fact")
1375 class_type = T_SYS_CLASS;
1378 metadata->class_names_[class_opcode_] = class_name;
1379 switch (class_type) {
1381 metadata->classes_by_opcodes_[class_opcode_] = metadata->classes_[class_name] = metadata->sys_classes_[class_name] = Class(atom, class_name, members);
1384 metadata->classes_by_opcodes_[class_opcode_] = metadata->classes_[class_name] = Class(atom, class_name, members);
1387 metadata->classes_by_opcodes_[class_opcode_] = metadata->classes_[class_name] = Class(Atom::SSet(class_opcode_, members.size()), class_name, members);
1393 }
else if ((*i)->cmd_ ==
"!op") {
1395 std::list<RepliStruct *> tpl_args;
1396 getMembers(s, members, tpl_args,
false);
1397 ReturnType return_type = getReturnType(s);
1399 std::string operator_name = s->cmd_;
1400 metadata->operator_names_.push_back(operator_name);
1401 metadata->classes_[operator_name] = Class(Atom::Operator(operator_opcode, s->args_.size()), operator_name, members, return_type);
1403 }
else if ((*i)->cmd_ ==
"!dfn") {
1405 vector<StructureMember> r_set;
1406 r_set.push_back(StructureMember(&Compiler::read_set,
""));
1408 std::string function_name = s->cmd_;
1409 metadata->function_names_.push_back(function_name);
1410 metadata->classes_[function_name] = Class(Atom::DeviceFunction(function_opcode), function_name, r_set);