--- capa/capa51/pProj/capaFormula.y 2000/07/07 18:30:57 1.4 +++ capa/capa51/pProj/capaFormula.y 2001/06/01 18:09:04 1.10 @@ -2,23 +2,28 @@ 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 Library General Public License as + 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 - Library General Public License for more details. + General Public License for more details. - You should have received a copy of the GNU Library General Public + 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. */ + 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. +*/ /* ====================================================== */ /* capaFormula.y created by Isaac Tsai @ Feb 1999 */ -/* copyrighted by Isaac Tsai 1999 */ /* TODO: checking user inputs 2/27/99 IT */ /* ====================================================== */ %{ @@ -72,7 +77,8 @@ int FormulaParseOK=1; %token F_NUMBER V_ID F_ID EoI F_ERROR %left F_PLUS F_MINUS %left F_MULT F_DIV F_MOD -%token F_POW F_LPAR F_RPAR F_COMMA +%token F_POW +%token F_LPAR F_RPAR F_COMMA %start f_expr @@ -100,19 +106,25 @@ f_expr : block block : block F_PLUS term { $$ = symbols_op($1, $3, ADD_op); } | block F_MINUS term { $$ = symbols_op($1, $3, SUB_op); } + | F_MINUS block { $$ = negate($2); } | term { $$ = $1; } | F_ERROR { FormulaParseOK = 0; FMLDBUG_PR1("[F_ERROR]\n"); return 0;} | error { FormulaParseOK = 0; FMLDBUG_PR1("[ERROR]\n"); return 0; } ; -term : term F_MULT basic_constr { $$ = symbols_op($1, $3, MUL_op); } - | term F_DIV basic_constr { $$ = symbols_op($1, $3, DIV_op); } - | term F_MOD basic_constr { $$ = symbols_op($1, $3, IDIV_op); } +term : term F_MULT basic_constr { $$ = symbols_op($1, $3, MUL_op); } + | term F_MULT F_MINUS basic_constr { $$ = symbols_op($1, negate($4), MUL_op); } + | term F_DIV basic_constr { $$ = symbols_op($1, $3, DIV_op); } + | term F_DIV F_MINUS basic_constr { $$ = symbols_op($1, negate($4), DIV_op); } + | term F_MOD basic_constr { $$ = symbols_op($1, $3, IDIV_op); } + | term F_MOD F_MINUS basic_constr { $$ = symbols_op($1, negate($4), IDIV_op); } | basic_constr { $$ = $1; } ; basic_constr : basic_constr F_POW basic_item { $$ = f_symbol_pow($1,$3); FMLDBUG_PR3("[%.16g ^ %.16g] ",$1->s_real,$3->s_real); } + | basic_constr F_POW F_MINUS basic_item { $$ = f_symbol_pow($1,negate($4)); + FMLDBUG_PR3("[%.16g ^ %.16g] ",$1->s_real,$4->s_real); } | basic_item { $$ = $1; } ; @@ -143,25 +155,12 @@ basic_item : F_ID F_LPAR F_RPAR $$ = do_function(tmp, $3->s_argc, $3->s_argp); capa_mfree(FuncStack[Func_idx].s_name); free_arglist($3->s_argp); + $3->s_argp=NULL; } } | V_ID { FMLDBUG_PR3("[V %s = %.16g] ",$1->s_name, $1->s_real); $$ = $1; } - | F_MINUS basic_item { $$ = $2; - switch($2->s_type) { - case I_VAR: $$ = (Symbol *)capa_malloc(sizeof(Symbol),1); - $$->s_type = I_CONSTANT; - case I_CONSTANT: $$->s_int = - $2->s_int; break; - case R_VAR: $$ = (Symbol *)capa_malloc(sizeof(Symbol),1); - $$->s_type = R_CONSTANT; - case R_CONSTANT: $$->s_real = (-1.0)*($2->s_real); - break; - case S_VAR: - case S_CONSTANT: break; - default: break; - } - } | F_PLUS basic_item { $$ = $2; } | F_NUMBER { FMLDBUG_PR2("[F %.16g] ",$1->s_real); $$ = $1; @@ -177,6 +176,24 @@ fml_error(char *msg) } /* ---------------------------------------------------- */ +Symbol* negate(Symbol* symb) +{ + Symbol* temp=symb; + switch(symb->s_type) { + case I_VAR: temp = (Symbol *)capa_malloc(sizeof(Symbol),1); + temp->s_type = I_CONSTANT; + case I_CONSTANT: temp->s_int = - symb->s_int; break; + case R_VAR: temp = (Symbol *)capa_malloc(sizeof(Symbol),1); + temp->s_type = R_CONSTANT; + case R_CONSTANT: temp->s_real = (-1.0)*(symb->s_real); + break; + case S_VAR: + case S_CONSTANT: break; + default: break; + } + return temp; +} + Symbol * f_symbol_pow(ap,bp) Symbol *ap; Symbol *bp; { @@ -184,7 +201,10 @@ f_symbol_pow(ap,bp) Symbol *ap; Symbol * double a, b; int error = 0; - cp = NULL; + /*Even if we can't do it we need to return something*/ + cp = (Symbol *)capa_malloc(sizeof(Symbol),1); + cp->s_type = R_CONSTANT; + cp->s_real = 0.0; switch(ap->s_type) { case I_VAR: a = (double)(ap->s_int); break; @@ -215,10 +235,12 @@ f_symbol_pow(ap,bp) Symbol *ap; Symbol * error = 1; } if (!error) { + printf("and trying"); cp = (Symbol *)capa_malloc(sizeof(Symbol),1); cp->s_type = R_CONSTANT; cp->s_real = pow(a,b); - + } else { + FormulaParseOK=0; } return (cp); }