90 using namespace r_code;
94 static bool Output =
true;
96 static inline bool is_decimal(
char c) {
return c >=
'0' && c <=
'9'; }
98 Compiler::Compiler(
bool allow_variables_and_wildcards_outside_pattern_skeleton)
99 : out_stream_(NULL), current_object_(NULL), error_(std::string(
"")),
100 allow_variables_and_wildcards_outside_pattern_skeleton_(allow_variables_and_wildcards_outside_pattern_skeleton)
104 Compiler::~Compiler() {
110 Compiler::State Compiler::save_state() {
116 void Compiler::restore_state(State s) {
118 in_stream_->seekg(s.stream_ptr);
122 void Compiler::set_error(
const std::string &s) {
124 if (!err_ && Output) {
131 void Compiler::set_arity_error(uint16 expected, uint16 got) {
133 set_error(
"error: got " + std::to_string(got) +
" elements, expected " +
134 std::to_string(expected));
146 metadata_ = metadata;
147 current_object_index_ = image->object_map_.objects_.size();
148 while (!in_stream_->eof()) {
150 switch (in_stream_->peek()) {
152 set_error(
"error: found preprocessor directive");
156 if (in_stream_->eof())
158 if (!read_sys_object()) {
163 current_object_index_++;
166 char c = (char)in_stream_->get();
168 in_stream_->putback(c);
174 bool Compiler::read_sys_object() {
176 local_references_.clear();
177 hlp_references_.clear();
178 bool indented =
false;
181 current_view_index_ = -1;
184 while (indent(
false));
185 char c = (char)in_stream_->get();
187 in_stream_->putback(c);
195 if (!expression_begin(indented)) {
198 set_error(
"error: label not followed by an expression");
200 set_error(
"syntax error: missing expression opening");
205 if (!sys_object(current_class_)) {
207 set_error(
"error: unknown class");
211 if (current_class_.str_opcode ==
"mdl" || current_class_.str_opcode ==
"cst")
215 if (global_references_.find(l) != global_references_.end()) {
216 set_error(
"error: redefinition of label `" + l +
"`");
219 global_references_[l] = Reference(image_->code_segment_.objects_.size(), current_class_, Class());
223 current_object_->code_[0] = current_class_.atom_;
224 if (current_class_.atom_.getAtomCount()) {
226 if (!right_indent(
true)) {
228 if (!separator(
false)) {
230 set_error(
"syntax error: missing separator/right_indent after head");
234 uint16 extent_index = current_class_.atom_.getAtomCount() + 1;
235 if (!expression_tail(indented, current_class_, 1, extent_index,
true))
250 while (indent(
false));
251 std::streampos i = in_stream_->tellg();
252 if (!match_symbol(
"|[]",
false)) {
254 in_stream_->seekg(i);
255 if (!set_begin(indented)) {
257 set_error(
" error: expected a view set");
263 if (current_class_.str_opcode ==
"grp")
264 current_class_ = metadata_->classes_.find(
"grp_view")->second;
265 else if (current_class_.str_opcode ==
"ipgm" ||
266 current_class_.str_opcode ==
"icpp_pgm" ||
267 current_class_.str_opcode ==
"mdl" ||
268 current_class_.str_opcode ==
"cst")
269 current_class_ = metadata_->classes_.find(
"pgm_view")->second;
271 current_class_ = metadata_->classes_.find(
"view")->second;
272 current_class_.use_as = StructureMember::I_CLASS;
275 bool _indented =
false;
276 while (!in_stream_->eof()) {
278 current_object_ =
new SysView();
279 current_view_index_ = count;
280 uint16 extent_index = 0;
282 if (set_end(indented)) {
286 set_error(
" syntax error: use |[] for empty sets");
287 delete current_object_;
291 delete current_object_;
299 if (!right_indent(
true)) {
301 if (!separator(
false)) {
303 set_error(
"syntax error: missing separator between 2 elements");
304 delete current_object_;
311 if (!read_set(_indented,
true, ¤t_class_, 0, extent_index,
true)) {
313 set_error(
" error: illegal element in set");
314 delete current_object_;
318 sys_object->views_.push_back((
SysView *)current_object_);
325 image_->add_sys_object(sys_object, l);
329 bool Compiler::read(
const StructureMember &m,
bool &indented,
bool enforce, uint16 write_index, uint16 &extent_index,
bool write) {
331 if (Class *p = m.get_class(metadata_)) {
333 p->use_as = m.getIteration();
334 return (this->*m.read())(indented, enforce, p, write_index, extent_index, write);
336 return (this->*m.read())(indented, enforce, NULL, write_index, extent_index, write);
339 bool Compiler::getGlobalReferenceIndex(
const std::string reference_name,
const ReturnType t,
ImageObject *
object, uint16 &index, Class *&_class) {
341 unordered_map<std::string, Reference>::iterator it = global_references_.find(reference_name);
342 if (it != global_references_.end() && (t == ANY || (t != ANY && it->second.class_.type == t))) {
344 _class = &it->second.class_;
345 for (uint16 j = 0; j <
object->references_.size(); ++j)
346 if (object->references_[j] == it->second.index_) {
351 object->references_.push_back(it->second.index_);
352 index =
object->references_.size() - 1;
358 void Compiler::addLocalReference(
const std::string reference_name,
const uint16 index,
const Class &p) {
361 size_t pos = reference_name.find(
'#');
362 if (pos != string::npos) {
364 std::string class_name = reference_name.substr(pos + 1);
365 std::string ref_name = reference_name.substr(0, pos);
367 unordered_map<std::string, Class>::iterator it = metadata_->classes_.find(class_name);
368 if (it != metadata_->classes_.end())
369 local_references_[ref_name] = Reference(index, p, it->second);
371 set_error(
" error: cast to " + class_name +
": unknown class");
373 local_references_[reference_name] = Reference(index, p, Class());
376 uint8 Compiler::add_hlp_reference(std::string reference_name) {
378 for (uint8 i = 0; i < hlp_references_.size(); ++i)
379 if (reference_name == hlp_references_[i])
381 hlp_references_.push_back(reference_name);
382 return hlp_references_.size() - 1;
385 uint8 Compiler::get_hlp_reference(std::string reference_name) {
387 for (uint8 i = 0; i < hlp_references_.size(); ++i)
388 if (reference_name == hlp_references_[i])
395 bool Compiler::comment() {
397 std::streampos i = in_stream_->tellg();
398 bool started =
false;
399 bool continuation =
false;
401 while (!in_stream_->eof()) {
403 switch (
char c = (
char)in_stream_->get()) {
413 set_error(
" syntax error: ...");
423 in_stream_->putback(c);
426 continuation = period =
false;
436 in_stream_->seekg(i);
441 bool Compiler::indent(
bool pushback) {
446 for (uint16 j = 0; j < 3 * state_.indents; j++)
448 return match_symbol(s.c_str(), pushback);
451 bool Compiler::right_indent(
bool pushback) {
456 if (state_.right_indents_ahead)
460 for (uint16 j = 0; j < 3 * (state_.indents + 1); j++)
462 return match_symbol(s.c_str(),
true);
464 if (state_.right_indents_ahead) {
467 state_.right_indents_ahead--;
472 for (uint16 j = 0; j < 3 * (state_.indents + 1); j++)
474 if (!match_symbol(s.c_str(),
false))
478 while (match_symbol(s.c_str(),
false))
479 state_.right_indents_ahead++;
483 bool Compiler::left_indent(
bool pushback) {
490 if (state_.left_indents_ahead)
494 for (uint16 j = 0; j < 3 * (state_.indents - 1); j++)
496 return match_symbol(s.c_str(),
true);
498 if (state_.left_indents_ahead) {
502 state_.left_indents_ahead--;
507 if (!match_symbol(s.c_str(),
false))
509 uint16 expected = state_.indents - 1;
516 state_.left_indents_ahead = expected;
518 for (uint16 j = 0; j < expected; j++) {
520 if (match_symbol(s.c_str(),
false))
521 state_.left_indents_ahead--;
528 bool Compiler::separator(
bool pushback) {
530 if (indent(pushback))
532 char c = (char)in_stream_->get();
536 in_stream_->putback(c);
540 in_stream_->putback(c);
544 bool Compiler::symbol_expr(std::string &s) {
546 std::streampos i = in_stream_->tellg();
548 while (!in_stream_->eof()) {
550 switch (
char c = (
char)in_stream_->get()) {
558 in_stream_->putback(c);
571 in_stream_->seekg(i);
580 in_stream_->seekg(i);
584 bool Compiler::symbol_expr_set(std::string &s) {
586 std::streampos i = in_stream_->tellg();
588 while (!in_stream_->eof()) {
590 switch (
char c = (
char)in_stream_->get()) {
598 in_stream_->putback(c);
605 in_stream_->seekg(i);
614 in_stream_->seekg(i);
618 bool Compiler::match_symbol_separator(
const char *symbol,
bool pushback) {
620 if (match_symbol(symbol, pushback)) {
622 if (separator(
true) || right_indent(
true) || left_indent(
true))
624 char c = (char)in_stream_->peek();
625 if (c ==
')' || c ==
']')
631 bool Compiler::match_symbol(
const char *symbol,
bool pushback) {
633 std::streampos i = in_stream_->tellg();
634 for (uint32 j = 0; j < strlen(symbol); j++) {
636 if (in_stream_->eof() || ((char)in_stream_->get()) != symbol[j]) {
639 in_stream_->seekg(i);
644 in_stream_->seekg(i);
648 bool Compiler::member(std::string &s) {
650 std::streampos i = in_stream_->tellg();
653 while (!in_stream_->eof()) {
655 switch (
char c = (
char)in_stream_->get()) {
664 in_stream_->putback(c);
670 in_stream_->seekg(i);
679 in_stream_->seekg(i);
683 bool Compiler::expression_begin(
bool &indented) {
685 if (right_indent(
false)) {
690 std::streampos i = in_stream_->tellg();
693 char c = (char)in_stream_->get();
698 in_stream_->seekg(i);
699 char c = (char)in_stream_->get();
703 in_stream_->putback(c);
707 bool Compiler::expression_end(
bool indented) {
710 return left_indent(
false);
711 std::streampos i = in_stream_->tellg();
714 char c = (char)in_stream_->get();
719 in_stream_->seekg(i);
720 char c = (char)in_stream_->get();
724 in_stream_->putback(c);
728 bool Compiler::set_begin(
bool &indented) {
730 std::streampos i = in_stream_->tellg();
731 if (match_symbol(
"[]",
false)) {
733 if (right_indent(
false)) {
739 set_error(
" syntax error: [] not followed by indent");
743 in_stream_->seekg(i);
746 char c = (char)in_stream_->get();
751 in_stream_->seekg(i);
752 char c = (char)in_stream_->get();
756 in_stream_->putback(c);
760 bool Compiler::set_end(
bool indented) {
763 return left_indent(
false);
764 std::streampos i = in_stream_->tellg();
767 char c = (char)in_stream_->get();
772 in_stream_->seekg(i);
773 char c = (char)in_stream_->get();
777 in_stream_->putback(c);
783 bool Compiler::nil() {
785 std::streampos i = in_stream_->tellg();
786 if (match_symbol_separator(
"nil",
false))
789 in_stream_->seekg(i);
793 bool Compiler::nil_nb() {
795 std::streampos i = in_stream_->tellg();
796 if (match_symbol_separator(
"|nb",
false))
799 in_stream_->seekg(i);
803 bool Compiler::nil_ts() {
805 std::streampos i = in_stream_->tellg();
806 if (match_symbol_separator(
"|ts",
false))
809 in_stream_->seekg(i);
813 bool Compiler::forever() {
815 std::streampos i = in_stream_->tellg();
816 if (match_symbol_separator(
"forever",
false))
819 in_stream_->seekg(i);
823 bool Compiler::nil_nid() {
825 std::streampos i = in_stream_->tellg();
826 if (match_symbol_separator(
"|nid",
false))
829 in_stream_->seekg(i);
833 bool Compiler::nil_did() {
835 std::streampos i = in_stream_->tellg();
836 if (match_symbol_separator(
"|did",
false))
839 in_stream_->seekg(i);
843 bool Compiler::nil_fid() {
845 std::streampos i = in_stream_->tellg();
846 if (match_symbol_separator(
"|fid",
false))
849 in_stream_->seekg(i);
853 bool Compiler::nil_bl() {
855 std::streampos i = in_stream_->tellg();
856 if (match_symbol_separator(
"|bl",
false))
859 in_stream_->seekg(i);
863 bool Compiler::nil_st() {
865 std::streampos i = in_stream_->tellg();
866 if (match_symbol_separator(
"|st",
false))
869 in_stream_->seekg(i);
873 bool Compiler::label(std::string &l) {
875 std::streampos i = in_stream_->tellg();
876 if (symbol_expr(l) && l[0] !=
'-' && !is_decimal(l[0]) && (
char)in_stream_->get() ==
':')
879 in_stream_->seekg(i);
883 bool Compiler::variable(std::string &l) {
885 std::streampos i = in_stream_->tellg();
886 if (symbol_expr(l) && !is_decimal(l[0]) && (
char)in_stream_->get() ==
':') {
888 in_stream_->seekg(i);
889 std::string _l = l +
':';
890 if (match_symbol_separator(_l.c_str(),
false))
894 in_stream_->seekg(i);
898 bool Compiler::this_() {
900 std::streampos i = in_stream_->tellg();
901 if (match_symbol_separator(
"this",
false))
904 in_stream_->seekg(i);
908 bool Compiler::local_reference(uint16 &index,
const ReturnType t) {
910 std::streampos i = in_stream_->tellg();
912 if (symbol_expr_set(r)) {
914 unordered_map<std::string, Reference>::iterator it = local_references_.find(r);
915 if (it != local_references_.end() && (t == ANY || it->second.class_.type == ANY || (t != ANY && it->second.class_.type == t))) {
917 index = it->second.index_;
922 in_stream_->seekg(i);
926 bool Compiler::global_reference(uint16 &index,
const ReturnType t) {
928 std::streampos i = in_stream_->tellg();
930 if (symbol_expr_set(r)) {
933 if (getGlobalReferenceIndex(r, t, current_object_, index, unused))
937 in_stream_->seekg(i);
941 bool Compiler::hlp_reference(uint16 &index) {
944 std::streampos i = in_stream_->tellg();
948 in_stream_->seekg(i);
952 if (symbol_expr(r)) {
954 for (uint8 i = 0; i < hlp_references_.size(); ++i)
955 if (r == hlp_references_[i]) {
962 in_stream_->seekg(i);
966 bool Compiler::this_indirection(vector<int16> &v,
const ReturnType t) {
968 std::streampos i = in_stream_->tellg();
969 if (match_symbol(
"this.",
false)) {
972 if (current_class_.str_opcode ==
"pgm")
973 p = &metadata_->sys_classes_[
"ipgm"];
982 _p = &metadata_->classes_.find(
"pgm_view")->second;
985 }
else if (m ==
"mks") {
990 }
else if (m ==
"vws") {
995 }
else if (!p->get_member_index(metadata_, m, index, _p)) {
997 set_error(
" error: " + m +
" is not a member of " + p->str_opcode);
1001 type = p->get_member_type(index);
1005 char c = (char)in_stream_->get();
1010 set_error(
" error: " + m +
" is not a structure");
1016 if (t == ANY || (t != ANY && type == t)) {
1018 in_stream_->putback(c);
1025 in_stream_->clear();
1026 in_stream_->seekg(i);
1030 bool Compiler::local_indirection(vector<int16> &v,
const ReturnType t, uint16 &cast_opcode) {
1032 std::streampos i = in_stream_->tellg();
1034 std::string path =
"";
1036 if (member(m) && (
char)in_stream_->get() ==
'.') {
1040 unordered_map<std::string, Reference>::iterator it = local_references_.find(m);
1041 if (it != local_references_.end()) {
1043 index = it->second.index_;
1045 if (it->second.cast_class_.str_opcode ==
"undefined") {
1047 p = &it->second.class_;
1048 cast_opcode = 0x0FFF;
1051 p = &it->second.cast_class_;
1052 cast_opcode = p->atom_.asOpcode();
1059 _p = &metadata_->classes_.find(
"pgm_view")->second;
1062 }
else if (m ==
"mks") {
1067 }
else if (m ==
"vws") {
1072 }
else if (!p->get_member_index(metadata_, m, index, _p)) {
1074 set_error(
" error: " + m +
" is not a member of " + p->str_opcode);
1078 type = p->get_member_type(index);
1084 char c = (char)in_stream_->get();
1089 set_error(
" error: " + path +
" is not an addressable structure");
1095 if (t == ANY || (t != ANY && type == t)) {
1097 in_stream_->putback(c);
1105 in_stream_->clear();
1106 in_stream_->seekg(i);
1110 bool Compiler::global_indirection(vector<int16> &v,
const ReturnType t) {
1112 std::streampos i = in_stream_->tellg();
1115 if (member(m) && (
char)in_stream_->get() ==
'.') {
1119 if (getGlobalReferenceIndex(m, ANY, current_object_, index, p)) {
1123 bool first_member =
true;
1128 set_error(
" error: vw is not accessible on global references");
1130 }
else if (m ==
"mks") {
1135 }
else if (m ==
"vws") {
1140 }
else if (!p->get_member_index(metadata_, m, index, _p)) {
1142 set_error(
" error: " + m +
" is not a member of " + p->str_opcode);
1146 type = p->get_member_type(index);
1147 if (first_member && index == 0)
1152 first_member =
false;
1154 char c = (char)in_stream_->get();
1159 set_error(
" error: " + m +
" is not a structure");
1165 if (t == ANY || (t != ANY && type == t)) {
1167 in_stream_->putback(c);
1175 in_stream_->clear();
1176 in_stream_->seekg(i);
1180 bool Compiler::wildcard() {
1182 std::streampos i = in_stream_->tellg();
1183 if (match_symbol_separator(
":",
false))
1185 in_stream_->clear();
1186 in_stream_->seekg(i);
1190 bool Compiler::tail_wildcard() {
1192 std::streampos i = in_stream_->tellg();
1193 if (match_symbol(
"::",
false)) {
1195 if (left_indent(
true)) {
1197 state_.no_arity_check =
true;
1200 char c = (char)in_stream_->peek();
1201 if (c ==
')' || c ==
']') {
1203 state_.no_arity_check =
true;
1207 in_stream_->clear();
1208 in_stream_->seekg(i);
1212 bool Compiler::number(float32 &n) {
1214 std::streampos i = in_stream_->tellg();
1215 if (match_symbol(
"0x",
true)) {
1217 in_stream_->clear();
1218 in_stream_->seekg(i);
1221 *in_stream_ >> std::dec >> n;
1222 if (in_stream_->fail() || in_stream_->eof()) {
1224 in_stream_->clear();
1225 in_stream_->seekg(i);
1228 if (match_symbol(
"us",
true) ||
1229 match_symbol(
"ms",
true) ||
1230 match_symbol(
"s",
true)) {
1232 in_stream_->clear();
1233 in_stream_->seekg(i);
1239 bool Compiler::hex(uint32 &h) {
1241 std::streampos i = in_stream_->tellg();
1242 if (!match_symbol(
"0x",
false)) {
1244 in_stream_->clear();
1245 in_stream_->seekg(i);
1248 *in_stream_ >> std::hex >> h;
1249 if (in_stream_->fail() || in_stream_->eof()) {
1251 in_stream_->clear();
1252 in_stream_->seekg(i);
1258 bool Compiler::boolean(
bool &b) {
1260 std::streampos i = in_stream_->tellg();
1261 if (match_symbol_separator(
"true",
false)) {
1266 if (match_symbol_separator(
"false",
false)) {
1271 in_stream_->clear();
1272 in_stream_->seekg(i);
1276 bool Compiler::duration(int64 &result) {
1278 std::streampos i = in_stream_->tellg();
1279 if (match_symbol(
"0x",
true)) {
1281 in_stream_->clear();
1282 in_stream_->seekg(i);
1285 *in_stream_ >> std::dec >> result;
1286 if (in_stream_->fail() || in_stream_->eof()) {
1288 in_stream_->clear();
1289 in_stream_->seekg(i);
1292 if (match_symbol(
"us",
false))
1294 else if (match_symbol(
"ms",
false)) {
1298 else if (match_symbol(
"s",
false)) {
1300 if (!match_symbol(
":",
true)) {
1306 in_stream_->clear();
1307 in_stream_->seekg(i);
1311 bool Compiler::timestamp_s_ms_us(int64 &ts) {
1313 std::streampos i = in_stream_->tellg();
1314 if (match_symbol(
"0x",
true)) {
1315 in_stream_->clear();
1316 in_stream_->seekg(i);
1320 bool negative = match_symbol(
"-",
false);
1322 *in_stream_ >> std::dec >> s;
1323 if (in_stream_->fail() || in_stream_->eof()) {
1324 in_stream_->clear();
1325 in_stream_->seekg(i);
1328 if (!match_symbol(
"s:",
false)) {
1329 in_stream_->clear();
1330 in_stream_->seekg(i);
1335 *in_stream_ >> std::dec >> ms;
1336 if (in_stream_->fail() || in_stream_->eof()) {
1337 in_stream_->clear();
1338 in_stream_->seekg(i);
1341 if (!match_symbol(
"ms:",
false)) {
1342 in_stream_->clear();
1343 in_stream_->seekg(i);
1348 *in_stream_ >> std::dec >> us;
1349 if (in_stream_->fail() || in_stream_->eof()) {
1350 in_stream_->clear();
1351 in_stream_->seekg(i);
1354 if (!match_symbol(
"us",
false)) {
1355 in_stream_->clear();
1356 in_stream_->seekg(i);
1360 ts = s * 1000000 + ms * 1000 + us;
1366 bool Compiler::str(std::string &s) {
1368 std::streampos i = in_stream_->tellg();
1370 bool started =
false;
1371 while (!in_stream_->eof()) {
1373 switch (
char c = (
char)in_stream_->get()) {
1384 in_stream_->clear();
1385 in_stream_->seekg(i);
1393 in_stream_->clear();
1394 in_stream_->seekg(i);
1398 bool Compiler::object(Class &p) {
1402 std::streampos i = in_stream_->tellg();
1404 if (!symbol_expr(s)) {
1406 in_stream_->seekg(i);
1408 if (!symbol_expr_set(s)) {
1410 in_stream_->seekg(i);
1414 unordered_map<std::string, Class>::const_iterator it = metadata_->classes_.find(s);
1415 if (it == metadata_->classes_.end()) {
1417 in_stream_->seekg(i);
1424 bool Compiler::object(
const Class &p) {
1428 std::streampos i = in_stream_->tellg();
1429 if (!match_symbol_separator(p.str_opcode.c_str(),
false)) {
1431 in_stream_->seekg(i);
1437 bool Compiler::sys_object(Class &p) {
1439 std::streampos i = in_stream_->tellg();
1441 if (!symbol_expr(s)) {
1443 in_stream_->seekg(i);
1445 if (!symbol_expr_set(s)) {
1447 in_stream_->seekg(i);
1451 unordered_map<std::string, Class>::const_iterator it = metadata_->sys_classes_.find(s);
1452 if (it == metadata_->sys_classes_.end()) {
1454 in_stream_->seekg(i);
1461 bool Compiler::sys_object(
const Class &p) {
1463 std::streampos i = in_stream_->tellg();
1464 if (!match_symbol_separator(p.str_opcode.c_str(),
false)) {
1466 in_stream_->seekg(i);
1472 bool Compiler::marker(Class &p) {
1474 std::streampos i = in_stream_->tellg();
1475 if (!match_symbol(
"mk.",
false)) {
1477 in_stream_->seekg(i);
1480 std::streampos j = in_stream_->tellg();
1482 if (!symbol_expr(s)) {
1484 in_stream_->seekg(j);
1486 if (!symbol_expr_set(s)) {
1488 in_stream_->seekg(i);
1492 unordered_map<std::string, Class>::const_iterator it = metadata_->sys_classes_.find(
"mk." + s);
1493 if (it == metadata_->sys_classes_.end()) {
1495 in_stream_->seekg(i);
1502 bool Compiler::op(Class &p,
const ReturnType t) {
1504 std::streampos i = in_stream_->tellg();
1506 if (!symbol_expr(s)) {
1508 in_stream_->seekg(i);
1511 unordered_map<std::string, Class>::const_iterator it = metadata_->classes_.find(s);
1512 if (it == metadata_->classes_.end() || (t != ANY && it->second.type != ANY && it->second.type != t)) {
1514 in_stream_->seekg(i);
1521 bool Compiler::op(
const Class &p) {
1523 std::streampos i = in_stream_->tellg();
1524 if (!match_symbol_separator(p.str_opcode.c_str(),
false)) {
1526 in_stream_->seekg(i);
1532 bool Compiler::function(Class &p) {
1534 std::streampos i = in_stream_->tellg();
1536 if (!symbol_expr(s)) {
1538 in_stream_->seekg(i);
1541 unordered_map<std::string, Class>::const_iterator it = metadata_->classes_.find(s);
1542 if (it == metadata_->classes_.end()) {
1544 in_stream_->seekg(i);
1551 bool Compiler::expression_head(Class &p,
const ReturnType t) {
1560 }
else if (!op(p, t))
1562 if (p.atom_.getAtomCount()) {
1564 if (!right_indent(
true)) {
1566 if (!separator(
false)) {
1568 set_error(
"syntax error: missing separator/right_indent after head");
1576 bool Compiler::expression_head(
const Class &p) {
1582 if (p.atom_.getAtomCount()) {
1584 if (!right_indent(
true)) {
1586 if (!separator(
false)) {
1588 set_error(
"syntax error: missing separator/right_indent after head");
1596 bool Compiler::expression_tail(
bool indented,
const Class &p, uint16 write_index, uint16 &extent_index,
bool write) {
1599 bool _indented =
false;
1600 bool entered_pattern;
1601 uint16 pattern_end_index;
1604 entered_pattern =
true;
1605 pattern_end_index = p.atom_.getAtomCount() - 1;
1608 entered_pattern = p.is_pattern(metadata_);
1609 pattern_end_index = 0;
1611 if (write && state_.pattern_lvl)
1612 for (uint16 j = write_index; j < write_index + p.atom_.getAtomCount(); ++j)
1613 current_object_->code_[j] = Atom::Wildcard();
1614 std::streampos i = in_stream_->tellg();
1615 while (!in_stream_->eof()) {
1617 if (expression_end(indented)) {
1619 if (state_.no_arity_check) {
1621 state_.no_arity_check =
false;
1622 if (entered_pattern && pattern_end_index > 0 && count - 1 < pattern_end_index)
1624 --state_.pattern_lvl;
1627 if (count == p.atom_.getAtomCount())
1629 set_arity_error(p.atom_.getAtomCount(), count);
1632 if (count >= p.atom_.getAtomCount()) {
1634 set_arity_error(p.atom_.getAtomCount(), count + 1);
1641 if (!right_indent(
true)) {
1643 if (!separator(
false)) {
1645 set_error(
"syntax error: missing separator between 2 elements");
1652 if (entered_pattern && count == 0)
1653 ++state_.pattern_lvl;
1654 if (!read(p.things_to_read[count], _indented,
true, write_index + count, extent_index, write)) {
1656 set_error(
" error: parsing element in expression");
1659 if (entered_pattern && count == pattern_end_index)
1660 --state_.pattern_lvl;
1668 bool Compiler::expression(
bool &indented,
const ReturnType t, uint16 write_index, uint16 &extent_index,
bool write) {
1671 std::streampos i = in_stream_->tellg();
1675 if (!expression_begin(indented)) {
1678 set_error(
" error: label not followed by an expression");
1682 if (!expression_head(p, t)) {
1684 in_stream_->seekg(i);
1687 if (lbl && !in_hlp_)
1688 addLocalReference(l, write_index, p);
1689 uint16 tail_write_index = 0;
1692 if (lbl && in_hlp_) {
1694 uint8 variable_index = get_hlp_reference(l);
1695 if (variable_index == 0xFF) {
1697 set_error(
" error: undeclared variable");
1700 current_object_->code_[write_index] = Atom::AssignmentPointer(variable_index, extent_index);
1702 current_object_->code_[write_index] = Atom::IPointer(extent_index);
1703 current_object_->code_[extent_index++] = p.atom_;
1704 tail_write_index = extent_index;
1705 extent_index += p.atom_.getAtomCount();
1707 if (!expression_tail(indented, p, tail_write_index, extent_index, write))
1712 bool Compiler::expression(
bool &indented,
const Class &p, uint16 write_index, uint16 &extent_index,
bool write) {
1715 std::streampos i = in_stream_->tellg();
1719 if (!expression_begin(indented)) {
1722 set_error(
" error: label not followed by an expression");
1725 if (!expression_head(p)) {
1727 in_stream_->seekg(i);
1731 addLocalReference(l, write_index, p);
1732 uint16 tail_write_index = 0;
1735 if (lbl && in_hlp_) {
1737 uint8 variable_index = get_hlp_reference(l);
1738 if (variable_index == 0xFF) {
1740 set_error(
" error: undeclared variable");
1743 current_object_->code_[write_index] = Atom::AssignmentPointer(variable_index, extent_index);
1745 current_object_->code_[write_index] = Atom::IPointer(extent_index);
1746 current_object_->code_[extent_index++] = p.atom_;
1747 tail_write_index = extent_index;
1748 extent_index += p.atom_.getAtomCount();
1750 if (!expression_tail(indented, p, tail_write_index, extent_index, write))
1755 bool Compiler::set(
bool &indented, uint16 write_index, uint16 &extent_index,
bool write) {
1757 std::streampos i = in_stream_->tellg();
1762 if (!set_begin(indented)) {
1765 set_error(
" error: label not followed by a structure");
1769 addLocalReference(l, write_index, Class(SET));
1771 uint16 content_write_index = 0;
1774 current_object_->code_[write_index] = Atom::IPointer(extent_index);
1775 uint8 element_count = set_element_count(indented);
1776 current_object_->code_[extent_index++] = Atom::Set(element_count);
1777 content_write_index = extent_index;
1778 extent_index += element_count;
1781 bool _indented =
false;
1782 while (!in_stream_->eof()) {
1784 if (set_end(indented)) {
1788 set_error(
" syntax error: use |[] for empty sets");
1797 if (!right_indent(
true)) {
1799 if (!separator(
false)) {
1801 set_error(
"syntax error: missing separator between 2 elements");
1808 if (!read_any(_indented,
false, NULL, content_write_index + count, extent_index, write)) {
1810 set_error(
" error: illegal element in set");
1815 in_stream_->clear();
1816 in_stream_->seekg(i);
1820 bool Compiler::set(
bool &indented,
const Class &p, uint16 write_index, uint16 &extent_index,
bool write) {
1822 std::streampos i = in_stream_->tellg();
1827 if (!set_begin(indented)) {
1830 set_error(
" error: label not followed by a structure");
1834 addLocalReference(l, write_index, p);
1836 uint16 content_write_index = 0;
1839 current_object_->code_[write_index] = Atom::IPointer(extent_index);
1840 uint8 element_count;
1841 if (p.atom_.getDescriptor() == Atom::S_SET && p.use_as != StructureMember::I_SET) {
1843 element_count = p.atom_.getAtomCount();
1844 current_object_->code_[extent_index++] = p.atom_;
1847 element_count = set_element_count(indented);
1848 current_object_->code_[extent_index++] = Atom::Set(element_count);
1850 content_write_index = extent_index;
1851 extent_index += element_count;
1854 bool _indented =
false;
1855 uint16 arity = 0xFFFF;
1856 if (p.use_as == StructureMember::I_CLASS) {
1858 arity = p.atom_.getAtomCount();
1860 for (uint16 j = content_write_index; j < content_write_index + arity; ++j)
1861 current_object_->code_[j] = Atom::Wildcard();
1863 while (!in_stream_->eof()) {
1865 if (set_end(indented)) {
1869 set_error(
" syntax error: use |[] for empty sets");
1872 if (count == arity || arity == 0xFFFF)
1874 if (state_.no_arity_check) {
1876 state_.no_arity_check =
false;
1879 set_arity_error(arity, count);
1882 if (count >= arity) {
1884 set_arity_error(arity, count + 1);
1891 if (!right_indent(
true)) {
1893 if (!separator(
false)) {
1895 set_error(
"syntax error: missing separator between 2 elements");
1904 case StructureMember::I_EXPRESSION:
1905 r = read_expression(_indented,
true, &p, content_write_index + count, extent_index, write);
1907 case StructureMember::I_SET:
1910 _p.use_as = StructureMember::I_CLASS;
1911 r = read_set(_indented,
true, &_p, content_write_index + count, extent_index, write);
1914 case StructureMember::I_CLASS:
1915 r = read(p.things_to_read[count], _indented,
true, content_write_index + count, extent_index, write);
1917 case StructureMember::I_DCLASS:
1918 r = read_class(_indented,
true, NULL, content_write_index + count, extent_index, write);
1923 set_error(
" error: illegal element in set");
1928 in_stream_->clear();
1929 in_stream_->seekg(i);
1933 uint8 Compiler::set_element_count(
bool indented) {
1937 State s = save_state();
1939 bool _indented =
false;
1940 uint16 unused_index = 0;
1941 while (!in_stream_->eof()) {
1943 if (set_end(indented))
1949 if (!right_indent(
true)) {
1951 if (!separator(
false))
1957 if (!read_any(_indented,
false, NULL, 0, unused_index,
false))
1961 in_stream_->clear();
1969 bool Compiler::read_any(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
1972 if (read_number(indented,
false, NULL, write_index, extent_index, write))
1976 if (read_timestamp(indented,
false, NULL, write_index, extent_index, write))
1978 if (read_duration(indented,
false, NULL, write_index, extent_index, write))
1982 if (read_string(indented,
false, NULL, write_index, extent_index, write))
1986 if (read_boolean(indented,
false, NULL, write_index, extent_index, write))
1990 if (read_function(indented,
false, NULL, write_index, extent_index, write))
1994 if (read_node(indented,
false, NULL, write_index, extent_index, write))
1998 if (read_device(indented,
false, NULL, write_index, extent_index, write))
2000 if (read_class(indented,
false, NULL, write_index, extent_index, write))
2004 if (read_expression(indented,
false, NULL, write_index, extent_index, write))
2008 if (read_set(indented,
false, NULL, write_index, extent_index, write))
2011 set_error(
" error: expecting more elements");
2015 bool Compiler::read_number(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2017 if (read_nil_nb(write_index, extent_index, write))
2019 if (read_forever_nb(write_index, extent_index, write))
2021 if (read_variable(write_index, extent_index, write, NUMBER))
2023 if (read_reference(write_index, extent_index, write, NUMBER))
2025 if (read_wildcard(write_index, extent_index, write))
2027 if (read_tail_wildcard(write_index, extent_index, write))
2034 current_object_->code_[write_index] = Atom::Float(n);
2037 State s = save_state();
2038 if (expression(indented, NUMBER, write_index, extent_index, write))
2043 set_error(
" error: expected a number or an expr evaluating to a number");
2049 bool Compiler::read_boolean(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2051 if (read_nil_bl(write_index, extent_index, write))
2053 if (read_variable(write_index, extent_index, write, BOOLEAN))
2055 if (read_reference(write_index, extent_index, write, BOOLEAN))
2057 if (read_wildcard(write_index, extent_index, write))
2059 if (read_tail_wildcard(write_index, extent_index, write))
2066 current_object_->code_[write_index] = Atom::Boolean(b);
2069 State s = save_state();
2070 if (expression(indented, BOOLEAN, write_index, extent_index, write))
2075 set_error(
" error: expected a Boolean or an expr evaluating to a Boolean");
2081 bool Compiler::read_timestamp(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2083 if (read_nil_ts(write_index, extent_index, write))
2085 if (read_variable(write_index, extent_index, write, TIMESTAMP))
2087 if (read_reference(write_index, extent_index, write, TIMESTAMP))
2089 if (read_wildcard(write_index, extent_index, write))
2091 if (read_tail_wildcard(write_index, extent_index, write))
2095 if (timestamp_s_ms_us(ts)) {
2098 current_object_->code_[write_index] = Atom::IPointer(extent_index);
2099 current_object_->code_[extent_index++] = Atom::Timestamp();
2100 current_object_->code_[extent_index + 1] = 0;
2101 Utils::SetInt64(¤t_object_->code_[0], extent_index, ts);
2107 State s = save_state();
2108 if (expression(indented, TIMESTAMP, write_index, extent_index, write))
2113 set_error(
" error: expected a timestamp or an expr evaluating to a timestamp");
2120 bool Compiler::read_duration(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2122 if (read_variable(write_index, extent_index, write, DURATION))
2124 if (read_reference(write_index, extent_index, write, DURATION))
2126 if (read_wildcard(write_index, extent_index, write))
2128 if (read_tail_wildcard(write_index, extent_index, write))
2136 current_object_->code_[write_index] = Atom::IPointer(extent_index);
2137 current_object_->code_[extent_index++] = Atom::Duration();
2138 current_object_->code_[extent_index + 1] = 0;
2139 Utils::SetInt64(¤t_object_->code_[0], extent_index, d);
2145 State s = save_state();
2146 if (expression(indented, DURATION, write_index, extent_index, write))
2151 set_error(
" error: expected a duration or an expr evaluating to a duration");
2157 bool Compiler::read_string(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2159 if (read_nil_st(write_index, extent_index, write))
2161 if (read_variable(write_index, extent_index, write, STRING))
2163 if (read_reference(write_index, extent_index, write, STRING))
2165 if (read_wildcard(write_index, extent_index, write))
2167 if (read_tail_wildcard(write_index, extent_index, write))
2175 uint16 l = (uint16)st.length();
2176 current_object_->code_[write_index] = Atom::IPointer(extent_index);
2177 current_object_->code_[extent_index++] = Atom::String(l);
2180 for (uint16 i = 0; i < l; ++i) {
2182 _st |= st[i] << shift;
2186 current_object_->code_[extent_index++] = _st;
2192 current_object_->code_[extent_index++] = _st;
2196 State s = save_state();
2197 if (expression(indented, STRING, write_index, extent_index, write))
2202 set_error(
" error: expected a string");
2208 bool Compiler::read_node(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2210 if (read_nil_nid(write_index, extent_index, write))
2212 if (read_variable(write_index, extent_index, write, NODE_ID))
2214 if (read_reference(write_index, extent_index, write, NODE_ID))
2216 if (read_wildcard(write_index, extent_index, write))
2218 if (read_tail_wildcard(write_index, extent_index, write))
2221 std::streampos i = in_stream_->tellg();
2223 if (hex(h) &&
Atom(h).getDescriptor() == Atom::NODE) {
2226 current_object_->code_[write_index] =
Atom(h);
2229 in_stream_->seekg(i);
2230 State s = save_state();
2231 if (expression(indented, NODE_ID, write_index, extent_index, write))
2236 set_error(
" error: expected a node id");
2242 bool Compiler::read_device(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2244 if (read_nil_did(write_index, extent_index, write))
2246 if (read_variable(write_index, extent_index, write, DEVICE_ID))
2248 if (read_reference(write_index, extent_index, write, DEVICE_ID))
2250 if (read_wildcard(write_index, extent_index, write))
2252 if (read_tail_wildcard(write_index, extent_index, write))
2255 std::streampos i = in_stream_->tellg();
2257 if (hex(h) &&
Atom(h).getDescriptor() == Atom::DEVICE) {
2260 current_object_->code_[write_index] =
Atom(h);
2263 in_stream_->seekg(i);
2264 State s = save_state();
2265 if (expression(indented, DEVICE_ID, write_index, extent_index, write))
2270 set_error(
" error: expected a device id");
2276 bool Compiler::read_function(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2278 if (read_nil_fid(write_index, extent_index, write))
2280 if (read_variable(write_index, extent_index, write, FUNCTION_ID))
2282 if (read_reference(write_index, extent_index, write, FUNCTION_ID))
2284 if (read_wildcard(write_index, extent_index, write))
2286 if (read_tail_wildcard(write_index, extent_index, write))
2293 current_object_->code_[write_index] = _p.atom_;
2296 State s = save_state();
2297 if (expression(indented, FUNCTION_ID, write_index, extent_index, write))
2302 set_error(
" error: expected a device function");
2308 bool Compiler::read_expression(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2310 if (read_nil(write_index, extent_index, write))
2312 if (p && p->str_opcode != Class::Expression) {
2314 if (read_variable(write_index, extent_index, write, *p))
2316 if (read_reference(write_index, extent_index, write, p->type))
2320 if (read_variable(write_index, extent_index, write, Class()))
2322 if (read_reference(write_index, extent_index, write, ANY))
2325 if (read_wildcard(write_index, extent_index, write))
2327 if (read_tail_wildcard(write_index, extent_index, write))
2331 if (p && p->str_opcode != Class::Expression) {
2333 if (expression(indented, *p, write_index, extent_index, write))
2335 }
else if (expression(indented, ANY, write_index, extent_index, write))
2339 std::string s =
" error: expected an expression";
2351 bool Compiler::read_set(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2353 if (read_nil_set(write_index, extent_index, write))
2355 if (read_variable(write_index, extent_index, write, Class(SET)))
2357 if (read_reference(write_index, extent_index, write, SET))
2359 if (read_wildcard(write_index, extent_index, write))
2361 if (read_tail_wildcard(write_index, extent_index, write))
2367 if (set(indented, *p, write_index, extent_index, write))
2369 }
else if (set(indented, write_index, extent_index, write))
2373 set_error(
" error: expected a set");
2379 bool Compiler::read_class(
bool &indented,
bool enforce,
const Class *p, uint16 write_index, uint16 &extent_index,
bool write) {
2381 std::streampos i = in_stream_->tellg();
2389 local_references_[l] = Reference(write_index, _p, Class());
2391 current_object_->code_[write_index] = _p.atom_;
2394 in_stream_->clear();
2395 in_stream_->seekg(i);
2401 bool Compiler::read_nil(uint16 write_index, uint16 &extent_index,
bool write) {
2406 current_object_->code_[write_index] = Atom::Nil();
2412 bool Compiler::read_nil_set(uint16 write_index, uint16 &extent_index,
bool write) {
2414 std::streampos i = in_stream_->tellg();
2415 if (match_symbol(
"|[]",
false) ||
2417 (match_symbol(
"[]",
false) && in_stream_->peek() >= 32)) {
2421 current_object_->code_[write_index] = Atom::IPointer(extent_index);
2422 current_object_->code_[extent_index++] = Atom::Set(0);
2426 in_stream_->seekg(i);
2430 bool Compiler::read_nil_nb(uint16 write_index, uint16 &extent_index,
bool write) {
2435 current_object_->code_[write_index] = Atom::UndefinedFloat();
2441 bool Compiler::read_nil_ts(uint16 write_index, uint16 &extent_index,
bool write) {
2447 current_object_->code_[write_index] = Atom::IPointer(extent_index);
2448 current_object_->code_[extent_index++] = Atom::UndefinedTimestamp();
2449 current_object_->code_[extent_index++] = 0xFFFFFFFF;
2450 current_object_->code_[extent_index++] = 0xFFFFFFFF;
2457 bool Compiler::read_forever_nb(uint16 write_index, uint16 &extent_index,
bool write) {
2463 current_object_->code_[write_index] = Atom::PlusInfinity();
2470 bool Compiler::read_nil_nid(uint16 write_index, uint16 &extent_index,
bool write) {
2475 current_object_->code_[write_index] = Atom::UndefinedNode();
2481 bool Compiler::read_nil_did(uint16 write_index, uint16 &extent_index,
bool write) {
2486 current_object_->code_[write_index] = Atom::UndefinedDevice();
2492 bool Compiler::read_nil_fid(uint16 write_index, uint16 &extent_index,
bool write) {
2497 current_object_->code_[write_index] = Atom::UndefinedDeviceFunction();
2503 bool Compiler::read_nil_bl(uint16 write_index, uint16 &extent_index,
bool write) {
2508 current_object_->code_[write_index] = Atom::UndefinedBoolean();
2514 bool Compiler::read_nil_st(uint16 write_index, uint16 &extent_index,
bool write) {
2519 current_object_->code_[write_index] = Atom::UndefinedString();
2525 bool Compiler::read_variable(uint16 write_index, uint16 &extent_index,
bool write,
const Class p) {
2530 if (state_.pattern_lvl || allow_variables_and_wildcards_outside_pattern_skeleton_) {
2533 (allow_variables_and_wildcards_outside_pattern_skeleton_ && current_class_.str_opcode !=
"pgm")) {
2535 uint8 variable_index = add_hlp_reference(v);
2537 current_object_->code_[write_index] = Atom::VLPointer(variable_index);
2540 addLocalReference(v, write_index, p);
2542 current_object_->code_[write_index] = Atom::Wildcard(p.atom_.asOpcode());
2547 set_error(
" error: no variables allowed outside a pattern skeleton");
2554 bool Compiler::read_reference(uint16 write_index, uint16 &extent_index,
bool write,
const ReturnType t) {
2557 if ((t == ANY || (t != ANY && current_class_.type == t)) && this_()) {
2560 current_object_->code_[write_index] = Atom::This();
2563 if (local_reference(index, t)) {
2566 current_object_->code_[write_index] = Atom::CodeVLPointer(index);
2569 if (global_reference(index, t)) {
2572 current_object_->code_[write_index] = Atom::RPointer(index);
2576 if (this_indirection(v, t)) {
2580 current_object_->code_[write_index] = Atom::IPointer(extent_index);
2581 current_object_->code_[extent_index++] = Atom::CPointer(v.size() + 1);
2582 current_object_->code_[extent_index++] = Atom::This();
2583 for (uint16 i = 0; i < v.size(); ++i) {
2587 current_object_->code_[extent_index++] = Atom::View();
2590 current_object_->code_[extent_index++] = Atom::Mks();
2593 current_object_->code_[extent_index++] = Atom::Vws();
2596 current_object_->code_[extent_index++] = Atom::IPointer(v[i]);
2604 if (local_indirection(v, t, cast_opcode)) {
2608 current_object_->code_[write_index] = Atom::IPointer(extent_index);
2609 current_object_->code_[extent_index++] = Atom::CPointer(v.size());
2610 current_object_->code_[extent_index++] = Atom::CodeVLPointer(v[0], cast_opcode);
2611 for (uint16 i = 1; i < v.size(); ++i) {
2615 current_object_->code_[extent_index++] = Atom::View();
2618 current_object_->code_[extent_index++] = Atom::Mks();
2621 current_object_->code_[extent_index++] = Atom::Vws();
2624 current_object_->code_[extent_index++] = Atom::IPointer(v[i]);
2631 if (global_indirection(v, t)) {
2635 current_object_->code_[write_index] = Atom::IPointer(extent_index);
2636 current_object_->code_[extent_index++] = Atom::CPointer(v.size());
2637 current_object_->code_[extent_index++] = Atom::RPointer(v[0]);
2638 for (uint16 i = 1; i < v.size(); ++i) {
2642 current_object_->code_[extent_index++] = Atom::Mks();
2645 current_object_->code_[extent_index++] = Atom::Vws();
2648 current_object_->code_[extent_index++] = Atom::IPointer(v[i]);
2655 if (hlp_reference(index)) {
2658 current_object_->code_[write_index] = Atom::VLPointer(index);
2664 bool Compiler::read_wildcard(uint16 write_index, uint16 &extent_index,
bool write) {
2668 if (state_.pattern_lvl || allow_variables_and_wildcards_outside_pattern_skeleton_) {
2671 current_object_->code_[write_index] = Atom::Wildcard();
2675 set_error(
" error: no wildcards allowed outside a pattern skeleton");
2682 bool Compiler::read_tail_wildcard(uint16 write_index, uint16 &extent_index,
bool write) {
2684 if (tail_wildcard()) {
2686 if (state_.pattern_lvl) {
2689 current_object_->code_[write_index] = Atom::TailWildcard();
2693 set_error(
" error: no wildcards allowed outside a pattern skeleton");
2700 std::string Compiler::getObjectName(
const uint16 index)
const {
2702 unordered_map<std::string, Reference>::const_iterator r;
2703 for (r = global_references_.begin(); r != global_references_.end(); ++r) {
2705 if (r->second.index_ == index)