Repository: josdejong/mathjs
Pull request #839 (2017-05-04 16:44:07)

cli: inline evaluate
Now you can use cli for inline interpretation:
```
bin/cli.js script1 script2
> 123 + 3
126
> + 15
15
> 
vganzin ~/work/mathjs bin/cli.js 1+2
3
```

p.s. I can't find any cli tests


Patch:
diff --git a/benchmark/README.md b/benchmark/README.md
deleted file mode 100644
index 74a31705d..000000000
--- a/benchmark/README.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# Benchmarks
-
-These are some rough benchmarks to get an idea of the performance of math.js compared to other JavaScript libraries and to Octave (C++). They only give an _indication_ of the order of magnitude difference meant to see were math.js has room for improvements, it's not a fully fletched benchmark suite.
-
-
-## How to run
-
-### JavaScript library benchmarks
-
-Install the dependencies once:
-
-```
-npm install
-```
-
-run the tests:
-
-```
-node benchmark.js
-```
-
-### Octave benchmarks
-
-Open Octave, run the script `benchmark_octave.m`
-
-## To do
-
--   compare with python and Octave
-
--   use larger matrix, like 250x250 instead of 25x25
-
--   Compare expression parsers
-
-    evaluate the following function thousand times
-
-        f(x) = (sin(x) + cos(x/2)) * 5
-
-    Libraries:
-    - math.js
-    - expr-eval
-    - jsep
-    - math-expression-evaluator
diff --git a/benchmark/benchmark.js b/benchmark/benchmark.js
deleted file mode 100644
index 7037b8abe..000000000
--- a/benchmark/benchmark.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * Benchmark
- * 
- * Compare performance of basic matrix operations of a number of math libraries. 
- */
-
-var padLeft = require('pad-left')
-var padRight = require('pad-right')
-
-var iterations = 1000
-
-// fiedler matrix 25 x 25
-var fiedler = [
-  [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
-  [ 1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
-  [ 2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22],
-  [ 3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
-  [ 4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
-  [ 5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
-  [ 6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18],
-  [ 7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17],
-  [ 8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16],
-  [ 9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15],
-  [10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14],
-  [11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13],
-  [12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12],
-  [13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
-  [14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10],
-  [15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
-  [16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8],
-  [17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6,  7],
-  [18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5,  6],
-  [19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4,  5],
-  [20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3,  4],
-  [21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2,  3],
-  [22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1,  2],
-  [23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  1],
-  [24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0]
-]
-
-// mathjs
-{
-  var math = require('../index')
-  var A = math.matrix(fiedler)
-
-  measure ('mathjs', 'A+A',    function () { res = math.add(A, A) })
-  measure ('mathjs', 'A*A',    function () { res = math.multiply(A, A) })
-  measure ('mathjs', 'A\'',    function () { res = math.transpose(A) })
-  measure ('mathjs', 'det(A)', function () { res = math.det(A) })
-}
-
-// sylvester
-{
-  var sylvester = require('sylvester')
-  var A = sylvester.Matrix.create(fiedler)
-
-  measure ('sylvester', 'A+A',    function () { A.add(A) })
-  measure ('sylvester', 'A*A',    function () { A.multiply(A) })
-  measure ('sylvester', 'A\'',    function () { A.transpose() })
-  measure ('sylvester', 'det(A)', function () { A.det() })
-}
-
-// numericjs
-{
-  var numeric = require('numericjs')
-  var A = fiedler
-
-  measure ('numericjs', 'A+A',    function () { numeric.add(A, A) })
-  measure ('numericjs', 'A*A',    function () { numeric.dot(A, A) })
-  measure ('numericjs', 'A\'',    function () { numeric.transpose(A) })
-  measure ('numericjs', 'det(A)', function () { numeric.det(A) })
-}
-
-// ndarray
-{
-  var ndarray = require('ndarray')
-  var gemm = require('ndarray-gemm')
-  var zeros = require('zeros')
-  var ops = require('ndarray-ops')
-  var pack = require('ndarray-pack')
-  var det  = require('ndarray-determinant')
-  
-  var A = pack(fiedler)
-  var B = zeros([25, 25])
-
-  measure('ndarray', 'A+A', function () { ops.add(B, A, A) })
-  measure('ndarray', 'A*A', function () { gemm(B, A, A) })
-  measure('ndarray', 'A\'', function () { ops.assign(B, A); B.transpose(1, 0); })
-  measure('ndarray', 'det(A)', function () { det(A) })
-}
-
-/**
- * Repeatedly execute test and print the average duration
- * @param {string} library
- * @param {string} description
- * @param {function} test 
- */
-function measure (library, description, test) {
-  // warm up
-  test() 
-
-  var start = Date.now()
-  for (var i = 0; i < iterations / 10; i++) {
-    // ten times to minimize the impact of the duration of the for loop itself
-    test()
-    test()
-    test()
-    test()
-    test()
-    test()
-    test()
-    test()
-    test()
-    test()
-  }
-  var end = Date.now()
-  var duration = Math.round((end - start) * 1000 / (iterations))  // in microseconds
-
-  console.log(padRight(library, 12, ' ') + padRight(description, 8, ' ') + padLeft(duration, 6, ' ') + ' microseconds')
-}
-
-function flatten (arr) {
-  return [].concat.apply([], arr)
-}
\ No newline at end of file
diff --git a/benchmark/benchmark_octave.m b/benchmark/benchmark_octave.m
deleted file mode 100644
index ff1c6cbea..000000000
--- a/benchmark/benchmark_octave.m
+++ /dev/null
@@ -1,75 +0,0 @@
-A = gallery("fiedler", 25);
-
-iterations = 1000;
-
-# --------------- ADD ---------------------
-timeStart = time();
-for n = 1:(iterations/10)
-  B = A + A;
-  B = A + A;
-  B = A + A;
-  B = A + A;
-  B = A + A;
-  B = A + A;
-  B = A + A;
-  B = A + A;
-  B = A + A;
-  B = A + A;
-endfor
-timeEnd = time();
-duration = timeEnd - timeStart; # seconds
-addDuration = duration / iterations * 1e6  # microseconds
-
-# --------------- MULTIPLY ---------------------
-timeStart = time();
-for n = 1:(iterations/10)
-  B = A * A;
-  B = A * A;
-  B = A * A;
-  B = A * A;
-  B = A * A;
-  B = A * A;
-  B = A * A;
-  B = A * A;
-  B = A * A;
-  B = A * A;
-endfor
-timeEnd = time();
-duration = timeEnd - timeStart; # seconds
-multiplyDuration = duration / iterations * 1e6  # microseconds
-
-# --------------- TRANSPOSE ---------------------
-timeStart = time();
-for n = 1:(iterations/10)
-  B = A';
-  B = A';
-  B = A';
-  B = A';
-  B = A';
-  B = A';
-  B = A';
-  B = A';
-  B = A';
-  B = A';
-endfor
-timeEnd = time();
-duration = timeEnd - timeStart; # seconds
-transposeDuration = duration / iterations * 1e6  # microseconds
-
-# --------------- DETERMINANT ---------------------
-timeStart = time();
-for n = 1:(iterations/10)
-  B = det(A);
-  B = det(A);
-  B = det(A);
-  B = det(A);
-  B = det(A);
-  B = det(A);
-  B = det(A);
-  B = det(A);
-  B = det(A);
-  B = det(A);
-endfor
-timeEnd = time();
-duration = timeEnd - timeStart; # seconds
-determinantDuration = duration / iterations * 1e6  # microseconds
diff --git a/benchmark/package.json b/benchmark/package.json
deleted file mode 100644
index 173c89456..000000000
--- a/benchmark/package.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "dependencies": {
-    "expr-eval": "1.0.0",
-    "jsep": "0.3.0",
-    "math-expression-evaluator": "1.2.16",
-    "ndarray": "1.0.18",
-    "ndarray-determinant": "1.0.0",
-    "ndarray-gemm": "1.0.0",
-    "ndarray-ops": "1.2.2",
-    "ndarray-pack": "1.2.1",
-    "numericjs": "1.2.6",
-    "pad-left": "2.1.0",
-    "pad-right": "0.2.2",
-    "sylvester": "0.0.21",
-    "zeros": "1.0.0"
-  }
-}
diff --git a/benchmark/results.txt b/benchmark/results.txt
deleted file mode 100644
index f110e7084..000000000
--- a/benchmark/results.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-mathjs      A+A         21 microseconds
-mathjs      A*A        288 microseconds
-mathjs      A'          23 microseconds
-mathjs      det(A)   10349 microseconds
-sylvester   A+A         20 microseconds
-sylvester   A*A        184 microseconds
-sylvester   A'          11 microseconds
-sylvester   det(A)     103 microseconds
-numericjs   A+A          6 microseconds
-numericjs   A*A         30 microseconds
-numericjs   A'           3 microseconds
-numericjs   det(A)      15 microseconds
-ndarray     A+A          6 microseconds
-ndarray     A*A         42 microseconds
-ndarray     A'           4 microseconds
-ndarray     det(A)      10 microseconds
-
diff --git a/bin/cli.js b/bin/cli.js
index ba9951ba6..653489b6e 100755
--- a/bin/cli.js
+++ b/bin/cli.js
@@ -22,6 +22,7 @@
  *
  * Example usage:
  *     mathjs                                 Open a command prompt
+ *     mathjs 1+2                             Evaluate expression
  *     mathjs script.txt                      Run a script file
  *     mathjs script1.txt script2.txt         Run two script files
  *     mathjs script.txt > results.txt        Run a script file, output to file
@@ -336,7 +337,7 @@ function outputHelp() {
   console.log('functions, and a flexible expression parser.');
   console.log();
   console.log('Usage:');
-  console.log('    mathjs [scriptfile(s)] {OPTIONS}');
+  console.log('    mathjs [scriptfile(s)|expression] {OPTIONS}');
   console.log();
   console.log('Options:');
   console.log('    --version, -v       Show application version');
@@ -348,6 +349,7 @@ function outputHelp() {
   console.log();
   console.log('Example usage:');
   console.log('    mathjs                                Open a command prompt');
+  console.log('    mathjs 1+2                            Evaluate expression');
   console.log('    mathjs script.txt                     Run a script file');
   console.log('    mathjs script.txt script2.txt         Run two script files');
   console.log('    mathjs script.txt > results.txt       Run a script file, output to file');
@@ -420,9 +422,15 @@ else if (scripts.length === 0) {
   runStream(process.stdin, process.stdout, mode, parenthesis);
 }
 else {
-  //work through the queue of scripts
-  scripts.forEach(function (arg) {
-    // run a script file
-    runStream(fs.createReadStream(arg), process.stdout, mode, parenthesis);
-  });
+  fs.stat(scripts[0], function(e, f) {
+    if (e) {
+      console.log(getMath().eval(scripts.join(' ')).toString())
+    } else {
+    //work through the queue of scripts
+      scripts.forEach(function (arg) {
+        // run a script file
+          runStream(fs.createReadStream(arg), process.stdout, mode, parenthesis);
+      });
+    }
+  })
 }


Test patch:
diff --git a/test/cli/cli.js b/test/cli/cli.js
new file mode 100644
index 000000000..56e8428d5
--- /dev/null
+++ b/test/cli/cli.js
@@ -0,0 +1,40 @@
+var assert = require('assert')
+var cp = require('child_process')
+    
+function run(args, done) {
+  cp.exec('bin/cli.js "' + args +'"', function(e,r) {
+    done(e, r.replace(/\n$/g, ''))
+  })
+}
+describe('evaluate expression', function() {
+    it('should sum numbers', function(done) {
+        run('1+1', function(e, result) {
+          assert.equal(result, 2)
+          done()
+        })
+    })
+    
+    it('should multiply matrices', function(done) {
+        run('[1,2] * [3,4]', function(e, result) {
+          assert.equal(result, 11)
+          done()
+        })
+    })
+    
+    it('should thow error', function(done) {
+      run('y=x', function(e, result) {
+        assert.equal(/^Error/g.test(e.toString()),true)
+        done()
+      })
+    })
+    
+    it('should interpret scripts', function(done) {
+      run('test/cli/script1" "test/cli/script2', function(e, result){
+        result = result.split('\n')
+        assert.equal(result[0], 2)
+        assert.equal(result[1], 8)
+        done()
+      })
+    })
+    
+})
diff --git a/test/cli/script1 b/test/cli/script1
new file mode 100644
index 000000000..c040fa67d
--- /dev/null
+++ b/test/cli/script1
@@ -0,0 +1,1 @@
+1+1
diff --git a/test/cli/script2 b/test/cli/script2
new file mode 100644
index 000000000..63c10fdf2
--- /dev/null
+++ b/test/cli/script2
@@ -0,0 +1,1 @@
+2*4