void check_is_valid_indexed_vector(DictItem *vector, comp_tree_t *int_expr) { // Tests if variable has been defined. if (!check_id_declr(vector)) { sserror(IKS_ERROR_UNDECLARED, vector); exit(IKS_ERROR_UNDECLARED); } if (!check_id_isvector(vector)) { sserror(IKS_ERROR_FUNCTION, vector); exit(IKS_ERROR_FUNCTION); } // Checks if expression is an integer (char) if (int_expr->data.semanticType == SYMTYPE_CHAR) { sserror(IKS_ERROR_CHAR_TO_X, NULL); exit(IKS_ERROR_CHAR_TO_X); } // Checks if expression is an integer (string) if (int_expr->data.semanticType == SYMTYPE_STRING) { sserror(IKS_ERROR_STRING_TO_X, NULL); exit(IKS_ERROR_STRING_TO_X); } // Checks if expression is an integer (string) if (int_expr->data.semanticType != SYMTYPE_INT) { sserror(IKS_ERROR_WRONG_TYPE, NULL); //TODO futuro: incluir cod de erro para indice nao inteiro. exit(IKS_ERROR_WRONG_TYPE); } }
/** Detecção de erros com string ou char */ void check_coercaoimpossivel_char_string(comp_tree_t *expr1, comp_tree_t *expr2) { if (eval_infer(expr1->data.semanticType, expr2->data.semanticType,&(expr1->data.semanticType), &(expr2->data.semanticType)) == IKS_ERROR_STRING_TO_X) { sserror(IKS_ERROR_STRING_TO_X, NULL); exit(IKS_ERROR_STRING_TO_X); } else if (eval_infer(expr1->data.semanticType, expr2->data.semanticType,&(expr1->data.semanticType), &(expr2->data.semanticType)) == IKS_ERROR_CHAR_TO_X) { sserror(IKS_ERROR_CHAR_TO_X, NULL); exit(IKS_ERROR_CHAR_TO_X); } }
struct in_out elaborateUnaryLeft(const Context &context, struct unary_expression &arg, int selfchange, bool ifContext) { /* Будем считать, что в левой части может быть только модицицируемый Lvalue как в стандарте * ограничимся только элементами массива или полями записей/объединений с кастингом */ struct in_out result; if (arg._postfix_ != NULL) { return elaboratePostfixExpressionLeft(context, *arg._postfix_, selfchange, ifContext); } if (arg._cast_ != NULL) { /* Remember pointer - '*' cast_expression struct unary_cast{ // unary_operator _cast_ char *unary_operator; // '&' | '*' | '+' | '-' | '~' | '!' struct cast_expression _cast_; }; */ if (arg._cast_->unary_operator == '*') { // named pointer case return skipCastingLeft(context, arg._cast_->_cast_, selfchange, ifContext); } else { sserror("Illegal Lvalue operation", arg._cast_->lt); } // FIXME - check for pointers deeds return result; } if (arg._change_ != NULL) { struct change_unary *temp = arg._change_; if (temp->op == "sizeof") { sserror("Lvalue required - sizeof = ", temp->lt); } if (temp->op == "++" || temp->op == "--") { sserror("Invalid Lvalue in assignment", temp->lt); } return result; // no such case } if (arg._sizeof_ != NULL) { // no variables - only type_name sserror("Lvalue required - sizeof = ", arg._sizeof_->lt); return result; } return result; }
void check_is_id_fun(DictItem *fun) { // Tests if variable has been defined. if (!check_id_declr(fun)) { sserror(IKS_ERROR_UNDECLARED, fun); exit(IKS_ERROR_UNDECLARED); } // Tests if was defined as function if (!check_id_isfunction(fun)) { sserror(IKS_ERROR_FUNCTION, fun); exit(IKS_ERROR_FUNCTION); } }
void check_is_id_var(DictItem *var) { // Tests if variable has been defined. if (!check_id_declr(var)) { sserror(IKS_ERROR_UNDECLARED, var); exit(IKS_ERROR_UNDECLARED); } if (!check_id_isvariable(var)) { sserror(IKS_ERROR_VARIABLE, var); exit(IKS_ERROR_VARIABLE); } }
void check_is_valid_output(comp_tree_t *expr) { if (expr->data.semanticType == SYMTYPE_CHAR || expr->data.semanticType == SYMTYPE_BOOL) { sserror(IKS_ERROR_WRONG_PAR_OUTPUT, NULL); exit(IKS_ERROR_WRONG_PAR_OUTPUT); } }
struct in_out elaboratePostFixAddonLeft(const Context &context, struct postfix_addon &arg, int selfchange, bool ifContext) { /* struct postfix_addon{ struct postfix_expression _main_; // only one must be non-NULL struct expression *_arrayindex_; // '[' expression ']' BOOLEAN is_braces; // '(' ')' struct argument_expression_list *_args_; //'(' argument_expression_list ')' struct qualified *_attribute_; BOOLEAN is_inc; // ++ BOOLEAN is_dec; // -- }; */ // Правила простые - сначала проверяется _main_ потом все остальное. struct in_out result; // первый случай - квалифицированный атрибут. if (arg. _attribute_ != NULL) { // нас интересует только переменная, а не поля - идем выше. return elaboratePostfixExpressionLeft(context, arg._main_, selfchange, ifContext); } // аргументы функции - слева не допустим вызов if (arg._args_ != NULL) { sserror("Invalid Lvalue in assignment - function call in left part of assignment", arg._args_->lt); } // функция без параметров - аналогично предыдущему случаю if (arg.is_braces) { sserror("Invalid Lvalue in assignment - function call in left part of assignment", arg.lt); } // индексирование if (arg._arrayindex_ != NULL) { return elaborateArrayIndexLeft(context, arg, ifContext); } // инкремент/декрeмент if (arg.is_inc || arg.is_dec) { sserror("Invalid Lvalue in assignment", arg.lt); } return result; }
struct in_out elaboratePostfixBeforeIncrement(const Context &context, struct postfix_expression &arg, bool ifContext) { struct in_out result; if (arg._primary_ != NULL) { // must check for enum's id and pointer area overloading // insert id and type to set if (arg. _primary_-> _name_ != NULL) { string name(arg. _primary_->_name_); //cout<<"Getting name3 '"<<name<<"'"<<endl; TParam par(name, context. getTypeInfo(name), ifContext); result.insertOut(par); result.insertIn(par); return result; } // если применяется к скобкам, то изменятся последняя переменная, которая // меняется внутри (либо ++,--, либо =) но она и так в списке if (arg. _primary_->_braces_ != NULL) return scanExpression(context, *arg._primary_->_braces_, ifContext); } if (arg._addon_ != NULL) { // инкремент/декрeмент if (arg._addon_->is_inc || arg._addon_->is_dec) { // откусываем все ++/-- то что получилось проверяем на допустимость result = elaboratePostfixBeforeIncrement(context, arg._addon_->_main_, ifContext); result. weight += options.get( (arg._addon_->is_inc) ? "++" : "--"); return result; } // все откусили, проверяем, что осталось if (arg._addon_->is_braces || arg._addon_->_args_ != NULL) { sserror("Lvalue required (++/-- operation)", arg._addon_->lt); return result; } if (arg._addon_->_attribute_ != NULL) { // нас интересует только переменная, а не поля - идем выше. return elaboratePostfixBeforeIncrement(context, arg._addon_->_main_, ifContext); } // индексирование if (arg._addon_->_arrayindex_ != NULL) { result = scanExpression(context, *(arg._addon_->_arrayindex_), ifContext); // check for array name concat(result, elaboratePostfixBeforeIncrement(context, arg._addon_->_main_, ifContext), options. get ("[]")); return result; } //return elaboratePostFixAddonRight(*arg._addon_); } return result; }
struct in_out elaborateUnaryAfterIncrement(const Context &context, struct unary_expression &arg, bool ifContext) { struct in_out result; // skip all increments/decrements if (arg._postfix_ != NULL) { return elaboratePostfixBeforeIncrement(context, *arg._postfix_, ifContext); } if (arg._cast_ != NULL) { // FIXME - unknown situation /* Remember pointer - '*' cast_expression struct unary_cast{ // unary_operator _cast_ char *unary_operator; // '&' | '*' | '+' | '-' | '~' | '!' struct cast_expression _cast_; }; return elaboratePostfixExpressionRight(*arg._postfix_, ifContext); */ } if (arg._change_ != NULL) { struct change_unary *temp = arg._change_; if (temp->op == "sizeof") { sserror("Lvalue required - ++/--", temp->lt); } if (temp->op == "++" || temp->op == "--") { result = elaborateUnaryAfterIncrement(context, temp->_operand_, ifContext); result. weight += options. get (temp->op); return result; } return result; // no such case } if (arg._sizeof_ != NULL) { // illegal inc\dec arg sserror("Lvalue required - ++/--", arg._sizeof_->lt); } return result; }
void check_is_valid_input(comp_tree_t *expr) { // Tests if expr is something valid (i.e. is declared in symbol table) if (expr->data.symEntry == NULL) { sserror(IKS_ERROR_WRONG_PAR_INPUT, NULL); exit(IKS_ERROR_WRONG_PAR_INPUT); } // Tests if identifier is a variable or vector if (!check_id_isvariable(expr->data.symEntry)) { sserror(IKS_ERROR_WRONG_PAR_INPUT, expr->data.symEntry); exit(IKS_ERROR_WRONG_PAR_INPUT); } if (!check_id_isvector(expr->data.symEntry)) { sserror(IKS_ERROR_WRONG_PAR_INPUT, expr->data.symEntry); exit(IKS_ERROR_WRONG_PAR_INPUT); } // Tests if variable has been defined (typed) if (!check_id_declr(expr->data.symEntry)) { sserror(IKS_ERROR_UNDECLARED, expr->data.symEntry); exit(IKS_ERROR_UNDECLARED); } }
struct in_out elaboratePrimaryExpressionLeft(const Context &context, struct primary_expression &arg, int selfchange, bool ifContext) { struct in_out result; // must check for enum's id and pointer area overloading // insert id and type to set if (arg. _name_ != NULL) { string name(arg. _name_); //cout<<"Getting name4 '"<<name<<"'"<<endl; TParam par(name, context. getTypeInfo(name), ifContext); result.insertOut(par); if (selfchange) result.insertIn(par); return result; } if (arg._braces_ != NULL) sserror("Braces in left part unsupported yet", arg._braces_->lt); return result; }
void sserror(char *arg, const Tpos &pos) { sserror(string(arg), pos); }
struct in_out elaborateArrayIndex(const Context &context, struct postfix_addon &arg, bool left, bool ifContext) { // Only [] allowed w/o . or -> struct postfix_addon *temp = &arg; // copy int size = 0; struct in_out result; // find sequence length while (temp->_arrayindex_ != NULL) { size++; if (temp->_main_. _addon_ != NULL) { // postfix-addon case temp = temp->_main_. _addon_; } else { break; } //if (temp->_main_. _primary_ != NULL) break; } // now we must have ref to primary else - semantic error if (temp->_main_. _primary_ == NULL) sserror("Only scalars and arrays are supported", temp->_main_.lt); string name; int dimension = size; if (temp->_main_. _primary_-> _name_ != NULL) { name = string(temp->_main_. _primary_-> _name_); } else { sserror("Name of array required", temp->_main_._primary_->lt); } // create storage TIndex *ref = new TIndex[size]; temp = &arg; while (temp->_arrayindex_ != NULL) { size--; concat(result, scanExpression(context, *temp->_arrayindex_, ifContext), options. get ("[]")); ref[size] = TIndex(temp->_arrayindex_); if (temp->_main_. _addon_ != NULL) { // postfix-addon case temp = temp->_main_. _addon_; } else { break; } } //cout<<"Getting name2 '"<<name<<"'"<<endl; TParam par(name, ref, dimension, context. getTypeInfo(name), ifContext); if (left == true) { result. insertOut(par); } else { result. insertIn(par); } delete[] ref; return result; }