int main() { char *buf1 = malloc(sizeof(char) * SIZE); char *buf2 = malloc(sizeof(char) * SIZE); int count1; int count2; count1 = input_number(SIZE, buf1); printf("count = %i\n", count1); count2 = input_number(SIZE, buf2); printf("count = %i\n", count2); output_number(count1, buf1); output_number(count2, buf2); char *buf1_reversed = reverse_number(count1, buf1); char *buf2_reversed = reverse_number(count2, buf2); char *res_diff = diff_number(count1, buf1_reversed, buf2_reversed); char *res = reverse_number(count1, res_diff); output_number(count1, res); free(buf1); free(buf2); free(buf1_reversed); free(buf2_reversed); free(res); free(res_diff); return 0; }
/** * dump all static variables */ void dumpglbs(void) { int dim, i, list_size, line_count, value; if (!glbflag) return; current_symbol_table_idx = rglobal_table_index; while (current_symbol_table_idx < global_table_index) { SYMBOL *symbol = &symbol_table[current_symbol_table_idx]; if (symbol->identity != FUNCTION) { ppubext(symbol); if (symbol->storage != EXTERN) { output_string(symbol->name); output_label_terminator(); dim = symbol->offset; list_size = 0; line_count = 0; if (find_symbol_initials(symbol->name)) { // has initials list_size = get_size(symbol->name); if (dim == -1) { dim = list_size; } } for (i=0; i<dim; i++) { if (symbol->type == STRUCT) { dump_struct(symbol, i); } else { if (line_count % 10 == 0) { newline(); if ((symbol->type & CINT) || (symbol->identity == POINTER)) { gen_def_word(); } else { gen_def_byte(); } } if (i < list_size) { // dump data value = get_item_at(symbol->name, i, &tag_table[symbol->tagidx]); output_number(value); } else { // dump zero, no more data available output_number(0); } line_count++; if (line_count % 10 == 0) { line_count = 0; } else { if (i < dim-1) { output_byte( ',' ); } } } } newline(); } } else { fpubext(symbol); } current_symbol_table_idx++; } }
/** * divide the primary register by INTSIZE, never used */ void gen_divide_by_two(void) { gen_push(HL_REG); /* push primary in prep for gasr */ gen_immediate (); output_number (1); newline (); gen_arithm_shift_right (); /* divide by two */ }
/** * decrement the primary register by one if char, INTSIZE if int */ void gen_decrement_primary_reg(LVALUE *lval) { output_line("dcx \th"); switch (lval->ptr_type) { case CINT: case UINT: output_line("dcx \th"); break; case STRUCT: gen_immediate2(); output_number(lval->tagsym->size - 1); newline(); // two's complement output_line("mov \ta,d"); output_line("cma"); output_line("mov \td,a"); output_line("mov \ta,e"); output_line("cma"); output_line("mov \te,a"); output_line("inx \td"); // substract output_line("dad \td"); break ; default: break; } }
/** * dump switch table */ dumpsw(loop_t *loop) { int i,j; data_segment_gdata (); generate_label (loop->body_label); if (loop->test_label != swstp) { j = loop->test_label; while (j < swstp) { gen_def_word (); i = 4; while (i--) { output_number (swstcase[j]); output_byte (','); print_label (swstlab[j++]); if ((i == 0) | (j >= swstp)) { newline (); break; } output_byte (','); } } } gen_def_word (); print_label (loop->cont_label); output_string (",0"); newline (); code_segment_gtext (); }
/** * add new symbol to local table * @param sname * @param identity * @param type * @param offset size in bytes * @param storage_class * @return */ int add_local (char *sname, int identity, int type, int offset, int storage_class) { int k; SYMBOL *symbol; char *buffer_ptr; if ((current_symbol_table_idx = find_locale (sname)) > -1) { return (current_symbol_table_idx); } if (local_table_index >= NUMBER_OF_GLOBALS + NUMBER_OF_LOCALS) { error ("local symbol table overflow"); return (0); } current_symbol_table_idx = local_table_index; symbol = &symbol_table[current_symbol_table_idx]; buffer_ptr = symbol->name; /* FIXME: only copy so many bytes */ while (alphanumeric(*buffer_ptr++ = *sname++)); symbol->identity = identity; symbol->type = type; symbol->storage = storage_class; if (storage_class == LSTATIC) { data_segment_gdata(); print_label(k = getlabel()); output_label_terminator(); gen_def_storage(); output_number(offset); newline(); code_segment_gtext(); offset = k; } symbol->offset = offset; local_table_index++; return (current_symbol_table_idx); }
/** * evaluate one initializer, add data to table * @param symbol_name * @param type * @param identity * @param dim * @param tag * @return * returns size of initializer, or 0 for none (a null string is size 1) * */ int init(char *symbol_name, int type, int identity, int *dim, TAG_SYMBOL *tag) { int value, n; /* A pointer is initialized as a word holding the address of the struct or string etc that directly follows */ if(identity == POINTER) { int x = getlabel(); gen_def_word(); print_label(x); newline(); print_label(x); output_label_terminator(); newline(); } /* FIXME: may need to distinguish const string v data in future */ if(quoted_string(&n, NULL)) { if((identity == VARIABLE) || !(type & CCHAR)) error("found string: must assign to char pointer or array"); *dim = *dim - n; /* ??? FIXME arrays of char only */ return n; } if (type & CCHAR) gen_def_byte(); else gen_def_word(); if (!number(&value) && !quoted_char(&value)) return 0; *dim = *dim - 1; output_number(value); newline(); return (type & CCHAR) ? 1 : 2; }
/** * dump switch table */ void dumpsw(WHILE *ws) { int i,j; data_segment_gdata (); generate_label (ws->body_tab); if (ws->case_test != swstp) { j = ws->case_test; while (j < swstp) { gen_def_word (); i = 4; while (i--) { output_number (swstcase[j]); output_byte (','); print_label (swstlab[j++]); if ((i == 0) | (j >= swstp)) { newline (); break; } output_byte (','); } } } gen_def_word (); print_label (ws->incr_def); output_string (",0"); newline (); code_segment_gtext (); }
/** * call the specified subroutine name * @param sname subroutine name */ void gen_call(char *sname) { output_with_tab ("call "); output_string (sname); output_byte(','); output_number(args); newline (); }
/* Output the given array to the output file. */ static void output_from_array(FILE * outfile, unsigned long ary[], unsigned long n) { unsigned long i; for (i = 0; i < n; i += 1) output_number(outfile, ary[i]); }
static void describe_access(SYMBOL *sym) { if (sym->storage == REGISTER) { output_string("r"); output_number(sym->offset); newline(); return; } output_byte('('); if (sym->storage == LSTATIC) { print_label(sym->offset); } else if (sym->storage == AUTO || sym->storage == DEFAUTO) { output_number(sym->offset); output_string("+fp"); } else output_label_name(sym->name); output_byte(')'); newline(); }
void gen_epilogue(void) { int i; /* FIXME: usual case we can pop these in this order need to spot the sp position and optimize accordingly */ for (i = nextreg - 1; i >= 3; i--) { if (stkp == regv[i]) { stkp += 2; output_with_tab("pop r"); output_number(i); } else { output_with_tab("load r"); output_number(i); output_string(" ("); output_number(regv[i]); output_string("+fp)"); } newline(); } }
/** * asm - fetch the address of the specified symbol into the primary register * @param sym the symbol name * @return which register pair contains result */ int gen_get_locale(SYMBOL *sym) { if (sym->storage == LSTATIC) { gen_immediate(); print_label(sym->offset); newline(); return HL_REG; } else { if (uflag && !(sym->identity == ARRAY)) {// || //(sym->identity == VARIABLE && sym->type == STRUCT))) { output_with_tab("ldsi\t"); output_number(sym->offset - stkp); newline (); return DE_REG; } else { gen_immediate(); output_number(sym->offset - stkp); newline (); output_line ("dad \tsp"); return HL_REG; } } }
int gen_register(int vp, int size, int typ) { if (size != 2) return -1; if (nextreg > 6) return -1; stkp = stkp - 2; regv[nextreg] = stkp; output_with_tab("push r"); output_number(nextreg); newline(); return nextreg++; }
/** * dump struct data * @param symbol struct variable * @param position position of the struct in the array, or zero */ void dump_struct(SYMBOL *symbol, int position) { int i, number_of_members, value; number_of_members = tag_table[symbol->tagidx].number_of_members; newline(); for (i=0; i<number_of_members; i++) { // i is the index of current member, get type int member_type = member_table[tag_table[symbol->tagidx].member_idx + i].type; if (member_type & CINT) { gen_def_word(); } else { gen_def_byte(); } if (position < get_size(symbol->name)) { // dump data value = get_item_at(symbol->name, position*number_of_members+i, &tag_table[symbol->tagidx]); output_number(value); } else { // dump zero, no more data available output_number(0); } newline(); } }
/** * asm - fetch the address of the specified symbol into the primary register * @param sym the symbol name * @return which register pair contains result */ int gen_get_locale(SYMBOL *sym) { if (sym->storage == LSTATIC) { gen_immediate(); print_label(sym->offset); newline(); return HL_REG; } else { gen_immediate(); output_number(sym->offset); output_string("+fp"); newline(); return HL_REG; } }
int constant(int val[]) { if (number (val)) gen_immediate (); else if (quoted_char (val)) gen_immediate (); else if (quoted_string (val)) { gen_immediate (); print_label (litlab); output_byte ('+'); } else return (0); output_number (val[0]); newline (); return (1); }
/** * multiply the primary register by the length of some variable * @param type * @param size */ void gen_multiply(int type, int size) { switch (type) { case CINT: case UINT: output_line("mul r1 2"); break; case STRUCT: output_with_tab("mul r1 "); output_number(size); newline(); break; default: break; } }
/** * decrement the primary register by one if char, INTSIZE if int */ void gen_decrement_primary_reg(LVALUE *lval) { switch (lval->ptr_type) { case CINT: case UINT: output_line("sub r1 2"); break; case STRUCT: output_with_tab("sub r1 "); output_number(lval->tagsym->size - 1); newline(); break ; default: output_line("sub r1 1"); break; } }
/** * multiply the primary register by the length of some variable * @param type * @param size */ void gen_multiply(int type, int size) { switch (type) { case CINT: case UINT: gen_multiply_by_two(); break; case STRUCT: gen_immediate2(); output_number(size); newline(); gen_call("ccmul"); break ; default: break; } }
/** * increment the primary register by 1 if char, INTSIZE if int */ void gen_increment_primary_reg(LVALUE *lval) { switch (lval->ptr_type) { case STRUCT: gen_immediate2(); output_number(lval->tagsym->size); newline(); output_line("dad \td"); break ; case CINT: case UINT: output_line("inx \th"); default: output_line("inx \th"); break; } }
/** * initialise structure * @param tag */ void struct_init(TAG_SYMBOL *tag, char *symbol_name) { int dim ; int member_idx; int size = tag->size; member_idx = tag->member_idx; while (member_idx < tag->member_idx + tag->number_of_members) { size -= init(symbol_name, member_table[tag->member_idx + member_idx].type, member_table[tag->member_idx + member_idx].identity, &dim, tag); ++member_idx; /* FIXME: not an error - zero rest */ if ((match(",") == 0) && (member_idx != (tag->member_idx + tag->number_of_members))) { gen_def_storage(); output_number(size); newline(); break; } } }
u8 mode_select_display_func(ui_mode_t mode, ui_display_event_t event) { if (event == CONFIG_SHORT_PRESS) { u16 m = 1; u8 i; for(i=0; i<3-mode_select_digit; i++) { m *= 10; } u8 p = (mode_select_current/m)%10; mode_select_current -= p*m; p = (p+1)%10; mode_select_current += p*m; } else if (event == CONFIG_LONG_PRESS) { ++mode_select_digit; if (mode_select_digit >= 4) { /* Save the new config word */ save_persist_data_16(PDATA_CONFIG_WORD_1L + mode_select_word*2, ~mode_select_current); ++mode_select_word; do_config_word(mode_select_word); } if (mode_select_word >= NUM_CONFIG_WORDS) { /* wait for button release */ while (!(LED_PIN & (1<<LED_BIT))); radio_disable(); /* reset */ void (*rstvec)() = (void (*)())0; (*rstvec)(); } } output_number(MODE_MODE_SELECT + mode_select_word + 1, mode_select_current, CENTER_NONE, DFLAGS_FLASH_PLACE_0<<mode_select_digit); return 1; }
void oilpres_display_func(ui_mode_t mode, u8 mode_changed) { const u16 r1 = 390; // value of resistor to +5 const u16 r2_fixed = 90; // value of fixed resistor added to sensor resistance // actually measured 96.5, but ADC reports 90. u16 adc_10q6 = oilpres_ctx.current_oilpres_accum; #if 1 u16 Vratio_10q6 = adc_10q6 / 1023; u16 r2 = (Vratio_10q6 * r1)/(64 - Vratio_10q6); #else // underflow ? u16 r2 = (adc_10q6 * r1)/(64*1023 - adc_10q6); #endif // r2_10q6 -= r2_fixed_10q6; if (r2 > r2_fixed) { r2 -= r2_fixed; } else { r2 = 0; } if (r2 > 999) { /* output_number uses signed int, so limit this */ r2 = 999; } else { r2 = r2 * 10; } output_number(mode, r2, CENTER_D, 0); }
/** * dump the literal pool */ void dumplits(void) { int j, k; if (litptr == 0) return; print_label(litlab); output_label_terminator(); k = 0; while (k < litptr) { gen_def_byte(); j = 8; while (j--) { output_number(litq[k++] & 127); if ((j == 0) | (k >= litptr)) { newline(); break; } output_byte(','); } } }
/** * modify the stack pointer to the new value indicated * @param newstkp new value */ int gen_modify_stack(int newstkp) { int k; k = newstkp - stkp; if (k == 0) return (newstkp); if (k > 0) { if (k < 7) { if (k & 1) { output_line ("inx \tsp"); k--; } while (k) { output_line ("pop \tb"); k = k - INTSIZE; } return (newstkp); } } else { if (k > -7) { if (k & 1) { output_line ("dcx \tsp"); k++; } while (k) { output_line ("push\tb"); k = k + INTSIZE; } return (newstkp); } } gen_swap (); gen_immediate (); output_number (k); newline (); output_line ("dad \tsp"); output_line ("sphl"); gen_swap (); return (newstkp); }
/** * add offset to primary register * @param val the value */ void add_offset(int val) { gen_immediate2(); output_number(val); newline(); output_line ("dad \td"); }
/** * Squirrel away argument count in a register that modstk doesn't touch. * @param d */ void gnargs(int d) { output_with_tab ("mvi \ta,"); output_number(d); newline (); }
/** * initialize global objects * @param symbol_name * @param type char or integer or struct * @param identity * @param dim * @return 1 if variable is initialized */ int initials(char *symbol_name, int type, int identity, int dim, int otag) { int dim_unknown = 0; int n; if(dim == 0) { // allow for xx[] = {..}; declaration dim_unknown = 1; } if (!(type & CCHAR) && !(type & CINT) && !(type == STRUCT)) { error("unsupported storage size"); } data_segment_gdata(); glabel(symbol_name); if(match("=")) { // an array or struct if(match("{")) { // aggregate initialiser if ((identity == POINTER || identity == VARIABLE) && type == STRUCT) { // aggregate is structure or pointer to structure dim = 0; struct_init(&tag_table[otag], symbol_name); } else { while((dim > 0) || (dim_unknown)) { if (identity == ARRAY && type == STRUCT) { // array of struct needbrack("{"); struct_init(&tag_table[otag], symbol_name); --dim; needbrack("}"); } else { if (init(symbol_name, type, identity, &dim, 0)) { dim_unknown++; } } if(match(",") == 0) { break; } } if(--dim_unknown == 0) identity = POINTER; else { /* Pad any missing objects */ n = dim; gen_def_storage(); if (identity != ARRAY && type != STRUCT) { if (!(type & CCHAR)) n *= 2; } else n = tag_table[otag].size; output_number(n); newline(); } } needbrack("}"); // single constant } else { init(symbol_name, type, identity, &dim, 0); } } code_segment_gtext(); return identity; }
int main(int argc, char **argv) { char *descriptor; char *curpos; /* current position in input string */ struct keyval *parser_id; /* the parser we are creating output for */ FILE *outputf; struct keyval *rkv; /* current read key:val */ struct keyval_list *curlist; bool do_token_check = true; /* if the check for valid tokens is done */ bool only_ident = true; /* if the only token type is ident */ bool is_generic = false; struct keyval_list base; struct keyval_list IDENT; struct keyval_list IDENT_LIST; struct keyval_list LENGTH_UNIT; struct keyval_list URI; struct keyval_list WRAP; struct keyval_list NUMBER; struct keyval_list COLOR; if (argc < 2) { fprintf(stderr,"Usage: %s [-o <filename>] <descriptor>\n", argv[0]); return 1; } if ((argv[1][0] == '-') && (argv[1][1] == 'o')) { if (argc != 4) { fprintf(stderr,"Usage: %s [-o <filename>] <descriptor>\n", argv[0]); return 1; } outputf = fopen(argv[2], "w"); if (outputf == NULL) { perror("unable to open file"); } descriptor = strdup(argv[3]); } else { outputf = stdout; descriptor = strdup(argv[1]); } curpos = descriptor; base.count = 0; IDENT.count = 0; URI.count = 0; WRAP.count = 0; NUMBER.count = 0; COLOR.count = 0; LENGTH_UNIT.count = 0; IDENT_LIST.count = 0; curlist = &base; while (*curpos != 0) { rkv = get_keyval(&curpos); if (rkv == NULL) { fprintf(stderr,"Token error at offset %ld\n", curpos - descriptor); fclose(outputf); return 2; } if (strcmp(rkv->key, "WRAP") == 0) { WRAP.item[WRAP.count++] = rkv; only_ident = false; } else if (strcmp(rkv->key, "NUMBER") == 0) { if (rkv->val[0] == '(') { curlist = &NUMBER; } else if (rkv->val[0] == ')') { curlist = &base; } else { NUMBER.item[NUMBER.count++] = rkv; } only_ident = false; } else if (strcmp(rkv->key, "IDENT") == 0) { if (rkv->val[0] == '(') { curlist = &IDENT; } else if (rkv->val[0] == ')') { curlist = &base; } else if (strcmp(rkv->val, str_INHERIT) == 0) { IDENT.item[IDENT.count++] = &ident_inherit; } } else if (strcmp(rkv->key, "IDENT_LIST") == 0) { if (rkv->val[0] == '(') { curlist = &IDENT_LIST; } else if (rkv->val[0] == ')') { curlist = &base; } } else if (strcmp(rkv->key, "LENGTH_UNIT") == 0) { if (rkv->val[0] == '(') { curlist = &LENGTH_UNIT; } else if (rkv->val[0] == ')') { curlist = &base; } only_ident = false; do_token_check = false; } else if (strcmp(rkv->key, "COLOR") == 0) { COLOR.item[COLOR.count++] = rkv; do_token_check = false; only_ident = false; } else if (strcmp(rkv->key, "URI") == 0) { URI.item[URI.count++] = rkv; only_ident = false; } else if (strcmp(rkv->key, "GENERIC") == 0) { is_generic = true; } else { /* just append to current list */ curlist->item[curlist->count++] = rkv; } } if (base.count != 1) { fprintf(stderr,"Incorrect base element count (got %d expected 1)\n", base.count); fclose(outputf); return 3; } /* header */ output_header(outputf, descriptor, base.item[0], is_generic); if (WRAP.count > 0) { output_wrap(outputf, base.item[0], &WRAP); } else { /* check token type is correct */ output_token_type_check(outputf, do_token_check, &IDENT, &URI, &NUMBER); if (IDENT.count > 0) output_ident(outputf, only_ident, base.item[0], &IDENT); if (URI.count > 0) output_uri(outputf, base.item[0], &URI); if (NUMBER.count > 0) output_number(outputf, base.item[0], &NUMBER); /* terminal blocks, these end the ladder ie no trailing else */ if (COLOR.count > 0) { output_color(outputf, base.item[0], &COLOR); } else if (LENGTH_UNIT.count > 0) { output_length_unit(outputf, base.item[0], &LENGTH_UNIT); } else if (IDENT_LIST.count > 0) { output_ident_list(outputf, base.item[0], &IDENT_LIST); } else { output_invalidcss(outputf); } output_footer(outputf); } fclose(outputf); return 0; }