diff --git a/Makefile b/Makefile index 84025f9..19b7646 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,33 @@ -OBJS=abCalc.o abCalcExpr.o abCalcExprReal.o abCalcExprInt.o abCalcStack.o \ - abCalcMode.o abCalcMain.o abCalcOp.o abCalcOpAdd.o abCalcError.o +OBJS=abCalc.o abCalcExpr.o abCalcExpReal.o abCalcExprInt.o abCalcStack.o \ + abCalcMode.o abCalcMain.o abCalcOp.o abCalcError.o abCalcOpAdd.o \ + abCalcOpSubtr.o abCalcOpMult.o abCalcOpDiv.o abCalcOpPower.o \ + abCalcOpAnd.o abCalcOpOr.o abCalcOpXor.o abCalcOpNot.o NAME=abCalc all: $(NAME) abCalcExpr.o: abCalcExpr.h -abCalcExprReal.o: abCalcExpr.h abCalcExprReal.h +abCalcExpReal.o: abCalcExpr.h abCalcExpReal.h +abCalcExprInt.o: abCalcExpr.h abCalcMode.h abCalcExprInt.h abCalcStack.o: abCalcExpr.h abCalcStack.h abCalcError.h abCalcMode.o: abCalcMode.h abCalcExpr.h -abCalcExprInt.o: abCalcExpr.h abCalcMode.h abCalcExprInt.h -abCalc.o: abCalc.h abCalcExpr.h abCalcMode.h abCalcExprReal.h abCalcExprInt.h \ - abCalcStack.h abCalcOp.h abCalcError.h -abCalcMain.o: abCalc.h abCalcStack.h abCalcExpr.h abCalcOp.h abCalcError.h -abCalcOp.o: abCalcOp.h abCalcError.h abCalcExpr.h abCalcStack.h abCalcOpAdd.h -abCalcOpAdd.o: abCalcOp.h abCalcError.h abCalcOpAdd.h abCalcError.o: abCalcError.h +abCalc.o: abCalc.h abCalcExpr.h abCalcMode.h abCalcExpReal.h abCalcExprInt.h \ + abCalcStack.h abCalcOp.h abCalcError.h +abCalcMain.o: abCalc.h abCalcStack.h abCalcExpr.h abCalcOp.h abCalcError.h +abCalcOp.o: abCalcOp.h abCalcError.h abCalcExpr.h abCalcStack.h abCalcOpAdd.h \ + abCalcOpSubtr.h abCalcOpMult.h abCalcOpDiv.h abCalcOpPower.h \ + abCalcOpAnd.h abCalcOpOr.h abCalcOpXor.h abCalcOpNot.h +abCalcOpAdd.o: abCalcOp.h abCalcError.h abCalcOpAdd.h +abCalcOpSubtr.o: abCalcOp.h abCalcError.h abCalcOpSubtr.h +abCalcOpMult.o: abCalcOp.h abCalcError.h abCalcOpMult.h +abCalcOpDiv.o: abCalcOp.h abCalcError.h abCalcOpDiv.h +abCalcOpPower.o: abCalcOp.h abCalcError.h abCalcOpPower.h +abCalcOpAnd.o: abCalcOp.h abCalcError.h abCalcOpAnd.h +abCalcOpOr.o: abCalcOp.h abCalcError.h abCalcOpOr.h +abCalcOpXor.o: abCalcOp.h abCalcError.h abCalcOpXor.h +abCalcOpNot.o: abCalcOp.h abCalcError.h abCalcOpNot.h $(NAME): $(OBJS) diff --git a/abCalc.c b/abCalc.c index 682389f..a48e4df 100644 --- a/abCalc.c +++ b/abCalc.c @@ -6,7 +6,7 @@ #include "abCalcExpr.h" #include "abCalcExprInt.h" -#include "abCalcExprReal.h" +#include "abCalcExpReal.h" #include "abCalcMode.h" #include "abCalcStack.h" #include "abCalcOp.h" diff --git a/abCalcError.c b/abCalcError.c index 360c64e..dbacf38 100644 --- a/abCalcError.c +++ b/abCalcError.c @@ -26,6 +26,8 @@ void abCalcErrorInit(void) gErrorStrings[abCalcBadArgValueError] = "Bad Argument Value"; gErrorStrings[abCalcTooFewArgsError] = "Too Few Arguments"; gErrorStrings[abCalcStackFullError] = "Stack Full"; + gErrorStrings[abCalcInfiniteResultError] = "Infinite Result"; + gErrorStrings[abCalcComplexResultError] = "Complex Result"; } diff --git a/abCalcError.h b/abCalcError.h index f191b09..aa7f396 100644 --- a/abCalcError.h +++ b/abCalcError.h @@ -16,6 +16,8 @@ typedef enum abCalcErrorType { abCalcBadArgValueError, abCalcTooFewArgsError, abCalcStackFullError, + abCalcInfiniteResultError, + abCalcComplexResultError, abCalcErrorTypeMax } abCalcErrorType; diff --git a/abCalcExprReal.c b/abCalcExpReal.c similarity index 99% rename from abCalcExprReal.c rename to abCalcExpReal.c index d73fda8..b7a9053 100644 --- a/abCalcExprReal.c +++ b/abCalcExpReal.c @@ -1,5 +1,5 @@ /* - abCalcExprReal.c + abCalcExpReal.c By: Jeremy Rand */ diff --git a/abCalcExprReal.h b/abCalcExpReal.h similarity index 51% rename from abCalcExprReal.h rename to abCalcExpReal.h index fab286a..2188393 100644 --- a/abCalcExprReal.h +++ b/abCalcExpReal.h @@ -1,11 +1,11 @@ /* - abCalcExprReal.h + abCalcExpReal.h By: Jeremy Rand */ -#ifndef ABCALCEXPRREAL_H -#define ABCALCEXPRREAL_H +#ifndef ABCALCEXPREAL_H +#define ABCALCEXPREAL_H void abCalcExprRealInit(void); diff --git a/abCalcOp.c b/abCalcOp.c index ed06342..a8e4e54 100644 --- a/abCalcOp.c +++ b/abCalcOp.c @@ -13,6 +13,14 @@ #include "abCalcStack.h" #include "abCalcOpAdd.h" +#include "abCalcOpSubtr.h" +#include "abCalcOpMult.h" +#include "abCalcOpDiv.h" +#include "abCalcOpPower.h" +#include "abCalcOpAnd.h" +#include "abCalcOpOr.h" +#include "abCalcOpXor.h" +#include "abCalcOpNot.h" #define AB_CALC_MAX_OPS 128 @@ -27,6 +35,14 @@ void abCalcOpInit(void) memset(gOps, 0, sizeof(gOps)); abCalcOpAddInit(); + abCalcOpSubtrInit(); + abCalcOpMultInit(); + abCalcOpDivInit(); + abCalcOpPowerInit(); + abCalcOpAndInit(); + abCalcOpOrInit(); + abCalcOpXorInit(); + abCalcOpNotInit(); } diff --git a/abCalcOpAdd.c b/abCalcOpAdd.c index 9bb185b..5b424ea 100644 --- a/abCalcOpAdd.c +++ b/abCalcOpAdd.c @@ -49,16 +49,16 @@ void addExecute(void) if ((expr1Real) && (expr2Real)) { result.type = abCalcExprTypeReal; - result.u.real = expr1->u.real + expr2->u.real; + result.u.real = expr2->u.real + expr1->u.real; } else { result.type = abCalcExprTypeInt; if (expr1Real) { - result.u.integer = (abCalcIntType)expr1->u.real + expr2->u.integer; + result.u.integer = expr2->u.integer + (abCalcIntType)expr1->u.real; } else if (expr2Real) { - result.u.integer = expr1->u.integer + (abCalcIntType)expr2->u.real; + result.u.integer = (abCalcIntType)expr2->u.real + expr1->u.integer; } else { - result.u.integer = expr1->u.integer + expr2->u.integer; + result.u.integer = expr2->u.integer + expr1->u.integer; } } diff --git a/abCalcOpAnd.c b/abCalcOpAnd.c new file mode 100644 index 0000000..5874871 --- /dev/null +++ b/abCalcOpAnd.c @@ -0,0 +1,50 @@ +/* + abCalcOpAnd.c + By: Jeremy Rand + */ + + +#include + +#include "abCalcOpAnd.h" + +#include "abCalcOp.h" +#include "abCalcError.h" +#include "abCalcExpr.h" +#include "abCalcStack.h" + + +#define OP_NAME "AND" + + +static void andExecute(void); + + +void abCalcOpAndInit(void) +{ + abCalcOpRegister(OP_NAME, andExecute); +} + + +void andExecute(void) +{ + abCalcExpr result; + AB_CALC_OP_TWO_ARGS(OP_NAME); + + if (expr1->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + if (expr2->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + result.type = abCalcExprTypeInt; + result.u.integer = expr2->u.integer & expr1->u.integer; + + abCalcStackExprPop(NULL); + abCalcStackExprPop(NULL); + abCalcStackExprPush(&result); +} diff --git a/abCalcOpAnd.h b/abCalcOpAnd.h new file mode 100644 index 0000000..be54b3c --- /dev/null +++ b/abCalcOpAnd.h @@ -0,0 +1,14 @@ +/* + abCalcOpAnd.h + By: Jeremy Rand + */ + + +#ifndef ABCALCOPAND_H +#define ABCALCOPAND_H + + +void abCalcOpAndInit(void); + + +#endif diff --git a/abCalcOpDiv.c b/abCalcOpDiv.c new file mode 100644 index 0000000..1d8c8ac --- /dev/null +++ b/abCalcOpDiv.c @@ -0,0 +1,77 @@ +/* + abCalcOpDiv.c + By: Jeremy Rand + */ + + +#include + +#include "abCalcOpDiv.h" + +#include "abCalcOp.h" +#include "abCalcError.h" +#include "abCalcExpr.h" +#include "abCalcStack.h" + + +#define OP_NAME "/" + + +static void divExecute(void); + + +void abCalcOpDivInit(void) +{ + abCalcOpRegister(OP_NAME, divExecute); +} + + +void divExecute(void) +{ + abCalcExpr result; + char expr1Real = 0; + char expr2Real = 0; + AB_CALC_OP_TWO_ARGS(OP_NAME); + + if (expr1->type == abCalcExprTypeReal) { + expr1Real = 1; + if (expr1->u.real == 0.0) { + abCalcRaiseError(abCalcInfiniteResultError, OP_NAME); + return; + } + } else if (expr1->type == abCalcExprTypeInt) { + if (expr1->u.integer == 0l) { + abCalcRaiseError(abCalcInfiniteResultError, OP_NAME); + return; + } + } else { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + if (expr2->type == abCalcExprTypeReal) { + expr2Real = 1; + } else if (expr2->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + if ((expr1Real) && (expr2Real)) { + result.type = abCalcExprTypeReal; + result.u.real = expr2->u.real / expr1->u.real; + } else { + result.type = abCalcExprTypeInt; + + if (expr1Real) { + result.u.integer = expr2->u.integer / (abCalcIntType)expr1->u.real; + } else if (expr2Real) { + result.u.integer = (abCalcIntType)expr2->u.real / expr1->u.integer; + } else { + result.u.integer = expr2->u.integer / expr1->u.integer; + } + } + + abCalcStackExprPop(NULL); + abCalcStackExprPop(NULL); + abCalcStackExprPush(&result); +} diff --git a/abCalcOpDiv.h b/abCalcOpDiv.h new file mode 100644 index 0000000..a668b2b --- /dev/null +++ b/abCalcOpDiv.h @@ -0,0 +1,14 @@ +/* + abCalcOpDiv.h + By: Jeremy Rand + */ + + +#ifndef ABCALCOPDIV_H +#define ABCALCOPDIV_H + + +void abCalcOpDivInit(void); + + +#endif diff --git a/abCalcOpMult.c b/abCalcOpMult.c new file mode 100644 index 0000000..35cc6de --- /dev/null +++ b/abCalcOpMult.c @@ -0,0 +1,68 @@ +/* + abCalcOpMult.c + By: Jeremy Rand + */ + + +#include + +#include "abCalcOpMult.h" + +#include "abCalcOp.h" +#include "abCalcError.h" +#include "abCalcExpr.h" +#include "abCalcStack.h" + + +#define OP_NAME "*" + + +static void multExecute(void); + + +void abCalcOpMultInit(void) +{ + abCalcOpRegister(OP_NAME, multExecute); +} + + +void multExecute(void) +{ + abCalcExpr result; + char expr1Real = 0; + char expr2Real = 0; + AB_CALC_OP_TWO_ARGS(OP_NAME); + + if (expr1->type == abCalcExprTypeReal) { + expr1Real = 1; + } else if (expr1->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + if (expr2->type == abCalcExprTypeReal) { + expr2Real = 1; + } else if (expr2->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + if ((expr1Real) && (expr2Real)) { + result.type = abCalcExprTypeReal; + result.u.real = expr2->u.real * expr1->u.real; + } else { + result.type = abCalcExprTypeInt; + + if (expr1Real) { + result.u.integer = expr2->u.integer * (abCalcIntType)expr1->u.real; + } else if (expr2Real) { + result.u.integer = (abCalcIntType)expr2->u.real * expr1->u.integer; + } else { + result.u.integer = expr2->u.integer * expr1->u.integer; + } + } + + abCalcStackExprPop(NULL); + abCalcStackExprPop(NULL); + abCalcStackExprPush(&result); +} diff --git a/abCalcOpMult.h b/abCalcOpMult.h new file mode 100644 index 0000000..01f4253 --- /dev/null +++ b/abCalcOpMult.h @@ -0,0 +1,14 @@ +/* + abCalcOpMult.h + By: Jeremy Rand + */ + + +#ifndef ABCALCOPMULT_H +#define ABCALCOPMULT_H + + +void abCalcOpMultInit(void); + + +#endif diff --git a/abCalcOpNot.c b/abCalcOpNot.c new file mode 100644 index 0000000..5bd896d --- /dev/null +++ b/abCalcOpNot.c @@ -0,0 +1,45 @@ +/* + abCalcOpNot.c + By: Jeremy Rand + */ + + +#include + +#include "abCalcOpNot.h" + +#include "abCalcOp.h" +#include "abCalcError.h" +#include "abCalcExpr.h" +#include "abCalcStack.h" + + +#define OP_NAME "NOT" + + +static void notExecute(void); + + +void abCalcOpNotInit(void) +{ + abCalcOpRegister(OP_NAME, notExecute); +} + + +void notExecute(void) +{ + abCalcExpr result; + AB_CALC_OP_ONE_ARG(OP_NAME); + + if (expr->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + result.type = abCalcExprTypeInt; + result.u.integer = ~(expr->u.integer); + + abCalcStackExprPop(NULL); + abCalcStackExprPop(NULL); + abCalcStackExprPush(&result); +} diff --git a/abCalcOpNot.h b/abCalcOpNot.h new file mode 100644 index 0000000..fc78343 --- /dev/null +++ b/abCalcOpNot.h @@ -0,0 +1,14 @@ +/* + abCalcOpNot.h + By: Jeremy Rand + */ + + +#ifndef ABCALCOPNOT_H +#define ABCALCOPNOT_H + + +void abCalcOpNotInit(void); + + +#endif diff --git a/abCalcOpOr.c b/abCalcOpOr.c new file mode 100644 index 0000000..a701d5d --- /dev/null +++ b/abCalcOpOr.c @@ -0,0 +1,50 @@ +/* + abCalcOpOr.c + By: Jeremy Rand + */ + + +#include + +#include "abCalcOpOr.h" + +#include "abCalcOp.h" +#include "abCalcError.h" +#include "abCalcExpr.h" +#include "abCalcStack.h" + + +#define OP_NAME "OR" + + +static void orExecute(void); + + +void abCalcOpOrInit(void) +{ + abCalcOpRegister(OP_NAME, orExecute); +} + + +void orExecute(void) +{ + abCalcExpr result; + AB_CALC_OP_TWO_ARGS(OP_NAME); + + if (expr1->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + if (expr2->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + result.type = abCalcExprTypeInt; + result.u.integer = expr2->u.integer | expr1->u.integer; + + abCalcStackExprPop(NULL); + abCalcStackExprPop(NULL); + abCalcStackExprPush(&result); +} diff --git a/abCalcOpOr.h b/abCalcOpOr.h new file mode 100644 index 0000000..c88aeb8 --- /dev/null +++ b/abCalcOpOr.h @@ -0,0 +1,14 @@ +/* + abCalcOpOr.h + By: Jeremy Rand + */ + + +#ifndef ABCALCOPOR_H +#define ABCALCOPOR_H + + +void abCalcOpOrInit(void); + + +#endif diff --git a/abCalcOpPower.c b/abCalcOpPower.c new file mode 100644 index 0000000..08bf58a --- /dev/null +++ b/abCalcOpPower.c @@ -0,0 +1,72 @@ +/* + abCalcOpPower.c + By: Jeremy Rand + */ + + +#include +#include + +#include "abCalcOpPower.h" + +#include "abCalcOp.h" +#include "abCalcError.h" +#include "abCalcExpr.h" +#include "abCalcStack.h" + + +#define OP_NAME "^" + + +static void powerExecute(void); + + +void abCalcOpPowerInit(void) +{ + abCalcOpRegister(OP_NAME, powerExecute); +} + + +void powerExecute(void) +{ + abCalcExpr result; + double integral; + AB_CALC_OP_TWO_ARGS(OP_NAME); + + if (expr1->type != abCalcExprTypeReal) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + if (expr2->type != abCalcExprTypeReal) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + result.type = abCalcExprTypeReal; + + if (expr2->u.real == 0.0) { + if (expr1->u.real < 0.0) { + abCalcRaiseError(abCalcInfiniteResultError, OP_NAME); + return; + } + if (expr1->u.real == 0.0) { + result.u.real = 1.0; + } else { + result.u.real = 0.0; + } + } else { + if (expr2->u.real < 0.0) { + modf(expr1->u.real, &integral); + if (expr1->u.real != integral) { + abCalcRaiseError(abCalcComplexResultError, OP_NAME); + return; + } + } + result.u.real = pow(expr2->u.real, expr1->u.real); + } + + abCalcStackExprPop(NULL); + abCalcStackExprPop(NULL); + abCalcStackExprPush(&result); +} diff --git a/abCalcOpPower.h b/abCalcOpPower.h new file mode 100644 index 0000000..92beb8b --- /dev/null +++ b/abCalcOpPower.h @@ -0,0 +1,14 @@ +/* + abCalcOpPower.h + By: Jeremy Rand + */ + + +#ifndef ABCALCOPPOWER_H +#define ABCALCOPPOWER_H + + +void abCalcOpPowerInit(void); + + +#endif diff --git a/abCalcOpSubtr.c b/abCalcOpSubtr.c new file mode 100644 index 0000000..f461242 --- /dev/null +++ b/abCalcOpSubtr.c @@ -0,0 +1,68 @@ +/* + abCalcOpSubtr.c + By: Jeremy Rand + */ + + +#include + +#include "abCalcOpSubtr.h" + +#include "abCalcOp.h" +#include "abCalcError.h" +#include "abCalcExpr.h" +#include "abCalcStack.h" + + +#define OP_NAME "-" + + +static void subtrExecute(void); + + +void abCalcOpSubtrInit(void) +{ + abCalcOpRegister(OP_NAME, subtrExecute); +} + + +void subtrExecute(void) +{ + abCalcExpr result; + char expr1Real = 0; + char expr2Real = 0; + AB_CALC_OP_TWO_ARGS(OP_NAME); + + if (expr1->type == abCalcExprTypeReal) { + expr1Real = 1; + } else if (expr1->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + if (expr2->type == abCalcExprTypeReal) { + expr2Real = 1; + } else if (expr2->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + if ((expr1Real) && (expr2Real)) { + result.type = abCalcExprTypeReal; + result.u.real = expr2->u.real - expr1->u.real; + } else { + result.type = abCalcExprTypeInt; + + if (expr1Real) { + result.u.integer = expr2->u.integer - (abCalcIntType)expr1->u.real; + } else if (expr2Real) { + result.u.integer = (abCalcIntType)expr2->u.real - expr1->u.integer; + } else { + result.u.integer = expr2->u.integer - expr2->u.integer; + } + } + + abCalcStackExprPop(NULL); + abCalcStackExprPop(NULL); + abCalcStackExprPush(&result); +} diff --git a/abCalcOpSubtr.h b/abCalcOpSubtr.h new file mode 100644 index 0000000..37201a2 --- /dev/null +++ b/abCalcOpSubtr.h @@ -0,0 +1,14 @@ +/* + abCalcOpSubtr.h + By: Jeremy Rand + */ + + +#ifndef ABCALCOPSUBTR_H +#define ABCALCOPSUBTR_H + + +void abCalcOpSubtrInit(void); + + +#endif diff --git a/abCalcOpXor.c b/abCalcOpXor.c new file mode 100644 index 0000000..7cd9e0c --- /dev/null +++ b/abCalcOpXor.c @@ -0,0 +1,50 @@ +/* + abCalcOpXor.c + By: Jeremy Rand + */ + + +#include + +#include "abCalcOpXor.h" + +#include "abCalcOp.h" +#include "abCalcError.h" +#include "abCalcExpr.h" +#include "abCalcStack.h" + + +#define OP_NAME "XOR" + + +static void xorExecute(void); + + +void abCalcOpXorInit(void) +{ + abCalcOpRegister(OP_NAME, xorExecute); +} + + +void xorExecute(void) +{ + abCalcExpr result; + AB_CALC_OP_TWO_ARGS(OP_NAME); + + if (expr1->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + if (expr2->type != abCalcExprTypeInt) { + abCalcRaiseError(abCalcBadArgTypeError, OP_NAME); + return; + } + + result.type = abCalcExprTypeInt; + result.u.integer = expr2->u.integer ^ expr1->u.integer; + + abCalcStackExprPop(NULL); + abCalcStackExprPop(NULL); + abCalcStackExprPush(&result); +} diff --git a/abCalcOpXor.h b/abCalcOpXor.h new file mode 100644 index 0000000..06dba2d --- /dev/null +++ b/abCalcOpXor.h @@ -0,0 +1,14 @@ +/* + abCalcOpXor.h + By: Jeremy Rand + */ + + +#ifndef ABCALCOPXOR_H +#define ABCALCOPXOR_H + + +void abCalcOpXorInit(void); + + +#endif