示例#1
0
TypeSpec
ASTtype_constructor::typecheck (TypeSpec expected)
{
    // FIXME - closures
    typecheck_children ();

    // Hijack the usual function arg-checking routines.
    // So we have a set of valid patterns for each type constructor:
    static const char *float_patterns[] = { "ff", "fi", NULL };
    static const char *triple_patterns[] = { "cf", "cfff", "csfff",
                                             "cc", "cp", "cv", "cn", NULL };
    static const char *matrix_patterns[] = { "mf", "msf", "mss",
                                             "mffffffffffffffff",
                                             "msffffffffffffffff", "mm", NULL };
    static const char *int_patterns[] = { "if", "ii", NULL };
    // Select the pattern for the type of constructor we are...
    const char **patterns = NULL;
    if (typespec().is_float())
        patterns = float_patterns;
    else if (typespec().is_triple())
        patterns = triple_patterns;
    else if (typespec().is_matrix())
        patterns = matrix_patterns;
    else if (typespec().is_int())
        patterns = int_patterns;
    if (! patterns) {
        error ("Cannot construct type '%s'", type_c_str(typespec()));
        return m_typespec;
    }

    // Try to get a match, first without type coercion of the arguments,
    // then with coercion.
    for (int co = 0;  co < 2;  ++co) {
        bool coerce = co;
        for (const char **pat = patterns;  *pat;  ++pat) {
            const char *code = *pat;
            if (check_arglist (type_c_str(typespec()), args(), code + 1, coerce))
                return m_typespec;
        }
    }

    // If we made it this far, no match could be found.
    std::string err = Strutil::format ("Cannot construct %s (", 
                                       type_c_str(typespec()));
    for (ref a = args();  a;  a = a->next()) {
        err += a->typespec().string();
        if (a->next())
            err += ", ";
    }
    err += ")";
    error ("%s", err.c_str());
    // FIXME -- it might be nice here to enumerate for the user all the
    // valid combinations.
    return m_typespec;
}
示例#2
0
TypeSpec
ASTfunction_call::typecheck_all_poly (TypeSpec expected, bool coerce)
{
    for (FunctionSymbol *poly = func();  poly;  poly = poly->nextpoly()) {
        const char *code = poly->argcodes().c_str();
        int advance;
        TypeSpec returntype = m_compiler->type_from_code (code, &advance);
        code += advance;
        if (check_arglist (m_name.c_str(), args(), code, coerce)) {
            // Return types also must match if not coercible
            if (coerce || expected == TypeSpec() || expected == returntype) {
                m_sym = poly;
                return returntype;
            }
        }
    }
    return TypeSpec();
}
示例#3
0
void
read_arglist(void)
{
    int i;
    u_char byte;
    u_short count;
    u_short length;
    char *sp;
    char *ep;
    unsigned int checksum;

    if (read(compat_sock, &byte, sizeof(byte)) != sizeof(byte))
	efatal("read needsecret failed");
    if (byte)
	efatal("request for secret");
    if (debug)
	diag("reading arglist");
    if (read(compat_sock, (char *)&count, sizeof(count)) != sizeof(count))
	efatal("server read");
    count = ntohs(count);
    if (debug)
	diag("arglist count %d", count);
    if ( ( batch && count < 1) || ( !batch && count < 3 ) || count > MAXARGC - 1)
	fatal("Invalid arg count");
    if (read(compat_sock, (char *)&length, sizeof(length)) != sizeof(length))
	efatal("server read");
    length = ntohs(length);
    if (debug)
	diag("arglist length %d", length);
    if ((int)length > NCARGS)
	fatal("Arglist too long");
    if (read(compat_sock, (char *)&tempslot, sizeof(tempslot)) != sizeof(tempslot))
	efatal("server read");
    tempslot = ntohs(tempslot);
    if (debug)
	diag("tempslot %d", tempslot);
    if ( ( batch && tempslot >= count) ||
         (!batch && tempslot >= count - 2 ) )
	fatal("Invalid temp file index");
    if (tempslot != 0) {
	if (read(compat_sock, (char *)&tempmode, sizeof(tempmode)) != sizeof(tempmode))
	    efatal("server read");
	if (debug)
	    diag("tempmode %d", tempmode);
    }
    if (read(compat_sock, (char *)&checksum, sizeof(checksum)) != sizeof(checksum))
	efatal("server read");
    checksum = ntohl(checksum);
    if (debug)
	diag("checksum %x", checksum);
    memset (args, 0, sizeof(args));
    sp = args;
    ep = args + length;
    while (ep > sp) {
	i = ep - sp;
	i = read(compat_sock, sp, i);
	if (i < 0)
	    efatal("server read");
	else if (i == 0)
	    fatal("read (eof)");
	sp += i;
    }
    check_arglist ( count, ep, sp, checksum);
}