/* multiply two phpnums, potentially converting to a double. */ obj_t phpmul(obj_t a, obj_t b) { long lval; double dval; unsigned char tx; if (ELONGP(a) && ELONGP(b)) { int use_dval; long alval = BELONG_TO_LONG(a); long blval = BELONG_TO_LONG(b); FAST_LONG_MULTIPLY(alval, blval, lval, dval, use_dval); if (use_dval) { return DOUBLE_TO_REAL(dval); } else { return LONG_TO_ONUM(lval); } } else if (REALP(a) && REALP(b)) { dval = REAL_TO_DOUBLE(a) * REAL_TO_DOUBLE(b); return DOUBLE_TO_REAL(dval); } else if (REALP (a) && ELONGP(b)) { dval = REAL_TO_DOUBLE(a) * (double) BELONG_TO_LONG(b); return DOUBLE_TO_REAL(dval); } else if (ELONGP(a) && REALP(b)) { dval = (double) BELONG_TO_LONG(a) * REAL_TO_DOUBLE(b); return DOUBLE_TO_REAL(dval); } phpnum_fail("jeepers creepers"); }
/* divide two phpnums, potentially converting to a double. */ obj_t phpdiv(obj_t a, obj_t b) { if ((ELONGP(b) && (BELONG_TO_LONG(b) == 0)) || (REALP(b) && (REAL_TO_DOUBLE(b) == 0.0))) { phpnum_fail("Derision by zero"); } if (ELONGP(a) && ELONGP(b)) { if (BELONG_TO_LONG(a) % BELONG_TO_LONG(b) == 0) { /* integer */ long lval = BELONG_TO_LONG(a) / BELONG_TO_LONG(b); /* if (WITHIN_PDL_RANGE(lval)) { */ /* return GET_PDL(lval); */ /* } else { */ return LONG_TO_ONUM(lval); /* } */ } else { double dval = ((double) BELONG_TO_LONG (a)) / BELONG_TO_LONG(b); return DOUBLE_TO_REAL(dval); } } if ((REALP(a) && ELONGP(b)) || (ELONGP(a) && REALP(b))) { double dval = (ELONGP(a) ? (((double) BELONG_TO_LONG(a)) / REAL_TO_DOUBLE(b)) : (REAL_TO_DOUBLE(a) / ((double) BELONG_TO_LONG(b)))); return DOUBLE_TO_REAL(dval); } if (REALP(a) && REALP(b)) { double dval = REAL_TO_DOUBLE(a) / REAL_TO_DOUBLE(b); return DOUBLE_TO_REAL(dval); } phpnum_fail("no clue"); }
/* subtract two phpnums, potentially converting to a double. */ obj_t phpsub(obj_t a, obj_t b) { if (ELONGP(a) && ELONGP(b)) { long lval = BELONG_TO_LONG(a) - BELONG_TO_LONG(b); /* if (WITHIN_PDL_RANGE(dval)) { */ /* return GET_PDL(dval); */ /* } else */ if ( (BELONG_TO_LONG(a) & PHP_LONGMIN) != (BELONG_TO_LONG(b) & PHP_LONGMIN) && (BELONG_TO_LONG(a) & PHP_LONGMIN) != (lval & PHP_LONGMIN) ) { return DOUBLE_TO_REAL((double) BELONG_TO_LONG(a) - (double) BELONG_TO_LONG(b)); } else { return LONG_TO_ONUM(lval); } } if ((REALP(a) && ELONGP(b)) || (ELONGP(a) && REALP(b))) { double dval = (REALP(a) ? (REAL_TO_DOUBLE(a) - ((double) BELONG_TO_LONG (b))) : ((double) BELONG_TO_LONG (a) - REAL_TO_DOUBLE(b))); return DOUBLE_TO_REAL(dval); } if (REALP(a) && REALP(b)) { double dval = REAL_TO_DOUBLE(a) - REAL_TO_DOUBLE(b); return DOUBLE_TO_REAL(dval); } phpnum_fail("phpsub: unknown operand types"); }
/* add two phpnums, potentially converting to a double. */ obj_t phpadd(obj_t a, obj_t b) { if (ELONGP(a) && ELONGP(b)) { long lval = BELONG_TO_LONG( a ) + BELONG_TO_LONG( b ); /* if (WITHIN_PDL_RANGE(dval)) { */ /* return GET_PDL(dval); */ /* } else */ if ( (BELONG_TO_LONG(a) & PHP_LONGMIN) == (BELONG_TO_LONG(b) & PHP_LONGMIN) && (BELONG_TO_LONG(a) & PHP_LONGMIN) != (lval & PHP_LONGMIN) ) { return DOUBLE_TO_REAL( (double)BELONG_TO_LONG( a ) + (double)BELONG_TO_LONG( b ) ); } else { return LONG_TO_ONUM( lval ); } } if ((REALP(a) && ELONGP(b)) || (ELONGP(a) && REALP(b))) { double dval = (ELONGP(a) ? (((double) BELONG_TO_LONG(a)) + REAL_TO_DOUBLE(b)) : ((REAL_TO_DOUBLE(a) + ((double) BELONG_TO_LONG(b))))); return DOUBLE_TO_REAL(dval); } if (REALP(a) && REALP(b)) { double dval = REAL_TO_DOUBLE(a) + REAL_TO_DOUBLE(b); return DOUBLE_TO_REAL(dval); } phpnum_fail("I'm lost!"); }
/* get the value of a phpnum as a long. doesn't mutate the phpnum. */ long phpnum_to_long(obj_t a) { if (REALP(a)) { return (REAL_TO_DOUBLE(a) > PHP_LONGMAX) ? (unsigned long) REAL_TO_DOUBLE(a) : (long) REAL_TO_DOUBLE(a); } else { return BELONG_TO_LONG(a); } }
/* convert a phpnum to a string. precision is irrelevant for longs. */ obj_t phpnum_to_string(obj_t a, int precision, int efg, int style) { int actual_length; #define ARB_STRING_SIZE 1024 char result[ARB_STRING_SIZE]; if (REALP(a)) { double dval = REAL_TO_DOUBLE(a); while (1) { switch (efg) { case 0: actual_length = pcc_snprintf(result, ARB_STRING_SIZE, E_FORMAT, precision, dval); break; case 1: actual_length = pcc_snprintf(result, ARB_STRING_SIZE, F_FORMAT, precision, dval); break; case 2: if (style == 0) { // echo actual_length = snprintf(result, ARB_STRING_SIZE, G_FORMAT, precision, dval); } else { // var_dump actual_length = pcc_snprintf(result, ARB_STRING_SIZE, G_FORMAT, precision, dval); } break; default: phpnum_fail("bad value for efg"); } /* this bit is from man snprintf. */ if (actual_length > -1 && actual_length < ARB_STRING_SIZE) return string_to_bstring_len(result, actual_length); if (actual_length > -1) /* glibc 2.1 */ phpnum_fail("Arbitrary constant not large enough"); else /* glibc 2.0 */ phpnum_fail("Arbitrary constant not large enough"); } } else { //long long lval = BELONG_TO_LONG(a); /* same game as above */ while (1) { actual_length = snprintf(result, ARB_STRING_SIZE, "%ld", lval); if (actual_length > -1 && actual_length < ARB_STRING_SIZE) return string_to_bstring_len(result, actual_length); if (actual_length > -1) phpnum_fail("Arbitrary constant not large enough"); else phpnum_fail("Arbitrary constant not large enough"); } } phpnum_fail("Reached end of phpnum_to_string unexpectedly."); }
char *get_col_west(t_env *e, int y, int col, int nbr) { char *saw; char *content; saw = NULL; while (nbr--) { if ((content = get_boxcontent(e->map[REALP(y, e->y)][col])) != NULL) saw = ft_strfreejoin(&saw, content); saw = ft_strfreejoin(&saw, ", "); y--; } return (saw); }
char *get_line_south(t_env *e, int x, int line, int nbr) { char *saw; char *content; saw = NULL; while (nbr--) { if ((content = get_boxcontent(e->map[line][REALP(x, e->x)])) != NULL) saw = ft_strfreejoin(&saw, content); saw = ft_strfreejoin(&saw, ", "); x--; } return (saw); }
/*---------------------------------------------------------------------*/ BGL_EXPORTED_DEF long obj_to_cobj( obj_t obj ) { if( INTEGERP( obj ) ) return (long)CINT( obj ); if( BOOLEANP( obj ) ) return (long)((long)CBOOL( obj )); if( STRINGP( obj ) ) return (long)BSTRING_TO_STRING( obj ); if( CHARP( obj ) ) return (long)((long)CCHAR( obj )); if( FOREIGNP( obj ) ) return (long)FOREIGN_TO_COBJ( obj ); if( REALP( obj ) ) return (long)the_failure( string_to_bstring( "obj->cobj" ), string_to_bstring( "Can't cast a real to foreign" ), obj); else return (long)the_failure( string_to_bstring( "obj->cobj" ), string_to_bstring( "Illegal object type" ), obj); }
/* /\* so that php can check the type *\/ */ int phpnum_is_long(obj_t a) { if ( REALP( a ) ) return 0; else return 1; }
/* so that php can check the type */ int phpnum_is_float(obj_t a) { if ( REALP( a ) ) return 1; else return 0; }