Skip to content

Commit

Permalink
FEAT: implemented basic ADD, SUBTRACT, DIVIDE and MULTIPLY between VE…
Browse files Browse the repository at this point in the history
…CTOR and NUMBER

Implements: metaeducation/rebol-issues#2355
  • Loading branch information
Oldes committed Jan 23, 2019
1 parent 7383e12 commit c272af1
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 10 deletions.
18 changes: 9 additions & 9 deletions src/boot/actions.r
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,26 @@ REBOL [

add: action [
{Returns the addition of two values.}
value1 [scalar! date!]
value2
value1 [scalar! date! vector!]
value2 [scalar! date! vector!]
]

subtract: action [
{Returns the second value subtracted from the first.}
value1 [scalar! date!]
value2 [scalar! date!]
value1 [scalar! date! vector!]
value2 [scalar! date! vector!]
]

multiply: action [
{Returns the first value multiplied by the second.}
value1 [scalar!]
value2 [scalar!]
value1 [scalar! vector!]
value2 [scalar! vector!]
]

divide: action [
{Returns the first value divided by the second.}
value1 [scalar!]
value2 [scalar!]
value1 [scalar! vector!]
value2 [scalar! vector!]
]

remainder: action [
Expand Down Expand Up @@ -421,7 +421,7 @@ open?: action [
]

query: action [
{Returns information about value if possible.}
{Returns information about target if possible.}
target [port! file! url! block! vector!]
/mode "Get mode information"
field [word! block! none!] "NONE will return valid modes for target type"
Expand Down
2 changes: 2 additions & 0 deletions src/core/f-series.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@
case A_SUBTRACT: // "test this" - 10
case A_MULTIPLY: // "t" * 4 = "tttt"
case A_DIVIDE:
if (IS_VECTOR(value)) return -1; // allow vector for actions above
//continue...
case A_REMAINDER:
case A_POWER:
case A_ODDQ:
Expand Down
3 changes: 2 additions & 1 deletion src/core/t-decimal.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ REBOOL almost_equal(REBDEC a, REBDEC b, REBCNT max_diff) {
type == REB_PAIR ||
type == REB_TUPLE ||
type == REB_MONEY ||
type == REB_TIME
type == REB_TIME ||
type == REB_VECTOR
) && (
action == A_ADD ||
action == A_MULTIPLY
Expand Down
123 changes: 123 additions & 0 deletions src/core/t-vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,122 @@ void Set_Vector_Row(REBSER *ser, REBVAL *blk)
}


/***********************************************************************
**
*/ REBVAL* Math_Op_Vector(REBVAL *v1, REBVAL *v2, REBCNT action)
/*
** Do basic math operation on a vector
**
***********************************************************************/
{
REBSER *vect = NULL;
REBYTE *data;
REBCNT bits;
REBCNT len;

REBVAL *left;
REBVAL *right;

REBI64 i = 0;
REBDEC f = 0;
REBCNT n = 0;

if (IS_VECTOR(v1) && IS_NUMBER(v2)) {
left = v1;
right = v2;
} else if (IS_VECTOR(v2) && IS_NUMBER(v1)) {
left = v2;
right = v1;
} else {
Trap_Action(VAL_TYPE(v1), action);
return NULL;
}
vect = VAL_SERIES(left);
len = VAL_LEN(left);
bits = VECT_TYPE(vect);
data = vect->data;

if (IS_INTEGER(right)) {
i = VAL_INT64(right);
f = (REBDEC)i;
} else {
f = VAL_DECIMAL(right);
i = (REBI64)f;
}

n = VAL_INDEX(left);

switch (action) {
case A_ADD:
switch (bits) {
case VTSI08: for (; n<len; n++) ( (i8*)data)[n] += ( i8)i; break;
case VTSI16: for (; n<len; n++) ((i16*)data)[n] += (i16)i; break;
case VTSI32: for (; n<len; n++) ((i32*)data)[n] += (i32)i; break;
case VTSI64: for (; n<len; n++) ((i64*)data)[n] += (i64)i; break;
case VTUI08: for (; n<len; n++) (( u8*)data)[n] += ( u8)i; break;
case VTUI16: for (; n<len; n++) ((u16*)data)[n] += (u16)i; break;
case VTUI32: for (; n<len; n++) ((u32*)data)[n] += (u32)i; break;
case VTUI64: for (; n<len; n++) ((i64*)data)[n] += (u64)i; break;
case VTSF08:
case VTSF16:
case VTSF32: for (; n<len; n++) (( float*)data)[n] += (float)f; break;
case VTSF64: for (; n<len; n++) ((double*)data)[n] += f; break;
}
break;
case A_SUBTRACT:
switch (bits) {
case VTSI08: for (; n<len; n++) (( i8*)data)[n] -= ( i8)i; break;
case VTSI16: for (; n<len; n++) ((i16*)data)[n] -= (i16)i; break;
case VTSI32: for (; n<len; n++) ((i32*)data)[n] -= (i32)i; break;
case VTSI64: for (; n<len; n++) ((i64*)data)[n] -= (i64)i; break;
case VTUI08: for (; n<len; n++) (( u8*)data)[n] -= ( u8)i; break;
case VTUI16: for (; n<len; n++) ((u16*)data)[n] -= (u16)i; break;
case VTUI32: for (; n<len; n++) ((u32*)data)[n] -= (u32)i; break;
case VTUI64: for (; n<len; n++) ((i64*)data)[n] -= (u64)i; break;
case VTSF08:
case VTSF16:
case VTSF32: for (; n<len; n++) (( float*)data)[n] -= (float)f; break;
case VTSF64: for (; n<len; n++) ((double*)data)[n] -= f; break;
}
break;
case A_MULTIPLY:
switch (bits) {
case VTSI08: for (; n<len; n++) (( i8*)data)[n] *= ( i8)i; break;
case VTSI16: for (; n<len; n++) ((i16*)data)[n] *= (i16)i; break;
case VTSI32: for (; n<len; n++) ((i32*)data)[n] *= (i32)i; break;
case VTSI64: for (; n<len; n++) ((i64*)data)[n] *= (i64)i; break;
case VTUI08: for (; n<len; n++) (( u8*)data)[n] *= ( u8)i; break;
case VTUI16: for (; n<len; n++) ((u16*)data)[n] *= (u16)i; break;
case VTUI32: for (; n<len; n++) ((u32*)data)[n] *= (u32)i; break;
case VTUI64: for (; n<len; n++) ((i64*)data)[n] *= (u64)i; break;
case VTSF08:
case VTSF16:
case VTSF32: for (; n<len; n++) (( float*)data)[n] *= (float)f; break;
case VTSF64: for (; n<len; n++) ((double*)data)[n] *= f; break;
}
break;
case A_DIVIDE:
if (i == 0) Trap0(RE_ZERO_DIVIDE);
switch (bits) {
case VTSI08: for (; n<len; n++) (( i8*)data)[n] /= ( i8)i; break;
case VTSI16: for (; n<len; n++) ((i16*)data)[n] /= (i16)i; break;
case VTSI32: for (; n<len; n++) ((i32*)data)[n] /= (i32)i; break;
case VTSI64: for (; n<len; n++) ((i64*)data)[n] /= (i64)i; break;
case VTUI08: for (; n<len; n++) (( u8*)data)[n] /= ( u8)i; break;
case VTUI16: for (; n<len; n++) ((u16*)data)[n] /= (u16)i; break;
case VTUI32: for (; n<len; n++) ((u32*)data)[n] /= (u32)i; break;
case VTUI64: for (; n<len; n++) ((i64*)data)[n] /= (u64)i; break;
case VTSF08:
case VTSF16:
case VTSF32: for (; n<len; n++) (( float*)data)[n] /= (float)f; break;
case VTSF64: for (; n<len; n++) ((double*)data)[n] /= f; break;
}
break;
}
return left;
}


/***********************************************************************
**
*/ REBINT Compare_Vector(REBVAL *v1, REBVAL *v2)
Expand Down Expand Up @@ -572,6 +688,13 @@ void Set_Vector_Row(REBSER *ser, REBVAL *blk)
Pick_Path(value, arg, D_ARG(3));
return R_ARG3;

case A_ADD:
case A_SUBTRACT:
case A_MULTIPLY:
case A_DIVIDE:
Math_Op_Vector(value, arg, action);
break;

case A_MAKE:
// We only allow MAKE VECTOR! ...
if (!IS_DATATYPE(value)) goto bad_make;
Expand Down

0 comments on commit c272af1

Please sign in to comment.