예제 #1
0
파일: backend_c.c 프로젝트: wm4/boringlang
static void write_const(CTX *ctx, struct ir_const_val v)
{
    char *s = const_unparse(NULL, v);
    if (TEST_UNION(IR_TYPE, tarray, &v.type)) {
        fprintf(ctx->f, "{%s}", s);
    } else if (type_is_integer(v.type)) {
        // Get rid of annoying-but-correct gcc warning. This happens because we
        // negate a value not representable in intmax_t, even though the result
        // is representable, i.e. the only case is INT64_MIN.
        if (type_equals(v.type, type_integer(true, 64))
            && *GET_UNION(VALUE, vuint64, &v.value) == INT64_MIN)
        {
            fprintf(ctx->f, "INT64_MIN");
        } else {
            fprintf(ctx->f, "%s(%s)", int_const(v.type), s);
        }
    } else if (TEST_UNION(IR_TYPE, tslice, &v.type)) {
        if (TEST_UNION0(VALUE, vempty, &v.value)) {
            fprintf(ctx->f, "{0}");
        } else if (type_equals(v.type, TYPE_STRING)) {
            char *raw = *GET_UNION(VALUE, vstring, &v.value);
            fprintf(ctx->f, "{ %s, %zd }", s, raw ? strlen(raw) : 0);
        } else {
            assert(false);
        }
    } else {
        fprintf(ctx->f, "%s", s);
    }
    talloc_free(s);
}
예제 #2
0
파일: type.c 프로젝트: manasdas17/nvc
bool type_is_integer(type_t t)
{
   assert(t != NULL);
   if (t->kind == T_SUBTYPE)
      return type_is_integer(type_base(t));
   else
      return (t->kind == T_INTEGER);
}
예제 #3
0
void UnionTree::parse(Parser *parser) {
	if (parser->cur()->type() != '<') {
		log_expect(parser->cur()->loc(), "'<'");
	}
	parser->eat();

	ptr<Token> token = parser->cur();
	if (!token->is_iden()) {
		log_expect(token->loc(), "identifier");
	}
	parser->eat();

	ptr<Tree> tree = _struct->getItem(token->text(), false);
	if (!tree) {
		log_error(token->loc(), "unknown key field '%s'", token->text());
	}
	if (tree->type() != TREE_STRUCT_ITEM) {
		log_error(token->loc(), "key field must is integer type", token->text());
	}
	if (!type_is_integer(tree.cast<StructItemTree>()->type()->type())) {
		log_error(token->loc(), "key field must is integer type", token->text());
	}
	_key = tree.cast<StructItemTree>();

	if (parser->cur()->type() != '>') {
		log_expect(parser->cur()->loc(), "'>'");
	}
	parser->eat();

	if (parser->cur()->type() != '{') {
		log_expect(parser->cur()->loc(), "'{'");
	}
	parser->eat();

	while (1) {
		switch (parser->cur()->type()) {
		case '}':
			do {
				parser->eat();
				ptr<Token> token = parser->cur();

				if (token->is_iden()) {
					parser->eat();
					_name = token;
					token = parser->cur();
				}

				if (token->type() == ';') {
					parser->eat();
					return;
				}
				else {
					log_expect(token->loc(), "identifier or ';'");
				}
				return;
			} while (0);
		default:
			do {
				object<UnionItemTree> item;
				item->parse(parser);
				for (auto sym : _symbols) {
					if (item->index()->value()->vint() == sym->index()->value()->vint()) {
						log_error(item->index()->loc, "dup union item index");
					}
					if (item->decl()->name()->text() == sym->decl()->name()->text()) {
						log_error(item->decl()->name()->loc(), "dup union item name");
					}
				}
				_symbols.push_back(item);
			} while (0);
		}
	}
}