TAC* makeWhile(TAC* codeTest, TAC* codeThen)
{
    TAC *newWhile, *targetEndWhile, *targetBeginWhile;
    HASH *labelBeginWhile, *labelEndWhile;

    // Create code and label fot the test (WHILE)
    labelBeginWhile = hash_make_label();
    labelEndWhile = hash_make_label();
    targetBeginWhile = tacCreate(TAC_LABEL, labelBeginWhile, 0, 0);

    //                                                  temp (bool)
    newWhile = tacCreate(TAC_IFZ, labelEndWhile, codeTest?codeTest->res:0, 0);
    newWhile->prev = codeTest;
    //printf("AAAAAAAAAAAAAAAAAAAAAAAAAAA %d\n", codeTest->type); // type: LTZ, GEZ... op1 e op2 are the operands

    // Add the jump at the end of the block back to the test
    codeThen = tacJoin4(targetBeginWhile,
                        newWhile,
                        codeThen,
                        tacCreate(TAC_JUMP, labelBeginWhile, 0, 0) );

    // Add the label to jump from the conditional test WHILE
    targetEndWhile = tacCreate(TAC_LABEL, labelEndWhile, 0, 0);
    targetEndWhile->prev = codeThen;

    return targetEndWhile;
}
TAC* makeIfThenElse(TAC* codeTest, TAC* codeThen, TAC* codeElse)
{
  TAC *newIf, *targetElse, *targetEndIf;
  HASH *labelElse, *labelEndIf;

  // Create code and label fot the test (IFZ)
  labelElse = hash_make_label();
  newIf = tacCreate(TAC_IFZ, labelElse, codeTest?codeTest->res:0, 0);
  newIf->prev = codeTest;

  // If there's an else, then add the jump at the end of the "then" block
  if (codeElse) {
    labelEndIf = hash_make_label();
    codeThen = tacJoin3(newIf,
      codeThen,
      tacCreate(TAC_JUMP, labelEndIf, 0, 0) );
  } else {
    codeThen = tacJoin(newIf, codeThen);
  }

  // Add the label to jump from the conditional test IFZ
  targetElse = tacCreate(TAC_LABEL, labelElse, 0, 0);
  targetElse->prev = codeThen;

  // If there's "else", append its code after the "then" block and create the label end-if
  if (codeElse) {
    codeElse = tacJoin(targetElse, codeElse);
    targetEndIf = tacCreate(TAC_LABEL, labelEndIf, 0, 0);
    targetEndIf->prev = codeElse;
  } else {
    targetEndIf = targetElse;
  }

  return targetEndIf;
}
Example #3
0
TAC *tacFunDec(HASH_NODE *res, TAC **code) { 
    TAC *begin, *end;

    begin = tacCreate(TAC_BEGINFUN, res, NULL, NULL);
    end = tacCreate(TAC_ENDFUN, res, NULL, NULL);
    
    return tacMultiJoin(3, begin, code[2], end);
}
Example #4
0
TAC *tacIfThen(TAC **code) {
    TAC *nIf, *target;
    HASH_NODE *label = makeLabel();
    /* ifz tac */
    nIf = tacCreate(TAC_IFZ, label, code[0]?code[0]->res:NULL, NULL);
    /* ifz false target */
    target = tacCreate(TAC_LABEL, label, NULL, NULL);

    return tacMultiJoin(4, code[0], nIf, code[1], target);
}
Example #5
0
// make america great again 
TAC *tacInputArgs(TAC **code, HASH_NODE *id) {
    TAC *lin = code[0];

    if(!id)
        return NULL; // no args

    if(!lin) // end of tree's list
        return tacCreate(TAC_INPUT, NULL, id?id:NULL, NULL);

    // there's still args
    return tacJoin(tacCreate(TAC_INPUT, NULL, id?id:NULL, NULL), lin);
}
Example #6
0
// deus abencoe a america 
TAC *tacOutputArgs(TAC **code) {
    TAC *lout = code[1];
    TAC *litOrExp = code[0]; 

    if(!litOrExp)
        return NULL; // no args

    if(!lout)   // end of tree's list
        return tacJoin(litOrExp, tacCreate(TAC_PRINT, NULL, litOrExp?litOrExp->res:NULL, NULL));

    // there's still args
    return tacMultiJoin(3, litOrExp, tacCreate(TAC_PRINT, NULL, 
                                                litOrExp?litOrExp->res:NULL, NULL), 
                        lout);
}
Example #7
0
TAC *tacFunCall(AST_NODE *funCall) {
    AST_NODE *funDef = funCall->symbol->declaration;
    AST_NODE *largs = funDef->children[1];
    AST_NODE *lexp = funCall->children[0];

    TAC *tacArg = tacArgs(largs, lexp);
    TAC *tacCall = tacCreate(TAC_CALL, makeTemp(funCall->datatype), funCall->symbol, NULL);
    return tacMultiJoin(2, tacArg, tacCall);
}
Example #8
0
TAC *tacWhile(TAC **code) {
    TAC *tacExp = code[0];
    TAC *tacCmd = code[1];

    // label before test expression
    HASH_NODE *labelPrev = makeLabel();
    TAC *tacPrev = tacCreate(TAC_LABEL, labelPrev, NULL, NULL);

    // label after while command
    HASH_NODE *labelNext = makeLabel();
    TAC *tacNext = tacCreate(TAC_LABEL, labelNext, NULL, NULL);
    
    // while conditional jump
    TAC *tacIfz = tacCreate(TAC_IFZ, labelNext, tacExp?tacExp->res:NULL, NULL);

    // jump back to test expression after command
    TAC *tacJmp = tacCreate(TAC_JUMP, labelPrev, NULL, NULL);

    return tacMultiJoin(6, tacPrev, tacExp, tacIfz, tacCmd, tacJmp, tacNext);
}
Example #9
0
TAC *tacIfThenElse(TAC **code) {
    TAC *tacExp = code[0];
    TAC *tacThen = code[1];
    TAC *tacElse = code[2];
    
    // label before else
    HASH_NODE* labelElse = makeLabel();
    TAC *tacLabelElse = tacCreate(TAC_LABEL, labelElse, NULL, NULL);

    // label after else
    HASH_NODE* labelNext = makeLabel();
    TAC *tacLabelNext = tacCreate(TAC_LABEL, labelNext, NULL, NULL);

    // ifz conditional jump
    TAC *tacIfz = tacCreate(TAC_IFZ, labelElse, tacExp?tacExp->res:NULL,
            NULL);

    // jump at end of then command
    TAC *tacJmp = tacCreate(TAC_JUMP, labelNext, NULL, NULL);
    
    return tacMultiJoin(7, tacExp, tacIfz, tacThen, tacJmp, tacLabelElse,
            tacElse, tacLabelNext);
}
Example #10
0
TAC *tacArgs(AST_NODE *larg, AST_NODE *lexp) {
    TAC *tacAcc = NULL;

    while(larg && lexp) {
        HASH_NODE *arg = larg->symbol;
        AST_NODE *exp = lexp->children[0];
        
        TAC *tacExp = tacGenerateCodeAux(exp);
        TAC *tacArg = tacCreate(TAC_ARG, arg, tacExp?tacExp->res:NULL, NULL);

        tacAcc = tacMultiJoin(3, tacAcc, tacExp, tacArg);

        larg = larg->children[1];
        lexp = lexp->children[1];
    }

    return tacAcc;
}
TAC* makeParameters(TREE* node, int tacType)
{
  TREE *exprList;
  TAC *resultCode = NULL, *generatedCode;
  HASH *parameterSymbol;
  int childNoParams;
  HASH *format;
  PARAM_LIST *currentParameter;

  if (node->type == TREE_EXPR_ARIT_FUNCALL) {
    childNoParams = 1;
    currentParameter = node->children[0]->symbol ? node->children[0]->symbol->dataType.params : NULL;
  } else {
    childNoParams = 0;
  }

  // Iterate over the expression list (the parameters)
  for (exprList = node->children[childNoParams]; exprList; exprList = exprList->children[1]) {

    generatedCode = generateCode(exprList->children[0]);

    switch(node->type) {
      case TREE_EXPR_ARIT_FUNCALL:
        if (currentParameter) {
          parameterSymbol = currentParameter->symbol;
          currentParameter = currentParameter->next;
        } else
          parameterSymbol = 0;
        break;
      case TREE_COMM_IN:
      case TREE_COMM_OUT:
        parameterSymbol = 0;

        if (generatedCode->res) {
          switch (generatedCode->res->type) {
            case SYMBOL_LITERAL_INT:
            case SYMBOL_LITERAL_BOOL:
              format = gbl_format_d;
            break;
            case SYMBOL_LITERAL_REAL:
              format = gbl_format_f;
            break;
            case SYMBOL_LITERAL_STRING:
              format = gbl_format_s;
            break;
            case SYMBOL_LITERAL_CHAR:
              format = gbl_format_c;
            break;
            case SYMBOL_IDENTIFIER:
              switch (generatedCode->res->dataType.valueType) {
                case VAL_TYPE_INT:
                case VAL_TYPE_BOOL:
                  format = gbl_format_d;
                break;
                case VAL_TYPE_REAL:
                  format = gbl_format_f;
                break;
                case VAL_TYPE_CHAR:
                  format = gbl_format_c;
                break;
                case VAL_TYPE_STRING:
                  format = gbl_format_s;
                break;
                default:
                  format = gbl_format_f;
              }
          }
        } else {
          format = NULL;
        }
    }

    // Concatenate the expression code of the current argument to the result
    // along with a TAC for argument, be it TAC_ARG OR TAC_READ OR TAC_PRINT
    resultCode = tacJoin3(resultCode,
      generatedCode,
      tacCreate(tacType, parameterSymbol, generatedCode?generatedCode->res:0, format));
  }

  return resultCode;
}
Example #12
0
TAC *tacUnaryOp(int type, int datatype, TAC **code) {
    TAC *newTac = tacCreate(type, makeTemp(datatype), code[0]?code[0]->res:NULL, NULL);
    return tacMultiJoin(2, code[0], newTac);
}
Example #13
0
TAC *tacGenerateCodeAux(AST_NODE *node) {
    TAC *code[node->size];    
    int i;

    if(node->type == AST_FUNCALL)
        return tacFunCall(node);

    for(i = 0; i < node->size; i++)
        if(!node->children[i])
            code[i] = NULL;
        else
            code[i] = tacGenerateCodeAux(node->children[i]); 

    switch(node->type) {
        case AST_LIT:
        case AST_VAR:
            return tacCreate(TAC_SYMBOL, node->symbol, NULL, NULL);
        case AST_ARRACCESS:
            return tacReadArr(node->symbol, code);
        case AST_ATTR:
            return tacAttr(node->symbol, code);
        case AST_ATTRARR:
            return tacAttrArr(node->symbol, code);
        case AST_FUNDEC:
            return tacFunDec(node->symbol, code);
        case AST_LOUT:
            return tacOutputArgs(code);
        case AST_LIN:
            return tacInputArgs(code, node->symbol);
        case AST_IF:
            return tacIfThen(code);
        case AST_IFTE:
            return tacIfThenElse(code);
        case AST_WHILE:
            return tacWhile(code);
        case AST_RETURN:
            return tacReturn(code);
        case AST_NOT:
            return tacUnaryOp(TAC_NOT, node->datatype, code);
        case AST_LE:
            return tacBinOp(TAC_LE, node->datatype, code);
        case AST_GE:
            return tacBinOp(TAC_GE, node->datatype, code);
        case AST_EQ:
            return tacBinOp(TAC_EQ, node->datatype, code);
        case AST_NE:
            return tacBinOp(TAC_NE, node->datatype, code);
        case AST_AND:
            return tacBinOp(TAC_AND, node->datatype, code);
        case AST_OR:
            return tacBinOp(TAC_OR, node->datatype, code);
        case AST_LESS:
            return tacBinOp(TAC_LESS, node->datatype, code);
        case AST_GREATER:
            return tacBinOp(TAC_GREATER, node->datatype, code);
        case AST_ADD:
            return tacBinOp(TAC_ADD, node->datatype, code);
        case AST_SUB:
            return tacBinOp(TAC_SUB, node->datatype, code);
        case AST_MUL:
            return tacBinOp(TAC_MUL, node->datatype, code);
        case AST_DIV:
            return tacBinOp(TAC_DIV, node->datatype, code);
        default: 
            return tacArrayJoin(node->size, code);
    }
}
TAC* makeLogicOp(int type, TAC* code0, TAC* code1)
{
  return tacJoin(tacJoin(code0, code1),
              tacCreate(type, hash_make_temp_int(), code0 ? code0->res : 0, code1 ? code1->res : 0));
}
TAC* generateCode(TREE* node)
{
  int i;
  TAC *code[MAX_CHILDREN], *generatedCode;

  if (!node)
    return NULL;

  for (i=0; i<MAX_CHILDREN; i++) {
    if (node->children[i])
      code[i] = generateCode(node->children[i]);
    else
      code[i] = 0;
  }

  switch (node->type) {
    case TREE_SYMBOL:
      return tacCreate(TAC_SYMBOL, node->symbol, 0, 0);
    case TREE_VAL_TRUE:
      return tacCreate(TAC_SYMBOL, gbl_value_true, 0, 0);
    case TREE_VAL_FALSE:
      return tacCreate(TAC_SYMBOL, gbl_value_false, 0, 0);
    case TREE_DECL_FUNC:
      return tacJoin3(
        tacCreate(TAC_BEGINFUN, 0, node->children[1]?node->children[1]->symbol:0, 0),
        code[3],
        tacCreate(TAC_ENDFUN, 0, node->children[1]?node->children[1]->symbol:0, 0)
      );
    case TREE_COMM_NOP:
      return tacCreate(TAC_NOP, 0, 0, 0);
    case TREE_COMM_IN:
      generatedCode = makeParameters(node, TAC_READ); // The code of the expressions in the parameters
      return generatedCode;
    case TREE_COMM_OUT:
      generatedCode = makeParameters(node, TAC_PRINT);
      return generatedCode; // The code of the expressions in the parameters
    case TREE_COMM_ASSIG:
      return tacJoin(code[1],
            tacCreate(TAC_MOVE, code[0]?code[0]->res:0, code[1]?code[1]->res:0, 0)
      );
    case TREE_COMM_ASSIG_VEC:
      return tacJoin3(code[1],
            code[2],
            tacCreate(TAC_STRIDX, code[0]?code[0]->res:0, code[1]?code[1]->res:0, code[2]?code[2]->res:0)
      );
    case TREE_COMM_IF_ELSE:
      return makeIfThenElse(code[0], code[1], code[2]);
    case TREE_COMM_WHILE:
      return makeWhile(code[0], code[1]);
    case TREE_COMM_RETURN:
      return tacJoin(code[0],
            tacCreate(TAC_RET, 0, code[0]?code[0]->res:0, 0));
    case TREE_EXPR_ARIT_FUNCALL:
      return tacJoin(makeParameters(node, TAC_ARG), // The code of the expressions in the parameters
            tacCreate(TAC_CALL, hash_make_temp(), code[0]?code[0]->res:0, 0));
    case TREE_EXPR_ARIT_VEC_READ:
      return tacJoin(code[1],
            tacCreate(TAC_LOADIDX, hash_make_temp(), code[0]?code[0]->res:0, code[1]?code[1]->res:0)
      );
      break;
    case TREE_EXPR_ARIT_ADD:
      return makeBinOp(TAC_ADD, code[0], code[1]);
    case TREE_EXPR_ARIT_SUB:
      return makeBinOp(TAC_SUB, code[0], code[1]);
    case TREE_EXPR_ARIT_MUL:
      return makeBinOp(TAC_MUL, code[0], code[1]);
    case TREE_EXPR_ARIT_DIV:
      return makeBinOp(TAC_DIV, code[0], code[1]);
    case TREE_EXPR_BOOL_LT:
    	return makeLogicOp(TAC_LTZ, code[0], code[1]);
    case TREE_EXPR_BOOL_GT:
    	return makeLogicOp(TAC_GTZ, code[0], code[1]);
    case TREE_EXPR_BOOL_LE:
    	return makeLogicOp(TAC_LEZ, code[0], code[1]);
    case TREE_EXPR_BOOL_GE:
    	return makeLogicOp(TAC_GEZ, code[0], code[1]);
    case TREE_EXPR_BOOL_EQ:
    	return makeLogicOp(TAC_EQZ, code[0], code[1]);
    case TREE_EXPR_BOOL_NE:
    	return makeLogicOp(TAC_ANEG, code[0],code[1]);
    case TREE_EXPR_BOOL_AND:
    	return makeLogicOp(TAC_AND, code[0], code[1]);
    case TREE_EXPR_BOOL_OR:
    	return makeLogicOp(TAC_OR, code[0], code[1]);
    default:
    break;
  }

  return tacJoin4(code[0], code[1], code[2], code[3]);
}
Example #16
0
TAC *tacAttrArr(HASH_NODE* res, TAC **code) {
    TAC *newTac = tacCreate(TAC_ATTRARR, res, code[0]?code[0]->res:NULL,
            code[1]?code[1]->res:NULL);
    return tacMultiJoin(3, code[0], code[1], newTac);
}
Example #17
0
TAC *tacReadArr(HASH_NODE* vec, TAC **code) {
    TAC *newTac = tacCreate(TAC_READARR, makeTemp(vec->datatype), vec,
            code[0]?code[0]->res:NULL);
    return tacMultiJoin(2, code[0], newTac);
}
Example #18
0
TAC *tacReturn(TAC **code) {
    TAC *retExp = code[0];
    TAC *retTac = tacCreate(TAC_RET, NULL, retExp?retExp->res:NULL, NULL);
    return tacJoin(retExp, retTac);
}
Example #19
0
TAC *tacReturn(TAC **code, HASH_NODE *funDec) {
    TAC *retExp = code[0];
    TAC *retTac = tacCreate(TAC_RET, retExp?retExp->res:NULL, funDec, NULL);
    return tacJoin(retExp, retTac);
}