int NMethodCall::checkParams(Node* funcParams) { int isValid = 1; node_children_t thisParams = children[0]->getChildren(); int thisSize = thisParams.size(); int expectedSize = funcParams->getChildrenSize(); /* Do we have the same number of expected and given arguments? */ if(thisSize != expectedSize) { printErrorHeader("method call"); error_num_args(name, expectedSize, thisSize); isValid = 0; } /* Compare the arguments and ensure they are of the same type. */ int i = 0; int j = 0; int expectedType, givenType; string varName; while( i < expectedSize && j < thisSize) { expectedType = funcParams->getChild(i)->getType(); givenType = thisParams[j]->getType(); if(!compareTypes(expectedType, givenType)) { varName = thisParams[j]->getID(); printErrorHeader("method call"); error_type_mismatch(varName, givenType, expectedType); isValid = 0; } ++i; ++j; } return isValid; }
int NUnaryOp::checkBoolean() { if(type != BOOLEAN) { printErrorHeader("unary operator"); error_type_mismatch(op, type, BOOLEAN); return 0; } return 1; }
/*GRAMMAR GET TYPES*/ struct expression_data_t* get_expr_expr_data(struct expression_t *expr, struct attribute_table_t* attr_hash_table, struct function_declaration_t *statement_func, int line_number) { if(expr->expr != NULL && expr->expr->type != NULL) { return expr->expr; /*we already have type*/ } else if(expr->se2 == NULL) /* if se2 is null then the expression type is the type of se1 */ { return get_simple_expr_expr_data(expr->se1, attr_hash_table, statement_func, line_number); } else { struct expression_data_t *se1_data = get_simple_expr_expr_data(expr->se1, attr_hash_table, statement_func, line_number); struct expression_data_t *se2_data = get_simple_expr_expr_data(expr->se2, attr_hash_table, statement_func, line_number); switch(expr->relop) { case RELOP_EQUAL: case RELOP_NOTEQUAL: if(strcmp(se1_data->type, se2_data->type)) { error_type_mismatch(line_number, se1_data->type, se2_data->type); } break; case RELOP_LT: case RELOP_GT: case RELOP_LE: case RELOP_GE: if( !is_integer(se1_data->type) && !is_real(se1_data->type) ) { error_datatype_is_not(line_number, se1_data->type, "real or integer"); } if( !is_integer(se2_data->type) && !is_real(se2_data->type) ) { error_datatype_is_not(line_number, se2_data->type, "real or integer"); } break; } return set_expression_data(EXPRESSION_DATA_BOOLEAN, "boolean"); } }
int NUnaryOp::check() { int isValid = 1; this->type = resolveType(); /* Do we have a unary boolean expression? (i.e. NOT) */ if(op == LNOT) { return checkBoolean(); } /* Valid if the type is a number and the children are valid. */ isValid &= Node::check(); /* Is the type invalid? */ if(type == INVALIDTYPE) { printErrorHeader("unary operator"); error_type_mismatch(op, children[0]->getType(), TNUMBER); isValid = 0; } return isValid; }
void validate_assignment_statement(struct statement_table_t* statement, struct attribute_table_t* attr_hash_table, struct function_declaration_t *statement_func) { struct assignment_statement_t *a_stat = statement->statement_data->as; if(a_stat->va->type == VARIABLE_ACCESS_T_IDENTIFIER) { if(is_true(a_stat->va->data.id) || is_false(a_stat->va->data.id)) { error_datatype_is_not(statement->line_number, "boolean", "variable"); } if(!strcmp(a_stat->va->data.id, statement_func->fh->id)) { if(a_stat->e != NULL) { struct expression_data_t *expr_type = get_expr_expr_data(a_stat->e, attr_hash_table, statement_func, statement->line_number); if(structurally_equivalent(set_expression_data(-1, statement_func->fh->res), expr_type)) { return; } else { error_datatype_is_not(statement->line_number, expr_type->type, statement_func->fh->res); } } else { struct expression_data_t *obj_type = get_obj_inst_expr_data(a_stat->oe, attr_hash_table, statement_func, statement->line_number); if(structurally_equivalent(set_expression_data(-1, statement_func->fh->res), obj_type)) { return; } else { error_datatype_is_not(statement->line_number, obj_type->type, statement_func->fh->res); } } return; } } struct expression_data_t *va_type = get_va_expr_data(a_stat->va, attr_hash_table, statement_func, statement->line_number); if(a_stat->e != NULL) { struct expression_data_t *expr_type = get_expr_expr_data(a_stat->e, attr_hash_table, statement_func, statement->line_number); if(!structurally_equivalent(va_type, expr_type)) /*types are different*/ { struct class_table_t *class_check = NULL; HASH_FIND_STR(g_class_table_head, va_type->type, class_check); if(class_check != NULL) { if(class_check->extend != NULL && !strcmp(class_check->extend->id, expr_type->type)) { return; } } error_type_mismatch(statement->line_number, va_type->type, expr_type->type); } } else /*has an object_instantiation*/ { struct expression_data_t *obj_inst_type = get_obj_inst_expr_data(a_stat->oe, attr_hash_table, statement_func, statement->line_number); if(!structurally_equivalent(va_type, obj_inst_type)) /*types are different*/ { struct class_table_t *class_check = NULL; HASH_FIND_STR(g_class_table_head, va_type->type, class_check); if(class_check != NULL) { if(class_check->extend != NULL && !strcmp(class_check->extend->id, obj_inst_type->type)) { return; } } error_type_mismatch(statement->line_number, va_type->type, obj_inst_type->type); } } }