Attribute* binary_operator( Attribute* attr1, Attribute* attr2, int op, int reverse, int rm1, int rm2, int lno) { if(attr1==NULL || attr2==NULL) die(lno, "NULL pointer for attr1 or attr2\n"); if(reverse) { Attribute* tmp = attr1; attr1 = attr2; attr2 = tmp; } Attribute* result; switch (op) { case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: result = math_operator(attr1, attr2, op, lno);break; case OP_GT: case OP_LT: case OP_GE: case OP_LE: result = relational_operator(attr1, attr2, op, lno);break; case OP_AND: case OP_OR: result = logic_operator(attr1, attr2, op, lno); break; case OP_EQ: case OP_NE: result = equal_operator(attr1, attr2, op, lno); break; default: die(lno, "binary_opertor: unsupported OP %d.\n", op); } if(rm1==FLAG_DESTROY_ATTR) destroy_attr(attr1); if(rm2==FLAG_DESTROY_ATTR) destroy_attr(attr2); return result; }
Attribute* cast_operator(Attribute* attr1, int type, int rm_attr1, int lno) { if(attr1 == NULL) die(lno, "NULL Attribute error"); int type1 = attr1->type; Attribute* result; if(type1 == INT_T && type == FLOAT_T) { result = new_attr(FLOAT_T, NULL); result->value.fv = (float)attr1->value.iv; } else if(type1 == FLOAT_T && type == INT_T) { result = new_attr(INT_T, NULL); result->value.iv = (int)attr1->value.fv; } else if(type1 == INT_T && type ==INT_T) { result = new_attr(INT_T, NULL); result->value.iv = attr1->value.iv; } else if(type1 == FLOAT_T && type == FLOAT_T) { result = new_attr(FLOAT_T, NULL); result->value.fv = attr1->value.fv; } else die(lno, "cast_operator: illegal type conversion "); if(rm_attr1==FLAG_DESTROY_ATTR) destroy_attr(attr1); return result; }
//static = attr1 void assign_operator_to_static(Attribute* attr1, int type, void* value, int rm_attr1, int lno) { if(attr1 == NULL) die(lno, "assign_operator_to_static: <null> Attribute error\n "); int type1 = attr1->type; if(type1 == type) { switch(type) { case INT_T: *(int*)value = attr1->value.iv; break; case FLOAT_T: *(float*)value = attr1->value.fv; break; case BOOL_T: *(bool*)value = attr1->value.bv; break; case STRING_T: value = attr1->value.sv; break; default: die(lno, "assign_operator_to_static: incompatible type\n"); } } else if(type1==FLOAT_T && type==INT_T) { *(int*)value = (int)(attr1->value.fv); } else if(type1==INT_T && type==FLOAT_T) { *(float*)value = (float)(attr1->value.iv); } else die(lno, "assign_operator_to_static: incompatible type\n"); if(rm_attr1==FLAG_DESTROY_ATTR) destroy_attr(attr1); }
static void destroy_attr_from_table ( gpointer key, gpointer entry, gpointer dummy2 ) { if(entry == NULL) return; Attribute * attr = (Attribute *) entry; #ifdef _DEBUG char * attr_name = (char *) key; fprintf(stderr, "DEBUG: Remove attr `%s' from table \n", attr_name); #endif destroy_attr( attr ); }
Attribute* unary_operator(Attribute* attr1, int op,int rm_attr1, int lno) { if(attr1 == NULL) die(lno, "NULL Attribute error"); int type1 = attr1->type; Attribute* result; switch(op) { case OP_PLUS: if(type1 == INT_T) { result = new_attr(INT_T, NULL); result->value.iv = +(attr1->value.iv); } else if(type1 == FLOAT_T) { result = new_attr(FLOAT_T, NULL); result->value.fv = +(attr1->value.fv); } else die(lno, "unary_operator: incompatible type.\n"); break; case OP_MINUS: if(type1 == INT_T) { result = new_attr(INT_T, NULL); result->value.iv = -(attr1->value.iv); } else if(type1 == FLOAT_T) { result = new_attr(FLOAT_T, NULL); result->value.fv = -(attr1->value.fv); } else die(lno, "unary_operator: incompatible type.\n"); break; case OP_NOT: if(type1 == BOOL_T) { result = new_attr(BOOL_T, NULL); result->value.bv = !(attr1->value.bv); } else die(lno, "unary_operator: incompatible type %d.\n", type1); break; default: die(lno, "unary_operator: unknown operator.\n"); break; } if(rm_attr1==FLAG_DESTROY_ATTR) destroy_attr(attr1); return result; }
//attr1 = attr2 Attribute* assign_operator(Attribute* attr1, Attribute* attr2, int rm_attr1, int rm_attr2, int lno) { if(attr1 == NULL || attr2 == NULL) die(lno, "assign_operator: <null> Attribute error\n"); if(attr1->type == UNKNOWN_T) attr1->type = attr2->type; int type1 = attr1->type, type2 = attr2->type; if(type1 == type2) { switch(type1) { case INT_T: attr1->value.iv = attr2->value.iv; break; case FLOAT_T: attr1->value.fv = attr2->value.fv; break; case BOOL_T: attr1->value.bv = attr2->value.bv; break; case STRING_T: if(attr1->value.sv != NULL) g_string_free(attr1->value.sv,1); attr1->value.sv = g_string_new( (attr2->value.sv)->str ); break; default: die( lno, "assign_operator : incompatible type.\n"); } } else if(type1==FLOAT_T && type2==INT_T) { attr1->value.fv = (float)(attr1->value.iv); } else if(type1==INT_T && type2==FLOAT_T) { attr1->value.iv = (int)(attr2->value.fv); } else die( lno, "assign_operator : incompatible type.\n"); if(rm_attr2==FLAG_DESTROY_ATTR) destroy_attr(attr2); return attr1; }
Attribute* assign_operator_attr(Attribute** a1, Attribute* a2) { if (*a1 != NULL) destroy_attr(*a1); //gcDef(*a1, DYN_ATTR_T); gcRef(a2, DYN_ATTR_T); return *a1 = a2; }