From f404affcd058b13999e25cc501108716e38a9eac Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@sbcglobal.net>
Date: Wed, 24 Jul 2024 08:41:42 -0700
Subject: [PATCH] Update multiply to a special form (like add)

---
 doc/DRAWL.md          |   2 +-
 images/apple/DRAWL.po | Bin 143360 -> 143360 bytes
 src/lisp/s-math.pla   |  55 ++++++++++++++++++++++++++++++------------
 3 files changed, 41 insertions(+), 16 deletions(-)

diff --git a/doc/DRAWL.md b/doc/DRAWL.md
index a7640e5..01ad8f4 100644
--- a/doc/DRAWL.md
+++ b/doc/DRAWL.md
@@ -108,7 +108,7 @@ The DRAWL implementation comes with the following built-in functions:
 
 - +(...)
 - -()
-- \*()
+- \*(...)
 - /()
 - REM()
 - NEG()
diff --git a/images/apple/DRAWL.po b/images/apple/DRAWL.po
index 229c58d22adc76283b0a07196ac842e9be177268..f02425247c27a7cbd414bba1eba430480a5c4319 100644
GIT binary patch
delta 3034
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
JubmZQKL7;=00aO4

delta 3030
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
Ezl<ROE&u=k

diff --git a/src/lisp/s-math.pla b/src/lisp/s-math.pla
index 30b82a0..c3731f1 100644
--- a/src/lisp/s-math.pla
+++ b/src/lisp/s-math.pla
@@ -201,23 +201,48 @@ def natv_sub(symptr, expr)
 end
 
 def natv_mul(symptr, expr)
-  res[t_numfloat] num1, num2
-  word[2] mul
-  res[t_extended] ext1, ext2
+  var num, extptr
+  word[2]         intmul
+  res[t_extended] extmul
 
-  memcpy(@num1, eval_num(expr),      t_numfloat)
-  memcpy(@num2, eval_num(expr=>cdr), t_numfloat)
-  if num1.type == NUM_INT and num2.type == NUM_INT
-    load32(@num1 + intval)
-    mul32(@num2 + intval)
-    store32(@mul)
-    return new_int(mul[0], mul[1])
+  intmul[0] = 0
+  intmul[1] = 0
+  num       = eval_num(expr)
+  expr      = expr=>cdr
+  if num->type == NUM_INT
+    //
+    // Multiply as integers unless a float is encountered
+    //
+    intmul[0] = num=>intval[0]
+    intmul[1] = num=>intval[1]
+    while expr
+      num  = eval_num(expr)
+      expr = expr=>cdr
+      if num->type == NUM_FLOAT
+        break
+      fin
+      load32(@intmul)
+      mul32(num + intval)
+      store32(@intmul)
+    loop
   fin
-  memcpy(@ext1, num_ext(@num1), t_extended)
-  memcpy(@ext2, num_ext(@num2), t_extended)
-  sane:saveZP()
-  sane:restoreZP(sane:op2FP(FOMUL, @ext1, @ext2))
-  return new_float(@ext1)
+  if num->type == NUM_FLOAT
+    //
+    // Multiply as floating point numbers
+    //
+    int32_ext(@intmul)
+    memcpy(@extmul, num + floatval, t_extended)
+    sane:saveZP()
+    sane:restoreZP(sane:op2FP(FOMUL, @extmul, @tempext))
+    while expr
+      extptr = eval_ext(expr)
+      sane:saveZP()
+      sane:restoreZP(sane:op2FP(FOMUL, @extmul, extptr))
+      expr = expr=>cdr
+    loop
+    return new_float(@extmul)
+  fin
+  return new_int(intmul[0], intmul[1])
 end
 
 def natv_div(symptr, expr)