static void emit_store(Node *var) { SAVE; switch (var->type) { case AST_DEREF: emit_assign_deref(var); break; case AST_STRUCT_REF: emit_assign_struct_ref(var->struc, var->ctype, 0); break; case AST_LVAR: ensure_lvar_init(var); emit_lsave(var->ctype, var->loff); break; case AST_GVAR: emit_gsave(var->varname, var->ctype, 0); break; default: error("internal error"); } }
static void emit_decl_init(List *inits, int off) { Iter *iter = list_iter(inits); while (!iter_end(iter)) { Node *node = iter_next(iter); assert(node->type == AST_INIT); if (node->initval->type == AST_LITERAL && node->totype->bitsize <= 0) { emit_save_literal(node->initval, node->totype, node->initoff + off); } else { emit_expr(node->initval); emit_lsave(node->totype, node->initoff + off); } } }
static void emit_decl_init(Vector *inits, int off, int totalsize) { emit_fill_holes(inits, off, totalsize); for (int i = 0; i < vec_len(inits); i++) { Node *node = vec_get(inits, i); assert(node->kind == AST_INIT); bool isbitfield = (node->totype->bitsize > 0); if (node->initval->kind == AST_LITERAL && !isbitfield) { emit_save_literal(node->initval, node->totype, node->initoff + off); } else { emit_expr(node->initval); emit_lsave(node->totype, node->initoff + off); } } }
static void emit_assign_struct_ref(Node *struc, Ctype *field, int off) { SAVE; switch (struc->type) { case AST_LVAR: ensure_lvar_init(struc); emit_lsave(field, struc->loff + field->offset + off); break; case AST_GVAR: emit_gsave(struc->varname, field, field->offset + off); break; case AST_STRUCT_REF: emit_assign_struct_ref(struc->struc, field, off + struc->ctype->offset); break; case AST_DEREF: push("rax"); emit_expr(struc->operand); emit_assign_deref_int(field, field->offset + off); break; default: error("internal error: %s", a2s(struc)); } }