Stack* Recorrer(Maze *m, Point *input){ int i; Stack *paux = NULL; /*pila auxiliar*/ Stack *pcamino = NULL; /*pila del camino seguido*/ EleStack *pele = NULL; /*punto donde nos encontramos*/ EleStack *pelepoint = NULL; /*Punto vecino*/ Point *ppoint = NULL; Point *ppoint2 = NULL; if(!m){ printf("Error pasando el maze\n"); return NULL; } if(!input){ printf("Error pasando el input\n"); return NULL; } paux = stack_ini(); if (!paux){ printf ("Error en reserva memoria paux\n"); return NULL; } pcamino = stack_ini(); if (!pcamino){ printf ("Error reserva memoria pcamino\n"); stack_free (paux); return NULL; } pele = elestack_ini(); if (!pele){ printf ("Error reserva memoria pele\n"); stack_free(paux); stack_free(pcamino); return NULL; } if (!elestack_setInfo(pele, input)){ /*Guardamos el punto input en pele*/ printf ("Error en setInfo de pele\n"); elestack_free(pele); stack_free(paux); stack_free(pcamino); return NULL; } if(!stack_push (paux, pele)){ /*Introducimos pele en la pila auxiliar*/ printf("Error push del input\n"); elestack_free(pele); stack_free(paux); stack_free(pcamino); return NULL; } elestack_free(pele); while (!stack_isEmpty(paux)){ /*mientras la pila auxiliar no esta vacia*/ pele = stack_pop(paux); /*extraemos el punto superior de la pila y nos "situamos" ahi*/ stack_push(pcamino, pele); /*Como visitamos ese punto lo introducimos en el camino*/ point_setSymbol(maze_getPoint(m, point_getCoordinateX((Point *)elestack_getInfo(pele)), point_getCoordinateY((Point *)elestack_getInfo(pele))), VISITADO); /*Modificamos el simbolo del punto a VISITADO, lo guardamos en el laberinto original*/ for(i = 0; i <= DOWN; i++){ /*Comprobamos las 4 direcciones que se pueden seguir dentro de un laberinto*/ pelepoint = elestack_ini(); if(!pelepoint){ printf("Error en elestack_ini\n"); elestack_free(pele); stack_free(paux); stack_free(pcamino); return NULL; } ppoint2 = (Point*)elestack_getInfo(pele); /*Obtenemos el punto de pele*/ if(!ppoint2){ printf("Error al obtener el punto de pele"); elestack_free(pelepoint); elestack_free(pele); stack_free(paux); stack_free(pcamino); return NULL; } ppoint = maze_getNeighborPoint(m, ppoint2, i); /*Obtenemos el punto vecino en la direccion que indica "i"*/ if(!ppoint){ printf("Error ppoint 1\n"); elestack_free(pelepoint); elestack_free(pele); stack_free(paux); stack_free(pcamino); return NULL; } if(!elestack_setInfo(pelepoint, (void*)ppoint)){ /*Asignamos a pelepoint el punto vecino*/ printf("Error setinfo\n"); elestack_free(pelepoint); elestack_free(pele); stack_free(paux); stack_free(pcamino); return NULL; } if(point_getSymbol(ppoint) == SPACE){ /*Introducimos el punto en la pila auxiliar SOLO si es un SPACE*/ if(!stack_push(paux, pelepoint)){ printf("Error al hacer el push de pelepoint"); elestack_free(pelepoint); elestack_free(pele); stack_free(paux); stack_free(pcamino); return NULL; } } else if(point_getSymbol(ppoint) == OUTPUT){ /*Si el punto es el OUTPUT, lo introduce en el camino y devuelve dicha pila*/ stack_push(pcamino, pelepoint); elestack_free(pelepoint); elestack_free(pele); stack_free(paux); return pcamino; } elestack_free(pelepoint); } elestack_free(pele); } stack_free(paux); stack_free(pcamino); return NULL; }
static bool daemon_serve(int s, char *cmd) { /* Do <cmd> for client connected on <s>. */ static Node *null=NULL, **stack=&null; char buf[FILEPATH_MAX]; bool keep_running=true; if( strcmp(cmd, CMD_PUSH) == 0 ) { char *status; if( stack_len(stack) >= STACK_MAX ) { printf("daemon: push request failed (stack full)\n"); status = MSG_ERROR; strcpy(buf, MSG_ERR_STACK_FULL); } else { soc_w(s, MSG_SUCCESS); if( soc_r(s, buf, FILEPATH_MAX) <= 0 ) { printf("daemon: push request failed (read error)\n"); status = MSG_ERROR; strcpy(buf, MSG_ERR_LENGTH); } else { status = MSG_SUCCESS; stack_push(buf, stack); printf("daemon: PUSH `%s'\n", buf); } } soc_w(s, status); soc_w(s, buf); } else if( strcmp(cmd, CMD_POP) == 0 ) { char *status; if( stack_len(stack) > 0 ) { status = MSG_SUCCESS; sprintf(buf, "%s", stack_peek(stack)); stack_drop(stack); printf("daemon: POP `%s'\n", buf); } else { printf("daemon: tried to pop from empty stack\n"); status = MSG_ERROR; sprintf(buf, MSG_ERR_STACK_EMPTY); } soc_w(s, status); soc_w(s, buf); } else if( strcmp(cmd, CMD_PEEK) == 0 ) { char *status; if( stack_len(stack) > 0 ) { status = MSG_SUCCESS; sprintf(buf, "%s", stack_peek(stack)); } else { status = MSG_ERROR; sprintf(buf, MSG_ERR_STACK_EMPTY); } soc_w(s, status); soc_w(s, buf); } else if( strcmp(cmd, CMD_PICK) == 0 ) { char *picked; soc_w(s, MSG_SUCCESS); soc_r(s, buf, MSG_MAX); picked = stack_nth(atoi(buf), stack); if( picked == NULL ) { soc_w(s, MSG_ERROR); soc_w(s, "stack is not quite that deep"); } else { soc_w(s, MSG_SUCCESS); soc_w(s, picked); } } else if( strcmp(cmd, CMD_SIZE) == 0 ) { sprintf(buf, "%d", stack_len(stack)); soc_w(s, buf); } else if( strcmp(cmd, CMD_STOP) == 0 ) { printf("daemon: Shutting down...\n"); soc_w(s, MSG_SUCCESS); keep_running = false; } else { char msg[MSG_MAX + FILEPATH_MAX]; sprintf(msg, "unknown command `%s'", cmd); soc_w(s, msg); } return keep_running; }
void append_call_stack_tabled(char type, obj_table* table){ obj * o = create_call_block_tabled(type, call_stack_top, table); stack_push(call_stack, o); call_stack_top = (call_block*)o->data; }
/* * input: rule straight from the DDDS + avp-stack. * * output: adds found rules to the stack and return * 1 on success * 0 on failure */ static int check_rule(str *rule, char *service, int service_len, struct avp_stack *stack) { /* for the select */ db_key_t keys[2]; db_val_t vals[2]; db_key_t cols[4]; db1_res_t* res; db_row_t* row; db_val_t* val; int i; char *type; int type_len; LM_INFO("checking for '%.*s'.\n", rule->len, ZSW(rule->s)); if ((service_len != 11) || (strncasecmp("d2p+sip:fed", service, 11) && strncasecmp("d2p+sip:std", service, 11) && strncasecmp("d2p+sip:dom", service, 11))) { LM_ERR("can only cope with d2p+sip:fed, d2p+sip:std,and d2p+sip:dom " "for now (and not %.*s).\n", service_len, service); return(0); } type = service + 8; type_len = service_len - 8; if (domainpolicy_dbf.use_table(db_handle, &domainpolicy_table) < 0) { LM_ERR("failed to domainpolicy table\n"); return -1; } keys[0]=&domainpolicy_col_rule; keys[1]=&domainpolicy_col_type; cols[0]=&domainpolicy_col_rule; cols[1]=&domainpolicy_col_type; cols[2]=&domainpolicy_col_att; cols[3]=&domainpolicy_col_val; VAL_TYPE(&vals[0]) = DB1_STR; VAL_NULL(&vals[0]) = 0; VAL_STR(&vals[0]).s = rule->s; VAL_STR(&vals[0]).len = rule->len; VAL_TYPE(&vals[1]) = DB1_STR; VAL_NULL(&vals[1]) = 0; VAL_STR(&vals[1]).s = type; VAL_STR(&vals[1]).len = type_len; /* * SELECT rule, att, val from domainpolicy where rule = "..." */ if (domainpolicy_dbf.query(db_handle, keys, 0, vals, cols, 2, 4, 0, &res) < 0 ) { LM_ERR("querying database\n"); return -1; } LM_INFO("querying database OK\n"); if (RES_ROW_N(res) == 0) { LM_DBG("rule '%.*s' is not know.\n", rule->len, ZSW(rule->s)); domainpolicy_dbf.free_result(db_handle, res); return 0; } else { LM_DBG("rule '%.*s' is known\n", rule->len, ZSW(rule->s)); row = RES_ROWS(res); for(i = 0; i < RES_ROW_N(res); i++) { if (ROW_N(row + i) != 4) { LM_ERR("unexpected cell count\n"); return(-1); } val = ROW_VALUES(row + i); if ((VAL_TYPE(val) != DB1_STRING) || (VAL_TYPE(val+1) != DB1_STRING) || (VAL_TYPE(val+2) != DB1_STRING) || (VAL_TYPE(val+3) != DB1_STRING)) { LM_ERR("unexpected cell types\n"); return(-1); } if (VAL_NULL(val+2) || VAL_NULL(val+3)) { LM_INFO("db returned NULL values. Fine with us.\n"); continue; } LM_INFO("DB returned %s/%s \n",VAL_STRING(val+2),VAL_STRING(val+3)); if (!stack_push(stack, (char *) VAL_STRING(val+2), (char *) VAL_STRING(val+3))) { return(-1); } } domainpolicy_dbf.free_result(db_handle, res); return 1; } }
int main(int argc, char* argv[]) { int i; node * m; /* obligatory */ printf("Hello, World\r\n"); printf("\r\n---\r\n"); /* Node stuff */ printf("Creating and destroying 10000 nodes\r\n"); for (i = 0; i < 10000 ; i++) { int data = i; node * n = build_node(&data); destroy_node(n); } printf("Done\r\n"); printf("\r\n---\r\n"); printf("Building a queue, adding 10000 nodes. Printing out every 1000\r\n"); queue * q = build_queue(); for (i = 0; i < 10000 ; i++) { int data = i; node * n = build_node(&data); queue_push(q, n); } printf("Queue has the size %d\r\n", q->size); for (i = 0; i < 10000 ; i++) { node * n = queue_pop(q); if((i%1000)==0) { printf("Node has the data %d\r\n", *(int*)n->data); } destroy_node(n); } printf("Queue has the size %d\r\n", q->size); destroy_queue(q); printf("\r\n---\r\n"); printf("Building a stack, adding 10000 nodes. Printing out every 1000\r\n"); stack * s = build_stack(); for (i = 0; i < 10000 ; i++) { int data = i; node * n = build_node(&data); stack_push(s, n); } printf("Stack has the size %d\r\n", s->size); for (i = 0; i < 10000 ; i++) { node * n = stack_pop(s); if((i%1000)==0) { printf("Node has the data %d\r\n", *(int*)n->data); } destroy_node(n); } printf("Stack has the size %d\r\n", s->size); destroy_stack(s); printf("\r\n---\r\n"); printf("Building a linked list, adding 10000 nodes. Printing out every 1000\r\n"); llist * l = build_llist(); for (i = 0; i < 10000 ; i++) { int data = i; node * n = build_node(&data); llist_add(l, n); } printf("llist has the size %d\r\n", l->size); printf("Testing arbitrary access...\r\n"); m = llist_get(l, 87); printf("Node has the data %d\r\n", *(int*)m->data); m = llist_get(l, 3487); printf("Node has the data %d\r\n", *(int*)m->data); m = llist_get(l, 287); printf("Node has the data %d\r\n", *(int*)m->data); printf("Testing arbitrary delete...\r\n"); m = llist_get(l, 299); printf("Node has the data %d\r\n", *(int*)m->data); llist_delete(l, 299); m = llist_get(l, 299); printf("Node has the data %d\r\n", *(int*)m->data); printf("Testing mass delete...\r\n"); destroy_llist(l); printf("\r\n---\r\n"); printf("Creating and destroying 10000 single trees\r\n"); for (i = 0; i < 10000 ; i++) { int data = i; tree * n = build_tree(&data); destroy_tree(n); } printf("Done\r\n"); printf("\r\n---\r\n"); printf("Testing add/delete for trees\r\n"); int data = 2; tree * root = build_tree(&data); //for (i = 0; i < 3 ; i++) // { // int data = i; // tree * n = build_tree(&data); // destroy_tree(n); // add_leaf(&root, n, &tree_int_comp); // } data = 1; tree * leaf1 = build_tree(&data); add_leaf(&root, leaf1, &tree_int_comp); data = 0; tree * leaf2 = build_tree(&data); add_leaf(&root, leaf2, &tree_int_comp); printf("Root node has value %d before deletion\r\n", *(int*)root->data); delete_node(&(root)); printf("Root node has value %d after deletion\r\n", *(int*)root->data); destroy_tree(leaf1); destroy_tree(leaf2); printf("Done\r\n"); return 0; }
//中間の数式を逆ポーランドに変換する関数 void convert_in_formula_to_rpn_formula(char* formula) { printf("\tConvert IN Formula to RPN Formula : start IN Formula = \"%s\"\n",formula); char tmp_buffer[BUFFER_LENGTH]; int tmp_buffer_pointer = 0; string_clear(tmp_buffer,'\0',BUFFER_LENGTH); int i; //メインループ for(i=0;formula[i]!='\0';i++) { //数字の処理 if((formula[i]>='0'&&formula[i]<='9')||formula[i]=='.') { tmp_buffer[tmp_buffer_pointer++] = formula[i]; } //各演算子の処理 else if(formula[i]=='+') { for(;;) { //自分の優先順位より低くなるまでスタックをポップ if((int)(stack_pointer-1)>=0) { if((int)stack[stack_pointer-1]!='(') { tmp_buffer[tmp_buffer_pointer++] = ' '; tmp_buffer[tmp_buffer_pointer++] = (int)stack_pop(); } else { stack_push(formula[i]); break; } } else { stack_push(formula[i]); break; } } tmp_buffer[tmp_buffer_pointer++] = ' '; } else if(formula[i]=='-') { //式の最初にマイナスがあったときのための処理 if(i==0) { tmp_buffer[tmp_buffer_pointer++] = '0'; tmp_buffer[tmp_buffer_pointer++] = ' '; } else if(formula[i-1]=='(') { tmp_buffer[tmp_buffer_pointer++] = '0'; tmp_buffer[tmp_buffer_pointer++] = ' '; } for(;;) { //自分の優先順位より低くなるまでスタックをポップ if((stack_pointer-1)>=0) { if((int)stack[stack_pointer-1]!='+'&&(int)stack[stack_pointer-1]!='(') { tmp_buffer[tmp_buffer_pointer++] = ' '; tmp_buffer[tmp_buffer_pointer++] = (int)stack_pop(); } else { stack_push(formula[i]); break; } } else { stack_push(formula[i]); break; } } tmp_buffer[tmp_buffer_pointer++] = ' '; } else if(formula[i]=='*') { for(;;) { //自分の優先順位より低くなるまでスタックをポップ if((stack_pointer-1)>=0) { if((int)stack[stack_pointer-1]!='+'&&(int)stack[stack_pointer-1]!='-'&&(int)stack[stack_pointer-1]!='(') { tmp_buffer[tmp_buffer_pointer++] = ' '; tmp_buffer[tmp_buffer_pointer++] = (int)stack_pop(); } else { stack_push(formula[i]); break; } } else { stack_push(formula[i]); break; } } tmp_buffer[tmp_buffer_pointer++] = ' '; } else if(formula[i]=='/') { for(;;) { //自分の優先順位より低くなるまでスタックをポップ if((stack_pointer-1)>=0) { if((int)stack[stack_pointer-1]!='+'&&(int)stack[stack_pointer-1]!='-'&&(int)stack[stack_pointer-1]!='*'&&(int)stack[stack_pointer-1]!='(') { tmp_buffer[tmp_buffer_pointer++] = ' '; tmp_buffer[tmp_buffer_pointer++] = (int)stack_pop(); } else { stack_push(formula[i]); break; } } else { stack_push(formula[i]); break; } } tmp_buffer[tmp_buffer_pointer++] = ' '; } //括弧開きがあったとき else if(formula[i]=='(') { stack_push(formula[i]); tmp_buffer[tmp_buffer_pointer++] = ' '; } //括弧閉じがあったとき else if(formula[i]==')') { for(;;) { //括弧開きが出るまでスタックをポップ if(stack[stack_pointer-1]!='(') { tmp_buffer[tmp_buffer_pointer++] = ' '; tmp_buffer[tmp_buffer_pointer++] = (int)stack_pop(); } //括弧開きは読み捨てる else { stack_pop(); break; } } } } //スタックに残っている演算子をすべてポップ for(i=stack_pointer-1;i>=0;i--) { tmp_buffer[tmp_buffer_pointer++] = ' '; tmp_buffer[tmp_buffer_pointer++] = (int)stack_pop(); } tmp_buffer[tmp_buffer_pointer++] = '\0'; my_strcpy(formula,tmp_buffer); string_clear(tmp_buffer,'\0',BUFFER_LENGTH); tmp_buffer_pointer = 0; stack_clear(); printf("\tConvert IN Formula to RPN Formula : done RPN Formula = \"%s\"\n",formula); }
static int push(struct eval *eval, struct tok *tok) { return stack_push(eval->opstk, tok); }
/** * Stores the current read and write pointers */ void buffer_pushp(buffer_t* buffer) { stack_push(&buffer->ptr_stack, buffer->read_ptr); stack_push(&buffer->ptr_stack, buffer->read_avail); }
/* @builtin-bind { '"', builtin_string }, */ int builtin_string(interpreter* interp) { string accum, s; int result; unsigned begin; accum = empty_string(); ++interp->ip; while (1) { /* Scan for the next important character. */ for (begin = interp->ip; is_ip_valid(interp); ++interp->ip) if (curr(interp) == '"' || curr(interp) == '$' || curr(interp) == '`' || curr(interp) == '\\' || curr(interp) == '%') break; /* Found important character or EOI. */ if (!is_ip_valid(interp)) { print_error("Encountered end-of-input in string literal"); goto error; } /* Append everything in-between */ accum = append_data(accum, string_data(interp->code) + begin, string_data(interp->code) + interp->ip); switch (curr(interp)) { case '"': goto done; case '$': ++interp->ip; if (!is_ip_valid(interp)) { print_error("Encountered end-of-input in string literal"); goto error; } /* Append value of this register */ accum = append_string(accum, interp->registers[curr(interp)]); touch_reg(interp, curr(interp)); break; case '%': s = stack_pop(interp); if (!s) { print_error("Stack underflow"); goto error; } accum = append_string(accum, s); free(s); break; case '`': if (!interp->initial_whitespace) { print_error("Initial whitespace (`) not available in this context."); goto error; } accum = append_string(accum, interp->initial_whitespace); break; case '\\': result = builtin_escape(interp); if (!result) goto error; if (result == 2) break; /* Didn't push anything */ s = stack_pop(interp); /* Popping will always succeed if escape returned success. */ accum = append_string(accum, s); free(s); break; } /* All the above (which don't goto elsewhere) leave the IP on the end of * whatever special thing they did. */ ++interp->ip; } done: stack_push(interp, accum); return 1; error: diagnostic(interp, NULL); free(accum); return 0; }
int primary_expression_mods(struct token *token) { printf("Hello from primary_expression_mods\n"); if (token->op_type == OPENPAREN){ tree_mknode(-1); //TODO implement '(' input_consume(); free_token(token); stack_pop(); stack_push(TOKEN_CLOSEPAREN); //')' stack_push(PRIMARY_EXPRESSION_LIST); return -1; } else if (token->op_type == OPENBRACKET){ tree_mknode(PRIMARY_EXPRESSION_MODS); input_consume(); //get the [ free_token(token); stack_pop(); struct token *t = input_consume(); //the inner part of the [x] struct identifier *nid = malloc(sizeof(struct identifier)); nid->lexeme = t->lexeme; if (t->type == ID_KW){ struct hashentry *he = hash_retrieve(kwtable, nid->lexeme); if (he != NULL){ //is a keyword (an error) log_error(PRIMARY_EXPRESSION_MODS); return -1; } else{ he = hash_retrieve(symboltable, nid->lexeme); if (he == NULL){ //symbol not defined log_error(PRIMARY_EXPRESSION_MODS); printf("%s has not been initialized\n", nid->lexeme); return -1; } else{ tree_add_attr(he->data, 4); free_token(t); input_consume(); //the last ] return 0; } } } else if (t->type >= C_NUM && t->type <= C_F){ struct identifier *id = malloc(sizeof(struct identifier)); id->lexeme = t->lexeme; type_const(id->type); tree_add_attr(id, 4); //add it as attribute free(t); input_consume(); // the last ] return 0; } else{ log_error(PRIMARY_EXPRESSION_MODS); printf("%s has not been initialized\n", nid->lexeme); return -1; } } else if (token->op_type == VALUEAT){ input_consume(); // throw away '.' struct token *tmp = input_consume(); //get the identifier struct hashentry *ifkw = hash_retrieve(kwtable, tmp->lexeme); if (ifkw != NULL){ //error is a keyword log_error(PRIMARY_EXPRESSION_MODS); return -1; } else{ tree_mknode(-1); //TODO implement '.' free_token(token); stack_pop(); stack_push(PRIMARY_EXPRESSION); return -1; } } else{ //not a mod of a primary expression stack_pop(); return 0; } }
inline void r_store_stack(CF, R0) { stack_push(RVAL(r0)); }
int binary_op(struct token *token) { switch (token->op_type){ case LOGOR: tree_mknode(BINARY_OP); stack_pop(); stack_push(LOGICAL_OR_EXPRESSION); return 0; case LOGAND: tree_mknode(BINARY_OP); stack_pop(); stack_push(LOGICAL_AND_EXPRESSION); return 0; case BWOR: tree_mknode(BINARY_OP); stack_pop(); stack_push(INCLUSIVE_OR_EXPRESSION); return 0; case BWXOR: tree_mknode(BINARY_OP); stack_pop(); stack_push(EXCLUSIVE_OR_EXPRESSION); return 0; case BWAND: tree_mknode(BINARY_OP); stack_pop(); stack_push(AND_EXPRESSION); return 0; case EQUALS: case NOTEQUALS: tree_mknode(BINARY_OP); stack_pop(); stack_push(EQUALITY_EXPRESSION); return 0; case LT: case LE: case GT: case GE: tree_mknode(BINARY_OP); stack_pop(); stack_push(RELATIONAL_EXPRESSION); return 0; case SHIFTLEFT: case SHIFTRIGHT: tree_mknode(BINARY_OP); stack_pop(); stack_push(SHIFT_EXPRESSION); return 0; case PLUS: case MINUS: // + - tree_mknode(BINARY_OP); stack_pop(); stack_push(ADDITIVE_EXPRESSION); return 0; case MULTIPLY: case DIVIDE: case MODULO: // * / % tree_mknode(BINARY_OP); stack_pop(); stack_push(MULTIPLICATIVE_EXPRESSION); return 0; case EOE: //direct expression //tree_mknode(BINARY_OP); //tree_add_attr(token, -1); stack_pop(); //pop the binary op stack_pop(); //pop the second lrvalue return 0; default: log_error(BINARY_OP); return -1; } }
int jump_statement(struct token *token) { printf("Hello from jump_statement\n");//DEBUG // goto label conditional if( strncmp("goto", token->lexeme, 4) == 0){ tree_mknode(JUMP_STATEMENT); input_consume(); //consume the goto free_token(token); struct token *label = input_consume(); struct token *conditional = input_consume(); if (label->type == ID_KW){ struct hashentry *ifkw = hash_retrieve(kwtable, label->lexeme); if (ifkw == NULL){//not a keyword, an identifier struct hashentry *predefined; struct hashentry *predefined2; //get symboltable entry for label predefined = hash_retrieve(symboltable, label->lexeme); if(predefined == NULL){ predefined = malloc(sizeof(struct hashentry)); predefined->data = malloc(sizeof(struct identifier)); predefined->data->lexeme = label->lexeme; type_id(predefined->data->type); //log_error(LABELED_STATEMENT); //printf("Symbol: %s has not been defined!\n", label->lexeme); //return -1; } //get symboltable entry for conditional predefined2 = hash_retrieve(symboltable, conditional->lexeme); if(predefined2 == NULL){ log_error(LABELED_STATEMENT); printf("Symbol: %s has not been defined!\n", conditional->lexeme); return -1; } struct hashentry *gokw = hash_retrieve(kwtable, "goto"); tree_add_attr(gokw->data, 0); tree_add_attr(predefined->data, 1); tree_add_attr(predefined2->data, 2); printf("Consumed: goto %s %s\n", label->lexeme, conditional->lexeme);//DEBUG stack_pop(); stack_push(TOKEN_ENDSTATEMENT); free(label); free(conditional); return 0; } else{ log_error(JUMP_STATEMENT); free_token(label); free_token(conditional); return -1; } } else{ printf("Incorrect goto label: %s\n", label->lexeme);//DEBUG free_token(label); free_token(conditional); log_error(JUMP_STATEMENT); return -1; } } else{ log_error(JUMP_STATEMENT); return -1; } }
/* * Print Binary Search Tree in inorder fashion without using recursion. * * @cur_root : Root of the Binary Search Tree. */ void bst_print_inorder_nonrecur(node_t *cur_root) { /* Stack of nodes that we have visited but yet to process their left sub-tree. */ Stack_t nodes_stack; /* Stack of childrens of nodes in the above stack which are yet to be visited. */ Stack_t childs_stack; stack_init(&nodes_stack); stack_init(&childs_stack); if (!cur_root) { //NO-OP. return; } /* we have just visited root's parent :). */ stack_push(&childs_stack, cur_root); while (!stack_empty(&childs_stack) || !stack_empty(&nodes_stack)) { if (!stack_empty(&childs_stack)) { node_t *child = (node_t *) stack_pop(&childs_stack); assert(child); if (child->left_child) { /* As this is inorder we need to process left sub-tree first. */ stack_push(&childs_stack, child->left_child); /* Once left sub-tree is prcessed we can process its parent then. */ stack_push(&nodes_stack, child); } else { //Done with left sub-tree. printf("%d ", child->data); if (child->right_child) { stack_push(&childs_stack, child->right_child); } } } else { assert(!stack_empty(&nodes_stack)); node_t *node = (node_t *) stack_pop(&nodes_stack); assert(node); //Done with left sub-tree. printf("%d ", node->data); if (node->right_child) { stack_push(&childs_stack, node->right_child); } } } assert(stack_empty(&nodes_stack) && stack_empty(&childs_stack)); }
int main(int argc, char *argv[]) { char command[32]; int eventsNr, eventId, procId, priority; int i, iteration; TStack **eventsStacks; TQueue *procQ; // Daca nu exista destule argumente la rularea programului, atunci opreste executia if (argc < 3) { printf("Argumente insuficiente!\n"); return -1; } // Seteaza fisierele de intrare si de iesire freopen(argv[1], "r", stdin); freopen(argv[2], "w", stdout); // Citeste numarul de event-uri si creeaza stivele lor fscanf(stdin, "%d", &eventsNr); eventsStacks = calloc(eventsNr, sizeof(TStack*)); for (i = 0; i < eventsNr; i++) { eventsStacks[i] = stack_new(sizeof(TProcess)); } // Creeaza coada de prioritati procQ = queue_new(sizeof(TProcess), compare_process); // Citeste si executa comenzile din fisierul de intrare iteration = 0; while (fscanf(stdin, "%s", command) != EOF) { iteration++; if (strcmp(command, "start") == 0) { fscanf(stdin, "%d", &procId); fscanf(stdin, "%d", &priority); // Creeaza un proces TProcess p; p.id = procId; p.priority = priority; p.iteration = iteration; // Introduce procesul creat in coada de prioritati queue_push(procQ, &p); } else if (strcmp(command, "wait") == 0) { fscanf(stdin, "%d", &eventId); fscanf(stdin, "%d", &procId); // Creaza o stiva auxiliara TStack *aux = stack_new(sizeof(TProcess)); // Muta procesele in stiva auxiliara pana cand procesul // cautat este gasit si mutat in stiva evenimentului TProcess *p; while (!queue_isEmpty(procQ)) { p = queue_pop(procQ); if (p->id == procId) { stack_push(eventsStacks[eventId], p); free_process(p); break; } stack_push(aux, p); free_process(p); } // Muta procesele din stiva auxiliara inapoi in coada // de prioritati while (!stack_isEmpty(aux)) { p = stack_pop(aux); queue_push(procQ, p); free_process(p); } // Distruge stiva auxiliara stack_destroy(&aux, free_process); } else if (strcmp(command, "event") == 0) { fscanf(stdin, "%d", &eventId); // Muta procesele din stiva evenimentului in coada // de prioritati TProcess *p; while (!stack_isEmpty(eventsStacks[eventId])) { p = stack_pop(eventsStacks[eventId]); queue_push(procQ, p); free_process(p); } } else if (strcmp(command, "end") == 0) { fscanf(stdin, "%d", &procId); // Creaza o stiva auxiliara TStack *aux = stack_new(sizeof(TProcess)); // Muta procesele in stiva auxiliara pana cand procesul // cautat este gasit si sters TProcess *p; while (!queue_isEmpty(procQ)) { p = queue_pop(procQ); if (p->id == procId) { free_process(p); break; } stack_push(aux, p); free_process(p); } // Muta procesele din stiva auxiliara inapoi in coada // de prioritati while (!stack_isEmpty(aux)) { p = stack_pop(aux); queue_push(procQ, p); free_process(p); } // Distruge stiva auxiliara stack_destroy(&aux, free_process); } // Afiseaza iteratia printf("%d\n", iteration); // Afiseaza coada de prioritati if (!queue_isEmpty(procQ)) { queue_print(procQ, print_process); } else { printf("\n"); } // Afiseaza stivele for (i = 0; i < eventsNr; i++) { if (!stack_isEmpty(eventsStacks[i])) { printf("%d: ", i); stack_print(eventsStacks[i], print_process); } } printf("\n"); } // Elibereaza memoria queue_destroy(&procQ, free_process); for (i = 0; i < eventsNr; i++) { stack_destroy(&eventsStacks[i], free_process); } free(eventsStacks); return 0; }
/* In order to communicate with builtin_string, builtin_escape will return 2 to * indicate it did not push anything. */ int builtin_escape(interpreter* interp) { byte what, x0, x1; ++interp->ip; if (!is_ip_valid(interp)) { print_error("Escaped character expected"); return 0; } switch (curr(interp)) { case '(': case ')': case '[': case ']': case '{': case '}': case '<': case '>': return 2; case 'a': what = '\a'; break; case 'b': what = '\b'; break; case 'e': what = '\033'; break; case 'f': what = '\f'; break; case 'n': what = '\n'; break; case 'r': what = '\r'; break; case 't': what = '\t'; break; case 'v': what = '\v'; break; case '"': case '\\': case '\'': case '$': case '%': case '`': what = curr(interp); break; case 'x': { /* Extract both digits if present. */ ++interp->ip; if (is_ip_valid(interp)) { x0 = curr(interp); ++interp->ip; if (is_ip_valid(interp)) x1 = curr(interp); } if (!is_ip_valid(interp)) { print_error("Two hexits expected after \\x"); return 0; } /* Convert integer */ if (x0 >= '0' && x0 <= '9') what = (x0 - '0') << 4; else if (x0 >= 'a' && x0 <= 'f') what = (x0 + 10 - 'a') << 4; else if (x0 >= 'A' && x0 <= 'F') what = (x0 + 10 - 'A') << 4; else { print_error("First \\x hexit is invalid"); return 0; } if (x1 >= '0' && x1 <= '9') what |= (x1 - '0'); else if (x1 >= 'a' && x1 <= 'f') what |= (x1 + 10 - 'a'); else if (x1 >= 'A' && x1 <= 'F') what |= (x1 + 10 - 'A'); else { print_error("Second \\x hexit is invalid"); return 0; } } break; default: print_error("Invalid escape sequence"); return 0; } /* Create and push the string. */ stack_push(interp, create_string(&what, (&what)+1)); return 1; }
//逆ポーランドモードの関数 void rpn_calc(char* formula) { printf("\tRPN Calc Exec : formula = \"%s\"\n",formula); double answer = 0; double ret = 0; int i; char tmp_buffer[BUFFER_LENGTH]; int tmp_buffer_pointer = 0; string_clear(tmp_buffer,'\0',BUFFER_LENGTH); //実数が含まれるか確認 for(i=0;formula[i]!='\0';i++) { if(formula[i]=='.') { double_flag = 1; printf("\tRPN Calc Exec : double mode is true\n"); break; } } //計算ループ for(i=0;formula[i]!='\0';i++) { //数値の場合 if((formula[i]>='0'&&formula[i]<='9')||formula[i]=='.') { tmp_buffer[tmp_buffer_pointer++] = formula[i]; } //演算子の場合 else if(formula[i]=='+'||formula[i]=='-'||formula[i]=='*'||formula[i]=='/') { if(tmp_buffer[0]!='\0') { if(double_flag==1) ret = my_atof(tmp_buffer); else ret = my_atoi(tmp_buffer); stack_push(ret); string_clear(tmp_buffer,'\0',BUFFER_LENGTH); tmp_buffer_pointer = 0; } stack_push(calc_exec(formula[i])); } //スペースまたはコンマの場合 else if(formula[i]==' '||formula[i]==',') { if(tmp_buffer[0]!='\0') { if(double_flag==1) ret = my_atof(tmp_buffer); else ret = my_atoi(tmp_buffer); stack_push(ret); string_clear(tmp_buffer,'\0',BUFFER_LENGTH); tmp_buffer_pointer = 0; } } } //解答を取り出す answer = stack_pop(); //エラーフラグのチェック if(error_flag==0) { //実数フラグによって表示方法を変更 if(double_flag==0) { printf("\tAnswer : %d\n",(int)answer); } else { printf("\tAnswer : %lf\n",answer); double_flag = 0; } } else { //エラーが起こったときに答えを表示せずにエラー件数を表示して終了 printf("\tError : Total Error -> %d\n",error_flag); error_flag = 0; } }
void testStack() { // Create stack* my_stack = NULL; stack* dummy_stack = NULL; assert(stack_create(&my_stack) == 0); // Successfully create assert(stack_create(&dummy_stack) == 0); // Successfully create assert(stack_get_size(my_stack) == 0); // 0 size int a = 3; int b = 4; double c = 5.12; char d = 'c'; char str[20] = "Hello World"; // Successful pushes assert(stack_push(my_stack, &a, sizeof(a)) == 0); assert(stack_push(my_stack, &b, sizeof(b)) == 0); assert(stack_push(my_stack, &c, sizeof(c)) == 0); assert(stack_push(my_stack, &d, sizeof(d)) == 0); assert(stack_push(my_stack, str, strlen(str)) == 0); // Bad pushes: assert(stack_push(NULL, &a, sizeof(a)) != 0); assert(stack_push(my_stack, NULL, sizeof(a)) != 0); assert(stack_push(my_stack, &a, 0) != 0); assert(stack_get_size(my_stack) == 5); // 5 items int a2; int b2; double c2; char d2; char str2[20]; // Bad pop: assert(stack_pop(NULL, &a) != 0); assert(stack_pop(dummy_stack, &a) != 0); assert(stack_pop(my_stack, NULL) != 0); // Successful pop: assert(stack_get_data_size(my_stack) <= 20); assert(stack_pop(my_stack, str2) == 0 && strcmp(str,str)==0); assert(stack_get_data_size(my_stack) == sizeof(d2)); assert(stack_pop(my_stack, &d2) == 0 && d==d2); assert(stack_get_data_size(my_stack) == sizeof(c2)); assert(stack_pop(my_stack, &c2) == 0 && c==c2); assert(stack_get_data_size(my_stack) == sizeof(b2)); assert(stack_pop(my_stack, &b2) == 0 && b==b2); assert(stack_get_data_size(my_stack) == sizeof(a2)); assert(stack_pop(my_stack, &a2) == 0 && a==a2); // Bad pop assert(stack_pop(my_stack, &a2) != 0); // Cleanup assert(stack_delete(my_stack) == 0); // Successfully create assert(stack_delete(dummy_stack) == 0); // Successfully create printf("Stack: Success\n"); }
static int output(struct eval *eval, struct tok *tok) { return stack_push(eval->stk, tok); }
void instruction_execute_push(_pmachine m, _pinstruction ins) { stack_push(&m->stack, (int)ins); }
int enum_clients_events_cb(const struct event_base *base, const struct event *event, void *arg) { (void)base; enum_clients_events_cb_arg_struct *cb_arg = (enum_clients_events_cb_arg_struct *)arg; if (cb_arg->events_filter(event)) stack_push(&cb_arg->events_stack, event); return 0; }
inline void push_has_block(CallFrame* call_frame) { stack_push(RBOOL(CBOOL(call_frame->scope->block()))); }
int dp_can_connect_str(str *domain, int rec_level) { struct rdata* head; struct rdata* l; struct naptr_rdata* naptr; struct naptr_rdata* next_naptr; int ret; str newdomain; char uri[MAX_URI_SIZE]; struct avp_stack stack; int last_order = -1; int failed = 0; int found_anything = 0; str pattern, replacement, result; stack_reset(&stack); /* If we're in a recursive call, set the domain-replacement */ if ( rec_level > 0 ) { stack_push(&stack, domain_replacement_name.s.s, domain->s); stack.succeeded = 0; } if (rec_level > MAX_DDDS_RECURSIONS) { LM_ERR("too many indirect NAPTRs. Aborting at %.*s.\n", domain->len, ZSW(domain->s)); return(DP_DDDS_RET_DNSERROR); } LM_INFO("looking up Domain itself: %.*s\n",domain->len, ZSW(domain->s)); ret = check_rule(domain,"D2P+sip:dom", 11, &stack); if (ret == 1) { LM_INFO("found a match on domain itself\n"); stack_to_avp(&stack); return(DP_DDDS_RET_POSITIVE); } else if (ret == 0) { LM_INFO("no match on domain itself.\n"); stack_reset(&stack); /* If we're in a recursive call, set the domain-replacement */ if ( rec_level > 0 ) { stack_push(&stack, domain_replacement_name.s.s, (char *) domain->s); stack.succeeded = 0; } } else { return(DP_DDDS_RET_DNSERROR); /* actually: DB error */ } LM_INFO("doing DDDS with %.*s\n",domain->len, ZSW(domain->s)); head = get_record(domain->s, T_NAPTR, RES_ONLY_TYPE); if (head == 0) { LM_NOTICE("no NAPTR record found for %.*s.\n", domain->len, ZSW(domain->s)); return(DP_DDDS_RET_NOTFOUND); } LM_DBG("found the following NAPTRs: \n"); for (l = head; l; l = l->next) { if (l->type != T_NAPTR) { LM_DBG("found non-NAPTR record.\n"); continue; /*should never happen*/ } naptr = (struct naptr_rdata*)l->rdata; if (naptr == 0) { LM_CRIT("null rdata\n"); continue; } LM_DBG("order %u, pref %u, flen %u, flags '%.*s', slen %u, " "services '%.*s', rlen %u, regexp '%.*s', repl '%s'\n", naptr->order, naptr->pref, naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), naptr->services_len, (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len, (int)(naptr->regexp_len), ZSW(naptr->regexp), ZSW(naptr->repl) ); } LM_DBG("sorting...\n"); naptr_sort(&head); for (l = head; l; l = l->next) { if (l->type != T_NAPTR) continue; /*should never happen*/ naptr = (struct naptr_rdata*)l->rdata; if (naptr == 0) { LM_CRIT("null rdata\n"); continue; } LM_DBG("considering order %u, pref %u, flen %u, flags '%.*s', slen %u, " "services '%.*s', rlen %u, regexp '%.*s', repl '%s'\n", naptr->order, naptr->pref, naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), naptr->services_len, (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len, (int)(naptr->regexp_len), ZSW(naptr->regexp), ZSW(naptr->repl) ); /* * New order? then we check whether the had success during the last one. * If yes, we can leave the loop. */ if (last_order != naptr->order) { last_order = naptr->order; failed = 0; if (stack_succeeded(&stack)) { LM_INFO("we don't need to consider further orders " "(starting with %d).\n",last_order); break; } } else if (failed) { LM_INFO("order %d has already failed.\n",last_order); continue; } /* * NAPTRs we don't care about */ if (!IS_D2PNAPTR(naptr)) continue; /* * once we've been here, don't return DP_DDDS_RET_NOTFOUND */ found_anything = 1; next_naptr = NULL; if (l->next && (l->next->type == T_NAPTR)) { next_naptr = (struct naptr_rdata*)l->next->rdata; } /* * Non-terminal? */ if ((naptr->services_len == 7) && !strncasecmp("D2P+SIP", naptr->services,7) && (naptr->flags_len == 0)){ LM_INFO("found non-terminal NAPTR\n"); /* * This needs to be the only record with this order. */ if (next_naptr && (next_naptr->order == naptr->order) && IS_D2PNAPTR(next_naptr)) { LM_ERR("non-terminal NAPTR needs to be the only one " "with this order %.*s.\n", domain->len, ZSW(domain->s)); return(DP_DDDS_RET_DNSERROR); } newdomain.s = naptr->repl; newdomain.len = strlen(naptr->repl); ret = dp_can_connect_str(&newdomain, rec_level + 1); if (ret == DP_DDDS_RET_POSITIVE) /* succeeded, we're done. */ return(ret); if (ret == DP_DDDS_RET_NEGATIVE) /* found rules, did not work */ continue; /* look for more rules */ if (ret == DP_DDDS_RET_DNSERROR) /* errors during lookup */ return(ret); /* report them */ if (ret == DP_DDDS_RET_NOTFOUND) /* no entries in linked domain? */ return(ret); /* ok, fine. go with that */ continue; /* not reached */ } /* * wrong kind of terminal */ if ((naptr->flags_len != 1) || (tolower(naptr->flags[0]) != 'u')) { LM_ERR("terminal NAPTR needs flag = 'u' and not '%.*s'.\n", (int)naptr->flags_len, ZSW(naptr->flags)); /* * It's not that clear what we should do now: Ignore this records or regard it as failed. * We go with "ignore" for now. */ continue; } if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len, &pattern, &replacement) < 0) { LM_ERR("parsing of NAPTR regexp failed\n"); continue; } result.s = &(uri[0]); result.len = MAX_URI_SIZE; /* Avoid making copies of pattern and replacement */ pattern.s[pattern.len] = (char)0; replacement.s[replacement.len] = (char)0; if (reg_replace(pattern.s, replacement.s, domain->s, &result) < 0) { pattern.s[pattern.len] = '!'; replacement.s[replacement.len] = '!'; LM_ERR("regexp replace failed\n"); continue; } LM_INFO("resulted in replacement: '%.*s'\n", result.len, ZSW(result.s)); pattern.s[pattern.len] = '!'; replacement.s[replacement.len] = '!'; ret = check_rule(&result,naptr->services,naptr->services_len, &stack); if (ret == 1) { LM_INFO("positive return\n"); } else if (ret == 0) { LM_INFO("check_rule failed.\n"); stack_reset(&stack); /* If we're in a recursive call, set the domain-replacement */ if ( rec_level > 0 ) { stack_push(&stack, domain_replacement_name.s.s, (char *) domain->s); stack.succeeded = 0; } failed = 1; } else { return(DP_DDDS_RET_DNSERROR); } } if (stack_succeeded(&stack)) { LM_INFO("calling stack_to_avp.\n"); stack_to_avp(&stack); return(DP_DDDS_RET_POSITIVE); } LM_INFO("returning %d.\n", (found_anything ? DP_DDDS_RET_NEGATIVE : DP_DDDS_RET_NOTFOUND)); return( found_anything ? DP_DDDS_RET_NEGATIVE : DP_DDDS_RET_NOTFOUND ); }
int main(int argc, char *argv[]) { //sgenrand(time(NULL)); int k, curr_pos, check; int chunk; /* Repeat experiment in chunks. */ srand(SEED); printf("# Info: $Header: /home/ma/p/pruess/.cvsroot/manna_range/dmitry_20151021/manna_stack_clean_edited.c,v 1.2 2015/10/21 11:37:00 pruess Exp $\n"); preamble(argc, argv); PRINT_PARAM(SEED, "%lu"); PRINT_PARAM(LENGTH, "%lu"); PRINT_PARAM(DROP_LOCATION, "%lu"); PRINT_PARAM(total_malloced, "%lli"); printf("# Info: Expected avalanche size: <s>(x) = 1+(1/2) (<s>(x+1)+<s>(x-1)), BC <s>(0)=0, <s>(L+1)=0, solved by <s>(x)=(L+1-x)x/2.\n"); printf("# Info: Here L=LENGTH=%lu and x=DROP_LOCATION+1=%lu, so expect %g\n", LENGTH, DROP_LOCATION+1, ((double)(DROP_LOCATION+1))*((double)(LENGTH-DROP_LOCATION))/2.); for (chunk=1; ((chunk<=NUM_CHUNKS) || (NUM_CHUNKS<0)); chunk++) { MOMENTS_INIT(size); for (drop = 0; drop < N_ROLLS; drop++) { // big droppping cycle size=0; /* printf("(%i.)", drop); for(k = 0; k<LENGTH; k++) { printf("\%i", lattice[k]); } printf("\n"); */ #if (1) if(check_cell(DROP_LOCATION) == 0) { lattice[DROP_LOCATION] = 1; } else { stack_push(DROP_LOCATION); stack_push(DROP_LOCATION); lattice[DROP_LOCATION] = 0; } /* If validated, optimse by turning stack operations into macros, * optime random number drawing (rather than having doubles in the tree * have integers there and draw an integer to compare against), * optimise the shuffling of particles. * * I have added MOMENT macros for size. */ while(stack_used != 0) { curr_pos = stack_pop(); /* This code with the "check" looks clumsy. I suppose * you are "following through" topplings? I would think * there is no point doing this later. Anyway, we validate * this code and take it from there. */ do { curr_pos = move_ball(curr_pos); if(curr_pos >= LENGTH || curr_pos < 0) { check = 0 ; } /* Why not just "else" instead of the "if"? */ if(curr_pos < LENGTH && curr_pos >= 0) { check = check_cell(curr_pos); if (check == 1) { stack_push(curr_pos); } else { check = 0; } } }while(check != 0); }/* end of while(stack_used != 0) look */ #endif #if (0) { int npos; #define PUSH(a) stack[stack_used++]=(a) #define POP(a) (a)=stack[--stack_used] if (lattice[DROP_LOCATION]++==1) { PUSH(DROP_LOCATION); while(stack_used) { size++; POP(curr_pos); do { lattice[curr_pos]-=2; npos=curr_pos+ ( (rand()>RAND_MAX/2) ? 1 : -1); if ((npos>=0) && (npos<LENGTH)) { if (lattice[npos]++==1) {PUSH(npos);} } if ((npos>=0) && (npos<LENGTH)) { if (lattice[npos]++==1) {PUSH(npos);} } } while (lattice[curr_pos]>1); } } } #endif //printf("size is %i\n", size); MOMENTS(size,size); } /* end of iterations loop */ MOMENTS_OUT(size); } /* chunk */ postamble(); }
inline void push_stack_local(CallFrame* call_frame, intptr_t which) { stack_push(stack_local(which)); }
long double evaluate(string_t* expr) { int i, length; double result, a, b; char as_string[2] = "\0"; char top, op, unused; stack values, ops; string_t formatted; init_string(&formatted, ""); format_expression_string(expr, &formatted); stack_new(&values, sizeof(double)); stack_new(&ops, sizeof(char)); length = strlen(formatted.string); for(i = 0; i < length; i++) { /* Current token is a whitespace, skip it */ if (formatted.string[i] == ' ') continue; /* Current token is a number, push it to stack for numbers */ if((formatted.string[i] >= '0' && formatted.string[i] <= '9') || (formatted.string[i] == '.')) { string_t buf; init_string(&buf, ""); /* There may be more than one digits in number */ while((i < length) && (((formatted.string[i] >= '0') && (formatted.string[i] <= '9')) || (formatted.string[i] == '.'))) { as_string[0] = formatted.string[i++]; append(&buf, as_string); } result = atof(buf.string); stack_push(&values, &result); } else if(formatted.string[i] == '(') { /* Current token is an opening brace, push it to 'ops' */ as_string[0] = formatted.string[i]; stack_push(&ops, as_string); } else if(formatted.string[i] == ')') { /* Closing brace encountered, solve entire brace */ while(TRUE) { stack_peek(&ops, &top); if(top == '(') break; stack_pop(&values, &a); stack_pop(&values, &b); stack_pop(&ops, &op); result = apply_op(op, a, b); stack_push(&values, &result); } stack_pop(&ops, &unused); /* pop ( */ } else if(is_operator(formatted.string[i])) { /* While top of 'ops' has same or greater precedence to current token, which is an operator. Apply operator on top of 'ops' to top two elements in values stack */ while(TRUE) { top = '('; if(!stack_empty(&ops)) stack_peek(&ops, &top); if(stack_empty(&ops) || !has_precedence(formatted.string[i], top)) break; stack_pop(&values, &a); stack_pop(&values, &b); stack_pop(&ops, &op); result = apply_op(op, a, b); /* !!!!!!!!!!!!!!!!!!!! if(division_by_zero) { return -255; } */ stack_push(&values, &result); } /* Push current token to 'ops'. */ as_string[0] = formatted.string[i]; stack_push(&ops, as_string); } } /* Entire expression has been parsed at this point, apply remaining ops to remaining values */ while(!stack_empty(&ops)) { stack_pop(&values, &a); stack_pop(&values, &b); stack_pop(&ops, &op); result = apply_op(op, a, b); stack_push(&values, &result); } /* Top of 'values' contains result, return it */ stack_pop(&values, &result); return result; }
void append_call_stack(char type){ obj * o = create_call_block(type, call_stack_top); stack_push(call_stack, o); call_stack_top = (call_block*)o->data; }
static __inline void push(struct value *v) { stack_push(&bmachine.stack, v); }
int eval_instruction(struct vm_context **ctx) { struct symbol *sym; struct object *value; struct compound_proc *template; switch (INS_AT((*ctx)->pc)->op) { case NONE: printf("Error: tried to execute a NONE op\n"); exit(1); break; case PUSH: /* printf("PUSH instruction\n"); */ stack_push((*ctx)->stk, INS_AT((*ctx)->pc)->arg); INC_REF(INS_AT((*ctx)->pc)->arg); ++(*ctx)->pc->offset; break; case POP: /* printf("POP instruction\n"); */ value = stack_pop((*ctx)->stk); DEC_REF(value); ++(*ctx)->pc->offset; break; case LOOKUP: /* printf("LOOKUP instruction\n"); */ assert(INS_AT((*ctx)->pc)->arg->type->code == SYMBOL_TYPE); sym = container_of(INS_AT((*ctx)->pc)->arg, struct symbol, obj); value = env_lookup((*ctx)->env, sym->value); if (! value) { char buf[1024]; debug_loc_str(INS_AT((*ctx)->pc)->arg, buf, 1024); printf("%s: unbound name: %s\n", buf, sym->value); exit(1); } stack_push((*ctx)->stk, value); INC_REF(value); ++(*ctx)->pc->offset; break; case CALL: case TAILCALL: /* printf("CALL instruction @ %p\n", *pc); */ eval_call(ctx); break; case RET: value = stack_pop((*ctx)->stk); struct object *orig_env = stack_pop((*ctx)->stk); assert(orig_env->type->code == ENVIRONMENT_TYPE); DEC_REF(orig_env); struct object *retaddr = stack_pop((*ctx)->stk); /* printf("RET instruction @ %p to %p\n", *pc, retaddr->cval); */ stack_push((*ctx)->stk, value); DEC_REF(&(*ctx)->env->obj); (*ctx)->env = container_of(orig_env, struct environment, obj); if (retaddr == NULL) { (*ctx)->pc = NULL; return 1; } assert(retaddr->type->code == CODEPTR_TYPE); *(*ctx)->pc = *container_of(retaddr, struct codeptr, obj); /* XXX: */ /* DEC_REF(retaddr); */ break; case DEFINE: /* printf("DEFINE instruction\n"); */ value = stack_pop((*ctx)->stk); assert(INS_AT((*ctx)->pc)->arg->type->code == SYMBOL_TYPE); sym = container_of(INS_AT((*ctx)->pc)->arg, struct symbol, obj); env_define((*ctx)->env, sym->value, value); DEC_REF(value); ++(*ctx)->pc->offset; break; case SET: value = stack_pop((*ctx)->stk); assert(INS_AT((*ctx)->pc)->arg->type->code == SYMBOL_TYPE); sym = container_of(INS_AT((*ctx)->pc)->arg, struct symbol, obj); env_set((*ctx)->env, sym->value, value); DEC_REF(value); ++(*ctx)->pc->offset; break; case LAMBDA: /* printf("LAMBDA instruction\n"); */ value = INS_AT((*ctx)->pc)->arg; assert(INS_AT((*ctx)->pc)->arg->type->code == PROCEDURE_TYPE);
/* setup_stack_and_mttrs() determines the stack to use after * cache-as-ram is torn down as well as the MTRR settings to use. */ static void *setup_stack_and_mttrs(void) { unsigned long top_of_stack; int num_mtrrs; uint32_t *slot; uint32_t mtrr_mask_upper; uint32_t top_of_ram; /* Top of stack needs to be aligned to a 4-byte boundary. */ top_of_stack = choose_top_of_stack() & ~3; slot = (void *)top_of_stack; num_mtrrs = 0; /* The upper bits of the MTRR mask need to set according to the number * of physical address bits. */ mtrr_mask_upper = (1 << ((cpuid_eax(0x80000008) & 0xff) - 32)) - 1; /* The order for each MTRR is value then base with upper 32-bits of * each value coming before the lower 32-bits. The reasoning for * this ordering is to create a stack layout like the following: * +0: Number of MTRRs * +4: MTRR base 0 31:0 * +8: MTRR base 0 63:32 * +12: MTRR mask 0 31:0 * +16: MTRR mask 0 63:32 * +20: MTRR base 1 31:0 * +24: MTRR base 1 63:32 * +28: MTRR mask 1 31:0 * +32: MTRR mask 1 63:32 */ /* Cache the ROM as WP just below 4GiB. */ slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRRphysMaskValid); slot = stack_push(slot, 0); /* upper base */ slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_TYPE_WRPROT); num_mtrrs++; /* Cache RAM as WB from 0 -> CONFIG_RAMTOP. */ slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ slot = stack_push(slot, ~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid); slot = stack_push(slot, 0); /* upper base */ slot = stack_push(slot, 0 | MTRR_TYPE_WRBACK); num_mtrrs++; top_of_ram = (uint32_t)cbmem_top(); /* Cache 8MiB below the top of ram. The top of ram under 4GiB is the * start of the TSEG region. It is required to be 8MiB aligned. Set * this area as cacheable so it can be used later for ramstage before * setting up the entire RAM as cacheable. */ slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid); slot = stack_push(slot, 0); /* upper base */ slot = stack_push(slot, (top_of_ram - (8 << 20)) | MTRR_TYPE_WRBACK); num_mtrrs++; /* Cache 8MiB at the top of ram. Top of ram is where the TSEG * region resides. However, it is not restricted to SMM mode until * SMM has been relocated. By setting the region to cacheable it * provides faster access when relocating the SMM handler as well * as using the TSEG region for other purposes. */ slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid); slot = stack_push(slot, 0); /* upper base */ slot = stack_push(slot, top_of_ram | MTRR_TYPE_WRBACK); num_mtrrs++; /* Save the number of MTRRs to setup. Return the stack location * pointing to the number of MTRRs. */ slot = stack_push(slot, num_mtrrs); return slot; }