import * as Commands from "./../../ast/commands"; import { Types } from "./../../typeSystem/types"; import * as Parsers from "./../../typeSystem/parsers"; import { IVProgParser } from "../../ast/ivprogParser"; import { RealLiteral, IntLiteral, BoolLiteral } from "../../ast/expressions"; import { Modes } from "../modes"; import { MultiType } from "../../typeSystem/multiType"; import { ProcessorErrorFactory } from "../error/processorErrorFactory"; import { StoreValue } from "../store/value/store_value"; /** * * is_real * is_int * is_bool * cast_real * cast_int * cast_bool * cast_string * cast_char */ export function createIsRealFun () { const isRealFun = async (sto, _) => { const str = sto.applyStore("str"); const parser = IVProgParser.createParser(str.get()); let result = false; try { const val = parser.parseTerm(); if (val instanceof RealLiteral) { result = true; } } catch (error) { // ignore } const temp = new StoreValue(Types.BOOLEAN, result); sto.insertStore("$", temp); sto.mode = Modes.RETURN; return sto; }; const block = new Commands.CommandBlock( [], [new Commands.SysCall(isRealFun)] ); const func = new Commands.Function( "$isReal", Types.BOOLEAN, [new Commands.FormalParameter(Types.STRING, "str", false)], block ); return func; } export function createIsIntFun () { const isIntFun = async (sto, _) => { const str = sto.applyStore("str"); const parser = IVProgParser.createParser(str.get()); let result = false; try { const val = parser.parseTerm(); if (val instanceof IntLiteral) { result = true; } } catch { // ignore } const temp = new StoreValue(Types.BOOLEAN, result); sto.insertStore("$", temp); sto.mode = Modes.RETURN; return sto; }; const block = new Commands.CommandBlock([], [new Commands.SysCall(isIntFun)]); const func = new Commands.Function( "$isInt", Types.BOOLEAN, [new Commands.FormalParameter(Types.STRING, "str", false)], block ); return func; } export function createIsBoolFun () { const isBoolFun = (sto, _) => { const str = sto.applyStore("str"); const parser = IVProgParser.createParser(str.get()); let result = false; try { const val = parser.parseTerm(); if (val instanceof BoolLiteral) { result = true; } } catch (error) { // ignore } const temp = new StoreValue(Types.BOOLEAN, result); sto.insertStore("$", temp); sto.mode = Modes.RETURN; return sto; }; const block = new Commands.CommandBlock( [], [new Commands.SysCall(isBoolFun)] ); const func = new Commands.Function( "$isBool", Types.BOOLEAN, [new Commands.FormalParameter(Types.STRING, "str", false)], block ); return func; } export function createCastRealFun () { const castRealFun = async (sto, _) => { const val = sto.applyStore("val"); let value = val.get(); switch (val.type.ord) { case Types.INTEGER.ord: { value = value.toNumber(); const temp = new StoreValue(Types.REAL, Parsers.toReal(value)); sto.insertStore("$", temp); sto.mode = Modes.RETURN; return sto; } case Types.STRING.ord: { const parser = IVProgParser.createParser(value); try { const result = parser.parseTerm(); if (result instanceof RealLiteral) { const temp = new StoreValue( Types.REAL, Parsers.toReal(result.value) ); sto.insertStore("$", temp); sto.mode = Modes.RETURN; return sto; } } catch (error) { // ignore } } } const typeStringInfoArray = Types.REAL.stringInfo(); const typeInfo = typeStringInfoArray[0]; throw ProcessorErrorFactory.invalid_type_conversion( value, typeInfo.type, typeInfo.dim ); }; const block = new Commands.CommandBlock( [], [new Commands.SysCall(castRealFun)] ); const func = new Commands.Function( "$castReal", Types.REAL, [ new Commands.FormalParameter( new MultiType([Types.INTEGER, Types.STRING]), "val", false ), ], block ); return func; } export function createCastIntFun () { const castIntFun = async (sto, _) => { const val = sto.applyStore("val"); let value = val.get(); switch (val.type.ord) { case Types.REAL.ord: { value = value.toNumber(); const temp = new StoreValue( Types.INTEGER, Parsers.toInt(Math.floor(value)) ); sto.insertStore("$", temp); sto.mode = Modes.RETURN; return sto; } case Types.CHAR.ord: { const temp = new StoreValue( Types.INTEGER, Parsers.toInt(value.charCodeAt(0)) ); sto.insertStore("$", temp); sto.mode = Modes.RETURN; return sto; } case Types.STRING.ord: { const parser = IVProgParser.createParser(value); try { const result = parser.parseTerm(); if (result instanceof IntLiteral) { const temp = new StoreValue( Types.INTEGER, Parsers.toInt(result.value) ); sto.insertStore("$", temp); sto.mode = Modes.RETURN; return sto; } } catch (error) { // ignore } } } const typeStringInfoArray = Types.INTEGER.stringInfo(); const typeInfo = typeStringInfoArray[0]; throw ProcessorErrorFactory.invalid_type_conversion( value, typeInfo.type, typeInfo.dim ); }; const block = new Commands.CommandBlock( [], [new Commands.SysCall(castIntFun)] ); const func = new Commands.Function( "$castInt", Types.INTEGER, [ new Commands.FormalParameter( new MultiType([Types.REAL, Types.STRING, Types.CHAR]), "val", false ), ], block ); return func; } export function createCastBoolFun () { const castBoolFun = async (sto, _) => { const str = sto.applyStore("str"); const value = str.get(); const parser = IVProgParser.createParser(value); try { const val = parser.parseTerm(); if (val instanceof BoolLiteral) { const temp = new StoreValue(Types.BOOLEAN, val.value); sto.insertStore("$", temp); sto.mode = Modes.RETURN; return sto; } } catch (error) { // ignore } const typeStringInfoArray = Types.BOOLEAN.stringInfo(); const typeInfo = typeStringInfoArray[0]; throw ProcessorErrorFactory.invalid_type_conversion( value, typeInfo.type, typeInfo.dim ); }; const block = new Commands.CommandBlock( [], [new Commands.SysCall(castBoolFun)] ); const func = new Commands.Function( "$castBool", Types.BOOLEAN, [new Commands.FormalParameter(Types.STRING, "str", false)], block ); return func; } export function createCastStringFun () { const castStringFun = async function (store, _) { const val = store.applyStore("str"); const result = Parsers.convertToString(val.get(), val.type); const temp = new StoreValue(Types.STRING, result); store.insertStore("$", temp); store.mode = Modes.RETURN; return store; }; const block = new Commands.CommandBlock( [], [new Commands.SysCall(castStringFun)] ); const func = new Commands.Function( "$castString", Types.STRING, [new Commands.FormalParameter(Types.ALL, "str", false)], block ); return func; } export function createCastCharFun () { const castCharFun = (store, _) => { const valSV = store.applyStore("charCode"); // Force the int value to the range [0, 255] const value = valSV.get().toNumber() & 0xff; const result = String.fromCharCode(value); const temp = new StoreValue(Types.CHAR, result); store.insertStore("$", temp); store.mode = Modes.RETURN; return store; }; const block = new Commands.CommandBlock( [], [new Commands.SysCall(castCharFun)] ); const func = new Commands.Function( "$castChar", Types.CHAR, [new Commands.FormalParameter(Types.INTEGER, "charCode", false)], block ); return func; }