Commits

Lionel Flandrin committed f297b65

Added variables

  • Participants
  • Parent commits 08618f4

Comments (0)

Files changed (8)

   this->printers["vd"] = new PrintVerilog(10);
   this->printers["vo"] = new PrintVerilog(8);
   this->printers["vb"] = new PrintVerilog(2);
+
+  // Some useful default variables. I use strings to avoid precision
+  // loss.
+  this->variables["k"] = new Integer("1000");
+  this->variables["M"] = new Integer("1000000");
+  this->variables["G"] = new Integer("1000000000");
+  this->variables["T"] = new Integer("1000000000000");
+  this->variables["m"] = new Float("0.001");
+  this->variables["u"] = new Float("0.000001");
+  this->variables["n"] = new Float("0.000000001");
+  this->variables["p"] = new Float("0.000000000001");
+
+  this->variables["kB"] = new Integer("400", 16);
+  this->variables["MB"] = new Integer("100000", 16);
+  this->variables["GB"] = new Integer("40000000", 16);
+  this->variables["TB"] = new Integer("10000000000", 16);
 }
 
 Lexer::~Lexer()
        i != this->printers.end();
        ++i)
     delete i->second;
+  this->printers.clear();
 
-  this->printers.clear();
+  for (var_map_t::iterator i = this->variables.begin();
+       i != this->variables.end();
+       ++i)
+    delete i->second;
+  this->variables.clear();
 }
 
 void Lexer::push_prompt(const std::string &p)
   return Parser::token::SYMBOL;
 }
 
+Value *Lexer::get_variable(const std::string &s)
+{
+  var_map_t::iterator it;
+
+  it = this->variables.find(s);
+
+  if (it == this->variables.end())
+    return NULL;
+  else
+    return it->second->clone();
+}
+
+void Lexer::set_variable(const std::string &s, const Value &v)
+{
+  var_map_t::iterator it;
+
+  it = this->variables.find(s);
+
+  if (it == this->variables.end())
+    this->variables[s] = v.clone();
+  else {
+    delete it->second;
+    it->second = v.clone();
+  }
+}
+
 void Lexer::result(Value *v, const std::string &p)
 {
   printer_map_t::iterator it;
   class Lexer : public yyFlexLexer {
   private:
     typedef std::map<std::string, Printer *> printer_map_t;
+    typedef std::map<std::string, Value *>   var_map_t;
 
     Parser::semantic_type   *yylval;
     Parser::location_type   *loc;
     std::stack<std::string>  prompts;
     std::string              rdbuf;
     printer_map_t            printers;
+    var_map_t                variables;
 
   public:
     Lexer(bool);
     int parse_verilog();
     int parse_symbol();
 
+    Value *get_variable(const std::string &);
+    void   set_variable(const std::string &, const Value &);
+
     void result(Value *, const std::string & = "");
 
   private:
   mpz_init_set_si(this->v, i);
 }
 
+Integer::Integer(unsigned long i)
+{
+  mpz_init_set_ui(this->v, i);
+}
+
 Integer::Integer(const Float &f)
 {
   mpz_init(this->v);
   return *this;
 }
 
+Value *Integer::clone() const
+{
+  return new Integer(*this);
+}
+
 Value &Integer::operator+=(const Value &v)
 {
   const Integer &i = dynamic_cast<const Integer &>(v);
   mpf_init_set_si(this->v, i);
 }
 
+Float::Float(double d)
+{
+  mpf_init_set_d(this->v, d);
+}
+
 Float::Float(const Integer &i)
 {
   mpf_init(this->v);
   return *this;
 }
 
+Value *Float::clone() const
+{
+  return new Float(*this);
+}
 
 Value &Float::operator+=(const Value &v)
 {
 
     virtual Value &neg() = 0;
     virtual Value &pow(const Value &) = 0;
+    virtual Value *clone() const = 0;
     virtual Value &operator+=(const Value &) = 0;
     virtual Value &operator-=(const Value &) = 0;
     virtual Value &operator*=(const Value &) = 0;
     Integer();
     Integer(const Integer &);
     Integer(int);
+    Integer(unsigned long);
     Integer(const Float &);
     Integer(const std::string &, int = 0);
     virtual ~Integer();
 
     virtual Value &neg();
     virtual Value &pow(const Value &);
+    virtual Value *clone() const;
     virtual Value &operator+=(const Value &);
     virtual Value &operator-=(const Value &);
     virtual Value &operator*=(const Value &);
     Float();
     Float(const Float &);
     Float(int);
+    Float(double);
     Float(const Integer &);
     Float(const std::string &, int = 0);
     virtual ~Float();
 
     virtual Value &neg();
     virtual Value &pow(const Value &);
+    virtual Value *clone() const;
     virtual Value &operator+=(const Value &);
     virtual Value &operator-=(const Value &);
     virtual Value &operator*=(const Value &);

tests/expected-output.txt

 2'sb11
 4'b1010 +0.1
 5'sb10110 -0.1
+2101587420200.001001
+42
+42
+129
+43
+132
+43
+4.2
+103.64
           ^^^^^ division by 0
           ^^^^^^^^^^^^^^^^ division by 0
 5
          ^ syntax error
-             ^^^^^^^ unknown symbol
+             ^^^^^^^ unbound variable
 Unknown printer unknown
           ^^^^ expected integer
            ^ syntax error
 10.1:vb
 -10.1:vb
 
+# Variables
+k + M + G + T + m + u + n + p + kB + MB + GB + TB
+var = 42
+var
+3 * (var + 1)
+var = 43
+3 * (var + 1)
+var1 = var2 = var
+var3 = var4 = 4.2
+var1 + var2 + var3 * var4
+
 # Error handling
 42 + 1 / 0
 42 + 2 / ( 4 - 5 + 1)
 \<\< { return Parser::token::LSHIFT; }
 \>\> { return Parser::token::RSHIFT; }
 
-[-+*/:|^&~,] { return *yytext; }
+[-+*/:|^&~,=] { return *yytext; }
 
 "("           { PUSH_STATE(inparens); return *yytext; }
 <inparens>")" { POP_STATE(); return *yytext; }
 {PREFIXINT} { return this->parse_int_prefix(); }
 {DEC}+      { return this->parse_int(); }
 
-[a-zA-Z]+ {  return this->parse_symbol(); }
+[a-zA-Z][a-zA-Z0-9]* { return this->parse_symbol(); }
 
 . { return Parser::token::BAD; }
 
 
 /* Order of the operators is significant: the lowest in the file, the
    highest the precedence */
+%right '='
 %left '|'
 %left '^'
 %left '&'
   | '(' INT ')' exp %prec CAST  { $$ = $4; cast_to_int($$); }
   | VALUE
   | BAD { this->error(@1, "unexpected character"); YYERROR; $$ = NULL; }
-  | SYMBOL { this->error(@1, "unknown symbol"); delete $1; YYERROR; $$ = NULL; }
+  | SYMBOL '=' exp {
+    this->lexer.set_variable(*$1, *$3);
+    $$ = $3;
+    delete $1;
+  }
+  | SYMBOL {
+    $$ = this->lexer.get_variable(*$1);
+    delete $1;
+    if (!$$) {
+      this->error(@1, "unbound variable");
+      YYERROR;
+    }
+  }
 ;
 
 %%