diff --git a/ChangeLog b/ChangeLog index f899171..d79ebe6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -75,8 +75,11 @@ o 1591959: Veriwell gets seg fault for `include with no +incdir * Fixed initialization issue with UDPs and constant args + 2008-5-24 Mark Hummel * Fixed bug 1293467: force a reg with $random * Don't reseed random number generator with time. * Change random number generator to alogrithm in spec. + * Fixed sysfunctions so the work correctly + * Added $dist_* system functions diff --git a/src/pass3.h b/src/pass3.h index 70b3613..87e52ff 100644 --- a/src/pass3.h +++ b/src/pass3.h @@ -27,6 +27,8 @@ enum convert_to { eNONE, eREAL, eINT }; extern tree dump; // common dump block +extern ngroups_t stack_size; +extern int max_label; // public exports diff --git a/src/pli.cc b/src/pli.cc index 11c23d7..ec539be 100644 --- a/src/pli.cc +++ b/src/pli.cc @@ -2916,7 +2916,6 @@ void tf_ievaluatep(int nparam, char *instance) numbits = TREE_NBITS(*TREE_EXPR_CODE(arg)); ngroups = (numbits - 1) / 32 + 1; - stack_allocate(); eval(TREE_EXPR_CODE(arg)); g = *--R; @@ -4237,7 +4236,6 @@ char *tf_istrgetp(int nparam, char format_character, char *instance) } numbits = TREE_NBITS(*TREE_EXPR_CODE(arg)); - stack_allocate(); eval(TREE_EXPR_CODE(arg)); g = *--R; diff --git a/src/random.cc b/src/random.cc index 495074f..b5d3e8c 100644 --- a/src/random.cc +++ b/src/random.cc @@ -1,3 +1,21 @@ +/***************************************************************************** + * Copyright 1994-2008, Elliot Mednick and Mark Hummel + * This file is part of Veriwell. + * + * Veriwell is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Veriwell is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + *****************************************************************************/ /* * Algorithm for probabilistic distribution functions. * @@ -5,6 +23,8 @@ */ #include #include +#include +#include static double uniform( int *seed, int start, int end ); static double normal( int *seed, int mean, int deviation); @@ -369,4 +389,326 @@ erlangian(int* seed,int k,int mean) return(x); } +/* + * pli interfaces + */ +/******************************************** + * dist_uniform + *******************************************/ +int dist_uniform(int user, int reason) +{ + const char name[] = "dist_uniform"; + const int ARG_COUNT = 3; + int result = 0; + int argCount = tf_nump(); + handle args[ARG_COUNT]; + + acc_initialize(); + + switch( reason ) { + case reason_sizetf: + result = 32; + break; + case reason_checktf: { + if( argCount != ARG_COUNT ) { + tf_error("illegal number of arguments to %s", name); + } + for (int i = 1; i <= argCount; i++) { + args[i-1] = acc_handle_tfarg(i); + if( acc_error_flag ) { + tf_error("illegal argument #%d to %s", i, name); + } + } + if( acc_fetch_type(args[0]) != accReg && + acc_fetch_type(args[0]) != accTimeVar && + acc_fetch_type(args[0]) != accIntVar ) { + tf_error("illegal argument 0 to %s", name); + } + } break; + case reason_calltf: { + int seed = acc_fetch_tfarg_int(1); + int imin = acc_fetch_tfarg_int(2); + int imax = acc_fetch_tfarg_int(3); + int value = rtl_dist_uniform(&seed, imin, imax); + tf_putp(1,seed); + tf_putp(0,value); + } break; + } + + acc_close(); + return result; +} +/******************************************** + * dist_normal + *******************************************/ +int dist_normal(int user, int reason) +{ + const char name[] = "dist_normal"; + const int ARG_COUNT = 3; + int result = 0; + int argCount = tf_nump(); + handle args[ARG_COUNT]; + + acc_initialize(); + + switch( reason ) { + case reason_sizetf: + result = 32; + break; + case reason_checktf: { + if( argCount != ARG_COUNT ) { + tf_error("illegal number of arguments to %s", name); + } + for (int i = 1; i <= argCount; i++) { + args[i-1] = acc_handle_tfarg(i); + if( acc_error_flag ) { + tf_error("illegal argument #%d to %s", i, name); + } + } + if( acc_fetch_type(args[0]) != accReg && + acc_fetch_type(args[0]) != accTimeVar && + acc_fetch_type(args[0]) != accIntVar ) { + tf_error("illegal argument 0 to %s", name); + } + } break; + case reason_calltf: { + int seed = acc_fetch_tfarg_int(1); + int mean = acc_fetch_tfarg_int(2); + int sd = acc_fetch_tfarg_int(3); + int value = rtl_dist_normal(&seed, mean, sd); + tf_putp(1,seed); + tf_putp(0,value); + } break; + } + + acc_close(); + return result; +} +/******************************************** + * dist_exponential + *******************************************/ +int dist_exponential(int user, int reason) +{ + const char name[] = "dist_exponential"; + const int ARG_COUNT = 2; + int result = 0; + int argCount = tf_nump(); + handle args[ARG_COUNT]; + + acc_initialize(); + + switch( reason ) { + case reason_sizetf: + result = 32; + break; + case reason_checktf: { + if( argCount != ARG_COUNT ) { + tf_error("illegal number of arguments to %s", name); + } + for (int i = 1; i <= argCount; i++) { + args[i-1] = acc_handle_tfarg(i); + if( acc_error_flag ) { + tf_error("illegal argument #%d to %s", i, name); + } + } + if( acc_fetch_type(args[0]) != accReg && + acc_fetch_type(args[0]) != accTimeVar && + acc_fetch_type(args[0]) != accIntVar ) { + tf_error("illegal argument 0 to %s", name); + } + } break; + case reason_calltf: { + int seed = acc_fetch_tfarg_int(1); + int mean = acc_fetch_tfarg_int(2); + int value = rtl_dist_exponential(&seed, mean); + tf_putp(1,seed); + tf_putp(0,value); + } break; + } + + acc_close(); + return result; +} +/******************************************** + * dist_poisson + *******************************************/ +int dist_poisson(int user, int reason) +{ + const char name[] = "dist_poisson"; + const int ARG_COUNT = 2; + int result = 0; + int argCount = tf_nump(); + handle args[ARG_COUNT]; + + acc_initialize(); + + switch( reason ) { + case reason_sizetf: + result = 32; + break; + case reason_checktf: { + if( argCount != ARG_COUNT ) { + tf_error("illegal number of arguments to %s", name); + } + for (int i = 1; i <= argCount; i++) { + args[i-1] = acc_handle_tfarg(i); + if( acc_error_flag ) { + tf_error("illegal argument #%d to %s", i, name); + } + } + if( acc_fetch_type(args[0]) != accReg && + acc_fetch_type(args[0]) != accTimeVar && + acc_fetch_type(args[0]) != accIntVar ) { + tf_error("illegal argument 0 to %s", name); + } + } break; + case reason_calltf: { + int seed = acc_fetch_tfarg_int(1); + int mean = acc_fetch_tfarg_int(2); + int value = rtl_dist_poisson(&seed, mean); + tf_putp(1,seed); + tf_putp(0,value); + } break; + } + + acc_close(); + return result; +} +/******************************************** + * dist_chi_square + *******************************************/ +int dist_chi_square(int user, int reason) +{ + const char name[] = "dist_chi_square"; + const int ARG_COUNT = 2; + int result = 0; + int argCount = tf_nump(); + handle args[ARG_COUNT]; + + acc_initialize(); + + switch( reason ) { + case reason_sizetf: + result = 32; + break; + case reason_checktf: { + if( argCount != ARG_COUNT ) { + tf_error("illegal number of arguments to %s", name); + } + for (int i = 1; i <= argCount; i++) { + args[i-1] = acc_handle_tfarg(i); + if( acc_error_flag ) { + tf_error("illegal argument #%d to %s", i, name); + } + } + if( acc_fetch_type(args[0]) != accReg && + acc_fetch_type(args[0]) != accTimeVar && + acc_fetch_type(args[0]) != accIntVar ) { + tf_error("illegal argument 0 to %s", name); + } + } break; + case reason_calltf: { + int seed = acc_fetch_tfarg_int(1); + int dof = acc_fetch_tfarg_int(2); + int value = rtl_dist_chi_square(&seed, dof); + tf_putp(1,seed); + tf_putp(0,value); + } break; + } + + acc_close(); + return result; +} +/******************************************** + * dist_t + *******************************************/ +int dist_t(int user, int reason) +{ + const char name[] = "dist_t"; + const int ARG_COUNT = 2; + int result = 0; + int argCount = tf_nump(); + handle args[ARG_COUNT]; + + acc_initialize(); + + switch( reason ) { + case reason_sizetf: + result = 32; + break; + case reason_checktf: { + if( argCount != ARG_COUNT ) { + tf_error("illegal number of arguments to %s", name); + } + for (int i = 1; i <= argCount; i++) { + args[i-1] = acc_handle_tfarg(i); + if( acc_error_flag ) { + tf_error("illegal argument #%d to %s", i, name); + } + } + if( acc_fetch_type(args[0]) != accReg && + acc_fetch_type(args[0]) != accTimeVar && + acc_fetch_type(args[0]) != accIntVar ) { + tf_error("illegal argument 0 to %s", name); + } + } break; + case reason_calltf: { + int seed = acc_fetch_tfarg_int(1); + int dof = acc_fetch_tfarg_int(2); + int value = rtl_dist_t(&seed, dof); + tf_putp(1,seed); + tf_putp(0,value); + } break; + } + + acc_close(); + return result; +} + +/******************************************** + * dist_erlang + *******************************************/ +int dist_erlang(int user, int reason) +{ + const char name[] = "dist_erlang"; + const int ARG_COUNT = 3; + int result = 0; + int argCount = tf_nump(); + handle args[ARG_COUNT]; + + acc_initialize(); + + switch( reason ) { + case reason_sizetf: + result = 32; + break; + case reason_checktf: { + if( argCount != ARG_COUNT ) { + tf_error("illegal number of arguments to %s", name); + } + for (int i = 1; i <= argCount; i++) { + args[i-1] = acc_handle_tfarg(i); + if( acc_error_flag ) { + tf_error("illegal argument #%d to %s", i, name); + } + } + if( acc_fetch_type(args[0]) != accReg && + acc_fetch_type(args[0]) != accTimeVar && + acc_fetch_type(args[0]) != accIntVar ) { + tf_error("illegal argument 0 to %s", name); + } + } break; + case reason_calltf: { + int seed = acc_fetch_tfarg_int(1); + int k_stage = acc_fetch_tfarg_int(2); + int mean = acc_fetch_tfarg_int(3); + int value = rtl_dist_normal(&seed, k_stage, mean); + tf_putp(1,seed); + tf_putp(0,value); + } break; + } + + acc_close(); + return result; +} diff --git a/src/random.h b/src/random.h index d07a192..cc02de6 100644 --- a/src/random.h +++ b/src/random.h @@ -1,3 +1,21 @@ +/***************************************************************************** + * Copyright 1994-2008, Elliot Mednick and Mark Hummel + * This file is part of Veriwell. + * + * Veriwell is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Veriwell is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + *****************************************************************************/ /* * Algorithm for probabilistic distribution functions. * @@ -13,5 +31,17 @@ int rtl_dist_normal( int* seed, int mean, int sd ); int rtl_dist_poisson( int* seed, int mean ); int rtl_dist_t( int* seed, int df ); int rtl_dist_uniform(int* seed, int start, int end); +/* + * pli interfaces + */ +int dist_uniform(int user, int reason); +int dist_uniform(int user, int reason); +int dist_normal(int user, int reason); +int dist_exponential(int user, int reason); +int dist_poisson(int user, int reason); +int dist_chi_square(int user, int reason); +int dist_t(int user, int reason); +int dist_erlang(int user, int reason); #endif + diff --git a/src/systask.cc b/src/systask.cc index 987d603..3e64c44 100644 --- a/src/systask.cc +++ b/src/systask.cc @@ -1728,8 +1728,6 @@ disp_common(tree node, enum radii default_radix, int is_file, is_integer = TREE_INTEGER_ATTR(t1); val = eval_(TREE_EXPR_CODE(t), &nbits); if (TREE_REAL_ATTR(TREE_EXPR(t))) { -// AVAL (val) = REAL_ (val); -// BVAL (val) = 0; print_datum_file(handle, val, (nbits_t) 0, nbits, FLOAT_, is_integer, fill_space, "%g"); } else { diff --git a/src/verisys.cc b/src/verisys.cc index 345b782..95c7ed7 100644 --- a/src/verisys.cc +++ b/src/verisys.cc @@ -45,6 +45,7 @@ int pmisc(int user, int reason); #include "sdf.h" +#include "random.h" #include "plihacks.h" @@ -70,6 +71,18 @@ s_tfcell verisystfs[] = { {usertask, 0, 0, 0, setvalue_call, 0, "$$testsetvalue"}, {usertask, 0, sdf_check, 0, sdf_call, sdf_misc, "$sdf_annotate"}, + {userfunction, 0, dist_uniform, dist_uniform, dist_uniform, + 0, "$dist_uniform"}, + {userfunction, 0, dist_normal, dist_normal, dist_normal, + 0, "$dist_normal"}, + {userfunction, 0, dist_exponential, dist_exponential, dist_exponential, + 0, "$dist_exponential"}, + {userfunction, 0, dist_poisson, dist_poisson, dist_poisson, 0, + "$dist_poisson"}, + {userfunction, 0, dist_chi_square, dist_chi_square, dist_chi_square, + 0, "$dist_chi_square"}, + {userfunction, 0, dist_t, dist_t, dist_t, 0, "$dist_t"}, + {userfunction, 0, dist_erlang, dist_erlang, dist_erlang, 0, "$dist_erlang"}, {0} /*** final entry must be 0 ***/ diff --git a/src/veriwell.cc b/src/veriwell.cc index fb73057..072ae7b 100644 --- a/src/veriwell.cc +++ b/src/veriwell.cc @@ -850,6 +850,13 @@ void PhaseII() void PhaseIII() { pass3_tree(top_level); + /* + * allocate extra size for sysfunctions + * - mdh ??? doesn't appear as easy as this + * as this seem to create memory corruption issues + */ +// max_label += 64; +// stack_size += 1024; stack_allocate(); }