package node.exprNode; import node.*; import env.*; import type.*; import type.basicType.*; import runEnv.*; import runEnv.basicValue.*; import text.*; public class CastNode extends ExprNode { private Type type; private ExprNode expr; public CastNode( Type type, ExprNode expr ) { this.type = type; this.expr = expr; precedence = PREC_CAST; } public String toString() { return "( " + type + " ) " + expr.toString( precedence ); } public void genEnv( Env env ) { error( "Should never invoke genEnv() for a CastNode()" ); } public Type checkType() { error( "Should never invoke checkType() for a CastNode()" ); return null; } public RunValue eval( RunEnv runEnv ) { RunValue exprValue = expr.eval( runEnv ); if ( type instanceof RealType ) return new RealValue( ( double ) exprValue.intValue() ); else if ( type instanceof CharType ) return new CharValue( ( char ) exprValue.intValue() ); else if ( type instanceof IntType ) return new IntValue( ( int ) exprValue.charValue() ); else if ( type instanceof StringType ) return new StringValue( exprValue.stringValue() ); else if ( type instanceof VoidType ) return new VoidValue(); else return exprValue; } public int calcWeight() { int exprWeight = expr.calcWeight(); weight = max( exprWeight, MAXREG ); return weight; } public void regCode( int freeReg, int freeTemp ) { expr.regCode( freeReg, freeTemp ); if ( type instanceof RealType ) { store( tempReg( freeReg ), tempMem( freeTemp ) ); loadF( ftempReg( freeReg ), tempMem( freeTemp ) ); instrn( "cvtqt", ftempReg( freeReg ), ftempReg( freeReg ) ); } else if ( type instanceof StringType ) { Type operandType = expr.type(); if ( operandType instanceof StringType ) return; else if ( operandType instanceof IntType ) { move( tempReg( freeReg ), "$a0" ); move( "10", "$a1" ); bsr( "Number.toSigned.enter" ); } else if ( operandType instanceof CharType ) { move( tempReg( freeReg ), "$a0" ); bsr( "String.fromChar.enter" ); } else if ( operandType instanceof BoolType ) { move( tempReg( freeReg ), "$a0" ); bsr( "Bool.toString.enter" ); } else if ( operandType instanceof RealType ) { moveF( ftempReg( freeReg ), "$fa0" ); move( "6", "$a1" ); bsr( "Number.doubleToString.enter" ); } else if ( operandType instanceof ArrayType ) { // Needs fixing move( tempReg( freeReg ), "$a0" ); move( "16", "$a1" ); bsr( "Number.toUnsigned.enter" ); } else { move( tempReg( freeReg ), "$a0" ); move( "16", "$a1" ); bsr( "Number.toUnsigned.enter" ); } move( "$v0", "$a0" ); bsr( "Array.fromString.enter" ); move( "$v0", tempReg( freeReg ) ); } } }