Browse Source

Fix some TypeScript issues regarding the typeSystem/ classes

Lucas de Souza 4 years ago
parent
commit
dd3fbaa603

+ 2 - 1
.vscode/settings.json

@@ -4,5 +4,6 @@
     "**/.git/objects/**": true,
     "**/.git/subtree-cache/**": true,
     "**/node_modules/**": true
-  }
+  },
+  "javascript.format.insertSpaceBeforeFunctionParenthesis": true
 }

+ 0 - 35
js/ast/operators.js

@@ -1,35 +0,0 @@
-export const Operators = Object.freeze({
-  ADD: {ord: 0, value: "+"},
-  SUB: {ord: 1, value: "-"},
-  MULT: {ord: 2, value: '*'},
-  DIV: {ord: 3, value: '/'},
-  MOD: {ord: 4, value: '%'},
-  GT: {ord: 5, value: '>'},
-  GE: {ord: 6, value: '>='},
-  LT: {ord: 7, value: '<'},
-  LE: {ord: 8, value: '<='},
-  EQ: {ord: 9, value: '=='},
-  NEQ: {ord: 10, value: '!='},
-  AND: {ord: 11, value: 'and'},
-  OR: {ord: 12, value: 'or'},
-  NOT: {ord: 13, value: 'not'}
-});
-
-export function convertFromString (op) {
-  switch (op) {
-    case '+' : return Operators.ADD;
-    case '-' : return Operators.SUB;
-    case '*' : return Operators.MULT;
-    case '/' : return Operators.DIV;
-    case '%' : return Operators.MOD;
-    case '>' : return Operators.GT;
-    case '>=' : return Operators.GE;
-    case '<' : return Operators.LT;
-    case '<=' : return Operators.LE;
-    case '==' : return Operators.EQ;
-    case '!=' : return Operators.NEQ;
-    case 'and' : return Operators.AND;
-    case 'or' : return Operators.OR;
-    case 'not' : return Operators.NOT;
-  }
-}

+ 0 - 219
js/processor/compatibilityTable.js

@@ -1,219 +0,0 @@
-import { Types } from './../typeSystem/types';
-import { Operators } from './../ast/operators';
-import { MultiType } from '../typeSystem/multiType';
-import { Config } from '../util/config';
-
-function buildInfixAddTable () {
-  const table = [[], [], [], []];
-
-  table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
-  table[Types.INTEGER.ord][Types.REAL.ord] = Types.REAL;
-  table[Types.INTEGER.ord][Types.STRING.ord] = Types.STRING;
-
-  table[Types.REAL.ord][Types.INTEGER.ord] = Types.REAL;
-  table[Types.REAL.ord][Types.REAL.ord] = Types.REAL;
-  table[Types.REAL.ord][Types.STRING.ord] = Types.STRING;
-
-  table[Types.STRING.ord][Types.INTEGER.ord] = Types.STRING;
-  table[Types.STRING.ord][Types.REAL.ord] = Types.STRING;
-  table[Types.STRING.ord][Types.STRING.ord] = Types.STRING;
-  table[Types.STRING.ord][Types.BOOLEAN.ord] = Types.STRING;
-
-  return table;
-}
-
-function buildInfixMultiDivSubTable () {
-  const table = [[], [], [], []];
-
-  table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
-  table[Types.INTEGER.ord][Types.REAL.ord] = Types.REAL;
-
-  table[Types.REAL.ord][Types.INTEGER.ord] = Types.REAL;
-  table[Types.REAL.ord][Types.REAL.ord] = Types.REAL;
-
-  return table;
-}
-
-function buildInfixEqualityInequalityTable () {
-  const table = [[], [], [], []];
-
-  table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.BOOLEAN;
-
-  table[Types.REAL.ord][Types.REAL.ord] = Types.BOOLEAN;
-
-  table[Types.BOOLEAN.ord][Types.BOOLEAN.ord] = Types.BOOLEAN;
-
-  table[Types.STRING.ord][Types.STRING.ord] = Types.BOOLEAN;
-
-  return table;
-}
-
-function buildInfixRelationalTable () {
-  const table = [[], [], [], []];
-
-  table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.BOOLEAN;
-
-  table[Types.REAL.ord][Types.REAL.ord] = Types.BOOLEAN;
-
-  table[Types.STRING.ord][Types.STRING.ord] = Types.BOOLEAN;
-
-  return table;
-}
-
-function buildInfixAndOrTable () {
-  const table = [[], [], [], []];
-
-  table[Types.BOOLEAN.ord][Types.BOOLEAN.ord] = Types.BOOLEAN;
-
-  return table;
-}
-
-function buildInfixModTable () {
-  const table = [[], [], [], []];
-
-  table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
-
-  return table;
-}
-
-function buildUnarySumSubList () {
-  const list = [];
-
-  list[Types.INTEGER.ord] = Types.INTEGER;
-
-  list[Types.REAL.ord] = Types.REAL;
-
-  return list;
-}
-
-function buildUnaryNegList () {
-  const list = [];
-
-  list[Types.BOOLEAN.ord] = Types.BOOLEAN;
-
-  return list;
-}
-
-function buildInfixCompatibilityTable () {
-  const compatibilityMap = new WeakMap();
-  compatibilityMap.set(Operators.ADD, buildInfixAddTable());
-  compatibilityMap.set(Operators.SUB, buildInfixMultiDivSubTable());
-  compatibilityMap.set(Operators.MULT, buildInfixMultiDivSubTable());
-  compatibilityMap.set(Operators.DIV, buildInfixMultiDivSubTable());
-  compatibilityMap.set(Operators.EQ, buildInfixEqualityInequalityTable());
-  compatibilityMap.set(Operators.NEQ, buildInfixEqualityInequalityTable());
-  compatibilityMap.set(Operators.GE, buildInfixRelationalTable());
-  compatibilityMap.set(Operators.GT, buildInfixRelationalTable());
-  compatibilityMap.set(Operators.LE, buildInfixRelationalTable());
-  compatibilityMap.set(Operators.LT, buildInfixRelationalTable());
-  compatibilityMap.set(Operators.OR, buildInfixAndOrTable());
-  compatibilityMap.set(Operators.AND, buildInfixAndOrTable());
-  compatibilityMap.set(Operators.MOD, buildInfixModTable());
-  return compatibilityMap;
-}
-
-function buildUnaryCompatibilityTable () {
-  const compatibilityMap = new WeakMap();
-  compatibilityMap.set(Operators.ADD, buildUnarySumSubList());
-  compatibilityMap.set(Operators.SUB, buildUnarySumSubList());
-  compatibilityMap.set(Operators.NOT, buildUnaryNegList());
-  return compatibilityMap;
-}
-
-const infixMap = buildInfixCompatibilityTable();
-const unaryMap = buildUnaryCompatibilityTable();
-
-export function resultTypeAfterInfixOp (operator, leftExpressionType, rightExpressionType) {
-  try {
-    if(leftExpressionType instanceof MultiType && rightExpressionType instanceof MultiType) {
-      let newMulti = [];
-      for (let i = 0; i < leftExpressionType.types.length; ++i) {
-        const typeA = leftExpressionType.types[i];
-        for(let j = 0; j < rightExpressionType.types.length; ++i) {
-          const typeB = rightExpressionType.types[j];
-          newMulti.push(resultTypeAfterInfixOp(operator, typeA, typeB));
-        }
-      }
-      newMulti = newMulti.filter(x => !x.isCompatible(Types.UNDEFINED));
-      if(newMulti.length <= 0) {
-        if(Config.enable_type_casting) {
-          if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
-            if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
-              return new MultiType([Types.INTEGER, Types.REAL]);
-            }
-          }
-        }
-        return Types.UNDEFINED;
-      } else {
-        return new MultiType(newMulti)
-      }
-    } else if(leftExpressionType instanceof MultiType) {
-      if(leftExpressionType.isCompatible(rightExpressionType)) {
-        return resultTypeAfterInfixOp(operator, rightExpressionType, rightExpressionType);
-      } else {
-        if(Config.enable_type_casting) {
-          if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
-            if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
-              return rightExpressionType;
-            }
-          }
-        }
-        return Types.UNDEFINED;
-      }
-    } else if(rightExpressionType instanceof MultiType) {
-      if(rightExpressionType.isCompatible(leftExpressionType)) {
-        return resultTypeAfterInfixOp(operator, leftExpressionType, leftExpressionType);
-      } else {
-        if(Config.enable_type_casting) {
-          if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
-            if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
-              return leftExpressionType;
-            }
-          }
-        }
-        return Types.UNDEFINED;
-      }
-    }
-    const resultType = infixMap.get(operator)[leftExpressionType.ord][rightExpressionType.ord];
-    if (resultType === null || resultType === undefined) {
-      if(Config.enable_type_casting) {
-        if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
-          if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
-            if(operator === Operators.MOD) {
-              return Types.INTEGER;
-            } else if (operator.ord >= 5 && operator.ord <= 10){
-              return Types.BOOLEAN;
-            }
-          }
-        }
-      }
-      return Types.UNDEFINED
-    }
-    return resultType;
-  } catch (e) {
-    if (e instanceof TypeError) {
-      return Types.UNDEFINED;
-    } else {
-      throw e;
-    }
-  }
-}
-
-export function resultTypeAfterUnaryOp (operator, leftExpressionType) {
-  try {
-    if(leftExpressionType instanceof MultiType){
-      return leftExpressionType;
-    }
-    const resultType = unaryMap.get(operator)[leftExpressionType.ord];
-    if (resultType == null) {
-      return Types.UNDEFINED;
-    }
-    return resultType;
-  } catch (e) {
-    if (e instanceof TypeError) {
-      return Types.UNDEFINED;
-    } else {
-      throw e;
-    } 
-  }
-}

+ 23 - 23
js/processor/compatibilityTable.ts

@@ -29,7 +29,7 @@ function buildInfixAddTable (): IType[][] {
 }
 
 function buildInfixMultiDivSubTable (): IType[][] {
-  const table: IType[][] = [[],[]];
+  const table: IType[][] = [[], []];
 
   table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
   table[Types.INTEGER.ord][Types.REAL.ord] = Types.REAL;
@@ -71,7 +71,7 @@ function buildInfixRelationalTable (): IType[][] {
 }
 
 function buildInfixAndOrTable (): IType[][] {
-  const table: IType[][] = [[],[],[],[]];
+  const table: IType[][] = [[], [], [], []];
 
   table[Types.BOOLEAN.ord][Types.BOOLEAN.ord] = Types.BOOLEAN;
 
@@ -143,16 +143,16 @@ export function resultTypeAfterInfixOp (
       let newMulti = [];
       for (let i = 0; i < leftExpressionType.types.length; ++i) {
         const typeA = leftExpressionType.types[i];
-        for(let j = 0; j < rightExpressionType.types.length; ++i) {
+        for (let j = 0; j < rightExpressionType.types.length; ++i) {
           const typeB = rightExpressionType.types[j];
           newMulti.push(resultTypeAfterInfixOp(operator, typeA, typeB));
         }
       }
       newMulti = newMulti.filter(x => !x.isCompatible(Types.UNDEFINED));
-      if(newMulti.length <= 0) {
-        if(Config.enable_type_casting) {
-          if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
-            if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
+      if (newMulti.length <= 0) {
+        if (Config.enable_type_casting) {
+          if (leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
+            if (rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
               return new MultiType([Types.INTEGER, Types.REAL]);
             }
           }
@@ -161,26 +161,26 @@ export function resultTypeAfterInfixOp (
       } else {
         return new MultiType(newMulti as Type[])
       }
-    } else if(leftExpressionType instanceof MultiType) {
-      if(leftExpressionType.isCompatible(rightExpressionType as Type)) {
+    } else if (leftExpressionType instanceof MultiType) {
+      if (leftExpressionType.isCompatible(rightExpressionType as Type)) {
         return resultTypeAfterInfixOp(operator, rightExpressionType, rightExpressionType);
       } else {
-        if(Config.enable_type_casting) {
-          if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
-            if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
+        if (Config.enable_type_casting) {
+          if (leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
+            if (rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
               return rightExpressionType;
             }
           }
         }
         return Types.UNDEFINED;
       }
-    } else if(rightExpressionType instanceof MultiType) {
-      if(rightExpressionType.isCompatible(leftExpressionType as Type)) {
+    } else if (rightExpressionType instanceof MultiType) {
+      if (rightExpressionType.isCompatible(leftExpressionType as Type)) {
         return resultTypeAfterInfixOp(operator, leftExpressionType, leftExpressionType);
       } else {
-        if(Config.enable_type_casting) {
-          if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
-            if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
+        if (Config.enable_type_casting) {
+          if (leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
+            if (rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
               return leftExpressionType;
             }
           }
@@ -192,12 +192,12 @@ export function resultTypeAfterInfixOp (
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     const resultType = resultTable[leftExpressionType.ord!][rightExpressionType.ord!];
     if (resultType === null || resultType === undefined) {
-      if(Config.enable_type_casting) {
-        if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
-          if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
-            if(operator === Operators.MOD) {
+      if (Config.enable_type_casting) {
+        if (leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
+          if (rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
+            if (operator === Operators.MOD) {
               return Types.INTEGER;
-            } else if (operator.ord >= 5 && operator.ord <= 10){
+            } else if (operator.ord >= 5 && operator.ord <= 10) {
               return Types.BOOLEAN;
             }
           }
@@ -241,6 +241,6 @@ export function resultTypeAfterUnaryOp (operator: Operator, leftExpressionType:
       return Types.UNDEFINED;
     } else {
       throw e;
-    } 
+    }
   }
 }

+ 8 - 6
js/typeSystem/array_type.ts

@@ -9,7 +9,7 @@ export class ArrayType implements IType {
     this.innerType = type;
   }
 
-  get isVector () {
+  get isVector (): boolean {
     return this.dimensions == 1;
   }
 
@@ -23,23 +23,25 @@ export class ArrayType implements IType {
     return false;
   }
 
-  stringInfo () {
+  stringInfo (): object[] {
     const list = this.innerType.stringInfo();
     list.forEach(v => {
-      v.dim = this.dimensions;
+      // eslint-disable-next-line @typescript-eslint/no-explicit-any
+      const tmp = v as any;
+      tmp.dim = this.dimensions;
     });
     return list;
   }
 
-  get value () {
+  get value (): undefined {
     return undefined;
   }
 
-  get ord () {
+  get ord (): undefined {
     return undefined;
   }
 
-  canAccept (another: IType, used_dims: number) {
+  canAccept (another: IType, used_dims: number): boolean {
     const free_dims = this.dimensions - used_dims;
     if(another instanceof ArrayType) {
       return free_dims == another.dimensions && this.innerType.isCompatible(another.innerType);

+ 4 - 3
js/typeSystem/itype.ts

@@ -1,10 +1,11 @@
+// eslint-disable-next-line @typescript-eslint/interface-name-prefix
 export interface IType {
 
-  value?: String;
+  value: string | undefined;
 
-  ord?: number;
+  ord: number | undefined;
 
-  stringInfo (): any[];
+  stringInfo (): object[];
 
   isCompatible (another: IType): boolean;
 

+ 5 - 5
js/typeSystem/multiType.ts

@@ -6,16 +6,16 @@ export class MultiType implements IType {
   constructor (public types: Type[]) {
   }
 
-  get value () {
+  get value (): undefined {
     return undefined;
   }
 
-  get ord () {
+  get ord (): undefined {
     return undefined;
   }
 
-  stringInfo () {
-    let list: any[] = [];
+  stringInfo (): object[] {
+    let list: object[] = [];
     for (let i = 0; i < this.types.length; i++) {
       const t = this.types[i];
       list = list.concat(t.stringInfo());
@@ -23,7 +23,7 @@ export class MultiType implements IType {
     return list;
   }
 
-  isCompatible (another: Type) {
+  isCompatible (another: Type): boolean {
     for (let i = 0; i < this.types.length; i++) {
       const t = this.types[i];
       if (another.isCompatible(t)) {

+ 10 - 4
js/typeSystem/type.ts

@@ -2,13 +2,19 @@ import { IType } from "./itype";
 
 export class Type implements IType {
 
-  constructor(public value: String, public ord: number) { }
+  public value: string;
+  public ord: number;
 
-  stringInfo () {
-    return [{type: this.value, dim: 0}];
+  constructor(value: string, ord: number) {
+    this.value = value;
+    this.ord = ord;
   }
 
-  isCompatible (another: IType) {
+  stringInfo (): object[] {
+    return [{ type: this.value, dim: 0 }];
+  }
+
+  isCompatible (another: IType): boolean {
     return this.value === another.value && this.ord === another.ord;
   }
 }

+ 1 - 1
js/typeSystem/types.ts

@@ -13,7 +13,7 @@ const UNDEFINED = new Type("undefined", 6);
 const ALL = new MultiType([INTEGER, REAL, STRING, CHAR, BOOLEAN]);
 
 interface TypeMap {
-  [key: string]: IType
+  [key: string]: IType;
 }
 
 export const Types = Object.freeze({

+ 0 - 23
js/util/config.js

@@ -1,23 +0,0 @@
-class ConfigObject {
-
-  constructor () {
-    this.decimalPlaces = 8;
-    this.intConvertRoundMode = 2;
-    this.default_lang = 'pt';
-    this.enable_type_casting = true;
-    this.idle_input_interval = 5000;
-    this.suspend_threshold = 100;
-    // this.max_instruction_count = 350250; - automated evaluation limit
-    this.max_instruction_count = Number.MAX_SAFE_INTEGER;
-  }
-
-  setConfig (opts) {
-    for (const key in opts) {
-      if(Object.prototype.hasOwnProperty.call(this, key)){
-        this[key] = opts[key];
-      }
-    }
-  }
-}
-const config = new ConfigObject();
-export const Config = config;

+ 3 - 3
js/util/either.ts

@@ -1,5 +1,5 @@
-type Left<T> = { tag: "left", value: T };
-type Right<T> = { tag: "right", value: T };
+type Left<T> = { tag: "left"; value: T };
+type Right<T> = { tag: "right"; value: T };
 export type Either<L, R> = Left<L> | Right<R>;
 
 export function left<T> (value: T): Left<T> {
@@ -10,7 +10,7 @@ export function right<T> (value: T): Right<T> {
   return {tag: "right", value: value}
 }
 
-export function match<T, L, R> (input: Either<L, R>, left: (l: L) => T, right: (right: R) => T) {
+export function match<T, L, R> (input: Either<L, R>, left: (l: L) => T, right: (right: R) => T): T {
   switch(input.tag) {
     case "left":
       return left(input.value);