/* SCCS - @(#)ArrayIndexNode.java 1.4 - 08/31/99 - 11:29:47 */ /* SCCS - @(#)ArrayIndexNode.java 1.2 - 02/28/99 - 12:39:00 */ /* * Copyright (c) 1997 USC Brain Project. email nsl@java.usc.edu. */ // // ArrayIndexNode //////////////////////////////////////////////////////////// /** * ArrayIndexNode - Array addressing * so something like var[i] */ package npp.src.util; import pp.src.jbf.*; public class ArrayIndexNode extends ExprNode{ // turn this flag true if the nslnumeric objects allow // another nsl numeric object as the index. // the current version does not support this. // @see BinaryExprNode static final boolean ALLOW_NSL_NUMERIC_IN_GET_SET = false; public ExprNode base; public ExprNode index; public ArrayIndexNode(ExprNode b, ExprNode ind) { super(b); index = ind; base = b; if(type!=null) { type = new TypeNode(b.type); type.subDim(1); } /* if (text!=null) System.err.print("ArrayIndexNode: "+text); if (b!=null) System.err.print(" Dim "+b.getDim()); if (type!=null) { System.err.print(" newDim "+type.getDim()); System.err.print(" type text:"+type.text); } System.err.println(" lvalue: "+b.isLvalue());*/ } public ArrayIndexNode(FormalNode b, ExprNode ind) { super(b); index = ind; base = new ExprNode(b); if (type != null) { type = new TypeNode(b.type); type.subDim(1); } //System.out.println("create array: "+text+" Dim"+b.getDim()+" newDim"+type.getDim()); } /** * Code generation. [RHS] * If the object variable is NslNumeric, use get() method to address it * @param npp Nsl Preprocessor * @return error value */ public int genCode(NslPreProcessor npp) { //System.err.println("ArrayIndexNode, calling code generation of base token"); base.genCode(npp); //System.err.println("ArrayIndexNode, calling code generation of index token"); index.genCode(npp); //System.err.println("ArrayIndexNode, generating code of line: "+lineno); if(base.processed || index.processed) processed = true; code = "(" + base.code + ")["+index.code+"]"; if (base.type == null) { type = null; //System.err.println("ArrayIndexNode, unkown array type not processing it"); return NO_OP; } else { type = new TypeNode(base.type); type.subDim(1); } if(index.type == null) { //System.err.println("ArrayIndexNode, unkown index type not processing it"); return NO_OP; } if (base.type.dim <=0 ) { // System.err.println("ArrayIndex: line "+(base.lineno+1)+ // " char "+(base.charno+1)+"\tBase Dimension <= 0"); return ARRAY_DIMENSION_ERROR;} if (index.type.dim >1) { // System.err.println("ArrayIndex: line "+(index.lineno+1)+ // " char "+(index.charno+1)+"\tIndex is an array"); return INDEX_HIGH_DIMENSION_ERROR; } if(index.type.type!=TypeNode.UNKNOWN) if(index.type.type != TypeNode.BYTE && index.type.type != TypeNode.SHORT && index.type.type != TypeNode.INT && index.type.type != TypeNode.LONG) { //System.out.println("\t\t We Get "+index.type.type); // System.err.println("ArrayIndex: line "+(index.lineno+1)+ // " char "+(index.charno+1)+"\tIndex is not an enumerable number (type# "+ index.type.type+")"); return INDEX_NOT_INT_ERROR; } // base is java numeric object if (base.type.numeric) { // both base and index are java numeric if (index.type.numeric) { //System.err.println("ArrayIndexNode, code: base and index are java types"); code = "("+base.code+")["+index.code+"]"; } // base is java, index is nsl numeric else if (index.type.nslNumeric ) { //|| index.type.type == TypeNode.UNKNOWN) { //System.err.println("ArrayIndexNode, code: base is java and index is nsl"); code = "("+base.code+")[("+index.code+").getint()]"; processed = true; } // index is not numeric object else { // System.err.println("ArrayIndex: line "+(index.lineno+1)+ // " char "+(index.charno+1)+"\tIndex is not an enumerable number"); return INDEX_NOT_INT_ERROR; } } // base is nsl numeric object else if (base.type.nslNumeric || base.type.nslBool) { //System.err.println("ArrayIndexNode, code: nsl numeric object"); type.numeric = false; type.nslNumeric = true; // 4d-> 0d if (base.type.nslDim-base.type.dim == 3 && base instanceof ArrayIndexNode) { //System.err.println("ArrayIndexNode, code: 4d->0d"); ArrayIndexNode array = (ArrayIndexNode) base; ArrayIndexNode array1 = (ArrayIndexNode) (array.base); ArrayIndexNode array2 = (ArrayIndexNode) (array1.base); if(ALLOW_NSL_NUMERIC_IN_GET_SET || (index.type.numeric && array.index.type.numeric && array1.index.type.numeric && array2.index.type.numeric)) { code = "("+array2.base.code+").get("+ array2.index.code+","+array1.index.code+","+array.index.code+","+index.code+")"; //System.err.println("ArrayIndexNode, code: ALLOW_NSL_NUMERIC_IN_GET_SET"); } else { if(array2.index.type.nslNumeric || array2.index.type.nslBool) { code = "("+array2.base.code+").get("+ array2.index.code+".get(),"; //System.err.println("ArrayIndexNode, code: index is nslNumeric array2"); } else { //System.err.println("ArrayIndexNode, code: index is not nslNumeric array2"); code = "("+array2.base.code+").get("+ array2.index.code+","; } if(array1.index.type.nslNumeric || array1.index.type.nslBool) { //System.err.println("ArrayIndexNode, code: index is nslNumeric array1"); code = code + array1.index.code+".get(),"; } else { code = code + array1.index.code+","; //System.err.println("ArrayIndexNode, code: index is not nslNumeric array1"); } if(array.index.type.nslNumeric || array.index.type.nslBool) { code = code + array.index.code+".get(),"; //System.err.println("ArrayIndexNode, code: index is nslNumeric array"); } else { code = code + array.index.code+","; //System.err.println("ArrayIndexNode, code: index is not nslNumeric array"); } if(index.type.nslNumeric || index.type.nslBool) { code = code + index.code+".get())"; //System.err.println("ArrayIndexNode, code: index is nslNumeric index"); } else { code = code +index.code+")"; //System.err.println("ArrayIndexNode, code: index is not nslNumeric index"); } } if (base.type.dim == 1) { type.nslNumeric = false; type.nslBool = false; type.numeric = true; } } // 3d-> 0d else if (base.type.nslDim-base.type.dim == 2 && base instanceof ArrayIndexNode) { //System.err.println("ArrayIndexNode, code: 3d->0d"); ArrayIndexNode array = (ArrayIndexNode) base; ArrayIndexNode array1 = (ArrayIndexNode) (array.base); if(ALLOW_NSL_NUMERIC_IN_GET_SET || (index.type.numeric && array.index.type.numeric && array1.index.type.numeric)) { code = "("+array1.base.code+").get("+ array1.index.code+","+array.index.code+","+index.code+")"; //System.err.println("ArrayIndexNode, code: ALLOW_NSL_NUMERIC_IN_GET_SET"); } else { if(array1.index.type.nslNumeric || array1.index.type.nslBool) { code = "("+array1.base.code+").get("+ array1.index.code+".getint(),"; //System.err.println("ArrayIndexNode, code: index is nslNumeric array1"); } else { code = "("+array1.base.code+").get("+ array1.index.code+","; //System.err.println("ArrayIndexNode, code: index is not nslNumeric array1"); } if(array.index.type.nslNumeric || array.index.type.nslBool) { code = code + array.index.code+".get(),"; //System.err.println("ArrayIndexNode, code: index is nslNumeric array"); } else { code = code + array.index.code+","; //System.err.println("ArrayIndexNode, code: index is not nslNumeric array"); } if(index.type.nslNumeric || index.type.nslBool) { code = code + index.code+".get())"; //System.err.println("ArrayIndexNode, code: index is nslNumeric index"); } else { code = code +index.code+")"; //System.err.println("ArrayIndexNode, code: index is not nslNumeric index"); } } if (base.type.dim == 1) { type.nslNumeric = false; type.nslBool = false; type.numeric = true; } } // 2d-> 0d else if (base.type.nslDim > base.type.dim && base instanceof ArrayIndexNode ) { //System.err.println("ArrayIndexNode, code: 2d->0d"); ArrayIndexNode array = (ArrayIndexNode) base; /* original code = "("+array.base.code+").get("+ array.index.code+","+index.code+")"; */ if(ALLOW_NSL_NUMERIC_IN_GET_SET || (index.type.numeric && array.index.type.numeric)) { code = "("+array.base.code+").get("+ array.index.code+","+index.code+")"; //System.err.println("ArrayIndexNode, code: ALLOW_NSL_NUMERIC_IN_GET_SET"); } else { // code = "("+array.base.code+").get("+ // array.index.code+","+index.code+".get())"; if(array.index.type.nslNumeric || array.index.type.nslBool) { code = "("+array.base.code+").get("+ array.index.code+".get(),"; //System.err.println("ArrayIndexNode, code: index is nslNumeric array"); } else { code = "("+array.base.code+").get("+ array.index.code+","; //System.err.println("ArrayIndexNode, code: index is not nslNumeric array"); } if(index.type.nslNumeric || index.type.nslBool) { code = code + index.code+".get())"; //System.err.println("ArrayIndexNode, code: index is nslNumeric index"); } else { code = code +index.code+")"; //System.err.println("ArrayIndexNode, code: index is not nslNumeric index"); } } if (base.type.dim == 1) { type.nslNumeric = false; type.nslBool = false; type.numeric = true; } } else if (base.type.nslDim >= base.type.dim){ //System.err.println("ArrayIndexNode, code: 1d->0d"); if(!ALLOW_NSL_NUMERIC_IN_GET_SET && index.type.nslNumeric) { code = "("+base.code+").get("+index.code+".get())"; //System.err.println("ArrayIndexNode, code: ALLOW_NSL_NUMERIC_IN_GET_SET"); } else { code = "("+base.code+").get("+index.code+")"; //System.err.println("ArrayIndexNode, code: base and index"); } processed = true; if (base.type.dim == 1) { type.nslNumeric = false; type.nslBool = false; type.numeric = true; } } else { // higher dimensional object // nsldim < dim // use normal array index syntax //System.err.println("ArrayIndexNode, Higher dimensional object"); return NO_OP; } } // base is not numeric object else { //System.err.println("ArrayIndexNode, base is not a numeric object"); return NO_OP; } //System.err.println("ArrayIndexNode, GenCode: "+code); return SUCCESS; } /* to return left valued functions only */ /** * Code generation. [LHS] * If the object variable is NslNumeric use set() method to set a portion of the elements or all elements to supplied value * @param npp Nsl Preprocessor * @return error value */ public int genCode(NslPreProcessor npp, boolean left_value) { //System.err.println("ArrayIndexNode, it's a left hand variable"); if (!left_value) return genCode(npp); else if(!lvalue) { // System.err.println("ArrayIndex: line "+(base.lineno+1)+ // " char "+(base.charno+1)+"\tInvalid left value."); return NOT_LEFT_VALUE_ASSIGNMENT_ERROR; } /******* SET VALUES *********/ base.genCode(npp); index.genCode(npp); if(base.processed || index.processed) processed = true; code = "(" + base.code + ")["+index.code+"]"; if (base.type == null) { type = null; return NO_OP; } else { type = new TypeNode(base.type); type.subDim(1); } if (index.type == null) return NO_OP; if (base.type.dim <=0 ){ // System.err.println("ArrayIndex: line "+(base.lineno+1)+ // " char "+(base.charno+1)+"\tBase Dimension <= 0"); return ARRAY_DIMENSION_ERROR; } if (index.type.dim >1){ // System.err.println("ArrayIndex: line "+(base.lineno+1)+ // " char "+(base.charno+1)+"\tIndex is an array"); return INDEX_HIGH_DIMENSION_ERROR; } if(index.type.type != TypeNode.UNKNOWN) if(index.type.type != TypeNode.BYTE && index.type.type != TypeNode.SHORT && index.type.type != TypeNode.INT && index.type.type != TypeNode.LONG) { //System.out.println("\t\t We Get "+index.type.type); // System.err.println("ArrayIndex: line "+(base.lineno+1)+ // " char "+(base.charno+1)+"\tIndex is not an enumerable number"); return INDEX_NOT_INT_ERROR; } // base is java numeric object if (base.type.numeric) { /* Legacy code, to be removed // is it directly based on NslNumeric objects? if (base.type.dim == 1 && base instanceof ArrayIndexNode) { ArrayIndexNode array = (ArrayIndexNode) base; // yes it is directly based on NslNumeric objects // do optumization. if (array.base.type.nslNumeric && array.base.type.nslDim == 2) { // code = "("+base.code+").set("+array.index.code+","+index.code+","; if(ALLOW_NSL_NUMERIC_IN_GET_SET || (index.type.numeric && array.index.type.numeric)) { code = "("+array.base.code+").set("+ array.index.code+","+index.code+","; } else { if(index.type.numeric) { code = "("+array.base.code+").set("+ array.index.code+","; } else { code = "("+array.base.code+").set("+ array.index.code+".getint(),"; } if(array.index.type.numeric) { code = code + index.code+","; } else { code = code +index.code+".getint(),"; } } } } else { */ // both base and index are java numeric if (index.type.numeric) { code = "("+base.code+")["+index.code+"]"; } // base is java, index is nsl numeric else if (index.type.nslNumeric) { // || index.type.type == TypeNode.UNKNOWN) { code = "("+base.code+")[("+index.code+").get()]"; processed = true; } // index is not numeric object else { // System.err.println("#ArrayIndex: line "+(base.lineno+1)+ // " char "+(base.charno+1)+"\tIndex is not an enumerable number"); return INDEX_NOT_INT_ERROR; } } //} // base is nsl numeric object else if (base.type.nslNumeric) { type.numeric = false; type.nslNumeric = true; // 2d-> 0d if(base instanceof ArrayIndexNode && base.type.nslDim > base.type.dim) { ArrayIndexNode array = (ArrayIndexNode) base; /* original code = "("+array.base.code+").set("+ array.index.code+","+index.code+","; */ if(ALLOW_NSL_NUMERIC_IN_GET_SET || (index.type.numeric && array.index.type.numeric)) { code = "("+array.base.code+").set("+ array.index.code+","+index.code+","; } else { if(array.index.type.nslNumeric) { code = "("+array.base.code+").set("+ array.index.code+".getint(),"; } else { code = "("+array.base.code+").set("+ array.index.code+","; } if(index.type.nslNumeric) { code = code + index.code+".getint(),"; } else { code = code +index.code+","; } } } else if (base.type.nslDim >= base.type.dim) { if(!ALLOW_NSL_NUMERIC_IN_GET_SET && index.type.nslNumeric) { code = "("+base.code+").set("+index.code+".getint(),"; } else { code = "("+base.code+").set("+index.code+","; } processed = true; } else return NO_OP; } // base is not numeric object else { return NO_OP; } //System.out.println("GenCode: "+code); return SUCCESS; } // return error code final public static int NO_OP = 0; final public static int SUCCESS = 1; final public static int INDEX_NOT_INT_ERROR = 2; final public static int ARRAY_DIMENSION_ERROR = 3; final public static int INDEX_HIGH_DIMENSION_ERROR = 4; }