예제 #1
0
void Parser  :: CheckReturn(FuncSymbol *func
                            ){
    ReturnStatement *ret = nullptr;
    SymbolType *real_type = func->value->getType();
    int size = func->body->body.size();
    for(int i = 0; i < size && !ret; i++)
        ret = dynamic_cast<ReturnStatement*>(func->body->body[i]);
    if(!ret || !ret->value ){

        errorIf((func->name != "main" && real_type->name != "void") , "Wrong return type", scan.Get());
        return;
    }
    SymbolType *a = ret->value->getType();
    errorIf(!a->canConvertTo(real_type), "Wrong return type", scan.Get());
}
예제 #2
0
SymbolType* FuncCallNode::getType(){
	if(nodeType)
		return nodeType;
	FuncSymbol* sym = dynamic_cast<FuncSymbol*>(symbol);
	int formalParametersCount = sym->params->size();
	int realParametersCount = args.size();
	if (formalParametersCount != realParametersCount)
		throw MyException("Incorrect parameters count", token);
	for (int i = 0; i < formalParametersCount; i++)
	{
		SymbolType* realParamType = args[i]->getType();
		SymbolType* formalParamType = sym->params->sym_ptr[i]->getType();
		if (!realParamType->canConvertTo(formalParamType))
			throw MyException("Invalid type of parameter", args[i]->token);
		args[i] = makeTypeCoerce(args[i], realParamType, formalParamType);
	}
	return symbol->getType();
}
예제 #3
0
SymbolType *UnaryOpNode::getType(){
	if(nodeType)
		return nodeType;
	SymbolType *type = operand->getType();
	Values operation = token->value;
	switch(operation){

	case factor:
			if(!dynamic_cast<PointerSymbol*>(type))
				throw MyException("Type of unary operation is not a pointer", token);
			nodeType = dynamic_cast<PointerSymbol*>(type)->pointer;
			return nodeType;
	
	case b_and:									
		if(!operand->isLvalue())							
			throw MyException("Expression must be a modifiable lvalue", token->line, token->start);
		nodeType = new PointerSymbol(type);
		return nodeType;
		
	case b_not:
		operand = makeTypeCoerce(operand, type, IntType);
		break;

	case l_not:
		if(dynamic_cast<StructSymbol*>(type))
			throw MyException("No operator \"!\" matches these operands operand types are: !" + type->name, token);
		break;

	case incr:
	case  decr:
		if(!operand->isModifiableLvalue())
			throw MyException("Expression must be a modifiable lvalue", token);
		break;
	case Values::minus:
		if(!type->canConvertTo(FloatType))
			throw MyException("Expression must have arithmetical type", token);
	}
	nodeType = type;
	return type;
}
예제 #4
0
SymbolType *BinaryOpNode::getType(){
	if(nodeType)
		return nodeType;
	SymbolType *leftType = left->getType();
	SymbolType *rightType = right->getType();
	if(rightType == VoidType)
		throw MyException("Type casting error", token);
	Values operation = token->value;
	SymbolType *maxType = 0;
	if(operationTypeOperands.count(operation))
		maxType = operationTypeOperands[operation];
	else
		maxType = typePriority[leftType] > typePriority[rightType] ? leftType : rightType;
	PointerSymbol *l_pointer = dynamic_cast<PointerSymbol*>(leftType);
	PointerSymbol *r_pointer= dynamic_cast<PointerSymbol*>(rightType);
	ArraySymbol *l_array = dynamic_cast<ArraySymbol*>(leftType);
	ArraySymbol *r_array = dynamic_cast<ArraySymbol*>(rightType);

	switch(operation){

	case per_eql:
	case or_eql:
	case and_eql:
	case xor_eql:
	case sr_eql:
	case sl_eql:
		if(!leftType->canConvertTo(IntType) || !rightType->canConvertTo(IntType))
			throw MyException("Expression must have integral type", token);

	case assign:

		if(leftType->isStruct() && *leftType == rightType){
			nodeType = leftType;
			return leftType;
		}

	case pl_eql:
	case mn_eql:
	case fct_eql:
	case div_eql:
		if(!left->isModifiableLvalue())
			throw MyException("Expression must be a modifiable lvalue", token);
		right = makeTypeCoerce(right, rightType, leftType);
		nodeType = rightType;
		return rightType;

	case point:
		if(!dynamic_cast<StructSymbol*>(leftType))
			throw MyException("Left operand of . must be a structure", token);
		nodeType = rightType;
		return rightType;

	case arrow:	
		if(!l_pointer || !dynamic_cast<StructSymbol*>(l_pointer->upType()))
			throw MyException("Left operand of -> must be of pointer-to-structure type", left->token);
		nodeType = rightType;
		return rightType;

	case Values::minus:
		if(l_pointer && r_pointer || l_array && r_array){
			if( l_pointer && r_pointer && (*l_pointer->pointer != r_pointer->pointer)
				|| l_array && r_array && (*l_array->type != r_array->type))
				throw MyException("Operand types are incompatible", token);
			nodeType = IntType;
			return IntType;
		}
		
	case Values::plus:
		if(l_pointer && r_pointer || l_array && r_array)
			throw MyException("Can't add two pointers");
		if(l_pointer || r_pointer)
			return l_pointer == 0 ? r_pointer : l_pointer;
		if(l_array || r_array){
			nodeType = new PointerSymbol(l_array == 0 ? r_array->type : l_array->type);
			return nodeType;
		}
		
	default:
		if(leftType->isStruct() || rightType->isStruct())
			throw MyException("Can't perform operation over two structures", token);
		if(typePriority[maxType] < max(typePriority[leftType], typePriority[rightType]))
			throw MyException("Invalid type of operands", token);
		left = makeTypeCoerce(left, leftType, maxType);
		right = makeTypeCoerce(right, rightType, maxType);
		if (operationReturningType.count(operation)){
			nodeType = operationReturningType[operation];
			return nodeType;
		}
		else{
			nodeType = maxType;
			return maxType;
		}
	}
}