#include #include #include #include // Assignment to declaration gen_res_t assign_declaration(fzl_gen_t *gen, fzl_node_t *node) { gen_res_t rres = gen_common(gen, node->binary_op.right); if (rres.error) return gen_error; gen_res_t lres = gen_common(gen, node->binary_op.left); if (lres.error) return gen_error; if (!gen_is_types_compatible(rres.type, lres.type, rres.classname, lres.classname)) return gen_error; gen_op(gen, FZL_OPCODE_WRITE); return (gen_res_t){ .error = false, .type = rres.type, .classname = rres.classname}; } // Assignment to identifier gen_res_t assign_id(fzl_gen_t *gen, fzl_node_t *node) { gen_res_t rres = gen_common(gen, node->binary_op.right); if (rres.error) return gen_error; char *name = (char *)node->binary_op.left->token->value; fzl_sym_t sym; bool found = false; ssize_t i = gen->syms_top - 1; for (; i >= 0; i--) if ((found = fzl_symt_get(gen->syms[i], name, &sym))) break; if (!found) return gen_error; if (!gen_is_types_compatible(sym.type, rres.type, sym.classname, rres.classname)) return gen_error; if (!sym.slot_set) return gen_error; size_t depth = gen->syms_top - 1 - i; gen_op(gen, FZL_OPCODE_STORE_LOCAL); gen_word(gen, depth); gen_word(gen, sym.slot); return (gen_res_t){ .error = false, .type = rres.type, .classname = rres.classname}; } // Assignment to field gen_res_t assign_field(fzl_gen_t *gen, fzl_node_t *node) { gen_res_t rres = gen_common(gen, node->binary_op.right); if (rres.error) return gen_error; fzl_node_t *field_node = node->binary_op.left; gen_res_t obj_res = gen_common(gen, field_node->memb.parent); if (obj_res.error) return gen_error; fzl_ctable_t *ct = NULL; for (size_t i = 0; i < gen->classes_count; i++) { if (strcmp(obj_res.classname, gen->classes[i]->name) == 0) { ct = gen->classes[i]; break; } } if (!ct) return gen_error; fzl_ctable_field_t *ctf = NULL; for (size_t i = 0; i < ct->fields_count; i++) { if (strcmp(field_node->memb.field->token->value, ct->fields[i].name) == 0) { ctf = &ct->fields[i]; break; } } if (!ctf) return gen_error; gen_op(gen, FZL_OPCODE_SET_FIELD); gen_word(gen, ctf->slot_index); return (gen_res_t){ .error = false, .type = rres.type, .classname = rres.classname}; } // Assignment gen_res_t gen_assign(fzl_gen_t *gen, fzl_node_t *node) { if (!gen || !node) return gen_error; if (node->binary_op.left->type == FZL_NODETYPE_DECLARATION) return assign_declaration(gen, node); if (node->binary_op.left->type == FZL_NODETYPE_IDENTIFIER) return assign_id(gen, node); if (node->binary_op.left->type == FZL_NODETYPE_FIELD) return assign_field(gen, node); return gen_error; }