Browse Source

Implement array access and parameters as array refference (still missing assignment to an array position)

Move store values classes to the folder store/value

Implement a store value type to represent a value from an array in order to allow reading into a position in the array
Lucas de Souza 4 years ago
parent
commit
e07c633c0d

+ 17 - 2
.eslintrc.json

@@ -3,7 +3,9 @@
         "browser": true,
         "es6": true
     },
-    "extends": "eslint:recommended",
+    "parser": "@typescript-eslint/parser",
+    "plugins": ["@typescript-eslint"],
+    "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
     "globals": {
         "Atomics": "readonly",
         "SharedArrayBuffer": "readonly"
@@ -13,6 +15,19 @@
         "sourceType": "module"
     },
     "rules": {
-        "no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
+        "camelcase": "off",
+        "no-unused-vars": "off",
+        "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
+        "@typescript-eslint/camelcase": "off"
     }
+    ,
+    "overrides": [
+        {
+            "files": ["*.js", "*.jsx"],
+            "rules": {
+                "@typescript-eslint/explicit-member-accessibility": 0,
+                "@typescript-eslint/explicit-function-return-type": 0
+            }
+        }
+    ]    
 }

+ 3 - 3
js/memory/location.ts

@@ -18,7 +18,7 @@ class LocationHolder {
    */
   allocate (value:any) : number {
     const id = this.address_id;
-    // console.log("Allocation address "+ id);
+    console.log("Allocation address "+ id);
     const address = new Address(id, value);
     this.data.push(address);
     this.address_id += 1;
@@ -31,7 +31,7 @@ class LocationHolder {
    */
   deallocate (id: number) : boolean {
     const index = this.findIndex(id);
-    // console.log("Deallocation address "+ id);
+    console.log("Deallocation address "+ id);
     if(index !== -1) {
       this.data.splice(index, 1);
       return true;
@@ -47,7 +47,7 @@ class LocationHolder {
   find (id: number): Address | undefined {
     let beg = 0
     let end = this.data.length;
-    // console.log("Finding address "+id);
+    console.log("Finding address "+id);
     while (beg < end) {
       const med = Math.floor((beg + end)/2);
       const address = this.getAddressAt(med);

+ 159 - 175
js/processor/ivprogProcessor.js

@@ -1,5 +1,4 @@
 import { Store } from './store/store';
-import { StoreObject } from './store/storeObject';
 import { StoreObjectArray } from './store/storeObjectArray';
 import { Modes } from './modes';
 import { Context } from './context';
@@ -17,8 +16,11 @@ import { Config } from '../util/config';
 import { ProcessorErrorFactory } from './error/processorErrorFactory';
 import { RuntimeError } from './error/runtimeError';
 import { Location } from '../memory/location';
-import { StoreValue } from './store/store_value';
-import { StoreValueRef } from './store/store_value_ref';
+import { StoreValue } from './store/value/store_value';
+import { StoreValueRef } from './store/value/store_value_ref';
+import { ArrayStoreValue } from './store/value/array_store_value';
+import { ArrayStoreValueRef } from './store/value/array_store_value_ref';
+import { StoreValueAddress } from './store/value/store_value_address';
 
 export class IVProgProcessor {
 
@@ -126,7 +128,7 @@ export class IVProgProcessor {
 
   runFunction (func, actualParameters, store) {
     const funcName = func.isMain ? IVProgProcessor.MAIN_INTERNAL_ID : func.name;
-    let funcStore = new Store(funcName);
+    const funcStore = new Store(funcName);
     funcStore.extendStore(this.globalStore);
     let returnStoreObject = null;
     if(func.returnType instanceof ArrayType) {
@@ -153,53 +155,65 @@ export class IVProgProcessor {
     });
   }
 
-  associateParameters (formalList, actualList, callerStore, calleeStore) {
-    const funcName = calleeStore.name === IVProgProcessor.MAIN_INTERNAL_ID ? 
-      LanguageDefinedFunction.getMainFunctionName() : calleeStore.name;
+  associateParameters (formal_params, effective_params, caller_store, callee_store) {
+    const funcName = callee_store.name === IVProgProcessor.MAIN_INTERNAL_ID ? 
+      LanguageDefinedFunction.getMainFunctionName() : callee_store.name;
 
-    if (formalList.length != actualList.length) {
-      throw ProcessorErrorFactory.invalid_parameters_size(funcName, formalList.length, actualList.length);
+    if (formal_params.length != effective_params.length) {
+      throw ProcessorErrorFactory.invalid_parameters_size(funcName, formal_params.length, effective_params.length);
     }
-    const promises$ = actualList.map(actualParameter => this.evaluateExpression(callerStore, actualParameter));
+    const promises$ = effective_params.map(actual_param => this.evaluateExpression(caller_store, actual_param));
     return Promise.all(promises$).then(values => {
       for (let i = 0; i < values.length; i++) {
-        const stoObj = values[i];
-        // console.log(calleeStore.name);
-        // console.log(stoObj);
-        const exp = actualList[i];
+        const sto_value = values[i];
+        // console.log(callee_store.name);
+        // console.log(sto_value);
+        const exp = effective_params[i];
         let shouldTypeCast = false;
-        const formalParameter = formalList[i];
-        if(!formalParameter.type.isCompatible(stoObj.type)) {
+        const formalParameter = formal_params[i];
+        if(!formalParameter.type.isCompatible(sto_value.type)) {
           if (Config.enable_type_casting && !formalParameter.byRef
-            && Store.canImplicitTypeCast(formalParameter.type, stoObj.type)) {
+            && Store.canImplicitTypeCast(formalParameter.type, sto_value.type)) {
               shouldTypeCast =  true;
           } else {
             throw ProcessorErrorFactory.invalid_parameter_type(funcName, exp.toString());
           }
         }
 
-        if(formalParameter.byRef && !stoObj.inStore()) {
+        if(formalParameter.byRef && !sto_value.inStore()) {
           throw ProcessorErrorFactory.invalid_ref(funcName, exp.toString());
         }
 
         if(formalParameter.byRef) {
+          const realObj = caller_store.getStoreObject(sto_value.id);
           let ref = null;
-          if (stoObj instanceof StoreObjectArrayAddress) {
-            ref = new StoreObjectArrayAddressRef(callerStore.getStoreObject(stoObj.id));
+          if(sto_value instanceof ArrayStoreValue) {
+            // it's a vector or matrix...
+            const values = sto_value.get();
+            const array_type = sto_value.type;
+            const addresses = values.map( v => realObj.getLocAddressOf(v.line, v.column));
+            const columns = sto_value.isVector() ? 0 : sto_value.columns;
+            ref = new ArrayStoreValueRef(array_type, values, addresses, sto_value.lines, columns, realObj.id);
           } else {
-            const realObj = callerStore.getStoreObject(stoObj.id);
-            ref = new StoreValueRef(realObj.type, realObj.value, realObj.locAddress, realObj.id);
+            if(sto_value instanceof StoreValueAddress) {
+              const line = sto_value.line;
+              const column = sto_value.column;
+              ref = new StoreValueRef(sto_value.type, sto_value.get(),
+                realObj.getLocAddressOf(line, column), realObj.id);
+            } else {
+              ref = new StoreValueRef(sto_value.type, sto_value.get(), realObj.locAddress, realObj.id);
+            }
           }
-          calleeStore.insertStore(formalParameter.id, ref);
+          callee_store.insertStore(formalParameter.id, ref);
         } else {
-          let realValue = stoObj;
+          let realValue = sto_value;
           if (shouldTypeCast) {
             realValue = Store.doImplicitCasting(formalParameter.type, realValue);
           }
-          calleeStore.insertStore(formalParameter.id, realValue);
+          callee_store.insertStore(formalParameter.id, realValue);
         }
       }
-      return calleeStore;
+      return callee_store;
     });
   }
 
@@ -454,7 +468,7 @@ export class IVProgProcessor {
           const info = stringInfo[0];
           return Promise.reject(ProcessorErrorFactory.invalid_return_type_full(funcName, info.type, info.dim, cmd.sourceInfo));
         } else {
-          let realValue = this.parseStoreObjectValue(vl);
+          const realValue = this.parseStoreObjectValue(vl);
           store.updateStore('$', realValue);
           store.mode = Modes.RETURN;
           return Promise.resolve(store);
@@ -549,7 +563,7 @@ export class IVProgProcessor {
             const type = mustBeArray.type.innerType;
             const stringInfo = type.stringInfo();
             const info = stringInfo[0];
-            const exp = cmd.expression.toString();
+            // const exp = cmd.expression.toString();
             return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
           }
           actualValue = Store.doImplicitCasting(mustBeArray.type.innerType, value);
@@ -583,66 +597,14 @@ export class IVProgProcessor {
     try {
       let $value = Promise.resolve(null);
       if(cmd instanceof Commands.ArrayDeclaration) {
-        if(cmd.initial !== null) {
-          // array can only be initialized by a literal....
-          $value = this.evaluateArrayLiteral(store, cmd.initial, cmd.type);
-        }
-        const $lines = this.evaluateExpression(store, cmd.lines);
-        const $columns = cmd.columns === null ? null: this.evaluateExpression(store, cmd.columns);
-        return Promise.all([$lines, $columns, $value]).then(values => {
-          const lineSO = values[0];
-          if(!Types.INTEGER.isCompatible(lineSO.type)) {
-            return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
-          }
-          const line = lineSO.get();
-          if(line < 0) {
-            throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
-          }
-          const columnSO = values[1];
-          let column = null
-          if (columnSO !== null) {
-            if(!Types.INTEGER.isCompatible(columnSO.type)) {
-              return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
-            }
-            column = columnSO.get();
-            if(column < 0) {
-              throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
-            }
-          }
-          const value = values[2];
-          const temp = new StoreObjectArray(cmd.type, line, column, null);
-          store.insertStore(cmd.id, temp);
-          let realValue = value;
-          if (value !== null) {
-            if(value instanceof StoreObjectArrayAddress) {
-              if(value.type instanceof ArrayType) {
-                realValue = Object.assign(new StoreObjectArray(null,null,null), value.refValue);
-              } else {
-                // TODO - update StoObj
-                realValue = Object.assign(new StoreObject(null,null), value.refValue);
-              }
-            }
-          } else {
-            realValue = new StoreObjectArray(cmd.type, line, column, [])
-            if(column !== null) {
-              for (let i = 0; i < line; i++) {
-                realValue.value.push(new StoreObjectArray(new ArrayType(cmd.type.innerType, 1), column, null, []));
-              }
-            }
-          }
-          realValue.readOnly = cmd.isConst;
-          store.updateStore(cmd.id, realValue);
-          return store;
-        });
-        
+        return this.executeArrayDeclaration(store, cmd);
       } else {
         if(cmd.initial !== null) {
           $value = this.evaluateExpression(store, cmd.initial);
         }
-        const temp = new StoreValue(cmd.type, null);
-        store.insertStore(cmd.id, temp);
         return $value.then(vl => {
           let realValue = vl;
+          let temp = null;
           if (vl !== null) {
             if(!vl.type.isCompatible(cmd.type)) {
               if(Config.enable_type_casting && Store.canImplicitTypeCast(cmd.type, vl.type)) {
@@ -653,19 +615,11 @@ export class IVProgProcessor {
                 return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
               }
             }
-            if(vl instanceof StoreObjectArrayAddress) {
-              if(vl.type instanceof ArrayType) {
-                return Promise.reject(new Error("!!!Critical Error: Compatibility check failed, a Type accepts a ArrayType"))
-              } else {
-                // TODO - update StoObj
-                realValue = Object.assign(new StoreObject(null,null), vl.refValue);
-              }
-            }
+            temp = new StoreValue(cmd.type, realValue.get(), null, cmd.isConst);
           } else {
-            realValue = new StoreValue(cmd.type, 0);
+            temp = new StoreValue(cmd.type, null, null, cmd.isConst);
           }
-          realValue.isConst = cmd.isConst;
-          store.updateStore(cmd.id, realValue);
+          store.insertStore(cmd.id, temp);
           return store;
         });
       }
@@ -674,6 +628,50 @@ export class IVProgProcessor {
     }
   }
 
+  /**
+   * 
+   * @param {Store} store 
+   * @param {Commands.ArrayDeclaration} cmd 
+   */
+  executeArrayDeclaration (store, cmd) {
+    const $lines = this.evaluateExpression(store, cmd.lines);
+    const $columns = cmd.columns === null ? null: this.evaluateExpression(store, cmd.columns);
+    return Promise.all([$lines, $columns]).then(([line_sv, column_sv]) => {
+      if(!Types.INTEGER.isCompatible(line_sv.type)) {
+        return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
+      }
+      const line = line_sv.get().toNumber();
+      if(line < 0) {
+        throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
+      }
+      let column = null
+      if (column_sv !== null) {
+        if(!Types.INTEGER.isCompatible(column_sv.type)) {
+          return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
+        }
+        column = column_sv.get().toNumber();
+        if(column < 0) {
+          throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
+        }
+      }
+      let $value = Promise.resolve(null);
+      if(cmd.initial !== null) {
+        // array can only be initialized by a literal....
+        $value = this.evaluateArrayLiteral(store, cmd.initial, cmd.type, line, column);
+      }
+      return $value.then(vector_list => {
+        let temp = null;
+        if (vector_list !== null) {
+          temp = new ArrayStoreValue(cmd.type, vector_list, line, column, null, cmd.isConst);
+        } else {
+          temp = new ArrayStoreValue(cmd.type, [], line, column, null, cmd.isConst);
+        }
+        store.insertStore(cmd.id, temp);
+        return store;
+      })
+    });
+  }
+
   evaluateExpression (store, exp) {
     if (exp instanceof Expressions.UnaryApp) {
       return this.evaluateUnaryApp(store, exp);
@@ -728,57 +726,22 @@ export class IVProgProcessor {
    * @param {Expressions.ArrayLiteral} exp 
    * @param {ArrayType} type 
    */
-  evaluateArrayLiteral (store, exp, type) {
-    const errorHelperFunction = (validationResult, exp) => {
-      const errorCode = validationResult[0];
-      let expectedColumns = null;
-      let actualColumns = null;
-      switch(errorCode) {
-        case StoreObjectArray.WRONG_COLUMN_NUMBER: {
-          expectedColumns = validationResult[1];
-          actualColumns = validationResult[2];
-          return Promise.reject(ProcessorErrorFactory.invalid_array_literal_column_full(expectedColumns, actualColumns, exp.sourceInfo));
-        }
-        case StoreObjectArray.WRONG_LINE_NUMBER: {
-          const lineValue = validationResult[1];
-          return Promise.reject(ProcessorErrorFactory.invalid_array_literal_line_full(arr.lines, lineValue, exp.sourceInfo));
-        }
-        case StoreObjectArray.WRONG_TYPE: {
-          let line = null;
-          let strExp = null;
-          if (validationResult.length > 2) {
-            line = validationResult[1];
-            const column = validationResult[2];
-            strExp = exp.value[line].value[column].toString()
-          } else {
-            line = validationResult[1];
-            strExp = exp.value[line].toString()
-          }
-          // TODO - fix error message
-          return Promise.reject(ProcessorErrorFactory.invalid_array_literal_type_full(strExp, exp.sourceInfo));            }
-      }
-    };
+  evaluateArrayLiteral (store, exp, type, lines, columns) {
     if(!exp.isVector) {
-      const $matrix = this.evaluateMatrix(store, exp.value, type);
-      return $matrix.then(list => {
-        const arr = new StoreObjectArray(type, list.length, list[0].lines, list);
-        const checkResult = arr.isValid;
-        if(checkResult.length == 0)
-          return Promise.resolve(arr);
-        else {
-          return errorHelperFunction(checkResult, exp);
-        }
+      if(columns == null) {
+        throw new Error("Vector cannot be initialized by a matrix");
+      }
+      const $matrix = this.evaluateMatrix(store, exp, type, lines, columns);
+      return Promise.all($matrix).then(vectorList => {
+        const values = vectorList.reduce((prev, next) =>  prev.concat(next), []);
+        return Promise.resolve(values);
       });
     } else {
-      return this.evaluateVector(store, exp.value, type).then(list => {
-        const type = new ArrayType(list[0].type, 1);
-        const stoArray = new StoreObjectArray(type, list.length, null, list);
-        const checkResult = stoArray.isValid;
-        if(checkResult.length == 0)
-          return Promise.resolve(stoArray);
-        else {
-          return errorHelperFunction(checkResult, exp);
-        }
+      if(columns != null) {
+        throw new Error("Matrix cannot be initialized by a vector");
+      }
+      return this.evaluateVector(store, exp, type, lines).then(list => {
+        return Promise.resolve(list);
       });
     }
   }
@@ -786,21 +749,26 @@ export class IVProgProcessor {
   /**
    * Evalautes a list of literals and expression composing the vector
    * @param {Store} store 
-   * @param {Literal[]} exps 
+   * @param {Expressions.ArrayLiteral} exps 
    * @param {ArrayType} type
-   * @returns {Promise<StoreObject[]>} store object list
+   * @param {number} n_elements
+   * @returns {Promise<StoreValue[]>} store object list
    */
-  evaluateVector (store, exps, type) {
-    const actual_values = Promise.all(exps.map( exp => this.evaluateExpression(store, exp)));
+  evaluateVector (store, exps, type, n_elements) {
+    const values =  exps.value;
+    if(n_elements !== values.length) {
+      throw new Error("invalid number of elements to array literal...");
+    }
+    const actual_values = Promise.all(values.map( exp => this.evaluateExpression(store, exp)));
     return actual_values.then( values => {
       return values.map((v, index) => {
         if(!type.canAccept(v.type)) {
           if (!Config.enable_type_casting || !Store.canImplicitTypeCast(type.innerType, v.type)) {
-            const stringInfo = v.type.stringInfo();
-            const info = stringInfo[0];
-            const exp_str = exps[index].toString();
+            // const stringInfo = v.type.stringInfo();
+            // const info = stringInfo[0];
+            const exp_str = values[index].toString();
             // TODO - fix error message
-            throw ProcessorErrorFactory.invalid_array_literal_type_full(exp_str, exps[index].sourceInfo);
+            throw ProcessorErrorFactory.invalid_array_literal_type_full(exp_str, values[index].sourceInfo);
           }
           const new_value = Store.doImplicitCasting(type.innerType, v);
           return new_value;
@@ -813,17 +781,19 @@ export class IVProgProcessor {
   /**
    * Evaluates a list of array literals composing the matrix
    * @param {Store} store 
-   * @param {Expressions.ArrayLiteral[]} exps 
-   * @param {ArrayType} type 
+   * @param {Expressions.ArrayLiteral} exps 
+   * @param {ArrayType} type
+   * @returns {Promise<StoreValue[]>[]}
    */
-  evaluateMatrix (store, exps, type) {
-    return Promise.all(exps.map( vector => {
+  evaluateMatrix (store, exps, type, lines, columns) {
+    const values = exps.value;
+    if(values.length !== lines) {
+      throw new Error("Invalid number of lines to matrix literal...");
+    }
+    return values.map( vector => {
       const vec_type = new ArrayType(type.innerType, 1);
-      const $vector = this.evaluateVector(store, vector.value, vec_type);
-      return $vector.then(list => {
-        return new StoreObjectArray(vec_type, list.length, null, list)
-      });
-    } ));
+      return this.evaluateVector(store, vector, vec_type, columns);
+    });
   }
 
   evaluateLiteral (_, exp) {
@@ -833,36 +803,35 @@ export class IVProgProcessor {
   evaluateVariableLiteral (store, exp) {
     try {
       const val = store.applyStore(exp.id);
-      if (val instanceof StoreObjectArray) {
-        return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null), val));
-      } else {
-        return Promise.resolve(val);
-      }
+      return Promise.resolve(val);
+      // if (val instanceof StoreObjectArray) {
+      //   return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null), val));
+      // } else {
+      //   return Promise.resolve(val);
+      // }
     } catch (error) {
       return Promise.reject(error);
     }
   }
 
   evaluateArrayAccess (store, exp) {
-    const mustBeArray = store.applyStore(exp.id);
+    const mustBeArray = store.getStoreObject(exp.id);
     if (!(mustBeArray.type instanceof ArrayType)) {
       return Promise.reject(ProcessorErrorFactory.invalid_array_access_full(exp.id, exp.sourceInfo));
     }
     const $line = this.evaluateExpression(store, exp.line);
     const $column = this.evaluateExpression(store, exp.column);
-    return Promise.all([$line, $column]).then(values => {
-      const lineSO = values[0];
-      const columnSO = values[1];
-      if(!Types.INTEGER.isCompatible(lineSO.type)) {
+    return Promise.all([$line, $column]).then(([line_sv, column_sv]) => {
+      if(!Types.INTEGER.isCompatible(line_sv.type)) {
         return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
       }
-      const line = lineSO.get();
+      const line = line_sv.get().toNumber();
       let column = null;
-      if(columnSO !== null) {
-        if(!Types.INTEGER.isCompatible(columnSO.type)) {
+      if(column_sv !== null) {
+        if(!Types.INTEGER.isCompatible(column_sv.type)) {
           return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
         }
-        column = columnSO.get();
+        column = column_sv.get().toNumber();
       }
 
       if (line >= mustBeArray.lines) {
@@ -874,7 +843,7 @@ export class IVProgProcessor {
       } else if (line < 0) {
         throw ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo);
       }
-      if (column !== null && mustBeArray.columns === null ){
+      if (column !== null && mustBeArray.columns === 0 ){
         return Promise.reject(ProcessorErrorFactory.vector_not_matrix_full(exp.id, exp.sourceInfo));
       }
       if(column !== null ) {
@@ -883,9 +852,24 @@ export class IVProgProcessor {
         } else if (column < 0) {
           throw ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo);
         }
-        
       }
-      return Promise.resolve(new StoreObjectArrayAddress(mustBeArray.id, line, column, store));
+      const result = mustBeArray.getAt(line, column);
+      const type = mustBeArray.type.innerType;
+      if(Array.isArray(result)) {
+        let l = 0;
+        const values = result.map(v => {
+          if(!Array.isArray(v)) {
+            return new StoreValueAddress(type.innerType, v, l++, undefined, mustBeArray.id, mustBeArray.readOnly);  
+          } else {
+            throw new Error("Indexing 3D structure....");
+          }
+        });
+        return Promise.resolve(new ArrayStoreValue(new ArrayType(type, 1),
+          values, mustBeArray.columns, null, mustBeArray.id, mustBeArray.readOnly))
+      } else {
+        return Promise.resolve(new StoreValueAddress(type, result, line, column, mustBeArray.id, mustBeArray.readOnly));
+      }
+      //return Promise.resolve(mustBeArray.getAt(line, column));
     });
   }
 

+ 2 - 3
js/processor/lib/io.js

@@ -1,11 +1,10 @@
-import { StoreObject } from './../store/storeObject';
 import * as Commands from './../../ast/commands';
 import { Modes } from '../modes';
 import {toInt, toString, toBool, toReal, convertToString} from './../../typeSystem/parsers';
 import { Types } from './../../typeSystem/types';
 import { ProcessorErrorFactory } from "./../error/processorErrorFactory";
 import { StoreObjectArrayAddressRef } from '../store/storeObjectArrayAddressRef';
-import { StoreValue } from '../store/store_value';
+import { StoreValue } from '../store/value/store_value';
 
 export function createOutputFun () {
   const writeFunction = function (store, _) {
@@ -46,7 +45,7 @@ export function createInputFun () {
         } else {
           return Promise.reject(new Error("!!!!Critical error: Unknown type in readFunction!!!!"));
         }
-      } catch (_) {StoreObject
+      } catch (_) {
         const stringInfo = typeToConvert.stringInfo()[0]
         const realObject = store.getStoreObject("p1");
         if (realObject instanceof StoreObjectArrayAddressRef) {

+ 0 - 39
js/processor/store/array_store_value.ts

@@ -1,39 +0,0 @@
-import { IStoreValue } from "./istore_value";
-import { Type } from "../../typeSystem/type";
-
-export class ArrayStoreValue implements IStoreValue {
-
-  public type: Type; 
-  public id?: String;
-  public isConst: boolean;
-  public lines: number;
-  public columns: number;
-  public values: any[];
-
-  constructor(type: Type, values: any[], lines: number, columns: number, id?: String, isConst = false) {
-    this.type = type;
-    this.id = id;
-    this.isConst = isConst
-    this.values = values;
-    this.lines = lines;
-    this.columns = columns;
-  }
-
-  get (): any[] {
-    return this.values;
-  }
-
-  getAt (line: number, column = 0): any {
-    const pos = column * this.lines + line;
-    return this.values[pos];
-  }
-
-  setAt (value: any, line:number, column = 0): any {
-    const pos = column * this.lines + line;
-    this.values[pos] = value;
-  }
-
-  inStore () {
-    return this.id != null;
-  }
-}

+ 43 - 7
js/processor/store/store.ts

@@ -4,11 +4,15 @@ import { StoreObject } from './storeObject';
 import { IType } from '../../typeSystem/itype';
 import { StoreObjectRef } from './storeObjectRef';
 import { ArrayType } from '../../typeSystem/array_type';
-import { ArrayStoreValue } from './array_store_value';
-import { IStoreValue } from './istore_value';
-import { StoreValue } from './store_value';
+import { ArrayStoreValue } from './value/array_store_value';
 import { Location } from '../../memory/location';
-import { StoreValueRef } from './store_value_ref';
+import { StoreObjectArray } from './storeObjectArray';
+import { IStoreValue } from './value/istore_value';
+import { StoreValue } from './value/store_value';
+import { StoreValueAddress } from './value/store_value_address';
+import { StoreValueRef } from './value/store_value_ref';
+import { ArrayStoreValueRef } from './value/array_store_value_ref';
+import { StoreObjectArrayRef } from './store_object_array_ref';
 
 export class Store {
 
@@ -56,7 +60,21 @@ export class Store {
     const val = this.store.get(id)!;
     let result = null
     if (val.type instanceof ArrayType) {
-      result = new ArrayStoreValue(val.type, val.value, 0, 0, val.id, val.readOnly);
+      const array = val as StoreObjectArray;
+      const array_type = array.type as ArrayType;
+      let l = 0, c = 0;
+      const values = array.value.map( v => {
+        if(array.isVector) {
+          return new StoreValueAddress(array_type.innerType, v, l++, undefined, array.id, array.readOnly);  
+        } else {
+          if(c >= array.columns) {
+            c = 0;
+            l += 1;
+          }
+          return new StoreValueAddress(array_type.innerType, v, l, c++, array.id, array.readOnly);  
+        }
+      });
+      result = new ArrayStoreValue(array_type, values, array.lines, array.columns, val.id, val.readOnly);
     } else {
       result = new StoreValue(val.type, val.value, val.id, val.readOnly);
     }
@@ -114,8 +132,26 @@ export class Store {
     // TODO check for array....
     let newObj:StoreObject;
     if(stoValue instanceof StoreValueRef) {
-      // TODO check for array....
-      newObj = new StoreObjectRef(stoValue, stoValue.getRefAddress());
+      newObj = new StoreObjectRef(stoValue);
+    } else if (stoValue instanceof ArrayStoreValueRef) {
+      newObj = new StoreObjectArrayRef(stoValue);
+    } else if (stoValue instanceof ArrayStoreValue) {
+      const columns = stoValue.isVector() ? 0 : stoValue.columns!;
+      const addresses: number[] = [];
+      const all_values = stoValue.get();
+      if(all_values.length > 0) {
+        for(let i = 0; i < stoValue.get().length; i += 1) {
+          const val = all_values[i].get();
+          addresses.push(Location.allocate(val));
+        }
+      } else {
+        let total = stoValue.lines;
+        total = stoValue.isVector() ? total : total * columns;
+        for(let i = 0; i < total; i += 1) {
+          addresses.push(Location.allocate(null));
+        }
+      }
+      newObj = new StoreObjectArray(stoValue.type as ArrayType, stoValue.lines, columns, addresses, stoValue.isConst);
     } else {
       const loc_address = Location.allocate(stoValue.get());
       newObj = new StoreObject(stoValue.type, loc_address, stoValue.isConst);

+ 4 - 5
js/processor/store/storeObject.ts

@@ -1,10 +1,10 @@
 import { Location } from "../../memory/location";
-import { Type } from '../../typeSystem/type';
-import { IStoreValue } from "./istore_value";
+import { IType } from "../../typeSystem/itype";
+import { IStoreValue } from "./value/istore_value";
 
 export class StoreObject {
 
-  private _type: Type;
+  private _type: IType;
   private _loc_address: number;
   private _readOnly: boolean;
   private _id?: String;
@@ -15,7 +15,7 @@ export class StoreObject {
    * @param {Number} loc_address 
    * @param {Boolean} readOnly 
    */
-  constructor (type: Type, loc_address: number, readOnly = false) {
+  constructor (type: IType, loc_address: number, readOnly = false) {
     this._loc_address = loc_address;
     this._type = type;
     this._readOnly = readOnly;
@@ -24,7 +24,6 @@ export class StoreObject {
 
   setID (id: String) {
     this._id = id;
-    Location.updateAddress(this._loc_address, this.value);
   }
 
   get id () {

+ 0 - 77
js/processor/store/storeObjectArray.js

@@ -1,77 +0,0 @@
-import { StoreObject } from './storeObject';
-
-export class StoreObjectArray extends StoreObject {
-
-  static get WRONG_LINE_NUMBER () {
-    return 1;
-  }
-
-  static get WRONG_TYPE () {
-    return 2;
-  }
-
-  static get WRONG_COLUMN_NUMBER () {
-    return 3;
-  }
-
-  constructor (type, lines, columns, value = null, readOnly = false) {
-    super(type, value, readOnly);
-    this._lines = lines;
-    this._columns = columns;
-  }
-
-  get lines () {
-    return this._lines;
-  }
-
-  get columns () {
-    return this._columns;
-  }
-
-  isCompatible (another) {
-    if(another instanceof StoreObjectArray) {
-      if((this.isVector && another.isVector) ||
-        (!this.isVector && !another.isVector)) {
-          return super.isCompatible(another);
-      }
-    }
-    return false;
-  }
-
-  get isVector () {
-    return this.type.dimensions === 1;
-  }
-
-  get isValid () {
-    if (this.value !== null) {
-      if( this.isVector) {
-        if(this.value.length !== this.lines) {
-          return [StoreObjectArray.WRONG_LINE_NUMBER, this.value.length];
-        }
-        // const mustBeNull = this.value.find(v => !this.type.canAccept(v.type) );
-        // if(!!mustBeNull) {
-        //   return [StoreObjectArray.WRONG_TYPE, this.value.indexOf(mustBeNull)];;
-        // }
-        return [];
-      } else if(this.lines !== this.value.length) {
-        return [StoreObjectArray.WRONG_LINE_NUMBER, this.value.length];
-      }
-      for (let i = 0; i < this.lines; i += 1) {
-        const thisRef = this;
-        const arrayObject = this.value[i];
-        if(arrayObject.lines !== this.columns) {
-          return [StoreObjectArray.WRONG_COLUMN_NUMBER, this.columns, arrayObject.lines];
-        }
-        // const mustBeNull = arrayObject.value.find(v => !arrayObject.type.canAccept(v.type) );
-        // if(!!mustBeNull) {
-        //   console.log(mustBeNull);
-        //   console.log(thisRef.type.canAccept(mustBeNull));
-        //   console.log(thisRef.type);
-        //   return [StoreObjectArray.WRONG_TYPE, i, arrayObject.value.indexOf(mustBeNull)];
-        // }
-      }
-    } 
-    return [];
-  }
-
-}

+ 130 - 0
js/processor/store/storeObjectArray.ts

@@ -0,0 +1,130 @@
+import { StoreObject } from './storeObject';
+import { ArrayType } from '../../typeSystem/array_type';
+import { ArrayStoreValue } from './value/array_store_value';
+import { Location } from "../../memory/location";
+import { IStoreValue } from './value/istore_value';
+
+export class StoreObjectArray extends StoreObject {
+
+  static get WRONG_LINE_NUMBER () {
+    return 1;
+  }
+
+  static get WRONG_TYPE () {
+    return 2;
+  }
+
+  static get WRONG_COLUMN_NUMBER () {
+    return 3;
+  }
+
+  constructor (type: ArrayType, public lines:number, public columns:number, private addresses:number[], readOnly = false) {
+    super(type, -1, readOnly);
+
+  }
+
+  isCompatible (another: IStoreValue): boolean {
+    if(another instanceof ArrayStoreValue) {
+      if((this.isVector && another.isVector) ||
+        (!this.isVector && !another.isVector)) {
+          return super.isCompatible(another);
+      }
+    }
+    return false;
+  }
+
+  get isVector () {
+    return (this.type as ArrayType).dimensions === 1;
+  }
+  /**@override 
+     * Returns the list of values stored by this array.
+     * All returned values are compatible with @prop{StoreObject.type}
+    */
+  get value () {
+    const values = [];
+    for(let i = 0; i < this.addresses.length; i += 1) {
+      const address = Location.find(this.addresses[i]);
+      if (address != null) {
+        values.push(address.value);
+      } else {
+        throw new Error("!!!Critical Error: variable "+this.id+" does not have a valid address. Loc-Address "+ this.locAddress);
+      }
+    }
+    return values;
+  }
+
+  destroy () {
+    let bool =  true;
+    for(let i = 0; i < this.addresses.length; i += 1) {
+      bool = bool && Location.deallocate(this.addresses[i]);
+    }
+    return bool;
+  }
+
+  get locAddress (): number {
+    throw new Error("!!!Internal Error: Cannot access locAddress property of StoreObjectArray");
+  }
+
+  getAt (line: number, column?: number): any {
+    if(this.isVector) {
+      if(column != null) {
+        throw new Error(this.id + " is not a matrix!");
+      }
+      column = line;
+      line = 0;
+    } else if (column == null) {
+      // this is a whole line...
+      const values = [];
+      for(let col = 0; col < this.columns; col += 1) {
+        const index = this.getIndexOf(line, col);
+        const address = Location.find(this.addresses[index])!;
+        values.push(address.value);
+      }
+      return values;
+    }
+    const index = this.getIndexOf(line, column);
+    const address = Location.find(this.addresses[index])!;
+    return address.value;
+  }
+
+  setAt (value: any, line:number, column?: number): void {
+    if(!(this.type as ArrayType).canAccept(value.type)) {
+      throw new Error("!!!Internal Error: Attempting to insert an invalid value inside array "+this.id);
+    }
+    if(this.isVector) {
+      if(column != null) {
+        throw new Error(this.id + " is not a matrix!");
+      }
+      column = line;
+      line = 0;
+    } else if (column == null) {
+      throw new Error("!!!Internal Error: Attempting to insert a line into matrix "+ this.id );
+    }
+    const pos = this.getIndexOf(line, column);
+    Location.updateAddress(this.addresses[pos], value);
+  }
+
+  private getIndexOf (line: number, column: number): number {
+    return line * this.lines + column;
+  }
+
+  getLocAddressOf (line: number, column?: number): number | number[] {
+    if(this.isVector) {
+      if(column != null) {
+        throw new Error(this.id + " is not a matrix!");
+      }
+      column = line;
+      line = 0;
+    } else if (column == null) {
+      // this is a whole line...
+      const values: number[] = [];
+      for(let col = 0; col < this.columns; col += 1) {
+        const index = this.getIndexOf(line, col);
+        values.push(this.addresses[index]);
+      }
+      return values;
+    }
+    const index = this.getIndexOf(line, column);
+    return this.addresses[index];
+  }
+}

+ 3 - 4
js/processor/store/storeObjectRef.ts

@@ -1,6 +1,5 @@
 import { StoreObject } from './storeObject';
-import { Location } from '../../memory/location';
-import { IStoreValue } from './istore_value';
+import { StoreValueRef } from './value/store_value_ref';
 
 export class StoreObjectRef extends StoreObject {
 
@@ -10,8 +9,8 @@ export class StoreObjectRef extends StoreObject {
    * 
    * @param {StoreObject} stoValue 
    */
-  constructor (stoValue: IStoreValue, loc_address: number) {
-    super(stoValue.type, loc_address, false);
+  constructor (stoValue: StoreValueRef) {
+    super(stoValue.type, stoValue.getRefAddress(), false);
     this.refObj = stoValue.id!;
   }
 

+ 24 - 0
js/processor/store/store_object_array_ref.ts

@@ -0,0 +1,24 @@
+import { StoreObjectArray } from "./storeObjectArray";
+import { ArrayStoreValueRef } from "./value/array_store_value_ref";
+
+export class StoreObjectArrayRef extends StoreObjectArray {
+
+  private refObj: String;
+
+  constructor(stoValue: ArrayStoreValueRef) {
+    super(stoValue.type, stoValue.lines, stoValue.columns, stoValue.getRefAddresses(), false);
+    this.refObj = stoValue.id;
+  }
+
+  get isRef () {
+    return true;
+  }
+
+  getRefObj (): String {
+    return this.refObj;
+  }
+
+  destroy () {
+    return false;
+  }
+}

+ 88 - 0
js/processor/store/value/array_store_value.ts

@@ -0,0 +1,88 @@
+import { IStoreValue } from "./istore_value";
+import { ArrayType } from "../../../typeSystem/array_type";
+import { IType } from "../../../typeSystem/itype";
+import { Type } from "../../../typeSystem/type";
+import { StoreValueAddress } from "./store_value_address";
+
+export class ArrayStoreValue implements IStoreValue {
+
+  public type: IType; 
+  public id?: String;
+  public isConst: boolean;
+  public lines: number;
+  public columns?: number;
+  public values: StoreValueAddress[];
+
+  constructor(type: ArrayType, values: StoreValueAddress[], lines: number, columns?: number, id?: String, isConst = false) {
+    this.type = type;
+    this.id = id;
+    this.isConst = isConst
+    this.values = values;
+    this.lines = lines;
+    this.columns = columns;
+  }
+
+  get (): StoreValueAddress[] {
+    return this.values;
+  }
+
+  /**
+   * @deprecated
+   * Potential not necessary since array access is occuring directly in the StoreObject
+   * @param line 
+   * @param column 
+   */
+  getAt (line: number, column?: number): IStoreValue {
+    if(this.isVector) {
+      if(column != null) {
+        throw new Error(this.id + " is not a matrix!");
+      }
+      column = line;
+      line = 0;
+    } else if (column == null) {
+      const values: StoreValueAddress[] = [];
+      for(let col = 0; col < this.columns!; col += 1) {
+        const index = line * this.lines + col;
+        values.push(this.values[index]);
+      }
+      const array_type = this.type as ArrayType
+      const vector_type = new ArrayType(array_type.innerType as Type, array_type.dimensions - 1);
+      return new ArrayStoreValue(vector_type, values, this.columns!, undefined, this.id, this.isConst);
+    }
+    const index = line * this.lines + column;
+    console.log("Get at: ",index);
+    return this.values[index];
+  }
+
+  /**
+   * @deprecated
+   * Potential not necessary since array access is occuring directly in the StoreObject
+   * @param line 
+   * @param column 
+   */
+  setAt (value: IStoreValue, line:number, column?: number): void {
+    if(!(this.type as ArrayType).canAccept(value.type)) {
+      throw new Error("!!!Internal Error: Attempting to insert an invalid value inside array "+this.id);
+    }
+    if(this.isVector) {
+      if(column != null) {
+        throw new Error(this.id + " is not a matrix!");
+      }
+      column = line;
+      line = 0;
+    } else if (column == null) {
+      throw new Error("!!!Internal Error: Attempting to insert line into matrix "+ this.id );
+    }
+    const pos = line * this.lines + column;
+    // TODO - fix this casting
+    this.values[pos] = value as StoreValueAddress;
+  }
+
+  inStore () {
+    return this.id != null;
+  }
+
+  isVector (): boolean {
+    return (this.type as ArrayType).dimensions == 1;
+  }
+}

+ 23 - 0
js/processor/store/value/array_store_value_ref.ts

@@ -0,0 +1,23 @@
+import { IStoreValue } from "./istore_value";
+import { StoreValueAddress } from "./store_value_address";
+import { ArrayType } from "../../../typeSystem/array_type";
+
+export class ArrayStoreValueRef implements IStoreValue {
+
+  public isConst = false;
+
+  constructor(public type: ArrayType, public values: StoreValueAddress[],
+    private loc_address: number[], public lines: number, public columns:number, public id:String) { }
+
+  get () {
+    return this.values;
+  }
+
+  getRefAddresses () : number[] {
+    return this.loc_address;
+  }
+
+  inStore () {
+    return this.id != null;
+  }
+}

+ 2 - 2
js/processor/store/istore_value.ts

@@ -1,7 +1,7 @@
-import { Type } from "./../../typeSystem/type";
+import { IType } from "../../../typeSystem/itype";
 
 export interface IStoreValue {
-  type: Type;
+  type: IType;
   get () : any;
   id? : String;
   isConst: boolean;

+ 3 - 3
js/processor/store/store_value.ts

@@ -1,14 +1,14 @@
 import { IStoreValue } from "./istore_value";
-import { Type } from "../../typeSystem/type";
+import { IType } from "../../../typeSystem/itype";
 
 export class StoreValue implements IStoreValue {
   
-  public type: Type;
+  public type: IType;
   public id?: String;
   public isConst: boolean;
   public value: any;
 
-  constructor(type: Type, value: any, id?:String, isConst = false) {
+  constructor(type: IType, value: any, id?:String, isConst = false) {
     this.type = type;
     this.id = id;
     this.isConst = isConst

+ 9 - 0
js/processor/store/value/store_value_address.ts

@@ -0,0 +1,9 @@
+import { StoreValue } from "./store_value";
+import { IType } from "../../../typeSystem/itype";
+
+export class StoreValueAddress extends StoreValue {
+
+  constructor (type: IType, value: any, public line: number, public column?: number, id?:String, isConst = false)  {
+    super(type,value,id, isConst);
+  }
+}

+ 1 - 1
js/processor/store/store_value_ref.ts

@@ -1,5 +1,5 @@
 import { IStoreValue } from "./istore_value";
-import { Type } from "../../typeSystem/type";
+import { Type } from "../../../typeSystem/type";
 
 export class StoreValueRef implements IStoreValue {
 

+ 9 - 2
js/runner.js

@@ -37,8 +37,15 @@ try {
       proc.registerInput(domConsole);
       domConsole.clear();
       proc.registerOutput(domConsole);
-      proc.interpretAST().then(sto => {editor.load(sto.store);console.log(Location.size());})
-        .catch( e => {alert(e); console.log(e);console.log(Location.size());});
+      proc.interpretAST().then(sto => {
+        console.log(sto);
+        editor.load(sto.store);
+        console.log(Location.size());
+      }).catch( e => {
+        alert(e);
+        console.log(e);
+        console.log(Location.size());
+      });
     } catch (error) {
       alert(error);
       console.log(error);

+ 2 - 2
js/typeSystem/array_type.ts

@@ -32,11 +32,11 @@ export class ArrayType implements IType {
   }
 
   get value () {
-    return null;
+    return undefined;
   }
 
   get ord () {
-    return null;
+    return undefined;
   }
 
   canAccept (another: IType) {

+ 2 - 2
js/typeSystem/itype.ts

@@ -1,8 +1,8 @@
 export interface IType {
 
-  value: String | null;
+  value?: String;
 
-  ord: number | null;
+  ord?: number;
 
   stringInfo (): any[];
 

+ 2 - 2
js/typeSystem/multiType.ts

@@ -7,11 +7,11 @@ export class MultiType implements IType {
   }
 
   get value () {
-    return null;
+    return undefined;
   }
 
   get ord () {
-    return null;
+    return undefined;
   }
 
   stringInfo () {

+ 84 - 3
package-lock.json

@@ -826,6 +826,72 @@
         "@types/babel-types": "*"
       }
     },
+    "@types/eslint-visitor-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+      "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
+      "dev": true
+    },
+    "@types/json-schema": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz",
+      "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==",
+      "dev": true
+    },
+    "@typescript-eslint/eslint-plugin": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.0.0.tgz",
+      "integrity": "sha512-Mo45nxTTELODdl7CgpZKJISvLb+Fu64OOO2ZFc2x8sYSnUpFrBUW3H+H/ZGYmEkfnL6VkdtOSxgdt+Av79j0sA==",
+      "dev": true,
+      "requires": {
+        "@typescript-eslint/experimental-utils": "2.0.0",
+        "eslint-utils": "^1.4.0",
+        "functional-red-black-tree": "^1.0.1",
+        "regexpp": "^2.0.1",
+        "tsutils": "^3.14.0"
+      }
+    },
+    "@typescript-eslint/experimental-utils": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.0.0.tgz",
+      "integrity": "sha512-XGJG6GNBXIEx/mN4eTRypN/EUmsd0VhVGQ1AG+WTgdvjHl0G8vHhVBHrd/5oI6RRYBRnedNymSYWW1HAdivtmg==",
+      "dev": true,
+      "requires": {
+        "@types/json-schema": "^7.0.3",
+        "@typescript-eslint/typescript-estree": "2.0.0",
+        "eslint-scope": "^4.0.0"
+      }
+    },
+    "@typescript-eslint/parser": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.0.0.tgz",
+      "integrity": "sha512-ibyMBMr0383ZKserIsp67+WnNVoM402HKkxqXGlxEZsXtnGGurbnY90pBO3e0nBUM7chEEOcxUhgw9aPq7fEBA==",
+      "dev": true,
+      "requires": {
+        "@types/eslint-visitor-keys": "^1.0.0",
+        "@typescript-eslint/experimental-utils": "2.0.0",
+        "@typescript-eslint/typescript-estree": "2.0.0",
+        "eslint-visitor-keys": "^1.0.0"
+      }
+    },
+    "@typescript-eslint/typescript-estree": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.0.0.tgz",
+      "integrity": "sha512-NXbmzA3vWrSgavymlzMWNecgNOuiMMp62MO3kI7awZRLRcsA1QrYWo6q08m++uuAGVbXH/prZi2y1AWuhSu63w==",
+      "dev": true,
+      "requires": {
+        "lodash.unescape": "4.0.1",
+        "semver": "^6.2.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
     "@webassemblyjs/ast": {
       "version": "1.8.5",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
@@ -3150,9 +3216,9 @@
       }
     },
     "eslint-utils": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz",
-      "integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==",
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
+      "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
       "dev": true,
       "requires": {
         "eslint-visitor-keys": "^1.0.0"
@@ -5501,6 +5567,12 @@
       "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
       "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
     },
+    "lodash.unescape": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
+      "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=",
+      "dev": true
+    },
     "log": {
       "version": "1.4.0",
       "resolved": "http://registry.npmjs.org/log/-/log-1.4.0.tgz",
@@ -8049,6 +8121,15 @@
       "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz",
       "integrity": "sha1-fcSjOvcVgatDN9qR2FylQn69mpc="
     },
+    "tsutils": {
+      "version": "3.17.1",
+      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
+      "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.8.1"
+      }
+    },
     "tty-browserify": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",

+ 2 - 0
package.json

@@ -28,6 +28,8 @@
   "devDependencies": {
     "@babel/core": "^7.4.3",
     "@babel/preset-env": "^7.4.3",
+    "@typescript-eslint/eslint-plugin": "^2.0.0",
+    "@typescript-eslint/parser": "^2.0.0",
     "antlr4-webpack-loader": "^0.1.1",
     "babel-loader": "^8.0.5",
     "clean-webpack-plugin": "^2.0.1",