## ~subsetpark/ec

603ec2239a258dcb283f48501d47444ca156c546 — Zach Smith 9 months ago
```Add some documentation
```
```5 files changed, 205 insertions(+), 24 deletions(-)

M main.janet
M project.janet
M src/operations.janet
```
`M README.md => README.md +90 -1`
```@@ 6,8 6,97 @@ An RPN calculator with array operations and quotations.
9
(nil)> [3 4 5] 6 x
([18 24 30])> 0 swap
-([18 24 30])> [+] /
+([18 24 30])> (+) /
(72)> p
72
(nil)>
```
+
+# Usage
+
+   ec <expression>: evaluate <expression> as a sequence of
+                    ec commands and print the resulting stack.
+   ec             : enter interactive (repl) mode.
+
+   ec operates as a RPN desk calculator with quotation
+   and vector math functions. Ordinarily, tokens are
+   evaluated from left to right as they're pushed onto
+   the stack. eg.,
+
+       3 4 +
+
+   will push 3, then 4, then apply the operation +, which
+   will pop two elements from the stack, add them, and
+   push their sum.
+
+   To quote a sequence of tokens, wrap it in
+   parentheses. eg.,
+
+       (3 4 +)
+
+   will push a single quotation containing just those
+   three tokens, which can be applied by subsequent
+   commands.
+
+   To create a vector, enclose a sequence of numbers or
+   other vectors in square brackets. eg.,
+
+       [3 4]
+
+   will create a 1-dimensional vector and push it on the
+   stack.
+
+   Vectors can be added to other vectors or individual
+   numbers. eg.,
+
+       [3 4] 2 +
+
+   will add 2 to each element of [3 4], resulting in
+   [5 6].
+
+       [3 4] [2 1] +
+
+   will add matching elements of vectors, resulting in
+   [5 5].
+
+   Vectors can be of arbitrary dimension, but must
+   contain homogeneous data. eg.,
+
+       [[2 1] [0 0]]
+
+   is a valid vector (of shape [2 2]), but
+
+       [[2] [0 0]]
+
+   is not.
+
+   For a full dictionary listing, enter the special
+   command:
+
+     ??
+
+   To get a description of any word, quote it and use the
+   special command. eg.,
+
+       (!) ?
+
+   Will print a description of the `apply` adverb.
+
+# Installation
+
+On Arch Linux, install `ec` via AUR:
+
+`yay -S ec`
+
+On other systems, install the [Janet][] language, clone this
+repository and build using `jpm`:
+
+```
+\$ mkdir janet_modules
+\$ JANET_PATH=janet_modules/ jpm build
+\$ cp build/ec <somewhere on your path>
+```
+
+[Janet]: https://janet-lang.org
+

```
`M main.janet => main.janet +83 -4`
```@@ 2,6 2,8 @@
(import /src/print)
(import /src/parser)

+(use argparse)
+
(defn handle-signal
[input]
(let [str (string input)]

@@ 105,8 107,85 @@
(handle-commands s))
(display-all (s :data))))

+(def params
+  [```
+   A desk calculator with vectors and quotations.
+
+   USAGE:
+      ec <expression>: evaluate <expression> as a sequence of
+                       ec commands and print the resulting stack.
+      ec             : enter interactive (repl) mode.
+
+      ec operates as a RPN desk calculator with quotation
+      and vector math functions. Ordinarily, tokens are
+      evaluated from left to right as they're pushed onto
+      the stack. eg.,
+
+          3 4 +
+
+      will push 3, then 4, then apply the operation +, which
+      will pop two elements from the stack, add them, and
+      push their sum.
+
+      To quote a sequence of tokens, wrap it in
+      parentheses. eg.,
+
+          (3 4 +)
+
+      will push a single quotation containing just those
+      three tokens, which can be applied by subsequent
+      commands.
+
+      To create a vector, enclose a sequence of numbers or
+      other vectors in square brackets. eg.,
+
+          [3 4]
+
+      will create a 1-dimensional vector and push it on the
+      stack.
+
+      Vectors can be added to other vectors or individual
+      numbers. eg.,
+
+          [3 4] 2 +
+
+      will add 2 to each element of [3 4], resulting in
+      [5 6].
+
+          [3 4] [2 1] +
+
+      will add matching elements of vectors, resulting in
+      [5 5].
+
+      Vectors can be of arbitrary dimension, but must
+      contain homogeneous data. eg.,
+
+          [[2 1] [0 0]]
+
+      is a valid vector (of shape [2 2]), but
+
+          [[2] [0 0]]
+
+      is not.
+
+      For a full dictionary listing, enter the special
+      command:
+
+        ??
+
+      To get a description of any word, quote it and use the
+      special command. eg.,
+
+          (!) ?
+
+      Will print a description of the `apply` adverb.
+   ```
+   :default {:kind :accumulate}])
+
(defn main
-  [_cmd & args]
-  (if (empty? args)
-    (repl)
-    (handle-line (string/join args " "))))
+  [& _args]
+  (let [res (argparse ;params)]
+    (when res
+      (match (res :default)
+        nil (repl)
+        inputs (handle-line (string/join inputs " "))))))

```
`M project.janet => project.janet +2 -1`
```@@ 2,7 2,8 @@
:name "ec"
:description "a very good calculator"
:dependencies ["fugue"
-                 "https://github.com/pyrmont/testament"])
+                 "argparse"
+                 "testament"])

(def *static-build* (= (or (os/getenv "EC_STATIC_BUILD") "0") "1"))

```
`M src/adverbs.janet => src/adverbs.janet +14 -14`
```@@ 12,7 12,7 @@
```
q -- x
"Unwrap" a quotation and push its elements onto the stack.
-  `1 1 [+] apply` is equivalent to `1 1 +`.
+  `1 1 (+) apply` is equivalent to `1 1 +`.
```
(let [quotation (calc/pop stack)]
(if (calc/Quotation*? quotation)

@@ 84,11 84,11 @@
```
q a -- q
-  If the second element on the stack `q` is a quotation, includes the
-  topmost element as the last item in `q`.
+  If the second element on the stack `q` is a quotation,
+  includes the topmost element as the last item in `q`.

-  If either element is a quotation, wraps the two top elements in a
-  quotation.
+  If either element is a quotation, wraps the two top
+  elements in a quotation.
```
(let [elem (calc/pop stack)
vector (calc/pop stack)

@@ 100,11 100,11 @@
```
a q -- q
-  If the topmost element on the stack `q` is a quotation, includes the
-  second element as the first item in `q`.
+  If the topmost element on the stack `q` is a quotation,
+  includes the second element as the first item in `q`.

-  If either element is a quotation, wraps the two top elements in a
-  quotation.
+  If either element is a quotation, wraps the two top
+  elements in a quotation.
```
(let [vector (calc/pop stack)
elem (calc/pop stack)

@@ 116,8 116,8 @@
```
a s -- a'
-  Given a quotation shape `s`, repeats the element `a` until it has
-  that shape.
+  Given a quotation shape `s`, recursively repeats the
+  element `a` until it has that shape.
```
(let [shape (calc/pop stack)
elem (calc/pop stack)]

@@ 132,8 132,8 @@
```
a -- n
-  Returns the number of stack elements that `a` would consume if it
-  were pushed to the stack.
+  Pushes the number of stack elements that `a` would consume
+  if it were pushed to the stack.
```
(let [elem (calc/pop stack)
arity (calc/get-arity elem)

@@ 143,7 143,7 @@
```
v -- w
-  Returns the shape of the vector `v`.
+  Pushes the shape of the vector `v`.
```
(let [v (calc/pop stack)
shape (calc/get-shape v)

```
`M src/operations.janet => src/operations.janet +16 -4`
```@@ 1,23 1,35 @@
(import /src/calc)

(defmacro defop
-  [name arity out-arity f]
+  [name arity out-arity f &opt doc]
~(def ,name (:new calc/Operation
:arity ,arity
:out-arity ,out-arity
:type ,(keyword name)
-                    :fun-ref ,f)))
+                    :fun-ref ,f
+                    :doc ,doc)))

(defmacro defcmp
[name arity out-arity cmp]
~(defop ,name ,arity ,out-arity
-     (fn [x y] (if (,cmp x y) 1 0))))
+     (fn [x y] (if (,cmp x y) 1 0))
+     (string/format
+      `x y -- p
+       Comparison predicate.
+       Push 1 if x %s y;
+       else 0.
+       ` ,(string cmp))))

(defop sub 2 1 -)
(defop div 2 1 /)
(defop mul 2 1 *)
-(defop cmp 2 1 cmp)
+(defop cmp 2 1 cmp
+  `x y -- p
+  Push -1 if x < y;
+        0 if x = y;
+        1 if x > y.
+  ` )
(defop pow 2 1 math/pow)
(defop sqrt 1 1 math/sqrt)

```