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, 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, Math.floor(value)); sto.insertStore("$", temp); sto.mode = Modes.RETURN; return sto; } case Types.CHAR.ord: { const temp = new StoreValue(Types.INTEGER, 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, 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]), '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; }