Logo Search packages:      
Sourcecode: fauhdlc version File versions

BuiltinSymbolTable.cpp

/* $Id: BuiltinSymbolTable.cpp 4323 2009-01-27 13:48:12Z potyra $
 *
 * BuiltinSymbolTable: SymbolTable preloaded with symbols from std.standard.
 *
 * Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

/* want INT64_MAX and others defined in c++ */
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif /* __STDC_LIMIT_MACROS */
extern "C" {
#include "stdint.h"
};

#include <climits>
#include <cfloat>
#include <cassert>

#include "frontend/misc/BuiltinSymbolTable.hpp"
#include "frontend/ast/Library.hpp"
#include "frontend/ast/Package.hpp"
#include "frontend/ast/FunctionDeclaration.hpp"
#include "frontend/ast/ConstantDeclaration.hpp"
#include "frontend/ast/EnumerationType.hpp"
#include "frontend/ast/UnconstrainedArrayType.hpp"
#include "frontend/ast/ConstInteger.hpp"
#include "frontend/ast/ConstReal.hpp"
#include "frontend/ast/RangeConstraintType.hpp"
#include "frontend/ast/NodeFactory.hpp"
#include "frontend/ast/PhysicalTypeUnit.hpp"
#include "frontend/ast/AttributeDeclaration.hpp"

namespace ast {

00039 BuiltinSymbolTable::BuiltinSymbolTable() : mayAddStdStandard(false)
{
      this->registerBuiltinSymbols();
      this->mayAddStdStandard = true;
}

void
00046 BuiltinSymbolTable::pushNewRegion(void)
{
      SymbolTable::pushNewRegion();
      if ((this->regionStack.size() == 2) && this->mayAddStdStandard) {
            // must be a library unit
            // add "library std;"
            this->addlibrary("std");

            // and add "using std.standard;"
            std::list<Symbol*> c = this->lookup("std");
            assert(c.size() == 1);

            Symbol *sym = c.front();
            assert(sym->type == SYMBOL_LIBRARY);
            assert(sym->region != NULL);

            c = sym->region->lookup("standard");
            assert(c.size() == 1);
            sym = c.front();
            assert(sym->type == SYMBOL_PACKAGE);
            assert(sym->region != NULL);
            this->importSymbols(*sym->region);
      }
}


void
00073 BuiltinSymbolTable::registerBuiltinSymbols(void)
{
      Library *std = new Library(new std::string("std"));
      this->pushLibrary(*std);

      std::list<SymbolDeclaration*>* standardSyms = 
                        new std::list<SymbolDeclaration*>();

      Package *standard = new Package(
                              new std::string("standard"),
                              NULL,       // lib clauses 
                              NULL,       // use clauses
                              standardSyms,
                              Location("standard"));
      std->units.push_back(standard);

      this->registerSymbolWithRegion(SYMBOL_PACKAGE, *standard);

      this->addStandardStd(*standardSyms);

      this->popRegion(); /* package standard */
      this->popRegion(); /* library std */

      //FIXME: add library std to library list. (note, actually right now I 
      //       think it's better to not have the builtins attached to the
      //       LibraryList. These can get looked up, but should be in the
      //       final form so that visiting these is imho not required, and
      //       could rather be harmful).
}

/* helper macros only for adding symbols */
// FIXME maybe templates might be better? or private member functions?
/* define an unary operator for the last defined enumeration type. 
 * The operand and the 
 * result type will be the last defined enumeration type.
 * No different type may get defined in between.
 */
#define UNOP_ENUM(name, gcBuiltinClass, cpBuiltinClass)\
      args = new std::list<ValDeclaration*>();\
      /* operand */\
      subtypeIndic = new SubtypeIndication(et, \
                        Location("std.standard"));\
      c = new ConstantDeclaration(new std::string("__anonymous__"), \
                        NULL,\
                        subtypeIndic,\
                        false,\
                        Location("std.standard"));\
      args->push_back(c);\
      /* return type */\
      subtypeIndic = new SubtypeIndication(et, \
                        Location("std.standard"));\
      /* create function declaration */\
      f = new FunctionDeclaration(new std::string(name),\
                        args,\
                        subtypeIndic,\
                        true,\
                        Location("std.standard"));\
      f->isBuiltin = true; \
      f->builtin = new cpBuiltinClass(); \
      f->gcBuiltin = new gcBuiltinClass(); \
      this->registerSymbol(SYMBOL_FUNCTION, *f);\
      standardSyms.push_back(f);


/* define a binary operator for the last enumeration defined type. 
 * Both operands and the
 * result type will be the last defined enumeration type.
 * No different type may get defined in between.
 */
#define BINOP_ENUM(name, gcBuiltinClass, cpBuiltinClass)\
      args = new std::list<ValDeclaration*>();\
      /* left operand */\
      subtypeIndic = new SubtypeIndication(et, \
                        Location("std.standard"));\
      c = new ConstantDeclaration(new std::string("__anonymous__"), \
                        NULL,\
                        subtypeIndic,\
                        false, \
                        Location("std.standard"));\
      args->push_back(c);\
      /* right operand */\
      subtypeIndic = new SubtypeIndication(et, \
                        Location("std.standard"));\
      c = new ConstantDeclaration(new std::string("__anonymous__"), \
                        NULL,\
                        subtypeIndic,\
                        false, \
                        Location("std.standard"));\
      args->push_back(c);\
      /* return type */\
      subtypeIndic = new SubtypeIndication(et, \
                        Location("std.standard"));\
      /* create function declaration */\
      f = new FunctionDeclaration(new std::string(name),\
                        args,\
                        subtypeIndic,\
                        true,\
                        Location("std.standard"));\
      f->isBuiltin = true; \
      f->builtin = new cpBuiltinClass(); \
      f->gcBuiltin = new gcBuiltinClass(); \
      this->registerSymbol(SYMBOL_FUNCTION, *f);\
      standardSyms.push_back(f);


#define RANGE_CONSTRAINT_BINOP(name, left, right, result) \
      args = new std::list<ValDeclaration*>();\
      /* left operand */\
      subtypeIndic = new SubtypeIndication(left, \
                        Location("std.standard"));\
      c = new ConstantDeclaration(new std::string("__anonymous__"),\
                        NULL, \
                        subtypeIndic, \
                        false, \
                        Location("std.standard"));\
      args->push_back(c);\
      /* right operand */\
      subtypeIndic = new SubtypeIndication(right, \
                        Location("std.standard"));\
      c = new ConstantDeclaration(new std::string("__anonymous__"),\
                        NULL, \
                        subtypeIndic, \
                        false, \
                        Location("std.standard"));\
      args->push_back(c);\
      /* return type */\
      subtypeIndic = new SubtypeIndication(result, \
                        Location("std.standard"));\
      f = new FunctionDeclaration(new std::string(name),\
                        args, \
                        subtypeIndic, \
                        true, \
                        Location("std.standard"));\
      f->isBuiltin = true; \
      this->registerSymbol(SYMBOL_FUNCTION, *f);\
      standardSyms.push_back(f);
      

/* begin an enumeration type */
#define ENUM_BEGIN(sym) \
      s = new std::string(sym);\
      enumElems = new std::list<EnumerationElement*>();

/* end en enumeration type */
#define ENUM_END \
      et = new EnumerationType(s, enumElems, \
                        Location("std.standard"));\
      \
      sym = this->registerSymbol(SYMBOL_TYPE, *et);\
      NodeFactory::registerEnumElems(et, *this, sym);\
      standardSyms.push_back(et);

#define RANGE_CONSTRAINT_INT(name, lower, upper) \
      s = new std::string(name);\
      i1 = new ConstInteger(lower, Location("lower bound"));\
      i2 = new ConstInteger(upper, Location("upper bound"));\
      dr = new DiscreteRange(i1, i2, DiscreteRange::DIRECTION_UP, \
                        Location("constraint"));\
      r = new RangeConstraintType(s, dr, Location(name));\
      r->baseType = BASE_TYPE_INTEGER;\
      \
      this->registerSymbol(SYMBOL_TYPE, *r);\
      standardSyms.push_back(r);


#define RANGE_CONSTRAINT_REAL(name, lower, upper) \
      s = new std::string(name);\
      r1 = new ConstReal(lower, Location("lower bound"));\
      r2 = new ConstReal(upper, Location("upper bound"));\
      dr = new DiscreteRange(r1, r2, DiscreteRange::DIRECTION_UP, \
                        Location("constraint"));\
      r = new RangeConstraintType(s, dr, Location(name));\
      r->baseType = BASE_TYPE_REAL;\
      \
      this->registerSymbol(SYMBOL_TYPE, *r);\
      standardSyms.push_back(r);

/** define a subtype of the *last* defined integer range constraint type */
#define RANGE_CONSTRAINT_SUBTYPE_INT(name1, lower, upper) \
      subtypeIndic = new SubtypeIndication(r, Location("std.standard")); \
      subtypeIndic->name = new std::string(name1); \
      i1 = new ConstInteger(lower, Location("lower bound")); \
      i2 = new ConstInteger(upper, Location("upper bound")); \
      dr = new DiscreteRange(i1, i2, DiscreteRange::DIRECTION_UP, \
                        Location("constraint")); \
      subtypeIndic->constraint = dr; \
      this->registerSymbol(SYMBOL_TYPE, *subtypeIndic); \
      standardSyms.push_back(subtypeIndic); 

#define DEFINELOCALS() \
      std::string *s;\
      ConstReal *r1;\
      ConstReal *r2;\
      ConstInteger *i1;\
      ConstInteger *i2;\
      DiscreteRange *dr;\
      RangeConstraintType *r;\
      std::list<EnumerationElement*> *enumElems;\
      EnumerationType *et;\
      SubtypeIndication *subtypeIndic;\
      ConstantDeclaration *c;\
      std::list<ValDeclaration*> *args;\
      FunctionDeclaration *f;\
      Symbol *sym;


void
00280 BuiltinSymbolTable::addStandardStd(
      std::list<SymbolDeclaration*> &standardSyms
)
{
      // tricky: each type that gets registered, will create a number
      //         of operations (cf. RegisterBuiltins and LRM 7.2).
      //         Hence the order, in which the types get registered
      //         is important.
      //         As an example, every range constraint type t will define
      //         boolean "=" (t, t). 
      //         For this, the type boolean must be defined already.
      //
      //         Operators, that apply only to specific types, will get 
      //         defined here, every generic operator will get defined
      //         via RegisterBuiltins.
      //
      //         Generic operators will get (automatically) defined *after* 
      //         a specific type was registered. That way it is possible to
      //         register the type boolean, since the generic operators of
      //         enumeration types use boolean as a result type.
      DEFINELOCALS();
      // type boolean
      ENUM_BEGIN("boolean")
      BuiltinSymbolTable::addEnumStr(*enumElems,"false");
      BuiltinSymbolTable::addEnumStr(*enumElems,"true");
      ENUM_END

      BINOP_ENUM("and", GCBuiltinsAnd, EnumAND)
      BINOP_ENUM("or", GCBuiltinsOr, EnumOR)
      BINOP_ENUM("nand", GCBuiltinsNand, EnumNAND)
      BINOP_ENUM("nor", GCBuiltinsNor, EnumNOR)
      BINOP_ENUM("xor", GCBuiltinsXor, EnumXOR)
      BINOP_ENUM("xnor", GCBuiltinsXnor, EnumXNOR)
      UNOP_ENUM("not", GCBuiltinsNot, EnumNOT)

      //type bit
      ENUM_BEGIN("bit")
      BuiltinSymbolTable::addEnumChar(*enumElems,'0');
      BuiltinSymbolTable::addEnumChar(*enumElems,'1');
      ENUM_END

      BINOP_ENUM("and", GCBuiltinsAnd, EnumAND)
      BINOP_ENUM("or", GCBuiltinsOr, EnumOR)
      BINOP_ENUM("nand", GCBuiltinsNand, EnumNAND)
      BINOP_ENUM("nor", GCBuiltinsNor, EnumNOR)
      BINOP_ENUM("xor", GCBuiltinsXor, EnumXOR)
      BINOP_ENUM("xnor", GCBuiltinsXnor, EnumXNOR)
      UNOP_ENUM("not", GCBuiltinsNot, EnumNOT)

      //type character
      ENUM_BEGIN("character")
      BuiltinSymbolTable::addEnumStr(*enumElems,"NUL"); // 0
      BuiltinSymbolTable::addEnumStr(*enumElems,"SOH");
      BuiltinSymbolTable::addEnumStr(*enumElems,"STX");
      BuiltinSymbolTable::addEnumStr(*enumElems,"ETX");
      BuiltinSymbolTable::addEnumStr(*enumElems,"EOT");
      BuiltinSymbolTable::addEnumStr(*enumElems,"ENQ");
      BuiltinSymbolTable::addEnumStr(*enumElems,"ACK");
      BuiltinSymbolTable::addEnumStr(*enumElems,"BEL");
      BuiltinSymbolTable::addEnumStr(*enumElems,"BS");
      BuiltinSymbolTable::addEnumStr(*enumElems,"HT");
      BuiltinSymbolTable::addEnumStr(*enumElems,"LF"); // 10
      BuiltinSymbolTable::addEnumStr(*enumElems,"VT");
      BuiltinSymbolTable::addEnumStr(*enumElems,"FF");
      BuiltinSymbolTable::addEnumStr(*enumElems,"CR");
      BuiltinSymbolTable::addEnumStr(*enumElems,"SO");
      BuiltinSymbolTable::addEnumStr(*enumElems,"SI");
      BuiltinSymbolTable::addEnumStr(*enumElems,"DLE");
      BuiltinSymbolTable::addEnumStr(*enumElems,"DC1");
      BuiltinSymbolTable::addEnumStr(*enumElems,"DC2");
      BuiltinSymbolTable::addEnumStr(*enumElems,"DC3");
      BuiltinSymbolTable::addEnumStr(*enumElems,"DC4"); // 20
      BuiltinSymbolTable::addEnumStr(*enumElems,"NAK");
      BuiltinSymbolTable::addEnumStr(*enumElems,"SYN");
      BuiltinSymbolTable::addEnumStr(*enumElems,"ETB");
      BuiltinSymbolTable::addEnumStr(*enumElems,"CAN");
      BuiltinSymbolTable::addEnumStr(*enumElems,"EM");
      BuiltinSymbolTable::addEnumStr(*enumElems,"SUB");
      BuiltinSymbolTable::addEnumStr(*enumElems,"ESC");
      BuiltinSymbolTable::addEnumStr(*enumElems,"FSP");
      BuiltinSymbolTable::addEnumStr(*enumElems,"GSP");
      BuiltinSymbolTable::addEnumStr(*enumElems,"RSP"); // 30
      BuiltinSymbolTable::addEnumStr(*enumElems,"USB");
      BuiltinSymbolTable::addEnumChar(*enumElems,' ');
      BuiltinSymbolTable::addEnumChar(*enumElems,'!');
      BuiltinSymbolTable::addEnumChar(*enumElems,'"');
      BuiltinSymbolTable::addEnumChar(*enumElems,'#');
      BuiltinSymbolTable::addEnumChar(*enumElems,'$');
      BuiltinSymbolTable::addEnumChar(*enumElems,'%');
      BuiltinSymbolTable::addEnumChar(*enumElems,'&');
      BuiltinSymbolTable::addEnumChar(*enumElems,'\'');
      BuiltinSymbolTable::addEnumChar(*enumElems,'('); // 40
      BuiltinSymbolTable::addEnumChar(*enumElems,')');
      BuiltinSymbolTable::addEnumChar(*enumElems,'*');
      BuiltinSymbolTable::addEnumChar(*enumElems,'+');
      BuiltinSymbolTable::addEnumChar(*enumElems,',');
      BuiltinSymbolTable::addEnumChar(*enumElems,'-');
      BuiltinSymbolTable::addEnumChar(*enumElems,'.');
      BuiltinSymbolTable::addEnumChar(*enumElems,'/');
      BuiltinSymbolTable::addEnumChar(*enumElems,'0');
      BuiltinSymbolTable::addEnumChar(*enumElems,'1');
      BuiltinSymbolTable::addEnumChar(*enumElems,'2'); // 50
      BuiltinSymbolTable::addEnumChar(*enumElems,'3');
      BuiltinSymbolTable::addEnumChar(*enumElems,'4');
      BuiltinSymbolTable::addEnumChar(*enumElems,'5');
      BuiltinSymbolTable::addEnumChar(*enumElems,'6');
      BuiltinSymbolTable::addEnumChar(*enumElems,'7');
      BuiltinSymbolTable::addEnumChar(*enumElems,'8');
      BuiltinSymbolTable::addEnumChar(*enumElems,'9');
      BuiltinSymbolTable::addEnumChar(*enumElems,':');
      BuiltinSymbolTable::addEnumChar(*enumElems,';');
      BuiltinSymbolTable::addEnumChar(*enumElems,'<'); // 60
      BuiltinSymbolTable::addEnumChar(*enumElems,'=');
      BuiltinSymbolTable::addEnumChar(*enumElems,'>');
      BuiltinSymbolTable::addEnumChar(*enumElems,'?');
      BuiltinSymbolTable::addEnumChar(*enumElems,'@');
      BuiltinSymbolTable::addEnumChar(*enumElems,'A');
      BuiltinSymbolTable::addEnumChar(*enumElems,'B');
      BuiltinSymbolTable::addEnumChar(*enumElems,'C');
      BuiltinSymbolTable::addEnumChar(*enumElems,'D');
      BuiltinSymbolTable::addEnumChar(*enumElems,'E');
      BuiltinSymbolTable::addEnumChar(*enumElems,'F'); // 70
      BuiltinSymbolTable::addEnumChar(*enumElems,'G');
      BuiltinSymbolTable::addEnumChar(*enumElems,'H');
      BuiltinSymbolTable::addEnumChar(*enumElems,'I');
      BuiltinSymbolTable::addEnumChar(*enumElems,'J');
      BuiltinSymbolTable::addEnumChar(*enumElems,'K');
      BuiltinSymbolTable::addEnumChar(*enumElems,'L');
      BuiltinSymbolTable::addEnumChar(*enumElems,'M');
      BuiltinSymbolTable::addEnumChar(*enumElems,'N');
      BuiltinSymbolTable::addEnumChar(*enumElems,'O');
      BuiltinSymbolTable::addEnumChar(*enumElems,'P'); // 80
      BuiltinSymbolTable::addEnumChar(*enumElems,'Q'); 
      BuiltinSymbolTable::addEnumChar(*enumElems,'R');
      BuiltinSymbolTable::addEnumChar(*enumElems,'S');
      BuiltinSymbolTable::addEnumChar(*enumElems,'T');
      BuiltinSymbolTable::addEnumChar(*enumElems,'U');
      BuiltinSymbolTable::addEnumChar(*enumElems,'V');
      BuiltinSymbolTable::addEnumChar(*enumElems,'W');
      BuiltinSymbolTable::addEnumChar(*enumElems,'X');
      BuiltinSymbolTable::addEnumChar(*enumElems,'Y');
      BuiltinSymbolTable::addEnumChar(*enumElems,'Z'); // 90
      BuiltinSymbolTable::addEnumChar(*enumElems,'[');
      BuiltinSymbolTable::addEnumChar(*enumElems,'\\');
      BuiltinSymbolTable::addEnumChar(*enumElems,']');
      BuiltinSymbolTable::addEnumChar(*enumElems,'^');
      BuiltinSymbolTable::addEnumChar(*enumElems,'_');
      BuiltinSymbolTable::addEnumChar(*enumElems,'`');
      BuiltinSymbolTable::addEnumChar(*enumElems,'a');
      BuiltinSymbolTable::addEnumChar(*enumElems,'b');
      BuiltinSymbolTable::addEnumChar(*enumElems,'c');
      BuiltinSymbolTable::addEnumChar(*enumElems,'d'); // 100
      BuiltinSymbolTable::addEnumChar(*enumElems,'e');
      BuiltinSymbolTable::addEnumChar(*enumElems,'f');
      BuiltinSymbolTable::addEnumChar(*enumElems,'g');
      BuiltinSymbolTable::addEnumChar(*enumElems,'h');
      BuiltinSymbolTable::addEnumChar(*enumElems,'i');
      BuiltinSymbolTable::addEnumChar(*enumElems,'j');
      BuiltinSymbolTable::addEnumChar(*enumElems,'k');
      BuiltinSymbolTable::addEnumChar(*enumElems,'l');
      BuiltinSymbolTable::addEnumChar(*enumElems,'m');
      BuiltinSymbolTable::addEnumChar(*enumElems,'n'); // 110
      BuiltinSymbolTable::addEnumChar(*enumElems,'o');
      BuiltinSymbolTable::addEnumChar(*enumElems,'p');
      BuiltinSymbolTable::addEnumChar(*enumElems,'q');
      BuiltinSymbolTable::addEnumChar(*enumElems,'r');
      BuiltinSymbolTable::addEnumChar(*enumElems,'s');
      BuiltinSymbolTable::addEnumChar(*enumElems,'t');
      BuiltinSymbolTable::addEnumChar(*enumElems,'u');
      BuiltinSymbolTable::addEnumChar(*enumElems,'v');
      BuiltinSymbolTable::addEnumChar(*enumElems,'w');
      BuiltinSymbolTable::addEnumChar(*enumElems,'x'); // 120
      BuiltinSymbolTable::addEnumChar(*enumElems,'y');
      BuiltinSymbolTable::addEnumChar(*enumElems,'z');
      BuiltinSymbolTable::addEnumChar(*enumElems,'{');
      BuiltinSymbolTable::addEnumChar(*enumElems,'|');
      BuiltinSymbolTable::addEnumChar(*enumElems,'}');
      BuiltinSymbolTable::addEnumChar(*enumElems,'~');
      BuiltinSymbolTable::addEnumStr(*enumElems,"DEL");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C128");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C129");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C130"); // 130
      BuiltinSymbolTable::addEnumStr(*enumElems,"C131");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C132");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C133");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C134");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C135");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C136");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C137");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C138");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C139");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C140"); // 140
      BuiltinSymbolTable::addEnumStr(*enumElems,"C141");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C142");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C143");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C144");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C145");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C146");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C147");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C148");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C149");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C150"); // 150 
      BuiltinSymbolTable::addEnumStr(*enumElems,"C151");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C152");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C153");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C154");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C155");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C156");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C157");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C158");
      BuiltinSymbolTable::addEnumStr(*enumElems,"C159");
      // TODO non ascii characters. not supported atm., since scanner
      // doesn't support these as well.
      ENUM_END
      TypeDeclaration *character = et;

      // severity_level
      ENUM_BEGIN("severity_level")
      BuiltinSymbolTable::addEnumStr(*enumElems,"note");
      BuiltinSymbolTable::addEnumStr(*enumElems,"warning");
      BuiltinSymbolTable::addEnumStr(*enumElems,"error");
      BuiltinSymbolTable::addEnumStr(*enumElems,"failure");
      ENUM_END

      // tricky: instead of LRM, integer *must* get defined before 
      //         universal_integer, since the exponentation of a
      //         range constraint type has integer as a result type!
      RANGE_CONSTRAINT_INT("integer", INT64_MIN, INT64_MAX)
      RANGE_CONSTRAINT_SUBTYPE_INT("natural", 0, INT64_MAX)
      RANGE_CONSTRAINT_SUBTYPE_INT("positive", 1, INT64_MAX)
      TypeDeclaration *positive = subtypeIndic;
      RANGE_CONSTRAINT_INT("__universal_integer__", INT64_MIN, INT64_MAX)
      TypeDeclaration *universal_integer = r;
      universal_integer->isUniversal = true;

      RANGE_CONSTRAINT_REAL("__universal_real__", DBL_MIN, DBL_MAX)
      TypeDeclaration *universal_real = r;
      universal_real->isUniversal = true;
      // additional operations for universal types.
      RANGE_CONSTRAINT_BINOP("*", universal_real, universal_integer, 
                        universal_real);
      RANGE_CONSTRAINT_BINOP("*", universal_integer, universal_real, 
                        universal_real);
      RANGE_CONSTRAINT_BINOP("/", universal_real, universal_integer, 
                        universal_real);

      RANGE_CONSTRAINT_REAL("real", DBL_MIN, DBL_MAX)

      this->addStdStandardTime(standardSyms);

      // FIXME delay_length, now
      // ...

      // string
      std::list<TypeDeclaration *> *indices = 
            new std::list<TypeDeclaration*>();
      indices->push_back(positive);
      UnconstrainedArrayType *stringT = 
            new UnconstrainedArrayType(new std::string("string"), indices,
                              character, Location("std.standard"));
      this->registerSymbol(SYMBOL_TYPE, *stringT);
      standardSyms.push_back(stringT);

      // "foreign" attribute
      this->addForeignAttribute(stringT, standardSyms);
}

#undef UNOP
#undef BINOP_ENUM
#undef ENUM_BEGIN
#undef ENUM_END
#undef RANGE_CONSTRAINT_INT
#undef RANGE_CONSTRAINT_REAL
#undef RANGE_CONSTRAINT_BINOP
#undef DEFINELOCALS

/* FIXME make this a runtime parameter! */
#if 0       /* correct VHDL */
void
BuiltinSymbolTable::addStdStandardTime(
      std::list<SymbolDeclaration*> &standardSyms
)
{
      ConstInteger *i1;
      ConstInteger *i2;
      DiscreteRange *dr;

      std::list<PhysicalTypeUnit*> *units = 
                  new std::list<PhysicalTypeUnit*>();

#if 0 /* minimum simulation resolution. */
      this->addPhysUnit(standardSyms, *units, "ps", 1, NULL);
      this->addPhysUnit(standardSyms, *units, "ns", 1000, "ps");
#else
      this->addPhysUnit(standardSyms, *units, "ns", 1, NULL);
#endif
      this->addPhysUnit(standardSyms, *units, "us", 1000, "ns");
      this->addPhysUnit(standardSyms, *units, "ms", 1000, "us");
      this->addPhysUnit(standardSyms, *units, "sec", 1000, "ms");
      this->addPhysUnit(standardSyms, *units, "min", 60, "sec");
      this->addPhysUnit(standardSyms, *units, "hr", 60, "min");
      
      i1 = new ConstInteger(INT64_MIN, Location("lower bound"));
      i2 = new ConstInteger(INT64_MAX, Location("upper bound"));
      dr = new DiscreteRange(i1, i2, DiscreteRange::DIRECTION_UP,
                        Location("constraint"));
      PhysicalType *timeT = new PhysicalType(
                              new std::string("time"), dr,
                              units,
                              Location("std.standard"));
      this->registerSymbol(SYMBOL_TYPE, *timeT);
      standardSyms.push_back(timeT);
}
#else /* above: correct VHDL, below: FAUmachine base time */
void
00595 BuiltinSymbolTable::addStdStandardTime(
      std::list<SymbolDeclaration*> &standardSyms
)
{
      ConstInteger *i1;
      ConstInteger *i2;
      DiscreteRange *dr;

      std::list<PhysicalTypeUnit*> *units = 
                  new std::list<PhysicalTypeUnit*>();

      /* minimum simulation unit for FAUmachine is
       * 1/2^32 sec
       */
      this->addPhysUnit(standardSyms, *units, "__time_hz__", 1, NULL);
      // ns would be too unsharp (4 vs. ~4.3)
      this->addPhysUnit(standardSyms, *units, "us", (1ull << 32) / 1000000,
                  "__time_hz__");
      this->addPhysUnit(standardSyms, *units, "ms", (1ull << 32) / 1000, 
                  "__time_hz__");
      this->addPhysUnit(standardSyms, *units, "sec", 1ull << 32, 
                  "__time_hz__");
      this->addPhysUnit(standardSyms, *units, "min", 60, "sec");
      this->addPhysUnit(standardSyms, *units, "hr", 60, "min");
      
      i1 = new ConstInteger(INT64_MIN, Location("lower bound"));
      i2 = new ConstInteger(INT64_MAX, Location("upper bound"));
      dr = new DiscreteRange(i1, i2, DiscreteRange::DIRECTION_UP,
                        Location("constraint"));
      PhysicalType *timeT = new PhysicalType(
                              new std::string("time"), dr,
                              units,
                              Location("std.standard"));
      this->registerSymbol(SYMBOL_TYPE, *timeT);
      standardSyms.push_back(timeT);
}
#endif /* correct VHDL / FAUmachine base unit switch */

void
00634 BuiltinSymbolTable::addPhysUnit(
      std::list<SymbolDeclaration*> &standardSyms,
      std::list<PhysicalTypeUnit*> &units,
      const char *name,
      universal_integer factor,
      const char *refName
)
{
      ConstInteger *unit;

      if (refName == NULL) {
            unit = new ConstInteger(factor, Location("std.standard"));
      } else {
            std::string *s = new std::string(refName);
            SimpleName *sn = new SimpleName(s, this->lookup(*s), 
                                    Location("std.stdandard"));
            unit = new ConstInteger(factor, sn, Location("std.standard"));
      }

      PhysicalTypeUnit *pu = 
            new PhysicalTypeUnit(
                  new std::string(name),
                  unit,
                  Location("std.standard"));

      this->registerSymbol(SYMBOL_UNIT, *pu);
      units.push_back(pu);
      standardSyms.push_back(pu);
}

void
00665 BuiltinSymbolTable::addEnumChar(std::list<EnumerationElement*> &elems, char c)
{
      std::string *s = new std::string("'");
      s->append(1, c);
      s->append("'");
      EnumerationElement *elem = 
            new EnumerationElement(s, Location("std.standard"));
      elems.push_back(elem);
}

void
00676 BuiltinSymbolTable::addEnumStr(
      std::list<EnumerationElement*> &elems, 
      const char *s
)
{
      std::string *st = new std::string(s);
      EnumerationElement *elem = 
            new EnumerationElement(st, Location("std.standard"));
      elems.push_back(elem);
}

void
00688 BuiltinSymbolTable::addForeignAttribute(
      const TypeDeclaration *stringT,
      std::list<SymbolDeclaration *> &standardSyms
)
{
      AttributeDeclaration *a = 
            new AttributeDeclaration(new std::string("foreign"),
                              stringT,
                              Location("std.standard"));
      this->registerSymbol(SYMBOL_ATTRIBUTE, *a);
      standardSyms.push_back(a);
}

}; /* namespace ast */

Generated by  Doxygen 1.6.0   Back to index