--- capa/capa51/pProj/capaGrammarDef.y 1999/09/28 21:26:21 1.1 +++ capa/capa51/pProj/capaGrammarDef.y 2000/08/07 20:47:29 1.13 @@ -1,6 +1,30 @@ +/* main CAPA parser + Copyright (C) 1992-2000 Michigan State University + + The CAPA system is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The CAPA system is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the CAPA system; see the file COPYING. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + As a special exception, you have permission to link this program + with the TtH/TtM library and distribute executables, as long as you + follow the requirements of the GNU GPL in regard to all of the + software in the executable aside from TtH/TtM. +*/ + /* ========================================================================== */ /* capaGrammarDef.y created by Isaac Tsai */ -/* 1998, 1999 copyrighted by Isaac Tsai */ +/* 1998, 1999 by Isaac Tsai */ /* no longer there is a length constrain on string concatenation July 13 1998 */ /* /RMAP() function */ /* TODO: new mechanism to collect answer informations */ @@ -36,17 +60,18 @@ case S_VAR: case S_CONSTANT: \ printf("STR(%s)\n",(xx)->s_str); break; \ } } -#else +#else /* YACC_DBUG */ #define YYDBUG_PR1(xx) { } #define YYDBUG_PR2(xx,yy) { } #define YYDBUG_PR3(xx,yy,zz) { } #define YYDBUG_PR4(xx,yy,zz,aa) { } #define YYDBUG_SYM(xx) { } -#endif +#endif /* YACC_DBUG */ int yylex(); void yyerror(char*); void free_calc_expr(Symbol*); +void assign_pts (Symbol *, Symbol *, Symbol *); /******************************************************************************/ /* GLOBAL VARIABLES */ /******************************************************************************/ @@ -117,7 +142,7 @@ PointsList_t *LastPtsList; %token ANS_OFF ANS_ON ANS_OR ANS_ORDERED %token ANS_PATH ANS_PCREDIT ANS_PLUS ANS_RANGE %token ANS_SHOW_BR ANS_SIG ANS_TOLERANCE ANS_TRY ANS_TYPE -%token ANS_UNFMT ANS_UNIT ANS_WEIGHT +%token ANS_UNFMT ANS_UNIT ANS_VERBATIM ANS_WEIGHT %token VAR_RANGE VERBATIM %token SLASH FORMAT %token EQ_op NE_op GT_op GE_op LT_op LE_op AND_op OR_op EoL @@ -194,7 +219,7 @@ a_line : startL statement EoL | EoL { YYDBUG_PR1(" a_line <= (CR)\n"); } | VERBATIM { YYDBUG_PR1(" a_line <= (VERBATIM)\n"); switch(Parsemode_f) { - case TeX_MODE: append_text("\begin{verbatim}"); + case TeX_MODE: append_text("\\begin{verbatim}"); break; case HTML_MODE: append_text("
");
 					    break;
@@ -202,9 +227,9 @@ a_line       :  startL  statement EoL
                                           append_text($1->s_str);
                                           capa_mfree($1->s_str); capa_mfree((char *)$1);
 	                                  switch(Parsemode_f) {
-					  case TeX_MODE: append_text("\end{verbatim}");
+					  case TeX_MODE: append_text("\\end{verbatim}\n");
 					    break;
-					  case HTML_MODE: append_text("
"); + case HTML_MODE: append_text("\n"); break; } } @@ -287,36 +312,36 @@ statement : IDENTIFIER '=' calc_expr ; rqo_def : rqo_speca { rqo_1spec(); } - | rqo_speca "," rqo_def { rqo_2spec(); } + | rqo_speca ',' rqo_def { rqo_2spec(); } ; rqo_speca : an_integer {start_rqo_type(SINGLE);append_rqo($1);} - | an_integer "!" {start_rqo_type(IMMOBILE);append_rqo($1);} - | an_integer "-" an_integer {start_rqo_type(RANGE);append_rqo($1); + | an_integer '!' {start_rqo_type(IMMOBILE);append_rqo($1);} + | an_integer '-' an_integer {start_rqo_type(RANGE);append_rqo($1); append_rqo($3); } - | an_integer "~" rqo_specb {prefix_rqo($1);} - | an_integer "+" rqo_specc {prefix_rqo($1);} + | an_integer '~' rqo_specb {prefix_rqo($1);} + | an_integer '+' rqo_specc {prefix_rqo($1);} ; rqo_specb : an_integer {start_rqo_type(ALL_MIX);append_rqo($1);} - | an_integer "~" rqo_specb {prefix_rqo($1);} - | an_integer "+" an_integer {start_rqo_type(LAST_FIXED);append_rqo($1); + | an_integer '~' rqo_specb {prefix_rqo($1);} + | an_integer '+' an_integer {start_rqo_type(LAST_FIXED);append_rqo($1); append_rqo($3);} ; rqo_specc : an_integer {start_rqo_type(ALL_FIXED);append_rqo($1);} - | an_integer "+" rqo_specd {prefix_rqo($1);} - | an_integer "~" rqo_spece {prefix_rqo($1);} + | an_integer '+' rqo_specd {prefix_rqo($1);} + | an_integer '~' rqo_spece {prefix_rqo($1);} ; rqo_specd : an_integer {start_rqo_type(ALL_FIXED);append_rqo($1);} - | an_integer "+" rqo_specd {prefix_rqo($1);} + | an_integer '+' rqo_specd {prefix_rqo($1);} ; rqo_spece : an_integer {start_rqo_type(FIRST_FIXED);append_rqo($1);} - | an_integer "~" rqo_spece {prefix_rqo($1);} - | an_integer "+" an_integer {start_rqo_type(BOTH_FIXED);append_rqo($1); + | an_integer '~' rqo_spece {prefix_rqo($1);} + | an_integer '+' an_integer {start_rqo_type(BOTH_FIXED);append_rqo($1); append_rqo($3);} ; @@ -332,7 +357,7 @@ q_text : TEXT_LINE ; if_expr : CAPA_IF '(' calc_expr ')' - { int leng; /* begin_next_line(); no use, can be get rid of */ + { int leng=0; /* begin_next_line(); no use, can be get rid of */ YYDBUG_PR2("(IF expr )\n",IFcount); switch($3->s_type) { case IDENTIFIER: @@ -358,8 +383,10 @@ if_expr : CAPA_IF '(' calc_expr ' } break; case S_CONSTANT: - leng = strlen($3->s_str); - capa_mfree($3->s_str); + if ( $3->s_str) { + leng = strlen($3->s_str); + capa_mfree($3->s_str); + } if(leng == 0) { IFstatus[IFcount] = IF_FALSE; begin_if_skip(); @@ -369,8 +396,11 @@ if_expr : CAPA_IF '(' calc_expr ' } break; case S_VAR: - leng = strlen($3->s_str); - if(leng == 0) { + if ( $3->s_str) { + leng = strlen($3->s_str); + capa_mfree($3->s_str); + } + if(leng == 0) { IFstatus[IFcount] = IF_FALSE; begin_if_skip(); }else{ @@ -500,6 +530,10 @@ ans_infospec : ANS_TOLERANCE '=' a_numbe } | ANS_SHOW_BR '=' ANS_OFF { LexiProblem_p->show_br = DONOT_SHOW; } + | ANS_VERBATIM '=' ANS_ON { LexiProblem_p->verbatim = DO_VERBATIM; + } + | ANS_VERBATIM '=' ANS_OFF { LexiProblem_p->verbatim = DONOT_VERBATIM; + } | ANS_BOX_SHOW '=' ANS_ON { LexiProblem_p->show_ans_box = DO_SHOW; } | ANS_BOX_SHOW '=' ANS_OFF { LexiProblem_p->show_ans_box = DONOT_SHOW; @@ -549,54 +583,64 @@ pt_list : pt_list ',' point_coo | pt_range { } ; -pt_range : point_coord ':' point_coord '#' IDENTIFIER { PointsList_t *pt; - - if( LastPtsList != NULL ) { - LastPtsList->pts_next = gen_ptslist( $1, $3, $5 ); - pt = LastPtsList->pts_next; - while( pt->pts_next != NULL ) { - pt = pt->pts_next; - } - LastPtsList = pt; - } else { - CurrPtsList = gen_ptslist( $1, $3, $5 ); - LastPtsList = CurrPtsList; - } - if( $1->s_type == S_CONSTANT ) { - capa_mfree($1->s_str); capa_mfree((char *)$1); - } - if( $3->s_type == S_CONSTANT ) { - capa_mfree($3->s_str); capa_mfree((char *)$3); - } - } - | point_coord ':' point_coord '#' a_number { PointsList_t *pt; - - if( LastPtsList != NULL ) { - LastPtsList->pts_next = gen_ptslist( $1, $3, $5 ); - pt = LastPtsList->pts_next; - while( pt->pts_next != NULL ) { - pt = pt->pts_next; - } - LastPtsList = pt; - } else { - CurrPtsList = gen_ptslist( $1, $3, $5 ); - LastPtsList = CurrPtsList; - } - if( $1->s_type == S_CONSTANT ) { - capa_mfree($1->s_str); capa_mfree((char *)$1); - } - if( $3->s_type == S_CONSTANT ) { - capa_mfree($3->s_str); capa_mfree((char *)$3); - } - if( $5->s_type == I_CONSTANT || $5->s_type == R_CONSTANT) { - capa_mfree((char *)$5); - } - } +pt_range : point_coord ':' point_coord '#' IDENTIFIER + { + assign_pts($1,$3,$5); + /*PointsList_t *pt; + if( LastPtsList != NULL ) { + LastPtsList->pts_next = gen_ptslist( $1, $3, $5 ); + pt = LastPtsList->pts_next; + while( pt->pts_next != NULL ) { + pt = pt->pts_next; + } + LastPtsList = pt; + } else { + CurrPtsList = gen_ptslist( $1, $3, $5 ); + LastPtsList = CurrPtsList; + } + if( $1->s_type == S_CONSTANT ) { + capa_mfree($1->s_str); capa_mfree((char *)$1); + } + if( $3->s_type == S_CONSTANT ) { + capa_mfree($3->s_str); capa_mfree((char *)$3); + } + */ + } + | point_coord ':' point_coord '#' ARRAY_ID '[' calc_expr ']' + { assign_pts($1,$3,get_array_symbol($5,$7,1)); } + | point_coord ':' point_coord '#' a_number + { + assign_pts($1,$3,$5); + /*PointsList_t *pt; + + if( LastPtsList != NULL ) { + LastPtsList->pts_next = gen_ptslist( $1, $3, $5 ); + pt = LastPtsList->pts_next; + while( pt->pts_next != NULL ) { + pt = pt->pts_next; + } + LastPtsList = pt; + } else { + CurrPtsList = gen_ptslist( $1, $3, $5 ); + LastPtsList = CurrPtsList; + } + if( $1->s_type == S_CONSTANT ) { + capa_mfree($1->s_str); capa_mfree((char *)$1); + } + if( $3->s_type == S_CONSTANT ) { + capa_mfree($3->s_str); capa_mfree((char *)$3); + } + if( $5->s_type == I_CONSTANT || $5->s_type == R_CONSTANT) { + capa_mfree((char *)$5); + } + */ + } ; -point_coord : IDENTIFIER { $$ = $1; } - | S_CONSTANT { $$ = $1; } +point_coord : IDENTIFIER { $$ = $1; } + | ARRAY_ID '[' calc_expr ']' { $$ = get_array_symbol($1,$3,1); } + | S_CONSTANT { $$ = $1; } ; @@ -646,7 +690,7 @@ answer_comp : ANS_CS { map_expr : startM '(' basic_constr ';' var_list ';' arg_list ')' - { char key[SIXTEEN]; + { char key[SMALL_LINE_BUFFER]; char warn_msg[WARN_MSG_LENGTH]; int result=0; @@ -674,7 +718,7 @@ map_expr : startM '(' basic_constr ' free_arglist($7->s_argp); } | startR '(' basic_constr ';' var_list ';' arg_list ')' - { char key[SIXTEEN]; + { char key[SMALL_LINE_BUFFER]; char warn_msg[WARN_MSG_LENGTH]; int result=0; @@ -829,7 +873,10 @@ an_integer : I_CONSTANT a_real : R_CONSTANT { $$ = $1; } ; -an_array : ARRAY_ID '[' calc_expr ']' { $$=get_array_symbol($1,$3,1); } +an_array : ARRAY_ID '[' calc_expr ']' { + YYDBUG_PR1(" an_array <= ARRAY_ID '['calc_expr ']' "); + $$=get_array_symbol($1,$3,1); + } ; startQ : { /* first matching will occur before first line of input text */ @@ -889,7 +936,6 @@ Symbol *name,*index;int free_symbols; Symbol *s_p, *a_p; char *key, *tmp; int leng, idx_len; - leng = strlen(name->s_name)+8; /* [ ] */ switch(index->s_type) { @@ -913,7 +959,7 @@ Symbol *name,*index;int free_symbols; sprintf(key,"%s[%s]",name->s_name,tmp); a_p = find_arrayid(name->s_name); /* use the array name to search array tree */ - /* */ + /* did not check for error! */ s_p = find_array_by_index(a_p,key); /* use the index portion to search along array linked list */ capa_mfree((char *)tmp); capa_mfree((char *)key); @@ -933,17 +979,17 @@ Symbol *ar_name;int num_elem; { int i; Symbol *arg_list,*a_p; - char idx_str[SIXTEEN]; + char idx_str[MAX_BUFFER_SIZE]; - a_p = find_arrayid(ar_name); + a_p = find_arrayid(ar_name->s_name); i = 1; - sprintf(idx_str,"%ld",i); /* create array elements with integer index */ + sprintf(idx_str,"%s[%d]",ar_name->s_name,i); /* create array elements with integer index */ arg_list = find_array_by_index(a_p,idx_str); /* will create a new element if not found */ arg_list->s_argc=1; arg_list->s_argp=new_arglist(arg_list); for (i=2;i<=num_elem;i++) { - sprintf(idx_str,"%ld",i); + sprintf(idx_str,"%s[%d]",ar_name->s_name,i); arg_list->s_argc++; arg_list->s_argp=addto_arglist(arg_list->s_argp,find_array_by_index(a_p,idx_str)); } @@ -1074,7 +1120,7 @@ append_warn(type,str) int type;char *str /*********** if *b is a constant symbol, destroy (free) b ********************/ /*********** if *a is a var symbol, create a new symbol **********************/ /* do not free(*a) */ -/* */ +/* If either a or b is invalid it propagates the error up the parse tree */ Symbol * symbols_op(a, b, op) Symbol *a; Symbol *b; int op; { @@ -1089,12 +1135,11 @@ if( a->s_type == IDENTIFIER || b->s_type if(a->s_type == IDENTIFIER) { /* a is IDENTIFIER */ sprintf(warn_msg,"var \"%s\" not defined before use.\n", a->s_name); capa_msg(MESSAGE_ERROR,warn_msg); - return (b); + return (a); } else { /* b is IDENTIFIER */ - sprintf(warn_msg, - "var \"%s\" not defined before use.\n",b->s_name); + sprintf(warn_msg,"var \"%s\" not defined before use.\n",b->s_name); capa_msg(MESSAGE_ERROR,warn_msg); - return (a); + return (b); } } else { /* a and b are neither identifiers */ if( (a->s_type == I_VAR) || @@ -1139,70 +1184,84 @@ if( a->s_type == IDENTIFIER || b->s_type (b->s_type == S_VAR) || (b->s_type == S_CONSTANT) ) { /* either a or b is a string */ type = S_CONSTANT; /* the return type is a string */ if( (a->s_type == S_VAR) || (a->s_type == S_CONSTANT) ) { /* a is a string */ - switch( b->s_type ) { - case I_VAR: - case I_CONSTANT: - leng = SIXTEEN; /* assuming a long integer does not exceed 16 digits*/ - b_str= capa_malloc(sizeof(char), leng); - sprintf(b_str,"%ld", b->s_int); - break; - case R_VAR: - case R_CONSTANT: - leng = SMALL_LINE_BUFFER;/*assuming a double does not exceed128chars*/ - b_str= capa_malloc(sizeof(char), leng); - sprintf(b_str,"%.15g", b->s_real); - break; - case S_VAR: - case S_CONSTANT: /* DONE: get rid of limitations on b_str[] */ - leng = strlen( b->s_str ) + 1; - b_str= capa_malloc(sizeof(char), leng); - sprintf(b_str,"%s",b->s_str); - /*if(b->s_type == S_CONSTANT) capa_mfree(b->s_str);*/ - break; - } - switch( op ) { - case ADD_op: - leng = strlen( a->s_str ) + strlen(b_str) + 1; - r_strp = capa_malloc(sizeof(char), leng); /* **** */ - strcat(r_strp, a->s_str); - strcat(r_strp, b_str); /* concatenate two strings together */ - if( !new ) capa_mfree(a->s_str); - a_symp->s_str = r_strp; - break; - case SUB_op: - case MUL_op: - case DIV_op: - case IDIV_op: - if( !new ) capa_mfree(a->s_str); - a_symp->s_str = strsave("<>"); - sprintf(warn_msg,"integer division (%%) cannot accept string operand!\n"); - capa_msg(MESSAGE_ERROR,warn_msg); - break; - case EQ_op: a_symp->s_int = (strcmp(a->s_str, b_str) == 0? 1: 0); - type = I_CONSTANT; break; - case NE_op: a_symp->s_int = (strcmp(a->s_str, b_str) == 0? 0: 1); - type = I_CONSTANT; break; - case GT_op: a_symp->s_int = (strcmp(a->s_str, b_str) > 0? 1: 0); - type = I_CONSTANT; break; - case GE_op: a_symp->s_int = (strcmp(a->s_str, b_str) >= 0? 1: 0); - type = I_CONSTANT; break; - case LT_op: a_symp->s_int = (strcmp(a->s_str, b_str) < 0? 1: 0); - type = I_CONSTANT; break; - case LE_op: a_symp->s_int = (strcmp(a->s_str, b_str) <= 0? 1: 0); - type = I_CONSTANT; break; - case AND_op: if( (a->s_str[0] != 0) && (b_str[0] != 0)) { - a_symp->s_int = 1; - } else { - a_symp->s_int = 0; - } - type = I_CONSTANT; break; - case OR_op: if( (a->s_str[0] != 0) || (b_str[0] != 0)) { - a_symp->s_int = 1; - } else { - a_symp->s_int = 0; - } - type = I_CONSTANT; break; - } + if (a->s_str == NULL || + (((b->s_type == S_VAR) || (b->s_type == S_CONSTANT)) && b->s_str == NULL)) { + if (a->s_str == NULL) { + sprintf(warn_msg,"variable %s has not yet been assigned a value.\n",a->s_name); + capa_msg(MESSAGE_ERROR,warn_msg); + } + if (((b->s_type == S_VAR) || (b->s_type == S_CONSTANT)) && b->s_str == NULL) { + sprintf(warn_msg,"variable %s has not yet been assigned a value.\n",a->s_name); + capa_msg(MESSAGE_ERROR,warn_msg); + } + } else { /* a is a valid string */ + switch( b->s_type ) { + case I_VAR: + case I_CONSTANT: + leng = SMALL_LINE_BUFFER; /* assuming a long integer does not exceed 128 digits*/ + b_str= capa_malloc(sizeof(char), leng); + sprintf(b_str,"%ld", b->s_int); + break; + case R_VAR: + case R_CONSTANT: + leng = SMALL_LINE_BUFFER;/*assuming a double does not exceed128chars*/ + b_str= capa_malloc(sizeof(char), leng); + sprintf(b_str,"%.15g", b->s_real); + break; + case S_VAR: + case S_CONSTANT: /* DONE: get rid of limitations on b_str[] */ + leng = strlen( b->s_str ) + 1; + b_str= capa_malloc(sizeof(char), leng); + sprintf(b_str,"%s",b->s_str); + /*if(b->s_type == S_CONSTANT) capa_mfree(b->s_str);*/ + break; + } + switch( op ) { + case ADD_op: + leng = strlen( a->s_str ) + strlen(b_str) + 1; + r_strp = capa_malloc(sizeof(char), leng); /* **** */ + strcat(r_strp, a->s_str); + strcat(r_strp, b_str); /* concatenate two strings together */ + if( !new ) capa_mfree(a->s_str); + a_symp->s_str = r_strp; + break; + case SUB_op: + case MUL_op: + case DIV_op: + case IDIV_op: + if( !new ) capa_mfree(a->s_str); + a_symp->s_str = strsave("<>"); + sprintf(warn_msg,"integer division (%%) cannot accept string operand!\n"); + capa_msg(MESSAGE_ERROR,warn_msg); + break; + case EQ_op: a_symp->s_int = (strcmp(a->s_str, b_str) == 0? 1: 0); + type = I_CONSTANT; break; + case NE_op: a_symp->s_int = (strcmp(a->s_str, b_str) == 0? 0: 1); + type = I_CONSTANT; break; + case GT_op: a_symp->s_int = (strcmp(a->s_str, b_str) > 0? 1: 0); + type = I_CONSTANT; break; + case GE_op: a_symp->s_int = (strcmp(a->s_str, b_str) >= 0? 1: 0); + type = I_CONSTANT; break; + case LT_op: a_symp->s_int = (strcmp(a->s_str, b_str) < 0? 1: 0); + type = I_CONSTANT; break; + case LE_op: a_symp->s_int = (strcmp(a->s_str, b_str) <= 0? 1: 0); + type = I_CONSTANT; break; + case AND_op: + if( (a->s_str[0] != 0) && (b_str[0] != 0)) { + a_symp->s_int = 1; + } else { + a_symp->s_int = 0; + } + type = I_CONSTANT; break; + case OR_op: + if( (a->s_str[0] != 0) || (b_str[0] != 0)) { + a_symp->s_int = 1; + } else { + a_symp->s_int = 0; + } + type = I_CONSTANT; break; + } + } if (b_str!=NULL) capa_mfree(b_str); } else { /* b is string and a is either integer or real */ switch( a->s_type ) { @@ -1326,7 +1385,7 @@ char * format_toTeX( real ) char *real; { int idx, length, fraclength, i_exp; - char *expo_p, fracS[SIXTEEN], result[ONE_K], *areal; + char *expo_p, fracS[SMALL_LINE_BUFFER], result[ONE_K], *areal; char warn_msg[WARN_MSG_LENGTH]; length = strlen(real); @@ -1374,7 +1433,7 @@ char * format_toHTML( real ) char *real; { int idx, length, fraclength, i_exp; - char *expo_p, fracS[SIXTEEN], result[ONE_K], *areal; + char *expo_p, fracS[SMALL_LINE_BUFFER], result[ONE_K], *areal; char warn_msg[WARN_MSG_LENGTH]; length = strlen(real); @@ -1487,16 +1546,22 @@ display_var( s )Symbol *s; } } break; - case S_VAR: case S_CONSTANT: - aline = (char *)capa_malloc(strlen(s->s_str)+1,1); - sprintf(aline,"%s",s->s_str); + case S_VAR: case S_CONSTANT: + if (s->s_str == NULL) { + sprintf(warn_msg,"variable %s has not yet been assigned a value.\n", + s->s_name); + capa_msg(MESSAGE_ERROR,warn_msg); + aline=(char *)capa_malloc(9,1); + sprintf(aline,"NO VALUE"); + } else { + aline = (char *)capa_malloc(strlen(s->s_str)+1,1); + sprintf(aline,"%s",s->s_str); + } break; } append_text(aline); capa_mfree((char *)aline); - if(s->s_format) { - capa_mfree((char *)s->s_format); - } + if(s->s_format) { capa_mfree((char *)s->s_format); } s->s_format = NULL; switch(s->s_type) { /* free up spaces taken by constants */ case I_CONSTANT: @@ -1765,6 +1830,32 @@ assign_id_list( s ) Symbol *s; } } +/* void assign_pts ( Symbol* coord1, Symbol* coord2, Symbol* num) { */ +void assign_pts (coord1, coord2, num)Symbol *coord1;Symbol *coord2;Symbol *num; +{ + PointsList_t *pt; + if( LastPtsList != NULL ) { + LastPtsList->pts_next = gen_ptslist( coord1, coord2, num ); + pt = LastPtsList->pts_next; + while( pt->pts_next != NULL ) { + pt = pt->pts_next; + } + LastPtsList = pt; + } else { + CurrPtsList = gen_ptslist( coord1, coord2, num ); + LastPtsList = CurrPtsList; + } + if(coord1->s_type == S_CONSTANT) { + capa_mfree(coord1->s_str); capa_mfree((char *)coord1); + } + if(coord2->s_type == S_CONSTANT) { + capa_mfree(coord2->s_str); capa_mfree((char *)coord2); + } + if(num->s_type == I_CONSTANT || num->s_type == R_CONSTANT) { + capa_mfree((char *)num); + } +} + /* =========================================================================== */