示例#1
0
static void gen_conditional(ClmStmtNode *node) {
  push_expression(node->conditionStmt.condition);

  if (node->conditionStmt.falseBody == NULL) {
    char end_label[LABEL_SIZE];
    next_label(end_label);

    ClmScope *trueScope =
        clm_scope_find_child(data.scope, node->conditionStmt.trueBody);

    asm_pop(EAX);
    asm_cmp(EAX, "1");
    asm_jmp_neq(end_label);
    data.scope = trueScope;
    gen_statements(node->conditionStmt.trueBody);
    asm_label(end_label);

    data.scope = trueScope->parent;
  } else {
    char end_label[LABEL_SIZE];
    char false_label[LABEL_SIZE];
    next_label(end_label);
    next_label(false_label);

    ClmScope *trueScope =
        clm_scope_find_child(data.scope, node->conditionStmt.trueBody);
    ClmScope *falseScope =
        clm_scope_find_child(data.scope, node->conditionStmt.falseBody);

    asm_pop(EAX);
    asm_cmp(EAX, "1");
    asm_jmp_neq(false_label);
    data.scope = trueScope;
    gen_statements(node->conditionStmt.trueBody);
    asm_jmp(end_label);
    asm_label(false_label);
    data.scope = falseScope;
    gen_statements(node->conditionStmt.falseBody);
    asm_label(end_label);

    data.scope = falseScope->parent;
  }
}
示例#2
0
static void gen_while_loop(ClmStmtNode *node) {
  char cmp_label[LABEL_SIZE];
  char end_label[LABEL_SIZE];
  next_label(cmp_label);
  next_label(end_label);

  asm_label(cmp_label);

  // don't need to store this - just evaulate every loop
  push_expression(node->whileLoopStmt.condition);
  pop_int_into(EAX);
  asm_cmp(EAX, "0");
  asm_jmp_eq(end_label);

  gen_statements(node->whileLoopStmt.body);

  asm_jmp(cmp_label);
  asm_label(end_label);
}
示例#3
0
static void gen_for_loop(ClmStmtNode *node) {
  char cmp_label[LABEL_SIZE];
  char end_label[LABEL_SIZE];
  next_label(cmp_label);
  next_label(end_label);

  ClmSymbol *var = clm_scope_find(data.scope, node->forLoopStmt.varId);
  char loop_var[32];
  load_var_location(var, loop_var, 4, NULL);

  // don't need to store this - just evaluate and put into loop var
  push_expression(node->forLoopStmt.start);  
  pop_int_into(loop_var);

  asm_label(cmp_label);

  // don't need to store this - just evaulate every loop
  push_expression(node->forLoopStmt.end);
  pop_int_into(EAX);
  asm_cmp(loop_var, EAX);
  asm_jmp_g(end_label);

  gen_statements(node->forLoopStmt.body);

  if (node->forLoopStmt.delta->type == EXP_TYPE_INT &&
      node->forLoopStmt.delta->ival == 1) {
    asm_inc(loop_var);
  } else if (node->forLoopStmt.delta->type == EXP_TYPE_INT &&
             node->forLoopStmt.delta->ival == -1) {
    asm_dec(loop_var);
  } else if (node->forLoopStmt.delta->type == EXP_TYPE_INT) {
    asm_add_i(loop_var, node->forLoopStmt.delta->ival);
  } else {
    push_expression(node->forLoopStmt.delta);
    asm_pop(EAX);
    asm_add(loop_var, EAX);
  }

  asm_jmp(cmp_label);
  asm_label(end_label);
}
示例#4
0
const char *clm_code_gen_main(ArrayList *statements, ClmScope *globalScope) {
  data.scope = globalScope;
  data.labelID = 0;
  data.temporaryID = 0;
  data.inFunction = 0;
  data.size = strlen(ASM_HEADER) + 1;
  data.capacity = data.size;
  data.code = malloc(strlen(ASM_HEADER) + 1);
  strcpy(data.code, ASM_HEADER);

  gen_functions(statements);

  writeLine(ASM_START);
  gen_statements(statements);

  writeLine(ASM_EXIT_PROCESS);
  writeLine(ASM_DATA);

  gen_globals(globalScope);

  return data.code;
}
示例#5
0
static void gen_func_dec(ClmStmtNode *node) {
  int i;
  char func_label[LABEL_SIZE];

  sprintf(func_label, "_%s", node->funcDecStmt.name);
  ClmScope *funcScope = clm_scope_find_child(data.scope, node);

  asm_label(func_label);
  asm_push(EBP);
  asm_mov(EBP, ESP);

  int local_var_size = 2 * 4 * (funcScope->symbols->length -
                                node->funcDecStmt.parameters->length);
  char local_var_size_str[32];
  sprintf(local_var_size_str, "%d", local_var_size);
  asm_sub(ESP, local_var_size_str);

  // each local var has 2 slots on the stack, their type and the value
  // for matrices, the value is a pointer to the location on the stack
  // these are all declared below the local variables
  ClmSymbol *sym;
  ClmExpNode *dec;
  char cmp_label[LABEL_SIZE];
  char end_label[LABEL_SIZE];
  char index_str[32];
  for (i = 0; i < funcScope->symbols->length; i++) {
    sym = funcScope->symbols->data[i];
    dec = sym->declaration;

    if (sym->location == LOCATION_PARAMETER)
      continue;

    // setting the type of the local var
    load_var_location(sym, index_str, 0, NULL);
    asm_mov_i(index_str, (int)sym->type);

    // setting the value of the local var
    load_var_location(sym, index_str, 4, NULL);
    asm_mov_i(index_str, 0);

    if (sym->type == CLM_TYPE_MATRIX) {
      // TODO what does this do? does it work?
      next_label(cmp_label);
      next_label(end_label);

      gen_exp_size(dec);
      asm_pop(EAX); // eax contains num of rows
      asm_pop(EBX); // ebx contains num of cols
      asm_mov(ECX, EAX);
      asm_imul(ECX, EBX);
      asm_label(cmp_label);
      asm_dec(ECX);
      asm_cmp(ECX, "0");
      asm_jmp_eq(end_label);
      asm_push_const_i(0);
      asm_jmp(cmp_label);
      asm_label(end_label);
      asm_push(EBX); // cols

      // setting the pointer to point at the rows
      // note: push changes the value at esp and THEN
      // decrements it
      load_var_location(sym, index_str, 4, NULL);
      asm_mov(index_str, ESP);

      asm_push(EAX); // rows
    }
  }
  // TODO figure out strings though!

  data.inFunction = 1;
  data.scope = funcScope;
  gen_statements(node->funcDecStmt.body);
  data.scope = funcScope->parent;
  data.inFunction = 0;

  if (node->funcDecStmt.returnSize.rows == -1) {
    // no return value!
    asm_mov(ESP, EBP);
    asm_pop(EBP);
  }
  asm_ret();
}
示例#6
0
void generate_code(is_node *node, prog_env* mySemantic)
{
    is_node* aux;
    is_node* aux2;
    char* method_name;
    char* return_type;
    
    printf("\ndeclare i32 @printf(i8*, ...)\n");
    printf("declare i32 @atoi(i8*) nounwind readonly\n");
    
    printf("@str = private unnamed_addr constant [4 x i8] c\"%%d\\0A\\00\"\n");
	printf("@.str2 = private unnamed_addr constant [4 x i8] c\"%%s\\0A\\00\"\n");
    
	printf("@.str = private unnamed_addr constant [5 x i8] c\"true\\00\"\n");
	printf("@.true = global i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0)\n");
	printf("@.str1 = private unnamed_addr constant [6 x i8] c\"false\\00\"\n");
	printf("@.false = global i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0)\n\n");
    
    aux = node->child; // passar o no 'Program'
    while(aux != NULL)
    {
        // tratar variaveis globais
        if(aux->type == VarDecl)
        {
            if(aux->child->type == Int)
            {
                aux2 = aux->child->next;
                while(aux2 != NULL)
                {
                    printf("@%s = global i32 0\n", aux2->id);
                    aux2 = aux2->next;
                }
            }
            else if(aux->child->type == Bool)
            {
                aux2 = aux->child->next;
                while(aux2 != NULL)
                {
                    printf("@%s = global i1 0\n", aux2->id);
                    aux2 = aux2->next;
                }
            }
        // criar metodos
        } else if(aux->type == MethodDecl)
        {
            counter = 0;
            
            method_name = aux->child->next->id;
            return_type = gen_type[aux->child->type];
            
            // main com parametros
            if(strcmp(method_name, "main") == 0 && aux->child->next->next->child != NULL)
                printf("\ndefine i32 @main(i32 %%.argc, i8** %%.argv)\n{\n"); // ponto argc para nao override variaveis locais com nome argc
            
            // todas as funcoes excepto main com parametros
            else
            {
                char* return_type = gen_code_type(gen_type[aux->child->type]);  // obter tipo do return
                is_node* params = aux->child->next->next; // MethodParams
                
                printf("\ndefine %s @%s(", return_type, method_name);
                if(params->child != NULL)
                {
                    is_node* paramDecl = params->child; // ParamDeclaration
                    while(paramDecl != NULL)
                    {
                        if(paramDecl->next != NULL)
                            printf("%s %%%s, ", gen_code_type(gen_type[paramDecl->child->type]), paramDecl->child->next->id);
                        else
                            printf("%s %%%s", gen_code_type(gen_type[paramDecl->child->type]), paramDecl->child->next->id);

                        paramDecl = paramDecl->next;
                    }
                }
                printf(")\n{\n");
            }
            
            aux2 = aux->child;
            while(aux2 != NULL)
            {
                if(aux2->type == MethodBody)
                    gen_statements(method_name, aux2->child, mySemantic);

                aux2 = aux2->next;
            }
            printf("\tret %s 0\n}\n", gen_code_type(return_type));
        }
        aux = aux->next;
    }
}