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; } }
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; }