Skip to content

Commit c272af1

Browse files
committed
FEAT: implemented basic ADD, SUBTRACT, DIVIDE and MULTIPLY between VECTOR and NUMBER
Implements: metaeducation/rebol-issues#2355
1 parent 7383e12 commit c272af1

File tree

4 files changed

+136
-10
lines changed

4 files changed

+136
-10
lines changed

src/boot/actions.r

+9-9
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,26 @@ REBOL [
2121

2222
add: action [
2323
{Returns the addition of two values.}
24-
value1 [scalar! date!]
25-
value2
24+
value1 [scalar! date! vector!]
25+
value2 [scalar! date! vector!]
2626
]
2727

2828
subtract: action [
2929
{Returns the second value subtracted from the first.}
30-
value1 [scalar! date!]
31-
value2 [scalar! date!]
30+
value1 [scalar! date! vector!]
31+
value2 [scalar! date! vector!]
3232
]
3333

3434
multiply: action [
3535
{Returns the first value multiplied by the second.}
36-
value1 [scalar!]
37-
value2 [scalar!]
36+
value1 [scalar! vector!]
37+
value2 [scalar! vector!]
3838
]
3939

4040
divide: action [
4141
{Returns the first value divided by the second.}
42-
value1 [scalar!]
43-
value2 [scalar!]
42+
value1 [scalar! vector!]
43+
value2 [scalar! vector!]
4444
]
4545

4646
remainder: action [
@@ -421,7 +421,7 @@ open?: action [
421421
]
422422

423423
query: action [
424-
{Returns information about value if possible.}
424+
{Returns information about target if possible.}
425425
target [port! file! url! block! vector!]
426426
/mode "Get mode information"
427427
field [word! block! none!] "NONE will return valid modes for target type"

src/core/f-series.c

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@
124124
case A_SUBTRACT: // "test this" - 10
125125
case A_MULTIPLY: // "t" * 4 = "tttt"
126126
case A_DIVIDE:
127+
if (IS_VECTOR(value)) return -1; // allow vector for actions above
128+
//continue...
127129
case A_REMAINDER:
128130
case A_POWER:
129131
case A_ODDQ:

src/core/t-decimal.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ REBOOL almost_equal(REBDEC a, REBDEC b, REBCNT max_diff) {
238238
type == REB_PAIR ||
239239
type == REB_TUPLE ||
240240
type == REB_MONEY ||
241-
type == REB_TIME
241+
type == REB_TIME ||
242+
type == REB_VECTOR
242243
) && (
243244
action == A_ADD ||
244245
action == A_MULTIPLY

src/core/t-vector.c

+123
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,122 @@ void Set_Vector_Row(REBSER *ser, REBVAL *blk)
226226
}
227227

228228

229+
/***********************************************************************
230+
**
231+
*/ REBVAL* Math_Op_Vector(REBVAL *v1, REBVAL *v2, REBCNT action)
232+
/*
233+
** Do basic math operation on a vector
234+
**
235+
***********************************************************************/
236+
{
237+
REBSER *vect = NULL;
238+
REBYTE *data;
239+
REBCNT bits;
240+
REBCNT len;
241+
242+
REBVAL *left;
243+
REBVAL *right;
244+
245+
REBI64 i = 0;
246+
REBDEC f = 0;
247+
REBCNT n = 0;
248+
249+
if (IS_VECTOR(v1) && IS_NUMBER(v2)) {
250+
left = v1;
251+
right = v2;
252+
} else if (IS_VECTOR(v2) && IS_NUMBER(v1)) {
253+
left = v2;
254+
right = v1;
255+
} else {
256+
Trap_Action(VAL_TYPE(v1), action);
257+
return NULL;
258+
}
259+
vect = VAL_SERIES(left);
260+
len = VAL_LEN(left);
261+
bits = VECT_TYPE(vect);
262+
data = vect->data;
263+
264+
if (IS_INTEGER(right)) {
265+
i = VAL_INT64(right);
266+
f = (REBDEC)i;
267+
} else {
268+
f = VAL_DECIMAL(right);
269+
i = (REBI64)f;
270+
}
271+
272+
n = VAL_INDEX(left);
273+
274+
switch (action) {
275+
case A_ADD:
276+
switch (bits) {
277+
case VTSI08: for (; n<len; n++) ( (i8*)data)[n] += ( i8)i; break;
278+
case VTSI16: for (; n<len; n++) ((i16*)data)[n] += (i16)i; break;
279+
case VTSI32: for (; n<len; n++) ((i32*)data)[n] += (i32)i; break;
280+
case VTSI64: for (; n<len; n++) ((i64*)data)[n] += (i64)i; break;
281+
case VTUI08: for (; n<len; n++) (( u8*)data)[n] += ( u8)i; break;
282+
case VTUI16: for (; n<len; n++) ((u16*)data)[n] += (u16)i; break;
283+
case VTUI32: for (; n<len; n++) ((u32*)data)[n] += (u32)i; break;
284+
case VTUI64: for (; n<len; n++) ((i64*)data)[n] += (u64)i; break;
285+
case VTSF08:
286+
case VTSF16:
287+
case VTSF32: for (; n<len; n++) (( float*)data)[n] += (float)f; break;
288+
case VTSF64: for (; n<len; n++) ((double*)data)[n] += f; break;
289+
}
290+
break;
291+
case A_SUBTRACT:
292+
switch (bits) {
293+
case VTSI08: for (; n<len; n++) (( i8*)data)[n] -= ( i8)i; break;
294+
case VTSI16: for (; n<len; n++) ((i16*)data)[n] -= (i16)i; break;
295+
case VTSI32: for (; n<len; n++) ((i32*)data)[n] -= (i32)i; break;
296+
case VTSI64: for (; n<len; n++) ((i64*)data)[n] -= (i64)i; break;
297+
case VTUI08: for (; n<len; n++) (( u8*)data)[n] -= ( u8)i; break;
298+
case VTUI16: for (; n<len; n++) ((u16*)data)[n] -= (u16)i; break;
299+
case VTUI32: for (; n<len; n++) ((u32*)data)[n] -= (u32)i; break;
300+
case VTUI64: for (; n<len; n++) ((i64*)data)[n] -= (u64)i; break;
301+
case VTSF08:
302+
case VTSF16:
303+
case VTSF32: for (; n<len; n++) (( float*)data)[n] -= (float)f; break;
304+
case VTSF64: for (; n<len; n++) ((double*)data)[n] -= f; break;
305+
}
306+
break;
307+
case A_MULTIPLY:
308+
switch (bits) {
309+
case VTSI08: for (; n<len; n++) (( i8*)data)[n] *= ( i8)i; break;
310+
case VTSI16: for (; n<len; n++) ((i16*)data)[n] *= (i16)i; break;
311+
case VTSI32: for (; n<len; n++) ((i32*)data)[n] *= (i32)i; break;
312+
case VTSI64: for (; n<len; n++) ((i64*)data)[n] *= (i64)i; break;
313+
case VTUI08: for (; n<len; n++) (( u8*)data)[n] *= ( u8)i; break;
314+
case VTUI16: for (; n<len; n++) ((u16*)data)[n] *= (u16)i; break;
315+
case VTUI32: for (; n<len; n++) ((u32*)data)[n] *= (u32)i; break;
316+
case VTUI64: for (; n<len; n++) ((i64*)data)[n] *= (u64)i; break;
317+
case VTSF08:
318+
case VTSF16:
319+
case VTSF32: for (; n<len; n++) (( float*)data)[n] *= (float)f; break;
320+
case VTSF64: for (; n<len; n++) ((double*)data)[n] *= f; break;
321+
}
322+
break;
323+
case A_DIVIDE:
324+
if (i == 0) Trap0(RE_ZERO_DIVIDE);
325+
switch (bits) {
326+
case VTSI08: for (; n<len; n++) (( i8*)data)[n] /= ( i8)i; break;
327+
case VTSI16: for (; n<len; n++) ((i16*)data)[n] /= (i16)i; break;
328+
case VTSI32: for (; n<len; n++) ((i32*)data)[n] /= (i32)i; break;
329+
case VTSI64: for (; n<len; n++) ((i64*)data)[n] /= (i64)i; break;
330+
case VTUI08: for (; n<len; n++) (( u8*)data)[n] /= ( u8)i; break;
331+
case VTUI16: for (; n<len; n++) ((u16*)data)[n] /= (u16)i; break;
332+
case VTUI32: for (; n<len; n++) ((u32*)data)[n] /= (u32)i; break;
333+
case VTUI64: for (; n<len; n++) ((i64*)data)[n] /= (u64)i; break;
334+
case VTSF08:
335+
case VTSF16:
336+
case VTSF32: for (; n<len; n++) (( float*)data)[n] /= (float)f; break;
337+
case VTSF64: for (; n<len; n++) ((double*)data)[n] /= f; break;
338+
}
339+
break;
340+
}
341+
return left;
342+
}
343+
344+
229345
/***********************************************************************
230346
**
231347
*/ REBINT Compare_Vector(REBVAL *v1, REBVAL *v2)
@@ -572,6 +688,13 @@ void Set_Vector_Row(REBSER *ser, REBVAL *blk)
572688
Pick_Path(value, arg, D_ARG(3));
573689
return R_ARG3;
574690

691+
case A_ADD:
692+
case A_SUBTRACT:
693+
case A_MULTIPLY:
694+
case A_DIVIDE:
695+
Math_Op_Vector(value, arg, action);
696+
break;
697+
575698
case A_MAKE:
576699
// We only allow MAKE VECTOR! ...
577700
if (!IS_DATATYPE(value)) goto bad_make;

0 commit comments

Comments
 (0)