/******************************************************************** This file is part of the abs 0.907 distribution. abs is a spreadsheet with graphical user interface. Copyright (C) 1998-2001 André Bertin (Andre.Bertin@ping.be) This program 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 if in the same spirit as version 2. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Concact: abs@pi.be http://home.pi.be/bertin/abs.shtml *********************************************************************/ #include "oper.h" #include #include "stdlib.h" #include "stdio.h" #include "y.tab.h" #include "libfct.h" #include "string.h" #include "memory.h" static obj absERROR = { {0}, STRING_CONSTANT, NULL}; obj mkassign (o1, o2) obj o1, o2; { if (o2.type == IDENTIFIER) o2 = obj2val (o2); if (o2.type == MEMBER) o2 = member2val (o2); if (o1.type == MEMBER) { obj oarg[2]; int member; int class = getbaseclass (o1); if (class < 0) return o1; member = getmemberpos (class, o1); if (member < 0) return o1; oarg[0] = o1; oarg[1] = o2; (arrayclass[class].data[member].setfct) (2, oarg); freenocstobj (o1); return o1; } freenocstobj (o1); if (o1.type == IDENTIFIER) { o1eqo2 (&o1, o2); return o1; } mkclassassign (o1, o2); return o1; } obj mksumassign (o1, o2) obj o1, o2; { mkassign (o1, mksum (o1, o2)); return o1; } obj mkplusplus (o1) obj o1; { if (o1.type != IDENTIFIER) return o1; o1plusplus (&o1); return o1; } obj mkminusminus (o1) obj o1; { if (o1.type != IDENTIFIER) return o1; o1moinsmoins (&o1); return o1; } obj mksum (o1, o2) obj o1, o2; { obj o3; o1 = obj2val (o1); o2 = obj2val (o2); o3 = o1; if (o1.type == o2.type) { switch (o1.type) { case INTEGER: o3.rec.i += o2.rec.i; return o3; case DOUBLE: o3.rec.d += o2.rec.d; return o3; case STRING_CONSTANT: /*concat.. */ ; return o3; default: { o3.rec.d = obj2double (o1) + obj2double (o2); o3.type = DOUBLE; return o3; } } } else { o3.rec.d = obj2double (o1) + obj2double (o2); o3.type = DOUBLE; } return o3; } obj mkdiff (o1, o2) obj o1, o2; { obj o3; o1 = obj2val (o1); o2 = obj2val (o2); o3 = o1; if (o1.type == o2.type) { switch (o1.type) { case INTEGER: o3.rec.i -= o2.rec.i; return o3; case DOUBLE: o3.rec.d -= o2.rec.d; return o3; case STRING_CONSTANT: /*concat.. */ ; return o3; default: { o3.rec.d = obj2double (o1) - obj2double (o2); o3.type = DOUBLE; return o3; } } } else { o3.rec.d = obj2double (o1) - obj2double (o2); o3.type = DOUBLE; } return o3; } obj mkuminus (o1) obj o1; { obj o3; o1 = obj2val (o1); o3.type = o1.type; o3.label = o1.label; switch (o1.type) { case INTEGER: o3.rec.i = -o1.rec.i; return o3; case DOUBLE: o3.rec.d = -o1.rec.d; return o3; case STRING_CONSTANT: /*concat.. */ ; return o3; default: { o3.rec.d = -obj2double (o1); o3.type = DOUBLE; return o3; } } } obj mkmult (o1, o2) obj o1, o2; { obj o3; o1 = obj2val (o1); o2 = obj2val (o2); o3 = o1; if (o1.type == o2.type) { switch (o1.type) { case INTEGER: o3.rec.i *= o2.rec.i; return o3; case DOUBLE: o3.rec.d *= o2.rec.d; return o3; case STRING_CONSTANT: /*concat.. */ ; return o3; default: { o3.rec.d = obj2double (o1) * obj2double (o2); o3.type = DOUBLE; return o3; } } } else { o3.rec.d = obj2double (o1) * obj2double (o2); o3.type = DOUBLE; } return o3; } obj mkdiv (o1, o2) obj o1, o2; { obj o3; o1 = obj2val (o1); o2 = obj2val (o2); o3 = o1; absERROR.rec.s = "!DIV0"; if ((o2.type == INTEGER && o2.rec.i == 0) || (o2.type == DOUBLE && o2.rec.d == 0.0)) return absERROR; if (o1.type == o2.type) { switch (o1.type) { case DOUBLE: o3.rec.d /= o2.rec.d; return o3; case STRING_CONSTANT: /*concat.. */ ; return o3; default: { if (obj2double (o2) == 0.0) return absERROR; o3.rec.d = obj2double (o1) / obj2double (o2); o3.type = DOUBLE; return o3; } } } else { if (obj2double (o2) == 0.0) return absERROR; o3.rec.d = obj2double (o1) / obj2double (o2); o3.type = DOUBLE; } return o3; } obj mkmod (o1, o2) obj o1, o2; { obj o3; o1 = obj2val (o1); o2 = obj2val (o2); o3.label = NULL; o3.type = DOUBLE; absERROR.rec.s = "!DIV0"; if ((o2.type == INTEGER && o2.rec.i == 0) || (o2.type == DOUBLE && o2.rec.d == 0.0)) return absERROR; if (o1.type == DOUBLE && DOUBLE == o2.type) { o3.rec.d = fmod (o1.rec.d, o2.rec.d); return o3; } else { if (obj2double (o2) == 0.0) return absERROR; o3.rec.d = fmod (obj2double (o1), obj2double (o2)); } return o3; } obj mkintdiv (o1, o2) obj o1, o2; { obj o3; o1 = obj2val (o1); o2 = obj2val (o2); o3.label = NULL; absERROR.rec.s = "!DIV0"; if (obj2int (o2) == 0) return absERROR; o3.rec.i = obj2int (o1) / obj2int (o2); o3.type = INTEGER; return o3; } obj mkpow (o1, o2) obj o1, o2; { obj o3; o1 = obj2val (o1); o2 = obj2val (o2); o3.label = NULL; if (o1.type == o2.type) { switch (o1.type) { case DOUBLE: o1.rec.d = pow (o1.rec.d, o2.rec.d); return o3; case STRING_CONSTANT: /*concat.. */ ; return o3; default: { o3.rec.d = pow (obj2double (o1), obj2double (o2)); o3.type = DOUBLE; return o3; } } } else { o3.rec.d = pow (obj2double (o1), obj2double (o2)); o3.type = DOUBLE; } return o3; } obj mklt (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; o3.rec.i = (obj2double (o1) < obj2double (o2)) ? 1 : 0; o3.label = NULL; return o3; } obj mkgt (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; o3.rec.i = (obj2double (o1) > obj2double (o2)) ? 1 : 0; o3.label = NULL; return o3; } obj mkge (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; o3.rec.i = (obj2double (o1) >= obj2double (o2)) ? 1 : 0; o3.label = NULL; return o3; } obj mkle (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; o3.rec.i = (obj2double (o1) <= obj2double (o2)) ? 1 : 0; o3.label = NULL; return o3; } obj mkne (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; if (objisstring (o1) && objisstring (o2)) { printobj (o1); printobj (o2); o3.rec.i = (strcmp (obj2string (o1), obj2string (o2)) ? 1 : 0); printobj (o3); } else { o3.rec.i = (obj2double (o1) != obj2double (o2)) ? 1 : 0; } o3.label = NULL; return o3; } obj mkeq (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; if (objisstring (o1) && objisstring (o2)) { o3.rec.i = (strcmp (obj2string (o1), obj2string (o2)) ? 0 : 1); } else { o3.rec.i = (obj2double (o1) == obj2double (o2)) ? 1 : 0; } o3.label = NULL; return o3; } obj mkor (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; o3.rec.i = (obj2double (o1) != 0 || obj2double (o2) != 0) ? 1 : 0; o3.label = NULL; return o3; } obj mkand (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; o3.rec.i = (obj2double (o1) != 0 && obj2double (o2) != 0) ? 1 : 0; o3.label = NULL; return o3; } obj mkxor (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; o3.rec.i = ((obj2int (o1) == 0 && obj2int (o2) != 0) || (obj2int (o1) != 0 && obj2int (o2) == 0)) ? 1 : 0; o3.label = NULL; return o3; } obj mkeqv (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; o3.rec.i = (obj2int (o1) == obj2int (o2)) ? 1 : 0; o3.label = NULL; return o3; } obj mkimp (o1, o2) obj o1, o2; { obj o3; o3.type = INTEGER; o3.rec.i = (!(obj2int (o1) != 0 && obj2int (o2) == 0)) ? 1 : 0; o3.label = NULL; return o3; } obj mknot (o1) obj o1; { obj o3; o3.type = INTEGER; o3.rec.i = (obj2int (o1) == 0) ? 1 : 0; o3.label = NULL; return o3; } obj mkconcat (o1, o2) obj o1, o2; { obj o3; int len = 0; char *str1 = obj2string (o1); char *str2 = obj2string (o2); if (str1 != NULL) len += strlen (str1); if (str2 != NULL) len += strlen (str2); o3.type = STRING; o3.rec.s = (char *) absmalloc ((len + 1) * sizeof (char), "mkconcat:o3.rec.s"); if (str1 != NULL) strcpy (o3.rec.s, str1); else o3.rec.s[0] = '\0'; if (str2 != NULL) strcat (o3.rec.s, str2); o3.label = NULL; return o3; }