Esempio n. 1
0
type_t type_universal_real(void)
{
   static type_t t = NULL;

   if (t == NULL) {
      tree_t min = tree_new(T_LITERAL);
      tree_set_subkind(min, L_REAL);
      tree_set_dval(min, -DBL_MAX);

      tree_t max = tree_new(T_LITERAL);
      tree_set_subkind(max, L_REAL);
      tree_set_dval(max, DBL_MAX);

      t = type_make_universal(T_REAL, "universal real", min, max);
   }

   return t;
}
Esempio n. 2
0
type_t type_universal_int(void)
{
   static type_t t = NULL;

   if (t == NULL) {
      tree_t min = tree_new(T_LITERAL);
      tree_set_subkind(min, L_INT);
      tree_set_ival(min, -INT_MAX);

      tree_t max = tree_new(T_LITERAL);
      tree_set_subkind(max, L_INT);
      tree_set_ival(max, INT_MAX);

      t = type_make_universal(T_INTEGER, "universal integer", min, max);
   }

   return t;
}
Esempio n. 3
0
tree_t get_real_lit(tree_t t, double r)
{
   tree_t f = tree_new(T_LITERAL);
   tree_set_loc(f, tree_loc(t));
   tree_set_subkind(f, L_REAL);
   tree_set_dval(f, r);
   tree_set_type(f, tree_type(t));

   return f;
}
Esempio n. 4
0
tree_t get_int_lit(tree_t t, int64_t i)
{
   tree_t f = tree_new(T_LITERAL);
   tree_set_subkind(f, L_INT);
   tree_set_ival(f, i);
   tree_set_loc(f, tree_loc(t));
   tree_set_type(f, tree_type(t));

   return f;
}
Esempio n. 5
0
static tree_t str_to_agg(const char *p, const char *end)
{
   tree_t t = tree_new(T_AGGREGATE);

   unsigned len = 0;
   while (*p != '\0' && p != end) {
      const char ch[] = { '\'', *p++, '\'', '\0' };

      tree_t ref = tree_new(T_REF);
      tree_set_ident(ref, ident_new(ch));

      tree_t a = tree_new(T_ASSOC);
      tree_set_subkind(a, A_POS);
      tree_set_value(a, ref);

      tree_add_assoc(t, a);

      ++len;
   }

   tree_t left = tree_new(T_LITERAL);
   tree_set_subkind(left, L_INT);
   tree_set_ival(left, 0);

   tree_t right = tree_new(T_LITERAL);
   tree_set_subkind(right, L_INT);
   tree_set_ival(right, len - 1);

   type_t type = type_new(T_CARRAY);
   type_set_ident(type, ident_new("string"));
   type_set_elem(type, type_universal_int());
   range_t r = { .kind = RANGE_DOWNTO, .left = left, .right = right };
   type_add_dim(type, r);

   tree_set_type(t, type);

   return t;
}
Esempio n. 6
0
tree_t add_param(tree_t call, tree_t value, param_kind_t kind, tree_t name)
{
   tree_t p = tree_new(T_PARAM);
   tree_set_loc(p, tree_loc(value));
   tree_set_subkind(p, kind);
   tree_set_value(p, value);

   if (kind == P_NAMED) {
      assert(name != NULL);
      tree_set_name(p, name);
   }

   tree_add_param(call, p);
   return p;
}
Esempio n. 7
0
tree_t str_to_literal(const char *start, const char *end, type_t type)
{
   tree_t t = tree_new(T_LITERAL);
   tree_set_subkind(t, L_STRING);

   type_t elem = NULL;
   if (type != NULL) {
      tree_set_type(t, type);
      elem = type_elem(type);
   }

   char last = '\0';
   for (const char *p = start; *p != '\0' && p != end; p++) {
      if (*p == -127)
         continue;
      else if (*p == '"' && last == '"') {
         last = '\0';
         continue;
      }
      else
         last = *p;

      const char ch[] = { '\'', *p, '\'', '\0' };
      ident_t id = ident_new(ch);
      tree_t ref = tree_new(T_REF);
      tree_set_ident(ref, id);
      tree_add_char(t, ref);

      if (elem != NULL) {
         const int nlit = type_enum_literals(elem);
         for (int i = 0; i < nlit; i++) {
            tree_t lit = type_enum_literal(elem, i);
            if (tree_ident(lit) == id) {
               tree_set_ref(ref, lit);
               break;
            }
         }
      }
   }

   return t;
}
Esempio n. 8
0
END_TEST

START_TEST(test_lib_save)
{
   {
      tree_t ent = tree_new(T_ENTITY);
      tree_set_ident(ent, ident_new("name"));

      tree_add_attr_str(ent, ident_new("attr"), ident_new("test string"));

      type_t e = type_new(T_ENUM);
      type_set_ident(e, ident_new("myenum"));
      tree_t a = tree_new(T_ENUM_LIT);
      tree_set_ident(a, ident_new("a"));
      tree_set_type(a, e);
      tree_set_pos(a, 55);
      type_enum_add_literal(e, a);
      tree_t b = tree_new(T_ENUM_LIT);
      tree_set_ident(b, ident_new("b"));
      tree_set_type(b, e);
      type_enum_add_literal(e, b);

      tree_t p1 = tree_new(T_PORT_DECL);
      tree_set_ident(p1, ident_new("foo"));
      tree_set_subkind(p1, PORT_OUT);
      tree_set_type(p1, type_universal_int());
      tree_add_port(ent, p1);

      tree_t p2 = tree_new(T_PORT_DECL);
      tree_set_ident(p2, ident_new("bar"));
      tree_set_subkind(p2, PORT_IN);
      tree_set_type(p2, e);
      tree_add_port(ent, p2);

      tree_t ar = tree_new(T_ARCH);
      tree_set_ident(ar, ident_new("arch"));
      tree_set_ident2(ar, ident_new("foo"));

      tree_t pr = tree_new(T_PROCESS);
      tree_set_ident(pr, ident_new("proc"));
      tree_add_stmt(ar, pr);

      tree_t v1 = tree_new(T_VAR_DECL);
      tree_set_ident(v1, ident_new("v1"));
      tree_set_type(v1, e);

      tree_t r = tree_new(T_REF);
      tree_set_ident(r, ident_new("v1"));
      tree_set_ref(r, v1);

      tree_t s = tree_new(T_VAR_ASSIGN);
      tree_set_ident(s, ident_new("var_assign"));
      tree_set_target(s, r);
      tree_set_value(s, r);
      tree_add_stmt(pr, s);

      tree_t c = tree_new(T_LITERAL);
      tree_set_subkind(c, L_INT);
      tree_set_ival(c, 53);

      tree_t s2 = tree_new(T_VAR_ASSIGN);
      tree_set_ident(s2, ident_new("var_assign"));
      tree_set_target(s2, r);
      tree_set_value(s2, c);
      tree_add_stmt(pr, s2);

      tree_t s3 = tree_new(T_VAR_ASSIGN);
      tree_set_ident(s3, ident_new("var_assign"));
      tree_set_target(s3, r);
      tree_set_value(s3, str_to_agg("foobar", NULL));
      tree_add_stmt(pr, s3);

      tree_t s4 = tree_new(T_ASSERT);
      tree_set_ident(s4, ident_new("assert"));
      tree_set_value(s4, c);
      tree_set_severity(s4, c);
      tree_set_message(s4, str_to_agg("message", NULL));
      tree_add_stmt(pr, s4);

      lib_put(work, ar);
      lib_put(work, ent);
   }

   tree_gc();

   lib_save(work);
   lib_free(work);

   lib_add_search_path("/tmp");
   work = lib_find(ident_new("test_lib"), false);
   fail_if(work == NULL);

   {
      tree_t ent = lib_get(work, ident_new("name"));
      fail_if(ent == NULL);
      fail_unless(tree_kind(ent) == T_ENTITY);
      fail_unless(tree_ident(ent) == ident_new("name"));
      fail_unless(tree_ports(ent) == 2);

      ident_t attr = tree_attr_str(ent, ident_new("attr"));
      fail_if(attr == NULL);
      fail_unless(icmp(attr, "test string"));

      tree_t p1 = tree_port(ent, 0);
      fail_unless(tree_kind(p1) == T_PORT_DECL);
      fail_unless(tree_subkind(p1) == PORT_OUT);
      fail_unless(type_kind(tree_type(p1)) == T_INTEGER);

      tree_t p2 = tree_port(ent, 1);
      fail_unless(tree_kind(p2) == T_PORT_DECL);
      fail_unless(tree_subkind(p2) == PORT_IN);

      type_t e = tree_type(p2);
      fail_unless(type_kind(e) == T_ENUM);
      fail_unless(type_enum_literals(e) == 2);
      tree_t a = type_enum_literal(e, 0);
      fail_unless(tree_kind(a) == T_ENUM_LIT);
      fail_unless(tree_ident(a) == ident_new("a"));
      fail_unless(tree_type(a) == e);
      fail_unless(tree_pos(a) == 55);
      tree_t b = type_enum_literal(e, 1);
      fail_unless(tree_kind(b) == T_ENUM_LIT);
      fail_unless(tree_ident(b) == ident_new("b"));
      fail_unless(tree_type(b) == e);

      tree_t ar = lib_get(work, ident_new("arch"));
      fail_if(ar == NULL);
      fail_unless(tree_ident(ar) == ident_new("arch"));
      fail_unless(tree_ident2(ar) == ident_new("foo"));

      tree_t pr = tree_stmt(ar, 0);
      fail_unless(tree_kind(pr) == T_PROCESS);
      fail_unless(tree_ident(pr) == ident_new("proc"));

      tree_t s = tree_stmt(pr, 0);
      fail_unless(tree_kind(s) == T_VAR_ASSIGN);

      tree_t r = tree_target(s);
      fail_unless(tree_kind(r) == T_REF);
      fail_unless(tree_value(s) == r);

      tree_t s2 = tree_stmt(pr, 1);
      fail_unless(tree_kind(s2) == T_VAR_ASSIGN);
      fail_unless(tree_target(s2) == r);

      tree_t s3 = tree_stmt(pr, 2);
      fail_unless(tree_kind(s3) == T_VAR_ASSIGN);
      fail_unless(tree_target(s3) == r);
      fail_unless(tree_kind(tree_value(s3)) == T_AGGREGATE);

      tree_t s4 = tree_stmt(pr, 3);
      fail_unless(tree_kind(s4) == T_ASSERT);
      fail_unless(tree_ident(s4) == ident_new("assert"));

      tree_t c = tree_value(s2);
      fail_unless(tree_kind(c) == T_LITERAL);
      fail_unless(tree_subkind(c) == L_INT);
      fail_unless(tree_ival(c) == 53);

      // Type declaration and reference written to different units
      // so two copies of the type declaration will be read back
      // hence can't check for pointer equality here
      fail_unless(type_eq(tree_type(tree_ref(r)), e));
   }
}
Esempio n. 9
0
tree_t call_builtin(const char *builtin, type_t type, ...)
{
   struct decl_cache {
      struct decl_cache *next;
      ident_t bname;
      tree_t  decl;
   };

   char *name = xasprintf("NVC.BUILTIN.%s", builtin);
   for (char *p = name; *p != '\0'; p++)
      *p = toupper((int)*p);

   static struct decl_cache *cache = NULL;

   ident_t bname = ident_new(builtin);
   ident_t name_i = ident_new(name);
   free(name);

   struct decl_cache *it;
   tree_t decl = NULL;
   for (it = cache; it != NULL; it = it->next) {
      if (it->bname == bname) {
         decl = it->decl;
         break;
      }
   }

   if (decl == NULL) {
      decl = tree_new(T_FUNC_DECL);
      tree_set_ident(decl, name_i);
      tree_add_attr_str(decl, builtin_i, ident_new(builtin));
   }

   struct decl_cache *c = xmalloc(sizeof(struct decl_cache));
   c->next  = cache;
   c->bname = bname;
   c->decl  = decl;

   cache = c;

   tree_t call = tree_new(T_FCALL);
   tree_set_ident(call, name_i);
   tree_set_ref(call, decl);
   if (type != NULL)
      tree_set_type(call, type);

   va_list ap;
   va_start(ap, type);
   tree_t arg;
   while ((arg = va_arg(ap, tree_t))) {
      tree_t p = tree_new(T_PARAM);
      tree_set_value(p, arg);
      tree_set_loc(p, tree_loc(arg));
      tree_set_subkind(p, P_POS);

      tree_add_param(call, p);
   }
   va_end(ap);

   return call;
}
Esempio n. 10
0
tree_t make_default_value(type_t type, const loc_t *loc)
{
   type_t base = type_base_recur(type);

   switch (type_kind(base)) {
   case T_UARRAY:
      assert(type_kind(type) == T_SUBTYPE);
      // Fall-through

   case T_CARRAY:
      {
         tree_t def = NULL;
         const int ndims = type_dims(type);
         for (int i = ndims - 1; i >= 0; i--) {
            tree_t val = (def ? def : make_default_value(type_elem(base), loc));
            def = tree_new(T_AGGREGATE);
            tree_set_type(def, array_aggregate_type(type, i));

            tree_t a = tree_new(T_ASSOC);
            tree_set_subkind(a, A_OTHERS);
            tree_set_value(a, val);

            tree_add_assoc(def, a);
         }
         tree_set_type(def, type);
         tree_set_loc(def, loc);
         return def;
      }

   case T_INTEGER:
   case T_PHYSICAL:
   case T_REAL:
      return type_dim(type, 0).left;

   case T_ENUM:
      {
         int64_t val = 0;
         const bool folded = folded_int(type_dim(type, 0).left, &val);
         if (folded)
            return make_ref(type_enum_literal(base, (unsigned) val));
         else
            return type_dim(type, 0).left;
      }

   case T_RECORD:
      {
         tree_t def = tree_new(T_AGGREGATE);
         tree_set_loc(def, loc);
         const int nfields = type_fields(base);
         for (int i = 0; i < nfields; i++) {
            tree_t field = type_field(base, i);

            tree_t a = tree_new(T_ASSOC);
            tree_set_subkind(a, A_POS);
            tree_set_value(a, make_default_value(tree_type(field),
                                                 tree_loc(field)));

            tree_add_assoc(def, a);
         }
         tree_set_type(def, type);
         return def;
      }

   case T_ACCESS:
      {
         tree_t null = tree_new(T_LITERAL);
         tree_set_loc(null, loc);
         tree_set_subkind(null, L_NULL);
         tree_set_type(null, type);
         return null;
      }

   case T_UNRESOLVED:
      return NULL;

   default:
      fatal_trace("cannot handle type %s in %s",
                  type_kind_str(type_kind(base)), __func__);
   }
}
Esempio n. 11
0
tree_t make_default_value(type_t type, const loc_t *loc)
{
   type_t base = type_base_recur(type);

   switch (type_kind(base)) {
   case T_UARRAY:
      assert(type_kind(type) == T_SUBTYPE);
      // Fall-through

   case T_CARRAY:
      {
         tree_t def = NULL;
         const int ndims = type_dims(type);
         for (int i = ndims - 1; i >= 0; i--) {
            tree_t val = (def ? def : make_default_value(type_elem(base), loc));
            def = tree_new(T_AGGREGATE);
            tree_set_type(def, array_aggregate_type(type, i));

            tree_t a = tree_new(T_ASSOC);
            tree_set_subkind(a, A_OTHERS);
            tree_set_value(a, val);

            tree_add_assoc(def, a);
         }
         tree_set_type(def, type);
         tree_set_loc(def, loc);
         return def;
      }

   case T_INTEGER:
   case T_PHYSICAL:
   case T_REAL:
      return type_dim(type, 0).left;

   case T_ENUM:
      return make_ref(type_enum_literal(base, 0));

   case T_RECORD:
      {
         tree_t def = tree_new(T_AGGREGATE);
         tree_set_loc(def, loc);
         const int nfields = type_fields(base);
         for (int i = 0; i < nfields; i++) {
            tree_t field = type_field(base, i);

            tree_t a = tree_new(T_ASSOC);
            tree_set_subkind(a, A_POS);
            tree_set_value(a, make_default_value(tree_type(field),
                                                 tree_loc(field)));

            tree_add_assoc(def, a);
         }
         tree_set_type(def, type);
         return def;
      }

   case T_ACCESS:
      {
         tree_t null = tree_new(T_LITERAL);
         tree_set_loc(null, loc);
         tree_set_subkind(null, L_NULL);
         tree_set_type(null, type);
         return null;
      }

   default:
      assert(false);
   }
}