/* * copy a user-defined variable length type in the group igrp to the * group ogrp */ static int copy_vlen_type(int igrp, nc_type itype, int ogrp) { int stat = NC_NOERR; nc_type ibasetype; nc_type obasetype; /* base type in target group */ char name[NC_MAX_NAME]; size_t size; char basename[NC_MAX_NAME]; size_t basesize; nc_type vlen_type; NC_CHECK(nc_inq_vlen(igrp, itype, name, &size, &ibasetype)); /* to get base type id in target group, use name of base type in * source group */ NC_CHECK(nc_inq_type(igrp, ibasetype, basename, &basesize)); stat = nc_inq_typeid(ogrp, basename, &obasetype); /* if no such type, create it now */ if(stat == NC_EBADTYPE) { NC_CHECK(copy_type(igrp, ibasetype, ogrp)); stat = nc_inq_typeid(ogrp, basename, &obasetype); } NC_CHECK(stat); /* Now we know base type exists in output and we know its type id */ NC_CHECK(nc_def_vlen(ogrp, name, obasetype, &vlen_type)); return stat; }
struct type * dup_type(struct type *src) { struct type *ret = alloc_type(); copy_type(ret, src, 0); copy_tlist(&ret->tlist, src->tlist); return ret; }
static size_t get_return_struct(code_system *system, type *return_type) { if (is_void(return_type)) { return 0; } size_t count = system->struct_count; code_struct *return_struct; for (size_t i = 0; i < count; i++) { return_struct = get_code_struct(system, i); if (return_struct->field_count != 1) { continue; } code_field *first_field = &return_struct->fields[0]; type *first = first_field->field_type; if (first->type != T_BLOCKREF || !first->blocktype || !first->blocktype->next || first->blocktype->next->next) { continue; } type *second = first->blocktype->next->argument_type; first = first->blocktype->argument_type; if (first->type == T_OBJECT && first->struct_index == i && equivalent_type(return_type, second)) { return i; } } return_struct = add_struct(system); return_struct->field_count = 1; return_struct->fields = xmalloc(sizeof(code_field)); return_struct->fields[0].field_type = new_type(T_BLOCKREF); argument *blocktype = xmalloc(sizeof(*blocktype)); blocktype->symbol_name = NULL; blocktype->argument_type = get_object_type(count); return_struct->fields[0].field_type->blocktype = blocktype; blocktype->next = xmalloc(sizeof(argument)); blocktype = blocktype->next; blocktype->symbol_name = NULL; blocktype->argument_type = copy_type(return_type); blocktype->next = NULL; return count; }
expression *new_function_node(function *fn) { expression *function = xmalloc(sizeof(*function)); function->operation.type = O_FUNCTION; function->type = xmalloc(sizeof(type)); function->type->type = T_BLOCKREF; function->type->blocktype = xmalloc(sizeof(argument)); function->type->blocktype->argument_type = copy_type(fn->return_type); function->type->blocktype->symbol_name = NULL; function->type->blocktype->next = copy_arguments(fn->argument, false); function->function = fn; function->next = NULL; function->line = fn->line; function->offset = fn->offset; return function; }
static code_block *generate_let(code_block *parent, let_statement *let) { code_system *system = parent->system; define_clause *clause = let->clause; do { parent = generate_expression(parent, clause->value); symbol_entry *entry = add_symbol(parent, clause->symbol_entry, last_instruction(parent)); entry->type = resolve_type(system, copy_type(clause->value->type)); entry->exists = true; clause = clause->next; } while (clause); return parent; }
static code_block *generate_define(code_block *parent, define_statement *define) { type *define_type = define->symbol_type; define_clause *clause = define->clause; do { size_t value = 0; if (clause->value) { parent = generate_expression(parent, clause->value); value = last_instruction(parent); } symbol_entry *entry = add_symbol(parent, clause->symbol_entry, value); entry->type = resolve_type(parent->system, copy_type(define_type)); entry->exists = !!clause->value; clause = clause->next; } while (clause); return parent; }
static void generate_return(code_block *parent, return_statement *ret) { function *fn = ret->target; bool non_void = !is_void(fn->return_type); if (non_void == !ret->value) { fprintf(stderr, "return from void function with return or non-void without " "return\n"); abort(); } size_t param_count = 1 + non_void; if (non_void) { parent = generate_expression(parent, ret->value); } parent->tail.type = GOTO; parent->tail.parameter_count = param_count; parent->tail.parameters = xmalloc(sizeof(size_t) * param_count); if (non_void) { parent->tail.parameters[1] = last_instruction(parent); } parent->tail.parameters[0] = 0; parent->tail.first_block = next_instruction(parent); size_t return_index = instruction_type(parent, 0)->struct_index; code_struct *return_struct = get_code_struct(parent->system, return_index); type *return_block_type = return_struct->fields[0].field_type; code_instruction *unwrap = new_instruction(parent, 2); unwrap->operation.type = O_GET_FIELD; unwrap->type = copy_type(return_block_type); unwrap->parameters[0] = 0; // return structs are always the first argument unwrap->parameters[1] = 0; // blockref position in all return structs }
static void mirror_instruction(code_block *parent, size_t src) { code_instruction *mirror = new_instruction(parent, 1); mirror->operation.type = O_GET_SYMBOL; mirror->type = copy_type(instruction_type(parent, src)); mirror->parameters[0] = src; }