void check_stmt(tree t) { for( ; t != NULL; t = t->next ) { switch (t->kind) { case If: case Elseif: if( check_expr(t->first) != Boolean ) { print_error("Invalid IF statement.", t); } check_stmt(t->second); check_stmt(t->third); continue; case Else: check_stmt(t->first); continue; case Exit: if(check_expr(t->first) != Boolean) { print_error("exit when must produce a boolean.", t); } continue; case Assign: if(t->first->kind == Obracket | check_expr(t->first) != check_expr(t->second)) { print_error("Invalid assignment statement.", t); } continue; case For: new_scope(); declare_var(id_name(t->first->value), Integer); if(check_expr(t->second->first) != Integer | check_expr(t->second->second) != Integer)//TODO or add a range check print_error("Invalid range.", t->second); check_stmt(t->third); end_scope(); continue; case Declaration:; if(t->second->kind == Array) { for(tree cur = t->first; cur != NULL; cur = cur->next) declare_array(id_name(cur->value), t->second->second->kind); } else { for(tree cur = t->first; cur != NULL; cur = cur->next) declare_var(id_name(cur->value), t->second->kind); } continue; case Declare: new_scope(); check_stmt(t->first); check_stmt(t->second); end_scope(); continue; default: print_error("Token of this type not checked by check_stmt.", t); continue; } } }
void StmtAssembler::visitWhile(While* p) { LabelPair labels; int ix = scope->nextIx(); labels.first = makeLabel("While_body", ix); labels.second = makeLabel("While_end", ix); std::string cond_label = makeLabel("While_cond", ix); stream << cond_label << ":" << std::endl; ExprAssembler expr_ass(scope, env, stream); expr_ass.labelStack.push(&labels); p->expr_->accept(&expr_ass); stackLimit = std::max(stackLimit, expr_ass.stackLimit); stream << labels.first << ":" << std::endl; Core::BlockScope::PtrType new_scope(new Core::BlockScope(scope)); StmtAssembler body_ass(new_scope, env, stream); p->stmt_->accept(&body_ass); stackLimit = std::max(stackLimit, body_ass.stackLimit); stream << " goto " << cond_label << std::endl; stream << labels.second << ":" << std::endl; };
void StmtAssembler::visitBlock(Block* p) { Core::BlockScope::PtrType new_scope(new Core::BlockScope(scope)); StmtAssembler stmt_ass(new_scope, env, stream); p->liststmt_->accept(&stmt_ass); stackLimit = std::max(stackLimit, stmt_ass.stackLimit); };
jomike::j_value Symbol_Component_List::derived_get_value(const Arguments& i_args)const{ assert(i_args.empty()); (void)i_args; //Symbol List getting the value is just getting the value of the last statement if(M_components.empty()){ throw J_Symbol_Error("Trying to get value from empty Symbol List!"); } J_Symbol_Scope new_scope(&symbol_scope()); j_value return_val = j_value(string(), J_Unit()); try{ for(auto symbol : M_components){ auto symbol_ptr = dynamic_cast<j_symbol*>(symbol); if(symbol_ptr){ symbol_ptr->get_value(); } } } catch(J_Routine_Transfer_Exception& e){ return_val += e.value(); } auto last_symbol = dynamic_cast<j_symbol*>(M_components.back()); if(!last_symbol){ throw J_Value_Error("Trying to get value from non j_symbol type. "); } return return_val; }
/* Function creates and inserts a scope table into table t*/ void insert_scope(char* n, tableptr t) { entryptr e = new_scope(n); insert(e, t); };
expr_val * compile_function(function_node * func, scope * current_scope, str_list * lines) { char * orig_name = func->name; char * name; // Declaring new scope scope * n_scope = new_scope(current_scope); expr_val * args = compile_statement(func->args, n_scope, lines); expr_val * return_type = compile_statement(func->return_type, n_scope, lines); // Does func with that name already exist if (get_variable_from_scope(current_scope, orig_name)) { int len = strlen(orig_name) + 46; char * msg = (char *) malloc(len); snprintf(msg, len, "Functions name already exists %s", orig_name); report_error(msg, 0); } else if(strcmp(orig_name, "main") == 0) { // @todo: remove this hack create_variable_in_scope(current_scope, orig_name, return_type->type, FUNC, &var_num); name = orig_name; } else { name = create_variable_in_scope(current_scope, orig_name, return_type->type, FUNC, &var_num); } int len = strlen(args->val) + strlen(return_type->val) + strlen(name) + 5; char * output = (char *) malloc(len); snprintf(output, len, "%s %s%s", return_type->val, name, args->val); insert_array(lines, output); compile_block(func->block, n_scope, lines, 1); return new_expr_val("(function)", NO_TYPE); }
/* * Creates a function scope using the function_declaration_t */ struct scope_t *symtab_create_function_scope(struct function_declaration_t *fd) { struct scope_t *temp_scope = new_scope(); // Sets its function properties temp_scope->attrId = SYM_ATTR_FUNC; temp_scope->fd = fd; return temp_scope; }
void TemplateEachExpr::render(std::string & buffer, expr::Scope &scope) const { //TODO: This is somewhat a workaround because String always owns the std::string. //It may be better just to always use the String object for template rendering auto tmp = create_object<String>(std::move(buffer)); expr::Scope new_scope(scope); new_scope.set("output_buffer", tmp); auto val = expression->eval(new_scope); buffer = std::move(tmp->get_value()); }
/* 'is_tmp_sc': true if the new scope is used for temprary. And it will be removed from the sub-scope-list while return to the parent. */ SCOPE * enter_sub_scope(bool is_tmp_sc) { SCOPE * sc = new_scope(); SCOPE_level(sc) = SCOPE_level(g_cur_scope) + 1; SCOPE_parent(sc) = g_cur_scope; SCOPE_is_tmp_sc(sc) = is_tmp_sc; //Add 'sc' as sub scope followed the most right one of subscope list. //e.g: first_sub_scope -> second_sub_scope -> ... add_next(&SCOPE_sub(g_cur_scope), sc); g_cur_scope = sc; return g_cur_scope; }
t_scope *create_scope(t_scope *scopes, char *id) { t_scope *cur; if (scopes == NULL) { return new_scope(id); } cur = scopes; while (cur->next != NULL) { if (strcmp(id, cur->id) == 0) { return NULL; } cur = cur->next; } cur->next = new_scope(id); return cur; }
/* * Creates a symtab scope entry for the class_list_t. * Checks for function scopes that have already been added to the symtab * and links them to the scope. Also adds the class to the root(program) * scope's class_scopes list. */ struct scope_t *symtab_create_class_scope(struct class_list_t *cl) { struct scope_t *classScope = new_scope(); // Sets its class properties classScope->attrId = SYM_ATTR_CLASS; classScope->cl = cl; classScope->parent = rootScope; // Parent scope is the program by default; // Find function scopes for each function in the class struct func_declaration_list_t *class_fdl = cl->cb->fdl; while(class_fdl != NULL) { struct scope_t *foundScope = symtab_lookup_function_scope(class_fdl->fd); if(foundScope == NULL) { // The function wasn't added to the symtab properly //printf("Could not find function scope for function %s for class %s\n", class_fdl->fd->fh->id, cl->ci->id); } else { // Set class scope as a sibling to other functions in the class // First function if(classScope->func_scopes == NULL) { classScope->func_scopes = foundScope; } else { // Add to end of sibling list struct scope_t *temp_scope = classScope->func_scopes; while(temp_scope->nextSibling != NULL) { temp_scope = temp_scope->nextSibling; } temp_scope->nextSibling = foundScope; } // Update the parent pointers foundScope->parent = classScope; } class_fdl = class_fdl->next; } // Update set class scope as a sibling to other classes in the program // First class scope if(rootScope->class_scopes == NULL) { rootScope->class_scopes = classScope; } else { // Add at end of sibling list struct scope_t *temp_scope = rootScope->class_scopes; while(temp_scope->nextSibling != NULL) { temp_scope = temp_scope->nextSibling; } temp_scope->nextSibling = classScope; } return classScope; }
void generate_three_address_code(block_node * statements) { // Writes basic functions to be used when generating three address code //prepare_cfile("out.c"); int i = 0; //init_array_vars(&vars, 2); init_array(&lines, 2); init_array(&functions, 2); init_errors(); scope * root_scope = new_scope(NULL); compile_block(statements, root_scope, &lines, 0); if(num_of_errors > 0) { print_array(&errors); } else { print_code(&lines); write_to_file(&lines, 0, "w+"); } }
void check_node(const Node* n) { for (auto input : n->inputs_) { if (!scope->contains(input)) { JIT_ASSERTM(0, "%%%d not in scope", input->unique()); } } JIT_ASSERT(anticipated_uses[n] == static_cast<int64_t>(n->inputs_.size())); anticipated_uses[n] = -1; // we saw the anticipated user! scope->insert(n); for(auto block : n->blocks()) { std::unique_ptr<LintScope> new_scope(new LintScope(std::move(scope))); scope = std::move(new_scope); check_block(block); scope = std::move(scope->parent); } size_t i = 0; for(auto o : n->outputs()) { JIT_ASSERT(o->node() == n); JIT_ASSERT(i++ == o->offset_); check_value(o); } n->lint(); }
int fcat_write_index_file(const char *dest, const char *src) { FILE *srcfd; FILE *destfd; struct token *t; int err = 0; struct decl **dec; struct token *curstd = NULL; struct token *curhead = NULL; unsigned long lines[4096] = { 0 }; int i; char buf[1024]; unsigned long count; fpos_t offsetpos; if ((srcfd = fopen(src, "r")) == NULL) { perror(src); return -1; } i = 0; count = 0; while (fgets(buf, sizeof buf, srcfd) != NULL) { lines[i++] = count; count += strlen(buf); } rewind(srcfd); if ((destfd = fopen(dest, "w")) == NULL) { perror(dest); (void) fclose(srcfd); return -1; } if (lex_nwcc(create_input_file(srcfd)) != 0) { (void) fprintf(stderr, "ERROR: Cannot lex function catalogue file\n"); return -1; } doing_fcatalog = 1; for (t = toklist; t != NULL; t = t->next) { if (t->type == TOK_IDENTIFIER && curhead == NULL) { /* Not typedef */ if (curstd == NULL) { /* A new standard definition */ curstd = t; if (expect_token(&t, TOK_COMP_OPEN, 0) != 0) { err = 1; break; } } else if (curhead == NULL) { /* A new header */ curhead = t; if (expect_token(&t, TOK_OP_STRUMEMB, 0) != 0) { err = 1; break; } /* XXX assume they all end with .h */ if (expect_token(&t, TOK_IDENTIFIER, 0) != 0) { err = 1; break; } /* XXX assume they all end with .h */ if (expect_token(&t, TOK_COMP_OPEN, 0) != 0) { err = 1; break; } } } else if (t->type == TOK_COMP_CLOSE) { if (curstd == NULL) { (void) fprintf(stderr, "%d: Unexpected closing brace\n", t->line); err = 1; break; } if (curhead != NULL) { curhead = NULL; } else { curstd = NULL; } } else { struct token *sav; fpos_t curpos; char *str; struct fcat_data_entry *dent; struct fcat_hash_entry *hent; unsigned long old_fcat_data_offset; int key; if (curstd == NULL) { (void) fprintf(stderr, "%d: Unexpected " "token `%s'\n", t->line, t->ascii); err = 1; break; } /* * Must be a declaration */ sav = t; new_scope(SCOPE_CODE); dec = parse_decl(&t, DECL_NOINIT); if (dec == NULL) { (void) fprintf(stderr, "%d: Cannot parse " "declaration at '%s'\n", t->line, t->ascii); err = 1; break; } /* Read the line containing the declaration */ fgetpos(srcfd, &curpos); fseek(srcfd, lines[sav->line], SEEK_SET); if (fgets(buf, sizeof buf, srcfd) != NULL) { /* printf(" on line '%s", buf);*/ } fsetpos(srcfd, &curpos); /* * Create a new data entry for this declaration * The format is: * standard,standard2,...;header;decl */ (void) strtok(buf, "\n"); str = n_xmalloc(strlen(buf) + strlen(curhead->data) + 128); sprintf(str, "%s;%s.h;%s;%s", (char *)curstd->data, (char *)curhead->data, dec[0]->dtype->name, buf); dent = n_xmalloc(sizeof *dent); dent->text = str; old_fcat_data_offset = fcat_data_offset; fcat_data_offset += strlen(str) + 1; /* +1 for newline */ /* Append data entry */ if (data_list_head == NULL) { data_list_head = data_list_tail = dent; } else { data_list_tail->next = dent; data_list_tail = dent; } /* Create hash entry */ hent = n_xmalloc(sizeof *hent); hent->name = dec[0]->dtype->name; sprintf(hent->offset, "%lu", old_fcat_data_offset); key = fcat_hash_name(hent->name); if (hash_table_head[key] == NULL) { hash_table_head[key] = hash_table_tail[key] = hent; } else { hash_table_tail[key]->next = hent; hash_table_tail[key] = hent; } hash_table_slot_length[key] += strlen(hent->name) + strlen(" \n") + strlen(hent->offset); } } /* * The slot length array now contains the length of each slot; Turn * that into a total offset (i.e. the sum of all preceding elements * is added to the length of each entry) */ for (i = 0; i < H_TABSIZE; ++i) { if (i > 0) { hash_table_slot_length[i] += hash_table_slot_length[i - 1]; } } /* * Now write all data. First comes the slot length header which * describes the size of the hash table slots. */ for (i = 0; i < H_TABSIZE; ++i) { fprintf(destfd, "%ld", hash_table_slot_length[i]); if (i + 1 < H_TABSIZE) { fprintf(destfd, ","); } else { fprintf(destfd, "\n"); } } /* * ... followed by the data start index. We first write an * ``empty'' line of spaces, and overwrite it with the real * offset when it is known */ fgetpos(destfd, &offsetpos); fprintf(destfd, " \n"); /* * ... followed by the hash slots containing the data pointers */ for (i = 0; i < H_TABSIZE; ++i) { struct fcat_hash_entry *e; for (e = hash_table_head[i]; e != NULL; e = e->next) { fprintf(destfd, "%s;%s\n", e->name, e->offset); } } /* * ... followed by the actual data entries */ { struct fcat_data_entry *d; fpos_t curpos; long bytes_written; fgetpos(destfd, &curpos); bytes_written = ftell(destfd); fsetpos(destfd, &offsetpos); fprintf(destfd, "%ld", bytes_written); fsetpos(destfd, &curpos); for (d = data_list_head; d != NULL; d = d->next) { fprintf(destfd, "%s\n", d->text); } } (void) fclose(srcfd); (void) fclose(destfd); /* XXX return err? */ (void) err; return 0; }
void decl (int kind) { //A C declaration comes in three forms: // - Local decls, which end in a semicolon and can have an initializer. // - Parameter decls, which do not and cannot. // - Module decls, which end in a semicolon unless there is a function body. bool fn = false; bool fn_impl = false; int local; next(); while (try_match("*")) ; //Owned (freed) by the symbol table char* ident = strdup(buffer); next(); //Functions if (try_match("(")) { if (kind == decl_module) new_scope(); //Params if (waiting_for(")")) do { decl(decl_param); } while (try_match(",")); match(")"); new_fn(ident); fn = true; //Body if (see("{")) { require(kind == decl_module, "a function implementation is illegal here\n"); fn_impl = true; function(ident); } //Add it to the symbol table } else { if (kind == decl_local) { local = new_local(ident); } else (kind == decl_module ? new_global : new_param)(ident); } //Initialization if (see("=")) require(!fn && kind != decl_param, fn ? "cannot initialize a function\n" : "cannot initialize a parameter\n"); if (kind == decl_module) { fputs(".section .data\n", output); if (try_match("=")) { if (token == token_int) fprintf(output, "%s: .quad %d\n", ident, atoi(buffer)); else error("expected a constant expression, found '%s'\n"); next(); //Static data defaults to zero if no initializer } else if (!fn) fprintf(output, "%s: .quad 0\n", ident); fputs(".section .text\n", output); } else if (try_match("=")) { expr(0); fprintf(output, "mov dword ptr [ebp%+d], eax\n", offsets[local]); } if (!fn_impl && kind != decl_param) match(";"); }
ErrorStack MasstreeStoragePimpl::fatify_first_root_double(thread::Thread* context) { MasstreeIntermediatePage* root; WRAP_ERROR_CODE(get_first_root(context, true, &root)); ASSERT_ND(root->is_locked()); ASSERT_ND(!root->is_moved()); // assure that all children have volatile version for (MasstreeIntermediatePointerIterator it(root); it.is_valid(); it.next()) { if (it.get_pointer().volatile_pointer_.is_null()) { MasstreePage* child; WRAP_ERROR_CODE(follow_page( context, true, const_cast<DualPagePointer*>(&it.get_pointer()), &child)); } ASSERT_ND(!it.get_pointer().volatile_pointer_.is_null()); } std::vector<Child> original_children = list_children(root); ASSERT_ND(original_children.size() * 2U <= kMaxIntermediatePointers); std::vector<Child> new_children; for (const Child& child : original_children) { CHECK_ERROR(split_a_child(context, root, child, &new_children)); } ASSERT_ND(new_children.size() >= original_children.size()); memory::NumaCoreMemory* memory = context->get_thread_memory(); memory::PagePoolOffset new_offset = memory->grab_free_volatile_page(); if (new_offset == 0) { return ERROR_STACK(kErrorCodeMemoryNoFreePages); } // from now on no failure (we grabbed a free page). VolatilePagePointer new_pointer = combine_volatile_page_pointer( context->get_numa_node(), kVolatilePointerFlagSwappable, // pointer to root page might be swapped! get_first_root_pointer().volatile_pointer_.components.mod_count + 1, new_offset); MasstreeIntermediatePage* new_root = context->resolve_newpage_cast<MasstreeIntermediatePage>(new_pointer); new_root->initialize_volatile_page( get_id(), new_pointer, 0, root->get_btree_level(), // same as current root. this is not grow_root kInfimumSlice, kSupremumSlice); // no concurrent access to the new page, but just for the sake of assertion in the func. PageVersionLockScope new_scope(context, new_root->get_version_address()); new_root->split_foster_migrate_records_new_first_root(&new_children); ASSERT_ND(count_children(new_root) == new_children.size()); verify_new_root(context, new_root, new_children); // set the new first-root pointer. assorted::memory_fence_release(); get_first_root_pointer().volatile_pointer_.word = new_pointer.word; // first-root snapshot pointer is unchanged. // old root page and the direct children are now retired assorted::memory_fence_acq_rel(); root->set_moved(); // not quite moved, but assertions assume that. root->set_retired(); context->collect_retired_volatile_page( construct_volatile_page_pointer(root->header().page_id_)); for (const Child& child : original_children) { MasstreePage* original_page = context->resolve_cast<MasstreePage>(child.pointer_); if (original_page->is_moved()) { PageVersionLockScope scope(context, original_page->get_version_address()); original_page->set_retired(); context->collect_retired_volatile_page(child.pointer_); } else { // This means, the page had too small records to split. We must keep it. } } assorted::memory_fence_acq_rel(); LOG(INFO) << "Split done. " << original_children.size() << " -> " << new_children.size(); return kRetOk; }
void iks_init() { // symbol_table_init(); iks_ast_init(); scope=new_scope(); }
start_block() { new_scope(); }
void begin_scope() { // Push to the top of stack scope_top = new_scope(new_table(), scope_top, scope_top->level + 1); }
void scope_init() { scope_top = new_scope(NULL, NULL, 0); }
/* * Initializes the symtab by creating the root node */ void symtab_init(struct program_t *program) { allScopes = NULL; rootScope = new_scope(); rootScope->attrId = SYM_ATTR_PROGRAM; rootScope->program = program; }