/* SCCS - %W% - %G% - %U% */ /* SCCS - @(#)BinaryExprNode.java 1.4 - 07/14/99 - 12:24:48 */ /* * Copyright (c) 1997 USC Brain Project. email nsl@java.usc.edu. */ // // BinaryExprNode //////////////////////////////////////////////////////////// /** * BinaryExprNode - Binary Expression Node * binary expressions like addition and convolution */ package npp.src.util; import pp.src.jbf.*; public class BinaryExprNode 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 ArrayIndexNode static final boolean ALLOW_NSL_NUMERIC_IN_GET_SET = false; public BinaryExprNode(ExprNode l, YYtoken o, ExprNode r) { super(l); left = l; op = o; right = r; lvalue = false; nslSymbol=false; } /** * Code generation. * Only +, - and * are implemented * @param npp Nsl Preprocessor * @return error value */ public int genCode(NslPreProcessor npp) { //System.err.println("BinaryExprNode, generating code of line: "+lineno); String decl_stmt; String inst_stmt; String init_stmt; String init_val; int tmp_dim; int tmp_prec; int tmp_num; String tmp_size1=""; String tmp_size2=""; String index2 = ""; String tmp_precision; boolean ret_bool = false; //System.err.println("BinaryExprNode, generating left code"); left.genCode(npp); //System.err.println("BinaryExprNode, generating right code"); right.genCode(npp); type = left.type; // default type if(left.processed || right.processed) processed = true; code = "("+left.code+")"+op.text+"("+right.code+")"; /* if(left.type != null && right.type != null) //System.out.println("Left "+left.code +" dim "+left.type.dim+" right "+right.code +" dim "+right.type.dim); */ switch (op.tokentype) { case YYtokentypes.OR: case YYtokentypes.AND: if (left.type.type!=TypeNode.BOOL && left.type.type!=TypeNode.UNKNOWN) { // System.err.println("BinExpr: line "+(left.lineno+1)+ // " char "+(left.charno+1)+ // "\tOperand must be boolean type"); } if (right.type.type!=TypeNode.BOOL && right.type.type!=TypeNode.UNKNOWN) { // System.err.println("BinExpr: line "+(right.lineno+1)+ // " char "+(right.charno+1)+ // "\tOperand must be boolean type"); } case '|': case '&': case YYtokentypes.BITSHIFT_RIGHT: case YYtokentypes.FILL_SHIFT_RIGHT: case YYtokentypes.SHIFT_LEFT: case '%': // do nothing return NO_OP; /* case YYtokentypes.EQUAL_COMPARE: case YYtokentypes.NOT_EQUAL: case YYtokentypes.LTEQ: case YYtokentypes.GTEQ: case '<': case '>': type = new TypeNode(TypeNode.BOOL, left);*/ /* here, I assume that the functions for comparison operators are not written yet. the operator thus can only accept scalar functions in this version */ //System.out.println("left.type:"+left.type+" right.type:"+right.type); /* if (left.type == null || right.type == null) return NO_OP; // ERH: does this cover NslPorts? if (left.type.nslNumeric) { code = "("+left.code+").get()"; processed = true; } else code = "("+left.code+")"; // code += op.text; code += opname(op.tokentype); // ERH: does this cover NslPorts? if (right.type.nslNumeric) { code +=( "("+right.code+").get()"); processed = true; } else code +=( "("+right.code+")"); return NO_OP; */ case '+': case '-': case '/': case '*': case '@': case '^': case YYtokentypes.BIT_MUL: case YYtokentypes.EQUAL_COMPARE: case YYtokentypes.NOT_EQUAL: case YYtokentypes.LTEQ: case YYtokentypes.GTEQ: case '<': case '>': if (op.tokentype == YYtokentypes.EQUAL_COMPARE || op.tokentype == YYtokentypes.NOT_EQUAL || op.tokentype == YYtokentypes.LTEQ || op.tokentype == YYtokentypes.GTEQ || op.tokentype == '<' || op.tokentype == '>' ) { // return type shud be boolean ret_bool = true; type = new TypeNode(TypeNode.BOOL, left); } // not identified type if(left.type == null || right.type == null){ return NO_OP; } if(!(left.type.nslNumeric || left.type.nslBool || (left.type.numeric && left.type.dim > 0)) && !(right.type.nslNumeric || right.type.nslBool || (right.type.numeric && right.type.dim > 0))) { /* if(!(left.type.nslNumeric || left.type.nslBool) && !(right.type.nslNumeric || right.type.nslBool)) { */ return NO_OP; } /* System.out.println("Left "+left.text+"type "+left.type.type+" dim="+left.type.dim+ " nsldim="+left.type.dim+ " num="+left.type.numeric+ " nnum="+left.type.nslNumeric+ " Right "+right.text+"type "+right.type.type+" dim="+right.type.dim+ " nsldim="+right.type.dim+ " num="+right.type.numeric+ " nnum="+right.type.nslNumeric); */ // assume java can handle CLASS/METHOD type rexpression if (left.type.type >=TypeNode.STRING || right.type.type >=TypeNode.STRING){ return NO_OP; } // error in processing java native object of higher degree // or nsl numeric object with degree higher than 2 // thr /* if (left.type.dim > left.type.nslDim){ return HIGHER_DEGREE_ERROR; } if (right.type.dim > right.type.nslDim) { return HIGHER_DEGREE_ERROR; } */ //////////////////////////////////////////////////////////// if(Use_Nsl_As_Temp_Variable) { /* generate temporary variable for the negation operation */ /* size of temp variable is the same as the input variable */ if(op.tokentype == '*' && left.type.dim > 0 && right.type.dim > 0) { if(left.type.dim ==1 && right.type.dim == 1) tmp_dim = 0; else if (left.type.dim == 1 && right.type.dim == 2) { tmp_dim = 1; tmp_size1=getTempSize2(right, npp); } else if (left.type.dim == 2 && right.type.dim == 1) { tmp_dim = 1; tmp_size1=getTempSize1(left, npp); } else if (left.type.dim == 2 && right.type.dim == 2) { tmp_dim = 2; tmp_size1=getTempSize1(left, npp); index2 = getTempSize2(right, npp); tmp_size2=", "+index2; } else tmp_dim = 0; // should not happen type = new TypeNode(left.type); type.nslDim = type.dim = tmp_dim; } else { if(op.tokentype == '*') op.tokentype = YYtokentypes.BIT_MUL; if(left.type.dim>right.type.dim) { if (ret_bool) type = new TypeNode(TypeNode.BOOL, left); else type = new TypeNode(left.type); tmp_dim = left.type.dim; if (tmp_dim>0) { tmp_size1=getTempSize1(left, npp); if(tmp_dim>1) { index2 = getTempSize2(left, npp); tmp_size2=", "+index2; if (op.tokentype != '@' && right.type.dim==1){ // invalid operation for addition // subtraction, multiplication // System.err.println("BinExpr: line "+(left.lineno+1)+ // " char "+(left.charno+1)+"\tOperand not match"); } } } } // if(left.type.dim>right.type.dim) else { // left.dim <= right.dim if (!ret_bool) type = new TypeNode(right.type); tmp_dim = right.type.dim; if(tmp_dim>0) { tmp_size1=getTempSize1(right, npp); if(tmp_dim>1) { // just convenient to add the comma here index2 = getTempSize2(right, npp); tmp_size2=", "+index2; if(op.tokentype != '@' && left.type.dim == 1) { // System.err.println("BinExpr: line "+(left.lineno+1)+ // " char "+(left.charno+1)+"\tOperand not match"); // invalid operation for addition // subtraction, multiplication } } } } } // not '*' /* precision of the temp variable si the highest of two input parameters */ if (ret_bool) tmp_prec = TypeNode.BOOL; else tmp_prec = left.type.type>right.type.type? left.type.type: right.type.type; type.type = tmp_prec; /* generate temp variable type */ if (tmp_prec == TypeNode.INT) { // cast it to integer type. if (tmp_dim==0) tmp_precision = "NslInt0 "; else tmp_precision = "NslInt"+tmp_dim+" "; } else if (tmp_prec == TypeNode.FLOAT) { if (tmp_dim==0) tmp_precision = "NslFloat0 "; else tmp_precision = "NslFloat"+tmp_dim+" "; } else if (tmp_prec == TypeNode.DOUBLE) { if (tmp_dim==0) tmp_precision = "NslDouble0 "; else tmp_precision = "NslDouble"+tmp_dim+" "; } else if (tmp_prec == TypeNode.BOOL) { if (tmp_dim==0) tmp_precision = "NslBoolean0 "; else tmp_precision = "NslBoolean"+tmp_dim+" "; } else { code = left.code+op.text+right.code; return NO_OP; } // get temp number from the preprocessor tmp_number = tmp_num = npp.getNextTempNumber(); // construct delcaration statment decl_stmt = npp.TEMP_ACCESS_FLAG+tmp_precision+ npp.TEMP_NUMBER_PREFIX+tmp_num+";"; // construct instantiation statement inst_stmt = npp.TEMP_NUMBER_PREFIX+tmp_num+" = new "+ tmp_precision+"("+tmp_size1+tmp_size2+");"; // construct initialization statement if (tmp_prec == TypeNode.BOOL) init_val = "false"; else init_val = "0"; if (tmp_dim == 0) init_stmt = npp.TEMP_NUMBER_PREFIX+tmp_num+" = "+init_val+";"; else if (tmp_dim == 1) init_stmt = "for (int i = 0; i < "+npp.TEMP_NUMBER_PREFIX+tmp_num+".length; i++) {\n\t\t"+ npp.TEMP_NUMBER_PREFIX+tmp_num+"[i] = "+init_val+";\n}"; else //if (tmp_dim == 2) init_stmt = "for (int i = 0; i < "+npp.TEMP_NUMBER_PREFIX+tmp_num+".length; i++) {\n"+ "\t\tfor (int j = 0; j < "+npp.TEMP_NUMBER_PREFIX+tmp_num+"[0].length; j++) {\n\t\t\t"+ npp.TEMP_NUMBER_PREFIX+tmp_num+"[i][j] = "+init_val+";\n\t\t}\n\t}"; npp.registerTempVar(tmp_num, decl_stmt, inst_stmt, init_stmt); code = "/* WWW */"+npp.TEMP_NUMBER_PREFIX+tmp_num+"=" +opname(op.tokentype)+"("+npp.TEMP_NUMBER_PREFIX+ tmp_num+"@@,"+left.code+"@@,"+right.code+")"; type.nslNumeric = false; type.numeric = true; } /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// if (!Use_Nsl_As_Temp_Variable) { /* size of temp variable is the same as the input variable */ if(op.tokentype == '*' && left.type.dim > 0 && right.type.dim > 0) { if(left.type.dim ==1 && right.type.dim == 1) tmp_dim = 0; else if (left.type.dim == 1 && right.type.dim == 2) { tmp_dim = 1; index2 = getTempSize2(right, npp); tmp_size1="]["+index2; } else if (left.type.dim == 2 && right.type.dim == 1) { tmp_dim = 1; tmp_size1=getTempSize1(left, npp); } else if (left.type.dim == 2 && right.type.dim == 2) { tmp_dim = 2; tmp_size1=getTempSize1(left, npp); index2 = getTempSize2(right, npp); tmp_size2="]["+index2; } else if (left.type.dim == 3 && right.type.dim == 2) { tmp_dim = 2; } else if (left.type.dim == 2 && right.type.dim == 3) { tmp_dim = 2; } else if (left.type.dim == 3 && right.type.dim == 3) { tmp_dim = 3; } else if (left.type.dim == 3 && right.type.dim == 4) { tmp_dim = 3; } else if (left.type.dim == 4 && right.type.dim == 3) { tmp_dim = 3; } else if (left.type.dim == 4 && right.type.dim == 4) { tmp_dim = 4; } else tmp_dim = 0; // should not happen if (ret_bool) type = new TypeNode(TypeNode.BOOL, left); else type = new TypeNode(left.type); type.nslDim = type.dim = tmp_dim; } // if(op.tokentype == '*' && left.type.dim > 0 && right.type.dim > 0) else { if(op.tokentype == '*') op.tokentype = YYtokentypes.BIT_MUL; if(left.type.dim>right.type.dim) { if (ret_bool) type = new TypeNode(TypeNode.BOOL, left); else type = new TypeNode(left.type); tmp_dim = left.type.dim; if (tmp_dim>0) { tmp_size1=getTempSize1(left, npp); if(tmp_dim>1) { index2 = getTempSize2(left, npp); tmp_size2="]["+index2; if (op.tokentype != '@' && right.type.dim==1){ // invalid operation for addition // subtraction, multiplication // System.err.println("BinExpr: line "+(left.lineno+1)+ // " char "+(left.charno+1)+"\tOperand not match"); } } } } // if(left.type.dim>right.type.dim) else { // left.dim <= right.dim if (ret_bool) type = new TypeNode(TypeNode.BOOL, left); else type = new TypeNode(right.type); tmp_dim = right.type.dim; if(tmp_dim>0) { tmp_size1=getTempSize1(right, npp); if(tmp_dim>1) { // just convenient to add the comma here index2 = getTempSize2(right, npp); tmp_size2="]["+index2; if(op.tokentype != '@' && left.type.dim == 1) { // System.err.println("BinExpr: line "+(left.lineno+1)+ // " char "+(left.charno+1)+"\tOperand not match"); // invalid operation for addition // subtraction, multiplication } } } } // else } // not '*' /* precision of the temp variable si the highest of two input parameters */ if (ret_bool) tmp_prec = TypeNode.BOOL; else tmp_prec = left.type.type>right.type.type? left.type.type: right.type.type; type.type = tmp_prec; /* generate temp variable type */ if (tmp_prec == TypeNode.INT) { // cast it to integer type. // if (tmp_dim==0) tmp_precision = "int"; // else // tmp_precision = "int["; } else if (tmp_prec == TypeNode.FLOAT) { tmp_precision = "float"; } else if (tmp_prec == TypeNode.DOUBLE) { tmp_precision = "double"; } else if (tmp_prec == TypeNode.BOOL) { tmp_precision = "boolean"; } else { code = left.code+op.text+right.code; return NO_OP; } if(tmp_dim == 0) { if (left.nslSymbol) left.code+=".get()"; if (right.nslSymbol) right.code+=".get()"; code = "\n "+opname(op.tokentype)+"("+left.code+","+right.code+")"; type.nslNumeric=false; type.nslBool=false; /* ERH: 11/20/97 all math ops return native types*/ } else { // get temp number from the preprocessor tmp_number = tmp_num = npp.getNextTempNumber(); if (tmp_prec == TypeNode.BOOL) init_val = "false"; else init_val = "0"; if (tmp_dim==1) { // construct delcaration statment decl_stmt = npp.TEMP_ACCESS_FLAG+" "+tmp_precision+"[] "+ npp.TEMP_NUMBER_PREFIX+tmp_num+";"; // construct instantiation statement inst_stmt = npp.TEMP_NUMBER_PREFIX+tmp_num+" = new "+ // tmp_precision+tmp_size1+"];"; tmp_precision+"[1];"; // construct initialization statement init_stmt = "for (int i = 0; i < "+npp.TEMP_NUMBER_PREFIX+tmp_num+".length; i++) {\n\t\t"+ npp.TEMP_NUMBER_PREFIX+tmp_num+"[i] = "+init_val+";\n}"; npp.registerTempVar(tmp_num, decl_stmt, inst_stmt, init_stmt); } else if (tmp_dim == 2) { // construct delcaration statment decl_stmt = npp.TEMP_ACCESS_FLAG+" "+tmp_precision+"[][] "+ npp.TEMP_NUMBER_PREFIX+tmp_num+";"; inst_stmt = npp.TEMP_NUMBER_PREFIX+tmp_num+" = new "+ // tmp_precision+tmp_size1+tmp_size2+"];"; tmp_precision+"[1][1];"; // construct initialization statement init_stmt = "for (int i = 0; i < "+npp.TEMP_NUMBER_PREFIX+tmp_num+".length; i++) {\n"+ "\t\tfor (int j = 0; j < "+npp.TEMP_NUMBER_PREFIX+tmp_num+"[0].length; j++) {\n\t\t\t"+ npp.TEMP_NUMBER_PREFIX+tmp_num+"[i][j] = "+init_val+";\n\t\t}\n\t}"; npp.registerTempVar(tmp_num, decl_stmt, inst_stmt, init_stmt); } else if (tmp_dim == 3) { // construct delcaration statment decl_stmt = npp.TEMP_ACCESS_FLAG+" "+tmp_precision+"[][][] "+ npp.TEMP_NUMBER_PREFIX+tmp_num+";"; inst_stmt = npp.TEMP_NUMBER_PREFIX+tmp_num+" = new "+ tmp_precision+"[1][1][1];"; // construct initialization statement init_stmt = "for (int i = 0; i < "+npp.TEMP_NUMBER_PREFIX+tmp_num+".length; i++) {\n"+ "\t\tfor (int j = 0; j < "+npp.TEMP_NUMBER_PREFIX+tmp_num+"[0].length; j++) {\n"+ "\t\t\tfor (int k = 0; k < "+npp.TEMP_NUMBER_PREFIX+tmp_num+"[0][0].length; k++) {\n\t\t\t\t"+ npp.TEMP_NUMBER_PREFIX+tmp_num+"[i][j][k] = "+init_val+";\n\t\t\t}\n\t\t}\n\t}"; npp.registerTempVar(tmp_num, decl_stmt, inst_stmt, init_stmt); } else if (tmp_dim == 4) { // construct delcaration statment decl_stmt = npp.TEMP_ACCESS_FLAG+" "+tmp_precision+"[][][][] "+ npp.TEMP_NUMBER_PREFIX+tmp_num+";"; inst_stmt = npp.TEMP_NUMBER_PREFIX+tmp_num+" = new "+ tmp_precision+"[1][1][1][1];"; // construct initialization statement init_stmt = "for (int i = 0; i < "+npp.TEMP_NUMBER_PREFIX+tmp_num+".length; i++) {\n"+ "\t\tfor (int j = 0; j < "+npp.TEMP_NUMBER_PREFIX+tmp_num+"[0].length; j++) {\n"+ "\t\t\tfor (int k = 0; k < "+npp.TEMP_NUMBER_PREFIX+tmp_num+"[0][0].length; k++) {\n"+ "\t\t\t\tfor (int l = 0; l < "+npp.TEMP_NUMBER_PREFIX+tmp_num+"[0][0][0].length; l++) {\n\t\t\t\t\t"+ npp.TEMP_NUMBER_PREFIX+tmp_num+"[i][j][k][l] = "+init_val+";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}"; npp.registerTempVar(tmp_num, decl_stmt, inst_stmt, init_stmt); } if (left.nslSymbol) left.code+=".get()"; if (right.nslSymbol) right.code+=".get()"; code = "\n "+npp.TEMP_NUMBER_PREFIX+tmp_num+"=" +opname(op.tokentype)+"("+npp.TEMP_NUMBER_PREFIX+ tmp_num+","+left.code+","+right.code+")"; } } //System.out.println("GenCode: "+code); processed = true; type.nslNumeric = false; type.numeric = true; return SUCCESS; /*-----------------------------------------------------------------*/ /* ASSIGNMENT */ /*-----------------------------------------------------------------*/ case '=': /* RHS is a new expression node. If the currnet method is makeinst(), put the LHS name into the expression for default name generation Register this variable in the class node for automatic declaration generation. */ // System.out.println("// IN case '=' for ["+left.text+"="+right.text+"]"); if (npp.cur_method_type == MethodNode.MAKEINST && right instanceof NewNode) { // System.out.println("// IF satisfied"); NewNode nn = (NewNode)right; nn.addInstanceName(left.code); // generate the code again. nn.genCode(npp); if(nn.processed) processed=true; processed=true; code = left.code+"="+nn.code; //System.out.println("GenCode: "+code); // if an undeclared variable is found instantiated // with a new statement, the declaration part is // automatically generated. if(left.type == null || left.type.type == TypeNode.UNKNOWN) { // possible undeclared class data member // re-resolve the variable at the current // class level ExprNode resolved_expr = (ExprNode)npp.resolveVar((YYtoken)left); if(left.type == null || left.type.type == TypeNode.UNKNOWN) { // declare it in the class level decl_stmt = "\t"+nn.type.text; int dimension = nn.type.dim - nn.type.nslDim; for(int count=0; count < dimension; count++) { decl_stmt += "[]"; } decl_stmt += (" "+left.code+";"+" /* auto decl. */"); npp.addMakeInstDeclStmt(decl_stmt, new FormalNode(nn.type, left)); left.type = nn.type; } else if (right.type.type != left.type.type) { // type incompatible error } else { // everything's fine. continue. } } return NO_OP; } /*-------------------------------------------------------*/ { /// SPECIAL METHOD CALL HANDLING BLOCK boolean method_call_test = false; TypeNode typenode = null; /* If the RHS is a Method call, then check if it is a special port creation statement (out, in, env or envt). If the statement contains a new expression, add the LHS name as teh default port name Register this variable in the class node for automatic declaration generation. */ if (npp.cur_method_type == MethodNode.MAKEINST && right instanceof MethodCallNode && ((MethodCallNode)right).makeinst) { method_call_test = true; MethodCallNode mcn = (MethodCallNode)right; mcn.addInstanceName(left.code); mcn.genCode(npp); if(mcn.processed) processed=true; code = left.code+"="+mcn.code; typenode = mcn.type; } /* Sometimes, the method node could be covered by a cast node. Only the instance name is added into the construction statement. here assumes that the user with proficiency in adding 'cast' statement will handle the rest as well. */ if(npp.cur_method_type == MethodNode.MAKEINST && right instanceof CastNode) { CastNode cn = (CastNode)right; ExprNode newexpr = cn.expr; if (newexpr instanceof NewNode) { cn.setConstructorFlag(); method_call_test = true; ((NewNode)newexpr).addInstanceName(left.code); // typenode = newexpr.type; typenode = cn.type; } else if (newexpr instanceof MethodCallNode && ((MethodCallNode)newexpr).makeinst){ cn.setConstructorFlag(); method_call_test = true; ((MethodCallNode)newexpr).addInstanceName(left.code); //typenode = newexpr.type; typenode = cn.type; } right.genCode(npp); if (newexpr.processed) processed = true; code = left.code+"="+right.code; } if(method_call_test) { // if an undeclared variable is found instantiated // with a new statement, the declaration part is // automatically generated. /* TODO: we should not be doing this anymore - aa 98/10/3 */ if(left.type == null || left.type.type == TypeNode.UNKNOWN) { // possible undeclared class data member // re-resolve the variable at the current // class level ExprNode resolved_expr = (ExprNode)npp.resolveVar((YYtoken)left); if(resolved_expr.type == null || resolved_expr.type.type == TypeNode.UNKNOWN) { // declare it in the class level decl_stmt = "\t"+typenode.text; int dimension = typenode.dim - typenode.nslDim; if(dimension > 0) for(int count=0; count < dimension; count++) { decl_stmt += "[]"; } decl_stmt += (" "+left.code+";"+" /* ?? auto*/"); npp.addMakeInstDeclStmt(decl_stmt, new FormalNode(typenode, left)); left.type = typenode; } else if (typenode.type != resolved_expr.type.type) { // type incompatible error } else { // everything's fine. continue. } } return NO_OP; } // method_call_test /// SPECIAL METHOD CALL HANDLING BLOCK } //System.err.println("BinaryExprNode, it's a left hand call"); left.genCode(npp, true); //98/10/2 had checking for left.type null and right.type null // here but it turns out this happens in a lot of cases // Don't know why? /* ERH:11/20/97 BUG fix: if right side were a method call node then it used to retrun NO_OP, resulting a badly formed translation. Here I am catching this situation */ if (right instanceof MethodCallNode) { // code = left.code+right.code+")"; // System.err.println(" ++++ Checking "+((MethodCallNode)right).method_sym.text); // System.err.println(" ("+ left.type.txt+")"); // System.err.println(" "+ ((MethodCallNode)right).method_sym.text); if ((((MethodCallNode)right).method_sym.text.equals("nslRefParent"))) { //System.err.println(" ##############"+ // ((MethodCallNode)right).method_sym.text); code=left.code+op.text+"("+left.type.txt+")"+right.code+ "/* rule 104 */"; } //we will be adding this next case soon 98/10/3 aa else if ((((MethodCallNode)right).method_sym.text.equals("nslRef"))) { //System.err.println(" ##############"+ // ((MethodCallNode)right).method_sym.text); code=left.code+op.text+"("+left.type.txt+")"+right.code+ "/* rule 105 */"; } else if ((((MethodCallNode)right).method_sym.text.equals("nslValParent"))) { code = left.code+".set("+"("+left.type.txt+")"+right.code+") /* rule 106 */"; } else if (left.nslSymbol) { code = left.code+".set("+right.code+") /* rule 108 */"; } else //98/10/2 aa - I think this code is here as a default case if ((left.type!=null)&&(left.type.nslNumeric || left.type.nslBool)) { code = left.code+right.code+")/* rule 100 */";//98/10/2 aa added } else { code = left.code+op.text+right.code+"/* rule 102*/"; } //98/10/2 aa end //System.err.println(" CODE:"+ code); processed=true; return SUCCESS; } //end if right side is a Methodcall //98/10/2 had to move after check for nslRefParent if(left.type == null ){ //System.err.println("debug: leaving rule 198"); //System.err.println("debug:"+left.code+op.text+right.code); // Hope java can handle this - erhan //98/10/2 aa - I think this code is here as a default case if ((left.type!=null)&&(left.type.nslNumeric || left.type.nslBool)) { code = left.code+right.code+")/* rule 200 */";//98/10/2 aa added } else { code = left.code+op.text+right.code+"/* rule 202*/"; } return NO_OP; } if (right.type == null) { //System.err.println("debug: leaving rule 199"); //System.err.println("debug:"+left.code+op.text+right.code); // Hope java can handle this - erhan //98/10/2 aa - I think this code is here as a default case if ((left.type!=null)&&(left.type.nslNumeric || left.type.nslBool)) { code = left.code+right.code+")/* rule 206 */";//98/10/2 aa added } else { code = left.code+op.text+right.code+"/* rule 208*/"; } return NO_OP; } //98/10/2 aa begin // note: this castnode test has to come after the nslRef tests if ((left.type.nslNumeric || left.type.nslBool) && (right instanceof CastNode)) { //aa: 98/10/3 - bad but it will have to do for now TODO if ((left.code.indexOf(".set"))>0) { //System.err.println("debug:1"+left.code); //System.err.println("debug:op1:"+op.text); //System.err.println("debug:RIGHT:"+right.code); code=left.code+right.code+ ") /* rule 110 */"; processed=true; return SUCCESS; } else { //left nslNumeric and right cast //new case: nsltype=(nsltype)userfunc(); code=left.code+".set("+right.code+") /*rule 114 */"; processed=true; return SUCCESS; } } //end if nslNumeric //left side java numeric case or anything else if ((right instanceof CastNode || right instanceof NewNode)) { //System.err.println("debug:2:"+left.code); //System.err.println("debug:op2:"+op.text); //System.err.println("debug:RIGHT:"+right.code); code=left.code+op.text+right.code+ "/* rule 112 */"; processed=true; return SUCCESS; } //98/10/2 end aa /*** Usual assignment statments ***/ /* if (left.type.dim5) { //code = left.code+op.text+right.code; //System.err.println("debug: leaving rule 190"); return NO_OP; } if (left.type.numeric) { if (tmp_dim >0 && right.type.nslNumeric) { code = left.code+"="+right.code+".get"; if(left.type.type<=TypeNode.INT) code += "int2()"; else if (left.type.type<=TypeNode.FLOAT) code += "float2()"; else if (left.type.type<=TypeNode.DOUBLE) code += "double2()"; else code +="()"; } else if (tmp_dim == 0 && right.type.nslNumeric && right.type.dim == 0){ code = left.code+"="+right.code+".get()"; } else { code = left.code+op.text+right.code; //System.err.println("debug: leaving rule 192"); //System.err.println(left.code+op.text+right.code); return NO_OP; } processed = true; } //end left.type.numeric else if (left.type.nslNumeric || left.type.nslBool) { if(left instanceof ArrayIndexNode && left.type.nslDim > left.type.dim) { code = left.code+right.code+")"; } else { code = left.code+".set("+right.code+")"; } processed = true; } //left.type.nslNumeric else { //System.err.println("debug: leaving rule 196"); //System.err.println(left.code+"~"+op.text+"~"+right.code); code = left.code+op.text+right.code; return NO_OP; } /* --- end ASSIGNMENT */ default: { //System.err.println("debug: leaving rule 999"); //System.err.println(left.code+"~"+op.text+"~"+right.code); return NO_OP; } } // System.out.println("GenCode: "+code); // processed = true; //return SUCCESS; } /** Translate from operator code to operator name. * just lazy, we should create a hash table to store this information * @param o operator tokentype * @return operator name */ String opname(int o) { switch(o) { case '+': return ADD_NAME; case '-': return SUB_NAME; case '*': return PROD_NAME; case '/': return DIV_NAME; case '^': return CAP_NAME; case '@': return CONV_NAME; case YYtokentypes.EQUAL_COMPARE: return EQUAL_COMPARE_NAME; case YYtokentypes.NOT_EQUAL: return NOT_EQUAL_NAME; case YYtokentypes.LTEQ: return LTEQ_NAME; case YYtokentypes.GTEQ: return GTEQ_NAME; case '<': return LESS_NAME; case '>': return GTR_NAME; case YYtokentypes.BIT_MUL: return BIT_MUL_NAME; default: return null; } } // operation code -> NSL operation function name conversion table // 98/7/21 aa: changed cap to BIT_MUL final public static String CAP_NAME = "nslj.src.math.NslElemMult.eval"; final public static String EQUAL_COMPARE_NAME = "nslj.src.math.NslEqu.eval"; final public static String NOT_EQUAL_NAME = "nslj.src.math.NslNeq.eval"; final public static String LTEQ_NAME = "nslj.src.math.NslLeq.eval"; final public static String GTEQ_NAME = "nslj.src.math.NslGeq.eval"; final public static String LESS_NAME = "nslj.src.math.NslLes.eval"; final public static String GTR_NAME = "nslj.src.math.NslGtr.eval"; final public static String ADD_NAME = "nslj.src.math.NslAdd.eval"; final public static String SUB_NAME = "nslj.src.math.NslSub.eval"; final public static String BIT_MUL_NAME = "nslj.src.math.NslElemMult.eval"; final public static String DIV_NAME = "nslj.src.math.NslElemDiv.eval"; final public static String CONV_NAME = "nslj.src.math.NslConvZero.eval"; final public static String PROD_NAME = "nslj.src.math.NslProd.eval"; // return error code final public static int NO_OP = 0; final public static int SUCCESS = 1; final public static int INVALID_OP_ERROR = 2; final public static int HIGHER_DEGREE_ERROR = 3; final public static int DIM_NOT_MATCH_ERROR = 4;// for assignment statements final public static int INVALID_OPERAND_ERROR = 5; public ExprNode left; public ExprNode right; public YYtoken op; }