Przeglądaj źródła

Implement some language defined functions

-Refactor the numeric types so it is possible to properly print real and int

-Refactor StoreObject to include a helper function to access numeric values

-Implement toReal function

-Refactor toInt function to use the new numeric lib
Lucas de Souza 5 lat temu
rodzic
commit
a92ca4a593

+ 2 - 2
js/ast/ivprogParser.js

@@ -1,7 +1,7 @@
 import { CommonTokenStream, InputStream } from 'antlr4/index';
 import * as Expressions from './expressions/';
 import * as Commands from './commands/';
-import { Types, toInt, toString, toBool } from './types';
+import { Types, toInt, toString, toBool, toReal } from './types';
 import { SourceInfo } from './sourceInfo';
 import { convertFromString } from './operators';
 import { SyntaxErrorFactory } from './error/syntaxErrorFactory';
@@ -336,7 +336,7 @@ export class IVProgParser {
 
   getRealLiteral (token) {
     const sourceInfo = SourceInfo.createSourceInfo(token);
-    const exp = new Expressions.RealLiteral(parseFloat(token.text));
+    const exp = new Expressions.RealLiteral(toReal(token.text));
     exp.sourceInfo = sourceInfo;
     return exp;
   }

+ 6 - 7
js/ast/types.js

@@ -1,4 +1,5 @@
 import { LanguageService } from "../services/languageService";
+import { BigNumber } from 'bignumber.js'
 
 export const Types = Object.freeze({
   INTEGER: {value: "int", ord: 0},
@@ -12,13 +13,7 @@ export const Types = Object.freeze({
 });
 
 export function toInt (str) {
-  if(str.match('^0b|^0B')) {
-    return parseInt(str.substring(2), 2);
-  } else if (str.match('^0x|^0X')) {
-    return parseInt(str.substring(2), 16);
-  } else {
-    return parseInt(str);
-  }
+  return new BigNumber(str);
 }
 
 export function toString (str) {
@@ -34,6 +29,10 @@ export function toString (str) {
   return value;
 }
 
+export function toReal (value) {
+  return new BigNumber(value);
+}
+
 export function toBool (str) {
   const val = "'" + str + "'";
   const lexer = LanguageService.getCurrentLexer();

+ 3 - 0
js/jquery.json-editor.min.js

@@ -35,6 +35,9 @@ function(e) {
               s += "</ol>]"
           } else s += "[]";
       else if ("object" == typeof e) {
+          if (e['_type'] && (e['_type'].value === 'real' || e['_type'].value === 'int')) {
+            e._value = e._value.toNumber();
+          }
           var a = Object.keys(e).length;
           if (a > 0) {
               s += '{<ul class="json-dict">';

+ 1 - 45
js/processor/definedFunctions.js

@@ -1,49 +1,5 @@
-import * as Commands from './../ast/commands';
-import {Types, toInt, toString, toBool} from './../ast/types';
 import { LanguageService } from '../services/languageService';
-import { StoreObject } from './store/storeObject';
-
-function createOutputFun () {
-  const writeFunction = function (store, _) {
-    const val = store.applyStore('p1');
-    this.output.sendOutput(''+val.value);
-    return Promise.resolve(store);
-  }
-  const block = new Commands.CommandBlock([], [new Commands.SysCall(writeFunction)]);
-  const func = new Commands.Function('$write', Types.VOID,
-    [new Commands.FormalParameter(Types.ALL, 'p1', 0, false)],
-    block);
-  return func;
-}
-
-function createInputFun () {
-  const readFunction = function (store, _) {
-    const request = new Promise((resolve, _) => {
-      this.input.requestInput(resolve);
-    });
-    return request.then(text => {
-      const typeToConvert = store.applyStore('p1').type;
-      let stoObj = null;
-      if (typeToConvert === Types.INTEGER) {
-        const val = toInt(text);
-        stoObj = new StoreObject(Types.INTEGER, val);
-      } else if (typeToConvert === Types.REAL) {
-        stoObj = new StoreObject(Types.REAL, parseFloat(text));
-      } else if (typeToConvert === Types.BOOLEAN) {
-        stoObj = new StoreObject(Types.BOOLEAN, toBool(text));
-      } else if (typeToConvert === Types.STRING) {
-        stoObj = new StoreObject(Types.STRING, toString(text));
-      }
-      store.updateStore('p1', stoObj);
-      return Promise.resolve(store);
-    });
-  }
-  const block = new Commands.CommandBlock([],  [new Commands.SysCall(readFunction)]);
-  const func = new Commands.Function('$read', Types.VOID,
-    [new Commands.FormalParameter(Types.ALL, 'p1', 0, true)],
-    block);
-  return func;
-}
+import {createInputFun, createOutputFun} from './lib/io';
 
 function valueToKey (value, object) {
   for (const key in object) {

+ 36 - 26
js/processor/ivprogProcessor.js

@@ -4,7 +4,7 @@ import { StoreObjectArray } from './store/storeObjectArray';
 import { StoreObjectRef } from './store/storeObjectRef';
 import { Modes } from './modes';
 import { Context } from './context';
-import { Types, toInt } from './../ast/types';
+import { Types } from './../ast/types';
 import { Operators } from './../ast/operators';
 import { LanguageDefinedFunction } from './definedFunctions';
 import { resultTypeAfterInfixOp, resultTypeAfterUnaryOp } from './compatibilityTable';
@@ -460,7 +460,7 @@ export class IVProgProcessor {
             //SHOULD NOT BE HERE. IT MUST HAVE A SEMANTIC ANALYSIS
             return Promise.reject(new Error("Array dimension must be of type int"));
           }
-          const line = lineSO.value;
+          const line = lineSO.number;
           const columnSO = values[1];
           let column = null
           if (columnSO !== null) {
@@ -469,7 +469,7 @@ export class IVProgProcessor {
               //SHOULD NOT BE HERE. IT MUST HAVE A SEMANTIC ANALYSIS
               return Promise.reject(new Error("Array dimension must be of type int"));
             }
-            column = columnSO.value;
+            column = columnSO.number;
           }
           const value = values[2];
           const temp = new StoreObjectArray(cmd.subtype, line, column, null, cmd.isConst);
@@ -603,7 +603,7 @@ export class IVProgProcessor {
         //SHOULD NOT BE HERE. IT MUST HAVE A SEMANTIC ANALYSIS
         return Promise.reject(new Error("Array dimension must be of type int"));
       }
-      const line = lineSO.value;
+      const line = lineSO.number;
       let column = null;
       if(columnSO !== null) {
         if(columnSO.type !== Types.INTEGER) {
@@ -611,7 +611,7 @@ export class IVProgProcessor {
           //SHOULD NOT BE HERE. IT MUST HAVE A SEMANTIC ANALYSIS
           return Promise.reject(new Error("Array dimension must be of type int"));
         }
-        column = columnSO.value;
+        column = columnSO.number;
       }
 
       if (line >= mustBeArray.lines) {
@@ -645,9 +645,9 @@ export class IVProgProcessor {
       }
       switch (unaryApp.op.ord) {
         case Operators.ADD.ord:
-          return new StoreObject(resultType, +left.value);
+          return new StoreObject(resultType, left.value);
         case Operators.SUB.ord:
-          return new StoreObject(resultType, -left.value);
+          return new StoreObject(resultType, left.value.negated());
         case Operators.NOT.ord:
           return new StoreObject(resultType, !left.value);
         default:
@@ -665,33 +665,31 @@ export class IVProgProcessor {
       const resultType = resultTypeAfterInfixOp(infixApp.op, left.type, right.type);
       if (resultType === Types.UNDEFINED) {
         // TODO: better urgent error message
-        return Promise.reject(new Error(`Cannot use this op to ${left.type} and ${right.type}`));
+        return Promise.reject(new Error(`Cannot use this ${infixApp.op.value} to ${left.type.value} and ${right.type.value}`));
       }
       let result = null;
       switch (infixApp.op.ord) {
         case Operators.ADD.ord:
-          return new StoreObject(resultType, left.value + right.value);
+          return new StoreObject(resultType, left.value.plus(right.value));
         case Operators.SUB.ord:
-          return new StoreObject(resultType, left.value - right.value);
-        case Operators.MULT.ord: {
-          result = left.value * right.value;
-          if (resultType === Types.INTEGER)
-            result = Math.trunc(result);
-          return new StoreObject(resultType, result);
-        }
+          return new StoreObject(resultType, left.value.minus(right.value));
+        case Operators.MULT.ord:
+          return new StoreObject(resultType, left.value.times(right.value));
         case Operators.DIV.ord: {
           result = left.value / right.value;
           if (resultType === Types.INTEGER)
-            result = Math.trunc(result);
+            result = left.value.idiv(right.value);
+          else
+            result = left.value.div(right.value);
           return new StoreObject(resultType, result);
         }
         case Operators.MOD.ord:
-          return new StoreObject(resultType, left.value % right.value);
+          return new StoreObject(resultType, left.value.modulo(right.value));
         case Operators.GT.ord: {
           if (left.type === Types.STRING) {
             result = left.value.length > right.value.length;
           } else {
-            result = left.value > right.value;
+            result = left.value.gt(right.value);
           }
           return new StoreObject(resultType, result);
         }
@@ -699,7 +697,7 @@ export class IVProgProcessor {
           if (left.type === Types.STRING) {
             result = left.value.length >= right.value.length;
           } else {
-            result = left.value >= right.value;
+            result = left.value.gte(right.value);
           }
           return new StoreObject(resultType, result);
         }
@@ -707,7 +705,7 @@ export class IVProgProcessor {
           if (left.type === Types.STRING) {
             result = left.value.length < right.value.length;
           } else {
-            result = left.value < right.value;
+            result = left.value.lt(right.value);
           }
           return new StoreObject(resultType, result);
         }
@@ -715,14 +713,26 @@ export class IVProgProcessor {
           if (left.type === Types.STRING) {
             result = left.value.length <= right.value.length;
           } else {
-            result = left.value <= right.value;
+            result = left.value.lte(right.value);
+          }
+          return new StoreObject(resultType, result);
+        }
+        case Operators.EQ.ord: {
+          if (left.type === Types.INTEGER || left.type === Types.REAL) {
+            result = left.value.eq(right.value);
+          } else {
+            result = left.value === right.value;
+          }
+          return new StoreObject(resultType, result);
+        }
+        case Operators.NEQ.ord: {
+          if (left.type === Types.INTEGER || left.type === Types.REAL) {
+            result = !left.value.eq(right.value);
+          } else {
+            result = left.value !== right.value;
           }
           return new StoreObject(resultType, result);
         }
-        case Operators.EQ.ord:
-          return new StoreObject(resultType, left.value === right.value);
-        case Operators.NEQ.ord:
-          return new StoreObject(resultType, left.value !== right.value);
         case Operators.AND.ord:
           return new StoreObject(resultType, left.value && right.value);
         case Operators.OR.ord:

+ 52 - 0
js/processor/lib/arrays.js

@@ -0,0 +1,52 @@
+import { StoreObject } from '../store/storeObject';
+import * as Commands from './../../ast/commands';
+import { Types } from './../../ast/types';
+
+/**
+ * num_elements
+ * matrix_lines
+ * matrix_columns
+ */
+
+export function createNumElementsFun () {
+  const numElementsFun = (sto, _) => {
+    const vector  = sto.applyStore("vector");
+    const temp = new StoreObject(Types.INTEGER, vector.lines);
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(numElementsFun)]);
+  const func = new Commands.Function('$numElements', Types.INTEGER,
+    [new Commands.FormalParameter(Types.ALL, 'vector', 1, false)],
+    block);
+  return func;
+ }
+
+export function createMatrixLinesFun () {
+  const matrixLinesFun = (sto, _) => {
+    const matrix  = sto.applyStore("matrix");
+    const temp = new StoreObject(Types.INTEGER, matrix.lines);
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(matrixLinesFun)]);
+  const func = new Commands.Function('$matrixLines', Types.INTEGER,
+    [new Commands.FormalParameter(Types.ALL, 'matrix', 2, false)],
+    block);
+  return func;
+ }
+
+export function createMatrixColumnsFun () {
+  const matrixColumnsFun = (sto, _) => {
+    const matrix  = sto.applyStore("matrix");
+    const temp = new StoreObject(Types.INTEGER, matrix.columns);
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(matrixColumnsFun)]);
+  const func = new Commands.Function('$matrixColumns', Types.INTEGER,
+    [new Commands.FormalParameter(Types.ALL, 'matrix', 2, false)],
+    block);
+  return func;
+ }
+ 

+ 55 - 0
js/processor/lib/io.js

@@ -0,0 +1,55 @@
+import { StoreObject } from './../store/storeObject';
+import * as Commands from './../../ast/commands';
+import {Types, toInt, toString, toBool, toReal} from './../../ast/types';
+
+export function createOutputFun () {
+  const writeFunction = function (store, _) {
+    const val = store.applyStore('p1');
+    if(val.type === Types.INTEGER) {
+      this.output.sendOutput(val.value.toString());
+    } else if (val.type === Types.REAL) {
+      if (val.value.dp() <= 0) {
+        this.output.sendOutput(val.value.toFixed(1));  
+      } else {
+        this.output.sendOutput(val.value.toString());
+      }
+    } else {
+      this.output.sendOutput(val.value);
+    }
+    return Promise.resolve(store);
+  }
+  const block = new Commands.CommandBlock([], [new Commands.SysCall(writeFunction)]);
+  const func = new Commands.Function('$write', Types.VOID,
+    [new Commands.FormalParameter(Types.ALL, 'p1', 0, false)],
+    block);
+  return func;
+}
+
+export function createInputFun () {
+  const readFunction = function (store, _) {
+    const request = new Promise((resolve, _) => {
+      this.input.requestInput(resolve);
+    });
+    return request.then(text => {
+      const typeToConvert = store.applyStore('p1').type;
+      let stoObj = null;
+      if (typeToConvert === Types.INTEGER) {
+        const val = toInt(text);
+        stoObj = new StoreObject(Types.INTEGER, val);
+      } else if (typeToConvert === Types.REAL) {
+        stoObj = new StoreObject(Types.REAL, toReal(text));
+      } else if (typeToConvert === Types.BOOLEAN) {
+        stoObj = new StoreObject(Types.BOOLEAN, toBool(text));
+      } else if (typeToConvert === Types.STRING) {
+        stoObj = new StoreObject(Types.STRING, toString(text));
+      }
+      store.updateStore('p1', stoObj);
+      return Promise.resolve(store);
+    });
+  }
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(readFunction)]);
+  const func = new Commands.Function('$read', Types.VOID,
+    [new Commands.FormalParameter(Types.ALL, 'p1', 0, true)],
+    block);
+  return func;
+}

+ 117 - 0
js/processor/lib/lang.js

@@ -0,0 +1,117 @@
+import { StoreObject } from '../store/storeObject';
+import * as Commands from './../../ast/commands';
+import { Types, toReal } from './../../ast/types';
+import { LanguageService } from '../../services/languageService';
+import { IVProgParser } from '../../ast/ivprogParser';
+import { RealLiteral, IntLiteral, BoolLiteral } from '../../ast/expressions';
+
+/**
+ * 
+ * is_real
+ * is_int
+ * is_bool
+ * cast_real
+ * cast_int
+ * cast_bool
+ * cast_string
+ */
+
+export function createIsRealFun () {
+  const isRealFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const lexer = LanguageService.getCurrentLexer();
+    const parser = new IVProgParser(str.value, lexer);
+    let result = false;
+    try {
+      const val = parser.parseTerm();
+      if (val instanceof RealLiteral) {
+        result = true;
+      }
+    } catch (error) { }
+    const temp = new StoreObject(Types.BOOLEAN, result);
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(isRealFun)]);
+  const func = new Commands.Function('$isReal', Types.BOOLEAN,
+    [new Commands.FormalParameter(Types.STRING, 'str', 0, false)],
+    block);
+  return func;
+}
+
+export function createIsIntFun () {
+  const isIntFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const lexer = LanguageService.getCurrentLexer();
+    const parser = new IVProgParser(str.value, lexer);
+    let result = false;
+    try {
+      const val = parser.parseTerm();
+      if (val instanceof IntLiteral) {
+        result = true;
+      }
+    } catch (error) { }
+    const temp = new StoreObject(Types.BOOLEAN, result);
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(isIntFun)]);
+  const func = new Commands.Function('$isInt', Types.BOOLEAN,
+    [new Commands.FormalParameter(Types.STRING, 'str', 0, false)],
+    block);
+  return func;
+}
+
+export function createIsBoolFun () {
+  const isBoolFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const lexer = LanguageService.getCurrentLexer();
+    const parser = new IVProgParser(str.value, lexer);
+    let result = false;
+    try {
+      const val = parser.parseTerm();
+      if (val instanceof BoolLiteral) {
+        result = true;
+      }
+    } catch (error) { }
+    const temp = new StoreObject(Types.BOOLEAN, result);
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(isBoolFun)]);
+  const func = new Commands.Function('$isBool', Types.BOOLEAN,
+    [new Commands.FormalParameter(Types.STRING, 'str', 0, false)],
+    block);
+  return func;
+}
+
+export function createCastRealFun () {
+  const castRealFun = (sto, _) => {
+    const val = sto.applyStore("val");
+    switch (val.type.ord) {
+      case Types.INTEGER.ord: {
+        const temp = new StoreObject(Types.REAL, toReal(val.value));
+        return Promise.resolve(sto.updateStore("$", temp));
+      }
+      case Types.STRING.ord: {
+        const lexer = LanguageService.getCurrentLexer();
+        const parser = new IVProgParser(val.value, lexer);
+        try {
+          const result = parser.parseTerm();
+          if (result instanceof RealLiteral) {
+            const temp = new StoreObject(Types.REAL, result.value);
+            return Promise.resolve(sto.updateStore("$", temp));
+          }
+        } catch (error) { 
+          return Promise.reject("cannot convert string to real");
+        }
+      }
+    }
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(castRealFun)]);
+  const func = new Commands.Function('$castReal', Types.REAL,
+    [new Commands.FormalParameter(Types.ALL, 'val', 0, false)],
+    block);
+  return func;
+}

+ 88 - 0
js/processor/lib/strings.js

@@ -0,0 +1,88 @@
+import { StoreObject } from '../store/storeObject';
+import * as Commands from './../../ast/commands';
+import { Types } from './../../ast/types';
+
+
+/*
+*  substring
+*  length
+*  uppercase
+*  lowercase
+*  letterAt
+**/
+
+export function createSubstringFun () {
+  const substringFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const start = sto.applyStore("start");
+    const end = sto.applyStore("end");
+    const result = str.value.substring(start.value, end.value);
+    const temp = new StoreObject(Types.STRING, result);
+    return Promise.resolve(sto.updateStore("$", temp));
+  };
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(substringFun)]);
+  const func = new Commands.Function('$substring', Types.STRING,
+    [new Commands.FormalParameter(Types.STRING, 'str', 0, false),
+    new Commands.FormalParameter(Types.INTEGER, 'start', 0, false),
+    new Commands.FormalParameter(Types.INTEGER, 'end', 0, false)],
+    block);
+  return func;
+}
+
+export function createLengthFun () {
+  const lengthFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const temp = new StoreObject(Types.INTEGER, str.value.length);
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(lengthFun)]);
+  const func = new Commands.Function('$length', Types.INTEGER,
+    [new Commands.FormalParameter(Types.STRING, 'str', 0, false)],
+    block);
+  return func;
+}
+
+export function createUppercaseFun () {
+  const uppercaseFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const temp = new StoreObject(Types.STRING, str.value.toUpperCase());
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(uppercaseFun)]);
+  const func = new Commands.Function('$uppercase', Types.STRING,
+    [new Commands.FormalParameter(Types.STRING, 'str', 0, false)],
+    block);
+  return func;
+}
+
+export function createLowercaseFun () {
+  const lowercaseFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const temp = new StoreObject(Types.STRING, str.value.toLowerCase());
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(lowercaseFun)]);
+  const func = new Commands.Function('$lowercase', Types.STRING,
+    [new Commands.FormalParameter(Types.STRING, 'str', 0, false)],
+    block);
+  return func;
+}
+
+export function createrCharAtFun () {
+  const charAtFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const idx = sto.applyStore("index");
+    if (idx.value < 0 || idx.value >= str.value.length) {
+      return Promise.reject(new Error("invalid string position"));
+    }
+    const temp = new StoreObject(Types.STRING, str.value.charAt(idx.value));
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(charAtFun)]);
+  const func = new Commands.Function('$charAt', Types.STRING,
+    [new Commands.FormalParameter(Types.STRING, 'str', 0, false),
+    new Commands.FormalParameter(Types.INTEGER, 'index', 0, false)],
+    block);
+  return func;
+}

+ 2 - 2
js/processor/semantic/semanticAnalyser.js

@@ -192,7 +192,7 @@ export class SemanticAnalyser {
         if (dimType !== Types.INTEGER) {
           throw new Error("dim must be int");
         }
-        if ((lines instanceof IntLiteral) && lines.value !== literal.value.length) {
+        if ((lines instanceof IntLiteral) && !lines.value.eq(literal.value.length)) {
           throw new Error("invalid array size");
         }
         literal.value.reduce((last, next) => {
@@ -208,7 +208,7 @@ export class SemanticAnalyser {
         if (dimType !== Types.INTEGER) {
           throw new Error("dim must be int");
         }
-        if ((columns instanceof IntLiteral) && columns.value !== literal.value.length) {
+        if ((columns instanceof IntLiteral) && !columns.value.eq(literal.value.length)) {
           throw new Error("invalid array size");
         }
         for (let i = 0; i < columns; i++) {

+ 9 - 0
js/processor/store/storeObject.js

@@ -1,3 +1,4 @@
+import { BigNumber } from 'bignumber.js'
 export class StoreObject {
 
   constructor (type, value, readOnly = false) {
@@ -26,6 +27,14 @@ export class StoreObject {
   get value () {
     return this._value;
   }
+  
+  get number () {
+    if (this._value instanceof BigNumber) {
+      return this._value.toNumber();
+    } else {
+      return null;
+    }
+  }
 
   get readOnly () {
     return this._readOnly;

+ 5 - 0
package-lock.json

@@ -1401,6 +1401,11 @@
       "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
       "dev": true
     },
+    "bignumber.js": {
+      "version": "7.2.1",
+      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz",
+      "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ=="
+    },
     "binary-extensions": {
       "version": "1.11.0",
       "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",

+ 1 - 0
package.json

@@ -44,6 +44,7 @@
   },
   "dependencies": {
     "antlr4": "^4.7.1",
+    "bignumber.js": "^7.2.1",
     "jquery": "^3.3.1"
   }
 }

+ 1 - 1
tests/test19.spec.js

@@ -18,7 +18,7 @@ describe('Multi(*) operation', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(8);
+      expect(sto.applyStore('a').number).toEqual(8);
       done();
     }).catch( err => done(err));
   });

+ 3 - 1
tests/test20.spec.js

@@ -19,7 +19,9 @@ describe('An Array initialization with expressions', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect([sto.applyStore('a').value[0].value,sto.applyStore('a').value[1].value]).toEqual(result);
+      expect([sto.applyStore('a').value[0].number,
+        sto.applyStore('a').value[1].number
+      ]).toEqual(result);
       done();
     });
   });

+ 1 - 1
tests/test21.spec.js

@@ -23,7 +23,7 @@ describe('A call to a function that returns a valid type', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(result);
+      expect(sto.applyStore('a').number).toEqual(result);
       done();
     }).catch(err => done(err));
   });

+ 1 - 1
tests/test24.spec.js

@@ -20,7 +20,7 @@ describe('Command Do...While', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(5);
+      expect(sto.applyStore('a').number).toEqual(5);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test25.spec.js

@@ -18,7 +18,7 @@ describe('Assigning an ID to another variable', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('b').value).toEqual(5);
+      expect(sto.applyStore('b').number).toEqual(5);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test27.spec.js

@@ -22,7 +22,7 @@ describe('A finite while loop', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(5);
+      expect(sto.applyStore('a').number).toEqual(5);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test28.spec.js

@@ -24,7 +24,7 @@ describe('A break command inside a inner while loop', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(5);
+      expect(sto.applyStore('a').number).toEqual(5);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test29.spec.js

@@ -20,7 +20,7 @@ describe('A break command inside a for loop', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(0);
+      expect(sto.applyStore('a').number).toEqual(0);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test30.spec.js

@@ -30,7 +30,7 @@ describe('A break command inside a switch..case', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(-5);
+      expect(sto.applyStore('a').number).toEqual(-5);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test31.spec.js

@@ -29,7 +29,7 @@ describe('A case without return/break', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(6);
+      expect(sto.applyStore('a').number).toEqual(6);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test33.spec.js

@@ -30,7 +30,7 @@ describe('A non-const global variable', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(13);
+      expect(sto.applyStore('a').number).toEqual(13);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test34.spec.js

@@ -23,7 +23,7 @@ describe('IfThenElse command ', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(10);
+      expect(sto.applyStore('a').number).toEqual(10);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test35.spec.js

@@ -27,7 +27,7 @@ describe('A recursive call', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(2);
+      expect(sto.applyStore('a').number).toEqual(2);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test37.spec.js

@@ -22,7 +22,7 @@ describe('The read function', function () {
     const exec = new IVProgProcessor(parser.parseTree());
     exec.registerInput(input);
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(255);
+      expect(sto.applyStore('a').number).toEqual(255);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test43.spec.js

@@ -24,7 +24,7 @@ describe('The sum of a real and a integer', function () {
     const exec = new IVProgProcessor(parser.parseTree());
     exec.registerInput(input);
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(5.8 + 0xff);
+      expect(sto.applyStore('a').number).toEqual(5.8 + 0xff);
       localStorage.removeItem('ivprog.lang');
       done();
     }).catch( err => done(err));