Explorar el Código

Implement type cast during assignment

Move implicit type cast functions from type system parser to Store

Remove LibIO workaround for writing type-casted integers
Lucas de Souza hace 5 años
padre
commit
31a124c9b1

+ 14 - 7
js/processor/ivprogProcessor.js

@@ -13,7 +13,7 @@ import * as Expressions from './../ast/expressions/';
 import { StoreObjectArrayAddress } from './store/storeObjectArrayAddress';
 import { StoreObjectArrayAddressRef } from './store/storeObjectArrayAddressRef';
 import { CompoundType } from './../typeSystem/compoundType';
-import { convertToString, canImplicitTypeCast } from '../typeSystem/parsers';
+import { convertToString } from '../typeSystem/parsers';
 import { Config } from '../util/config';
 import Decimal from 'decimal.js';
 import { ProcessorErrorFactory } from './error/processorErrorFactory';
@@ -477,9 +477,20 @@ export class IVProgProcessor {
 
   executeAssign (store, cmd) {
     try {
+      const inStore = store.applyStore(cmd.id);
       const $value = this.evaluateExpression(store, cmd.expression);
       return $value.then( vl => {
         let realValue = this.parseStoreObjectValue(vl);
+        if(!inStore.type.isCompatible(realValue.type)) {
+          if(Config.enable_type_casting && Store.canImplicitTypeCast(inStore.type, vl.type)) {
+            realValue = Store.doImplicitCasting(inStore.type, realValue);
+          } else {
+            const stringInfo = inStore.type.stringInfo()
+            const info = stringInfo[0]
+            return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
+          }
+        }
+        
         store.updateStore(cmd.id, realValue) 
         return store;
       });
@@ -614,12 +625,8 @@ export class IVProgProcessor {
           let realValue = vl;
           if (vl !== null) {
             if(!vl.type.isCompatible(cmd.type)) {
-              if(Config.enable_type_casting && canImplicitTypeCast(cmd.type, vl.type)) {
-                if(Types.INTEGER.isCompatible(cmd.type)) {
-                  realValue = new StoreObject(cmd.type, vl.value.trunc());
-                } else {
-                  realValue = new StoreObject(cmd.type, vl.value);
-                }
+              if(Config.enable_type_casting && Store.canImplicitTypeCast(cmd.type, vl.type)) {
+                realValue = Store.doImplicitCasting(cmd.type, realValue);
               } else {
                 const stringInfo = typeInfo.type.stringInfo();
                 const info = stringInfo[0];

+ 1 - 1
js/processor/lib/io.js

@@ -7,7 +7,7 @@ export function createOutputFun () {
   const writeFunction = function (store, _) {
     const val = store.applyStore('p1');
     if(val.type.isCompatible(Types.INTEGER)) {
-      this.output.sendOutput(val.value.trunc().toString());
+      this.output.sendOutput(val.value.toString());
     } else if (val.type.isCompatible(Types.REAL)) {
       if (val.value.dp() <= 0) {
         this.output.sendOutput(val.value.toFixed(1));  

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

@@ -9,7 +9,7 @@ import { Types } from '../../typeSystem/types';
 import { CompoundType } from '../../typeSystem/compoundType';
 import { MultiType } from '../../typeSystem/multiType';
 import { Config } from '../../util/config';
-import { canImplicitTypeCast } from '../../typeSystem/parsers';
+import { Store } from '../store/store';
 
 export class SemanticAnalyser {
 
@@ -127,12 +127,11 @@ export class SemanticAnalyser {
           throw ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, declaration.sourceInfo);
         }
         this.insertSymbol(declaration.id, {id: declaration.id, type: declaration.type})
-      } else if(!declaration.type.isCompatible(resultType) && !Config.enable_type_casting) {
+      } else if((!declaration.type.isCompatible(resultType) && !Config.enable_type_casting)
+        || (Config.enable_type_casting && !Store.canImplicitTypeCast(declaration.type, resultType))) {
         const stringInfo = declaration.type.stringInfo();
         const info = stringInfo[0];
         throw ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, declaration.sourceInfo);
-      } else if (Config.enable_type_casting && canImplicitTypeCast(declaration.type, resultType)) {
-        this.insertSymbol(declaration.id, {id: declaration.id, type: declaration.type});
       } else {
         this.insertSymbol(declaration.id, {id: declaration.id, type: declaration.type});
       }
@@ -426,7 +425,8 @@ export class SemanticAnalyser {
         this.evaluateArrayLiteral(cmd.id, typeInfo.lines, typeInfo.columns, typeInfo.type, exp);
       } else {
         const resultType = this.evaluateExpressionType(exp);
-        if(!resultType.isCompatible(typeInfo.type)) {
+        if((!resultType.isCompatible(typeInfo.type) && !Config.enable_type_casting)
+          || (Config.enable_type_casting && !Store.canImplicitTypeCast(typeInfo.type, resultType))) {
           const stringInfo = typeInfo.type.stringInfo();
           const info = stringInfo[0];
           throw ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo);

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

@@ -1,7 +1,29 @@
 import { Modes } from './../modes';
+import { Types } from "./../../typeSystem/types";
+import { StoreObject } from './storeObject';
 
 export class Store {
 
+  static canImplicitTypeCast (castType, sourceType) {
+    if (castType.isCompatible(Types.INTEGER) || castType.isCompatible(Types.REAL)) {
+      if (sourceType.isCompatible(Types.INTEGER) || sourceType.isCompatible(Types.REAL)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  static doImplicitCasting (castType, stoObj) {
+    if(!Store.canImplicitTypeCast(castType, stoObj.type)) {
+      throw new Error("!!!Critical error: attempted to type cast invalid types");
+    }
+    if(Types.INTEGER.isCompatible(castType)) {
+      return new StoreObject(castType, stoObj.value.trunc());
+    } else {
+      return new StoreObject(castType, stoObj.value);
+    }
+  }
+
   constructor(name) {
     this.name = name;
     this.store = {};

+ 0 - 9
js/typeSystem/parsers.js

@@ -47,15 +47,6 @@ function convertBoolToString (bool) {
   }
 }
 
-export function canImplicitTypeCast (castType, sourceType) {
-  if (castType.isCompatible(Types.INTEGER) || castType.isCompatible(Types.REAL)) {
-    if (sourceType.isCompatible(Types.INTEGER) || sourceType.isCompatible(Types.REAL)) {
-      return true;
-    }
-  }
-  return false;
-}
-
 export function convertToString(stoObj, type) {
   switch (type.ord) {
     case Types.INTEGER.ord: