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; }
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(); }
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); }