summaryrefslogtreecommitdiff
path: root/utils/regtools/lib/soc_desc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/regtools/lib/soc_desc.cpp')
-rw-r--r--utils/regtools/lib/soc_desc.cpp700
1 files changed, 693 insertions, 7 deletions
diff --git a/utils/regtools/lib/soc_desc.cpp b/utils/regtools/lib/soc_desc.cpp
index 6a6d47648f..1c9eaf7972 100644
--- a/utils/regtools/lib/soc_desc.cpp
+++ b/utils/regtools/lib/soc_desc.cpp
@@ -21,8 +21,12 @@
21#include "soc_desc.hpp" 21#include "soc_desc.hpp"
22#include <libxml/parser.h> 22#include <libxml/parser.h>
23#include <libxml/tree.h> 23#include <libxml/tree.h>
24#include <libxml/xmlsave.h>
25#include <libxml/xmlwriter.h>
24#include <stdio.h> 26#include <stdio.h>
25#include <string.h> 27#include <string.h>
28#include <algorithm>
29#include <cctype>
26 30
27#define XML_CHAR_TO_CHAR(s) ((const char *)(s)) 31#define XML_CHAR_TO_CHAR(s) ((const char *)(s))
28 32
@@ -78,6 +82,9 @@
78#define END_NODE_MATCH() \ 82#define END_NODE_MATCH() \
79 } 83 }
80 84
85namespace
86{
87
81bool validate_string_hook(const std::string& str, std::string& s) 88bool validate_string_hook(const std::string& str, std::string& s)
82{ 89{
83 s = str; 90 s = str;
@@ -137,6 +144,7 @@ bool parse_value_elem(xmlNode *node, soc_reg_field_value_t& value)
137 BEGIN_ATTR_MATCH(node->properties) 144 BEGIN_ATTR_MATCH(node->properties)
138 MATCH_TEXT_ATTR("name", value.name) 145 MATCH_TEXT_ATTR("name", value.name)
139 MATCH_UINT32_ATTR("value", value.value) 146 MATCH_UINT32_ATTR("value", value.value)
147 MATCH_TEXT_ATTR("desc", value.desc)
140 END_ATTR_MATCH() 148 END_ATTR_MATCH()
141 149
142 return true; 150 return true;
@@ -256,28 +264,706 @@ bool parse_soc_elem(xmlNode *node, soc_t& soc)
256 return true; 264 return true;
257} 265}
258 266
259bool parse_root_elem(xmlNode *node, std::vector< soc_t >& soc) 267bool parse_root_elem(xmlNode *node, soc_t& soc)
260{ 268{
269 std::vector< soc_t > socs;
261 BEGIN_NODE_MATCH(node) 270 BEGIN_NODE_MATCH(node)
262 MATCH_ELEM_NODE("soc", soc, parse_soc_elem) 271 MATCH_ELEM_NODE("soc", socs, parse_soc_elem)
263 END_NODE_MATCH() 272 END_NODE_MATCH()
273 if(socs.size() != 1)
274 {
275 fprintf(stderr, "A description file must contain exactly one soc element\n");
276 return false;
277 }
278 soc = socs[0];
264 return true; 279 return true;
265} 280}
266 281
267bool soc_desc_parse_xml(const std::string& filename, std::vector< soc_t >& socs) 282}
283
284bool soc_desc_parse_xml(const std::string& filename, soc_t& socs)
268{ 285{
269 LIBXML_TEST_VERSION 286 LIBXML_TEST_VERSION
270 287
271 xmlDoc *doc = xmlReadFile(filename.c_str(), NULL, 0); 288 xmlDocPtr doc = xmlReadFile(filename.c_str(), NULL, 0);
272 if(doc == NULL) 289 if(doc == NULL)
273 return false; 290 return false;
274 291
275 xmlNode *root_element = xmlDocGetRootElement(doc); 292 xmlNodePtr root_element = xmlDocGetRootElement(doc);
276
277 bool ret = parse_root_elem(root_element, socs); 293 bool ret = parse_root_elem(root_element, socs);
278 294
279 xmlFreeDoc(doc); 295 xmlFreeDoc(doc);
280 xmlCleanupParser(); 296 xmlCleanupParser();
281 297
282 return ret; 298 return ret;
283} \ No newline at end of file 299}
300
301namespace
302{
303
304int produce_field(xmlTextWriterPtr writer, const soc_reg_field_t& field)
305{
306#define SAFE(x) if((x) < 0) return -1;
307 /* <field> */
308 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "field"));
309 /* name */
310 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST field.name.c_str()));
311 /* desc */
312 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "desc", BAD_CAST field.desc.c_str()));
313 /* bitrange */
314 SAFE(xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "bitrange", "%d:%d",
315 field.last_bit, field.first_bit));
316 /* values */
317 for(size_t i = 0; i < field.value.size(); i++)
318 {
319 /* <value> */
320 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "value"));
321 /* name */
322 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST field.value[i].name.c_str()));
323 /* value */
324 SAFE(xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "value", "0x%x", field.value[i].value));
325 /* name */
326 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "desc", BAD_CAST field.value[i].desc.c_str()));
327 /* </value> */
328 SAFE(xmlTextWriterEndElement(writer));
329 }
330 /* </field> */
331 SAFE(xmlTextWriterEndElement(writer));
332#undef SAFE
333 return 0;
334}
335
336int produce_reg(xmlTextWriterPtr writer, const soc_reg_t& reg)
337{
338#define SAFE(x) if((x) < 0) return -1;
339 /* <reg> */
340 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "reg"));
341 /* name */
342 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST reg.name.c_str()));
343 /* name */
344 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "desc", BAD_CAST reg.desc.c_str()));
345 /* flags */
346 if(reg.flags & REG_HAS_SCT)
347 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "sct", BAD_CAST "yes"));
348 /* formula */
349 if(reg.formula.type != REG_FORMULA_NONE)
350 {
351 /* <formula> */
352 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "formula"));
353 switch(reg.formula.type)
354 {
355 case REG_FORMULA_STRING:
356 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "string",
357 BAD_CAST reg.formula.string.c_str()));
358 break;
359 default:
360 break;
361 }
362 /* </formula> */
363 SAFE(xmlTextWriterEndElement(writer));
364 }
365 /* addresses */
366 for(size_t i = 0; i < reg.addr.size(); i++)
367 {
368 /* <addr> */
369 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "addr"));
370 /* name */
371 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST reg.addr[i].name.c_str()));
372 /* addr */
373 SAFE(xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "addr", "0x%x", reg.addr[i].addr));
374 /* </addr> */
375 SAFE(xmlTextWriterEndElement(writer));
376 }
377 /* fields */
378 for(size_t i = 0; i < reg.field.size(); i++)
379 produce_field(writer, reg.field[i]);
380 /* </reg> */
381 SAFE(xmlTextWriterEndElement(writer));
382#undef SAFE
383 return 0;
384}
385
386int produce_dev(xmlTextWriterPtr writer, const soc_dev_t& dev)
387{
388#define SAFE(x) if((x) < 0) return -1;
389 /* <dev> */
390 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "dev"));
391 /* name */
392 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST dev.name.c_str()));
393 /* long_name */
394 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "long_name", BAD_CAST dev.long_name.c_str()));
395 /* desc */
396 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "desc", BAD_CAST dev.desc.c_str()));
397 /* version */
398 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "version", BAD_CAST dev.version.c_str()));
399 /* addresses */
400 for(size_t i = 0; i < dev.addr.size(); i++)
401 {
402 /* <addr> */
403 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "addr"));
404 /* name */
405 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST dev.addr[i].name.c_str()));
406 /* addr */
407 SAFE(xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "addr", "0x%x", dev.addr[i].addr));
408 /* </addr> */
409 SAFE(xmlTextWriterEndElement(writer));
410 }
411 /* registers */
412 for(size_t i = 0; i < dev.reg.size(); i++)
413 produce_reg(writer, dev.reg[i]);
414 /* </dev> */
415 SAFE(xmlTextWriterEndElement(writer));
416#undef SAFE
417 return 0;
418}
419
420}
421
422bool soc_desc_produce_xml(const std::string& filename, const soc_t& soc)
423{
424 LIBXML_TEST_VERSION
425
426 xmlTextWriterPtr writer = xmlNewTextWriterFilename(filename.c_str(), 0);
427 if(writer == NULL)
428 return false;
429#define SAFE(x) if((x) < 0) goto Lerr
430 SAFE(xmlTextWriterSetIndent(writer, 1));
431 SAFE(xmlTextWriterSetIndentString(writer, BAD_CAST " "));
432 /* <xml> */
433 SAFE(xmlTextWriterStartDocument(writer, NULL, NULL, NULL));
434 /* <soc> */
435 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "soc"));
436 /* name */
437 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST soc.name.c_str()));
438 /* desc */
439 SAFE(xmlTextWriterWriteAttribute(writer, BAD_CAST "desc", BAD_CAST soc.desc.c_str()));
440 /* devices */
441 for(size_t i = 0; i < soc.dev.size(); i++)
442 SAFE(produce_dev(writer, soc.dev[i]));
443 /* end <soc> */
444 SAFE(xmlTextWriterEndElement(writer));
445 /* </xml> */
446 SAFE(xmlTextWriterEndDocument(writer));
447 xmlFreeTextWriter(writer);
448 return true;
449#undef SAFE
450Lerr:
451 xmlFreeTextWriter(writer);
452 return false;
453}
454
455namespace
456{
457
458struct soc_sorter
459{
460 bool operator()(const soc_dev_t& a, const soc_dev_t& b) const
461 {
462 return a.name < b.name;
463 }
464
465 bool operator()(const soc_dev_addr_t& a, const soc_dev_addr_t& b) const
466 {
467 return a.name < b.name;
468 }
469
470 bool operator()(const soc_reg_t& a, const soc_reg_t& b) const
471 {
472 soc_addr_t aa = a.addr.size() > 0 ? a.addr[0].addr : 0;
473 soc_addr_t ab = b.addr.size() > 0 ? b.addr[0].addr : 0;
474 return aa < ab;
475 }
476
477 bool operator()(const soc_reg_addr_t& a, const soc_reg_addr_t& b) const
478 {
479 return a.addr < b.addr;
480 }
481
482 bool operator()(const soc_reg_field_t& a, const soc_reg_field_t& b) const
483 {
484 return a.last_bit > b.last_bit;
485 }
486
487 bool operator()(const soc_reg_field_value_t a, const soc_reg_field_value_t& b) const
488 {
489 return a.value < b.value;
490 }
491};
492
493void normalize(soc_reg_field_t& field)
494{
495 std::sort(field.value.begin(), field.value.end(), soc_sorter());
496}
497
498void normalize(soc_reg_t& reg)
499{
500 std::sort(reg.addr.begin(), reg.addr.end(), soc_sorter());
501 std::sort(reg.field.begin(), reg.field.end(), soc_sorter());
502 for(size_t i = 0; i < reg.field.size(); i++)
503 normalize(reg.field[i]);
504}
505
506void normalize(soc_dev_t& dev)
507{
508 std::sort(dev.addr.begin(), dev.addr.end(), soc_sorter());
509 std::sort(dev.reg.begin(), dev.reg.end(), soc_sorter());
510 for(size_t i = 0; i < dev.reg.size(); i++)
511 normalize(dev.reg[i]);
512}
513
514}
515
516void soc_desc_normalize(soc_t& soc)
517{
518 std::sort(soc.dev.begin(), soc.dev.end(), soc_sorter());
519 for(size_t i = 0; i < soc.dev.size(); i++)
520 normalize(soc.dev[i]);
521}
522
523namespace
524{
525 soc_error_t make_error(soc_error_level_t lvl, std::string at, std::string what)
526 {
527 soc_error_t err;
528 err.level = lvl;
529 err.location = at;
530 err.message = what;
531 return err;
532 }
533
534 soc_error_t make_warning(std::string at, std::string what)
535 {
536 return make_error(SOC_ERROR_WARNING, at, what);
537 }
538
539 soc_error_t make_fatal(std::string at, std::string what)
540 {
541 return make_error(SOC_ERROR_FATAL, at, what);
542 }
543
544 soc_error_t prefix(soc_error_t err, const std::string& prefix_at)
545 {
546 err.location = prefix_at + "." + err.location;
547 return err;
548 }
549
550 void add_errors(std::vector< soc_error_t >& errors,
551 const std::vector< soc_error_t >& new_errors, const std::string& prefix_at)
552 {
553 for(size_t i = 0; i < new_errors.size(); i++)
554 errors.push_back(prefix(new_errors[i], prefix_at));
555 }
556
557 std::vector< soc_error_t > no_error()
558 {
559 std::vector< soc_error_t > s;
560 return s;
561 }
562
563 std::vector< soc_error_t > one_error(const soc_error_t& err)
564 {
565 std::vector< soc_error_t > s;
566 s.push_back(err);
567 return s;
568 }
569
570 bool name_valid(char c)
571 {
572 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
573 (c >= 'A' && c <= 'Z') || c == '_';
574 }
575
576 bool name_valid(const std::string& s)
577 {
578 for(size_t i = 0; i < s.size(); i++)
579 if(!name_valid(s[i]))
580 return false;
581 return true;
582 }
583}
584
585std::vector< soc_error_t > soc_reg_field_value_t::errors(bool recursive)
586{
587 (void) recursive;
588 if(name.size() == 0)
589 return one_error(make_fatal(name, "empty name"));
590 else if(!name_valid(name))
591 return one_error(make_fatal(name, "invalid name"));
592 else
593 return no_error();
594}
595
596std::vector< soc_error_t > soc_reg_field_t::errors(bool recursive)
597{
598 std::vector< soc_error_t > err;
599 std::string at(name);
600 if(name.size() == 0)
601 err.push_back(make_fatal(at, "empty name"));
602 else if(!name_valid(name))
603 err.push_back(make_fatal(at, "invalid name"));
604 if(last_bit > 31)
605 err.push_back(make_fatal(at, "last bit is greater than 31"));
606 if(first_bit > last_bit)
607 err.push_back(make_fatal(at, "last bit is greater than first bit"));
608 for(size_t i = 0; i < value.size(); i++)
609 {
610 for(size_t j = 0; j < value.size(); j++)
611 {
612 if(i == j)
613 continue;
614 if(value[i].name == value[j].name)
615 err.push_back(prefix(make_fatal(value[i].name,
616 "there are several values with the same name"), at));
617 if(value[i].value == value[j].value)
618 err.push_back(prefix(make_warning(value[i].name,
619 "there are several values with the same value"), at));
620 }
621 if(value[i].value > (bitmask() >> first_bit))
622 err.push_back(prefix(make_warning(at, "value doesn't fit into the field"), value[i].name));
623 if(recursive)
624 add_errors(err, value[i].errors(true), at);
625 }
626 return err;
627}
628
629std::vector< soc_error_t > soc_reg_addr_t::errors(bool recursive)
630{
631 (void) recursive;
632 if(name.size() == 0)
633 return one_error(make_fatal("", "empty name"));
634 else if(!name_valid(name))
635 return one_error(make_fatal(name, "invalid name"));
636 else
637 return no_error();
638}
639
640std::vector< soc_error_t > soc_reg_formula_t::errors(bool recursive)
641{
642 (void) recursive;
643 if(type == REG_FORMULA_STRING && string.size() == 0)
644 return one_error(make_fatal("", "empty string formula"));
645 else
646 return no_error();
647}
648
649namespace
650{
651
652bool field_overlap(const soc_reg_field_t& a, const soc_reg_field_t& b)
653{
654 return !(a.first_bit > b.last_bit || b.first_bit > a.last_bit);
655}
656
657}
658
659std::vector< soc_error_t > soc_reg_t::errors(bool recursive)
660{
661 std::vector< soc_error_t > err;
662 std::string at(name);
663 if(name.size() == 0)
664 err.push_back(make_fatal(at, "empty name"));
665 else if(!name_valid(name))
666 err.push_back(make_fatal(at, "invalid name"));
667 for(size_t i = 0; i < addr.size(); i++)
668 {
669 for(size_t j = 0; j < addr.size(); j++)
670 {
671 if(i == j)
672 continue;
673 if(addr[i].name == addr[j].name)
674 err.push_back(prefix(make_fatal(addr[i].name,
675 "there are several instances with the same name"), at));
676 if(addr[i].addr == addr[j].addr)
677 err.push_back(prefix(make_fatal(addr[i].name,
678 "there are several instances with the same address"), at));
679 }
680 if(recursive)
681 add_errors(err, addr[i].errors(true), at);
682 }
683 if(recursive)
684 add_errors(err, formula.errors(true), at);
685 for(size_t i = 0; i < field.size(); i++)
686 {
687 for(size_t j = 0; j < field.size(); j++)
688 {
689 if(i == j)
690 continue;
691 if(field[i].name == field[j].name)
692 err.push_back(prefix(make_fatal(field[i].name,
693 "there are several fields with the same name"), at));
694 if(field_overlap(field[i], field[j]))
695 err.push_back(prefix(make_fatal(field[i].name,
696 "there are overlapping fields"), at));
697 }
698 if(recursive)
699 add_errors(err, field[i].errors(true), at);
700 }
701 return err;
702}
703
704std::vector< soc_error_t > soc_dev_addr_t::errors(bool recursive)
705{
706 (void) recursive;
707 if(name.size() == 0)
708 return one_error(make_fatal("", "empty name"));
709 else if(!name_valid(name))
710 return one_error(make_fatal(name, "invalid name"));
711 else
712 return no_error();
713}
714
715std::vector< soc_error_t > soc_dev_t::errors(bool recursive)
716{
717 std::vector< soc_error_t > err;
718 std::string at(name);
719 if(name.size() == 0)
720 err.push_back(make_fatal(at, "empty name"));
721 else if(!name_valid(name))
722 err.push_back(make_fatal(at, "invalid name"));
723 for(size_t i = 0; i < addr.size(); i++)
724 {
725 for(size_t j = 0; j < addr.size(); j++)
726 {
727 if(i == j)
728 continue;
729 if(addr[i].name == addr[j].name)
730 err.push_back(prefix(make_fatal(addr[i].name,
731 "there are several instances with the same name"), at));
732 if(addr[i].addr == addr[j].addr)
733 err.push_back(prefix(make_fatal(addr[i].name,
734 "there are several instances with the same address"), at));
735 }
736 if(recursive)
737 add_errors(err, addr[i].errors(true), at);
738 }
739 for(size_t i = 0; i < reg.size(); i++)
740 {
741 for(size_t j = 0; j < reg.size(); j++)
742 {
743 if(i == j)
744 continue;
745 if(reg[i].name == reg[j].name)
746 err.push_back(prefix(make_fatal(reg[i].name,
747 "there are several registers with the same name"), at));
748 }
749 if(recursive)
750 add_errors(err, reg[i].errors(true), at);
751 }
752 return err;
753}
754
755std::vector< soc_error_t > soc_t::errors(bool recursive)
756{
757 std::vector< soc_error_t > err;
758 std::string at(name);
759 for(size_t i = 0; i < dev.size(); i++)
760 {
761 for(size_t j = 0; j < dev.size(); j++)
762 {
763 if(i == j)
764 continue;
765 if(dev[i].name == dev[j].name)
766 err.push_back(prefix(make_fatal(dev[i].name,
767 "there are several devices with the same name"), at));
768 }
769 if(recursive)
770 add_errors(err, dev[i].errors(true), at);
771 }
772 return err;
773}
774
775namespace
776{
777
778struct formula_evaluator
779{
780 std::string formula;
781 size_t pos;
782 std::string error;
783
784 bool err(const char *fmt, ...)
785 {
786 char buffer[256];
787 va_list args;
788 va_start(args, fmt);
789 vsnprintf(buffer,sizeof(buffer), fmt, args);
790 va_end(args);
791 error = buffer;
792 return false;
793 }
794
795 formula_evaluator(const std::string& s):pos(0)
796 {
797 for(size_t i = 0; i < s.size(); i++)
798 if(!isspace(s[i]))
799 formula.push_back(s[i]);
800 }
801
802 void adv()
803 {
804 pos++;
805 }
806
807 char cur()
808 {
809 return end() ? 0 : formula[pos];
810 }
811
812 bool end()
813 {
814 return pos >= formula.size();
815 }
816
817 bool parse_digit(char c, int basis, soc_word_t& res)
818 {
819 c = tolower(c);
820 if(isdigit(c))
821 {
822 res = c - '0';
823 return true;
824 }
825 if(basis == 16 && isxdigit(c))
826 {
827 res = c + 10 - 'a';
828 return true;
829 }
830 return err("invalid digit '%c'", c);
831 }
832
833 bool parse_signed(soc_word_t& res)
834 {
835 char op = cur();
836 if(op == '+' || op == '-')
837 {
838 adv();
839 if(!parse_signed(res))
840 return false;
841 if(op == '-')
842 res *= -1;
843 return true;
844 }
845 else if(op == '(')
846 {
847 adv();
848 if(!parse_expression(res))
849 return false;
850 if(cur() != ')')
851 return err("expected ')', got '%c'", cur());
852 adv();
853 return true;
854 }
855 else if(isdigit(op))
856 {
857 res = op - '0';
858 adv();
859 int basis = 10;
860 if(op == '0' && cur() == 'x')
861 {
862 basis = 16;
863 adv();
864 }
865 soc_word_t digit = 0;
866 while(parse_digit(cur(), basis, digit))
867 {
868 res = res * basis + digit;
869 adv();
870 }
871 return true;
872 }
873 else if(isalpha(op) || op == '_')
874 {
875 std::string name;
876 while(isalnum(cur()) || cur() == '_')
877 {
878 name.push_back(cur());
879 adv();
880 }
881 return get_variable(name, res);
882 }
883 else
884 return err("express signed expression, got '%c'", op);
885 }
886
887 bool parse_term(soc_word_t& res)
888 {
889 if(!parse_signed(res))
890 return false;
891 while(cur() == '*' || cur() == '/' || cur() == '%')
892 {
893 char op = cur();
894 adv();
895 soc_word_t tmp;
896 if(!parse_signed(tmp))
897 return false;
898 if(op == '*')
899 res *= tmp;
900 else if(tmp != 0)
901 res = op == '/' ? res / tmp : res % tmp;
902 else
903 return err("division by 0");
904 }
905 return true;
906 }
907
908 bool parse_expression(soc_word_t& res)
909 {
910 if(!parse_term(res))
911 return false;
912 while(!end() && (cur() == '+' || cur() == '-'))
913 {
914 char op = cur();
915 adv();
916 soc_word_t tmp;
917 if(!parse_term(tmp))
918 return false;
919 if(op == '+')
920 res += tmp;
921 else
922 res -= tmp;
923 }
924 return true;
925 }
926
927 bool parse(soc_word_t& res, std::string& _error)
928 {
929 bool ok = parse_expression(res);
930 if(ok && !end())
931 err("unexpected character '%c'", cur());
932 _error = error;
933 return ok && end();
934 }
935
936 virtual bool get_variable(std::string name, soc_word_t& res)
937 {
938 return err("unknown variable '%s'", name.c_str());
939 }
940};
941
942struct my_evaluator : public formula_evaluator
943{
944 const std::map< std::string, soc_word_t>& var;
945
946 my_evaluator(const std::string& formula, const std::map< std::string, soc_word_t>& _var)
947 :formula_evaluator(formula), var(_var) {}
948
949 virtual bool get_variable(std::string name, soc_word_t& res)
950 {
951 std::map< std::string, soc_word_t>::const_iterator it = var.find(name);
952 if(it == var.end())
953 return formula_evaluator::get_variable(name, res);
954 else
955 {
956 res = it->second;
957 return true;
958 }
959 }
960};
961
962}
963
964bool soc_desc_evaluate_formula(const std::string& formula,
965 const std::map< std::string, soc_word_t>& var, soc_word_t& result, std::string& error)
966{
967 my_evaluator e(formula, var);
968 return e.parse(result, error);
969}