void BinOpNode::generateLvalue(AsmCode& code){
	string value = token->Value;
	if (value == "+"){
		
			SymbolType *type = left->getType();
		if (dynamic_cast<ArraySymbol*>(type))
			left->generateLvalue(code);
		else if (dynamic_cast<PointerSymbol*>(type))
			left->generate(code);
		SymbolType *t = type->upType();
			right->generate(code);
		
			code.add(_POP, _EAX)
				.add(_MOV, _EBX, to_string(t->byteSize()))
				.add(_IMUL, _EAX, _EBX)
				.add(_POP, _EBX)
				.add(_ADD, _EAX, _EBX)
				.add(_PUSH, _EAX);
			t = t->upType();
		
		
	}
	else	if (isAssing(token)){ 
		generate(code);
		code.add(_POP, _EAX);
		left->generateLvalue(code);
	}
	else
		throw MyException("Compiler error");
}
void Block::generate(AsmCode &code){
    for(int i = 0; i < size(); i++){
        body[i]->generate(code);
        if(body[i]->isExpression()){
            SymbolType *type = body[i]->getType();
            if(type && type->byteSize())
                code.add(_POP, _EAX);
        }
    }
}
void CSubroutine::emitPUSHMn( const string &symbol, const bool &pushType )
{
   SymbolType symbolType = _symbolTable->getSymbol( getName( ), symbol, true ).getType( );

   _body.writeln( string("push ")   + symbol );

   if (pushType) {
      _body.writeln( string("push_") + symbolType.toAsmType( ) );
   }
}
Exemplo n.º 4
0
bool ExpressionValue::isCompatibleWidth(SymbolType& other) const {
  if(!matchesType(other.isPrimitive())) {
    return false;
  } else if(!matchesDimensions(other.dimensions())) {
    return false;
  } else if(!matchesPrimitiveType(other.primitiveType())) {
    return false;
  }
  return true;
}
Exemplo n.º 5
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());
}
Exemplo n.º 6
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();
}
Exemplo n.º 7
0
SymbolType *ArrNode::getType() {
	if(nodeType)
		return nodeType;
	ArraySymbol *sym = dynamic_cast<ArraySymbol*>(name->getType());
	if(!sym)
		throw MyException("Expression must be a pointer type", token);
	SymbolType *type = sym;
	for(int i = 0; i < args.size(); i++){
		type = type->upType();
		if(type == 0)
			throw MyException("Expression must be a pointer type", args[i]->token);
		if(!args[i]->getType()->canConvertTo(IntType))
			throw MyException("Expression must have integral type", args[i]->token);
		args[i] = makeTypeCoerce(args[i], args[i]->getType(), IntType);
	}
	nodeType = type;
	return type;
}
void ArrNode::generateLvalue(AsmCode &code){
    SymbolType *type = name->getType();
    if(dynamic_cast<ArraySymbol*>(type))
        name->generateLvalue(code);
    else if(dynamic_cast<PointerSymbol*>(type))
        name->generate(code);
    SymbolType *t = type->upType();
    for(int i = 0; i < args.size(); i++){
        args[i]->generate(code);
        code.add(_POP, _EAX)
        .add(_MOV, _EBX, to_string(t->byteSize()))
        .add(_IMUL, _EAX, _EBX)
        .add(_POP, _EBX)
        .add(_ADD, _EAX, _EBX)
        .add(_PUSH, _EAX);
        t = t->upType();
    }
}
Exemplo n.º 9
0
void SemanticEval::evaluateReturnCmd(ExpressionValue& ev, int line) {
  if(currentScope == SymbolTable::GlobalScope) {
    //tentando retornar no bloco principal
    ErrorHandler::self()->add("Bloco principal não deve ter retorno", line);
  } else {
    //currentScope eh o nome da funcao atual
    try {
      SymbolType sctype = stable.getSymbol(SymbolTable::GlobalScope, currentScope).type;
      
      if(!ev.isCompatibleWidth(sctype)) {
          stringstream msg;
          msg << "Expressão de retorno deve ser compatível com o tipo \"" 
            << sctype.toString() <<  "\"";
          ErrorHandler::self()->add(msg.str(), line);
      } //else ok!
    } catch(SymbolTableException& e) {
      cerr << "Erro interno: SemanticEval::evaluateReturnCmd exception\n";
    }
  } 
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
ExprNode* Parser :: ParseMember(ExprNode* left){
    SymbolType *type = left->getType();
    if ( dynamic_cast<TypedefSymbol*>(type))
        type = type->getType();
    StructSymbol *struct_type = 0;
    if(dynamic_cast<PointerSymbol*>(type))
        struct_type = dynamic_cast<StructSymbol*>(dynamic_cast<PointerSymbol*>(type)->pointer);
    else
        struct_type = dynamic_cast<StructSymbol*>(type);
    errorIf(!struct_type, "Left operand of . or -> must be a structure", scan.Get());
    Token* opTok = scan.Get();
    Token* token =scan.GetNext();
    errorIf(token->Type != _IDENTIFIER , "Right operand of . or -> must be a identifier", token);
    string fieldName = token->Value;
    if (!struct_type->m_fields->exists(fieldName))
        fieldName = '%' + fieldName;
    errorIf(!struct_type->m_fields->exists(fieldName), "Undefined field in structure",token);
    scan.Next();
    ExprNode* right = new IdentifierNode(token, dynamic_cast<VarSymbol*>(struct_type->m_fields->find_symbol(fieldName)));
    return new BinOpNode(opTok, left, right);

}
Exemplo n.º 12
0
bool ArrNode::isModifiableLvalue() const {
	SymbolType *type = name->getType();
	for(int i = 0; i < args.size(); i++)
		type = type->upType();
	return type->isModifiableLvalue();
}
Exemplo n.º 13
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;
		}
	}
}
void BinOpNode::generate(AsmCode & code) {
	SymbolType * leftType = left->getType();
	SymbolType * rightType = right->getType();

	ArraySymbol* leftTypeArray = dynamic_cast<ArraySymbol *>(leftType);
	ArraySymbol* rightTypeArray = dynamic_cast<ArraySymbol *>(rightType);
	PointerSymbol* leftTypePointer = dynamic_cast<PointerSymbol *>(leftType);
	PointerSymbol* rightTypePointer = dynamic_cast<PointerSymbol *>(rightType);



	if (isAssing(token)) {
		left->generateLvalue(code);
		right->generate(code);

	}
	else {
		left->generate(code);
		right->generate(code);
	}

	if (token->Value == "+"){
		if (leftTypePointer || rightTypeArray || leftTypeArray || rightTypePointer) {
			int shift;

			if (leftTypeArray) shift = leftTypeArray->getType()->offset;
			if (rightTypeArray) shift = rightTypeArray->getType()->offset;
			if (leftTypePointer) shift = leftTypePointer->getType()->offset;
			if (rightTypePointer) shift = rightTypePointer->getType()->offset;

			if (leftTypePointer) generateOperationPointer(code, _ADD, shift, false);
			else generateOperationPointer(code, _ADD, shift, true);

		}

		generateOperation(code, _ADD);

	}
	else if (token->Value == "-"){
		if (leftTypePointer || rightTypeArray || leftTypeArray || rightTypePointer) {
			int shift;

			if (leftTypeArray) shift = leftTypeArray->getType()->offset;
			if (rightTypeArray) shift = rightTypeArray->getType()->offset;
			if (leftTypePointer) shift = leftTypePointer->getType()->offset;
			if (rightTypePointer) shift = rightTypePointer->getType()->offset;

			if (leftTypePointer && !rightTypePointer) generateOperationPointer(code, _SUB, shift, false);


		}

		generateOperation(code, _SUB);

	}

	else if (token->Value == "*"){
		generateOperation(code, _IMUL);

	}

	else if (token->Value == "/"){

		generateOperation(code, _IDIV);

	}

	else if (token->Value == "%"){

		generateOperation(code, _IDIV, _EDX);

	}

	else if (token->Value == "&"){
		generateOperation(code, _AND);
	}

	else if (token->Value == "|"){
		generateOperation(code, _OR);
	}

	else if (token->Value == "^"){
		generateOperation(code, _XOR);

	}

	else if (token->Value == "<<"){
		generateOperationShift(code, _SHL);

	}

	else if (token->Value == ">>"){
		generateOperationShift(code, _SHR);

	}

	else if (token->Value == "=="){

		generateCmp(code, _SETE);

	}

	else if (token->Value == ">="){

		generateCmp(code, _SETGE);
	}

	else if (token->Value == "<="){
		generateCmp(code, _SETLE);
	}

	else if (token->Value == "!="){

		generateCmp(code, _SETNE);

	}

	else if (token->Value == ">"){
		generateCmp(code, _SETG);
	}

	else if (token->Value == "<"){

		generateCmp(code, _SETL);
	}

	else if (token->Value == "&&"){
		generateOperationLogic(code, _AND);

	}

	else if (token->Value == "||"){

		generateOperationLogic(code, _OR);
	}

	else if (token->Value == "="){
		code.add(_POP, _EBX)
			.add(_POP, _EAX);

		if (!(leftTypePointer || leftTypeArray) && leftType->getType() == CharType) {
			code.add(_MOV, new AsmIndirectArg(_EAX), new AsmRegArg(_BL))
				.add(_XOR, _EBX, _EBX)
				.add(_MOV, new AsmRegArg(_BL), new AsmIndirectArg(_EAX))
				.add(_PUSH, new AsmRegArg(_EAX));
		}
		else {
			code.add(_MOV, new AsmIndirectArg(_EAX), new AsmRegArg(_EBX));
		}

		code.add(_PUSH, _EBX);


	}

	else if (token->Value == "+="){
		if ((leftTypePointer || leftTypeArray)) {
			int shift;
			if (leftTypeArray) shift = leftTypeArray->getType()->offset;
			if (rightTypeArray) shift = rightTypeArray->getType()->offset;
			if (leftTypePointer) shift = leftTypePointer->getType()->offset;
			if (rightTypePointer) shift = rightTypePointer->getType()->offset;
			generateOperationPointer(code, _ADD, shift, false);
		}

		generateOperationAssing(leftType, code, _ADD);

	}

	else if (token->Value == "-="){
		generateOperationAssing(leftType, code, _SUB);

	}

	else if (token->Value == "*="){
		generateOperationAssing(leftType, code, _IMUL);

	}

	else if (token->Value == "/="){
		generateOperationAssing(leftType, code, _IDIV);

	}

	else if (token->Value == "%="){
		generateOperationAssing(leftType, code, _IDIV, _EDX);

	}

	else if (token->Value == "&="){
		generateOperationAssing(leftType, code, _AND);

	}

	else if (token->Value == "|="){

		generateOperationAssing(leftType, code, _OR);

	}

	else if (token->Value == "^="){
		generateOperationAssing(leftType, code, _XOR);

	}

	else if (token->Value == ","){
		code.add(_POP, _EAX)
			.add(_POP, _EBX)
			.add(_PUSH, _EAX);

	}

}
Exemplo n.º 15
0
void ExpressionValue::set(SymbolType& s) {
  _isPrimitive  = s.isPrimitive();
  _primitiveType = s.primitiveType();
  _dimensions = s.dimensions();
}