Ejemplo n.º 1
0
void *bank_server(void *args) {
	OpQueue queue;
	init_opqueue(&queue);

	int balance = 0;
	int locked_by = -1;
	while(1) {
		Operation *op = NULL;

		if(operation.status == 1) {
			pthread_mutex_lock(&operation.mutex);
			op = clone_op(&operation);
			operation.status = 0;
			pthread_mutex_unlock(&operation.mutex);

			fprintf(stderr, "[Thread %d], operation %s, new op", op->client_id, code_to_text(op->code));
		}
		else if(locked_by == -1) {
			op = pop_op(&queue);

			if(op != NULL)
			{
				fprintf(stderr, "[Thread %d], operation %s, popped op", op->client_id, code_to_text(op->code));
			}
		}
		else {
			continue;
		}

		if(op == NULL) {
			continue;
		}

		int is_performable = can_perform_op(op->code, op->client_id, locked_by);

		if(is_performable != 0) {
			pthread_mutex_lock(&op->put_answer_to->mutex);

			if(is_performable == 1) {
				switch(op->code) {
					case OP_LOOK:
						op->put_answer_to->comment = "";
						break;
					case OP_LOCK:
						op->put_answer_to->comment = "successfully locked";
						locked_by = op->client_id;
						break;
					case OP_UNLOCK:
						op->put_answer_to->comment = "successfully unlocked";
						locked_by = -1;
						break;
					case OP_INC:
						balance += op->value;
						op->put_answer_to->comment = "successfuly added";
						break;
					case OP_DEC:
						balance -= op->value;
						op->put_answer_to->comment = "successfully withdrawed";
						break;
				}
				fprintf(stderr, " - completed\n");
			}
			else {
				op->put_answer_to->comment = "balance not locked";

				fprintf(stderr, " - declined\n");
			}

			op->put_answer_to->status = is_performable;
			op->put_answer_to->value = balance;

			// free(op);

			pthread_cond_signal(&op->put_answer_to->cond);
			pthread_mutex_unlock(&op->put_answer_to->mutex);
		}
		else {
			push_op(&queue, op);

			fprintf(stderr, " - pushed to queue\n");
		}
	}
	return NULL;
}
Ejemplo n.º 2
0
static bool execute(char *buffer, bool *data)
{
    char *token, **ops, *o1, *o2;
    bool *output, res;
    int n_o, n_q, sz_o, sz_q;;

    sz_o = 8192;
    sz_q = 8192;
    ops = malloc(sz_q * sizeof(char *));
    output = malloc(sz_o * sizeof(bool));
    n_o = n_q = 0;


    for (token = strtok(buffer, " "); token; token = strtok(NULL, " ")) {
        if (strncmp(token, "b", 1) == 0) {
            push_bit(data[atoi(token + 1)], &output, &n_o, &sz_o);
        } else if (is_function(token)) {
            push_op(token, &ops, &n_q, &sz_q);
        } else if (strncmp(token, ",", 1) == 0) {
            while (strncmp(peek_op(ops, n_q), "(", 1) != 0) {
                token = pop_op(ops, &n_q);
                if (is_operator(token)) {
                    push_bit(operator(token, pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o);
                } else {
                    push_bit(function(token, output, &n_o), &output, &n_o, &sz_o);
                }
            }
        } else if (is_operator(token)) {
            o1 = token;
            while (peek_op(ops, n_q) && is_operator(peek_op(ops, n_q))) {
                o2 = peek_op(ops, n_q);
                if (operator_precedence(o1) <= operator_precedence(o2)) {
                    push_bit(operator(pop_op(ops, &n_q), pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o);
                } else {
                    break;
                }
            }
            push_op(o1, &ops, &n_q, &sz_q);
        } else if (strncmp(token, "(", 1) == 0) {
            push_op(token, &ops, &n_q, &sz_q);
        } else if (strncmp(token, ")", 1) == 0) {
            while (strncmp(peek_op(ops, n_q), "(", 1) != 0) {
                token = pop_op(ops, &n_q);
                if (is_operator(token)) {
                    push_bit(operator(token, pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o);
                } else {
                    push_bit(function(token, output, &n_o), &output, &n_o, &sz_o);
                }
            }

            token = pop_op(ops, &n_q); /* pop the left bracket */

            if (peek_op(ops, n_q) && is_function(peek_op(ops, n_q))) {
                push_bit(function(pop_op(ops, &n_q), output, &n_o), &output, &n_o, &sz_o);
            }
        } else {
            fprintf(stderr, "ERROR: unknown symbol: %s\n", token);
            exit(EXIT_FAILURE);
        }
    }

    while ((token = pop_op(ops, &n_q))) {
        if (is_operator(token)) {
            push_bit(operator(token, pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o);
        } else {
            push_bit(function(token, output, &n_o), &output, &n_o, &sz_o);
        }
    }

    res = output[0];

    free(output);
    free(ops);

    return res;
}
Ejemplo n.º 3
0
int
push_val(int type)
{
	unsigned int mul, val;
	int op;
	char c;

	val = 0;
	c = *expr;

	switch (type) {
	/* program counter */
	case T_PC:
		if (data_loccnt == -1)
			val = (loccnt + (page << 13));
		else
			val = (data_loccnt + (page << 13));
		expr++;
		break;

	/* char ascii value */
	case T_CHAR:
		expr++;
		val = *expr++;
		if ((*expr != c) || (val == 0)) {
			error("Syntax Error!");
			return (0);
		}
		expr++;
		break;

	/* symbol */
	case T_SYMBOL:
		/* extract it */
		if (!getsym())
			return (0);

		/* an user function? */
		if (func_look()) {
			if (!func_getargs())
				return (0);

			expr_stack[func_idx++] = expr;
			expr = func_ptr->line;
			return (1);
		}

		/* a predefined function? */
		op = check_keyword();
		if (op) {
			if (!push_op(op))
				return (0);
			else
				return (1);
		}

		/* search the symbol */
		expr_lablptr = stlook(1);

		/* check if undefined, if not get its value */
		if (expr_lablptr == NULL)
			return (0);
		else if (expr_lablptr->type == UNDEF)
			undef++;
		else if (expr_lablptr->type == IFUNDEF)
			undef++;
		else
			val = expr_lablptr->value;

		/* remember we have seen a symbol in the expression */
		expr_lablcnt++;
		break;

	/* binary number %1100_0011 */
	case T_BINARY:
		mul = 2;
		goto extract;

	/* hexa number $15AF */
	case T_HEXA:
		mul = 16;
		goto extract;

	/* decimal number 48 (or hexa 0x5F) */
	case T_DECIMAL:
		if ((c == '0') && (toupper(expr[1]) == 'X')) {
			mul = 16;
			expr++;
		}
		else {
			mul = 10;
			val = c - '0';
		}
		/* extract a number */
extract:
		for (;;) {
			expr++;
			c = *expr;

			if (isdigit(c))
				c -= '0';
			else if (isalpha(c)) {
				c = toupper(c);
				if (c < 'A' && c > 'F')
					break;
				else {
					c -= 'A';
					c += 10;
				}
			}
			else if (c == '_' && mul == 2)
				continue;
			else
				break;
			if (c >= mul)
				break;
			val = (val * mul) + c;
		}
		break;
	}

	/* check for too big expression */
	if (val_idx == 63) {
		error("Expression too complex!");
		return (0);
	}

	/* push the result on the value stack */
	val_idx++;
	val_stack[val_idx] = val;

	/* next must be an operator */
	need_operator = 1;

	/* ok */
	return (1);
}
Ejemplo n.º 4
0
static  int evaluate( char * * line, long *val )
{
    long        arg;
    char    *   ptr;
    char    *   str;
    char    *   endptr;
    int         ercode;
    operator *  op;
    int         expr_oper;              // looking for term or operator

    expr_oper = 0;
    coper     = 0;
    cvalue    = 0;
    nparens   = 0;
    ptr       = *line;

    while( *ptr ) {
        if( *ptr == ' ' ) {
            if( ignore_blanks ) {
                ptr++;
                continue;
            } else {
                break;
            }
        }
        switch( expr_oper ) {
        case 0:                         // look for term
            str = get_exp( ptr );

            if( str == NULL ) {         // nothing is error
                return( not_ok );
            }

            op = get_op( str );
            if( *(str +1) == NULC ) {
                if( NULL != op ) {
                    push_op( op->operc );
                    ptr++;
                    break;
                }

                if( (*str == '-' ) || (*str == '+' ) ) {
                    push_op(*str);
                    ++ptr;
                    break;
                }
            }

            arg = strtol( str, &endptr, 10 );
            if( (((arg == LONG_MIN) || (arg == LONG_MAX)) && errno == ERANGE)
                 || (str == endptr) ) {
                 return( not_ok );
            }

            push_val( arg );

            ptr += endptr - str;        // to the next unprocessed char

            expr_oper = 1;              // look for operator next
            break;

        case 1:                         // look for operator
            op = get_op( ptr );
            if( NULL == op ) {
                return( not_ok );
            }
            if( ')' == *ptr ) {
                ercode = do_paren();
                if( ok > ercode ) {
                    return( ercode );
                }
            } else {
                while( coper && op->priority <= get_prio_m1() ) {
                    do_expr();
                }
                push_op( op->operc );
                expr_oper = 0;      // look for term next
            }
            ptr++;
            break;
        }
    }

    while( 1 < cvalue ) {
        ercode = do_expr();
        if( ok > ercode )
             return ercode;
    }
    if( !coper ) {
        *line = ptr;                    // next scan position
        return( pop_val( val ) );       // no operations left return result
    } else {
        return( not_ok );
    }
}
Ejemplo n.º 5
0
Archivo: eval.c Proyecto: eldy/other
int evaluate(char *line, double *val)
//--------------------------------------------------------------------
// Evaluates an ASCII mathematical expression
// INPUT:  line:  String to evaluate
//         val:   Storage to receive double result
//   
// RETURN: SUCCESS =  0 if successful  
//         E_ERROR = -1 if syntax error  
//         R_ERROR = -2 if runtime error 
//         DUV_ZERO= -3 Division by 0    
// 
// Side effects: Removes all whitespace from the string and converts
//               it to U.C.
//--------------------------------------------------------------------
{
double arg;
char *ptr = line, *str, *endptr;
int ercode;
struct operator *op;

strupr(line);
rmallws(line);
state = op_sptr = arg_sptr = parens = 0;

while (*ptr)
      {
	    switch (state)
	    {
	    case 0:
		  if (NULL != (str = get_exp(ptr)))
		  {
			if (NULL != (op = get_op(str)) &&
			      strlen(str) == op->taglen)
			{
			      push_op(op->token);
			      ptr += op->taglen;
			      break;
			}

			if (SUCCESS == strcmp(str, "-"))
			{
			      push_op(*str);
			      ++ptr;
			      break;
			}

			if (SUCCESS == strcmp(str, "PI"))
			      push_arg(Pi);

			else
			{
			      if (0.0 == (arg = strtod(str, &endptr)) &&
				    NULL == strchr(str, '0'))
			      {
				    return E_ERROR;
			      }
			      push_arg(arg);
			}
			ptr += strlen(str);
		  }
		  else  return E_ERROR;

		  state = 1;
		  break;

	    case 1:
		  if (NULL != (op = get_op(ptr)))
		  {
			if (')' == *ptr)
			{
			      if (SUCCESS > (ercode = do_paren()))
				    return ercode;
			}
			else
			{
			      while (op_sptr &&
				    op->precedence <= getTOSprec())
			      {
				    do_op();
			      }
			      push_op(op->token);
			      state = 0;
			}

			ptr += op->taglen;
		  }
		  else  return E_ERROR;

		  break;
	    }
      }

      while (1 < arg_sptr)
      {
	    if (SUCCESS > (ercode = do_op()))
		  return ercode;
      }
      if (!op_sptr)
	    return pop_arg(val);
      else  return E_ERROR;
}
Ejemplo n.º 6
0
int
evaluate(int *ip, char last_char)
{
	int end, level;
	int op, type;
	int arg;
	int i;
	unsigned char c;

	end = 0;
	level = 0;
	undef = 0;
	op_idx = 0;
	val_idx = 0;
	value = 0;
	val_stack[0] = 0;
	need_operator = 0;
	expr_lablptr = NULL;
	expr_lablcnt = 0;
	op = OP_START;
	func_idx = 0;

	/* array index to pointer */
	expr = &prlnbuf[*ip];

	/* skip spaces */
cont:
	while (isspace(*expr))
		expr++;

	/* search for a continuation char */
	if (*expr == '\\') {
		/* skip spaces */
		i = 1;
		while (isspace(expr[i]))
			i++;

		/* check if end of line */
		if (expr[i] == ';' || expr[i] == '\0') {
			/* output */
			if (!continued_line) {
				/* replace '\' with three dots */
				strcpy(expr, "...");

				/* store the current line */
				strcpy(tmplnbuf, prlnbuf);
			}

			/* ok */
			continued_line++;

			/* read a new line */
			if (readline() == -1)
				return (0);

			/* rewind line pointer and continue */
			expr = &prlnbuf[SFIELD];
			goto cont;
		}
	}

	/* parser main loop */
	while (!end) {
		c = *expr;

		/* number */
		if (isdigit(c)) {
			if (need_operator)
				goto error;
			if (!push_val(T_DECIMAL))
				return (0);
		}

		/* symbol */
		else
		if (isalpha(c) || c == '_' || c == '.') {
			if (need_operator)
				goto error;
			if (!push_val(T_SYMBOL))
				return (0);
		}

		/* operators */
		else {
			switch (c) {
			/* function arg */
			case '\\':
				if (func_idx == 0) {
					error("Syntax error in expression!");
					return (0);
				}
				expr++;
				c = *expr++;
				if (c < '1' || c > '9') {
					error("Invalid function argument index!");
					return (0);
				}
				arg = c - '1';
				expr_stack[func_idx++] = expr;
				expr = func_arg[func_idx - 2][arg];
				break;

			/* hexa prefix */
			case '$':
				if (need_operator)
					goto error;
				if (!push_val(T_HEXA))
					return (0);
				break;

			/* character prefix */
			case '\'':
				if (need_operator)
					goto error;
				if (!push_val(T_CHAR))
					return (0);
				break;

			/* round brackets */
			case '(':
				if (need_operator)
					goto error;
				if (!push_op(OP_OPEN))
					return (0);
				level++;
				expr++;
				break;
			case ')':
				if (!need_operator)
					goto error;
				if (level == 0)
					goto error;
				while (op_stack[op_idx] != OP_OPEN) {
					if (!do_op())
						return (0);
				}
				op_idx--;
				level--;
				expr++;
				break;

			/* not equal, left shift, lower, lower or equal */
			case '<':
				if (!need_operator)
					goto error;
				expr++;
				switch (*expr) {
				case '>':
					op = OP_NOT_EQUAL;
					expr++;
					break;
				case '<':
					op = OP_SHL;
					expr++;
					break;
				case '=':
					op = OP_LOWER_EQUAL;
					expr++;
					break;
				default:
					op = OP_LOWER;
					break;
				}
				if (!push_op(op))
					return (0);
				break;

			/* right shift, higher, higher or equal */
			case '>':
				if (!need_operator)
					goto error;
				expr++;
				switch (*expr) {
				case '>':
					op = OP_SHR;
					expr++;
					break;
				case '=':
					op = OP_HIGHER_EQUAL;
					expr++;
					break;
				default:
					op = OP_HIGHER;
					break;
				}
				if (!push_op(op))
					return (0);
				break;

			/* equal */
			case '=':
				if (!need_operator)
					goto error;
				if (!push_op(OP_EQUAL))
					return (0);
				expr++;
				break;

			/* one complement */
			case '~':
				if (need_operator)
					goto error;
				if (!push_op(OP_COM))
					return (0);
				expr++;
				break;

			/* sub, neg */
			case '-':
				if (need_operator)
					op = OP_SUB;
				else
					op = OP_NEG;
				if (!push_op(op))
					return (0);
				expr++;
				break;

			/* not, not equal */
			case '!':
				if (!need_operator)
					op = OP_NOT;
				else {
					op = OP_NOT_EQUAL;
					expr++;
					if (*expr != '=')
						goto error;
				}
				if (!push_op(op))
					return (0);
				expr++;
				break;

			/* binary prefix, current PC */
			case '%':
			case '*':
				if (!need_operator) {
					if (c == '%')
						type = T_BINARY;
					else
						type = T_PC;
					if (!push_val(type))
						return (0);
					break;
				}

			/* modulo, mul, add, div, and, xor, or */
			case '+':
			case '/':
			case '&':
			case '^':
			case '|':
				if (!need_operator)
					goto error;
				switch (c) {
				case '%': op = OP_MOD; break;
				case '*': op = OP_MUL; break;
				case '+': op = OP_ADD; break;
				case '/': op = OP_DIV; break;
				case '&': op = OP_AND; break;
				case '^': op = OP_XOR; break;
				case '|': op = OP_OR;  break;
				}
				if (!push_op(op))
					return (0);
				expr++;
				break;

			/* skip immediate operand prefix if in macro */
			case '#':
				if (expand_macro)
					expr++;
				else
					end = 3;
				break;

			/* space or tab */
			case ' ':
			case '\t':
				expr++;
				break;

			/* end of line */
			case '\0':
				if (func_idx) {
					func_idx--;
					expr = expr_stack[func_idx];
					break;
				}
			case ';':
				end = 1;
				break;
			case ',':
				end = 2;
				break;
			default:
				end = 3;
				break;
			}
		}
	}

	if (!need_operator)
		goto error;
	if (level != 0)
		goto error;
	while (op_stack[op_idx] != OP_START) {
		if (!do_op())
			return (0);
	}

	/* get the expression value */
	value = val_stack[val_idx];

	/* any undefined symbols? trap that if in the last pass */
	if (undef) {
		if (pass == LAST_PASS)
			error("Undefined symbol in operand field!");
	}

	/* check if the last char is what the user asked for */
	switch (last_char) {
	case ';':
		if (end != 1)
			goto error;
		expr++;
		break;
	case ',':
		if (end != 2) {
			error("Argument missing!");
			return (0);
		}
		expr++;
		break;
	}

	/* convert back the pointer to an array index */
	*ip = expr - prlnbuf;

	/* ok */
	return (1);

	/* syntax error */
error:
	error("Syntax error in expression!");
	return (0);
}
Ejemplo n.º 7
0
static inline void push_increase_dlevel(op_stack_t *stack) {
  push_op(stack, INCREASE_DLEVEL);
}
Ejemplo n.º 8
0
static inline void push_push(op_stack_t *stack) {
  push_op(stack, PUSH);
}
Ejemplo n.º 9
0
static inline void push_propagate(op_stack_t *stack) {
  push_op(stack, PROPAGATE);
}
Ejemplo n.º 10
0
/* Parse command-line options. */
static bool
parse_options (int argc, char *argv[])
{
  int opt;
  operation_t op;
  int i_blocksize = 0;

  static const char helpText[] =
    "Usage: %s [OPTION...]\n"
    " Issues libcdio Multimedia commands. Operations occur in the order\n"
    " in which the options are given and a given operation may appear\n"
    " more than once to have it run more than once.\n"
    "options: \n"
    "  -b, --blocksize[=INT]           set blocksize. If no block size or a \n"
    "                                  zero blocksize is given we return the\n"
    "                                  current setting.\n"
    "  -C, --drive-cap [6|10]          print mode sense 2a data\n"
    "                                  using 6-byte or 10-byte form\n"
    "  -c, --close drive               close drive via ALLOW_MEDIUM_REMOVAL\n"
    "  -e, --eject [drive]             eject drive via ALLOW_MEDIUM_REMOVAL\n"
    "                                  and a MMC START/STOP command\n"
    "  -I, --idle                      set CD-ROM to idle or power down\n"
    "                                  via MMC START/STOP command\n"
    "  -i, --inquiry                   print HW info via INQUIRY\n"
    "  -m, --mcn                       get media catalog number (AKA UPC)\n"
    "  -s, --speed-KB=INT              Set drive speed to SPEED K bytes/sec\n"
    "                                  Note: 1x = 176 KB/s          \n"
    "  -S, --speed-X=INT               Set drive speed to INT X\n"
    "                                  Note: 1x = 176 KB/s          \n"
    "  -V, --version                   display version and copyright information\n"
    "                                  and exit\n"
    "\n"
    "Help options:\n"
    "  -?, --help                      Show this help message\n"
    "  --usage                         Display brief usage message\n";
  
  static const char usageText[] =
    "Usage: %s [-b|--blocksize[=INT]] [-m|--mcn]\n"
    "        [-I|--idle] [-I|inquiry] [-m[-s|--speed-KB INT]\n"
    "        [-V|--version] [-?|--help] [--usage]\n";
  
  /* Command-line options */
  static const char optionsString[] = "b::c:C::e::Iis:V?";
  const struct option optionsTable[] = {
  
    {"blocksize", optional_argument, &i_blocksize, 'b' },
    {"close", required_argument, NULL, 'c'},
    {"drive-cap", optional_argument, NULL, 'C'},
    {"eject", optional_argument, NULL, 'e'},
    {"idle", no_argument, NULL, 'I'},
    {"inquiry", no_argument, NULL, 'i'},
    {"mcn",   no_argument, NULL, 'm'},
    {"speed-KB", required_argument, NULL, 's'},
    {"speed-X",  required_argument, NULL, 'S'},

    {"version", no_argument, NULL, 'V'},
    {"help", no_argument, NULL, '?' },
    {"usage", no_argument, NULL, OPT_USAGE },
    { NULL, 0, NULL, 0 }
  };
  
  while ((opt = getopt_long(argc, argv, optionsString, optionsTable, NULL)) >= 0)
    switch (opt)
      {
      case 'b': 
	op.op = OP_BLOCKSIZE;
	op.arg.i_num = i_blocksize;
	push_op(&op);
	break;
      case 'C': 
	op.arg.i_num = optarg ? atoi(optarg) : 10;
	switch (op.arg.i_num) {
	case 10:
	    op.op = OP_MODE_SENSE_2A;
	  op.arg.i_num = 10;
	  push_op(&op);
	  break;
	case 6:
	  op.op = OP_MODE_SENSE_2A;
	  op.arg.i_num = 6;
	  push_op(&op);
	  break;
	default:
	  report( stderr, "%s: Expecting 6 or 10 or nothing\n", program_name );
	}
	break;
      case 'c': 
	op.op = OP_CLOSETRAY;
	op.arg.psz = strdup(optarg);
	push_op(&op);
	break;
      case 'e': 
	op.op = OP_EJECT;
	op.arg.psz=NULL;
	if (optarg) op.arg.psz = strdup(optarg);
	push_op(&op);
	break;
      case 'i': 
	op.op = OP_INQUIRY;
	op.arg.psz=NULL;
	push_op(&op);
	break;
      case 'I': 
	op.op = OP_IDLE;
	op.arg.psz=NULL;
	push_op(&op);
	break;
      case 'm': 
	op.op = OP_MCN;
	op.arg.psz=NULL;
	push_op(&op);
	break;
      case 's': 
	op.op = OP_SPEED;
	op.arg.i_num=atoi(optarg);
	push_op(&op);
	break;
      case 'S': 
	op.op = OP_SPEED;
	op.arg.i_num=176 * atoi(optarg);
	push_op(&op);
	break;
      case 'V':
        print_version(program_name, VERSION, 0, true);
	free(program_name);
        exit (EXIT_SUCCESS);
        break;

      case '?':
	fprintf(stdout, helpText, program_name);
	free(program_name);
	exit(EXIT_INFO);
	break;
	
      case OPT_USAGE:
	fprintf(stderr, usageText, program_name);
	free(program_name);
	exit(EXIT_FAILURE);
	break;

      case OPT_HANDLED:
	break;
      i_blocksize = 0;
      }

  if (optind < argc) {
    const char *remaining_arg = argv[optind++];

    if (source_name != NULL) {
      report( stderr, "%s: Source specified in option %s and as %s\n", 
	      program_name, source_name, remaining_arg );
      free(program_name);
      exit (EXIT_FAILURE);
    }

    source_name = strdup(remaining_arg);
      
    if (optind < argc) {
      report( stderr, "%s: Source specified in previously %s and %s\n", 
	      program_name, source_name, remaining_arg );
      free(program_name);
      exit (EXIT_FAILURE);
    }
  }
  
  return true;
}
Ejemplo n.º 11
0
static int parse_token_list() {
    token_list *tok;
    tok = tl;
    ops = new_op_list();
    while( tok != NULL ) {
        switch( tok->t ) {
            /* 3-register instructions */
            case token_add:
                tok = three_reg_op(tok, op_add); break;
            case token_and:
                tok = three_reg_op(tok, op_and); break;
            case token_arccos:
                tok = three_reg_op(tok, op_arccos); break;
            case token_arcsin:
                tok = three_reg_op(tok, op_arcsin); break;
            case token_arctan:
                tok = three_reg_op(tok, op_arctan); break;
            case token_cos:
                tok = three_reg_op(tok, op_cos); break;
            case token_dist:
                tok = three_reg_op(tok, op_dist); break;
            case token_div:
                tok = three_reg_op(tok, op_div); break;
            case token_eq:
                tok = three_reg_op(tok, op_eq); break;
            case token_gt:
                tok = three_reg_op(tok, op_gt); break;
            case token_lt:
                tok = three_reg_op(tok, op_lt); break;
            case token_max:
                tok = three_reg_op(tok, op_max); break;
            case token_min:
                tok = three_reg_op(tok, op_min); break;
            case token_mod:
                tok = three_reg_op(tok, op_mod); break;
            case token_mul:
                tok = three_reg_op(tok, op_mul); break;
            case token_ne:
                tok = three_reg_op(tok, op_ne); break;
            case token_or:
                tok = three_reg_op(tok, op_or); break;
            case token_sin:
                tok = three_reg_op(tok, op_sin); break;
            case token_sub:
                tok = three_reg_op(tok, op_sub); break;
            case token_tan:
                tok = three_reg_op(tok, op_tan); break;
            case token_xor:
                tok = three_reg_op(tok, op_xor); break;
            /* 2-register instructions */
            case token_abs:
                tok = two_reg_op(tok, op_abs); break;
            case token_chs:
                tok = two_reg_op(tok, op_chs); break;
            case token_mov:
                tok = two_reg_op(tok, op_mov); break;
            case token_not:
                tok = two_reg_op(tok, op_not); break;
            case token_setparam:
                tok = two_reg_op(tok, op_setparam); break;
            case token_sqrt:
                tok = two_reg_op(tok, op_sqrt); break;
            case token_vrecall:
                tok = two_reg_op(tok, op_vrecall); break;
            case token_vstore:
                tok = two_reg_op(tok, op_vstore); break;
            /* 1-register instructions */
            case token_icon:
                tok = one_reg_op(tok, op_icon); break;
            case token_peek:
                tok = one_reg_op(tok, op_peek); break;
            case token_pop:
                tok = one_reg_op(tok, op_pop); break;
            case token_print:
                tok = one_reg_op(tok, op_print); break;
            case token_random:
                tok = one_reg_op(tok, op_random); break;
            case token_roll:
                tok = one_reg_op(tok, op_roll); break;
            case token_sound:
                tok = one_reg_op(tok, op_sound); break;
            case token_test:
                tok = one_reg_op(tok, op_test); break;
            case token_debug:
                tok = one_reg_op(tok, op_debug); break;
            /* 0-register instructions */
            case token_beep:
                tok = zero_reg_op(tok, op_beep); break;
            case token_drop:
                tok = zero_reg_op(tok, op_drop); break;
            case token_dropall:
                tok = zero_reg_op(tok, op_dropall); break;
            case token_dup:
                tok = zero_reg_op(tok, op_dup); break;
            case token_end:
                tok = zero_reg_op(tok, op_end); break;
            case token_recall:
                tok = zero_reg_op(tok, op_recall); break;
            case token_return:
                tok = zero_reg_op(tok, op_return); break;
            case token_store:
                tok = zero_reg_op(tok, op_store); break;
            case token_swap:
                tok = zero_reg_op(tok, op_swap); break;
            case token_sync:
                tok = zero_reg_op(tok, op_sync); break;
            case token_nop:
                tok = zero_reg_op(tok, op_nop); break;
            /* Branching instructions */
            case token_if:
            case token_ife:
            case token_ifg:
            case token_ifeg:
            case token_jump:
            case token_call:
                tok = branch_op(tok); break;
            /* Push instruction */
            case token_push:
                tok = push_op(tok); break;
            /* Labels */
            case token_label:
                tok = create_label(tok); break;
            /* Default: Syntax error */
            default:
                /* TODO: error and die */
                error_line = tok->line_number;
                error = err_unknown_token;
                return error;
        }
    }
    return error;
}
Ejemplo n.º 12
0
/* Calcola e restituisce il risultato di un'espressione in forma infissa */
double EvalInfix(const char *strExpression, char * strError)
{
    Token tok;
    Token tok_temp;
    double left, right;
    double dblRet;

    strcpy(strError, "");

    tok_temp.Type = EOL;
    tok_temp.str[0] = '@';
    tok_temp.str[1] = '\0';
    push_op(tok_temp, strError);
    if ( strError[0] != '\0' )
        return 0.0;

    left = right = 0.0;
    while ( (PreviousTokenType = GetNextToken(strExpression, &tok, TRUE)) != EOL )
    {
        if ( tok.Type == UNKNOWN )
        {
            sprintf(strError, "Error: invalid token: %s\n", tok.str);
            return 0.0;
        }
        else if ( tok.Type == VALUE )
        {
            push_val(tok.Value, strError);
            if ( strError[0] != '\0' )
                return 0.0;
        }
        else if ( tok.Type == OPAREN || tok.Type == UMINUS || tok.Type == UPLUS )
        {
            push_op(tok, strError);
            if ( strError[0] != '\0' )
                return 0.0;
        }
        else if ( tok.Type == CPAREN )
        {
            while ( top_op(strError).Type != OPAREN )
            {
                if ( strError[0] != '\0' )
                    return 0.0;

                tok_temp = pop_op(strError);
                if ( strError[0] != '\0' )
                    return 0.0;

                if ( (tok_temp.Type == EOL) || (is_empty_op()) )
                {
                    sprintf(strError, "Error: unbalanced brackets.\n");
                    return 0.0;
                }

                right = pop_val(strError);
                if ( strError[0] != '\0' )
                    return 0.0;

                if ( tok_temp.Type != UMINUS )
                {
                    left = pop_val(strError);
                    if ( strError[0] != '\0' )
                        return 0.0;

                    dblRet = BinaryOperation(left, right, tok_temp.str[0], strError);
                    if ( strError[0] != '\0' )
                        return 0.0;

                    push_val(dblRet, strError);
                    if ( strError[0] != '\0' )
                        return 0.0;
                }
                else
                {
                    push_val( -1 * right, strError );
                    if ( strError[0] != '\0' )
                        return 0.0;
                }
            }
            pop_op(strError);
            if ( strError[0] != '\0' )
                return 0.0;
        }
        else
        {
            while ( PREC_TABLE[ top_op(strError).Type ].topOfStack >= PREC_TABLE[ tok.Type ].inputSymbol )
            {
                if ( strError[0] != '\0' )
                    return 0.0;

                if ( top_op(strError).Type != UMINUS && top_op(strError).Type != UPLUS )
                {
                    if ( strError[0] != '\0' )
                        return 0.0;

                    right = pop_val(strError);
                    if ( strError[0] != '\0' )
                        return 0.0;

                    left = pop_val(strError);
                    if ( strError[0] != '\0' )
                        return 0.0;

                    tok_temp = pop_op(strError);
                    if ( strError[0] != '\0' )
                        return 0.0;

                    dblRet = BinaryOperation(left, right, tok_temp.str[0], strError);
                    if ( strError[0] != '\0' )
                        return 0.0;

                    push_val(dblRet, strError);
                    if ( strError[0] != '\0' )
                        return 0.0;
                }
                else
                {
                    if ( top_op(strError).Type == UMINUS )
                    {
                        if ( strError[0] != '\0' )
                            return 0.0;

                        right = pop_val(strError);
                        if ( strError[0] != '\0' )
                            return 0.0;

                        pop_op(strError);
                        if ( strError[0] != '\0' )
                            return 0.0;

                        push_val(-1 * right, strError);
                        if ( strError[0] != '\0' )
                            return 0.0;
                    }
                    else
                    {
                        pop_op(strError);
                        if ( strError[0] != '\0' )
                            return 0.0;
                    }
                }
            }

            if ( tok.Type != EOL )
            {
                push_op(tok, strError);
                if ( strError[0] != '\0' )
                    return 0.0;
            }
        }
    }

    while ( 1 )
    {
        tok_temp = pop_op(strError);
        if ( strError[0] != '\0' )
            return 0.0;

        if ( tok_temp.Type == EOL )
            break;

        if ( tok_temp.Type != UPLUS )
        {
            right = pop_val(strError);
            if ( strError[0] != '\0' )
                return 0.0;
        }

        if ( tok_temp.Type != UMINUS && tok_temp.Type != UPLUS )
        {
            left = pop_val(strError);
            if ( strError[0] != '\0' )
                return 0.0;

            dblRet = BinaryOperation(left, right, tok_temp.str[0], strError);
            if ( strError[0] != '\0' )
                return 0.0;

            push_val(dblRet, strError);
            if ( strError[0] != '\0' )
                return 0.0;
        }
        else
        {
            push_val( -1 * right, strError );
            if ( strError[0] != '\0' )
                return 0.0;
        }
    }

    dblRet = pop_val(strError);
    if ( strError[0] != '\0' )
        return 0.0;

    if ( is_empty_val() )
    {
        return dblRet;
    }
    else
    {
        sprintf(strError, "Error: malformed expression.\n");
        return 0.0;
    }
}
Ejemplo n.º 13
0
// Solves the equation in 'str'
// returns SUCCESS if equation was solved
// returns FAIL if equation couldn't be solved
// Solution returned in 'answer'
int solve_equation(char* str, int *answer)
{
	int j = 0;
	int ret;
	char curr;

	// intialize stack
	curr_num_stack = -1;
	curr_op_stack = -1;

	while (str[j] != 0)
	{
		curr = str[j];
		// walk through the equation
		if (curr <= '9' && curr >= '0')
		{
			char t;
			int is_neg = 0;
			int val;
			// get the number (could be any number of spots)
			// this is a number, push it on the stack

			ret = peek_op(&t);
			if (ret == SUCCESS && t == '-')
			{
				if(pop_op(&t) != SUCCESS) return FAIL;
				push_op('+');
				is_neg = 1;
			}
			int moved = 0;
			val = stoi(str+j, &moved);
	
			if (is_neg)
				val *= -1;
			is_neg = 0;

			push_num(val);
			//tmp = get_str_end(str+j);
			j += moved; 
			continue;		
		}
		if (curr == '(')
		{
			push_op(str[j]);
			j++;
			continue;
		}
		if (curr == ')')
		{
			if (satisfy_paren() != SUCCESS) return FAIL;
			j++;
			continue;
		}
		if (curr == '+' || curr == '-')
		{
			char p_op;
			ret = peek_op(&p_op);
			if (ret == SUCCESS && (p_op == '+' || p_op == '-' || p_op == '*' || p_op == '/'))
			{
				char prev_op;
				int larg, rarg, answer = 0;
				if (pop_num(&rarg)!= SUCCESS) return FAIL;
				if (pop_num(&larg)!= SUCCESS) return FAIL;
				if (pop_op(&prev_op)!= SUCCESS) return FAIL;
				if (evaluate(larg, prev_op, rarg, &answer) != SUCCESS) return FAIL;
				push_num(answer);
			}
			push_op(str[j]);
			j++;
			continue;
		}
		if (curr == '*' || curr == '/')
		{
			char prev_op;
			ret = peek_op(&prev_op);
			if (ret == SUCCESS && (prev_op == '*' || prev_op == '/'))
			{
				int larg, rarg, answer = 0;
				if (pop_num(&rarg)!= SUCCESS) return FAIL;
				if (pop_num(&larg)!= SUCCESS) return FAIL;
				if (pop_op(&prev_op)!= SUCCESS) return FAIL;
				if (evaluate(larg, prev_op, rarg, &answer) != SUCCESS) return FAIL;
				push_num(answer);
			}
			push_op(str[j]);
			j++;
			continue;
		}
		return FAIL; // Invalid input. 
			
	}

	int b,a, tmp;
	pop_num(&b);
	while(curr_op_stack != -1)
	{
		if (pop_num(&a)!= SUCCESS) return FAIL;
		if (pop_op(&curr)!= SUCCESS) return FAIL;
		if (evaluate(a,curr,b, &tmp)!= SUCCESS) return FAIL;
		b = tmp;
	}
	*answer = b;
		
	return SUCCESS;
}