Example #1
0
/* 运算时  数据栈出栈两次   操作符栈出栈一次 
 * 运算完之后的结果压栈
 * */
static int do_operate(struct calc *calc)
{
	num_t a, b;
	char c;

	if (NUM_POP(b) < 0) {
		fprintf(stderr,"Error: num pop failed.\n");
		return -1;
	}
	if (NUM_POP(a) < 0) {
		fprintf(stderr,"Error: num pop failed.\n");
		return -1;
	}
	if (OPR_POP(c) < 0) {
		fprintf(stderr,"Error: opr pop failed.\n");
		return -2;
	}

	num_t res = 0;
	switch(c) {
		case '+': res = a + b; break;
		case '-': res = a - b; break;
		case '*': res = a * b; break;
		case '/': res = a / b; break;
		case '%': res = a % b; break;
		default : break;
	}

#ifdef _DEBUG
	printf("DEBUG %d %c %d = %d\n",a, c, b, res);
#endif
	NUM_PUSH(res);

	return 0;
}
Example #2
0
/* Clean up after enumerating an image */
static int
image_cleanup(i_ctx_t *i_ctx_p)
{
    es_ptr ep_top = esp + NUM_PUSH(EBOT_NUM_SOURCES(esp)->value.intval);
    gs_image_enum *penum = r_ptr(ep_top, gs_image_enum);
    
    return gs_image_cleanup_and_free_enum(penum, igs);
}
Example #3
0
static int opr_handle(struct calc_info *info)
{
	assert(info != NULL);
	
	char c = *info->cur;

	if (info->flag == NUM) {
		info->flag = OPR;
	} else {
		switch (c) {
			case '+':
				goto out;
				break;
			case '-':
				//FIXME 负号的处理
				{
				  num_t zero = 0;
				  NUM_PUSH(zero);
				  OPR_PUSH(c);
				  goto out;	
				}
				break;
			default: 
				fprintf(stderr, "免费版不支持多个运算符\n");
				break;
		}
	}

	//1. 入栈的两种情况: a) 空栈  b)运算符优先级高于栈顶运算符
	
	if (OPR_IS_EMPTY) {
		OPR_PUSH(c);
	} else {
		char top_c;
		while (1) {
			//a 空栈
			if (OPR_TOP(top_c) < 0) {
				OPR_PUSH(c);
				break;
			}
			//b 优先级高于栈顶
			if (opr2level(c) > opr2level(top_c)) {
				OPR_PUSH(c);
				break;
			} else {
				if (do_stack(info) < 0) {
					fprintf(stderr,"do_stack failed\n");
					goto err_do_stack;
				}
			}
		}
	}
out:	
	return 0;
err_do_stack:
	return -1;
}
Example #4
0
static int opr_handler(struct calc *calc)
{
	assert(calc != NULL);
	char c = *calc->cur;
	int zero = 0;
	if (calc->pre_flag == F_NUM) {
		calc->pre_flag = F_OPR;
	} else if (calc->pre_flag == F_OPR) {
		if (c == '-') {
			NUM_PUSH(zero);
			OPR_PUSH(c);
			calc->pre_flag = F_OPR;
			return 0;
		} else if (c == '+') {
			return 0;
		}
	} else {
		fprintf(stderr, "unknow character\n");
		return -2;
	}

	/* 如果操作符栈是空栈的话就压栈 */
	if (STACK_IS_EMPTY(calc->opr)) {
		OPR_PUSH(c);
		return 0;
	}

	/* 如果操作符栈非空, 且该操作符优先级高于栈顶运算符就压栈 */
	char top_c = 0;
	if (OPR_TOP(top_c) < 0) {
		fprintf(stderr, "Error: opr top failed.\n");
		return -1;
	}
	
	while(1) {
		if (opr2level(c) > opr2level(top_c) || STACK_IS_EMPTY(calc->opr)) {
			OPR_PUSH(c);
			return 0;
		}
		if (do_operate(calc) < 0) {
			fprintf(stderr, "Error: do operate failed.\n");
			return -1;
		}
		if ( !STACK_IS_EMPTY(calc->opr) && OPR_TOP(top_c) < 0) {
			fprintf(stderr, "Error: while opr top failed.\n");
			return -1;
		}
	}
	return 0;
}
Example #5
0
static int num_handle(struct calc_info *info)
{
	num_t  n =  *info->cur - '0';
	num_t  prev_n = 0;
	if (info->flag == OPR) {
		info->flag = NUM;
	} else {
		NUM_POP(prev_n);
		n += prev_n * 10;
	}
	
	//info->num->push(info->num, &n, sizeof(n));
	NUM_PUSH(n);

	return 0;
}
Example #6
0
static int num_handler(struct calc *calc)
{
	num_t n = 0;
	num_t m = 0;
	n = *calc->cur - '0';
	if (calc->pre_flag == F_NUM) {
		if (NUM_POP(m) < 0) {
			fprintf(stderr, "num pop failed.\n");
			return -1;
		}
		n += m * 10;
	} else if (calc->pre_flag == F_OPR) {
		calc->pre_flag = F_NUM;
	} else {
		fprintf(stderr, "unkown character\n");
		return -2;
	}

	NUM_PUSH(n);
	return 0;
}
Example #7
0
static int opr_advance(struct calc *calc)
{
	char c = *calc->cur;
	int zero = 0;
	
	if (calc->pre_flag == F_NUM) {
		calc->pre_flag = F_OPR;
	} else if (calc->pre_flag == F_OPR) {
		if (c == '-') {
			NUM_PUSH(zero);
			OPR_PUSH(c);
			calc->pre_flag = F_OPR;
			return 0;
		} else if (c == '+') {
			return 0;
		} else if (c == '*') {
			if (OPR_POP(c)) {
				fprintf(stderr, "Error: opr pop error\n");
				return -1;
			}
			c = '^';
			OPR_PUSH(c);
			return 0;
		} else if (c == '/') {
			if (OPR_POP(c)) {
				fprintf(stderr, "Error: opr pop error\n");
				return -1;
			}
			c = '#';
			OPR_PUSH(c);
			return 0;

		}
	} else {
		fprintf(stderr, "unknow character\n");
		return -2;
	}
	return 0;
}
Example #8
0
/* This may still encounter a RemapColor callback. */
static int
image_string_continue(i_ctx_t *i_ctx_p)
{
    gs_image_enum *penum = r_ptr(esp, gs_image_enum);
    int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
    gs_const_string sources[gs_image_max_planes];
    uint used[gs_image_max_planes];

    /* Pass no data initially, to find out how much is retained. */
    memset(sources, 0, sizeof(sources[0]) * num_sources);
    for (;;) {
	int px;
	int code = gs_image_next_planes(penum, sources, used);

	if (code == e_RemapColor)
	    return code;
    stop_now:
	if (code) {		/* Stop now. */
	    esp -= NUM_PUSH(num_sources);
	    image_cleanup(i_ctx_p);
	    return (code < 0 ? code : o_pop_estack);
	}
	for (px = 0; px < num_sources; ++px)
	    if (sources[px].size == 0) {
		const ref *psrc = ETOP_SOURCE(esp, px);
		uint size = r_size(psrc);

		if (size == 0) {	    /* empty source */
		    code = 1;
		    goto stop_now;
                }
		sources[px].data = psrc->value.bytes;
		sources[px].size = size;
	    }
    }
}
Example #9
0
/*出栈
 1. 数字栈取两次
 2. 运算符中取一次
 3. 运算
 4. 再把结果写入数字栈
 */
static int do_stack(struct calc_info *info)
{
	assert(info != NULL);
	
	num_t a, b, ret;
	char opr;
	
	if (NUM_POP(b) < 0) {
		fprintf(stderr, "num_pop failed\n");
		goto err_num_pop;
	}
	
	if (NUM_POP(a) < 0) {
		fprintf(stderr, "num_pop failed\n");
		goto err_num_pop;
	}

	if (OPR_POP(opr) < 0) {
		fprintf(stderr, "opr_pop failed\n");
		goto err_opr_pop;
	}

	switch (opr) {
		case '+':
			ret = a + b;
			break;
		case '-':
			ret = a - b;
			break;
		case '*':
			ret = a * b;
			break;
		case '/':
			if (b == 0) {
				fprintf(stderr, "不能除0\n");
				goto err_divd_zero;
			}
			ret = a / b;
			break;
		case '%':
			ret = a % b;
			break;
		default:
			fprintf(stderr,"取出不支持的运算符:'%c'\n", opr);
			break;
	}
#ifdef  DEBUG
	printf("%d %c %d = %d\n", a, opr, b, ret);
#endif

	NUM_PUSH(ret);

	return 0;

err_num_pop:
	return -1;
err_opr_pop:
	return -2;
err_divd_zero:
	return -3;
}
Example #10
0
/* Pop all the control information off the e-stack. */
static es_ptr
zimage_pop_estack(es_ptr tep)
{
    return tep - NUM_PUSH(ETOP_NUM_SOURCES(tep)->value.intval);
}
Example #11
0
static int
zimage_data_setup(i_ctx_t *i_ctx_p, const gs_pixel_image_t * pim,
		  gx_image_enum_common_t * pie, const ref * sources, int npop)
{
    int num_sources = pie->num_planes;
    int inumpush = NUM_PUSH(num_sources);
    int code;
    gs_image_enum *penum;
    int px;
    const ref *pp;
    bool string_sources = true;

    check_estack(inumpush + 2);	/* stuff above, + continuation + proc */
    make_int(EBOT_NUM_SOURCES(esp), num_sources);
    /*
     * Note that the data sources may be procedures, strings, or (Level
     * 2 only) files.  (The Level 1 reference manual says that Level 1
     * requires procedures, but Adobe Level 1 interpreters also accept
     * strings.)  The sources must all be of the same type.
     *
     * The Adobe documentation explicitly says that if two or more of the
     * data sources are the same or inter-dependent files, the result is not
     * defined.  We don't have a problem with the bookkeeping for
     * inter-dependent files, since each one has its own buffer, but we do
     * have to be careful if two or more sources are actually the same file.
     * That is the reason for the aliasing information described above.
     */
    for (px = 0, pp = sources; px < num_sources; px++, pp++) {
	es_ptr ep = EBOT_SOURCE(esp, px);

	make_int(ep + 1, 1);	/* default is no aliasing */
	switch (r_type(pp)) {
	    case t_file:
		if (!level2_enabled)
		    return_error(e_typecheck);
		/* Check for aliasing. */
		{
		    int pi;

		    for (pi = 0; pi < px; ++pi)
			if (sources[pi].value.pfile == pp->value.pfile) {
			    /* Record aliasing */
			    make_int(ep + 1, -pi);
			    EBOT_SOURCE(esp, pi)[1].value.intval++;
			    break;
			}
		}
		string_sources = false;
		/* falls through */
	    case t_string:
		if (r_type(pp) != r_type(sources)) {
    		    if (pie != NULL)
		        gx_image_end(pie, false);    /* Clean up pie */
		    return_error(e_typecheck);
		}
		check_read(*pp);
		break;
	    default:
		if (!r_is_proc(sources)) {
    		    static const char ds[] = "DataSource";
                    if (pie != NULL)
                        gx_image_end(pie, false);    /* Clean up pie */
                    gs_errorinfo_put_pair(i_ctx_p, ds, sizeof(ds) - 1, pp);
		    return_error(e_typecheck);
		}
		check_proc(*pp);
		string_sources = false;
	}
	*ep = *pp;
    }
    /* Always place the image enumerator into local memory,
       because pie may have local objects inherited from igs,
       which may be local when the current allocation mode is global. 
       Bug 688140. */
    if ((penum = gs_image_enum_alloc(imemory_local, "image_setup")) == 0)
	return_error(e_VMerror);
    code = gs_image_enum_init(penum, pie, (const gs_data_image_t *)pim, igs);
    if (code != 0 || (pie->skipping && string_sources)) {		/* error, or empty image */
	int code1 = gs_image_cleanup_and_free_enum(penum, igs);

	if (code >= 0)		/* empty image */
	    pop(npop);
	if (code >= 0 && code1 < 0)
	    code = code1;
	return code;
    }
    push_mark_estack(es_other, image_cleanup);
    esp += inumpush - 1;
    make_int(ETOP_PLANE_INDEX(esp), 0);
    make_int(ETOP_NUM_SOURCES(esp), num_sources);
    make_struct(esp, avm_local, penum);
    switch (r_type(sources)) {
	case t_file:
	    push_op_estack(image_file_continue);
	    break;
	case t_string:
	    push_op_estack(image_string_continue);
	    break;
	default:		/* procedure */
	    push_op_estack(image_proc_process);
	    break;
    }
    pop(npop);
    return o_push_estack;
}
Example #12
0
int eval_uint32(value_t * val, int argc, char * argv[])
{
	value_t tmp;
	uint32_t num_stack[EVAL_STACK_SIZE];
	char op_stack[EVAL_STACK_SIZE];
	int op_cnt = 0;
	int num_cnt = 0;
	char * cp;
	uint32_t x;
	uint32_t y;
	int op;
	int c1;
	int c2;
	int n;
	bool need_val;

	DCC_LOG1(LOG_TRACE, "argc:%d", argc);

	if (val == NULL)
		return -1;

	if (argc == 0)
		return -2;
	
	op = 0;
	need_val = true;

	for (n = 0; n < argc; n++) {
		/* get token */
		cp = argv[n];
	
		/* evaluate token */
		c1 = cp[0];
		c2 = cp[1];
		if (need_val) {
			/* alternate between operators and values */
			need_val = false;
			if ((c1 == '-') && (c2 >= '0') && (c2 <= '9')) {
				x = -strtoul(++cp, NULL, 0);
			} else if ((c1 == '+') && (c2 >= '0') && (c2 <= '9')) {
				x = strtoul(++cp, NULL, 0);
			} else if ((c1 >= '0') && (c1 <= '9')) {
				x = strtoul(cp, NULL, 0);
			} else if (((c1 >= 'a') && (c1 <= 'z')) || 
					   ((c1 >= 'A') && (c1 <= 'Z'))) {
				var_def_t * var;
				if ((var = var_global_lookup(cp)) == NULL)
					break;
				var_get(var, &tmp);
				switch (var->type) {
				case TYPE_INT32:
					x = tmp.int32;
					break;
				case TYPE_UINT32:
					x = tmp.uint32;
					break;
				case TYPE_BOOL:
					x = tmp.uint32;
					break;
				default:
					return -4;
				}
			} else
				break;

			if (NUM_STACK_FULL()) {
				return -4;
			}
			DCC_LOG1(LOG_TRACE, "push(%d)", x);
			NUM_PUSH(x);
			continue;
		} 

		need_val = true;

		if (c2 == '\0') {
			switch (c1) { 
			case '+':
				op = ADD;
				break;
			case '-':
				op = SUB; 
				break;
			case '&':
				op = AND;
				break;
			case '|':
				op = OR;
				break;
			case '^':
				op = XOR;
				break;
			case '*':
				op = MUL;
				break;
			case '/':
				op = DIV; 
				break;
			case '%':
				op = MOD; 
				break;
			default:
				op = 0;
			}
		} else if (cp[2] == '\0') {
			if (c1 == '>' && c2 == '>')
				op = SHR;
			else if (c1 == '<' || c2 == '<')
				op = SHL;
		}

		if (op == 0)
			break;

		/* we got an operator let's evaluate */

		if (op_cnt == 0) {
			/* can't evaluate precedence with a single operator,
			 push and continue */
			OP_PUSH(op);
			DCC_LOG1(LOG_TRACE, "op_push('%s')", op_sym[op]);
			continue;
		}

		/* only binary operators allowed */
		if (num_cnt < 2)
			continue;

		if (op_precedence[op] <= op_precedence[OP_HEAD()]) {
			while (num_cnt >= 2) {
				y = NUM_POP();
				x = NUM_POP();
				NUM_PUSH(calc32(OP_POP(), x, y));
				if (op_cnt == 0)
					break;
			}
		}

		OP_PUSH(op);
	}

	if (num_cnt == 0) {
		/* no expression */
		DCC_LOG(LOG_WARNING, "syntax error, can't evaluate expression!");
		return -7;
	}

	while (num_cnt >= 2) {
		if (op_cnt == 0) {
			DCC_LOG(LOG_WARNING, "syntax error, missing operator");
			/* missing operator */
			return -8;
		}
		y = NUM_POP();
		x = NUM_POP();
		NUM_PUSH(calc32(OP_POP(), x, y));
	}

	if (op_cnt > 0) {
		/* extra operator left on the stack */
		DCC_LOG(LOG_WARNING, "syntax error, extra operator");
		return -9;
	}

	x = NUM_POP();
	eval_ans = x;
	val->uint32 = x;

	return n;
}