Пример #1
0
void stack_minus()
{
	if (num_stack_items() < 2) {
		eprintf("stack underflow error.");
		return;
	}

	bool arg1_success;
	bool arg2_success;

	int arg1 = get_stack_int(&arg1_success);
	int arg2 = get_stack_int(&arg2_success);

	/* Error is handled and printed in get_stack_int */
	if (!arg1_success || !arg2_success) {
		return;
	}

	push_stack_int(arg2 - arg1);
}
Пример #2
0
int scriptlet_run(hscriptlet *r)
{
	r->it_stack = 0;
	r->it_syms = r->it_syms_save;
	r->level = 0;
	r->it = 0;

	double result = 1.0;
	int bc, nbr_params = 0, dummy = 0;
	bytecode value = NULL;
	bytecode val1 = NULL;
	bytecode val2 = NULL;
	int type1 = 0, type2 = 0;
	int done = 0;

	while (!done && (bc = nextbytecode_(r, &value, &nbr_params, &r->level)) != 0)
	{
		DEBUG printf("run level=%d, bc=%d nbr_params=%d\n", r->level, bc, nbr_params);

		if (nbr_params)
		{
			nextbytecode_(r, &val1, &dummy, &dummy);
			val1 = substitute(r, val1);
			type1 = val1->tc;
			nbr_params--;
		}

		if (nbr_params)
		{
			nextbytecode_(r, &val2, &dummy, &dummy);
			val2 = substitute(r, val2);
			type2 = val2->tc;
			nbr_params--;
		}

		switch(bc)
		{
			case empty_tc:
			{
				break;
			}
			case multiply_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, result=v1*v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "*", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (double)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_real(r, result=v1*v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "*", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "*", val2->str_val, result);
				}

				break;
			}

			case power_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, result=(long long)pow((double)v1,(double)v2));
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "*", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (double)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_real(r, result=pow(v1,v2));
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "*", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "*", val2->str_val, result);
				}

				break;
			}

			case divide_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "/", (double)v2, result);
					if (v2 == 0) return result = 0.0;
					push_stack_int(r, result=v1/v2);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (double)(type2==int_tc?val2->int_val:val2->real_val);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "/", (double)v2, result);
					if (v2 == 0.0) return 0.0;
					push_stack_real(r, result=v1/v2);
				}
				else
				{
					return result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "/", val2->str_val, result);
				}

				break;
			}

			case modulo_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, result=v1%v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "%", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					long long v1 = (long long)val1->real_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, result=v1%v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "%", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "%", val2->str_val, result);
				}

				break;
			}

			case assign_tc:
			{
				if (type2 == int_tc)
				{
					long long v2 = (long long)val2->int_val;
					sb_string_set(r->symtab, val1->str_val, (void*)val2);
					push_stack_int(r, result=v2);
					DEBUG printf("run %s %s '%g'\n", val1->str_val, "=", (double)v2);
				}
				else if (type2 == real_tc)
				{
					double v2 = val2->real_val;
					sb_string_set(r->symtab, val1->str_val, (void*)val2);
					push_stack_real(r, result=v2);
					DEBUG printf("run %s %s '%g'\n", val1->str_val, "=", (double)v2);
				}
				else if (type2 == string_tc)
				{
					const char *v2 = val2->str_val;
					void *v3 = NULL;

					if (sb_string_get(r->symtab, v2, &v3))
						sb_string_set(r->symtab, val1->str_val, v3);
					else
						sb_string_set(r->symtab, val1->str_val, (void*)val2);
					push_stack_string(r, v2); result=0.0;
					DEBUG printf("run %s %s %s\n", val1->str_val, "=", v2);
				}
				else
				{
					push_stack_real(r, result=0.0);
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "+", val2->str_val, result);
				}

				break;
			}

			case add_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, result=v1+v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "+", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_real(r, result=v1+v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "+", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "+", val2->str_val, result);
				}

				break;
			}

			case subtract_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, result=v1-v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "-", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_real(r, result=v1-v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "-", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "-", val2->str_val, result);
				}

				break;
			}

			case eq_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, result=v1==v2?1:0);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "==", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, result=v1==v2?1:0);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "==", (double)v2, result);
				}
				else
				{
					const char *v1 = val1->str_val;
					const char *v2 = val2->str_val;
					push_stack_int(r, !strcmp(v1,v2));
					DEBUG printf("run '%s' %s '%s' = %g\n", val1->str_val, "==", val2->str_val, result);
				}

				break;
			}

			case neq_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, result=v1!=v2?1:0);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "!=", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, result=v1!=v2?1:0);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "!=", (double)v2, result);
				}
				else
				{
					const char *v1 = val1->str_val;
					const char *v2 = val2->str_val;
					push_stack_int(r, strcmp(v1,v2));
					DEBUG printf("run '%s' %s '%s' = %g\n", val1->str_val, "!=", val2->str_val, result);
				}

				break;
			}

			case if_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					result = (double)v1;
					DEBUG printf("run '%g' %s = %g\n", (double)v1, "if", result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s = %g\n", val1->str_val, "if", result);
				}

				if (!result)
				{
					int skip = 0, tmp_level = 0, tmp_code;

					while ((tmp_code = peekbytecode_(r, &tmp_level)) != 0)
					{
						if (tmp_level <= r->level)
							break;

						skipbytecode_(r);
						skip++;
					}
				}

				break;
			}

			case else_tc:
			{
				if (result)
				{
					int skip = 0, tmp_level = 0, tmp_code;

					while ((tmp_code = peekbytecode_(r, &tmp_level)) != 0)
					{
						if (tmp_level <= r->level)
							break;

						skipbytecode_(r);
						skip++;
					}
				}

				DEBUG printf("runstr %s = %g\n", "else", result);
				break;
			}

			case fi_tc:
			{
				DEBUG printf("runstr %s = %g\n", "fi", result);
				break;
			}

			case not_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					result = (double)!v1;
					DEBUG printf("run '%g' %s = %g\n", (double)v1, "!", result);
					if (!v1) done = 1;
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s = %g\n", val1->str_val, "!", result);
				}

				break;
			}

			case and_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1&&v2); result=(double)v1&&v2;
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "&&", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_real(r, result=v1&&v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "&&", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "&&", val2->str_val, result);
				}

				break;
			}

			case or_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1||v2); result=(double)(v1||v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "||", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_real(r, result=v1||v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "||", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "||", val2->str_val, result);
				}

				break;
			}

			case xor_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, (v1&&!v2) || (v2&&!v1)); result=(double)((v1&&!v2) || (v2&&!v1));
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "^^", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_real(r, result=(v1&&!v2) || (v2&&!v1));
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "^^", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "^^", val2->str_val, result);
				}

				break;
			}

			case bit_negate_tc:
			{
				if (type1 == int_tc)
				{
					unsigned long long v1 = val1->int_val;
					push_stack_int(r, ~v1); result=(double)~v1;
					DEBUG printf("run %s '%g' = %g\n", "~", (double)v1, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr %s '%s' = %g\n", "~", val1->str_val, result);
				}

				break;
			}

			case bit_and_tc:
			{
				if (type1 == int_tc)
				{
					unsigned long long v1 = val1->int_val;
					unsigned long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1&v2); result=(double)(v1&v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "&", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "&", val2->str_val, result);
				}

				break;
			}

			case bit_or_tc:
			{
				if (type1 == int_tc)
				{
					unsigned long long v1 = val1->int_val;
					unsigned long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1|v2); result=(double)(v1|v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "|", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "|", val2->str_val, result);
				}

				break;
			}

			case bit_xor_tc:
			{
				if (type1 == int_tc)
				{
					unsigned long long v1 = val1->int_val;
					unsigned long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1^v2); result=(double)(v1^v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "^", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "^", val2->str_val, result);
				}

				break;
			}

			case lt_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1<v2); result=(double)(v1<v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "<", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1<v2); result=(double)(v1<v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "<", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "<", val2->str_val, result);
				}

				break;
			}

			case leq_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1<=v2); result=(double)(v1<=v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "<=", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1<=v2); result=(double)(v1<=v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "<=", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "<", val2->str_val, result);
				}

				break;
			}

			case gt_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1>v2); result=(double)(v1>v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, ">", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1>v2); result=(double)(v1>v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, ">", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, ">", val2->str_val, result);
				}

				break;
			}

			case geq_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1>=v2); result=(double)(v1>=v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, ">=", (double)v2, result);
				}
				else if (type1 == real_tc)
				{
					double v1 = val1->real_val;
					double v2 = (type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1>=v2); result=(double)(v1>=v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, ">=", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, ">=", val2->str_val, result);
				}

				break;
			}

			case shift_left_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1<<v2); result=(double)(v1<<v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, "<<", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, "<<", val2->str_val, result);
				}

				break;
			}

			case shift_right_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, v1>>v2); result=(double)(v1>>v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, ">>", (double)v2, result);
				}
				else
				{
					result = 0.0;
					DEBUG printf("runstr '%s' %s '%s' = %g\n", val1->str_val, ">>", val2->str_val, result);
				}

				break;
			}

			case logical_shift_right_tc:
			{
				if (type1 == int_tc)
				{
					long long v1 = val1->int_val;
					long long v2 = (long long)(type2==int_tc?val2->int_val:val2->real_val);
					push_stack_int(r, ((unsigned long long)v1)>>v2); result=(double)(((unsigned long long)v1)>>v2);
					DEBUG printf("run '%g' %s '%g' = %g\n", (double)v1, ">>>", (double)v2, result);
				}
				else
				{