ERROR_CODE _bencoding_dictionary_start_callback(struct bencoding_engine_t *bencoding_engine) { /* allocates space for the hash map and for the type structure that will encapsulate it */ struct hash_map_t *hash_map; struct sort_map_t *sort_map; struct type_t *type; /* retrieves the bencoding handler from the template engine context then uses it to store the (current) value */ struct bencoding_handler_t *bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context; /* switchs over the "target" map type to be used to store conceptual maps in the bencoding structure */ switch(bencoding_engine->map_type) { case MAP_TYPE: /* creates a new hash map for the new structure (sequence) context and then creates the respective type for the map */ create_hash_map(&hash_map, 0); create_type(&type, MAP_TYPE); *type = map_type(hash_map); case SORT_MAP_TYPE: /* creates a new sort map for the new structure (sequence) context and then creates the respective type for the map */ create_sort_map(&sort_map, 0); create_type(&type, SORT_MAP_TYPE); *type = sort_map_type(sort_map); default: /* creates a new sort map for the new structure (sequence) context and then creates the respective type for the map */ create_sort_map(&sort_map, 0); create_type(&type, SORT_MAP_TYPE); *type = sort_map_type(sort_map); } /* adds the sequence type to the sequence stack and then adds the current handler key to the key stack, then updates the current sequence reference and the current key in the handler */ append_value_linked_list(bencoding_handler->sequence_stack, (void *) type); append_value_linked_list(bencoding_handler->key_stack, (void *) bencoding_handler->key); bencoding_handler->sequence = type; bencoding_handler->key = NULL; /* in case there is no top type defined for the handler sets the current type as the top type (base type) */ if(bencoding_handler->top == NULL) { bencoding_handler->top = type; } /* sets the next key flag so that in the next iteration the string is "accepted" as the current key value */ bencoding_handler->next_key = 1; /* raises no error */ RAISE_NO_ERROR; }
void test_user_defined_type() { Type* type = create_type(); handle_t::setup_type<MyType>(type); // Create a value and then free it. test_assert(MyType_allocated == 0); caValue value; handle_t::set(&value, type, new MyType()); test_assert(MyType_allocated == 1); set_null(&value); test_assert(MyType_allocated == 0); // Overwrite a value with a new value handle_t::set(&value, type, new MyType()); test_assert(MyType_allocated == 1); handle_t::set(&value, type, new MyType()); test_assert(MyType_allocated == 1); handle_t::set(&value, type, new MyType()); test_assert(MyType_allocated == 1); set_null(&value); test_assert(MyType_allocated == 0); };
/*create a function and add it into function list *the function is defined by an extdef node in syntax tree*/ struct func_descriptor* create_function(struct tree_node* specifier_node, struct tree_node* fundec_node){ char* func_name = fundec_node -> child -> unit_value; if(find_func(func_table_head, func_name) != NULL){ printf("Error type 4 at line %d: Function \'%s\'redifine\n", fundec_node -> lineno, func_name); semantic_error_flag = true; return NULL; } if(is_struct_type(specifier_node) && is_struct_definition(specifier_node -> child)){ printf("Warnning: struct defined inside return field of function \'%s\'\n", func_name); } /*handle return type*/ struct type_descriptor* return_type = create_type(specifier_node); /*create func descriptor and add into list*/ struct func_descriptor* new_func_descriptor = create_func_descriptor(func_name, return_type, 0); add_func(func_table_head, new_func_descriptor); /*handle params*/ if(fundec_node -> child -> sibling -> sibling -> unit_code == VarList){ struct tree_node* varlist_node = fundec_node -> child -> sibling -> sibling; new_func_descriptor -> param_num = init_param_list(new_func_descriptor -> param_list_head, varlist_node); } return new_func_descriptor; }
ERROR_CODE _bencoding_list_start_callback(struct bencoding_engine_t *bencoding_engine) { /* allocates space for the linked list and for the type structure that will encapsulate it */ struct linked_list_t *list; struct type_t *type; /* retrieves the bencoding handler from the template engine context then uses it to store the (current) value */ struct bencoding_handler_t *bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context; /* creates a new linked list for the new structure (sequence) context and then creates the respective type for the list */ create_linked_list(&list); create_type(&type, LIST_TYPE); *type = list_type(list); /* adds the sequence type to the sequence stack and then adds the current handler key to the key stack, then updates the current sequence reference and the current key in the handler */ append_value_linked_list(bencoding_handler->sequence_stack, (void *) type); append_value_linked_list(bencoding_handler->key_stack, (void *) bencoding_handler->key); bencoding_handler->sequence = type; bencoding_handler->key = NULL; /* in case there is no top type defined for the handler sets the current type as the top type (base type) */ if(bencoding_handler->top == NULL) { bencoding_handler->top = type; } /* unsets the next key flag to avoid any possible misbehavior, colliding with the hash map structure */ bencoding_handler->next_key = 0; /* raises no error */ RAISE_NO_ERROR; }
/*创建一个结构体原型,返回其索引*/ extern int Tina_CreateProtype( const char * name,int index,int initial_acc) { struct_index++; create_type(struct_index,name); struct_list[struct_index].initializer_index=index; struct_list[struct_index].initializer_acc=initial_acc; return struct_index; }
Type* create_typed_unsized_list_type(Type* elementType) { Type* type = create_type(); list_t::setup_type(type); set_type(&type->parameter, elementType); std::string name = std::string("List<") + name_to_string(elementType->name) + ">"; type->name = name_from_string(name.c_str()); return type; }
Type* create_typed_unsized_list_type(Type* elementType) { Type* type = create_type(); list_t::setup_type(type); set_type(&type->parameter, elementType); std::string name = std::string("List<") + as_cstring(&elementType->name) + ">"; set_string(&type->name, name.c_str()); return type; }
void bug_with_lookup_type_and_qualified_name() { // Bug repro. There was an issue where, when searching for a qualified name, we would // use the original lookup type on the prefix. (which is wrong). Block block; Block* module = create_block(&block, "module"); Term* T = create_type(module, "T"); test_assert(T == find_name(&block, "module:T", -1, sym_LookupType)); }
Type* create_compound_type() { Type* type = create_type(); list_t::setup_type(type); caValue* param = &type->parameter; set_list(param, 2); set_list(list_get(param, 0), 0); set_list(list_get(param, 1), 0); return type; }
void test_import_type() { Type* type = create_type(); Branch branch; type->name = "A"; Term* term = import_type(&branch, type); test_assert(term->type->name == "Type"); test_assert(term->name == "A"); }
void create_type_table(Ttable *table) { type t_char = create_type(0,-1,1,-1); insert_type(tabla,t_char); // // // // // // }
/*create a variable and add it into a var list *var defined by the specifier and vardec nodes in syntax tree*/ struct var_descriptor* create_variable(struct tree_node* specifier_node, struct tree_node* vardec_node, struct var_descriptor* head, bool is_member_var){ struct type_descriptor* var_type = create_type(specifier_node); if(var_type == NULL) return NULL; char* var_name = find_id_node_in_vardec(vardec_node) -> unit_value; struct array_descriptor* var_array = create_array_descriptor_by_vardec(vardec_node); struct var_descriptor* new_var = create_var_descriptor(var_name, var_type, var_array); if(find_var(head, var_name) == NULL && find_struct(struct_table_head, var_name) == NULL){ add_var(head, new_var); return new_var; } else{ if(is_member_var) printf("Error type 15 at line %d: member variable \'%s\' redefine\n", vardec_node -> lineno, var_name); else printf("Error type 3 at line %d: variable \'%s\' redefine\n", vardec_node -> lineno, var_name); semantic_error_flag = true; return NULL; } }
ERROR_CODE _bencoding_string_end_callback(struct bencoding_engine_t *bencoding_engine, const unsigned char *pointer, size_t size) { /* allocates space for the reference to the type structure to hold the string */ struct type_t *type; /* retrieves the bencoding handler from the template engine context then uses it to store the (current) value */ struct bencoding_handler_t *bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context; /* allocates memory for the string and then copies the source pointer data into the string buffer for the provided size and then closes it */ char *string = MALLOC(size + 1); memcpy(string, pointer, size); string[size] = '\0'; /* in case the next key flag is active must set the current key as the just retrieved string */ if(bencoding_handler->next_key == 1) { /* in case there's a key pending to be release must release it to avoid memory leaks, then sets the current string as the key and unsets the next key flag to save the value */ if(bencoding_handler->key != NULL) { FREE(bencoding_handler->key); } bencoding_handler->key = (unsigned char *) string; bencoding_handler->next_key = 0; } /* otherwise in case the sequence type is defined the string must be a value and must be associated with the sequence */ else if(bencoding_handler->sequence != NULL) { /* creates a new type structure for the string and sets it with the correct string value */ create_type(&type, STRING_TYPE); *type = buffer_type(string, size); /* switches over the type of current sequence to execute the proper operations */ switch(bencoding_handler->sequence->type) { case LIST_TYPE: /* adds the current type to the list sequence */ append_value_linked_list( bencoding_handler->sequence->value.value_list, (void *) type ); /* breaks the switch */ break; case MAP_TYPE: /* sets the value in the map for the current key and sets the next key flag so that the next string is saved as a key */ set_value_string_hash_map( bencoding_handler->sequence->value.value_map, bencoding_handler->key, (void *) type ); bencoding_handler->next_key = 1; /* breaks the switch */ break; case SORT_MAP_TYPE: /* sets the value in the map for the current key and sets the next key flag so that the next string is saved as a key */ set_value_string_sort_map( bencoding_handler->sequence->value.value_sort_map, bencoding_handler->key, (void *) type ); bencoding_handler->next_key = 1; /* breaks the switch */ break; default: /* breaks the switch */ break; } } /* in case there is no top type defined for the handler sets the current type as the top type (base type) */ if(bencoding_handler->top == NULL) { bencoding_handler->top = type; } /* raises no error */ RAISE_NO_ERROR; }
static Type* analyze_exp(NODE* exp){ /*child_head*/ if(exp->attr == NULL){ NODE * temp = exp->child_head ; if(temp->name == terminal_name[ID - WHILE]){ NODE* ntemp = temp->next_sister ; IDTEM* tid = temp->value.type_p ; tid = tid->cur; temp->value.type_p = tid ; temp->parent->attr = tid->u.t;//Exp get attr from ID temp->value.type_p = tid ; if(ntemp == NULL){ if(tid->kind != VARIABLE_KIND){ error("Undefined variable",1,temp->line); temp->parent->attr = create_type(); }else{ if(temp->parent->attr){}else{ temp->parent->attr = create_type(); } } }else if(ntemp->name == terminal_name[LP - WHILE]){ if(tid->kind == UNSPECIFIED ){ error("Undefined function",2,temp->line); temp->parent->attr = create_type(); }else if(tid->kind == FUNCTION_KIND){ FieldList * arg = tid->u.funtype.varhead ; NODE * tmp = temp->next_sister->next_sister ; analyze_args_exp(tmp , arg) ; }else if(tid->kind == STRUCTURE_KIND){ error("not a function before \'(\':it\'s a struct name",11,ntemp->line); temp->parent->attr = create_type(); }else{ error("not a function before \'(\':it\'s a variable",11,ntemp->line); temp->parent->attr = create_type(); } } }else if(temp->name == terminal_name[FLOAT - WHILE]){ (temp->parent->attr = create_type_kind(BASIC_TYPE,float_type)) ;//Exp get attr from FLOAT }else if(temp->name == terminal_name[INT - WHILE]){ (temp->parent->attr = create_type_kind(BASIC_TYPE,int_type)) ;//Exp get attr from INT }else if(temp->name == terminal_name[MINUS - WHILE]){//int or float Type * ttype = temp->parent->attr = analyze_exp(temp->next_sister) ;//Exp get attr from Exp after MINUS if(ttype->kind == BASIC_TYPE){ }else { error("illegal arithmetic operation",7,temp->line); } (temp->parent->attr = ttype) ; }else if(temp->name == terminal_name[LP - WHILE]){ (temp->parent->attr = analyze_exp(temp->next_sister)) ;//Exp get attr from Exp after LP }else if(temp->name == terminal_name[NOT - WHILE]){// only int Type * ttype = temp->parent->attr = analyze_exp(temp->next_sister) ;//Exp get attr from Exp after MINUS if(ttype->kind == BASIC_TYPE && ttype->u.basic == int_type){ }else { error("illegal NOT logic operation",7,temp->line); } (temp->parent->attr = ttype) ; }else if(temp->name == nonterminal_name[Exp]){ NODE* ntemp = temp->next_sister; if(ntemp->name == terminal_name[AND - WHILE] || ntemp->name == terminal_name[OR - WHILE]){//only int Type * ttype1 = analyze_exp(temp) ; Type * ttype2 = analyze_exp(ntemp->next_sister) ; if(ttype1->kind == ttype2->kind && ttype1->kind == BASIC_TYPE && ttype1->u.basic == ttype2->u.basic && ttype1->u.basic == int_type){ (temp->parent->attr = ttype1) ; }else{ error("illegal logic operation ",7,ntemp->line); (temp->parent->attr = create_type_kind(BASIC_TYPE,int_type)); } }else if(ntemp->name == terminal_name[PLUS - WHILE]|| ntemp->name == terminal_name[MINUS - WHILE]|| ntemp->name == terminal_name[STAR - WHILE]|| ntemp->name == terminal_name[DIV - WHILE] ){//int or float Type * ttype1 = analyze_exp(temp) ; Type * ttype2 = analyze_exp(ntemp->next_sister) ; if(ttype1->kind == ttype2->kind && ttype1->kind == BASIC_TYPE && ttype1->u.basic == ttype2->u.basic){ }else { error("illegal arithmetic operation" , 7 , ntemp->line); } (temp->parent->attr = ttype1) ; }else if(ntemp->name == terminal_name[RELOP - WHILE]){//int or float Type * ttype1 = analyze_exp(temp) ; Type * ttype2 = analyze_exp(ntemp->next_sister) ; if(ttype1->kind == ttype2->kind && ttype1->kind == BASIC_TYPE && ttype1->u.basic == ttype2->u.basic){ }else { error("illegal relation operation",7,ntemp->line); } (temp->parent->attr = create_type_kind(BASIC_TYPE,int_type)); }else if(ntemp->name == terminal_name[LB - WHILE]){ Type * ttype1 = analyze_exp(temp) ; Type * ttype2 = analyze_exp(ntemp->next_sister) ; if(ttype2->kind == BASIC_TYPE && ttype2->u.basic == int_type){ }else{ error("noninteger in bracket",12,ntemp->next_sister->line); } if(ttype1->kind == ARRAY_TYPE){ (temp->parent->attr = ttype1->u.array.elem ); }else { error("not an array before \'[\'",10,ntemp->line); (temp->parent->attr = create_type()); } }else if(ntemp->name == terminal_name[ASSIGNOP - WHILE]){ Type * ttype1 = analyze_exp(temp) ; Type * ttype2 = analyze_exp(ntemp->next_sister) ; if((temp->child_head->name == terminal_name[ID - WHILE] && temp->child_head->next_sister == NULL)|| (temp->child_head->name == nonterminal_name[Exp] && ( temp->child_head->next_sister->name == terminal_name[LB - WHILE] || temp->child_head->next_sister->name == terminal_name[DOT - WHILE] ))){// temp->child_head->next_sister may not be null pointer if(ttype1->kind == ttype2->kind && ttype1->kind == BASIC_TYPE && ttype1->u.basic == ttype2->u.basic){ }else if(ttype1->kind == ttype2->kind && ttype1->kind == STRUCTURE_TYPE && ttype1->u.structure.name == ttype2->u.structure.name){ }else { if(ttype1->kind != UNSPECIFIED && ttype2->kind != UNSPECIFIED) error("unmatched type",5,ntemp->line); } (temp->parent->attr = ttype1) ; }else{ error("lvalue expression expected",6,ntemp->line); (temp->parent->attr = ttype2) ; } }else if(ntemp->name == terminal_name[DOT - WHILE]){ Type * ttype1 = analyze_exp(temp) ; IDTEM * tid = ntemp->next_sister->value.type_p ; tid = tid->cur ; const char * ctemp = tid->name ; if(ttype1->kind == STRUCTURE_TYPE){ FieldList * field = ttype1->u.structure.field; while(field){ if(strcmp(field->name,ctemp) == 0){ break; } field = field->tail ; } if(field == NULL){ error("undefined field" , 14, ntemp->next_sister->line); (temp->parent->attr = create_type()); }else{ (temp->parent->attr = field->type); } }else{ error("not a structure before \'.\'",13,ntemp->line); (temp->parent->attr = create_type()); } } } } { NODE * temp = exp->previous_sister ; if(temp && temp->name == terminal_name[RETURN - WHILE]){ NODE * tmp = temp; Type * ttype1 ; Type * ttype2 = exp->attr ; while((tmp = tmp->parent)->name != nonterminal_name[CompSt]) {}//tmp->name ==CompSt tmp = tmp->previous_sister ;//tmp->name == FunDec ttype1 = tmp->attr ; if(ttype1->kind == ttype2->kind && ttype1->kind == BASIC_TYPE && ttype1->u.basic == ttype2->u.basic){ }else if(ttype1->kind == ttype2->kind && ttype1->kind == STRUCTURE_TYPE && cmp_structure_name(ttype1,ttype2)==0){ }else { error("function return unmatched type",8,temp->line); } }else if(temp && temp->name == terminal_name[ASSIGNOP - WHILE] && temp->previous_sister && temp->previous_sister->name == nonterminal_name[VarDec] && temp->next_sister && temp->next_sister->name == nonterminal_name[Exp]){ NODE * tmp1 = temp->previous_sister ; NODE * tmp2 = temp->next_sister ; Type* ttype1 = tmp1->attr ; Type* ttype2 = tmp2->attr ; if(ttype1->kind == ttype2->kind && ttype1->kind == BASIC_TYPE && ttype1->u.basic == ttype2->u.basic){ }else if(ttype1->kind == ttype2->kind && ttype1->kind == STRUCTURE_TYPE && cmp_structure_name(ttype1,ttype2)==0){ }else { error("unmatched type before and after \'=\'",5,temp->line); } } } return exp->attr; }
ERROR_CODE _bencoding_integer_end_callback(struct bencoding_engine_t *bencoding_engine, const unsigned char *pointer, size_t size) { /* allocates space for the integer value and for the type that will encapsulate it */ int _integer; struct type_t *type; /* retrieves the bencoding handler from the template engine context then uses it to store the (current) value */ struct bencoding_handler_t *bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context; /* allocates space for the integer string value and then copies the data buffer into it and terminates the null string */ char *integer = MALLOC(size + 1); memcpy(integer, pointer, size); integer[size] = '\0'; /* in case the sequence type is defined the integer must be a value and must be associated with the sequence */ if(bencoding_handler->sequence != NULL) { /* converts the integer string into an integer value, then creates the type structure for the integer and sets it as an integer value */ _integer = atoi(integer); create_type(&type, INTEGER_TYPE); *type = integer_type(_integer); /* switches over the type of current sequence to execute the proper operations */ switch(bencoding_handler->sequence->type) { case LIST_TYPE: /* adds the current type to the list sequence */ append_value_linked_list(bencoding_handler->sequence->value.value_list, (void *) type); /* breaks the switch */ break; case MAP_TYPE: /* sets the value in the map for the current key and sets the next key flag so that the next string is saved as a key */ set_value_string_hash_map(bencoding_handler->sequence->value.value_map, bencoding_handler->key, (void *) type); bencoding_handler->next_key = 1; /* breaks the switch */ break; case SORT_MAP_TYPE: /* sets the value in the map for the current key and sets the next key flag so that the next string is saved as a key */ set_value_string_sort_map(bencoding_handler->sequence->value.value_sort_map, bencoding_handler->key, (void *) type); bencoding_handler->next_key = 1; /* breaks the switch */ break; default: /* breaks the switch */ break; } } /* in case there is no top type defined for the handler sets the current type as the top type (base type) */ if(bencoding_handler->top == NULL) { bencoding_handler->top = type; } /* releases the memory associated with the intger string value in order to avoid memory leaks */ FREE(integer); /* raises no error */ RAISE_NO_ERROR; }
void bootstrap_kernel() { // First, instanciate the types that are used by Type. TYPES.dict = create_type_uninitialized(); TYPES.null = create_type_uninitialized(); TYPES.string = create_type_uninitialized(); TYPES.type = create_type_uninitialized(); initialize_type(TYPES.dict); initialize_type(TYPES.null); initialize_type(TYPES.string); initialize_type(TYPES.type); string_setup_type(TYPES.string); // Initialize remaining global types. TYPES.any = create_type(); TYPES.block = create_type(); TYPES.bool_type = create_type(); TYPES.error = create_type(); TYPES.eval_context = create_type(); TYPES.float_type = create_type(); TYPES.function = create_type(); TYPES.int_type = create_type(); TYPES.list = create_type(); TYPES.map = create_type(); TYPES.opaque_pointer = create_type(); TYPES.symbol = create_type(); TYPES.term = create_type(); TYPES.void_type = create_type(); any_t::setup_type(TYPES.any); block_setup_type(TYPES.block); bool_t::setup_type(TYPES.bool_type); dict_t::setup_type(TYPES.dict); eval_context_t::setup_type(TYPES.eval_context); function_t::setup_type(TYPES.function); hashtable_setup_type(TYPES.map); int_t::setup_type(TYPES.int_type); list_t::setup_type(TYPES.list); symbol_setup_type(TYPES.symbol); null_t::setup_type(TYPES.null); number_t::setup_type(TYPES.float_type); opaque_pointer_t::setup_type(TYPES.opaque_pointer); term_setup_type(TYPES.term); string_setup_type(TYPES.error); // errors are just stored as strings for now type_t::setup_type(TYPES.type); void_t::setup_type(TYPES.void_type); // Start building World g_world = alloc_world(); g_world->bootstrapStatus = sym_Bootstrapping; // Create root Block. g_world->root = new Block(); Block* kernel = g_world->root; // Create value function Term* valueFunc = kernel->appendNew(); rename(valueFunc, "value"); FUNCS.value = valueFunc; // Create Type type Term* typeType = kernel->appendNew(); typeType->function = FUNCS.value; typeType->type = TYPES.type; term_value(typeType)->value_type = TYPES.type; term_value(typeType)->value_data.ptr = TYPES.type; TYPES.type->declaringTerm = typeType; rename(typeType, "Type"); // Create Any type Term* anyType = kernel->appendNew(); anyType->function = valueFunc; anyType->type = TYPES.type; term_value(anyType)->value_type = TYPES.type; term_value(anyType)->value_data.ptr = TYPES.any; TYPES.any->declaringTerm = anyType; rename(anyType, "any"); // Create Function type Term* functionType = kernel->appendNew(); functionType->function = valueFunc; functionType->type = TYPES.type; TYPES.function->declaringTerm = functionType; term_value(functionType)->value_type = TYPES.type; term_value(functionType)->value_data.ptr = TYPES.function; rename(functionType, "Function"); // Initialize value() func valueFunc->type = TYPES.function; valueFunc->function = valueFunc; make(TYPES.function, term_value(valueFunc)); function_t::initialize(TYPES.function, term_value(valueFunc)); initialize_function(valueFunc); as_function(valueFunc)->name = "value"; block_set_evaluation_empty(function_contents(valueFunc), true); // Initialize primitive types (this requires value() function) create_type_value(kernel, TYPES.bool_type, "bool"); create_type_value(kernel, TYPES.block, "Block"); create_type_value(kernel, TYPES.dict, "Dict"); create_type_value(kernel, TYPES.float_type, "number"); create_type_value(kernel, TYPES.int_type, "int"); create_type_value(kernel, TYPES.list, "List"); create_type_value(kernel, TYPES.opaque_pointer, "opaque_pointer"); create_type_value(kernel, TYPES.string, "String"); create_type_value(kernel, TYPES.symbol, "Symbol"); create_type_value(kernel, TYPES.term, "Term"); create_type_value(kernel, TYPES.void_type, "void"); create_type_value(kernel, TYPES.map, "Map"); // Finish initializing World (this requires List and Hashtable types) world_initialize(g_world); // Create global symbol table (requires Hashtable type) symbol_initialize_global_table(); // Setup output_placeholder() function, needed to declare functions properly. FUNCS.output = create_value(kernel, TYPES.function, "output_placeholder"); function_t::initialize(TYPES.function, term_value(FUNCS.output)); initialize_function(FUNCS.output); as_function(FUNCS.output)->name = "output_placeholder"; as_function(FUNCS.output)->evaluate = NULL; as_function(FUNCS.output)->specializeType = output_placeholder_specializeType; ca_assert(function_get_output_type(FUNCS.output, 0) == TYPES.any); // Fix some holes in value() function { Function* attrs = as_function(valueFunc); Term* output = append_output_placeholder(function_contents(attrs), NULL); change_declared_type(output, TYPES.any); finish_building_function(function_contents(attrs)); } ca_assert(function_get_output_type(valueFunc, 0) == TYPES.any); // input_placeholder() is needed before we can declare a function with inputs FUNCS.input = import_function(kernel, NULL, "input_placeholder() -> any"); block_set_evaluation_empty(function_contents(FUNCS.input), true); // Now that we have input_placeholder() let's declare one input on output_placeholder() apply(function_contents(as_function(FUNCS.output)), FUNCS.input, TermList())->setBoolProp("optional", true); namespace_function::early_setup(kernel); // Setup declare_field() function, needed to represent compound types. FUNCS.declare_field = import_function(kernel, NULL, "declare_field() -> any"); // Initialize a few more types Term* set_type = create_value(kernel, TYPES.type, "Set"); set_t::setup_type(unbox_type(set_type)); Term* indexableType = create_value(kernel, TYPES.type, "Indexable"); indexable_t::setup_type(unbox_type(indexableType)); TYPES.selector = unbox_type(create_value(kernel, TYPES.type, "Selector")); list_t::setup_type(TYPES.selector); control_flow_setup_funcs(kernel); selector_setup_funcs(kernel); loop_setup_functions(kernel); // Setup all the builtin functions defined in src/functions setup_builtin_functions(kernel); FUNCS.section_block = import_function(kernel, NULL, "def section_block() -> any"); as_function(FUNCS.section_block)->formatSource = section_block_formatSource; // Create IMPLICIT_TYPES (deprecated) type_initialize_kernel(kernel); // Now we can build derived functions // Create overloaded functions FUNCS.add = create_overloaded_function(kernel, "add(any a,any b) -> any"); append_to_overloaded_function(FUNCS.add, FUNCS.add_i); append_to_overloaded_function(FUNCS.add, FUNCS.add_f); Term* less_than = create_overloaded_function(kernel, "less_than(any a,any b) -> bool"); append_to_overloaded_function(less_than, kernel->get("less_than_i")); append_to_overloaded_function(less_than, kernel->get("less_than_f")); Term* less_than_eq = create_overloaded_function(kernel, "less_than_eq(any a,any b) -> bool"); append_to_overloaded_function(less_than_eq, kernel->get("less_than_eq_i")); append_to_overloaded_function(less_than_eq, kernel->get("less_than_eq_f")); Term* greater_than = create_overloaded_function(kernel, "greater_than(any a,any b) -> bool"); append_to_overloaded_function(greater_than, kernel->get("greater_than_i")); append_to_overloaded_function(greater_than, kernel->get("greater_than_f")); Term* greater_than_eq = create_overloaded_function(kernel, "greater_than_eq(any a,any b) -> bool"); append_to_overloaded_function(greater_than_eq, kernel->get("greater_than_eq_i")); append_to_overloaded_function(greater_than_eq, kernel->get("greater_than_eq_f")); Term* max_func = create_overloaded_function(kernel, "max(any a,any b) -> any"); append_to_overloaded_function(max_func, kernel->get("max_i")); append_to_overloaded_function(max_func, kernel->get("max_f")); Term* min_func = create_overloaded_function(kernel, "min(any a,any b) -> any"); append_to_overloaded_function(min_func, kernel->get("min_i")); append_to_overloaded_function(min_func, kernel->get("min_f")); Term* remainder_func = create_overloaded_function(kernel, "remainder(any a,any b) -> any"); append_to_overloaded_function(remainder_func, kernel->get("remainder_i")); append_to_overloaded_function(remainder_func, kernel->get("remainder_f")); Term* mod_func = create_overloaded_function(kernel, "mod(any a,any b) -> any"); append_to_overloaded_function(mod_func, kernel->get("mod_i")); append_to_overloaded_function(mod_func, kernel->get("mod_f")); FUNCS.mult = create_overloaded_function(kernel, "mult(any a,any b) -> any"); append_to_overloaded_function(FUNCS.mult, kernel->get("mult_i")); append_to_overloaded_function(FUNCS.mult, kernel->get("mult_f")); FUNCS.neg = create_overloaded_function(kernel, "neg(any n) -> any"); append_to_overloaded_function(FUNCS.neg, kernel->get("neg_i")); append_to_overloaded_function(FUNCS.neg, kernel->get("neg_f")); as_function(FUNCS.neg)->formatSource = neg_function::formatSource; FUNCS.sub = create_overloaded_function(kernel, "sub(any a,any b) -> any"); append_to_overloaded_function(FUNCS.sub, kernel->get("sub_i")); append_to_overloaded_function(FUNCS.sub, kernel->get("sub_f")); // Create vectorized functions Term* add_v = create_function(kernel, "add_v"); create_function_vectorized_vv(function_contents(add_v), FUNCS.add, TYPES.list, TYPES.list); Term* add_s = create_function(kernel, "add_s"); create_function_vectorized_vs(function_contents(add_s), FUNCS.add, TYPES.list, TYPES.any); append_to_overloaded_function(FUNCS.add, add_v); append_to_overloaded_function(FUNCS.add, add_s); Term* sub_v = create_function(kernel, "sub_v"); create_function_vectorized_vv(function_contents(sub_v), FUNCS.sub, TYPES.list, TYPES.list); Term* sub_s = create_function(kernel, "sub_s"); create_function_vectorized_vs(function_contents(sub_s), FUNCS.sub, TYPES.list, TYPES.any); append_to_overloaded_function(FUNCS.sub, sub_v); append_to_overloaded_function(FUNCS.sub, sub_s); // Create vectorized mult() functions Term* mult_v = create_function(kernel, "mult_v"); create_function_vectorized_vv(function_contents(mult_v), FUNCS.mult, TYPES.list, TYPES.list); Term* mult_s = create_function(kernel, "mult_s"); create_function_vectorized_vs(function_contents(mult_s), FUNCS.mult, TYPES.list, TYPES.any); append_to_overloaded_function(FUNCS.mult, mult_v); append_to_overloaded_function(FUNCS.mult, mult_s); Term* div_s = create_function(kernel, "div_s"); create_function_vectorized_vs(function_contents(div_s), FUNCS.div, TYPES.list, TYPES.any); // Need dynamic_method before any hosted functions FUNCS.dynamic_method = import_function(kernel, dynamic_method_call, "def dynamic_method(any inputs :multiple) -> any"); // Load the standard library from stdlib.ca parser::compile(kernel, parser::statement_list, STDLIB_CA_TEXT); // Install C functions static const ImportRecord records[] = { {"assert", hosted_assert}, {"cppbuild:build_module", cppbuild_function::build_module}, {"file:version", file__version}, {"file:exists", file__exists}, {"file:read_text", file__read_text}, {"length", length}, {"from_string", from_string}, {"to_string_repr", to_string_repr}, {"call_actor", call_actor_func}, {"send", send_func}, {"test_spy", test_spy}, {"test_oracle", test_oracle}, {"refactor:rename", refactor__rename}, {"refactor:change_function", refactor__change_function}, {"reflect:this_block", reflect__this_block}, {"reflect:kernel", reflect__kernel}, {"sys:module_search_paths", sys__module_search_paths}, {"sys:perf_stats_reset", sys__perf_stats_reset}, {"sys:perf_stats_dump", sys__perf_stats_dump}, {"Dict.count", Dict__count}, {"Dict.get", Dict__get}, {"Dict.set", Dict__set}, {"Function.block", Function__block}, {"empty_list", empty_list}, {"List.append", List__append}, {"List.concat", List__concat}, {"List.resize", List__resize}, {"List.count", List__count}, {"List.insert", List__insert}, {"List.length", List__length}, {"List.join", List__join}, {"List.slice", List__slice}, {"List.get", List__get}, {"List.set", List__set}, {"Map.contains", Map__contains}, {"Map.remove", Map__remove}, {"Map.get", Map__get}, {"Map.set", Map__set}, {"Map.insertPairs", Map__insertPairs}, {"Mutable.get", Mutable__get}, {"Mutable.set", Mutable__set}, {"String.char_at", String__char_at}, {"String.ends_with", String__ends_with}, {"String.length", String__length}, {"String.substr", String__substr}, {"String.slice", String__slice}, {"String.starts_with", String__starts_with}, {"String.split", String__split}, {"String.to_camel_case", String__to_camel_case}, {"String.to_upper", String__to_upper}, {"String.to_lower", String__to_lower}, {"Type.name", Type__name}, {"Type.property", Type__property}, {"Type.declaringTerm", Type__declaringTerm}, {"type", typeof_func}, {"static_type", static_type_func}, {NULL, NULL} }; install_function_list(kernel, records); closures_install_functions(kernel); modules_install_functions(kernel); reflection_install_functions(kernel); interpreter_install_functions(kernel); // Fetch refereneces to certain builtin funcs. FUNCS.block_dynamic_call = kernel->get("Block.call"); FUNCS.dll_patch = kernel->get("sys:dll_patch"); FUNCS.dynamic_call = kernel->get("dynamic_call"); FUNCS.has_effects = kernel->get("has_effects"); FUNCS.length = kernel->get("length"); FUNCS.list_append = kernel->get("List.append"); FUNCS.native_patch = kernel->get("native_patch"); FUNCS.not_func = kernel->get("not"); FUNCS.output_explicit = kernel->get("output"); FUNCS.type = kernel->get("type"); block_set_has_effects(nested_contents(FUNCS.has_effects), true); // Finish setting up some hosted types TYPES.actor = as_type(kernel->get("Actor")); TYPES.color = as_type(kernel->get("Color")); TYPES.closure = as_type(kernel->get("Closure")); callable_t::setup_type(as_type(kernel->get("Callable"))); TYPES.frame = as_type(kernel->get("Frame")); TYPES.point = as_type(kernel->get("Point")); TYPES.file_signature = as_type(kernel->get("FileSignature")); Type* mutableType = as_type(kernel->get("Mutable")); circa_setup_object_type(mutableType, sizeof(Value), MutableRelease); mutableType->initialize = MutableInitialize; color_t::setup_type(TYPES.color); as_function(FUNCS.list_append)->specializeType = List__append_specializeType; }
static void set_typedef_type(SgScopeStatement& n, const std::string& name, SgTypedefType*& res) { res = create_type(n, name, res); ROSE_ASSERT(res); }
static void set_rtedtype(SgScopeStatement& n, const std::string& name, SgClassType*& res) { res = create_type(n, rtedIdentifier(name), res); ROSE_ASSERT(res); }
void bootstrap_kernel() { memset(&FUNCS, 0, sizeof(FUNCS)); memset(&TYPES, 0, sizeof(TYPES)); // Allocate a World object. g_world = alloc_world(); g_world->bootstrapStatus = s_Bootstrapping; World* world = g_world; // Instanciate the types that are used by Type. TYPES.table = create_type_unconstructed(); TYPES.nil = create_type_unconstructed(); TYPES.string = create_type_unconstructed(); TYPES.type = create_type_unconstructed(); // Now we can fully instanciate types. type_finish_construction(TYPES.table); type_finish_construction(TYPES.nil); type_finish_construction(TYPES.string); type_finish_construction(TYPES.type); string_setup_type(TYPES.string); // Initialize remaining global types. TYPES.any = create_type(); TYPES.blob = create_type(); TYPES.block = create_type(); TYPES.bool_type = create_type(); TYPES.error = create_type(); TYPES.float_type = create_type(); TYPES.int_type = create_type(); TYPES.list = create_type(); TYPES.native_ptr = create_type(); TYPES.table = create_type(); TYPES.opaque_pointer = create_type(); TYPES.symbol = create_type(); TYPES.term = create_type(); TYPES.vm = create_type(); TYPES.void_type = create_type(); for_each_root_type(type_set_root); any_setup_type(TYPES.any); blob_setup_type(TYPES.blob); block_setup_type(TYPES.block); bool_setup_type(TYPES.bool_type); hashtable_setup_type(TYPES.table); int_setup_type(TYPES.int_type); list_t::setup_type(TYPES.list); symbol_setup_type(TYPES.symbol); native_ptr_setup_type(TYPES.native_ptr); null_setup_type(TYPES.nil); number_setup_type(TYPES.float_type); opaque_pointer_setup_type(TYPES.opaque_pointer); term_setup_type(TYPES.term); string_setup_type(TYPES.error); // errors are just stored as strings for now type_t::setup_type(TYPES.type); void_setup_type(TYPES.void_type); vm_setup_type(TYPES.vm); // Finish initializing World (this requires List and Hashtable types) world_initialize(g_world); // Create builtins block. Value builtinsStr; set_string(&builtinsStr, "builtins"); Block* builtins = create_module(g_world); module_set_name(world, builtins, &builtinsStr); g_world->builtins = builtins; // Create function_decl function. Term* functionDeclFunction = builtins->appendNew(); rename(functionDeclFunction, "function_decl"); FUNCS.function_decl = functionDeclFunction; FUNCS.function_decl->function = FUNCS.function_decl; make_nested_contents(FUNCS.function_decl); block_set_function_has_nested(nested_contents(FUNCS.function_decl), true); // Create value function Term* valueFunc = builtins->appendNew(); rename(valueFunc, "value"); FUNCS.value = valueFunc; // Create Type type Term* typeType = builtins->appendNew(); typeType->function = FUNCS.value; typeType->type = TYPES.type; term_value(typeType)->value_type = TYPES.type; term_value(typeType)->value_data.ptr = TYPES.type; TYPES.type->declaringTerm = typeType; rename(typeType, "Type"); // Create Any type Term* anyType = builtins->appendNew(); anyType->function = valueFunc; anyType->type = TYPES.type; term_value(anyType)->value_type = TYPES.type; term_value(anyType)->value_data.ptr = TYPES.any; TYPES.any->declaringTerm = anyType; rename(anyType, "any"); // Initialize value() func valueFunc->type = TYPES.any; valueFunc->function = FUNCS.function_decl; make_nested_contents(valueFunc); block_set_evaluation_empty(nested_contents(valueFunc), true); // Initialize primitive types (this requires value() function) create_type_value(builtins, TYPES.blob, "Blob"); create_type_value(builtins, TYPES.bool_type, "bool"); create_type_value(builtins, TYPES.block, "Block"); create_type_value(builtins, TYPES.float_type, "number"); create_type_value(builtins, TYPES.int_type, "int"); create_type_value(builtins, TYPES.list, "List"); create_type_value(builtins, TYPES.opaque_pointer, "opaque_pointer"); create_type_value(builtins, TYPES.native_ptr, "native_ptr"); create_type_value(builtins, TYPES.string, "String"); create_type_value(builtins, TYPES.symbol, "Symbol"); create_type_value(builtins, TYPES.term, "Term"); create_type_value(builtins, TYPES.table, "Table"); create_type_value(builtins, TYPES.void_type, "void"); create_type_value(builtins, TYPES.vm, "VM"); // Create global symbol table (requires Hashtable type) symbol_initialize_global_table(); // Setup output_placeholder() function, needed to declare functions properly. FUNCS.output = apply(builtins, FUNCS.function_decl, TermList(), "output_placeholder"); nested_contents(FUNCS.output)->overrides.specializeType = output_placeholder_specializeType; ca_assert(get_output_type(nested_contents(FUNCS.output), 0) == TYPES.any); // Now that output_placeholder is created, fix the value() function. { Term* output = append_output_placeholder(nested_contents(valueFunc), NULL); set_declared_type(output, TYPES.any); finish_building_function(nested_contents(valueFunc)); } ca_assert(get_output_type(nested_contents(valueFunc), 0) == TYPES.any); // input_placeholder() is needed before we can declare a function with inputs FUNCS.input = apply(builtins, FUNCS.function_decl, TermList(), "input_placeholder"); block_set_evaluation_empty(nested_contents(FUNCS.input), true); // Now that we have input_placeholder(), declare one input on output_placeholder() apply(nested_contents(FUNCS.output), FUNCS.input, TermList())->setBoolProp(s_Optional, true); // Initialize a few more types TYPES.selector = unbox_type(create_value(builtins, TYPES.type, "Selector")); list_t::setup_type(TYPES.selector); // Need the comment() function before parsing stdlib.ca FUNCS.comment = apply(builtins, FUNCS.function_decl, TermList(), "comment"); // Parse stdlib.ca parse(builtins, parse_statement_list, find_builtin_file("$builtins/stdlib.ca")); set_string(block_insert_property(builtins, s_ModuleName), "stdlib"); blob_install_functions(world->builtinPatch); selector_setup_funcs(world->builtinPatch); closures_install_functions(world->builtinPatch); reflection_install_functions(world->builtinPatch); misc_builtins_setup_functions(world->builtinPatch); type_install_functions(world->builtinPatch); vm_install_functions(world->builtinPatch); block_set_bool_prop(builtins, s_Builtins, true); ca_assert(FUNCS.declared_state != NULL); nested_contents(FUNCS.add)->overrides.specializeType = specializeType_add_sub_mult; nested_contents(FUNCS.sub)->overrides.specializeType = specializeType_add_sub_mult; nested_contents(FUNCS.mult)->overrides.specializeType = specializeType_add_sub_mult; nested_contents(FUNCS.div)->overrides.specializeType = specializeType_div; FUNCS.get_with_symbol = builtins->get("get_with_symbol"); FUNCS.length = builtins->get("length"); FUNCS.list_append = builtins->get("List.append"); FUNCS.native_patch = builtins->get("native_patch"); FUNCS.package = builtins->get("package"); nested_contents(builtins->get("Type.cast"))->overrides.specializeType = Type_cast_specializeType; // Finish setting up types that are declared in stdlib.ca. TYPES.color = as_type(builtins->get("Color")); TYPES.func = as_type(builtins->get("Func")); TYPES.module_ref = as_type(builtins->get("Module")); TYPES.vec2 = as_type(builtins->get("Vec2")); // Fix function_decl now that Func type is available. { set_declared_type(append_output_placeholder(nested_contents(FUNCS.function_decl), NULL), TYPES.func); set_declared_type(FUNCS.function_decl, TYPES.func); finish_building_function(nested_contents(FUNCS.function_decl)); } // Also, now that Func type is available, update all static closures. for (BlockIterator it(builtins); it; ++it) { Term* term = *it; if (is_function(term)) { set_declared_type(term, TYPES.func); if (term->owningBlock == builtins) // Functions at top level must be static closures update_static_closure_force(term); else update_static_closure_if_possible(term); } } nested_contents(FUNCS.list_append)->overrides.specializeType = List__append_specializeType; #define set_evaluation_empty(name) block_set_evaluation_empty(nested_contents(FUNCS.name), true) set_evaluation_empty(annotate); set_evaluation_empty(annotate_block); set_evaluation_empty(return_func); set_evaluation_empty(discard); set_evaluation_empty(break_func); set_evaluation_empty(continue_func); set_evaluation_empty(comment); set_evaluation_empty(extra_output); set_evaluation_empty(loop_iterator); set_evaluation_empty(static_error); #undef set_evaluation_empty block_link_missing_functions(builtins, builtins); }