@@ -90,6 +90,7 @@ class smv_typecheckt:public typecheckt
9090 void typecheck (smv_parse_treet::modulet::itemt &);
9191 void typecheck_expr_rec (exprt &, modet);
9292 void convert_expr_to (exprt &, const typet &dest);
93+ exprt convert_word_constant (const constant_exprt &);
9394
9495 smv_parse_treet::modulet *modulep;
9596
@@ -582,6 +583,123 @@ void smv_typecheckt::typecheck(exprt &expr, modet mode)
582583
583584/* ******************************************************************\
584585
586+ Function: convert_word_constant
587+
588+ Inputs:
589+
590+ Outputs:
591+
592+ Purpose:
593+
594+ \*******************************************************************/
595+
596+ exprt smv_typecheckt::convert_word_constant (const constant_exprt &src_expr)
597+ {
598+ auto &src = id2string (src_expr.get_value ());
599+
600+ DATA_INVARIANT (src[0 ] == ' 0' , " word constant grammar" );
601+
602+ std::size_t index = 1 ;
603+ bool is_signed = false ;
604+
605+ DATA_INVARIANT (index < src.size (), " word constant length" );
606+
607+ switch (src[index])
608+ {
609+ case ' s' :
610+ case ' S' :
611+ is_signed = true ;
612+ index++;
613+ break ;
614+
615+ case ' u' :
616+ case ' U' :
617+ // this is the default
618+ index++;
619+ break ;
620+
621+ default :;
622+ }
623+
624+ DATA_INVARIANT (index < src.size (), " word constant length" );
625+
626+ unsigned base;
627+ switch (src[index])
628+ {
629+ case ' d' :
630+ case ' D' :
631+ base = 10 ;
632+ break ;
633+
634+ case ' h' :
635+ case ' H' :
636+ base = 16 ;
637+ break ;
638+
639+ case ' b' :
640+ case ' B' :
641+ base = 2 ;
642+ break ;
643+
644+ case ' o' :
645+ case ' O' :
646+ base = 8 ;
647+ break ;
648+
649+ default :
650+ DATA_INVARIANT (false , " word constant base" );
651+ }
652+
653+ index++;
654+
655+ DATA_INVARIANT (index < src.size (), " word constant length" );
656+
657+ std::optional<mp_integer> bits = {};
658+
659+ // optional number of bits
660+ if (isdigit (src[index]))
661+ {
662+ std::string bits_str;
663+ for (; index < src.size () && isdigit (src[index]); index++)
664+ {
665+ bits_str += src[index];
666+ }
667+
668+ bits = string2integer (bits_str);
669+ }
670+
671+ std::string digits;
672+ digits.reserve (src.size ());
673+
674+ for (; index < src.size (); index++)
675+ {
676+ if (src[index] != ' _' )
677+ digits.push_back (src[index]);
678+ }
679+
680+ if (!bits.has_value ())
681+ {
682+ if (base == 10 )
683+ throw errort{}.with_location (src_expr.source_location ())
684+ << " decimal word constant without width" ;
685+ else if (base == 2 )
686+ bits = digits.size ();
687+ else if (base == 8 )
688+ bits = digits.size () * 3 ;
689+ else if (base == 16 )
690+ bits = digits.size () * 4 ;
691+ }
692+
693+ auto digits_int = string2integer (digits, base);
694+
695+ auto type =
696+ bitvector_typet{is_signed ? ID_signedbv : ID_unsignedbv, bits.value ()};
697+
698+ return from_integer (digits_int, type).with_source_location (src_expr);
699+ }
700+
701+ /* ******************************************************************\
702+
585703Function: smv_typecheckt::typecheck_expr_rec
586704
587705 Inputs:
@@ -845,6 +963,11 @@ void smv_typecheckt::typecheck_expr_rec(exprt &expr, modet mode)
845963 {
846964 // good as is
847965 }
966+ else if (type.id () == ID_smv_word_constant)
967+ {
968+ // turn into signedbv/unsignedbv
969+ expr = convert_word_constant (to_constant_expr (expr));
970+ }
848971 else
849972 {
850973 PRECONDITION (false );
0 commit comments