bool parameters::then_else( bool expr, value_type const &s, value_type::size_type *pos, value_type *replacement ) const { value_type::value_type c = s[ *pos ]; bool found_param = false, not_empty = false; switch ( c ) { case_123456789: found_param = true; if ( expr ) { *replacement = lookup_param( to_index( c ) ); not_empty = !replacement->empty(); } break; case '{': while ( ++*pos < s.size() ) { c = s[ *pos ]; switch ( c ) { case_123456789: found_param = true; if ( expr ) { value_type const param = lookup_param( to_index( c ) ); not_empty = !param.empty() || not_empty; *replacement += param; } break; case '}': goto done; case '\\': if ( *pos + 1 < s.size() ) c = s[ ++*pos ]; // no break; default: if ( expr ) *replacement += c; } // switch } // while throw invalid_argument( "'}' expected for ?:" ); default: throw invalid_argument( BUILD_STRING( '\'', c, "': invalid character after '", (expr ? '?' : ':'), "' (one of [1-9{] expected)" ) ); } // switch done: return !found_param || not_empty; }
static void add_param(char* name, char* value) { /* static Param* lookup_param(char* name); */ if (param == 0) { param_size = 20; param = malloc(param_size*sizeof(Param)); } else if (n_params >= param_size) { param_size *= 2; param = realloc(param, param_size*sizeof(Param)); } assert(n_params < param_size); /* if name is present, warn and ignore */ if (lookup_param(name)) { fprintf(stderr, "warning: duplicate param %s; only the first will be used\n", name); } else { param[n_params].name = strdup(name); /* remove surrounding quotation marks from value */ if (*value == '"') value++; if (value[strlen(value)-1] == '"') value[strlen(value)-1] = '\0'; param[n_params].value = strdup(value); n_params++; } }
static Param* lookup_param_force(char *name) { Param* p = lookup_param(name); if (!p) { fprintf(stderr, "error: parameter %s not found\n", name); exit(1); } else return p; }
static void var() { int has_prefix = false; int var_addr; AutoInfo * _auto = NULL; ParamInfo * _param = NULL; Symbol * _global = NULL; //Symbol * temp = NULL; if(token==TOK_MUL||token==TOK_AND){ has_prefix = true; /* if is * or & */ match(token); //如果有前缀 则返回指针地址或者指针值 } _global = lookup_global_sym(GLOB_VAR,save_word); _auto = lookup_local_var(save_word); _param = lookup_param(save_word); match(TOK_ID); /* array */ if(token == TOK_LSQUARE){ if(_auto && _param){ fprintf(stderr, "line %d: param and auto can't be same name\n", save_line); } if(_param){ gen_code("lda %d\n", _param->offset); }else if(_auto){ gen_code("lda %d\n", _auto->offset); }else if(_global){ gen_code("lda %d\n", _global->u.g.offset); }else{ fprintf(stderr, "line %d: can't find var %s\n", save_line, save_word); } match(TOK_LSQUARE); var_in_square = true; expression(); var_in_square = false; match(TOK_RSQUARE); gen_code("ixa elem_size(%d)\n", 1); if(!before_assign){ gen_code("ind %d\n",0); } } /* not array */ else { if(_auto && _param){ fprintf(stderr, "line %d: param and auto can't be same name\n", save_line); } if(_param){ var_addr = _param->offset; }else if(_auto){ var_addr = _auto->offset; }else if(_global){ var_addr = _global->u.g.offset; }else{ fprintf(stderr, "line %d: can't find var %s\n", save_line, save_word); } if((before_assign && !var_in_square) || (var_in_read_write && !var_in_square)){ gen_code("lda %d\n", var_addr); }else{ gen_code("lod %d\n", var_addr); } } }
bool param_defined(char* name) { return (lookup_param(name) != NULL); }