//assigns calling arguments with defined symbols. void macro_operand(char *symbols,char *val) { char tmp[MAX_LINE_LENGTH],*ptr=symbols,*sym=tmp,*next_sym=sym,*next_val=val; extern unsigned int macro_depth; if(symbols==NULL&&val==NULL) return; if(symbols==NULL||val==NULL) as_exit("error in macro_operand, Null operand list"); while(*ptr!='\n' && *ptr!=';') ptr++; *ptr='\0'; strcpy(tmp,symbols); //#ifdef DEBUG // printf("syms:\"%s\",vals:\"%s\"\n",sym,val); //#endif *ptr='\n'; while(1){ //skip over blanks: advance(next_sym); advance(next_val); sym = next_sym; val = next_val; if(*next_val=='\0' && *next_sym=='\0') return; if(*next_sym=='\0') as_exit("Error, To many arguments for defined Macro"); if(*next_val=='\0') as_exit("Error, Not enough arguments for defined macro"); while(*next_sym != '\0' && *next_sym!= ',' ) next_sym++; while(*next_val != '\0' && *next_val!= ',' ) next_val++; // printf("sym=\"%s\";val=\"%s\"(=0x%x)\n",sym, val,arg_decode(val,0) ); if( sym!=next_sym || val!=next_val ){ update_symbol(sym,TYPE_MACRO_ARG,arg_decode(val,0),macro_depth+1); } } }
static void eval_ast_decl(oast_t *decl) { oast_t *ast; oast_t *list; osymbol_t *symbol; ovector_t *vector; for (list = decl; list; list = list->next) { ast = list; switch (ast->token) { case tok_symbol: break; case tok_vecdcl: if (ast->r.ast) oeval_ast(ast->r.ast); goto eval_left; case tok_proto: if (ast->r.ast) oeval_ast(ast->r.ast); goto eval_left; case tok_set: oeval_ast(ast->r.ast); eval_left: for (ast = ast->l.ast; ast->token != tok_symbol; ast = ast->l.ast) ; break; default: abort(); } /* make symbol bound */ symbol = ast->l.value; vector = symbol->name; symbol = oget_symbol(current_record, vector); assert(symbol); ast->l.value = symbol; symbol->bound = true; /* remember symbol is referenced */ update_symbol(ast, false); } }
void oeval_ast(oast_t *ast) { oast_t *temp; orecord_t *record; osymbol_t *symbol; switch (ast->token) { case tok_set: case tok_andset: case tok_orset: case tok_xorset: case tok_mul2set: case tok_div2set: case tok_shlset: case tok_shrset: case tok_addset: case tok_subset: case tok_mulset: case tok_divset: case tok_trunc2set: case tok_remset: oeval_ast(ast->l.ast); oeval_ast(ast->r.ast); break; case tok_vector: oeval_ast(ast->l.ast); if (ast->r.ast == null) oparse_error(ast, "expecting offset"); oeval_ast(ast->r.ast); /* validate element reference */ oeval_ast_tag(ast); break; case tok_dot: oeval_ast(ast->l.ast); /* validate field reference */ oeval_ast_tag(ast); break; case tok_explicit: oeval_ast_tag(ast); break; case tok_andand: case tok_oror: case tok_ne: case tok_lt: case tok_le: case tok_eq: case tok_ge: case tok_gt: case tok_and: case tok_or: case tok_xor: case tok_mul2: case tok_div2: case tok_shl: case tok_shr: case tok_add: case tok_sub: case tok_mul: case tok_div: case tok_trunc2: case tok_rem: case tok_complex: oeval_ast(ast->l.ast); oeval_ast(ast->r.ast); ofold(ast); break; case tok_inc: case tok_dec: case tok_postinc: case tok_postdec: case tok_new: case tok_thread: oeval_ast(ast->l.ast); break; case tok_init: case tok_vecnew: oeval_ast(ast->r.ast); break; case tok_com: case tok_plus: case tok_neg: case tok_not: case tok_integer_p: case tok_rational_p: case tok_float_p: case tok_real_p: case tok_complex_p: case tok_number_p: case tok_finite_p: case tok_inf_p: case tok_nan_p: case tok_num: case tok_den: case tok_real: case tok_imag: case tok_signbit: case tok_abs: case tok_signum: case tok_rational: case tok_arg: case tok_conj: case tok_floor: case tok_trunc: case tok_round: case tok_ceil: case tok_sqrt: case tok_cbrt: case tok_sin: case tok_cos: case tok_tan: case tok_asin: case tok_acos: case tok_atan: case tok_sinh: case tok_cosh: case tok_tanh: case tok_asinh: case tok_acosh: case tok_atanh: case tok_proj: case tok_exp: case tok_log: case tok_log2: case tok_log10: oeval_ast(ast->l.ast); ofold(ast); break; case tok_atan2: case tok_pow: case tok_hypot: oeval_ast(ast->l.ast); oeval_ast(ast->r.ast); ofold(ast); break; case tok_subtypeof: oeval_ast(ast->l.ast); oeval_ast(ast->r.ast); break; case tok_sizeof: eval_ast_sizeof(ast); break; case tok_typeof: eval_ast_typeof(ast); break; case tok_renew: eval_ast_renew(ast); break; case tok_question: oeval_ast(ast->t.ast); oeval_ast(ast->l.ast); oeval_ast(ast->r.ast); break; case tok_if: eval_ast_stat(ast->t.ast); eval_ast_stat(ast->l.ast); eval_ast_stat(ast->r.ast); break; case tok_return: check_exception(ast); case tok_throw: if (ast->l.ast) oeval_ast(ast->l.ast); break; case tok_switch: eval_ast_stat(ast->t.ast); eval_ast_stat(ast->c.ast); break; case tok_for: eval_ast_stat(ast->l.ast); eval_ast_stat(ast->t.ast); eval_ast_stat(ast->r.ast); eval_ast_stat(ast->c.ast); break; case tok_do: case tok_while: eval_ast_stat(ast->c.ast); eval_ast_stat(ast->t.ast); break; case tok_list: temp = ast->l.ast; eval_ast_stat(temp); /* Check inner fields for the sake of clean debug output. */ if (temp->next == null && temp->r.value == null && temp->t.value == null && temp->c.value == null) omove_ast_up_full(ast, temp); break; case tok_call: if (ast->l.ast->token != tok_symbol) oeval_ast(ast->l.ast); else update_symbol(ast->l.ast, true); eval_ast_stat(ast->r.ast); break; case tok_stat: case tok_code: case tok_data: case tok_finally: eval_ast_stat(ast->l.ast); break; case tok_decl: oeval_ast(ast->l.ast); eval_ast_decl(ast->r.ast); break; case tok_symbol: update_symbol(ast, false); break; case tok_goto: eval_ast_goto(ast); break; case tok_try: eval_ast_stat(ast->r.ast); break; case tok_catch: eval_ast_decl(ast->l.ast->r.ast); eval_ast_stat(ast->r.ast); break; case tok_break: case tok_continue: check_exception(ast); case tok_type: case tok_number: case tok_string: case tok_class: case tok_label: case tok_case: case tok_default: case tok_function: case tok_ellipsis: case tok_this: case tok_enum: break; case tok_namespace: record = current_record; assert(ast->l.ast->token == tok_symbol); symbol = ast->l.ast->l.value; current_record = symbol->value; assert(otype(current_record) == t_namespace); eval_ast_stat(ast->c.ast); current_record = record; break; default: #if DEBUG oparse_warn(ast, "code: not handling %s", otoken_to_charp(ast->token)); #endif break; } }
otag_t * oeval_ast_tag(oast_t *ast) { otag_t *tag; oast_t *rast; orecord_t *record; osymbol_t *symbol; ovector_t *vector; switch (ast->token) { case tok_symbol: update_symbol(ast, false); symbol = ast->l.value; return (symbol->tag); case tok_vector: tag = oeval_ast_tag(ast->l.ast); switch (tag->type) { case tag_vector: case tag_varargs: break; case tag_hash: /* Patch token to simplify later parsing */ ast->token = tok_hash; break; default: if (ast->l.ast->token == tok_symbol) { symbol = ast->l.ast->l.value; oparse_error(ast, "'%p' is not a vector %A", symbol->name, ast); } oparse_error(ast, "not a vector reference %A", ast); break; } return (tag->base); case tok_dot: if (ast->l.ast->token == tok_this) { for (record = current_record; record; record = record->parent) if (otype(record) == t_record) break; if (record == null) oparse_error(ast, "'this' now allowed outside 'class' method"); tag = record->name->tag; } else tag = oeval_ast_tag(ast->l.ast); rast = ast->r.ast; assert(rast->token == tok_symbol); if (tag->type == tag_class && ast->l.ast->token == tok_this) { omove_ast_up_full(ast, rast); rast = ast; } else { while (tag->type == tag_function) { vector = tag->name; tag = vector->v.ptr[0]; } if (tag->type != tag_class) { if (ast->l.ast->token == tok_symbol) { symbol = ast->l.ast->l.value; oparse_error(ast, "'%p' is not a class or namespace %A", symbol->name, ast); } oparse_error(ast, "not a class or namespace %A", ast); } } record = tag->name; symbol = rast->l.value; vector = symbol->name; if ((symbol = oget_symbol(record, vector)) == null) oparse_error(ast, "'%p' has no %s named '%p'", record->name, tag->type == tag_class ? "field" : "symbol", vector); rast->l.value = symbol; return (symbol->tag); case tok_explicit: tag = ast->l.ast->l.value; if (tag->type != tag_class) oparse_error(ast, "not a class reference"); record = tag->name; rast = ast->r.ast; assert(rast->token == tok_symbol); symbol = rast->l.value; vector = symbol->name; if ((symbol = oget_symbol(record, vector)) == null) oparse_error(ast, "'%p' has no field named '%p'", record->name, vector); rast->l.value = symbol; return (symbol->tag); case tok_string: return (string_tag); case tok_ellipsis: return (varargs_tag); case tok_call: return (oeval_ast_tag(ast->l.ast)); default: oparse_error(ast, "not a type or symbol reference %A", ast); } }