Ver Fonte

Implement the missing Language Defined Functions

Lucas de Souza há 5 anos atrás
pai
commit
88aa8cdb62

+ 5 - 0
js/ast/ivprogParser.js

@@ -10,6 +10,11 @@ import { LanguageService } from '../services/languageService';
 
 export class IVProgParser {
 
+  static createParser (input) {
+    const lexerClass = LanguageService.getCurrentLexer();
+    return new IVProgParser(input, lexerClass);
+  }
+
   // <BEGIN scope consts>
   static get BASE () {
     return 0;

+ 4 - 4
js/processor/lib/arrays.js

@@ -1,6 +1,6 @@
 import { StoreObject } from '../store/storeObject';
 import * as Commands from './../../ast/commands';
-import { Types } from './../../ast/types';
+import { Types, toInt } from './../../ast/types';
 
 /**
  * num_elements
@@ -11,7 +11,7 @@ import { Types } from './../../ast/types';
 export function createNumElementsFun () {
   const numElementsFun = (sto, _) => {
     const vector  = sto.applyStore("vector");
-    const temp = new StoreObject(Types.INTEGER, vector.lines);
+    const temp = new StoreObject(Types.INTEGER, toInt(vector.lines));
     return Promise.resolve(sto.updateStore("$", temp));
   }
 
@@ -25,7 +25,7 @@ export function createNumElementsFun () {
 export function createMatrixLinesFun () {
   const matrixLinesFun = (sto, _) => {
     const matrix  = sto.applyStore("matrix");
-    const temp = new StoreObject(Types.INTEGER, matrix.lines);
+    const temp = new StoreObject(Types.INTEGER, toInt(matrix.lines));
     return Promise.resolve(sto.updateStore("$", temp));
   }
 
@@ -39,7 +39,7 @@ export function createMatrixLinesFun () {
 export function createMatrixColumnsFun () {
   const matrixColumnsFun = (sto, _) => {
     const matrix  = sto.applyStore("matrix");
-    const temp = new StoreObject(Types.INTEGER, matrix.columns);
+    const temp = new StoreObject(Types.INTEGER, toInt(matrix.columns));
     return Promise.resolve(sto.updateStore("$", temp));
   }
 

+ 84 - 10
js/processor/lib/lang.js

@@ -1,7 +1,6 @@
 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';
 
@@ -19,8 +18,7 @@ import { RealLiteral, IntLiteral, BoolLiteral } from '../../ast/expressions';
 export function createIsRealFun () {
   const isRealFun = (sto, _) => {
     const str = sto.applyStore("str");
-    const lexer = LanguageService.getCurrentLexer();
-    const parser = new IVProgParser(str.value, lexer);
+    const parser = IVProgParser.createParser(str.value);
     let result = false;
     try {
       const val = parser.parseTerm();
@@ -42,8 +40,7 @@ export function createIsRealFun () {
 export function createIsIntFun () {
   const isIntFun = (sto, _) => {
     const str = sto.applyStore("str");
-    const lexer = LanguageService.getCurrentLexer();
-    const parser = new IVProgParser(str.value, lexer);
+    const parser = IVProgParser.createParser(str.value);
     let result = false;
     try {
       const val = parser.parseTerm();
@@ -65,8 +62,7 @@ export function createIsIntFun () {
 export function createIsBoolFun () {
   const isBoolFun = (sto, _) => {
     const str = sto.applyStore("str");
-    const lexer = LanguageService.getCurrentLexer();
-    const parser = new IVProgParser(str.value, lexer);
+    const parser = IVProgParser.createParser(str.value);
     let result = false;
     try {
       const val = parser.parseTerm();
@@ -90,12 +86,11 @@ export function createCastRealFun () {
     const val = sto.applyStore("val");
     switch (val.type.ord) {
       case Types.INTEGER.ord: {
-        const temp = new StoreObject(Types.REAL, toReal(val.value));
+        const temp = new StoreObject(Types.REAL, toReal(val.number));
         return Promise.resolve(sto.updateStore("$", temp));
       }
       case Types.STRING.ord: {
-        const lexer = LanguageService.getCurrentLexer();
-        const parser = new IVProgParser(val.value, lexer);
+        const parser = IVProgParser.createParser(val.value);
         try {
           const result = parser.parseTerm();
           if (result instanceof RealLiteral) {
@@ -114,4 +109,83 @@ export function createCastRealFun () {
     [new Commands.FormalParameter(Types.ALL, 'val', 0, false)],
     block);
   return func;
+}
+
+export function createCastIntFun () {
+  const castIntFun = (sto, _) => {
+    const val = sto.applyStore("val");
+    switch (val.type.ord) {
+      case Types.REAL.ord: {
+        const temp = new StoreObject(Types.INTEGER, Math.floor(val.number));
+        return Promise.resolve(sto.updateStore("$", temp));
+      }
+      case Types.STRING.ord: {
+        const parser = IVProgParser.createParser(val.value);
+        try {
+          const result = parser.parseTerm();
+          if (result instanceof IntLiteral) {
+            const temp = new StoreObject(Types.INTEGER, 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(castIntFun)]);
+  const func = new Commands.Function('$castInt', Types.INTEGER,
+    [new Commands.FormalParameter(Types.ALL, 'val', 0, false)],
+    block);
+  return func;
+}
+
+export function createCastBoolFun () {
+  const castBoolFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const parser = IVProgParser.createParser(str.value);
+    try {
+      const val = parser.parseTerm();
+      if (val instanceof BoolLiteral) {
+        const temp = new StoreObject(Types.BOOLEAN, val.value);
+        return Promise.resolve(sto.updateStore("$", temp));
+      }
+    } catch (error) { }
+    return Promise.reject("cannot convert " + str.value + " to boolean");
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(castBoolFun)]);
+  const func = new Commands.Function('$castBool', Types.BOOLEAN,
+    [new Commands.FormalParameter(Types.STRING, 'str', 0, false)],
+    block);
+  return func;
+}
+
+export function createCastStringFun () {
+  const castStringFun = function (store, _) {
+    const val = store.applyStore('str');
+    switch (val.type.ord) {
+      case Types.INTEGER.ord:
+        this.output.sendOutput(val.number);  
+        break;
+      case Types.REAL.ord: {
+        if (val.value.dp() <= 0) {
+          this.output.sendOutput(val.value.toFixed(1));  
+        } else {
+          this.output.sendOutput(val.number);
+        }
+        break;
+      }
+      default:
+        this.output.sendOutput(val.value);
+        break;
+    }
+    return Promise.resolve(store);
+  }
+  const block = new Commands.CommandBlock([], [new Commands.SysCall(castStringFun)]);
+  const func = new Commands.Function('$castString', Types.STRING,
+    [new Commands.FormalParameter(Types.ALL, 'str', 0, false)],
+    block);
+  return func;
 }

+ 192 - 0
js/processor/lib/math.js

@@ -0,0 +1,192 @@
+import { StoreObject } from '../store/storeObject';
+import * as Commands from './../../ast/commands';
+import { Types, toReal } from './../../ast/types';
+import { BigNumber } from 'bignumber.js';
+
+/**
+ * sin
+ * cos
+ * tan
+ * sqrt
+ * pow
+ * log
+ * abs
+ * negate
+ * invert
+ * max
+ * min
+ */
+
+export function createSinFun () {
+   const sinFun = (sto, _) => {
+     const x = sto.applyStore('x');
+     const result = toReal(Math.sin(x.number));
+     const temp = new StoreObject(Types.REAL, result);
+     return Promise.resolve(sto.updateStore('$', temp));
+   };
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(sinFun)]);
+  const func = new Commands.Function('$sin', Types.REAL,
+    [new Commands.FormalParameter(Types.REAL, 'x', 0, false)],
+    block);
+  return func;
+}
+
+export function createCosFun () {
+  const cosFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const result = toReal(Math.cos(x.number));
+    const temp = new StoreObject(Types.REAL, result);
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(cosFun)]);
+ const func = new Commands.Function('$cos', Types.REAL,
+   [new Commands.FormalParameter(Types.REAL, 'x', 0, false)],
+   block);
+ return func;
+}
+
+export function createTanFun () {
+  const tanFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const result = toReal(Math.tan(x.number));
+    const temp = new StoreObject(Types.REAL, result);
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(tanFun)]);
+ const func = new Commands.Function('$tan', Types.REAL,
+   [new Commands.FormalParameter(Types.REAL, 'x', 0, false)],
+   block);
+ return func;
+}
+
+export function createSqrtFun () {
+  const sqrtFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const result = x.value.sqrt();
+    const temp = new StoreObject(Types.REAL, result);
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(sqrtFun)]);
+ const func = new Commands.Function('$sqrt', Types.REAL,
+   [new Commands.FormalParameter(Types.REAL, 'x', 0, false)],
+   block);
+ return func;
+}
+
+export function createPowFun () {
+  const powFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const y = sto.applyStore('y');
+    const result = toReal(Math.pow(x.number, y.number));
+    const temp = new StoreObject(Types.REAL, result);
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(powFun)]);
+ const func = new Commands.Function('$pow', Types.REAL,
+   [new Commands.FormalParameter(Types.REAL, 'x', 0, false),
+    new Commands.FormalParameter(Types.REAL, 'y', 0, false)],
+   block);
+ return func;
+}
+
+export function createLogFun () {
+  const logFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    if (x.isNegative()) {
+      return Promise.reject("the value passed to log function cannot be negative");
+    }
+    const result = toReal(Math.log10(x.number));
+    const temp = new StoreObject(Types.REAL, result);
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(logFun)]);
+ const func = new Commands.Function('$log', Types.REAL,
+   [new Commands.FormalParameter(Types.REAL, 'x', 0, false)],
+   block);
+ return func;
+}
+
+export function createAbsFun () {
+  const absFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const result = x.value.abs();
+    const temp = new StoreObject(Types.REAL, result);
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(absFun)]);
+ const func = new Commands.Function('$abs', Types.REAL,
+   [new Commands.FormalParameter(Types.REAL, 'x', 0, false)],
+   block);
+ return func;
+}
+
+export function createNegateFun () {
+  const negateFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const result = x.value.negated();
+    const temp = new StoreObject(Types.REAL, result);
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(negateFun)]);
+ const func = new Commands.Function('$negate', Types.REAL,
+   [new Commands.FormalParameter(Types.REAL, 'x', 0, false)],
+   block);
+ return func;
+}
+
+export function createInvertFun () {
+  const invertFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const result = toReal(1).dividedBy(x.value);
+    const temp = new StoreObject(Types.REAL, result);
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(invertFun)]);
+ const func = new Commands.Function('$invert', Types.REAL,
+   [new Commands.FormalParameter(Types.REAL, 'x', 0, false)],
+   block);
+ return func;
+}
+
+export function createMaxFun () {
+  const minFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const y = sto.applyStore('y');
+    const result = BigNumber.max(x.value, y.value);
+    const temp = new StoreObject(Types.REAL, result);
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(maxFun)]);
+ const func = new Commands.Function('$max', Types.ALL,
+   [new Commands.FormalParameter(Types.ALL, 'x', 0, false),
+   new Commands.FormalParameter(Types.ALL, 'y', 0, false)],
+   block);
+ return func;
+}
+
+export function createMinFun () {
+  const minFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const y = sto.applyStore('y');
+    const result = BigNumber.max(x.value, y.value);
+    const temp = new StoreObject(Types.REAL, result);
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(minFun)]);
+ const func = new Commands.Function('$min', Types.ALL,
+   [new Commands.FormalParameter(Types.ALL, 'x', 0, false),
+   new Commands.FormalParameter(Types.ALL, 'y', 0, false)],
+   block);
+ return func;
+}

+ 2 - 2
js/processor/lib/strings.js

@@ -1,6 +1,6 @@
 import { StoreObject } from '../store/storeObject';
 import * as Commands from './../../ast/commands';
-import { Types } from './../../ast/types';
+import { Types, toInt } from './../../ast/types';
 
 
 /*
@@ -33,7 +33,7 @@ export function createSubstringFun () {
 export function createLengthFun () {
   const lengthFun = (sto, _) => {
     const str = sto.applyStore("str");
-    const temp = new StoreObject(Types.INTEGER, str.value.length);
+    const temp = new StoreObject(Types.INTEGER, toInt(value.length));
     return Promise.resolve(sto.updateStore("$", temp));
   }
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(lengthFun)]);

+ 1 - 0
js/processor/store/store.js

@@ -1,4 +1,5 @@
 import { Modes } from './../modes';
+
 export class Store {
 
   constructor() {

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

@@ -1,4 +1,5 @@
 import { BigNumber } from 'bignumber.js'
+
 export class StoreObject {
 
   constructor (type, value, readOnly = false) {