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