Annotation of capa/capa51/pProj/capaFunction.c, revision 1.5
1.1 albertel 1:
2: /* =||>>================================================================<<||= */
3: /* 45678901234567890123456789012345678901234567890123456789012345678901234567 */
4: /* copyrighted by Isaac Tsai, 1996, 1997, 1998, 1999, 2000 */
5: /* =||>>================================================================<<||= */
6:
7: #include <stdlib.h>
8: #include <string.h>
9: #include <math.h>
10:
11: #include "capaParser.h" /* Symbol_p */
12: #include "capaFunction.h" /* RANDOM_F etc. */
13: #include "capaToken.h"
14: #include "capaCommon.h"
15: #include "ranlib.h"
16:
17: char Parse_class[QUARTER_K];
18: int Parse_set;
19: int Parse_section;
20: char Parse_student_number[MAX_STUDENT_NUMBER+1];
21: char Parse_name[MAX_NAME_CHAR+1];
22: long capaid_plus_gen;
1.3 albertel 23: int managermode;
1.1 albertel 24:
25: extern int Parsemode_f;
26:
27: extern int Lexi_qnum;
28: extern char Opened_filename[MAX_OPENED_FILE][QUARTER_K];
29: extern int Input_idx;
30: extern int Current_line[MAX_OPENED_FILE];
31:
32: extern int Func_idx;
33: extern Symbol FuncStack[MAX_FUNC_NEST];
34:
35: /* --------------------------------------------------------------------------- */
36: int
37: match_function(func, argc) char *func; int argc;
38: {
39: if( !strcmp(func,"random") ) return (((argc==2 || argc==3)? RANDOM_F : MIS_ARG_COUNT));
1.5 ! albertel 40: if( !strcmp(func,"random_normal") ) return ((argc==5)? RANDOM_NORMAL_F : MIS_ARG_COUNT);
! 41: if( !strcmp(func,"random_beta") ) return ((argc==5)? RANDOM_BETA_F : MIS_ARG_COUNT);
! 42: if( !strcmp(func,"random_gamma") ) return ((argc==5)? RANDOM_GAMMA_F : MIS_ARG_COUNT);
! 43: if( !strcmp(func,"random_poisson") ) return ((argc==4)? RANDOM_POISSON_F : MIS_ARG_COUNT);
! 44: if( !strcmp(func,"random_exponential") ) return ((argc==4)? RANDOM_EXPONENTIAL_F : MIS_ARG_COUNT);
! 45: if( !strcmp(func,"random_chi") ) return ((argc==4)? RANDOM_CHI_F : MIS_ARG_COUNT);
! 46: if( !strcmp(func,"random_noncentral_chi") ) return ((argc==4)? RANDOM_NONCENTRAL_CHI_F : MIS_ARG_COUNT);
1.1 albertel 47: if( !strcmp(func,"choose") ) return (CHOOSE_F);
48: if( !strcmp(func,"tex") ) return (((argc==2)? TEX_F: MIS_ARG_COUNT));
49: if( !strcmp(func,"var_in_tex") ) return (VAR_IN_TEX_F);
50: if( !strcmp(func,"html") ) return (((argc==1)? HTML_F: MIS_ARG_COUNT));
51: if( !strcmp(func,"web") ) return (((argc==3)? WEB_F: MIS_ARG_COUNT));
52: if( !strcmp(func,"pin") ) return (((argc<2)? PIN_F: MIS_ARG_COUNT));
53: if( !strcmp(func,"capa_id") ) return (((argc<2)? PIN_F: MIS_ARG_COUNT));
54: if( !strcmp(func,"class") ) return (((argc==0)? CLASS_F: MIS_ARG_COUNT));
55: if( !strcmp(func,"section") ) return (((argc==0)? SECTION_F: MIS_ARG_COUNT));
56: if( !strcmp(func,"set") ) return (((argc==0)? SET_F: MIS_ARG_COUNT));
57: if( !strcmp(func,"problem") ) return (((argc==0)? PROBLEM_F: MIS_ARG_COUNT));
58: if( !strcmp(func,"name") ) return (((argc==0)? NAME_F: MIS_ARG_COUNT));
59: if( !strcmp(func,"student_number") ) return (((argc==0)? SNUMBER_F: MIS_ARG_COUNT));
60: if( !strcmp(func,"due_date") ) return (((argc<2)? DUE_DATE_F: MIS_ARG_COUNT));
61: if( !strcmp(func,"due_day") ) return (((argc<2)? DUE_DAY_F: MIS_ARG_COUNT));
62: if( !strcmp(func,"open_date") ) return (((argc<2)? OPEN_DATE_F: MIS_ARG_COUNT));
63: if( !strcmp(func,"answer_date") ) return (((argc<2)? ANSWER_DATE_F: MIS_ARG_COUNT));
64: if( !strcmp(func,"to_string") ) return (((argc==1 || argc==2)? TO_STRING_F: MIS_ARG_COUNT));
65: if( !strcmp(func,"sub_string") ) return (((argc==2 || argc==3)? SUB_STRING_F: MIS_ARG_COUNT));
66: if( !strcmp(func,"strlen") ) return (((argc==1)? STRLEN_F: MIS_ARG_COUNT));
67: if( !strcmp(func,"get_seed") ) return (((argc==0)? GET_SEED_F: MIS_ARG_COUNT));
68: if( !strcmp(func,"set_seed") ) return (((argc==1)? SET_SEED_F: MIS_ARG_COUNT));
1.5 ! albertel 69: if( !strcmp(func,"init_array") ) return (((argc==1)? INIT_ARRAY_F: MIS_ARG_COUNT));
1.1 albertel 70: if( !strcmp(func,"array_index") ) return (((argc==1)? ARRAY_INDEX_F: MIS_ARG_COUNT));
71: if( !strcmp(func,"array_sorted_index") ) return (((argc==2)? ARRAY_SORTED_INDEX_F: MIS_ARG_COUNT));
72: if( !strcmp(func,"array_max") ) return (((argc==1)? ARRAY_MAX_F: MIS_ARG_COUNT));
73: if( !strcmp(func,"array_min") ) return (((argc==1)? ARRAY_MIN_F: MIS_ARG_COUNT));
74: if( !strcmp(func,"array_moments") ) return (((argc==2)? ARRAY_MOMENTS_F: MIS_ARG_COUNT));
75: if( !strcmp(func,"array_var") ) return (((argc==1)? ARRAY_VARIANCE_F: MIS_ARG_COUNT));
76: if( !strcmp(func,"array_std_dev") ) return (((argc==1)? ARRAY_STD_DEV_F: MIS_ARG_COUNT));
77: if( !strcmp(func,"array_skewness") ) return (((argc==1)? ARRAY_SKEWNESS_F: MIS_ARG_COUNT));
78: if( !strcmp(func,"to_int") ) return (((argc==1)? TO_INT_F: MIS_ARG_COUNT));
79: if( !strcmp(func,"format") ) return (FORMAT_F);
80: if( !strcmp(func,"pick") ) return (((argc> 1)? PICK_F: MIS_ARG_COUNT));
81: if( !strcmp(func,"sin") ) return (((argc==1)? SIN_F: MIS_ARG_COUNT));
82: if( !strcmp(func,"cos") ) return (((argc==1)? COS_F: MIS_ARG_COUNT));
83: if( !strcmp(func,"tan") ) return (((argc==1)? TAN_F: MIS_ARG_COUNT));
84: if( !strcmp(func,"asin") ) return (((argc==1)? ASIN_F: MIS_ARG_COUNT));
85: if( !strcmp(func,"acos") ) return (((argc==1)? ACOS_F: MIS_ARG_COUNT));
86: if( !strcmp(func,"atan") ) return (((argc==1)? ATAN_F: MIS_ARG_COUNT));
87: if( !strcmp(func,"sinh") ) return (((argc==1)? SINH_F: MIS_ARG_COUNT));
88: if( !strcmp(func,"cosh") ) return (((argc==1)? COSH_F: MIS_ARG_COUNT));
89: if( !strcmp(func,"tanh") ) return (((argc==1)? TANH_F: MIS_ARG_COUNT));
90: if( !strcmp(func,"asinh") ) return (((argc==1)? ASINH_F: MIS_ARG_COUNT));
91: if( !strcmp(func,"acosh") ) return (((argc==1)? ACOSH_F: MIS_ARG_COUNT));
92: if( !strcmp(func,"atanh") ) return (((argc==1)? ATANH_F: MIS_ARG_COUNT));
93: if( !strcmp(func,"atan2") ) return (((argc==2)? ATANTWO_F: MIS_ARG_COUNT));
94: if( !strcmp(func,"j0") ) return (((argc==1)? J_ZERO_F: MIS_ARG_COUNT));
95: if( !strcmp(func,"j1") ) return (((argc==1)? J_ONE_F: MIS_ARG_COUNT));
96: if( !strcmp(func,"jn") ) return (((argc==2)? J_N_F: MIS_ARG_COUNT));
97: if( !strcmp(func,"y0") ) return (((argc==1)? Y_ZERO_F: MIS_ARG_COUNT));
98: if( !strcmp(func,"y1") ) return (((argc==1)? Y_ONE_F: MIS_ARG_COUNT));
99: if( !strcmp(func,"yn") ) return (((argc==2)? Y_N_F: MIS_ARG_COUNT));
100: if( !strcmp(func,"log") ) return (((argc==1)? LOG_F: MIS_ARG_COUNT));
101: if( !strcmp(func,"log10") ) return (((argc==1)? LOG_TEN_F: MIS_ARG_COUNT));
102: if( !strcmp(func,"exp") ) return (((argc==1)? EXP_F: MIS_ARG_COUNT));
103: if( !strcmp(func,"pow") ) return (((argc==2)? POW_F: MIS_ARG_COUNT));
104: if( !strcmp(func,"erf") ) return (((argc==1)? ERF_F: MIS_ARG_COUNT));
105: if( !strcmp(func,"erfc") ) return (((argc==1)? ERFC_F: MIS_ARG_COUNT));
106: if( !strcmp(func,"sqrt") ) return (((argc==1)? SQRT_F: MIS_ARG_COUNT));
107: if( !strcmp(func,"min") ) return (MIN_F);
108: if( !strcmp(func,"max") ) return (MAX_F);
109: if( !strcmp(func,"abs") ) return (((argc==1)? ABS_F: MIS_ARG_COUNT));
110: if( !strcmp(func,"floor") ) return (((argc==1)? FLOOR_F: MIS_ARG_COUNT));
111: if( !strcmp(func,"ceil") ) return (((argc==1)? CEIL_F: MIS_ARG_COUNT));
112: if( !strcmp(func,"sgn") ) return (((argc==1)? SGN_F: MIS_ARG_COUNT));
113: if( !strcmp(func,"mod") ) return (((argc==2)? MOD_F: MIS_ARG_COUNT));
114: if( !strcmp(func,"remainder") ) return (((argc==2)? REMAINDER_F: MIS_ARG_COUNT));
115: if( !strcmp(func,"factorial") ) return (((argc==1)? FACTORIAL_F: MIS_ARG_COUNT));
116: if( !strcmp(func,"roundto") ) return (((argc==2)? ROUNDTO_F: MIS_ARG_COUNT));
117: if( !strcmp(func,"eval_formula") ) return (((argc==3)? EVALUATE_F: MIS_ARG_COUNT));
118: if( !strcmp(func,"capa_id_plus") ) return (((argc==1 || argc==2)? CAPAID_PLUS: MIS_ARG_COUNT));
119: if( !strcmp(func,"seat_number") ) return (((argc <2)? SEAT_NUMBER: MIS_ARG_COUNT));
120: if( !strcmp(func,"duration") ) return (((argc==0)? DURATION: MIS_ARG_COUNT));
121: if( !strcmp(func,"is_open") ) return (((argc <2)? IS_OPEN_F: MIS_ARG_COUNT));
122: if( !strcmp(func,"is_due") ) return (((argc <2)? IS_DUE_F: MIS_ARG_COUNT));
123: if( !strcmp(func,"is_answer") ) return (((argc <2)? IS_ANSWER_F: MIS_ARG_COUNT));
1.3 albertel 124: if( !strcmp(func,"correct") ) return (((argc <3)? CORRECT_F: MIS_ARG_COUNT));
125: if( !strcmp(func,"grade") ) return (((argc <3)? GRADE_F: MIS_ARG_COUNT));
126: if( !strcmp(func,"tries") ) return (((argc <3)? TRIES_F: MIS_ARG_COUNT));
127: if( !strcmp(func,"managermode")) return (((argc==0)? MANAGERMODE_F:MIS_ARG_COUNT));
1.1 albertel 128: return (UNKNOWN_F);
129: }
130:
131: /**********************************************************/
132:
133:
134: #ifdef SGN
135: #undef SGN
136: #endif
137: #define SGN(xx) ( (xx) > 0 ? 1 : ( (xx) == 0 ? 0 : -1) )
138:
139:
140: #define MAX_DOUBLE 1.7976931348623157E+308
141: #define MIN_DOUBLE 2.2250738585072014E-308
142:
143: #define INT_DIV 0
144: #define REAL_DIV 1
145: #define INT_LOWER 0
146: #define REAL_LOWER 2
147: #define INT_UPPER 0
148: #define REAL_UPPER 4
149:
150: #define ALL_INTEGER 0
151:
152: int which_set(argc,argp,resultp)
153: int argc;
154: ArgNode_t *argp;
155: Symbol *resultp;
156: {
157: char aline[MAX_BUFFER_SIZE], tmpS[MAX_BUFFER_SIZE];
158: int result=Parse_set;
159: if( argc == 1 ) {
160: if( (FIRST_ARGTYPE(argp) == S_VAR ) ||
161: (FIRST_ARGTYPE(argp) == S_CONSTANT ) ) {
162: sprintf(aline,"<<ARG TYPE MISMATCH>>");
163: resultp->s_type = S_CONSTANT;
164: resultp->s_str = strsave(aline);
165: sprintf(tmpS, "function %s() cannot accept string as argument.\n",
166: FuncStack[Func_idx].s_name);
167: capa_msg(MESSAGE_ERROR,tmpS);
168: result=-1;
169: } else {
170: if( (FIRST_ARGTYPE(argp) == I_VAR ) ||
171: (FIRST_ARGTYPE(argp) == I_CONSTANT ) ) {
172: result = FIRST_ARGINT(argp);
173: } else {
174: result = FIRST_ARGREAL(argp);
175: }
176: }
177: }
178: return result;
179: }
180:
181: Symbol *
182: do_function(func,argc,argp)
183: int func;
184: int argc;
185: ArgNode_t *argp;
186: {
187: Symbol *resultp;
188: ArgNode_t *tmpArgp;
189: char aline[MAX_BUFFER_SIZE], tmpS[MAX_BUFFER_SIZE], fmt_str[FORMAT_STRING_LENG];
190: char num_str[SMALL_LINE_BUFFER],date_str[SMALL_LINE_BUFFER];
191: double tmpA=0.0, tmpB=0.0;
192: int slots, noError, errCode, mo, yy, dd, hh, mm, tmpInt;
193: long rout;
194: char *wday[9] = {"Sat,", "Sun,", "Mon,", "Tue,", "Wed,", "Thr,", "Fri,", "Sat,", "\0"};
1.2 albertel 195: char *month[14] = { "UNKNOWN", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
196: "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "\0"};
1.1 albertel 197:
198: resultp = (Symbol *)capa_malloc(1,sizeof(Symbol));
199:
200: switch(func) {
201: case RANDOM_F: { int type_flag=0;
202: double r_lower=0.0, r_upper=1.0, r_division=1.0;
203:
204: errCode = 0; rout = ignlgi();
205: switch( FIRST_ARGTYPE(argp) ) {
206: case I_VAR: case I_CONSTANT: break;
207: case R_VAR: case R_CONSTANT: type_flag = (type_flag | 1); break;
208: case S_VAR: case S_CONSTANT: errCode = 1; break;
209: }
210: switch( SECOND_ARGTYPE(argp) ) {
211: case I_VAR: case I_CONSTANT: break;
212: case R_VAR: case R_CONSTANT: type_flag = (type_flag | 2); break;
213: case S_VAR: case S_CONSTANT: errCode = 2; break;
214: }
215: if( argc == 3 ) {
216: switch( THIRD_ARGTYPE(argp) ) {
217: case I_VAR: case I_CONSTANT: break;
218: case R_VAR: case R_CONSTANT: type_flag = (type_flag | 4); break;
219: case S_VAR: case S_CONSTANT: errCode = 4; break;
220: }
221: }
222: if( errCode == 0 ) {
223: if( argc == 3 ) {
224: switch(type_flag) {
225: case 0: r_division = (double)FIRST_ARGINT(argp);
226: r_upper = (double)SECOND_ARGINT(argp);
227: r_lower = (double)THIRD_ARGINT(argp); break;
228: case 2: r_division = (double)FIRST_ARGINT(argp);
229: r_upper = SECOND_ARGREAL(argp);
230: r_lower = (double)THIRD_ARGINT(argp); break;
231: case 4: r_division = (double)FIRST_ARGINT(argp);
232: r_upper = (double)SECOND_ARGINT(argp);
233: r_lower = THIRD_ARGREAL(argp); break;
234: case 6: r_division = (double)FIRST_ARGINT(argp);
235: r_upper = SECOND_ARGREAL(argp);
236: r_lower = THIRD_ARGREAL(argp); break;
237: case 1: r_division = FIRST_ARGREAL(argp);
238: r_upper = (double)SECOND_ARGINT(argp);
239: r_lower = (double)THIRD_ARGINT(argp); break;
240: case 3: r_division = FIRST_ARGREAL(argp);
241: r_upper = SECOND_ARGREAL(argp);
242: r_lower = (double)THIRD_ARGINT(argp); break;
243: case 5: r_division = FIRST_ARGREAL(argp);
244: r_upper = (double)SECOND_ARGINT(argp);
245: r_lower = THIRD_ARGREAL(argp); break;
246: case 7: r_division = FIRST_ARGREAL(argp);
247: r_upper = SECOND_ARGREAL(argp);
248: r_lower = THIRD_ARGREAL(argp); break;
249: }
250: } else { /* two args */
251: switch(type_flag) {
252: case 0: r_upper = (double)FIRST_ARGINT(argp);
253: r_lower = (double)SECOND_ARGINT(argp); break;
254: case 1: r_upper = FIRST_ARGREAL(argp);
255: r_lower = (double)SECOND_ARGINT(argp); break;
256: case 2: r_upper = (double)FIRST_ARGINT(argp);
257: r_lower = SECOND_ARGREAL(argp); break;
258: case 3: r_upper = FIRST_ARGREAL(argp);
259: r_lower = SECOND_ARGREAL(argp); break;
260: }
261: r_division = 1.0;
262: }
263: if( r_upper >= r_lower ) {
264: slots = 1 + (int)floor( (r_upper - r_lower)/r_division );
265: if( type_flag == 0 ) {
266: resultp->s_type = I_CONSTANT;
267: resultp->s_int = (int)r_lower + ((int)r_division)*(rout % slots );
268: } else {
269: resultp->s_type = R_CONSTANT;
270: resultp->s_real = r_lower + r_division*(double)(rout % slots );
271: }
272: } else {
273: resultp->s_type = S_CONSTANT;
274: resultp->s_str = strsave("<<2ND ARG MUST .GE. 1ST ARG>>");
275: sprintf(tmpS,"random()'s second arg. must be greater than the first arg.\n");
276: capa_msg(MESSAGE_ERROR,tmpS);
277: }
278: } else {
279: resultp->s_type = S_CONSTANT;
280: resultp->s_str = strsave("<<ARG CANNOT BE STRING>>");
281: sprintf(tmpS,"random() cannot accept string as argument.\n");
282: capa_msg(MESSAGE_ERROR,tmpS);
283: }
284: } break;
1.5 ! albertel 285:
1.1 albertel 286: case CHOOSE_F: { int ii, pick=1;
287: ArgNode_t *tmpArgp;
288:
289: noError = 1;
290: tmpArgp = argp; ii=0;
291: while( ii < argc-1 ) {tmpArgp = tmpArgp->a_next; ii++; }
292: switch( FIRST_ARGTYPE(tmpArgp) ) {
293: case IDENTIFIER:
294: sprintf(tmpS,"The first argument to choose(): \"%s\" has not been defined yet. I will choose the first element.\n",FIRST_ARGNAME(tmpArgp));
295: capa_msg(MESSAGE_ERROR,tmpS);
296: pick = 1;
297: break;
298: case I_VAR: case I_CONSTANT:
299: pick = FIRST_ARGINT(tmpArgp); break;
300: case R_VAR: case R_CONSTANT:
301: pick = (int)FIRST_ARGREAL(tmpArgp);
302: sprintf(tmpS,"The first argument to choose() is a real number: \"%.15g\", it must be an integer, I will use %d instead.\n",FIRST_ARGREAL(tmpArgp),pick);
303: capa_msg(MESSAGE_ERROR,tmpS);
304: break;
305: case S_VAR: case S_CONSTANT:
306: resultp->s_type = S_CONSTANT;
307: resultp->s_str = strsave("CHOOSE: first argument must be an integer");
308: sprintf(tmpS,"The first argument to choose() cannot be a string, I will choose the first element.\n");
309: capa_msg(MESSAGE_ERROR,tmpS);
310: pick = 1;
311: break;
312: }
313: if( noError ) {
314: if( (pick <= 0) || (pick > argc-1) ) {
315: sprintf(tmpS,"The first argument to choose() is out of bounds, tt is %d, but should be in the range [1,%d].\n", pick, argc-1);
316: capa_msg(MESSAGE_ERROR,tmpS);
317: pick = argc-1;
318: } else { pick = argc - pick; }
319: for(ii=1,tmpArgp = argp;(ii < pick)&&(ii < argc-1);ii++) { tmpArgp = tmpArgp->a_next; }
320:
321: resultp->s_type = (tmpArgp->a_sp)->s_type;
322: switch((tmpArgp->a_sp)->s_type) {
323: case IDENTIFIER:
324: sprintf(tmpS,"The variable \"%s\" selected by choose() has not yet been defined.\n",(tmpArgp->a_sp)->s_name);
325: capa_msg(MESSAGE_ERROR,tmpS);
326: resultp->s_type = S_CONSTANT;
327: resultp->s_str = strsave(tmpS);
328: break;
329: case I_VAR: case I_CONSTANT:
330: resultp->s_type = I_CONSTANT;
331: resultp->s_int = (tmpArgp->a_sp)->s_int; break;
332: case R_VAR: case R_CONSTANT:
333: resultp->s_type = R_CONSTANT;
334: resultp->s_real = (tmpArgp->a_sp)->s_real; break;
335: case S_VAR: case S_CONSTANT:
336: resultp->s_type = S_CONSTANT;
337: resultp->s_str = strsave((tmpArgp->a_sp)->s_str); break; /********* */
338: }
339:
340: }
341:
342: } break;
343: case PIN_F: {
344: if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
345: resultp->s_type = I_CONSTANT;
346: resultp->s_int=capa_PIN(Parse_student_number,tmpInt,0);
347: }
348: break;
349: case CLASS_F: {
350: resultp->s_type = S_CONSTANT;
351: if(strlen(Parse_class) != 0 ) {
352: resultp->s_str=strsave(Parse_class);
353: } else {
354: resultp->s_str=strsave("UNKNOWN");
355: }
356: }
357: break;
358: case SECTION_F:{ resultp->s_type = I_CONSTANT;
359: resultp->s_int = Parse_section;
360: } break;
361: case PROBLEM_F:{ resultp->s_type = I_CONSTANT;
362: resultp->s_int= Lexi_qnum+1;
363: } break;
364: case SET_F: { resultp->s_type = I_CONSTANT;
365: resultp->s_int=Parse_set;
366: } break;
367: case NAME_F: {
368: resultp->s_type = S_CONSTANT;
369: resultp->s_str=strsave(Parse_name);
370: } break;
371: case SNUMBER_F: {
372: resultp->s_type = S_CONSTANT;
373: resultp->s_str=strsave(Parse_student_number);
374: } break;
375: case IS_DUE_F:
376: case IS_ANSWER_F:
377: case IS_OPEN_F: {
378: int whichDate=CHECK_OPEN_DATE;
379: if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
380: resultp->s_type = I_CONSTANT;
381: switch(func) {
382: case IS_OPEN_F: whichDate=CHECK_OPEN_DATE;break;
383: case IS_DUE_F: whichDate=CHECK_DUE_DATE;break;
384: case IS_ANSWER_F: whichDate=CHECK_ANS_DATE;break;
385: }
386: if( capa_check_date(whichDate,Parse_student_number,
387: Parse_section,tmpInt) < 0 ) {
388: resultp->s_int = 0;
389: } else {
390: resultp->s_int = 1;
391: }
392: } break;
393: case DUE_DATE_F:
394: { if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
395: resultp->s_type = S_CONSTANT;
396: if(capa_get_date(CHECK_DUE_DATE,Parse_student_number,Parse_section,tmpInt,date_str) > 0 ) {
397: sscanf(date_str,"%4d/%2d/%2d %2d:%2d",&yy, &mo, &dd, &hh, &mm);
398: sprintf(aline, "%s %s %2d, %4d at %02d:%02d",
399: wday[weekday(yy,mo,dd)], month[mo], dd, yy, hh, mm);
400: resultp->s_str= strsave(aline);
401: } else {
402: resultp->s_str= strsave("UNKNOWN");
403: }
404: } break;
405: case DUE_DAY_F:
406: { if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
407: resultp->s_type = S_CONSTANT;
408: if(capa_get_date(CHECK_DUE_DATE,Parse_student_number,Parse_section,tmpInt,date_str) > 0 ) {
409: sscanf(date_str,"%4d/%2d/%2d %2d:%2d",&yy, &mm, &dd, &hh, &mm);
410: sprintf(aline, "%s %s %2d, %4d",
411: wday[weekday(yy,mo,dd)], month[mo], dd, yy);
412: resultp->s_str= strsave(aline);
413: } else {
414: resultp->s_str= strsave("UNKNOWN");
415: }
416: } break;
417: case OPEN_DATE_F:
418: { if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
419: resultp->s_type = S_CONSTANT;
420: if(capa_get_date(CHECK_OPEN_DATE,Parse_student_number,Parse_section,tmpInt,date_str) > 0 ) {
421: sscanf(date_str,"%4d/%2d/%2d %2d:%2d",&yy, &mm, &dd, &hh, &mm);
422: sprintf(aline, "%s %s %2d, %4d at %02d:%02d",
423: wday[weekday(yy,mo,dd)], month[mo], dd, yy, hh, mm);
424: resultp->s_str= strsave(aline);
425: } else {
426: resultp->s_str= strsave("UNKNOWN");
427: }
428: } break;
429: case ANSWER_DATE_F:
430: { if (-1==(tmpInt=which_set(argc,argp,resultp))) break;
431: resultp->s_type = S_CONSTANT;
432: if(capa_get_date(CHECK_ANS_DATE,Parse_student_number,Parse_section,tmpInt,date_str) > 0 ) {
433: sscanf(date_str,"%4d/%2d/%2d %2d:%2d",&yy, &mo, &dd, &hh, &mm);
434: sprintf(aline, "%s %s %2d, %4d at %02d:%02d",
435: wday[weekday(yy,mo,dd)], month[mo], dd, yy, hh, mm);
436: resultp->s_str= strsave(aline);
437: } else {
438: resultp->s_str= strsave("UNKNOWN");
439: }
440: } break;
441: case STRLEN_F: {
442: resultp->s_type = I_CONSTANT;
443: switch( FIRST_ARGTYPE(argp) ) {
444: case I_VAR:
445: case I_CONSTANT:
446: resultp->s_type = S_CONSTANT;
447: sprintf(tmpS,"strlen() only accepts string variable, not integer.\n");
448: capa_msg(MESSAGE_ERROR,tmpS);
449: resultp->s_str=strsave(tmpS);
450: break;
451: case R_VAR:
452: case R_CONSTANT:
453: resultp->s_type = S_CONSTANT;
454: sprintf(tmpS,"strlen() only accepts string variable, not float number.\n");
455: capa_msg(MESSAGE_ERROR,tmpS);
456: resultp->s_str=strsave(tmpS);
457: break;
458: case S_VAR:
459: case S_CONSTANT:
460: resultp->s_int = strlen( FIRST_ARGSTR(argp) );
461: break;
462: case IDENTIFIER:
463: sprintf(tmpS,"Unknown variable, %s, argument to function strlen()\n",argp->a_sp->s_name);
464: capa_msg(MESSAGE_ERROR,tmpS);
465: resultp->s_str=strsave(tmpS);
466: break;
467: }
468: } break;
469: case TO_STRING_F:
470: { char aline[MAX_BUFFER_SIZE],rline[MAX_BUFFER_SIZE];
471:
472: resultp->s_type = S_CONSTANT;
473:
474: if( argc == 1 ) {
475: switch( FIRST_ARGTYPE(argp) ) {
476: case I_VAR:
477: case I_CONSTANT:
478: sprintf(aline,"%ld",FIRST_ARGINT(argp));
479: resultp->s_str = strsave(aline); break;
480: case R_VAR:
481: case R_CONSTANT:
482: sprintf(aline,"%.15g",FIRST_ARGREAL(argp));
483: resultp->s_str = strsave(aline); break;
484: case S_VAR:
485: case S_CONSTANT:
486: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
487: case IDENTIFIER:
488: sprintf(tmpS,"Unknown variable, %s, argument to function to_string()\n",argp->a_sp->s_name);
489: capa_msg(MESSAGE_ERROR,tmpS);
490: resultp->s_str=strsave(tmpS);
491: break;
492: }
493: } else {
494: switch( FIRST_ARGTYPE(argp) ) {
495: case I_VAR:
496: case I_CONSTANT:
497: case R_VAR:
498: case R_CONSTANT:
499: sprintf(tmpS,
500: "to_string()'s second arg. must be a string.\n");
501: capa_msg(MESSAGE_ERROR,tmpS);
502: sprintf(aline,"%%.15g");
503: break;
504: case S_VAR:
505: case S_CONSTANT:
506: sprintf(aline,"%%%s",FIRST_ARGSTR(argp));
507: break;
508: case IDENTIFIER:
509: sprintf(tmpS,"Unknown variable, %s, argument to function to_string()\n",argp->a_next->a_sp->s_name);
510: capa_msg(MESSAGE_ERROR,tmpS);
511: resultp->s_str=strsave(tmpS);
512: break;
513:
514: }
515: switch( SECOND_ARGTYPE(argp) ) {
516: case I_VAR:
517: case I_CONSTANT:
518: sprintf(aline,"%ld",SECOND_ARGINT(argp));
519: resultp->s_str = strsave(aline); break;
520: case R_VAR:
521: case R_CONSTANT:
522: sprintf(rline,aline,SECOND_ARGREAL(argp));
523: resultp->s_str = strsave(rline); break;
524: case S_VAR:
525: case S_CONSTANT:
526: resultp->s_str = strsave(SECOND_ARGSTR(argp));
527: break;
528: case IDENTIFIER:
529: sprintf(tmpS,"Unknown variable, %s, argument to function to_string()\n",argp->a_sp->s_name);
530: capa_msg(MESSAGE_ERROR,tmpS);
531: resultp->s_str=strsave(tmpS);
532: break;
533: }
534: }
535: } break;
536: case SUB_STRING_F: /* sub_string(str, 2), 1 is the first char */
537: /* sub_string(str, 3, 5) means start from the third char and take 5 chars */
538: { int idx=1, leng, rleng=0,ii;
539: char *a_str, *b_str;
540:
541: resultp->s_type = S_CONSTANT;
542: if( argc == 2 ) { /* two arguments format */
543: switch( FIRST_ARGTYPE(argp) ) {
544: case IDENTIFIER:
545: sprintf(tmpS,
546: "sub_string()'s second arg. must be an integer.\n");
547: capa_msg(MESSAGE_ERROR,tmpS);
548: break;
549: case I_VAR:
550: case I_CONSTANT:
551: idx = FIRST_ARGINT(argp);
552: break;
553: case R_VAR:
554: case R_CONSTANT:
555: idx = (int) FIRST_ARGREAL(argp);
556: break;
557: case S_VAR:
558: case S_CONSTANT:
559: sprintf(tmpS,
560: "sub_string()'s second arg. must be an integer.\n");
561: capa_msg(MESSAGE_ERROR,tmpS);
562: break;
563: }
564: switch( SECOND_ARGTYPE(argp) ) {
565: case IDENTIFIER:
566: sprintf(tmpS,
567: "sub_string()'s first arg. is not defined before use.\n");
568: capa_msg(MESSAGE_ERROR,tmpS);
569: break;
570: case I_VAR:
571: case I_CONSTANT:
572: sprintf(tmpS,
573: "sub_string()'s first arg. cannot be an integer.\n");
574: capa_msg(MESSAGE_ERROR,tmpS);
575: break;
576: case R_VAR:
577: case R_CONSTANT:
578: sprintf(tmpS,
579: "sub_string()'s first arg. cannot be a number.\n");
580: capa_msg(MESSAGE_ERROR,tmpS);
581: break;
582: case S_VAR:
583: case S_CONSTANT:
584: a_str = SECOND_ARGSTR(argp);
585: leng = strlen(a_str);
586: if( (idx<1) || (idx > leng) ) {
587: sprintf(tmpS, "sub_string()'s second arg. is out of range.\n");
588: capa_msg(MESSAGE_ERROR,tmpS);
589: idx = 1;
590: }
591: b_str = (char *)&a_str[idx-1];
592: resultp->s_str = strsave(b_str);
593:
594: if( SECOND_ARGTYPE(argp) == S_CONSTANT) {
595: /* freed in free arg_list */
596: /* capa_mfree((char *)SECOND_ARGSTR(argp)); */
597: }
598: break;
599: }
600: } else { /* three arguments format sub_string(string, start, length) */
601: switch( FIRST_ARGTYPE(argp) ) {
602: case IDENTIFIER:
603: sprintf(tmpS,
604: "sub_string()'s third arg. must be an integer.\n");
605: capa_msg(MESSAGE_ERROR,tmpS);
606: break;
607: case I_VAR:
608: case I_CONSTANT:
609: rleng = FIRST_ARGINT(argp);
610: break;
611: case R_VAR:
612: case R_CONSTANT:
613: rleng = (int) FIRST_ARGREAL(argp);
614: break;
615: case S_VAR:
616: case S_CONSTANT:
617: sprintf(tmpS,
618: "sub_string()'s third arg. must be an integer.\n");
619: capa_msg(MESSAGE_ERROR,tmpS);
620: break;
621: }
622: switch( SECOND_ARGTYPE(argp) ) {
623: case IDENTIFIER:
624: sprintf(tmpS,
625: "sub_string()'s second arg. must be an integer.\n");
626: capa_msg(MESSAGE_ERROR,tmpS);
627: break;
628: case I_VAR:
629: case I_CONSTANT:
630: idx = SECOND_ARGINT(argp);
631: break;
632: case R_VAR:
633: case R_CONSTANT:
634: idx = (int) SECOND_ARGREAL(argp);
635: break;
636: case S_VAR:
637: case S_CONSTANT:
638: sprintf(tmpS,
639: "sub_string()'s second arg. must be an integer.\n");
640: capa_msg(MESSAGE_ERROR,tmpS);
641: break;
642: }
643: switch( THIRD_ARGTYPE(argp) ) {
644: case IDENTIFIER:
645: sprintf(tmpS,
646: "sub_string()'s first arg. is not defined before use.\n");
647: capa_msg(MESSAGE_ERROR,tmpS);
648: break;
649: case I_VAR:
650: case I_CONSTANT:
651: sprintf(tmpS,
652: "sub_string()'s first arg. cannot be an integer.\n");
653: capa_msg(MESSAGE_ERROR,tmpS);
654: break;
655: case R_VAR:
656: case R_CONSTANT:
657: sprintf(tmpS,
658: "sub_string()'s first arg. cannot be a number.\n");
659: capa_msg(MESSAGE_ERROR,tmpS);
660: break;
661: case S_VAR:
662: case S_CONSTANT:
663: a_str = THIRD_ARGSTR(argp);
664: leng = strlen(a_str);
665: if( (idx < 1) || (idx > leng) ) {
666: sprintf(tmpS, "sub_string()'s second arg. is out of range.\n");
667: capa_msg(MESSAGE_ERROR,tmpS);
668: idx = 1;
669: }
670: if( (rleng<1) || ((rleng+idx-1) > leng)) {
671:
672: rleng = leng - idx + 1;
673: }
674: b_str = (char *)capa_malloc((rleng+1)*sizeof(char),1);
675: for(ii=idx-1;ii<(rleng+idx-1);ii++) {
676: b_str[ii-idx+1] = a_str[ii];
677: }
678: resultp->s_str = strsave(b_str);
679: capa_mfree(b_str);
680:
681: if( THIRD_ARGTYPE(argp) == S_CONSTANT) {
682: /* handled in free_arglist() */
683: /* capa_mfree((char *)THIRD_ARGSTR(argp)); */
684: }
685: break;
686: }
687: }
688: } break;
689: case PICK_F: { int ii, pick=1;
690: ArgNode_t *tmpArgp;
691:
692: noError = 1;
693: rout = ignlgi();
694: tmpArgp = argp; ii=0;
695: while( ii < argc-1 ) {tmpArgp = tmpArgp->a_next; ii++; }
696: switch( FIRST_ARGTYPE(tmpArgp) ) {
697: case I_VAR:
698: case I_CONSTANT:
699: pick = FIRST_ARGINT(tmpArgp);
700: if( (pick <= 0 ) || (pick > argc-1) ) {
701: noError = 0;
702: resultp->s_type = S_CONSTANT;
703: resultp->s_str = strsave("PICK: first arg out of bound.");
704: }
705: break;
706: case R_VAR:
707: case R_CONSTANT:
708: pick = (int)FIRST_ARGREAL(tmpArgp);
709: if( (pick <= 0 ) || (pick > argc-1) ) {
710: noError = 0;
711: resultp->s_type = S_CONSTANT;
712: resultp->s_str = strsave("PICK: first arg out of bound.");
713: }
714: break;
715: case S_VAR:
716: case S_CONSTANT: noError = 0;
717: resultp->s_type = S_CONSTANT;
718: resultp->s_str = strsave("PICK: first arg must be int");
719: break;
720: }
721: if( noError ) {
722: for( ii=0; ii< pick; ii++) {
723: }
724: }
725: }
726: break;
727: case GET_SEED_F:
728: { long seed1, seed2;
729: char *tmp;
730:
731: getsd(&seed1,&seed2);
732: tmp = (char *)capa_malloc(32,1);
733: sprintf(tmp,"%ld,%ld",seed1,seed2);
734: resultp->s_type = S_CONSTANT;
735: resultp->s_str = strsave(tmp);
736: capa_mfree(tmp);
737: } break;
738: case SET_SEED_F:
739: { long seed1, seed2;
740: int leng;
741:
742: switch( FIRST_ARGTYPE(argp) ) {
743: case I_VAR: case I_CONSTANT: break;
744: case R_VAR: case R_CONSTANT: break;
745: case S_VAR: case S_CONSTANT:
746: leng = strlen(FIRST_ARGSTR(argp));
747: if( (index(FIRST_ARGSTR(argp), ' ') != NULL) ) {
748: sscanf(FIRST_ARGSTR(argp),"%ld,%ld", &seed1, &seed2);
749: setall(seed1,seed2);
750: }
751:
752: break;
753: }
754: resultp->s_type = I_CONSTANT;
755: resultp->s_int = 0;
756: } break;
1.5 ! albertel 757: /* generate random numbers according to a pre-defined distributions and a seed */
! 758: case RANDOM_NORMAL_F: /* random_normal(return_array,item_cnt,seed,av,std_dev) */
! 759: case RANDOM_BETA_F: /* random_beta(return_array,item_cnt,seed,aa,bb) */
! 760: case RANDOM_GAMMA_F: /* random_gamma(return_array,item_cnt,seed,a,r) */
! 761: case RANDOM_POISSON_F: /* random_poisson(return_array,item_cnt,seed,mu) */
! 762: case RANDOM_EXPONENTIAL_F:
! 763: /* random_exponential(return_array,item_cnt,seed,av) */
! 764: case RANDOM_CHI_F: /* random_chi(return_array,item_cnt,seed,df) */
! 765: case RANDOM_NONCENTRAL_CHI_F:
! 766: /* random_noncentral_chi(return_array,item_cnt,seed,df,xnonc) */
! 767: /* gen_random_by_selector(output_p,sel,seed,item_cnt,p1,p2) */
! 768: { int sel, item_cnt, tmp_int;
! 769: float para1, para2;
! 770: char *tmp_str;
! 771: long tmp_long;
! 772: Symbol *r_p;
! 773:
! 774: switch(func) { /* assigns the function selector */
! 775: case RANDOM_NORMAL_F: sel = NORMAL_DIS; break;
! 776: case RANDOM_BETA_F: sel = BETA_DIS; break;
! 777: case RANDOM_GAMMA_F: sel = GAMMA_DIS; break;
! 778: case RANDOM_POISSON_F: sel = POISSON_DIS; break;
! 779: case RANDOM_EXPONENTIAL_F: sel = EXPONENTIAL_DIS; break;
! 780: case RANDOM_CHI_F: sel = CHI_DIS; break;
! 781: case RANDOM_NONCENTRAL_CHI_F: sel = NONCENTRAL_CHI_DIS; break;
! 782: }
! 783: switch(func) {
! 784: case RANDOM_NORMAL_F:
! 785: case RANDOM_BETA_F:
! 786: case RANDOM_GAMMA_F: /* two-parameter functions */
! 787: { errCode = 0;
! 788: switch( FIRST_ARGTYPE(argp) ) { /* parameter two */
! 789: case I_VAR: case I_CONSTANT:
! 790: para2 = (float)FIRST_ARGINT(argp);
! 791: break;
! 792: case R_VAR: case R_CONSTANT:
! 793: para2 = (float)FIRST_ARGREAL(argp);
! 794: break;
! 795: case S_VAR: case S_CONSTANT:
! 796: case IDENTIFIER:
! 797: resultp->s_type = S_CONSTANT;
! 798: resultp->s_str = strsave("<<LAST ARG. OF THIS FUNCTION MUST BE A NUMBER>>");
! 799: sprintf(tmpS,"%s()'s last arg. must be a number.\n",FuncStack[Func_idx].s_name);
! 800: capa_msg(MESSAGE_ERROR,tmpS);
! 801: errCode = 1;
! 802: break;
! 803: }
! 804: if(errCode == 0 ) {
! 805: switch( SECOND_ARGTYPE(argp) ) { /* parameter one */
! 806: case I_VAR: case I_CONSTANT:
! 807: para1 = (float)SECOND_ARGINT(argp);
! 808: break;
! 809: case R_VAR: case R_CONSTANT:
! 810: para1 = (float)SECOND_ARGREAL(argp);
! 811: break;
! 812: case S_VAR: case S_CONSTANT:
! 813: case IDENTIFIER:
! 814: resultp->s_type = S_CONSTANT;
! 815: resultp->s_str = strsave("<<FOURTH ARG. OF THIS FUNCTION MUST BE A NUMBER>>");
! 816: sprintf(tmpS,"%s()'s fourth arg. must be a number.\n",FuncStack[Func_idx].s_name);
! 817: capa_msg(MESSAGE_ERROR,tmpS);
! 818: errCode = 1;
! 819: break;
! 820: }
! 821: if(errCode == 0 ) {
! 822: switch( THIRD_ARGTYPE(argp) ) { /* seed */
! 823: case I_VAR: case I_CONSTANT:
! 824: tmp_str = (char *)capa_malloc(32,1);
! 825: sprintf(tmp_str,"%ld",THIRD_ARGINT(argp) );
! 826: break;
! 827: case R_VAR: case R_CONSTANT:
! 828: tmp_long = (long)THIRD_ARGREAL(argp);
! 829: tmp_str = (char *)capa_malloc(32,1);
! 830: sprintf(tmp_str,"%ld",tmp_long);
! 831: break;
! 832: case S_VAR: case S_CONSTANT:
! 833: tmp_str = strsave(THIRD_ARGSTR(argp));
! 834: break;
! 835: case IDENTIFIER:
! 836: resultp->s_type = S_CONSTANT;
! 837: resultp->s_str = strsave("<<THIRD ARG. OF THIS FUNCTION MUST BE A NUMBER>>");
! 838: sprintf(tmpS,"%s()'s third arg. must be a number.\n",FuncStack[Func_idx].s_name);
! 839: capa_msg(MESSAGE_ERROR,tmpS);
! 840: errCode = 1;
! 841: break;
! 842: }
! 843: if(errCode == 0 ) {
! 844: switch( FOURTH_ARGTYPE(argp) ) { /* item_cnt */
! 845: case I_VAR: case I_CONSTANT:
! 846: item_cnt = FOURTH_ARGINT(argp);
! 847: break;
! 848: case R_VAR: case R_CONSTANT:
! 849: item_cnt = (int)FOURTH_ARGREAL(argp);
! 850: break;
! 851: case S_VAR: case S_CONSTANT:
! 852: case IDENTIFIER:
! 853: resultp->s_type = S_CONSTANT;
! 854: resultp->s_str = strsave("<<SECOND ARG. OF THIS FUNCTION MUST BE A NUMBER>>");
! 855: sprintf(tmpS,"%s()'s second arg. must be a number.\n",FuncStack[Func_idx].s_name);
! 856: capa_msg(MESSAGE_ERROR,tmpS);
! 857: errCode = 1;
! 858: break;
! 859: }
! 860: if(errCode == 0 ) {
! 861: switch( FIFTH_ARGTYPE(argp) ) { /* array_name, clear the content of this array first */
! 862: case I_VAR: case I_CONSTANT:
! 863: case R_VAR: case R_CONSTANT:
! 864: resultp->s_type = S_CONSTANT;
! 865: resultp->s_str = strsave("<<FIRST ARG. OF THIS FUNCTION MUST BE AN ARRAY NAME>>");
! 866: sprintf(tmpS,"%s()'s first arg. must be a name of an array.\n",FuncStack[Func_idx].s_name);
! 867: capa_msg(MESSAGE_ERROR,tmpS);
! 868: errCode = 1;
! 869: break;
! 870: case S_VAR: case S_CONSTANT:
! 871: tmp_int = free_array(FIFTH_ARGSTR(argp));
! 872: r_p = gen_random_by_selector(FIFTH_ARGSTR(argp),sel,tmp_str,item_cnt,para1,para2);
! 873: capa_mfree((char *)resultp);
! 874: resultp = r_p;
! 875: break;
! 876: case IDENTIFIER:
! 877: tmp_int = free_array(FIFTH_ARGNAME(argp));
! 878: r_p = gen_random_by_selector(FIFTH_ARGSTR(argp),sel,tmp_str,item_cnt,para1,para2);
! 879: capa_mfree((char *)resultp);
! 880: resultp = r_p;
! 881: break;
! 882: }
! 883: } /* the fourth argument of this function (item_cnt) */
! 884: } /* the third argument of this function (seed) */
! 885: } /* the second argument of this function (paramenter one) */
! 886: } /* the first argument of this function (parameter two) */
! 887:
! 888: }
! 889: break;
! 890: case RANDOM_POISSON_F:
! 891: case RANDOM_EXPONENTIAL_F:
! 892: case RANDOM_CHI_F:
! 893: case RANDOM_NONCENTRAL_CHI_F: /* one parameter functions */
! 894: { errCode = 0;
! 895: switch( FIRST_ARGTYPE(argp) ) { /* parameter one */
! 896: case I_VAR: case I_CONSTANT:
! 897: para2 = (float)FIRST_ARGINT(argp);
! 898: break;
! 899: case R_VAR: case R_CONSTANT:
! 900: para2 = (float)FIRST_ARGREAL(argp);
! 901: break;
! 902: case S_VAR: case S_CONSTANT:
! 903: case IDENTIFIER:
! 904: resultp->s_type = S_CONSTANT;
! 905: resultp->s_str = strsave("<<LAST ARG. OF THIS FUNCTION MUST BE A NUMBER>>");
! 906: sprintf(tmpS,"%s()'s last arg. must be a number.\n",FuncStack[Func_idx].s_name);
! 907: capa_msg(MESSAGE_ERROR,tmpS);
! 908: errCode = 1;
! 909: break;
! 910: }
! 911: if(errCode == 0 ) {
! 912: switch( SECOND_ARGTYPE(argp) ) { /* seed */
! 913: case I_VAR: case I_CONSTANT:
! 914: tmp_str = (char *)capa_malloc(32,1);
! 915: sprintf(tmp_str,"%ld",SECOND_ARGINT(argp) );
! 916: break;
! 917: case R_VAR: case R_CONSTANT:
! 918: tmp_long = (long)SECOND_ARGREAL(argp);
! 919: tmp_str = (char *)capa_malloc(32,1);
! 920: sprintf(tmp_str,"%ld",tmp_long);
! 921: break;
! 922: case S_VAR: case S_CONSTANT:
! 923: tmp_str = strsave(SECOND_ARGSTR(argp));
! 924: break;
! 925: case IDENTIFIER:
! 926: resultp->s_type = S_CONSTANT;
! 927: resultp->s_str = strsave("<<THIRD ARG. OF THIS FUNCTION MUST BE A NUMBER>>");
! 928: sprintf(tmpS,"%s()'s third arg. must be a number.\n",FuncStack[Func_idx].s_name);
! 929: capa_msg(MESSAGE_ERROR,tmpS);
! 930: errCode = 1;
! 931: break;
! 932: }
! 933: if(errCode == 0 ) {
! 934: switch( THIRD_ARGTYPE(argp) ) { /* item_cnt */
! 935: case I_VAR: case I_CONSTANT:
! 936: item_cnt = THIRD_ARGINT(argp);
! 937: break;
! 938: case R_VAR: case R_CONSTANT:
! 939: item_cnt = (int)THIRD_ARGREAL(argp);
! 940: break;
! 941: case S_VAR: case S_CONSTANT:
! 942: case IDENTIFIER:
! 943: resultp->s_type = S_CONSTANT;
! 944: resultp->s_str = strsave("<<SECOND ARG. OF THIS FUNCTION MUST BE A NUMBER>>");
! 945: sprintf(tmpS,"%s()'s second arg. must be a number.\n",FuncStack[Func_idx].s_name);
! 946: capa_msg(MESSAGE_ERROR,tmpS);
! 947: errCode = 1;
! 948: break;
! 949: }
! 950: if(errCode == 0 ) {
! 951: switch( FOURTH_ARGTYPE(argp) ) { /* array_name, clear the content of this array first */
! 952: case I_VAR: case I_CONSTANT:
! 953: case R_VAR: case R_CONSTANT:
! 954: resultp->s_type = S_CONSTANT;
! 955: resultp->s_str = strsave("<<FIRST ARG. OF THIS FUNCTION MUST BE AN ARRAY NAME>>");
! 956: sprintf(tmpS,"%s()'s first arg. must be a name of an array.\n",FuncStack[Func_idx].s_name);
! 957: capa_msg(MESSAGE_ERROR,tmpS);
! 958: errCode = 1;
! 959: break;
! 960: case S_VAR: case S_CONSTANT:
! 961: tmp_int = free_array(FOURTH_ARGSTR(argp));
! 962: r_p = gen_random_by_selector(FOURTH_ARGSTR(argp),sel,tmp_str,item_cnt,para1,para2);
! 963: capa_mfree((char *)resultp);
! 964: resultp = r_p;
! 965: break;
! 966: case IDENTIFIER:
! 967: tmp_int = free_array(FOURTH_ARGNAME(argp));
! 968: r_p = gen_random_by_selector(FOURTH_ARGSTR(argp),sel,tmp_str,item_cnt,para1,para2);
! 969: capa_mfree((char *)resultp);
! 970: resultp = r_p;
! 971: break;
! 972: }
! 973:
! 974: } /* the third argument of this function (seed) */
! 975: } /* the second argument of this function (paramenter one) */
! 976: } /* the first argument of this function (parameter two) */
! 977: }
! 978: break;
! 979: } /* end second switch */
! 980: } break;
! 981: case ARRAY_MOMENTS_F: /* */
1.1 albertel 982: {
983: char *tmp_input;
984: Symbol *r_p;
985:
986: switch( FIRST_ARGTYPE(argp) ) {
987: case I_VAR: case I_CONSTANT:
988: case R_VAR: case R_CONSTANT:
989: resultp->s_type = S_CONSTANT;
990: resultp->s_str = strsave("<<ARG. OF THIS FUNCTION MUST BE AN ARRAY NAME>>");
991: sprintf(tmpS,"array_moments()'s arg. must be a name of an array.\n");
992: capa_msg(MESSAGE_ERROR,tmpS);
993: errCode = 1;
994: break;
995: case S_VAR: case S_CONSTANT:
996: tmp_input = strsave(FIRST_ARGSTR(argp));
997: errCode = 0;
998: break;
999: case IDENTIFIER:
1000: tmp_input = strsave(FIRST_ARGNAME(argp));
1001: errCode = 0;
1002: break;
1003: }
1004: if( errCode == 0 ) {
1005: switch( SECOND_ARGTYPE(argp) ) {
1006: case I_VAR: case I_CONSTANT:
1007: case R_VAR: case R_CONSTANT:
1008: resultp->s_type = S_CONSTANT;
1009: resultp->s_str = strsave("<<ARG. OF THIS FUNCTION MUST BE AN ARRAY NAME>>");
1010: sprintf(tmpS,"array_moments()'s arg. must be a name of an array.\n");
1011: capa_msg(MESSAGE_ERROR,tmpS);
1012: errCode = 1;
1013: break;
1014: case S_VAR: case S_CONSTANT:
1015: r_p = array_moments(SECOND_ARGSTR(argp),tmp_input);
1016: capa_mfree((char *)tmp_input);
1017: /* fprintf(stdout,"DONE array_moments()\n"); fflush(stdout); */
1018: break;
1019: case IDENTIFIER:
1020: r_p = array_moments(SECOND_ARGNAME(argp),tmp_input);
1021: capa_mfree((char *)tmp_input);
1022:
1023: break;
1024: }
1025: if(errCode == 0 ) {
1026: capa_mfree((char *)resultp);
1027: resultp = r_p;
1028: }
1029: }
1030:
1031: } break;
1032: case ARRAY_SORTED_INDEX_F: /* array_sorted_index(array_name_str, sort_type) */
1033: {
1034: switch( FIRST_ARGTYPE(argp) ) {
1035: case I_VAR: case I_CONSTANT:
1036: switch( FIRST_ARGINT(argp) ) {
1037: case ASCEND_SORT: break;
1038: case DESCEND_SORT: break;
1039: case NUMERICAL_SORT: break;
1040: default: break;
1041: }
1042:
1043: break;
1044: case R_VAR: case R_CONSTANT: break;
1045: case S_VAR: case S_CONSTANT:
1046:
1047:
1048: break;
1049: }
1050: resultp->s_type = S_CONSTANT;
1051: resultp->s_str = strsave("NOT YET");
1052: } break;
1053:
1.4 albertel 1054: case INIT_ARRAY_F:
1055: { int rr;
1056:
1057: switch( FIRST_ARGTYPE(argp) ) {
1058: case I_VAR: case I_CONSTANT:
1059: case R_VAR: case R_CONSTANT:
1060: resultp->s_type = S_CONSTANT;
1061: resultp->s_str = strsave("<<ARG. OF THIS FUNCTION MUST BE AN ARRAY NAME>>");
1062: sprintf(tmpS,"init_array()'s arg. must be a name of an array.\n");
1063: capa_msg(MESSAGE_ERROR,tmpS);
1064: break;
1065: case S_VAR: case S_CONSTANT: /* allows the use of init_array(array[1]) which array[1]="another" */
1066: rr = free_array(FIRST_ARGSTR(argp));
1067: resultp->s_type = I_CONSTANT;
1068: resultp->s_int = rr;
1069: break;
1070: case IDENTIFIER:
1071: rr = free_array(FIRST_ARGNAME(argp));
1072: resultp->s_type = I_CONSTANT;
1073: resultp->s_int = rr;
1074: break;
1075: }
1076: } break;
1.1 albertel 1077: case ARRAY_MAX_F:
1078: case ARRAY_MIN_F:
1079: { int min;
1080: Symbol *r_p;
1081:
1082: min = ((func==ARRAY_MIN_F)? 1 : 0);
1083: switch( FIRST_ARGTYPE(argp) ) {
1084: case I_VAR: case I_CONSTANT:
1085: case R_VAR: case R_CONSTANT:
1086: resultp->s_type = S_CONSTANT;
1087: resultp->s_str = strsave("<<ARG. OF THIS FUNCTION MUST BE AN ARRAY NAME>>");
1088: sprintf(tmpS,"%s()'s arg. must be a name of an array.\n",(min ? "min" : "max"));
1089: capa_msg(MESSAGE_ERROR,tmpS);
1090: break;
1091: case S_VAR: case S_CONSTANT: /* this allows the use of min(array[1]) which array[1]="another" */
1092: r_p = array_min_max(FIRST_ARGSTR(argp),min);
1093: if( r_p == NULL ) { /* array name is not in array tree */
1094: resultp->s_type = S_CONSTANT;
1095: resultp->s_str = strsave("<<STRING ARRAY NAME IS NOT YET DEFINED!>>");
1096: } else {
1097: /*
1098: fprintf(stdout,"min_max():: STR arg. R=%g\n",r_p->s_real); fflush(stdout);
1099: */
1100: capa_mfree((char *)resultp);
1101: resultp = r_p;
1102: }
1103: break;
1104: case IDENTIFIER:
1105: r_p = array_min_max(FIRST_ARGNAME(argp),min);
1106: if( r_p == NULL ) { /* array name is not in array tree */
1107: /* fprintf(stdout,"min_max() return NULL\n"); fflush(stdout); */
1108: resultp->s_type = S_CONSTANT;
1109: resultp->s_str = strsave("<<ARRAY NAME IS NOT YET DEFINED!>>");
1110: } else {
1111: /*
1112: fprintf(stdout,"min_max():: ID arg. R=%g\n",r_p->s_real); fflush(stdout);
1113: */
1114: capa_mfree((char *)resultp);
1115: resultp = r_p;
1116: }
1117: break;
1118: }
1119: } break;
1120: case SIN_F:
1121: case COS_F:
1122: case TAN_F:
1123: case ASIN_F:
1124: case ACOS_F:
1125: case ATAN_F:
1126: case SINH_F:
1127: case COSH_F:
1128: case TANH_F:
1129: case ASINH_F:
1130: case ACOSH_F:
1131: case ATANH_F:
1132: case J_ZERO_F:
1133: case J_ONE_F:
1134: case Y_ZERO_F:
1135: case Y_ONE_F:
1136: case LOG_F:
1137: case LOG_TEN_F:
1138: case EXP_F:
1139: case ERF_F:
1140: case ERFC_F:
1141: case ABS_F:
1142: case SQRT_F:
1143: case FLOOR_F:
1144: case CEIL_F:
1145: case SGN_F:{ if( (FIRST_ARGTYPE(argp) == S_VAR ) || (FIRST_ARGTYPE(argp) == S_CONSTANT ) ) {
1146: sprintf(aline,"<<ARG TYPE MISMATCH>>");
1147: resultp->s_type = S_CONSTANT;
1148: resultp->s_str = strsave(aline);
1149: sprintf(tmpS,"function %s() cannot accept string as argument.\n", FuncStack[Func_idx].s_name);
1150: capa_msg(MESSAGE_ERROR,tmpS);
1151: } else {
1152: if( (FIRST_ARGTYPE(argp) == I_VAR ) || (FIRST_ARGTYPE(argp) == I_CONSTANT ) ) {
1153: tmpA = (double)FIRST_ARGINT(argp);
1154: } else {
1155: tmpA = (double)FIRST_ARGREAL(argp);
1156: }
1157: resultp->s_type = R_CONSTANT;
1158: switch(func) {
1159: case SIN_F: resultp->s_real = sin(tmpA); break;
1160: case COS_F: resultp->s_real = cos(tmpA); break;
1161: case TAN_F: resultp->s_real = tan(tmpA); break;
1162: case ASIN_F: if(fabs(tmpA) <= 1.0) {
1163: resultp->s_real = asin(tmpA);
1164: } else {
1165: resultp->s_type = S_CONSTANT;
1166: sprintf(aline,"<<ARG OUT OF BOUND>>");
1167: resultp->s_str = strsave(aline);
1168: sprintf(tmpS, "asin()'s arg. is not in the range of [-1.0,+1.0].\n");
1169: capa_msg(MESSAGE_ERROR,tmpS);
1170: }
1171: break;
1172: case ACOS_F: if(fabs(tmpA) <= 1.0) {
1173: resultp->s_real = acos(tmpA);
1174: } else {
1175: resultp->s_type = S_CONSTANT;
1176: sprintf(aline,"<<ARG OUT OF BOUND>>");
1177: resultp->s_str = strsave(aline);
1178: sprintf(tmpS,"acos()'s arg. is not in the range of [-1.0,+1.0].\n");
1179: capa_msg(MESSAGE_ERROR,tmpS);
1180: }
1181: break;
1182: case ATAN_F: resultp->s_real = atan(tmpA); break;
1183: case SINH_F: resultp->s_real = sinh(tmpA); break;
1184: case COSH_F: resultp->s_real = cosh(tmpA); break;
1185: case TANH_F: resultp->s_real = tanh(tmpA); break;
1186: case ASINH_F: resultp->s_real = asinh(tmpA); break;
1187: case ACOSH_F: resultp->s_real = acosh(tmpA); break;
1188: case ATANH_F: resultp->s_real = atanh(tmpA); break;
1189: case J_ZERO_F: resultp->s_real = j0(tmpA); break;
1190: case J_ONE_F: resultp->s_real = j1(tmpA); break;
1191: case Y_ZERO_F: resultp->s_real = y0(tmpA); break;
1192: case Y_ONE_F: resultp->s_real = y1(tmpA); break;
1193: case LOG_F: resultp->s_real = log(tmpA); break;
1194: case LOG_TEN_F: resultp->s_real = log10(tmpA); break;
1195: case EXP_F: resultp->s_real = exp(tmpA); break;
1196: case ERF_F: resultp->s_real = erf(tmpA); break;
1197: case ERFC_F: resultp->s_real = erfc(tmpA); break;
1198: case ABS_F: resultp->s_real = fabs(tmpA); break;
1199: case SQRT_F: if( tmpA >= 0.0) {
1200: resultp->s_real = sqrt(tmpA);
1201: } else {
1202: resultp->s_type = S_CONSTANT;
1203: sprintf(aline,"<<ARG OUT OF BOUND>>");
1204: resultp->s_str = strsave(aline);
1205: sprintf(tmpS, "sqrt()'s arg. is not in the range of [0.0,+Inf].\n");
1206: capa_msg(MESSAGE_ERROR,tmpS);
1207: }
1208: break;
1209: case FLOOR_F: resultp->s_type = I_CONSTANT;
1210: resultp->s_int = (long)floor(tmpA); break;
1211: case CEIL_F: resultp->s_type = I_CONSTANT;
1212: resultp->s_int = (long)ceil(tmpA); break;
1213: case SGN_F: resultp->s_type = I_CONSTANT;
1214: resultp->s_int = (int)SGN(tmpA); break;
1215: }
1216: }
1217: }
1218: break;
1219: case ATANTWO_F:
1220: case J_N_F:
1221: case Y_N_F:
1222: case POW_F: { noError = 1;
1223: switch(FIRST_ARGTYPE(argp)) {
1224: case I_VAR:
1225: case I_CONSTANT: tmpA = (double)FIRST_ARGINT(argp); break;
1226: case R_VAR:
1227: case R_CONSTANT: tmpA = FIRST_ARGREAL(argp); break;
1228: case S_VAR:
1229: case S_CONSTANT: noError = 0;
1230: resultp->s_str = strsave("<<MIS TYPE>>");
1231: sprintf(tmpS,"%s()'s second arg. cannot be string.\n",FuncStack[Func_idx].s_name);
1232: capa_msg(MESSAGE_ERROR,tmpS);
1233: break;
1234: }
1235: switch(SECOND_ARGTYPE(argp)) {
1236: case I_VAR:
1237: case I_CONSTANT: tmpB = (double)SECOND_ARGINT(argp); break;
1238: case R_VAR:
1239: case R_CONSTANT: tmpB = SECOND_ARGREAL(argp); break;
1240: case S_VAR:
1241: case S_CONSTANT: noError = 0;
1242: resultp->s_str = strsave("<<MIS TYPE>>");
1243: sprintf(tmpS,"%s()'s first arg. cannot be string.\n",FuncStack[Func_idx].s_name);
1244: capa_msg(MESSAGE_ERROR,tmpS);
1245: break;
1246: }
1247: if ( POW_F == func ) {
1248: if ((!(((double)((int)tmpA)) == tmpA)) && (tmpB < 0.0)) {
1249: resultp->s_str = strsave("<<ARG OUT OF BOUND>>");
1250: sprintf(tmpS,
1251: "%s()'s arguments would result in a complex number.\n",
1252: FuncStack[Func_idx].s_name);
1253: capa_msg(MESSAGE_ERROR,tmpS);
1254: noError=0;
1255: }
1256: }
1257: if(noError) {
1258: resultp->s_type = R_CONSTANT;
1259: switch( func ) {
1260: case J_N_F: resultp->s_real = jn((int)tmpB, tmpA); break;
1261: case Y_N_F: resultp->s_real = yn((int)tmpB, tmpA); break;
1262: case POW_F: resultp->s_real = pow(tmpB, tmpA); break;
1263: case ATANTWO_F: resultp->s_real = atan2(tmpB, tmpA); break;
1264: }
1265: }else {
1266: resultp->s_type = S_CONSTANT;
1267: }
1268:
1269: }
1270: break;
1271: case TEX_F: { if (Parsemode_f != TeX_MODE) {
1272: resultp->s_type = FIRST_ARGTYPE(argp);
1273: switch(FIRST_ARGTYPE(argp)) {
1274: case I_VAR:
1275: case I_CONSTANT: resultp->s_int = FIRST_ARGINT(argp); break;
1276: case R_VAR:
1277: case R_CONSTANT: resultp->s_real = FIRST_ARGREAL(argp); break;
1278: case S_VAR:
1279: case S_CONSTANT: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
1280: }
1281: } else {
1282: resultp->s_type = SECOND_ARGTYPE(argp);
1283: switch(SECOND_ARGTYPE(argp)) {
1284: case I_VAR:
1285: case I_CONSTANT: resultp->s_int = SECOND_ARGINT(argp); break;
1286: case R_VAR:
1287: case R_CONSTANT: resultp->s_real = SECOND_ARGREAL(argp); break;
1288: case S_VAR:
1289: case S_CONSTANT: resultp->s_str = strsave(SECOND_ARGSTR(argp)); break;
1290: }
1291: }
1292: } break;
1293: case VAR_IN_TEX_F:{
1294:
1295: if (Parsemode_f == TeX_MODE) {
1296: resultp->s_type = FIRST_ARGTYPE(argp);
1297:
1298: switch(FIRST_ARGTYPE(argp)) {
1299: case I_VAR:
1300: case I_CONSTANT: resultp->s_int = FIRST_ARGINT(argp); break;
1301: case R_VAR:
1302: case R_CONSTANT: resultp->s_real = FIRST_ARGREAL(argp); break;
1303: case S_VAR:
1304: case S_CONSTANT: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
1305: }
1306: } else {
1307: resultp->s_type = S_CONSTANT;
1308: resultp->s_str = strsave("");
1309:
1310: }
1311: } break;
1312: case HTML_F: { if (Parsemode_f == HTML_MODE) {
1313: resultp->s_type = FIRST_ARGTYPE(argp);
1314: switch(FIRST_ARGTYPE(argp)) {
1315: case I_VAR:
1316: case I_CONSTANT: resultp->s_int = FIRST_ARGINT(argp); break;
1317: case R_VAR:
1318: case R_CONSTANT: resultp->s_real = FIRST_ARGREAL(argp); break;
1319: case S_VAR:
1320: case S_CONSTANT: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
1321: }
1322: } else {
1323: resultp->s_type = S_CONSTANT;
1324: resultp->s_str = strsave("");
1325: }
1326: /* printf("HTML:%s\n",resultp->s_str); */
1327: } break;
1328: case WEB_F:
1329: case FORMAT_F: { /* web(ASCII,TeX,HTML) */
1330: if( argc == 3 ) {
1331: switch(Parsemode_f) {
1332: case HTML_MODE: {
1333: resultp->s_type = FIRST_ARGTYPE(argp);
1334: switch(FIRST_ARGTYPE(argp)) {
1335: case I_VAR:
1336: case I_CONSTANT: resultp->s_int = FIRST_ARGINT(argp); break;
1337: case R_VAR:
1338: case R_CONSTANT: resultp->s_real = FIRST_ARGREAL(argp); break;
1339: case S_VAR:
1340: case S_CONSTANT: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
1341: }
1342: } break;
1343: case TeX_MODE: {
1344: resultp->s_type = SECOND_ARGTYPE(argp);
1345: switch(SECOND_ARGTYPE(argp)) {
1346: case I_VAR:
1347: case I_CONSTANT: resultp->s_int = SECOND_ARGINT(argp); break;
1348: case R_VAR:
1349: case R_CONSTANT: resultp->s_real = SECOND_ARGREAL(argp); break;
1350: case S_VAR:
1351: case S_CONSTANT: resultp->s_str = strsave(SECOND_ARGSTR(argp)); break;
1352: }
1353: } break;
1354: default: {
1355: resultp->s_type = THIRD_ARGTYPE(argp);
1356: switch(THIRD_ARGTYPE(argp)) {
1357: case I_VAR:
1358: case I_CONSTANT: resultp->s_int = THIRD_ARGINT(argp); break;
1359: case R_VAR:
1360: case R_CONSTANT: resultp->s_real = THIRD_ARGREAL(argp); break;
1361: case S_VAR:
1362: case S_CONSTANT: resultp->s_str = strsave(THIRD_ARGSTR(argp)); break;
1363: }
1364: } break;
1365: }
1366: } else { /* argc == 2 */
1367: switch(Parsemode_f) {
1368: case TeX_MODE: {
1369: resultp->s_type = FIRST_ARGTYPE(argp);
1370: switch(FIRST_ARGTYPE(argp)) {
1371: case I_VAR:
1372: case I_CONSTANT: resultp->s_int = FIRST_ARGINT(argp); break;
1373: case R_VAR:
1374: case R_CONSTANT: resultp->s_real = FIRST_ARGREAL(argp); break;
1375: case S_VAR:
1376: case S_CONSTANT: resultp->s_str = strsave(FIRST_ARGSTR(argp)); break;
1377: }
1378: } break;
1379: default : {
1380: resultp->s_type = SECOND_ARGTYPE(argp);
1381: switch(SECOND_ARGTYPE(argp)) {
1382: case I_VAR:
1383: case I_CONSTANT: resultp->s_int = SECOND_ARGINT(argp); break;
1384: case R_VAR:
1385: case R_CONSTANT: resultp->s_real = SECOND_ARGREAL(argp); break;
1386: case S_VAR:
1387: case S_CONSTANT: resultp->s_str = strsave(SECOND_ARGSTR(argp)); break;
1388: }
1389: } break;
1390: }
1391: }
1392: } break;
1393: case FACTORIAL_F: {
1394: int ii;
1395: unsigned long long l_fac;
1396: double d_fac;
1397:
1398: switch(FIRST_ARGTYPE(argp)) {
1399: case I_VAR:
1400: case I_CONSTANT: {
1401: if( FIRST_ARGINT(argp) < 0 ) {
1402: sprintf(aline,"<<FACTORIAL ERROR>>");
1403: resultp->s_type = S_CONSTANT;
1404: resultp->s_str = strsave(aline);
1405: sprintf(tmpS,"%s()'s arg. cannot be less than zero.\n",FuncStack[Func_idx].s_name);
1406: capa_msg(MESSAGE_ERROR,tmpS);
1407: } else {
1408: if( FIRST_ARGINT(argp) <= 20 ) {
1409: resultp->s_type = I_CONSTANT;
1410: l_fac = 1;
1411: for(ii=2; ii <= FIRST_ARGINT(argp); ii++) { l_fac *= ii; }
1412: resultp->s_int = l_fac;
1413: } else {
1414: resultp->s_type = R_CONSTANT;
1415: d_fac = 362880.0;
1416: for(ii=10; ii <= FIRST_ARGINT(argp); ii++) { d_fac *= ii; }
1417: resultp->s_real = d_fac;
1418: }
1419: }
1420: }
1421: break;
1422: case R_VAR:
1423: case R_CONSTANT: {
1424: if( FIRST_ARGREAL(argp) < 0.0 ) {
1425: sprintf(aline,"<<FACTORIAL ERROR>>");
1426: resultp->s_type = S_CONSTANT;
1427: resultp->s_str = strsave(aline);
1428: sprintf(tmpS,"%s()'s arg. cannot be less than zero.\n", FuncStack[Func_idx].s_name);
1429: capa_msg(MESSAGE_ERROR,tmpS);
1430: } else {
1431: if( FIRST_ARGREAL(argp) <= 20.0 ) {
1432: resultp->s_type = I_CONSTANT;
1433: l_fac = 1;
1434: for(ii=2; ii <= FIRST_ARGREAL(argp); ii++) { l_fac *= ii; }
1435: resultp->s_int = l_fac;
1436: } else {
1437: resultp->s_type = R_CONSTANT;
1438: d_fac = 362880.0;
1439: for(ii=10; ii <= FIRST_ARGREAL(argp); ii++) { d_fac *= ii; }
1440: resultp->s_real = d_fac;
1441: }
1442: }
1443: }
1444: break;
1445: case S_VAR:
1446: case S_CONSTANT: {
1447: sprintf(aline,"<<FACTORIAL ERROR>>");
1448: resultp->s_type = S_CONSTANT;
1449: resultp->s_str = strsave(aline);
1450: sprintf(tmpS,"%s()'s arg. cannot be of string type.\n",FuncStack[Func_idx].s_name);
1451: capa_msg(MESSAGE_ERROR,tmpS);
1452: }
1453: break;
1454: }
1455: } break;
1456: case MOD_F: break;
1457: case REMAINDER_F: break;
1458: case MAX_F:
1459: case MIN_F: { int ii, idx, type;
1460:
1461: tmpArgp = argp;
1462: tmpA = ((func == MIN_F)? MAX_DOUBLE : - MAX_DOUBLE);
1463: type = R_CONSTANT; idx = -1;
1464: noError = 1;
1465: for(ii = 0; (ii < argc)&&(noError); ii++) {
1466: switch (FIRST_ARGTYPE(tmpArgp)) {
1467: case I_VAR:
1468: case I_CONSTANT:
1469: if( type == S_CONSTANT) {
1470: sprintf(aline,"<<ARG TYPE>>");
1471: resultp->s_type = S_CONSTANT;
1472: resultp->s_str = strsave(aline);
1473: sprintf(tmpS,"%s()'s arg. type cannot mix string with int or real.\n",FuncStack[Func_idx].s_name);
1474: capa_msg(MESSAGE_ERROR,tmpS);
1475: noError = 0;
1476: } else {
1477: switch(func) {
1478: case MIN_F:
1479: if( tmpA <= FIRST_ARGINT(tmpArgp) ) {
1480: } else {
1481: idx = ii; type = I_CONSTANT;
1482: tmpA = (double)FIRST_ARGINT(tmpArgp);
1483: }
1484: break;
1485: case MAX_F:
1486: if( tmpA >= FIRST_ARGINT(tmpArgp) ) {
1487: } else {
1488: idx = ii; type = I_CONSTANT;
1489: tmpA = (double)FIRST_ARGINT(tmpArgp);
1490: }
1491: break;
1492: }
1493: }
1494: break;
1495: case R_VAR:
1496: case R_CONSTANT:
1497: if( type == S_CONSTANT ) {
1498: sprintf(aline,"<<ARG TYPE>>");
1499: resultp->s_type = S_CONSTANT;
1500: resultp->s_str = strsave(aline);
1501: sprintf(tmpS,"%s()'s arg. type cannot mix string with int or real.\n",FuncStack[Func_idx].s_name);
1502: capa_msg(MESSAGE_ERROR,tmpS);
1503: noError = 0;
1504: } else {
1505: switch(func) {
1506: case MIN_F:
1507: if( tmpA <= FIRST_ARGREAL(tmpArgp) ) {
1508: } else {
1509: idx = ii; type = R_CONSTANT;
1510: tmpA = FIRST_ARGREAL(tmpArgp);
1511: }
1512: break;
1513: case MAX_F:
1514: if( tmpA >= FIRST_ARGREAL(tmpArgp) ) {
1515: } else {
1516: idx = ii; type = R_CONSTANT;
1517: tmpA = FIRST_ARGREAL(tmpArgp);
1518: }
1519: break;
1520: }
1521: }
1522: break;
1523: case S_VAR:
1524: case S_CONSTANT:
1525: if( (ii != 0)&&(type != S_CONSTANT) ) {
1526: sprintf(aline,"<<ARG TYPE>>");
1527: resultp->s_type = S_CONSTANT;
1528: resultp->s_str = strsave(aline);
1529: sprintf(tmpS," %s()'s arg. type cannot mix string with int or real.\n",FuncStack[Func_idx].s_name);
1530: capa_msg(MESSAGE_ERROR,tmpS);
1531: noError = 0;
1532: } else {
1533: if( ii == 0 ) { idx = 0; strcpy(tmpS, FIRST_ARGSTR(tmpArgp)); }
1534: type = S_CONSTANT;
1535: switch( func) {
1536: case MIN_F:
1537: if( strcmp(tmpS, FIRST_ARGSTR(tmpArgp)) <= 0 ) {
1538: } else {
1539: idx = ii;
1540: strcpy(tmpS, FIRST_ARGSTR(tmpArgp));
1541: }
1542: break;
1543: case MAX_F:
1544: if( strcmp(tmpS, FIRST_ARGSTR(tmpArgp)) >= 0 ) {
1545: } else {
1546: idx = ii;
1547: strcpy(tmpS, FIRST_ARGSTR(tmpArgp));
1548: }
1549: break;
1550: }
1551: }
1552: break;
1553: }
1554: tmpArgp = tmpArgp->a_next;
1555: }
1556: if( noError ) {
1557: for(tmpArgp=argp,ii=0; ii<idx; ii++) { tmpArgp=tmpArgp->a_next; }
1558: resultp->s_type = type;
1559: switch(type) {
1560: case I_CONSTANT: resultp->s_int = (tmpArgp->a_sp)->s_int;
1561: break;
1562: case R_CONSTANT: resultp->s_real = (tmpArgp->a_sp)->s_real;
1563: break;
1564: case S_CONSTANT: resultp->s_str = strsave((tmpArgp->a_sp)->s_str);
1565: break;
1566: }
1567: }
1568:
1569: }
1570: break;
1571: case ROUNDTO_F: {
1572: noError = 1; hh = 0; /* reuse integer hh and mm */
1573: switch(FIRST_ARGTYPE(argp)) {
1574: case I_VAR:
1575: case I_CONSTANT: mm = FIRST_ARGINT(argp); break;
1576: case R_VAR:
1577: case R_CONSTANT: mm = (int)FIRST_ARGREAL(argp); break;
1578: case S_VAR:
1579: case S_CONSTANT: noError = 0;
1580: resultp->s_type = S_CONSTANT;
1581: resultp->s_str = strsave("<<MIS TYPE>>");
1582: sprintf(tmpS,
1583: "%s()'s second arg. cannot be string.\n",FuncStack[Func_idx].s_name);
1584: capa_msg(MESSAGE_ERROR,tmpS);
1585: break;
1586: }
1587: switch(SECOND_ARGTYPE(argp)) {
1588: case I_VAR:
1589: case I_CONSTANT: hh = SECOND_ARGINT(argp); break;
1590: case R_VAR:
1591: case R_CONSTANT: tmpA = SECOND_ARGREAL(argp); break;
1592: case S_VAR:
1593: case S_CONSTANT: noError = 0;
1594: resultp->s_type = S_CONSTANT;
1595: resultp->s_str = strsave("<<MIS TYPE>>");
1596: sprintf(tmpS,
1597: "%s()'s first arg. cannot be string.\n",
1598: FuncStack[Func_idx].s_name);
1599: capa_msg(MESSAGE_ERROR,tmpS);
1600: break;
1601: }
1602: if(noError) {
1603: resultp->s_type = R_CONSTANT;
1604: if( hh != 0 ) {
1605: resultp->s_type = I_CONSTANT;
1606: resultp->s_int = hh;
1607: } else {
1608: if ( mm >= 0 ) {
1609: sprintf(fmt_str,"%%.%df",mm);
1610: sprintf(num_str,fmt_str,tmpA);
1611: tmpB = atof(num_str);
1612: resultp->s_real = tmpB;
1613: } else {
1614: sprintf(tmpS,"%s()'s second arg. cannot be negative (%d).\n",
1615: FuncStack[Func_idx].s_name,mm);
1616: capa_msg(MESSAGE_ERROR,tmpS);
1617: resultp->s_real = tmpA; /* not changed */
1618: }
1619: }
1620: }
1621: } break;
1622: case EVALUATE_F: { char *f_str, *v_str, *pt_str, *out_come;
1623: noError = 1;
1624: switch(FIRST_ARGTYPE(argp)) { /* now only accepts string like "0.0,0.1,0.2,0.3,0.4,0.5" */
1625: case I_VAR:
1626: case I_CONSTANT: noError = 0;
1627: resultp->s_type = S_CONSTANT;
1628: resultp->s_str = strsave("<<Evaulate Formula: Pts TYPE incorrect>>");
1629: sprintf(tmpS,
1630: "%s()'s third arg. cannot be integer.\n",FuncStack[Func_idx].s_name);
1631: capa_msg(MESSAGE_ERROR,tmpS);
1632: break;
1633: case R_VAR:
1634: case R_CONSTANT: noError = 0;
1635: resultp->s_type = S_CONSTANT;
1636: resultp->s_str = strsave("<<Evaulate Formula: Pts TYPE incorrect>>");
1637: sprintf(tmpS,
1638: "%s()'s third arg. cannot be integer.\n",FuncStack[Func_idx].s_name);
1639: capa_msg(MESSAGE_ERROR,tmpS);
1640: break;
1641: case S_VAR:
1642: case S_CONSTANT:
1643: pt_str = FIRST_ARGSTR(argp);
1644: break;
1645: }
1646: switch(SECOND_ARGTYPE(argp)) {
1647: case I_VAR:
1648: case I_CONSTANT:
1649: case R_VAR:
1650: case R_CONSTANT: noError = 0;
1651: resultp->s_type = S_CONSTANT;
1652: resultp->s_str = strsave("<<Evaluate Formula: Var list TYPE incorrect>>");
1653: sprintf(tmpS,
1654: "%s()'s second arg. cannot be number.\n",FuncStack[Func_idx].s_name);
1655: capa_msg(MESSAGE_ERROR,tmpS);
1656: break;
1657:
1658: case S_VAR:
1659: case S_CONSTANT: v_str = SECOND_ARGSTR(argp);
1660: break;
1661: }
1662: switch(THIRD_ARGTYPE(argp)) {
1663: case I_VAR:
1664: case I_CONSTANT:
1665: case R_VAR:
1666: case R_CONSTANT: noError = 0;
1667: resultp->s_type = S_CONSTANT;
1668: resultp->s_str = strsave("<<Evaluate Formula: Formula TYPE incorrect>>");
1669: sprintf(tmpS,
1670: "%s()'s first arg. cannot be number.\n",FuncStack[Func_idx].s_name);
1671: capa_msg(MESSAGE_ERROR,tmpS);
1672: break;
1673: case S_VAR:
1674: case S_CONSTANT: f_str = THIRD_ARGSTR(argp);
1675: break;
1676: }
1677: if(noError) {
1678: resultp->s_type = S_CONSTANT;
1679: /* printf("EVALUATE:::%s,%s,%s\n",f_str, v_str, pt_str); */
1680: out_come = eval_formula_range_str(f_str, v_str, pt_str);
1681: if( !out_come ) {
1682: resultp->s_str = strsave("<<Evaluate formula:: NULL>>");
1683: sprintf(tmpS,
1684: "%s() cannot evaluate the formula correctly.\n",FuncStack[Func_idx].s_name);
1685: capa_msg(MESSAGE_ERROR,tmpS);
1686: } else {
1687: resultp->s_str = out_come;
1688: }
1689: }
1690: }
1691: break;
1692: case CAPAID_PLUS:
1693: {
1694: extern Problem_t* FirstProblem_p;
1695: extern Problem_t* LexiProblem_p;
1696: Problem_t* problem;
1697: int num_char,pin;
1698: errCode = 0;
1699: if (argc==1) {
1700: switch( FIRST_ARGTYPE(argp) ) {
1701: case I_VAR: case I_CONSTANT: num_char=FIRST_ARGINT(argp); break;
1702: case R_VAR: case R_CONSTANT: errCode = 1; break;
1703: case S_VAR: case S_CONSTANT: errCode = 1; break;
1704: }
1705: } else {
1706: switch( SECOND_ARGTYPE(argp) ) {
1707: case I_VAR: case I_CONSTANT: num_char=SECOND_ARGINT(argp); break;
1708: case R_VAR: case R_CONSTANT: errCode = 1; break;
1709: case S_VAR: case S_CONSTANT: errCode = 1; break;
1710: }
1711: }
1712:
1713: if( errCode == 0 ) {
1714: if ( FirstProblem_p ) {
1715: problem=FirstProblem_p;
1716: } else {
1717: problem=LexiProblem_p;
1718: }
1719: if (!(problem->capaidplus)) capa_mfree(problem->capaidplus);
1720: if (-1==(tmpInt=which_set(argc-1,argp,resultp))) break;
1721: pin=capa_PIN(Parse_student_number,tmpInt,0);
1722: problem->capaidplus = capa_id_plus(Parse_student_number,
1723: tmpInt,num_char);
1724: resultp->s_type = S_CONSTANT;
1725: resultp->s_str = strsave(problem->capaidplus);
1726: } else {
1727: resultp->s_type = S_CONSTANT;
1728: resultp->s_str = strsave("<<INCORRECT ARGS TO CAPAID_PLUS>>");
1729: }
1730: }
1731: break;
1732: case SEAT_NUMBER:
1733: {
1734: int filenum;
1735: double filedoub;
1736: char *filename;
1737: if ( argc == 1 ) {
1738: switch( FIRST_ARGTYPE(argp)) {
1739: case I_VAR: case I_CONSTANT: filenum=FIRST_ARGINT(argp);
1740: filename=capa_malloc(TMP_LINE_LENGTH,1);
1741: sprintf(filename,"%d",filenum);
1742: break;
1743: case R_VAR: case R_CONSTANT: filedoub=FIRST_ARGREAL(argp);
1744: filename=capa_malloc(TMP_LINE_LENGTH,1);
1745: sprintf(filename,"%f",filedoub);
1746: break;
1747: case S_VAR: case S_CONSTANT:
1748: filename=strsave(FIRST_ARGSTR(argp)); break;
1749: }
1750: } else {
1751: filename=NULL;
1752: }
1753: resultp->s_type = S_CONSTANT;
1754: resultp->s_str = capa_get_seat(Parse_student_number,filename);
1755: if ( filename != NULL ) capa_mfree(filename);
1756: break;
1757: }
1758: case DURATION: { resultp->s_type = I_CONSTANT;
1759: resultp->s_int=capa_get_duration(Parse_student_number,
1760: Parse_section,Parse_set);
1761: } break;
1.3 albertel 1762: case MANAGERMODE_F: { resultp->s_type = I_CONSTANT;
1763: resultp->s_int=managermode;
1764: }break;
1765: case CORRECT_F: {
1766:
1767: }break;
1768:
1769: case TRIES_F: {
1770:
1771: }break;
1772:
1773: case GRADE_F: {
1774:
1775: }break;
1776:
1.1 albertel 1777: case MIS_ARG_COUNT:
1778: { resultp->s_type = S_CONSTANT;
1779: resultp->s_str = strsave("<<ARG COUNT>>");
1.3 albertel 1780: sprintf(tmpS,"%s()'s arg. count is not correct.\n",
1781: FuncStack[Func_idx].s_name);
1.1 albertel 1782: capa_msg(MESSAGE_ERROR,tmpS);
1783: } break;
1784: case UNKNOWN_F:
1785: default: { resultp->s_type = S_CONSTANT;
1786: resultp->s_str = strsave("<<UNKNOWN FUNCTION>>");
1787: sprintf(tmpS,"%s() unknown.\n",FuncStack[Func_idx].s_name);
1788: capa_msg(MESSAGE_ERROR,tmpS);
1789:
1790: } break;
1791: }
1792:
1793: return (resultp);
1794: }
1795:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>