Beispiel #1
0
        inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
        {
          switch (get_common_type(t_lhs)) {
            case Common_Types::t_int32:
              return oper_rhs<int32_t>(t_oper, t_lhs, t_rhs);
            case Common_Types::t_uint8:
              return oper_rhs<uint8_t>(t_oper, t_lhs, t_rhs);
            case Common_Types::t_int8:
              return oper_rhs<int8_t>(t_oper, t_lhs, t_rhs);
            case Common_Types::t_uint16:
              return oper_rhs<uint16_t>(t_oper, t_lhs, t_rhs);
            case Common_Types::t_int16:
              return oper_rhs<int16_t>(t_oper, t_lhs, t_rhs);
            case Common_Types::t_uint32:
              return oper_rhs<uint32_t>(t_oper, t_lhs, t_rhs);
            case Common_Types::t_uint64:
              return oper_rhs<uint64_t>(t_oper, t_lhs, t_rhs);
            case Common_Types::t_int64:
              return oper_rhs<int64_t>(t_oper, t_lhs, t_rhs);
            case Common_Types::t_double:
              return oper_rhs<double>(t_oper, t_lhs, t_rhs);
            case Common_Types::t_float:
              return oper_rhs<float>(t_oper, t_lhs, t_rhs);
            case Common_Types::t_long_double:
              return oper_rhs<long double>(t_oper, t_lhs, t_rhs);
          }

          throw chaiscript::detail::exception::bad_any_cast();
        }
Beispiel #2
0
static int parse_complete(token_t *tok)
{
    unsigned int t0;
    _cffi_opcode_t t1;
    int modifiers_length, modifiers_sign;

 qualifiers:
    switch (tok->kind) {
    case TOK_CONST:
        /* ignored for now */
        next_token(tok);
        goto qualifiers;
    case TOK_VOLATILE:
        /* ignored for now */
        next_token(tok);
        goto qualifiers;
    default:
        ;
    }

    modifiers_length = 0;
    modifiers_sign = 0;
 modifiers:
    switch (tok->kind) {

    case TOK_SHORT:
        if (modifiers_length != 0)
            return parse_error(tok, "'short' after another 'short' or 'long'");
        modifiers_length--;
        next_token(tok);
        goto modifiers;

    case TOK_LONG:
        if (modifiers_length < 0)
            return parse_error(tok, "'long' after 'short'");
        if (modifiers_length >= 2)
            return parse_error(tok, "'long long long' is too long");
        modifiers_length++;
        next_token(tok);
        goto modifiers;

    case TOK_SIGNED:
        if (modifiers_sign)
            return parse_error(tok, "multiple 'signed' or 'unsigned'");
        modifiers_sign++;
        next_token(tok);
        goto modifiers;

    case TOK_UNSIGNED:
        if (modifiers_sign)
            return parse_error(tok, "multiple 'signed' or 'unsigned'");
        modifiers_sign--;
        next_token(tok);
        goto modifiers;

    default:
        break;
    }

    if (modifiers_length || modifiers_sign) {

        switch (tok->kind) {

        case TOK_VOID:
        case TOK__BOOL:
        case TOK_FLOAT:
        case TOK_STRUCT:
        case TOK_UNION:
        case TOK_ENUM:
            return parse_error(tok, "invalid combination of types");

        case TOK_DOUBLE:
            if (modifiers_sign != 0 || modifiers_length != 1)
                return parse_error(tok, "invalid combination of types");
            next_token(tok);
            t0 = _CFFI_PRIM_LONGDOUBLE;
            break;

        case TOK_CHAR:
            if (modifiers_length != 0)
                return parse_error(tok, "invalid combination of types");
            modifiers_length = -2;
            /* fall-through */
        case TOK_INT:
            next_token(tok);
            /* fall-through */
        default:
            if (modifiers_sign >= 0)
                switch (modifiers_length) {
                case -2: t0 = _CFFI_PRIM_SCHAR; break;
                case -1: t0 = _CFFI_PRIM_SHORT; break;
                case 1:  t0 = _CFFI_PRIM_LONG; break;
                case 2:  t0 = _CFFI_PRIM_LONGLONG; break;
                default: t0 = _CFFI_PRIM_INT; break;
                }
            else
                switch (modifiers_length) {
                case -2: t0 = _CFFI_PRIM_UCHAR; break;
                case -1: t0 = _CFFI_PRIM_USHORT; break;
                case 1:  t0 = _CFFI_PRIM_ULONG; break;
                case 2:  t0 = _CFFI_PRIM_ULONGLONG; break;
                default: t0 = _CFFI_PRIM_UINT; break;
                }
        }
        t1 = _CFFI_OP(_CFFI_OP_PRIMITIVE, t0);
    }
    else {
        switch (tok->kind) {
        case TOK_INT:
            t1 = _CFFI_OP(_CFFI_OP_PRIMITIVE, _CFFI_PRIM_INT);
            break;
        case TOK_CHAR:
            t1 = _CFFI_OP(_CFFI_OP_PRIMITIVE, _CFFI_PRIM_CHAR);
            break;
        case TOK_VOID:
            t1 = _CFFI_OP(_CFFI_OP_PRIMITIVE, _CFFI_PRIM_VOID);
            break;
        case TOK__BOOL:
            t1 = _CFFI_OP(_CFFI_OP_PRIMITIVE, _CFFI_PRIM_BOOL);
            break;
        case TOK_FLOAT:
            t1 = _CFFI_OP(_CFFI_OP_PRIMITIVE, _CFFI_PRIM_FLOAT);
            break;
        case TOK_DOUBLE:
            t1 = _CFFI_OP(_CFFI_OP_PRIMITIVE, _CFFI_PRIM_DOUBLE);
            break;
        case TOK_IDENTIFIER:
        {
            const char *replacement;
            int n = search_in_typenames(tok->info->ctx, tok->p, tok->size);
            if (n >= 0) {
                t1 = _CFFI_OP(_CFFI_OP_TYPENAME, n);
                break;
            }
            n = search_standard_typename(tok->p, tok->size);
            if (n >= 0) {
                t1 = _CFFI_OP(_CFFI_OP_PRIMITIVE, n);
                break;
            }
            replacement = get_common_type(tok->p, tok->size);
            if (replacement != NULL) {
                n = parse_common_type_replacement(tok, replacement);
                if (n < 0)
                    return parse_error(tok, "internal error, please report!");
                t1 = _CFFI_OP(_CFFI_OP_NOOP, n);
                break;
            }
            return parse_error(tok, "undefined type name");
        }
        case TOK_STRUCT:
        case TOK_UNION:
        {
            int n, kind = tok->kind;
            next_token(tok);
            if (tok->kind != TOK_IDENTIFIER)
                return parse_error(tok, "struct or union name expected");

            n = search_in_struct_unions(tok->info->ctx, tok->p, tok->size);
            if (n < 0) {
                if (kind == TOK_STRUCT && tok->size == 8 &&
                        !memcmp(tok->p, "_IO_FILE", 8))
                    n = _CFFI__IO_FILE_STRUCT;
                else
                    return parse_error(tok, "undefined struct/union name");
            }
            else if (((tok->info->ctx->struct_unions[n].flags & _CFFI_F_UNION)
                      != 0) ^ (kind == TOK_UNION))
                return parse_error(tok, "wrong kind of tag: struct vs union");

            t1 = _CFFI_OP(_CFFI_OP_STRUCT_UNION, n);
            break;
        }
        case TOK_ENUM:
        {
            int n;
            next_token(tok);
            if (tok->kind != TOK_IDENTIFIER)
                return parse_error(tok, "enum name expected");

            n = search_in_enums(tok->info->ctx, tok->p, tok->size);
            if (n < 0)
                return parse_error(tok, "undefined enum name");

            t1 = _CFFI_OP(_CFFI_OP_ENUM, n);
            break;
        }
        default:
            return parse_error(tok, "identifier expected");
        }
        next_token(tok);
    }

    return parse_sequel(tok, write_ds(tok, t1));
}
Beispiel #3
0
      static Common_Types get_common_type(const Boxed_Value &t_bv)
      {
        const Type_Info &inp_ = t_bv.get_type_info();

        if (inp_ == typeid(int)) {
          return get_common_type(sizeof(int), true);
        } else if (inp_ == typeid(double)) {
          return Common_Types::t_double;
        } else if (inp_ == typeid(long double)) {
          return Common_Types::t_long_double;
        } else if (inp_ == typeid(float)) {
          return Common_Types::t_float;
        } else if (inp_ == typeid(char)) {
          return get_common_type(sizeof(char), std::is_signed<char>::value);
        } else if (inp_ == typeid(unsigned char)) {
          return get_common_type(sizeof(unsigned char), false);
        } else if (inp_ == typeid(unsigned int)) {
          return get_common_type(sizeof(unsigned int), false);
        } else if (inp_ == typeid(long)) {
          return get_common_type(sizeof(long), true);
        } else if (inp_ == typeid(long long)) {
          return get_common_type(sizeof(long long), true);
        } else if (inp_ == typeid(unsigned long)) {
          return get_common_type(sizeof(unsigned long), false);
        } else if (inp_ == typeid(unsigned long long)) {
          return get_common_type(sizeof(unsigned long long), false);
        } else if (inp_ == typeid(std::int8_t)) {
          return Common_Types::t_int8;
        } else if (inp_ == typeid(std::int16_t)) {
          return Common_Types::t_int16;
        } else if (inp_ == typeid(std::int32_t)) {
          return Common_Types::t_int32;
        } else if (inp_ == typeid(std::int64_t)) {
          return Common_Types::t_int64;
        } else if (inp_ == typeid(std::uint8_t)) {
          return Common_Types::t_uint8;
        } else if (inp_ == typeid(std::uint16_t)) {
          return Common_Types::t_uint16;
        } else if (inp_ == typeid(std::uint32_t)) {
          return Common_Types::t_uint32;
        } else if (inp_ == typeid(std::uint64_t)) {
          return Common_Types::t_uint64;
        } else if (inp_ == typeid(wchar_t)) {
          return get_common_type(sizeof(wchar_t), std::is_signed<wchar_t>::value);
        } else if (inp_ == typeid(char16_t)) {
          return get_common_type(sizeof(char16_t), std::is_signed<char16_t>::value);
        } else if (inp_ == typeid(char32_t)) {
          return get_common_type(sizeof(char32_t), std::is_signed<char32_t>::value);
        } else  {
          throw chaiscript::detail::exception::bad_any_cast();
        }
      }
Beispiel #4
0
/*-------------------------------------------------------------------------*/
static lpctype_t *
internal_get_common_type(lpctype_t *t1, lpctype_t* t2, bool find_one)

/* Determine the intersection of both types.
 * Returns NULL if there is no common type.
 * If one of both types is TYPE_UNKNOWN, then
 * the result will by TYPE_UNKNOWN, too.
 *
 * If <find_one> is true, then it may finish even if only a part
 * of the result type was found (used for has_common_type()).
 */

{
    /* Hopefully the most common case. */
    if (t1 && t1 == t2)
        return ref_lpctype(t1);

    /* We can't return NULL, as this is an error condition. */
    if (t1 == NULL && t2 == NULL)
        return lpctype_mixed;
    else if (t1 == NULL)
        return ref_lpctype(t2);
    else if (t2 == NULL)
        return ref_lpctype(t1);

    if (t2->t_class == TCLASS_UNION && t1->t_class != TCLASS_UNION)
    {
        /* Switch them, so t2 is not a union unless t1 is one, too. */
        lpctype_t *temp; temp = t1; t1 = t2; t2 = temp;
    }
    /* Some shortcuts, before we're diving into t1.*/
    if (t2->t_class == TCLASS_PRIMARY)
    {
        switch (t2->t_primary)
        {
        case TYPE_UNKNOWN:
            return ref_lpctype(t2);
        case TYPE_ANY:
            return ref_lpctype(t1);
        default:
            break;
        }
    }

    switch (t1->t_class)
    {
    case TCLASS_PRIMARY:
        switch (t1->t_primary)
        {
        case TYPE_UNKNOWN:
            return ref_lpctype(t1);
        case TYPE_ANY:
            return ref_lpctype(t2);
        default:
            /* Primary types besides the above exceptions should
               be identical (checked at the beginning of this function). */
            return NULL;
        }

    case TCLASS_STRUCT:
        if (t2->t_class != TCLASS_STRUCT)
            return NULL;
        else if (t1->t_struct == NULL)
            return ref_lpctype(t2);
        else if (t2->t_struct == NULL)
            return ref_lpctype(t1);
        /* This is somewhat counterintuitive, but the derived struct
           is more specialized, so it is the result of the intersection. */
        else if (struct_baseof(t1->t_struct, t2->t_struct))
            return ref_lpctype(t2);
        else if (struct_baseof(t2->t_struct, t1->t_struct))
            return ref_lpctype(t1);
        else
            return NULL;

    case TCLASS_ARRAY:
        if (t2->t_class != TCLASS_ARRAY)
            return NULL;
        else
        {
            lpctype_t *common_element = get_common_type(t1->t_array.element, t2->t_array.element);
            lpctype_t *result = get_array_type(common_element);
            free_lpctype(common_element);
            return result;
        }

    case TCLASS_UNION:
        {
            lpctype_t *result = NULL;
            while (true)
            {
                lpctype_t *base = t1->t_class == TCLASS_UNION ? t1->t_union.member : t1;
                lpctype_t *common_base = get_common_type(t2, base);
                lpctype_t *oldresult = result;

                if (find_one && common_base)
                    return common_base;

                result = get_union_type(result, common_base);
                free_lpctype(common_base);
                free_lpctype(oldresult);

                if (t1->t_class == TCLASS_UNION)
                    t1 = t1->t_union.head;
                else
                    break;
            }

            return result;
        }

    default:
        fatal("Unknown type class %d!\n", t1->t_class);
        return NULL;
    }
} /* internal_get_common_type() */