void gen_PROGRAM ( node_t *root, int scopedepth) { /* Output the data segment */ if( outputStage == 12 ) strings_output ( stderr ); instruction_add ( STRING, STRDUP( ".text" ), NULL, 0, 0 ); tracePrint("Starting PROGRAM\n"); gen_default(root, scopedepth);//RECUR(); TEXT_DEBUG_FUNC_ARM(); TEXT_HEAD_ARM(); gp(root,scopedepth); tracePrint("End PROGRAM\n"); TEXT_TAIL_ARM(); if( outputStage == 12 ) instructions_print ( stderr ); instructions_finalize (); }
void gen_PROGRAM ( node_t *root, int scopedepth) { /* Output the data segment */ if( outputStage == 12 ) strings_output ( stderr ); instruction_add ( STRING, STRDUP( ".text" ), NULL, 0, 0 ); tracePrint("Starting PROGRAM\n"); gen_default(root, scopedepth);//RECUR(); TEXT_DEBUG_FUNC_ARM(); TEXT_HEAD_ARM(); /* Call the first defined function */ int last_child = root->n_children - 1; if (root->children[last_child] != NULL) { char *func_label = root->children[last_child]->children[0]->function_entry->label; instruction_add( CALL, STRDUP(func_label), NULL, 0, 0); } tracePrint("End PROGRAM\n"); TEXT_TAIL_ARM(); if( outputStage == 12 ) instructions_print ( stderr ); instructions_finalize (); }
void gen_FUNCTION ( node_t *root, int scopedepth ) { // Generating label. This may need to be changed to handle labels for methods function_symbol_t* entry = root->function_entry; int len = strlen(entry->label); if (currentClass != NULL) { len += strlen(currentClass); } char *temp = (char*) malloc(sizeof(char) * (len + 4)); temp[0] = 0; strcat(temp, "_"); if (currentClass != NULL) { strcat(temp, currentClass); strcat(temp, "_"); } strcat(temp, entry->label); strcat(temp, ":"); instruction_add(STRING, STRDUP(temp), NULL, 0, 0); instruction_add(PUSH, lr, NULL, 0, 0); instruction_add(PUSH, fp, NULL, 0, 0); instruction_add(MOVE, fp, sp, 0, 0); gen_default(root, scopedepth); // In case we haven't already returned instruction_add(MOVE, sp, fp, 0, 0); instruction_add(POP, fp, NULL, 0, 0); instruction_add(POP, "pc", NULL, 0, 0); }
int main(int argc, char *argv[]) { FILE *fp; char *input_filename = argv[1]; char *output_filename = _PATH_PARSER; char *conf_filename = _PATH_SQUID_CONF; int linenum = 0; Entry *entries = NULL; Entry *curr = NULL; enum State state; int rc = 0; char *ptr = NULL; #ifdef _SQUID_OS2_ const char *rmode = "rt"; #else const char *rmode = "r"; #endif /*-------------------------------------------------------------------* * Parse input file *-------------------------------------------------------------------*/ /* Open input file */ if ((fp = fopen(input_filename, rmode)) == NULL) { perror(input_filename); exit(1); } state = sSTART; while (feof(fp) == 0 && state != sEXIT) { char buff[MAX_LINE]; char *t; if (NULL == fgets(buff, MAX_LINE, fp)) break; linenum++; if ((t = strchr(buff, '\n'))) *t = '\0'; switch (state) { case sSTART: if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) { /* ignore empty and comment lines */ (void) 0; } else if (!strncmp(buff, "NAME:", 5)) { char *name; if ((name = strtok(buff + 5, WS)) == NULL) { printf("Error in input file\n"); exit(1); } curr = calloc(1, sizeof(Entry)); curr->name = xstrdup(name); state = s1; } else if (!strcmp(buff, "EOF")) { state = sEXIT; } else if (!strcmp(buff, "COMMENT_START")) { curr = calloc(1, sizeof(Entry)); curr->name = xstrdup("comment"); curr->loc = xstrdup("none"); state = sDOC; } else { printf("Error on line %d\n", linenum); printf("--> %s\n", buff); exit(1); } break; case s1: if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) { /* ignore empty and comment lines */ (void) 0; } else if (!strncmp(buff, "COMMENT:", 8)) { ptr = buff + 8; while (xisspace(*ptr)) ptr++; curr->comment = xstrdup(ptr); } else if (!strncmp(buff, "DEFAULT:", 8)) { ptr = buff + 8; while (xisspace(*ptr)) ptr++; curr->default_value = xstrdup(ptr); } else if (!strncmp(buff, "DEFAULT_IF_NONE:", 16)) { ptr = buff + 16; while (xisspace(*ptr)) ptr++; curr->default_if_none = xstrdup(ptr); } else if (!strncmp(buff, "LOC:", 4)) { if ((ptr = strtok(buff + 4, WS)) == NULL) { printf("Error on line %d\n", linenum); exit(1); } curr->loc = xstrdup(ptr); } else if (!strncmp(buff, "TYPE:", 5)) { if ((ptr = strtok(buff + 5, WS)) == NULL) { printf("Error on line %d\n", linenum); exit(1); } curr->type = xstrdup(ptr); } else if (!strncmp(buff, "IFDEF:", 6)) { if ((ptr = strtok(buff + 6, WS)) == NULL) { printf("Error on line %d\n", linenum); exit(1); } curr->ifdef = xstrdup(ptr); } else if (!strcmp(buff, "DOC_START")) { state = sDOC; } else if (!strcmp(buff, "DOC_NONE")) { /* add to list of entries */ curr->next = entries; entries = curr; state = sSTART; } else { printf("Error on line %d\n", linenum); exit(1); } break; case sDOC: if (!strcmp(buff, "DOC_END") || !strcmp(buff, "COMMENT_END")) { Line *head = NULL; Line *line = curr->doc; /* reverse order of doc lines */ while (line != NULL) { Line *tmp; tmp = line->next; line->next = head; head = line; line = tmp; } curr->doc = head; /* add to list of entries */ curr->next = entries; entries = curr; state = sSTART; } else if (!strcmp(buff, "NOCOMMENT_START")) { state = sNOCOMMENT; } else { Line *line = calloc(1, sizeof(Line)); line->data = xstrdup(buff); line->next = curr->doc; curr->doc = line; } break; case sNOCOMMENT: if (!strcmp(buff, "NOCOMMENT_END")) { Line *head = NULL; Line *line = curr->nocomment; /* reverse order of lines */ while (line != NULL) { Line *tmp; tmp = line->next; line->next = head; head = line; line = tmp; } curr->nocomment = head; state = sDOC; } else { Line *line = calloc(1, sizeof(Line)); line->data = xstrdup(buff); line->next = curr->nocomment; curr->nocomment = line; } break; case sEXIT: assert(0); /* should never get here */ break; } } if (state != sEXIT) { printf("Error unexpected EOF\n"); exit(1); } else { /* reverse order of entries */ Entry *head = NULL; while (entries != NULL) { Entry *tmp; tmp = entries->next; entries->next = head; head = entries; entries = tmp; } entries = head; } fclose(fp); /*-------------------------------------------------------------------* * Generate default_all() * Generate parse_line() * Generate dump_config() * Generate free_all() * Generate example squid.conf file *-------------------------------------------------------------------*/ /* Open output x.c file */ if ((fp = fopen(output_filename, "w")) == NULL) { perror(output_filename); exit(1); } fprintf(fp, "/*\n" " * Generated automatically from %s by %s\n" " *\n" " * Abstract: This file contains routines used to configure the\n" " * variables in the squid server.\n" " */\n" "\n", input_filename, argv[0] ); rc = gen_default(entries, fp); gen_default_if_none(entries, fp); gen_parse(entries, fp); gen_dump(entries, fp); gen_free(entries, fp); fclose(fp); /* Open output x.conf file */ if ((fp = fopen(conf_filename, "w")) == NULL) { perror(conf_filename); exit(1); } gen_conf(entries, fp); fclose(fp); return (rc); }
void gen_EXPRESSION ( node_t *root, int scopedepth ) { /* * Expressions: * Handle any nested expressions first, then deal with the * top of the stack according to the kind of expression * (single variables/integers handled in separate switch/cases) */ tracePrint ( "Starting EXPRESSION of type %s\n", (char*) root->expression_type.text); switch(root->expression_type.index) { case FUNC_CALL_E: { if (root->children[1] != NULL) { // Push arguments on stack gen_default(root->children[1], scopedepth); } char *func_label = root->function_entry->label; instruction_add(CALL, STRDUP(func_label), NULL, 0, 0); // There is an issue where, if the parent node does not use the returned result, // this will pollute the stack, and offset any new local variables declared. // I see no easy way to fix this, and it also doesn't seem to be covered by // the tests. instruction_add(PUSH, r0, NULL, 0, 0); } break; case METH_CALL_E: { if (root->children[2] != NULL) { // Push arguments on stack gen_default(root->children[2], scopedepth); } tracePrint( "Pushing THIS\n" ); root->children[0]->generate(root->children[0], scopedepth); char *class_label = root->children[0]->data_type.class_name; char *func_label = root->function_entry->label; int len = strlen(class_label) + strlen(func_label); char *meth_label = malloc(sizeof(char) * (len+1)); meth_label[0] = 0; strcat(meth_label, class_label); strcat(meth_label, "_"); strcat(meth_label, func_label); instruction_add(CALL, STRDUP(meth_label), NULL, 0, 0); // There is an issue where, if the parent node does not use the returned result, // this will pollute the stack, and offset any new local variables declared. // I see no easy way to fix this, and it also doesn't seem to be covered by // the tests. instruction_add(PUSH, r0, NULL, 0, 0); } break; case NEW_E: { class_symbol_t *class_entry = root->children[0]->class_entry; char class_size[10]; int32_t class_entry_size = (int32_t)class_entry->size * 8; sprintf(class_size, "#%d", class_entry_size); instruction_add(MOVE32, STRDUP(class_size), r0, 0, 0); instruction_add(PUSH, r0, NULL, 0, 0); instruction_add(CALL, STRDUP("malloc"), NULL, 0, 0); instruction_add(PUSH, r0, NULL, 0, 0); } break; case CLASS_FIELD_E: { root->children[0]->generate(root->children[0], scopedepth); char stack_offset[10]; sprintf(stack_offset, "#%d", root->entry->stack_offset); instruction_add(POP, r1, NULL, 0, 0); instruction_add(MOVE, r2, STRDUP(stack_offset), 0, 0); instruction_add3(ADD, r3, r1, r2); instruction_add(LOAD, r0, r3, 0, 0); instruction_add(PUSH, r0, NULL, 0, 0); } break; case THIS_E: { instruction_add(LOAD, r1, fp, 0, 8); instruction_add(PUSH, r1, NULL, 0, 0); } break; default: gen_default(root, scopedepth); } switch (root->expression_type.index) { case ADD_E: case OR_E: instruction_add(POP, r2, NULL, 0, 0); instruction_add(POP, r1, NULL, 0, 0); instruction_add3(ADD, r0, r1, r2); instruction_add(PUSH, r0, NULL, 0, 0); break; case SUB_E: instruction_add(POP, r2, NULL, 0, 0); instruction_add(POP, r1, NULL, 0, 0); instruction_add3(SUB, r0, r1, r2); instruction_add(PUSH, r0, NULL, 0, 0); break; case MUL_E: case AND_E: instruction_add(POP, r2, NULL, 0, 0); instruction_add(POP, r1, NULL, 0, 0); instruction_add3(MUL, r0, r1, r2); instruction_add(PUSH, r0, NULL, 0, 0); break; case DIV_E: instruction_add(POP, r2, NULL, 0, 0); instruction_add(POP, r1, NULL, 0, 0); instruction_add3(DIV, r0, r1, r2); instruction_add(PUSH, r0, NULL, 0, 0); break; case UMINUS_E: instruction_add(MOVE, r1, STRDUP("#0"), 0, 0); instruction_add(POP, r2, NULL, 0, 0); instruction_add3(SUB, r0, r1, r2); instruction_add(PUSH, r0, NULL, 0, 0); break; case EQUAL_E: instruction_add(POP, r2, NULL, 0, 0); instruction_add(POP, r1, NULL, 0, 0); instruction_add(CMP, r1, r2, 0, 0); instruction_add(MOVE, r0, STRDUP("#0"), 0, 0); instruction_add(MOVEQ, r0, STRDUP("#1"), 0, 0); instruction_add(PUSH, r0, NULL, 0, 0); break; case NEQUAL_E: instruction_add(POP, r2, NULL, 0, 0); instruction_add(POP, r1, NULL, 0, 0); instruction_add(CMP, r1, r2, 0, 0); instruction_add(MOVE, r0, STRDUP("#1"), 0, 0); instruction_add(MOVEQ, r0, STRDUP("#0"), 0, 0); instruction_add(PUSH, r0, NULL, 0, 0); break; case GEQUAL_E: instruction_add(POP, r2, NULL, 0, 0); instruction_add(POP, r1, NULL, 0, 0); instruction_add(CMP, r1, r2, 0, 0); instruction_add(MOVE, r0, STRDUP("#0"), 0, 0); instruction_add(MOVGE, r0, STRDUP("#1"), 0, 0); instruction_add(PUSH, r0, NULL, 0, 0); break; case LEQUAL_E: instruction_add(POP, r2, NULL, 0, 0); instruction_add(POP, r1, NULL, 0, 0); instruction_add(CMP, r1, r2, 0, 0); instruction_add(MOVE, r0, STRDUP("#0"), 0, 0); instruction_add(MOVLE, r0, STRDUP("#1"), 0, 0); instruction_add(PUSH, r0, NULL, 0, 0); break; case LESS_E: instruction_add(POP, r2, NULL, 0, 0); instruction_add(POP, r1, NULL, 0, 0); instruction_add(CMP, r1, r2, 0, 0); instruction_add(MOVE, r0, STRDUP("#0"), 0, 0); instruction_add(MOVLT, r0, STRDUP("#1"), 0, 0); instruction_add(PUSH, r0, NULL, 0, 0); break; case GREATER_E: instruction_add(POP, r2, NULL, 0, 0); instruction_add(POP, r1, NULL, 0, 0); instruction_add(CMP, r1, r2, 0, 0); instruction_add(MOVE, r0, STRDUP("#0"), 0, 0); instruction_add(MOVGT, r0, STRDUP("#1"), 0, 0); instruction_add(PUSH, r0, NULL, 0, 0); break; case NOT_E: instruction_add(POP, r1, NULL, 0, 0); instruction_add(CMP, r1, STRDUP("#0"), 0, 0); instruction_add(MOVE, r0, STRDUP("#0"), 0, 0); instruction_add(MOVEQ, r0, STRDUP("#1"), 0, 0); instruction_add(PUSH, r0, NULL, 0, 0); break; } tracePrint ( "Ending EXPRESSION of type %s\n", (char*) root->expression_type.text); }
void gen_CLASS (node_t *root, int scopedepth) { currentClass = root->label; gen_default(root->children[1], scopedepth); currentClass = NULL; }
int main(int argc, char *argv[]) { FILE *fp; char *input_filename = argv[1]; const char *output_filename = _PATH_PARSER; const char *conf_filename = _PATH_SQUID_CONF; const char *conf_filename_short = _PATH_SQUID_CONF_SHORT; const char *type_depend = argv[2]; int linenum = 0; Entry *entries = NULL; Entry *curr = NULL; Type *types = NULL; enum State state; int rc = 0; char *ptr = NULL; #ifdef _SQUID_OS2_ const char *rmode = "rt"; #else const char *rmode = "r"; #endif char buff[MAX_LINE]; if (argc != 3) usage(argv[0]); input_filename = argv[1]; type_depend = argv[2]; /*-------------------------------------------------------------------* * Parse type dependencies *-------------------------------------------------------------------*/ if ((fp = fopen(type_depend, rmode)) == NULL) { perror(input_filename); exit(1); } while ((NULL != fgets(buff, MAX_LINE, fp))) { const char *type = strtok(buff, WS); const char *dep; Type *t; if (!type || type[0] == '#') continue; t = (Type *) xcalloc(1, sizeof(*t)); t->name = xstrdup(type); while ((dep = strtok(NULL, WS)) != NULL) { TypeDep *d = (TypeDep *) xcalloc(1, sizeof(*d)); d->name = xstrdup(dep); d->next = t->depend; t->depend = d; } t->next = types; types = t; } fclose(fp); /*-------------------------------------------------------------------* * Parse input file *-------------------------------------------------------------------*/ /* Open input file */ if ((fp = fopen(input_filename, rmode)) == NULL) { perror(input_filename); exit(1); } #ifdef _SQUID_WIN32_ setmode(fileno(fp), O_TEXT); #endif state = sSTART; while (feof(fp) == 0 && state != sEXIT) { char *t; if (NULL == fgets(buff, MAX_LINE, fp)) break; linenum++; if ((t = strchr(buff, '\n'))) *t = '\0'; switch (state) { case sSTART: if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) { /* ignore empty and comment lines */ (void) 0; } else if (!strncmp(buff, "NAME:", 5)) { char *name, *aliasname; if ((name = strtok(buff + 5, WS)) == NULL) { printf("Error in input file\n"); exit(1); } curr = xcalloc(1, sizeof(Entry)); curr->name = xstrdup(name); while ((aliasname = strtok(NULL, WS)) != NULL) { EntryAlias *alias = xcalloc(1, sizeof(EntryAlias)); alias->next = curr->alias; alias->name = xstrdup(aliasname); curr->alias = alias; } state = s1; } else if (!strcmp(buff, "EOF")) { state = sEXIT; } else if (!strcmp(buff, "COMMENT_START")) { curr = xcalloc(1, sizeof(Entry)); curr->name = xstrdup("comment"); curr->loc = xstrdup("none"); state = sDOC; } else { printf("Error on line %d\n", linenum); printf("--> %s\n", buff); exit(1); } break; case s1: if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) { /* ignore empty and comment lines */ (void) 0; } else if (!strncmp(buff, "COMMENT:", 8)) { ptr = buff + 8; while (xisspace(*ptr)) ptr++; curr->comment = xstrdup(ptr); } else if (!strncmp(buff, "DEFAULT:", 8)) { ptr = buff + 8; while (xisspace(*ptr)) ptr++; curr->default_value = xstrdup(ptr); } else if (!strncmp(buff, "DEFAULT_IF_NONE:", 16)) { ptr = buff + 16; while (xisspace(*ptr)) ptr++; lineAdd(&curr->default_if_none, ptr); } else if (!strncmp(buff, "LOC:", 4)) { if ((ptr = strtok(buff + 4, WS)) == NULL) { printf("Error on line %d\n", linenum); exit(1); } curr->loc = xstrdup(ptr); } else if (!strncmp(buff, "TYPE:", 5)) { if ((ptr = strtok(buff + 5, WS)) == NULL) { printf("Error on line %d\n", linenum); exit(1); } /* hack to support arrays, rather than pointers */ if (0 == strcmp(ptr + strlen(ptr) - 2, "[]")) { curr->array_flag = 1; *(ptr + strlen(ptr) - 2) = '\0'; } checkDepend(curr->name, ptr, types, entries); curr->type = xstrdup(ptr); } else if (!strncmp(buff, "IFDEF:", 6)) { if ((ptr = strtok(buff + 6, WS)) == NULL) { printf("Error on line %d\n", linenum); exit(1); } curr->ifdef = xstrdup(ptr); } else if (!strcmp(buff, "DOC_START")) { state = sDOC; } else if (!strcmp(buff, "DOC_NONE")) { /* add to list of entries */ curr->next = entries; entries = curr; state = sSTART; } else { printf("Error on line %d\n", linenum); exit(1); } break; case sDOC: if (!strcmp(buff, "DOC_END") || !strcmp(buff, "COMMENT_END")) { Line *head = NULL; Line *line = curr->doc; /* reverse order of doc lines */ while (line != NULL) { Line *tmp; tmp = line->next; line->next = head; head = line; line = tmp; } curr->doc = head; /* add to list of entries */ curr->next = entries; entries = curr; state = sSTART; } else if (!strcmp(buff, "NOCOMMENT_START")) { state = sNOCOMMENT; } else { Line *line = xcalloc(1, sizeof(Line)); line->data = xstrdup(buff); line->next = curr->doc; curr->doc = line; } break; case sNOCOMMENT: if (!strcmp(buff, "NOCOMMENT_END")) { Line *head = NULL; Line *line = curr->nocomment; /* reverse order of lines */ while (line != NULL) { Line *tmp; tmp = line->next; line->next = head; head = line; line = tmp; } curr->nocomment = head; state = sDOC; } else { Line *line = xcalloc(1, sizeof(Line)); line->data = xstrdup(buff); line->next = curr->nocomment; curr->nocomment = line; } break; case sEXIT: assert(0); /* should never get here */ break; } } if (state != sEXIT) { printf("Error unexpected EOF\n"); exit(1); } else { /* reverse order of entries */ Entry *head = NULL; while (entries != NULL) { Entry *tmp; tmp = entries->next; entries->next = head; head = entries; entries = tmp; } entries = head; } fclose(fp); /*-------------------------------------------------------------------* * Generate default_all() * Generate parse_line() * Generate dump_config() * Generate free_all() * Generate example squid.conf.default file *-------------------------------------------------------------------*/ /* Open output x.c file */ if ((fp = fopen(output_filename, "w")) == NULL) { perror(output_filename); exit(1); } #ifdef _SQUID_WIN32_ setmode(fileno(fp), O_TEXT); #endif fprintf(fp, "/*\n" " * Generated automatically from %s by %s\n" " *\n" " * Abstract: This file contains routines used to configure the\n" " * variables in the squid server.\n" " */\n" "\n", input_filename, argv[0] ); rc = gen_default(entries, fp); gen_default_if_none(entries, fp); gen_parse(entries, fp); gen_dump(entries, fp); gen_free(entries, fp); fclose(fp); /* Open output x.conf file */ if ((fp = fopen(conf_filename, "w")) == NULL) { perror(conf_filename); exit(1); } #ifdef _SQUID_WIN32_ setmode(fileno(fp), O_TEXT); #endif gen_conf(entries, fp, 1); fclose(fp); if ((fp = fopen(conf_filename_short, "w")) == NULL) { perror(conf_filename); exit(1); } #ifdef _SQUID_WIN32_ setmode(fileno(fp), O_TEXT); #endif gen_conf(entries, fp, 0); fclose(fp); return (rc); }