static void emit_expr(Node *node) { SAVE; switch (node->type) { case AST_LITERAL: emit_literal(node); return; case AST_STRING: emit_literal_string(node); return; case AST_LVAR: emit_lvar(node); return; case AST_GVAR: emit_gvar(node); return; case AST_FUNCALL: case AST_FUNCPTR_CALL: emit_func_call(node); return; case AST_DECL: emit_decl(node); return; case AST_CONV: emit_conv(node); return; case AST_ADDR: emit_addr(node->operand); return; case AST_DEREF: emit_deref(node); return; case AST_IF: case AST_TERNARY: emit_ternary(node); return; case AST_FOR: emit_for(node); return; case AST_WHILE: emit_while(node); return; case AST_DO: emit_do(node); return; case AST_SWITCH: emit_switch(node); return; case AST_CASE: emit_case(node); return; case AST_DEFAULT: emit_default(node); return; case AST_GOTO: emit_goto(node); return; case AST_LABEL: if (node->newlabel) emit_label(node->newlabel); return; case AST_RETURN: emit_return(node); return; case AST_BREAK: emit_break(node); return; case AST_CONTINUE: emit_continue(node); return; case AST_COMPOUND_STMT: emit_compound_stmt(node); return; case AST_STRUCT_REF: emit_load_struct_ref(node->struc, node->ctype, 0); return; case AST_VA_START: emit_va_start(node); return; case AST_VA_ARG: emit_va_arg(node); return; case OP_UMINUS: emit_uminus(node); return; case OP_PRE_INC: emit_pre_inc_dec(node, "add"); return; case OP_PRE_DEC: emit_pre_inc_dec(node, "sub"); return; case OP_POST_INC: emit_post_inc_dec(node, "add"); return; case OP_POST_DEC: emit_post_inc_dec(node, "sub"); return; case '!': emit_lognot(node); return; case '&': emit_bitand(node); return; case '|': emit_bitor(node); return; case '~': emit_bitnot(node); return; case OP_LOGAND: emit_logand(node); return; case OP_LOGOR: emit_logor(node); return; case OP_CAST: emit_cast(node); return; case ',': emit_comma(node); return; case '=': emit_assign(node); return; case OP_LABEL_ADDR: emit_label_addr(node); return; case AST_COMPUTED_GOTO: emit_computed_goto(node); return; default: emit_binop(node); } }
static void emit_expr(Node *node) { SAVE; maybe_print_source_loc(node); switch (node->kind) { case AST_LITERAL: emit_literal(node); return; case AST_LVAR: emit_lvar(node); return; case AST_GVAR: emit_gvar(node); return; case AST_FUNCDESG: return; case AST_FUNCALL: if (maybe_emit_builtin(node)) return; // fall through case AST_FUNCPTR_CALL: emit_func_call(node); return; case AST_DECL: emit_decl(node); return; case AST_CONV: emit_conv(node); return; case AST_ADDR: emit_addr(node->operand); return; case AST_DEREF: emit_deref(node); return; case AST_IF: case AST_TERNARY: emit_ternary(node); return; case AST_GOTO: emit_goto(node); return; case AST_LABEL: if (node->newlabel) emit_label(node->newlabel); return; case AST_RETURN: emit_return(node); return; case AST_COMPOUND_STMT: emit_compound_stmt(node); return; case AST_STRUCT_REF: emit_load_struct_ref(node->struc, node->ty, 0); return; case OP_PRE_INC: emit_pre_inc_dec(node, "add"); return; case OP_PRE_DEC: emit_pre_inc_dec(node, "sub"); return; case OP_POST_INC: emit_post_inc_dec(node, "add"); return; case OP_POST_DEC: emit_post_inc_dec(node, "sub"); return; case '!': emit_lognot(node); return; case '&': emit_bitand(node); return; case '|': emit_bitor(node); return; case '~': emit_bitnot(node); return; case OP_LOGAND: emit_logand(node); return; case OP_LOGOR: emit_logor(node); return; case OP_CAST: emit_cast(node); return; case ',': emit_comma(node); return; case '=': emit_assign(node); return; case OP_LABEL_ADDR: emit_label_addr(node); return; case AST_COMPUTED_GOTO: emit_computed_goto(node); return; default: emit_binop(node); } }