/* 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;
}