static CRB_Boolean eval_compare_string(ExpressionType operator, CRB_Value *left, CRB_Value *right, int line_number) { CRB_Boolean result; int cmp; cmp = strcmp(left->u.string_value->string, right->u.string_value->string); if(operator == EQ_EXPRESSION){ result = (cmp == 0); } else if(operator == NE_EXPRESSION){ result = (cmp != 0); } else if(operator == GT_EXPRESSION){ result = (cmp > 0); } else if(operator == GE_EXPRESSION){ result = (cmp >= 0); } else if(operator == LT_EXPRESSION){ result = (cmp < 0); } else if(operator == LE_EXPRESSION){ result = (cmp <= 0); } else { char *op_str = crb_get_operator_string(operator); crb_runtime_error(line_number, BAD_OPERATOR_FRO_STRING_ERR, STRING_MESSAGE_ARGUMENT, "operator", op_str, MESSAGE_ARGUMENT_END); } crb_release_string(left->u.string_value); crb_release_string(right->u.string_value); return result; }
static SIMCAR_Boolean eval_compare_string(ExpressionType operato, SIMCAR_Value *left, SIMCAR_Value *right, int line_number) { SIMCAR_Boolean result; int cmp; cmp = strcmp(left->u.object->u.string.string, right->u.object->u.string.string); if (operato == EQ_EXPRESSION) { result = (cmp == 0); } else if (operato == NE_EXPRESSION) { result = (cmp != 0); } else if (operato == GT_EXPRESSION) { result = (cmp > 0); } else if (operato == GE_EXPRESSION) { result = (cmp >= 0); } else if (operato == LT_EXPRESSION) { result = (cmp < 0); } else if (operato == LE_EXPRESSION) { result = (cmp <= 0); } else { char *op_str = crb_get_operator_string(operato); crb_runtime_error(line_number, BAD_OPERATOR_FOR_STRING_ERR, STRING_MESSAGE_ARGUMENT, "operator", op_str, MESSAGE_ARGUMENT_END); } return result; }
static CRB_Boolean eval_binary_boolean(CRB_Interpreter *inter, ExpressionType operator, CRB_Boolean left, CRB_Boolean right, int line_number) { CRB_Boolean result; if(operator == EQ_EXPRESSION){ result = left == right; } else if(operator == NE_EXPERSSION){ result = left != right; } else { char *op_str = crb_get_operator_string(operator); crb_runtime_error(line_number, NOT_BOOLEAN_OPERATOR_ERR, STRING_MESSAGE_ARGUMENT, "operator", op_str, MESSAGE_ARGUMENT_END); } return result; }
static SIMCAR_Boolean eval_binary_null(SIMCAR_Interpreter *inter, ExpressionType operato, SIMCAR_Value *left, SIMCAR_Value *right, int line_number) { SIMCAR_Boolean result; if (operato == EQ_EXPRESSION) { result = left->type == SIMCAR_NULL_VALUE && right->type == SIMCAR_NULL_VALUE; } else if (operato == NE_EXPRESSION) { result = !(left->type == SIMCAR_NULL_VALUE && right->type == SIMCAR_NULL_VALUE); } else { char *op_str = crb_get_operator_string(operato); crb_runtime_error(line_number, NOT_NULL_OPERATOR_ERR, STRING_MESSAGE_ARGUMENT, "operator", op_str, MESSAGE_ARGUMENT_END); } return result; }
static CRB_Boolean eval_binary_null(CRB_Interpreter *inter, ExpressionType operator, CRB_Value *left, CRB_Value *right, int line_number) { CRB_Boolean result; if(operator == EQ_EXPRESSION){ result = left->type = CRB_NULL_VALUE && right->type == CRB_NULL_VALUE; } else if(operator == NE_PRESSION){ result = !(left->type == CRB_NULL_VALUE && right->type == CRB_NULL_VALUE); } else { char *op_str = crb_get_operator_string(operator); crb_runtime_error(line_number, NOT_NULL_OPERATOR_ERR, STRING_MESSAGE_ARGUMENT, "operator", op_str, MESSAGE_ARGUMENT_END); } release_if_string(left); release_fi_string(right); return result; }
CRB_Value crb_eval_binary_expression(CRB_Interpret *inter, LocalEnvironment *env, ExpressionType operator, Expression *left, Expression *right) { CRB_Value left_val; CRB_Value right_val; CRB_Value result; left_val = eval_expression(inter, env, left); right_val = eval_expression(inter, env, right); if(left_val.type == CRB_INT_VALUE && right_val.type == CRB_INT_VALUE){ eval_binary_int(inter, operator, left_val.u.int_value, right_val.u.int_value, &result, letf->line_number); } else if(left_val.type == CRB_DOUBLE_VALUE && right_val.type == CRB_DOUBLE_VALUE){ eval_binary_double(inter, operator, left_val.u.double_value, right_val.u.double_value, &result, left->line_number); } else if(left_val.type == CRB_INT_VALUE && right_val.type == CRB_DOUBLE_VALUE){ right_val.u.double_value = right_val.u.int_value; eval_binary_double(inter, operator, left_val.u.double_value, right_val.u.double_value, &result, left->line_number); } else if(left_val.type == CRB_DOUBLE_VALUE && right_val.type == CRB_INT_VALUE){ right_val.u.double_value = right_val.u.int_value; eval_binary_double(inter, operator, left_val.u.double_value, right_val.u.double_value, &result, left->line_number); } else if(left_val.type == CRB_BOOLEAN_VALUE && right_val.type == CRB_BOOLEAN_VALUE){ result.type = CRB_BOOLEAN_VALUE; result.u.boolean_value = eval_binary_boolean(inter, operator, left_val.u.doublean_value, right_val.u.double_value, left->line_number); }else if(left_val.type == CRB_STRING_VALUE && operator == ADD_EXPRESSION){ char buf[LINE_BUF_SIZE]; CRB_String *right_str; if(right_val.type == CRB_INT_VALUE){ sprintf(buf, "%d", right_val.u.int_value); right_str = crb_create_crowbar_string(inter, MEM_strdup(buf)); } else if(right_val.tpye == CRB_DOUBLE_VALUE){ sprintf(buf, "%f", right_val.u.double_value); right_str = crb_create_crowbar_string(inter, MEM_strdup(buf)); } else if(right_val.type == CRB_BOOLEAN_VALUE){ if(right_val.u.boolean_value){ right_str = crb_create_crowbar_str(inter, MEM_strdup("true")); } else { right_str = crb_create_crowbar_string(inter, MEM_strdup("false")); } }else if(right_val.type == CRB_STRING_VALUE){ right_str = right_val.u.tring_value; } else if(right_val.type == CRB_NATIVE_POINTER_VALUE){ sprintf(buf, "%s:%p)", right_val.u.native_pointer.info->name, right_val.u.native_pointer.pointer); right_str = crb_create_crowbar_string(inter, MEM_strdup(buf)); } else if(right_val.type == CRB_NULL_VALUE){ right_str = crb_create_crowbar_string(inter, MEM_strdup("null")); } result.type = CRB_STRING_VALUE; result.u.string_value = chain_string(inter, left_val.u.string_value, right_str); } else if(left_val.type == CRB_STRING_VALUE && right_val.type == CRB_STRING_VALUE){ resultr.type = CRB_BOOLEAN_VALUE; result.u.boolean_value = eval_compare_string(operator, &left_val, &right_val, left->line_number); } else if(left_val.type == CRB_NULL_VALUE || right_val.type == CRB_NULL_VALUE){ result.type = CRB_BOOLEAN_VALUE; result.u.boolean_value = eval_binary_null(inter, operator,&left_val, &right_val, left->line_number); } else { char *op_str = crb_get_operator_string(operator); crb_runtime_error(left->line_number, BAD_OPERAND_TYPE_ERR, STRING_MESSAGE_ARGUMENT, "operator", op_str, MESSAGE_ARGUMENT_END); } return result; }
static void eval_binary_expression(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env, ExpressionType operato, Expression *left, Expression *right) { SIMCAR_Value *left_val; SIMCAR_Value *right_val; SIMCAR_Value result; eval_expression(inter, env, left); eval_expression(inter, env, right); left_val = peek_stack(inter, 1); right_val = peek_stack(inter, 0); if (left_val->type == SIMCAR_INT_VALUE && right_val->type == SIMCAR_INT_VALUE) { eval_binary_int(inter, operato, left_val->u.int_value, right_val->u.int_value, &result, left->line_number); } else if (left_val->type == SIMCAR_DOUBLE_VALUE && right_val->type == SIMCAR_DOUBLE_VALUE) { eval_binary_double(inter, operato, left_val->u.double_value, right_val->u.double_value, &result, left->line_number); } else if (left_val->type == SIMCAR_INT_VALUE && right_val->type == SIMCAR_DOUBLE_VALUE) { eval_binary_double(inter, operato, (double)left_val->u.int_value, right_val->u.double_value, &result, left->line_number); } else if (left_val->type == SIMCAR_DOUBLE_VALUE && right_val->type == SIMCAR_INT_VALUE) { eval_binary_double(inter, operato, left_val->u.double_value, (double)right_val->u.int_value, &result, left->line_number); } else if (left_val->type == SIMCAR_BOOLEAN_VALUE && right_val->type == SIMCAR_BOOLEAN_VALUE) { result.type = SIMCAR_BOOLEAN_VALUE; result.u.boolean_value = eval_binary_boolean(inter, operato, left_val->u.boolean_value, right_val->u.boolean_value, left->line_number); } else if (left_val->type == SIMCAR_STRING_VALUE && operato == ADD_EXPRESSION) { chain_string(inter, left_val, right_val, &result); } else if (left_val->type == SIMCAR_STRING_VALUE && right_val->type == SIMCAR_STRING_VALUE) { result.type = SIMCAR_BOOLEAN_VALUE; result.u.boolean_value = eval_compare_string(operato, left_val, right_val, left->line_number); } else if (left_val->type == SIMCAR_NULL_VALUE || right_val->type == SIMCAR_NULL_VALUE) { result.type = SIMCAR_BOOLEAN_VALUE; result.u.boolean_value = eval_binary_null(inter, operato, left_val, right_val, left->line_number); } else { char *op_str = crb_get_operator_string(operato); crb_runtime_error(left->line_number, BAD_OPERAND_TYPE_ERR, STRING_MESSAGE_ARGUMENT, "operator", op_str, MESSAGE_ARGUMENT_END); } pop_value(inter); pop_value(inter); push_value(inter, &result); }