diff --git a/Makefile b/Makefile index 116538c..9572506 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,10 @@ abCalcExprReal.o: abCalcExpr.h abCalcExprReal.h abCalcStack.o: abCalcExpr.h abCalcStack.h abCalcMode.o: abCalcMode.h abCalcExpr.h abCalcExprInt.o: abCalcExpr.h abCalcMode.h abCalcExprInt.h -abCalc.o: abCalcExpr.h abCalcMode.h abCalcExprReal.h abCalcExprInt.h abCalcStack.h +abCalc.o: abCalc.h abCalcExpr.h abCalcMode.h abCalcExprReal.h abCalcExprInt.h abCalcStack.h +abCalcMain.o: abCalc.h abCalcStack.h abCalcExpr.h + +CFLAGS=-g $(NAME): $(OBJS) cc -o $(NAME) $(OBJS) diff --git a/abCalcExprReal.c b/abCalcExprReal.c index 96b81b5..d73fda8 100644 --- a/abCalcExprReal.c +++ b/abCalcExprReal.c @@ -4,6 +4,7 @@ */ +#include #include #include #include @@ -101,6 +102,17 @@ abCalcExpr *abCalcExprRealParse(abCalcExpr *expr, char *buffer) char *abCalcExprRealFormat(abCalcExpr *expr, char *buffer) { + abCalcRealType exp; + abCalcRealType value; + char format[16]; + int numDecDigits; + int periodPos = -1; + int zerosStart = -1; + int spaceStart = -1; + int expPos = -1; + int len; + int i; + if (expr == NULL) return NULL; @@ -110,6 +122,86 @@ char *abCalcExprRealFormat(abCalcExpr *expr, char *buffer) if (expr->type != abCalcExprTypeReal) return NULL; - sprintf(buffer, "%f", expr->u.real); + value = expr->u.real; + + if (value == 0.0) { + exp = 0.0; + } else { + exp = floor(log10(fabs(value))); + } + + if (exp >= 0) + exp++; + + if ((exp > 12) || + (exp < -12)) { + strcpy(format, "%-25.11E"); + } else if (exp <= -2) { + double shiftedValue = value * 1.0e12; + if (shiftedValue == floor(shiftedValue)) { + strcpy(format, "%-18.12f"); + } else { + strcpy(format, "%-25.11E"); + } + } else { + int numDecDigits = (int)(12 - exp); + if (numDecDigits > 12) { + numDecDigits = 12; + } + sprintf(format, "%%-28.%df", numDecDigits); + } + + sprintf(buffer, format, value); + len = strlen(buffer); + + for (i = 0; i < len; i++) { + switch (buffer[i]) { + case '.': + periodPos = i; + break; + + case '0': + if (expPos != -1) { + break; + } + if ((periodPos != -1) && + (zerosStart == -1)) { + if (periodPos == i - 1) { + zerosStart = periodPos; + } else { + zerosStart = i; + } + } + break; + case 'E': + expPos = i; + break; + case ' ': + spaceStart = i; + break; + default: + if (expPos == -1) + zerosStart = -1; + break; + } + if (spaceStart != -1) + break; + } + + if (spaceStart != -1) { + buffer[spaceStart] = '\0'; + len = spaceStart; + } + + if (zerosStart != -1) { + if (expPos != -1) { + memmove(&buffer[zerosStart], &buffer[expPos], len - expPos + 1); + len = expPos - zerosStart; + } + else { + buffer[zerosStart] = '\0'; + } + } + return buffer; } diff --git a/abCalcMain.c b/abCalcMain.c index b5398b5..7ba3c91 100644 --- a/abCalcMain.c +++ b/abCalcMain.c @@ -1,9 +1,58 @@ +/* + abCalcMain.c + By: Jeremy Rand + */ + + #include +#include #include +#include "abCalc.h" +#include "abCalcExpr.h" +#include "abCalcStack.h" + + +char gBuffer[AB_CALC_EXPR_STRING_MAX]; +abCalcExpr gExpr; + int main(void) { - printf("Hello, world!\n"); + int timeToQuit = 0; + int depth; + int item; + int len; + + abCalcInit(); + + while (!timeToQuit) { + printf("Stack:\n"); + depth = abCalcStackNumItems(); + + if (depth == 0) { + printf(" Empty!\n"); + } else { + for(item = depth - 1; item >= 0; item--) { + abCalcFormatExpr(abCalcStackExprAt(item), gBuffer); + printf(" %3d: %s\n", item + 1, gBuffer); + } + } + + timeToQuit = 1; + if (fgets(gBuffer, sizeof(gBuffer), stdin) != NULL) { + len = strlen(gBuffer); + if ((gBuffer[len - 1] == '\r') || + (gBuffer[len - 1] == '\n')) { + gBuffer[len - 1] = '\0'; + } + + if ((abCalcParseExpr(&gExpr, gBuffer) != NULL) && + (abCalcStackExprPush(&gExpr) != NULL)) { + timeToQuit = 0; + } + } + } + exit(0); } diff --git a/abCalcStack.c b/abCalcStack.c index a10f576..07fc886 100644 --- a/abCalcStack.c +++ b/abCalcStack.c @@ -54,11 +54,10 @@ int abCalcStackNumItems(void) } -abCalcExpr *abCalcStackExprAt(abCalcExpr *expr, int depth) +abCalcExpr *abCalcStackExprAt(int depth) { abCalcExpr *result = NULL; - if ((depth < gStackNumItems) && - (expr != NULL)) { + if (depth < gStackNumItems) { result = &(gStack[gStackNumItems - 1 - depth]); } diff --git a/abCalcStack.h b/abCalcStack.h index 0346029..9e7dba3 100644 --- a/abCalcStack.h +++ b/abCalcStack.h @@ -16,7 +16,7 @@ abCalcExpr *abCalcStackExprPush(abCalcExpr *expr); abCalcExpr *abCalcStackExprPop(abCalcExpr *expr); -abCalcExpr *abCalcStackExprAt(abCalcExpr *expr, int depth); +abCalcExpr *abCalcStackExprAt(int depth); int abCalcStackNumItems(void);