Beispiel #1
0
void gen_statement(tree_t *t) {
  int local_if_label;
  int local_while_label;
  int local_for_label;
  int num_args;

  if (t->type == ARRAY || t->right->type == ARRAY || t->left->type == ARRAY) {
    yyerror("Array access not supported");
  }

  switch(t->type) {
  case ASSIGNOP:
    // Generate code for expression
    gen_label(t->right, 1);
    gen_expression(t->right);
    fprintf(yyout, "\tmovl\t%%ebx, %%eax\n");
    
    // If this is actually a return statement, then return with correct value in %eax
    if(!strcmp(t->left->attribute.variable->name, top_scope->curr->name)) 
      fprintf(yyout, "\tjmp\tsubprog%send\n", top_scope->curr->name);
    else {
      // Generate code for assignment
      gen_assignment(t->left);
    }

    break;
  case IF:
    local_if_label = if_label++;
    
    //Generate code for expression
    gen_label(t->left, 1);
    gen_expression(t->left);

    //Compare and jump accordingly
    fprintf(yyout, "\tcmpl\t$1, %%ebx\n\tjge\tiftrue%d\n", local_if_label);

    //Generate code for else first
    if (t->right->right != NULL) {
      gen_statement(t->right->right);
      fprintf(yyout, "\tjmp\tifend%d\n", local_if_label);
    }
    
    //Generate code for true section
    fprintf(yyout, "iftrue%d:\n", local_if_label);
    gen_statement(t->right->left);
    fprintf(yyout, "ifend%d:\n", local_if_label);

    break;
  case WHILE:
    local_while_label = while_label++;

    //Plant label for beginning of loop
    fprintf(yyout, "beginwhile%d:\n", local_while_label);
    
    //Generate code for expression
    gen_label(t->left, 1);
    gen_expression(t->left);

    //Compare and jump to end if needed
    fprintf(yyout, "\tcmpl\t$0, %%ebx\n\tje\tendwhile%d\n", local_while_label);

    //Generate code for statements
    gen_statement(t->right);
    fprintf(yyout, "\tjmp\tbeginwhile%d\n", local_while_label);
    fprintf(yyout, "endwhile%d:\n", local_while_label);

    break;
  case PROCEDURE:
    if (!strcmp(t->left->attribute.variable->name, "read"))
      gen_read(t->right);
    else if (!strcmp(t->left->attribute.variable->name, "write"))
      gen_write(t->right);
    else if (t->right != NULL) {
      // push arguments on the stack
      num_args = gen_expression_list(t->right); 
      fprintf(yyout, "\tcall\tsubprog%s\n", t->left->attribute.variable->name);

      // move the top of the stack below args
      fprintf(yyout, "\taddl\t$%d, %%esp\n", 4*num_args); 
    }
    else {
      fprintf(yyout, "\tcall\tsubprog%s\n", t->left->attribute.variable->name);
    }
    
    break;
  case COMMA:
    // Generate left and right statements
    if (t->left->type == ARRAY || t->right->type == ARRAY)
      yyerror("Array access not supported");
    else {
      gen_statement(t->left);
      gen_statement(t->right);
    }
    break;
  case FOR:
    local_for_label = for_label++;

    // Generate assignment
    gen_statement(t->left->left);

    //Plant label for beginning
    fprintf(yyout, "forloop%d:\n", local_for_label);

    // Generate expression for TO value
    gen_label(t->left->right, 1);
    gen_expression(t->left->right);

    //Compare and jump to end if needed
    if (t->left->left->left->attribute.variable->local_or_parameter == LOCAL)
      fprintf(yyout, "\tcmpl\t-%i(%%ebp), %%ebx\n\tjl\tforend%d\n",
	      t->left->left->left->attribute.variable->offset, local_for_label);
    else
      fprintf(yyout, "\tcmpl\t-%i(%%ebp), %%ebx\n\tjl\tforend%d\n",
	      t->left->left->left->attribute.variable->offset, local_for_label); 

    //Generate code for statements
    gen_statement(t->right);

    //Increment, jump to top then plant end label
    fprintf(yyout, "\tincl\t-%i(%%ebp)\n\tjmp\tforloop%d\nforend%d:\n", 
	    t->left->left->left->attribute.variable->offset,
	    local_for_label, local_for_label);

    break;
  default:
    fprintf(stderr, "TYPE: %d\n", t->type);
    yywarn("Statement not supported");
    break;
  }
}
Beispiel #2
0
int repo_new(repo* rep, const char* newname) {
	int err = 0;
	// New branches track empty directories. The branch has no old roots.
	// It is staging and the current root being staged points to the only
	// object already staged: an empty directory.

	// Create a string buffer for making paths
	char* path = gen_malloc(MAX_PATH_LEN);
	if (!path) {
		err = -ENOMEM;
		goto exit;
	}
	gen_sprintf(path, "%s/br/%s", rep->repo, newname);

	// mkdir <rep->repo>/br/<newname>
	err = gen_mkdir(path, (mode_t)0700);
	if (err)
		goto exit;

	// mkdir <rep->repo>/br/<newname>/oldroots
	strcat(path, "/oldroots");
	err = gen_mkdir(path, (mode_t)0700);
	if (err)
		goto exit;

	// mkdir <rep->repo>/br/<newname>/stage
	gen_sprintf(path, "%s/br/%s/stage", rep->repo, newname);
	err = gen_mkdir(path, (mode_t)0700);
	if (err)
		goto exit;

	// mkdir <rep->repo>/br/<newname>/stage/objs
	strcat(path, "/objs");
	err = gen_mkdir(path, (mode_t)0700);
	if (err)
		goto exit;

	// mkdir <rep->repo>/br/<newname>/stage/objs/<nextid>
	uint64_t nextid = repo_newid(rep);
	gen_sprintf(path, "%s/br/%s/%lu", rep->repo, newname, nextid);
	err = gen_mkdir(path, (mode_t)0700);
	if (err)
		goto exit;

	// echo `repo_newid` > <rep->repo>/br/<newname>/stage/root
	gen_sprintf(path, "%s/br/%s/root", rep->repo, newname);
	int fd = gen_open(path, O_CREAT|O_RDWR, (mode_t)0700);
	if (fd < 0) {
		err = fd;
		goto exit;
	}
	gen_sprintf(path, "%lu\n", nextid);
	int nbytes;
	err = gen_write(fd, path, strlen(path), &nbytes);
	if (err)
		goto exit;
	gen_close(fd);
	sync();
exit:
	gen_free(path);
	return err;
}