void eval(stack **n_stack, stack **o_stack, double *x, double *y){ //Using easier names char op=top_operator(*o_stack); double n1, n2; //Checking the different cases for the top of the stack if(op=='='){ pop_operator(&(*o_stack)); if(pop_operator(&(*o_stack))=='x') *x=top_number(*n_stack); else *y=top_number(*n_stack); } else if(op=='x'){ pop_operator(&(*o_stack)); push_number(*x, &(*n_stack)); } else if(op=='y'){ pop_operator(&(*o_stack)); push_number(*y, &(*n_stack)); } else{//Push the computed result into the n_stack n1=pop_number(&(*n_stack)); n2=pop_number(&(*n_stack)); op=pop_operator(&(*o_stack)); push_number(compute(n1, op, n2), &(*n_stack)); } }
void evalStackUntilLeftP() { //printf("eval leftp called\n"); command_t operand2, operand1; int operatorNumber; //pop_operator(); // get rid of RIGHTP while(operator_stack_top() != LEFTP) { //printf("operator top is %i\n",operator_stack_top()); if(operator_stack_top() == -1) error(1,0,"%i: Syntax Error. Mismatching parenthesis\n",g_lineNumber); operand2 = pop_operand(); operand1 = pop_operand(); operatorNumber = pop_operator(); push_operand(createCommand(operand1, operand2, operatorNumber)); } //do not assume we have a result. Parenthesis could be empty (). pop_operator();// get rid of LEFTP //printf("Operator_stackTop %i\n",operator_stack_top()); //printf("Operand_stacktop %i\n",operand_stack_top()); if(operand_stack_top() != NULL) { //convert command at the top of operand stack to subshell command. //printf("pooping operand\n"); operand1 = pop_operand(); push_operand(createCommand(operand1, NULL, RIGHTP)); } //printf("Number of operands left %i\n",g_iOperand_stack_size); //printf("Number of operators left %i\n",g_iOperator_stack_size); }
void eval_exp(char *exp, int len){ //Using two stacks stack *n_stack=NULL;//number stack int i=0;//counter for the above array double n;//To store the converted number char c;//To store the character in the expression double x=1.0, y=1.0; //Making changes so that the end and beginning of the exoression can be identified stack *o_stack=NULL; push_operator('{', &o_stack);;//initializing the first value of o_stack strcat(exp,"}"); ++len; while(isnotempty(o_stack)){ c=exp[i]; if(isdigit(c)){ n=atof((exp+i));//Getting the entire number while(isdigit(c)||c=='.'){ ++i; c=exp[i]; } --i;//The last increment takes an extra character from the expression //Pushing into n stack push_number(n, &n_stack); } else{ if(c=='}'){//End of the expression while(top_operator(o_stack)!='{'){ //Updating stacks after computation eval(&n_stack, &o_stack, &x, &y); } pop_operator(&o_stack);//poping the '{' from the o_stack } else if(c==')'){//Priority of parenthesis while(top_operator(o_stack)!='('){ //updating stacks after computation eval(&n_stack, &o_stack, &x, &y); } pop_operator(&o_stack);//popping the '(' operator from the o_stack } else if(in_stack_priority(top_operator(o_stack))>=out_stack_priority(c)){ do{ //Pooping elements and taking temporary values eval(&n_stack, &o_stack, &x, &y); }while(in_stack_priority(top_operator(o_stack))>=out_stack_priority(c)); push_operator(c, &o_stack);//Pushing the new operator into the o_stack } else{//Pushing the operator in the o_stack push_operator(c, &o_stack); } } ++i;//incrementing the counter } //returning the final result printf("\nThe value of x is %lf and y is %lf.\nThe value of the expression is: %lf\n", x, y, pop_number(&n_stack)); }
/* * Parse an infix expression from a token stream * Returns a parse tree * See https://en.wikipedia.org/wiki/Shunting-yard_algorithm */ Token parse_infix_expression(Token tokens){ Token operators = NULL; unsigned operatorsLen = 0; Token output = NULL; unsigned outputLen = 0; Token nextToken; while(tokens != NULL){ nextToken = tokens->next; tokens->next = NULL; // if it's not a builtin, stick it in output if(tokens->type != BUILTIN){ push_token_stack(tokens, &output, &outputLen); } else { // if it's a builtin, do magic // check if it's allowed to be here ERROR_UNLESS(!can_start_line(tokens->builtin), "statement operators not allowed in expressions") if(operatorsLen == 0){ push_token_stack(tokens, &operators, &operatorsLen); } else if(tokens->builtin == L_PAREN){ push_token_stack(tokens, &operators, &operatorsLen); } else if(tokens->builtin == R_PAREN){ // pop operators until L_PAREN free_token(&tokens); // we don't need the R_PAREN while(operatorsLen > 0 && operators->builtin != L_PAREN) pop_operator(&operators, &operatorsLen, &output, &outputLen); if(operatorsLen == 0){ // there was no L_PAREN, so error ERROR("mismatched parentheses") } else { // discard the L_PAREN Token discard = pop_token_stack(&operators, &operatorsLen); free_token(&discard); } } else if(get_precedence(tokens->builtin) > get_precedence(operators->builtin)){ push_token_stack(tokens, &operators, &operatorsLen); } else { // we are not a parenthesis and we're lower precedence than // the operator on the stack, so pop it and put us there pop_operator(&operators, &operatorsLen, &output, &outputLen); push_token_stack(tokens, &operators, &operatorsLen); } }
/** * While there are still operators, keep evaluating the stack so that what is left will * be one complete command in the operand stack. */ void evalStack() { command_t operand2, operand1; int operatorNumber; while(g_iOperator_stack_size > 0) { operand2 = pop_operand(); // if( !( g_iOperand_stack_size <= 0 && operator_stack_top() == SEMIC) ) operand1 = pop_operand(); // else //allow ';' to only have one operand // operand1 = NULL; operatorNumber = pop_operator(); push_operand(createCommand(operand1, operand2, operatorNumber)); } if(g_iOperand_stack_size > 1) { error(1, 0, "%i: Syntax Error. Incorrect number of elements on operand stack after evalStack\n", g_lineNumber); } }
double in_eval(char *exp) { int exp_length = strlen(exp), numOfVars = 0; struct operator_stack *os = create_operator_stack(exp_length / 2); char *token, *copy, *vars[10] = {NULL}, rpn_exp[1024] = ""; double value = 0; copy = (char *) malloc(sizeof(char) * exp_length); strcpy(copy, exp); token = strtok(copy, " "); bool previousIsOperator = false, previousIsLeftParenthese = false, varsSet = false; while (token != NULL) { errorOccurs = true; varsSet = false; if (isNumeric(token) && sscanf(token, "%lf", &value) > 0) { if (!(strlen(rpn_exp) == 0 || previousIsOperator || previousIsLeftParenthese)) return value; for (int i = 0; i < numOfVars; i++) { setVariable(vars[i], value); vars[i] = NULL; varsSet = true; } numOfVars = 0; errorOccurs = false; previousIsOperator = false; previousIsLeftParenthese = false; concat_double(rpn_exp, value); } else if (variableValid(token)) { if (!(strlen(rpn_exp) == 0 || previousIsOperator || previousIsLeftParenthese)) return value; char operator = *(token + strlen(token) + 1); if (operator == '=') { vars[numOfVars++] = token; errorOccurs = false; } else { value = getVariable(token); errorOccurs = !variableExists(token); concat_double(rpn_exp, value); } previousIsOperator = false; previousIsLeftParenthese = false; } else if (isOperator(token) || isParenthese(token)) { if ((isOperator(token) && previousIsOperator) || (strcmp(token, ")") == 0 && strlen(rpn_exp) == 0)) return value; if (numOfVars > 0) return value; char *op = NULL; if (strcmp(token, "(") == 0) { push_operator(os, token); previousIsLeftParenthese = true; } else if (strcmp(token, ")") == 0) { op = peek_operator(os); if (strcmp(op, "(") == 0) return value; op = pop_operator(os); while (strcmp(op, "(") != 0) { if (strcmp(op, ")") == 0) return value; concat_operator(rpn_exp, op); op = pop_operator(os); } previousIsLeftParenthese = false; } else { int pre1 = -1, pre2 = getOperatorPrecedence(token); if (os->top > -1) pre1 = getOperatorPrecedence(peek_operator(os)); while (pre2 > pre1 && pre1 > 0 && os->top > -1) { concat_operator(rpn_exp, pop_operator(os)); if (os->top > -1) pre1 = getOperatorPrecedence(peek_operator(os)); } push_operator(os, token); previousIsOperator = true; previousIsLeftParenthese = false; } errorOccurs = false; } else if (strcmp(token, "=") == 0) { errorOccurs = false; } else { return value; } if (errorOccurs) return value; token = strtok(NULL, " "); } while (os->top > -1) concat_operator(rpn_exp, pop_operator(os)); free(copy); free_operator_stack(os); if (!(varsSet || errorOccurs)) value = rpn_eval(rpn_exp); return value; }
static int compile(scriptlet *s, const char *src) { compiletime c = (compiletime)calloc(1, sizeof(struct compiletime_)); c->s = s; s->it_codes = 0; token tok; while ((src = get_token(src, tok)) != 0) { int precedence = get_precedence(tok); if (precedence) { DEBUG printf("operator '%s' precedence=%d\n", tok, precedence); } else { DEBUG printf("operand '%s'\n", tok); } if (!precedence) { push_operand(c, tok); continue; } if (!strcmp(tok, "(")) { push_operator(c, tok, precedence); continue; } int top_precedence, discard = 0, empty_list; const char *top_op; while ((top_op = head_operator(c, &top_precedence, &empty_list)), !empty_list) { if (!strcmp(top_op, "(") && !strcmp(tok, ")")) { int operand_count; pop_operator(c, &operand_count); discard = 1; continue; } DEBUG printf("top_op = '%s' with precedence = %d\n", top_op, top_precedence); if (precedence > top_precedence) break; if (!compile_operator(c)) { free(c); return 0; } if (discard) break; } if (!discard) push_operator(c, tok, precedence); } int top_precedence, empty_list; const char *top_op; while ((top_op = head_operator(c, &top_precedence, &empty_list)), !empty_list ) { DEBUG printf("top_op = '%s'\n", top_op); if (!compile_operator(c)) { free(c); return 0; } } free(c); return 1; }
static int compile_operator(compiletime c) { int operand_count = 0; const char *op = pop_operator(c, &operand_count); if (!strcmp(op, "*")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, multiply_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "**")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, power_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "/")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, divide_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "%")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, modulo_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "=")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, assign_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, ";")) { } else if (!strcmp(op, "if")) { const char *val1 = pop_operand(c); emit2(c, if_tc, val1); DEBUG printf("emit '%s' %s\n", val1, op); c->level++; } else if (!strcmp(op, "else")) { c->level--; emit1(c, else_tc); c->level++; DEBUG printf("emit %s\n", op); } else if (!strcmp(op, "fi")) { c->level--; emit1(c, fi_tc); DEBUG printf("emit %s\n", op); } else if (!strcmp(op, "!")) { const char *val1 = pop_operand(c); emit2(c, not_tc, val1); DEBUG printf("emit '%s' %s\n", val1, op); } else if (!strcmp(op, "+")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, add_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "-")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, subtract_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, ">")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, gt_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, ">=")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, geq_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "<=")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, leq_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "<")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, lt_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "&&")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, and_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "||")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, or_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "^^")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, xor_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "&")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, bit_and_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "|")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, bit_or_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "^")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, bit_xor_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "~")) { const char *val1 = pop_operand(c); emit2(c, bit_negate_tc, val1); DEBUG printf("emit %s %s\n", val1, op); } else if (!strcmp(op, "<<")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, shift_left_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, ">>")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, shift_right_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, ">>>")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, logical_shift_right_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "==")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, eq_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "!=")) { const char *val2 = pop_operand(c); const char *val1 = pop_operand(c); emit3(c, neq_tc, val1, val2); DEBUG printf("emit %s %s %s\n", val1, op, val2); } else if (!strcmp(op, "fold-case")) { const char *val1 = pop_operand(c); emit2(c, func_fold_case_tc, val1); DEBUG printf("emit %s %s\n", op, val1); } else if (!strcmp(op, "size")) { const char *val1 = pop_operand(c); emit2(c, func_size_tc, val1); DEBUG printf("emit %s %s\n", op, val1); } else if (!strcmp(op, "print")) { const char *val1 = pop_operand(c); emit2(c, func_print_tc, val1); DEBUG printf("emit %s %s\n", op, val1); } else if (!strcmp(op, "jday")) { const char *val1 = pop_operand(c); emit2(c, func_jday_tc, val1); DEBUG printf("emit %s %s\n", op, val1); } else if (!strcmp(op, "dow")) { const char *val1 = pop_operand(c); emit2(c, func_dow_tc, val1); DEBUG printf("emit %s %s\n", op, val1); } else if (!strcmp(op, "equals")) { emit_code(c, func_eq_tc, operand_count); while (operand_count--) { const char *val1 = pop_operand(c); emit_value(c, val1); DEBUG printf("emit %s '%s'\n", op, val1); } } else if (!strcmp(op, "contains")) { emit_code(c, func_contains_tc, operand_count); while (operand_count--) { const char *val1 = pop_operand(c); emit_value(c, val1); DEBUG printf("emit %s '%s'\n", op, val1); } } else if (!strcmp(op, "begins-with")) { emit_code(c, func_begins_with_tc, operand_count); while (operand_count--) { const char *val1 = pop_operand(c); emit_value(c, val1); DEBUG printf("emit %s '%s'\n", op, val1); } } else if (!strcmp(op, "ends-with")) { emit_code(c, func_ends_with_tc, operand_count); while (operand_count--) { const char *val1 = pop_operand(c); emit_value(c, val1); DEBUG printf("emit %s '%s'\n", op, val1); } } else if (!strcmp(op, "int")) { const char *val1 = pop_operand(c); emit2(c, func_is_int_tc, val1); DEBUG printf("emit %s '%s'\n", op, val1); } else if (!strcmp(op, "real")) { const char *val1 = pop_operand(c); emit2(c, func_is_real_tc, val1); DEBUG printf("emit %s '%s'\n", op, val1); } else if (!strcmp(op, "nan")) { const char *val1 = pop_operand(c); emit2(c, func_is_nan_tc, val1); DEBUG printf("emit %s '%s'\n", op, val1); } else if (!strcmp(op, "string")) { const char *val1 = pop_operand(c); emit2(c, func_is_string_tc, val1); DEBUG printf("emit %s '%s'\n", op, val1); } else if (!strcmp(op, "(")) { return 1; } else if (!strcmp(op, ")")) { return 1; } else { DEBUG printf("bad operator '%s'\n", op); return 0; } push_operand(c, "_STACK"); return 1; }
command_stream_t make_command_stream (int (*get_next_byte) (void *), void *get_next_byte_argument) { char *operators[] = { "&&", "||", "|", "(", ")", ";" };//, "\n" }; int precedences[] = { 1, 1, 2, 4, -1, 0, 0 }; int i, j, isOperator, numChars = 0, inComment = 0; int operatorNumber = 0; int possibleNewCommand = 0; unsigned int currentWordSize = 16 * sizeof(char); int lastOperatorWasRightP = 0; char *operand, *lastCommand, *currentWord = checked_malloc(16 * sizeof(char)); char c = (char) get_next_byte(get_next_byte_argument); command_t operand1, operand2; // Initialize command stream command_stream_t commandStream = checked_malloc(10 * sizeof(struct command)); commandStream->currentStreamSize = 10 * sizeof(struct command); commandStream->numCommands = 0; commandStream->currentCommand = 0; g_lineNumber = 0; init_stacks(); while(c != EOF) { //printf("loop entered\n"); if( c == '\n') { g_lineNumber++; } if(inComment) { if( c == '\n' ) { inComment = 0; c = get_next_byte(get_next_byte_argument); continue; } else { c = get_next_byte(get_next_byte_argument); continue; } } else if( c == '#' ) { inComment = 1; c = get_next_byte(get_next_byte_argument); continue; } /** * Basically if there is a non-operator followed by a newline, there is a possibility * that the current command is done. The current command will be over if the newline * is then followed by another non-operator. Also ignore newlines inside commands. */ //printf("possible New COmmand is set to %i\n",possibleNewCommand); if ( (!isOperator || lastOperatorWasRightP) && c == '\n') { possibleNewCommand = 1; //printf("PossibleNewCommand set to 1 char is %c\n",c); // Used if a new command is actually started to finish the current one lastCommand = currentWord; fpos_t pos; fgetpos(get_next_byte_argument, &pos); c = get_next_byte(get_next_byte_argument); if (c != '\n') { //printf("continuing after setting possibleNewCommand to 1\n"); // if(c == EOF) // printf("new character is EOF and num of operands left is %i\n",g_iOperand_stack_size); fsetpos(get_next_byte_argument, &pos); lastOperatorWasRightP = 0; continue; } else { g_lineNumber++; } } else if (c == '\n') { c = get_next_byte(get_next_byte_argument); //printf("Operator followed by newlien detected. continiuing\n"); lastOperatorWasRightP = 0; continue; } //printf("Checkpoint 2\n"); /** * This loop checks if the current char is an operator. If it is, we create the operator word * and then we check the next char in case of double char operators such as || or && */ lastOperatorWasRightP = 0; isOperator = 0; for (i = 0; i < 6; i++) { // check if start of an operator if (c == operators[i][0]) { isOperator = 1; operand = currentWord; // Save old operand before creating operator currentWord = checked_malloc(3 * sizeof(char)); // Create the operator word currentWord[0] = c; fpos_t pos; fgetpos(get_next_byte_argument, &pos); if (c == '|' || c == '&') { if(g_iOperand_stack_size <= 0 && numChars <= 0) error(1,0,"%i: Did not expect binary operator",g_lineNumber); char current_char = c; c = get_next_byte(get_next_byte_argument); currentWord[1] = c; currentWord[2] = '\0'; if (c == '|' && c == current_char) { i = OR; } else if (c == '&' && c == current_char) { i = AND; } else if( current_char == '&' && c != current_char) { //TODO: Throw syntax error here. Single &! //fprintf(stderr,"%i: Isolated & found. Not a valid word character, and it is not an &&",lineNumber); error(1,0,"%i: Isolated & found",g_lineNumber); } else { i = PIPE; currentWord[1] = '\0'; fsetpos(get_next_byte_argument, &pos); } } else if( c == '(') { //printf("Found leftP\n"); i = LEFTP; currentWord[1] = '\0'; fsetpos(get_next_byte_argument, &pos); } else if( c == ')') { //printf("Found rightP\n"); lastOperatorWasRightP = 1; i = RIGHTP; currentWord[1] = '\0'; fsetpos(get_next_byte_argument, &pos); } else if( c == ';') { if(g_iOperand_stack_size <= 0 && numChars <= 0) error(1,0,"%i: Did not expect binary operator",g_lineNumber); currentWord[1] = '\0'; fsetpos(get_next_byte_argument, &pos); } else { currentWord[1] = '\0'; fsetpos(get_next_byte_argument, &pos); } break; } } /** * When we encounter an operator, we can create a simple command out of the previous word * if there was a word (operand) there. This should always happen?? */ if (isOperator) { //printf("isOperator\n"); if (numChars > 0) { operand[numChars] = '\0'; //printf("Pushed %s on operand stack\n", operand); //get rid of whitespaces in operand here. int onlyWhite = getRidOfExtraWhitespaces(operand); if(onlyWhite == 0) push_operand(createSimpleCommand(operand)); // printf("simple out of operand %s\n", operand); numChars = 0; } /** * While the top of the stack contains an operator with equal or higher precedance than the * operator we are currently dealing with, keeping popping one operator and two operands, * creating a command out of them, and pushing it onto the operand stack. */ //printf("Charly:top of stack is %i\n",operator_stack_top()); // if(operator_stack_top() == RIGHTP ) //eval stack until a LEFTP is found if(i == RIGHTP) { //printf("EvalStackuntilLeftP found. possibleNewCommand is %i\n",possibleNewCommand); evalStackUntilLeftP(); //printf("current char is %c\n",c); c = get_next_byte(get_next_byte_argument); //printf("nextchar is %c\n",c); continue; } while(g_iOperator_stack_size > 0 && g_iOperand_stack_size > 1 && (precedences[operator_stack_top()] >= precedences[i]) && ((operator_stack_top() != LEFTP) && i != RIGHTP )) { operand2 = pop_operand(); operand1 = pop_operand(); operatorNumber = pop_operator(); //printf("popped operands types %d %d\n", operand1->type, operand2->type); //printf("popped operator %s\n", operators[operatorNumber]); //printf("pushed type %d operand on stack\n", operatorNumber); push_operand(createCommand(operand1, operand2, operatorNumber)); } // Get the operator number for the current word for (j = 0; j < 6; j++) { if (strcmp(currentWord, operators[j]) == 0) { break; } } //printf("pushed operators %s %d on stack\n", currentWord, j); push_operator(j); currentWord = checked_malloc(3 * sizeof(char)); } else if (!possibleNewCommand) { //if last operator was rightP. do not run this. //printf("not a new command. new char is %c, numChars is %i, currentWordSize is %i\n",c,numChars,currentWordSize); if(c != ' ' || numChars > 0) { //printf("growing current word %s currentWordSize is %i and numChars is %i\n",currentWord,currentWordSize,numChars); // Grow current word which is an operand if necessary if ((numChars * sizeof(char)) >= currentWordSize) { //printf("doubling size of word %s\n",currentWord); currentWordSize *= 2; //char * buffer = checked_malloc(currentWordSize); //strncpy(buffer,currentWord,numChars); //free((void *)currentWord); //currentWord = checked_malloc(currentWordSize); //strncpy(currentWord,buffer,numChars); currentWord = checked_realloc(currentWord, currentWordSize );// for some reason this was messing up //printf("it is now %s\n",currentWord); } currentWord[numChars] = c; numChars++; } } else { //printf("Going to new command. operand stack size is %i\n",g_iOperand_stack_size); //printf("Operator stack size is %i. numChars is %i\n",g_iOperator_stack_size,numChars); //if(g_iOperand_stack_size <= 0) //{ // c = get_next_byte(get_next_byte_argument); // possibleNewCommand = 0; //continue; //} /** * This means that we are about to go onto a new command. We stop the current command and * finish building it with the lastCommand variable, and an operand/operator if necessary. * This command is then put into the command stream. */ lastCommand[numChars] = '\0'; //printf("Last Command getting rid of whites\n"); if(numChars > 0) { //printf("numchars is > 0 so word is %s\n",lastCommand); getRidOfExtraWhitespaces(lastCommand); push_operand(createSimpleCommand(lastCommand)); } else if(g_iOperand_stack_size <= 0) { c = get_next_byte(get_next_byte_argument); possibleNewCommand = 0; continue; } //else //{ // printf("numChars == 0 so we are continuing\n"); //continue // c = get_next_byte(get_next_byte_argument); // possibleNewCommand = 0; // continue; //} evalStack(); //printf("%s\n", "Finished one command"); if ((commandStream->numCommands * sizeof(struct command)) == commandStream->currentStreamSize) { commandStream->currentStreamSize *= 2; commandStream = checked_realloc(commandStream, commandStream->currentStreamSize); } command_t commandToPushToStream = pop_operand(); commandToPushToStream->status = -1; commandStream->stream[commandStream->numCommands] = commandToPushToStream; // TODO: if stack not empty, there was an error? commandStream->numCommands++; numChars = 0; currentWord = checked_malloc(3 * sizeof(char)); // prevent overwriting } //printf("PossibleNewCOmmand set to 0 right before checkpoint1\n"); c = get_next_byte(get_next_byte_argument); possibleNewCommand = 0; } //printf("Checkpoint1. possibleNEwCommand is %i num of operands is %i\n",possibleNewCommand,g_iOperand_stack_size); // Push last word onto operand stack and evaluate the rest if (!isOperator) { currentWord[numChars] = '\0'; //printf("pushed simple word %s with word count %i strlen is %i\n", currentWord,numChars,(int)strlen(currentWord)); getRidOfExtraWhitespaces(currentWord); if(strlen(currentWord) > 0) push_operand(createSimpleCommand(currentWord)); } else { // if a semicolon, valid? } //printf("evalstack at the end of loop\n"); evalStack(); // Put last command in command stream // if there is one! if(operand_stack_top() != NULL) { command_t commandToPushToStream = pop_operand(); commandToPushToStream->status = -1; commandStream->stream[commandStream->numCommands] = commandToPushToStream; commandStream->numCommands++; } //printf("Stack sizes: %d, %d\n", g_iOperator_stack_size, g_iOperand_stack_size); //printf("Final command type is %d\n", commandStream->stream[0]->type); return commandStream; }