Add .h file guards and a basic integer implementation

This commit is contained in:
Jeremy Rand 2013-07-24 10:56:02 -05:00
parent b691e28672
commit b8e9fd0c9c
9 changed files with 311 additions and 5 deletions

View File

@ -7,6 +7,7 @@ abCalcExpr.o: abCalcExpr.h
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
$(NAME): $(OBJS)
cc -o $(NAME) $(OBJS)

View File

@ -4,6 +4,10 @@
*/
#ifndef ABCALCEXPR_H
#define ABCALCEXPR_H
typedef enum abCalcExprType {
abCalcExprTypeMin = 0,
abCalcExprTypeReal = 0,
@ -17,6 +21,11 @@ typedef double abCalcRealType;
typedef unsigned long abCalcIntType;
#define AB_CALC_EXPR_MAX_INT_WIDTH ((sizeof(abCalcIntType) * 8))
#define AB_CALC_EXPR_STRING_MAX (AB_CALC_EXPR_MAX_INT_WIDTH + 4)
typedef struct abCalcExpr {
abCalcExprType type;
union {
@ -37,3 +46,6 @@ void abCalcRegisterExprType(abCalcExprType type, abCalcExprCallbacks *callbacks)
abCalcExpr *abCalcParseExpr(abCalcExpr *expr, char *buffer);
char *abCalcFormatExpr(abCalcExpr *expr, char *buffer);
#endif

View File

@ -0,0 +1,243 @@
/*
abCalcExprInt.c
By: Jeremy Rand
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "abCalcExpr.h"
#include "abCalcMode.h"
static abCalcExpr *abCalcExprIntParse(abCalcExpr *expr, char *buffer);
static char *abCalcExprIntFormat(abCalcExpr *expr, char *buffer);
static abCalcExprCallbacks gCallbacks = {
abCalcExprIntParse,
abCalcExprIntFormat
};
void abCalcExprIntInit(void)
{
abCalcRegisterExprType(abCalcExprTypeInt, &gCallbacks);
}
abCalcExpr *abCalcExprIntParse(abCalcExpr *expr, char *buffer)
{
abCalcModeIntBase base = abCalcModeGetBase();
abCalcIntType value = 0;
int len;
int offset;
if (buffer == NULL)
return NULL;
if (expr == NULL)
return NULL;
len = strlen(buffer);
if (len < 2)
return NULL;
if (buffer[0] != '#')
return NULL;
switch (base) {
case abCalcModeBinBase:
for (offset = 1; offset < len; offset++) {
value <<= 1;
switch (buffer[offset]) {
case '1':
value++;
break;
case '0':
break;
default:
return NULL;
}
}
break;
case abCalcModeOctBase:
for (offset = 1; offset < len; offset++) {
value <<= 3;
switch (buffer[offset]) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
value += (buffer[offset] - '0');;
break;
default:
return NULL;
}
}
break;
case abCalcModeDecBase:
for (offset = 1; offset < len; offset++) {
value *= 10;
switch (buffer[offset]) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value += (buffer[offset] - '0');;
break;
default:
return NULL;
}
}
break;
case abCalcModeHexBase:
for (offset = 1; offset < len; offset++) {
value <<= 4;
switch (buffer[offset]) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value += (buffer[offset] - '0');;
break;
case 'a':
case 'A':
value += 10;
break;
case 'b':
case 'B':
value += 11;
break;
case 'c':
case 'C':
value += 12;
break;
case 'd':
case 'D':
value += 13;
break;
case 'e':
case 'E':
value += 14;
break;
case 'f':
case 'F':
value += 15;
break;
default:
return NULL;
}
}
break;
default:
return NULL;
}
expr->type = abCalcExprTypeInt;
expr->u.integer = value;
return expr;
}
char *abCalcExprIntFormat(abCalcExpr *expr, char *buffer)
{
abCalcModeIntBase base = abCalcModeGetBase();
int width = abCalcModeGetIntWidth();
abCalcIntType value;
char *ptr;
int gotFirstOne;
int i;
if (expr == NULL)
return NULL;
if (buffer == NULL)
return NULL;
if (expr->type != abCalcExprTypeInt)
return NULL;
value = expr->u.integer;
if (width < AB_CALC_EXPR_MAX_INT_WIDTH) {
value &= ((1l << width) - 1);
}
switch (base) {
case abCalcModeBinBase:
gotFirstOne = 0;
ptr = buffer;
*ptr = '*';
ptr++;
for (i = width - 1; i >= 0; i--) {
if ((value >> i) & 1) {
*ptr = '1';
ptr++;
gotFirstOne = 1;
} else {
if (gotFirstOne) {
*ptr = '0';
ptr++;
}
}
}
if (!gotFirstOne) {
*ptr = '0';
ptr++;
}
*ptr = '\0';
break;
case abCalcModeOctBase:
sprintf(buffer, "#%lo", value);
break;
case abCalcModeDecBase:
sprintf(buffer, "#%lu", value);
break;
case abCalcModeHexBase:
sprintf(buffer, "#%lX", value);
break;
default:
return NULL;
}
return buffer;
}

14
abCalcExprInt.h Normal file
View File

@ -0,0 +1,14 @@
/*
abCalcExprInt.h
By: Jeremy Rand
*/
#ifndef ABCALCEXPRINT_H
#define ABCALCEXPRINT_H
void abCalcExprIntInit(void);
#endif

View File

@ -21,17 +21,27 @@ static abCalcExprCallbacks gCallbacks = {
};
void abCalcExprRealInit(void)
{
abCalcRegisterExprType(abCalcExprTypeReal, &gCallbacks);
}
abCalcExpr *abCalcExprRealParse(abCalcExpr *expr, char *buffer)
{
int offset;
int expOffset = -1;
int periodOffset = -1;
int len;
int numOffset = -1;
/* First validate */
if (buffer == NULL)
return NULL;
if (expr == NULL)
return NULL;
len = strlen(buffer);
for (offset = 0; offset < len; offset++) {
@ -46,11 +56,14 @@ abCalcExpr *abCalcExprRealParse(abCalcExpr *expr, char *buffer)
case '7':
case '8':
case '9':
numOffset = offset;
break;
case '.':
if (periodOffset != -1)
return NULL;
if (expOffset != -1)
return NULL;
periodOffset = offset;
break;
@ -69,12 +82,16 @@ abCalcExpr *abCalcExprRealParse(abCalcExpr *expr, char *buffer)
if (expOffset != -1)
return NULL;
expOffset = offset;
numOffset = -1;
break;
default:
return NULL;
}
}
if (numOffset == -1)
return NULL;
expr->type = abCalcExprTypeReal;
expr->u.real = atof(buffer);

View File

@ -4,5 +4,11 @@
*/
#ifndef ABCALCEXPRREAL_H
#define ABCALCEXPRREAL_H
void abCalcExprRealInit(void);
#endif

View File

@ -9,7 +9,7 @@
static abCalcModeIntBase gBase = abCalcModeDecBase;
static int gIntWidth = AB_CALC_MODE_MAX_INT_WIDTH;
static int gIntWidth = AB_CALC_EXPR_MAX_INT_WIDTH;
void abCalcModeInit(void)
@ -41,7 +41,7 @@ int abCalcModeGetIntWidth(void)
void abCalcModeSetIntWidth(int width)
{
if ((width > 0) &&
(width <= AB_CALC_MODE_MAX_INT_WIDTH)) {
(width <= AB_CALC_EXPR_MAX_INT_WIDTH)) {
gIntWidth = width;
}
}

View File

@ -4,6 +4,10 @@
*/
#ifndef ABCALCMODE_H
#define ABCALCMODE_H
#include "abCalcExpr.h"
@ -19,9 +23,6 @@ typedef enum abCalcModeIntBase
} abCalcModeIntBase;
#define AB_CALC_MODE_MAX_INT_WIDTH ((sizeof(abCalcIntType) * 8))
void abCalcModeInit(void);
abCalcModeIntBase abCalcModeGetBase(void);
@ -31,3 +32,6 @@ void abCalcModeSetBase(abCalcModeIntBase base);
int abCalcModeGetIntWidth(void);
void abCalcModeSetIntWidth(int width);
#endif

View File

@ -4,6 +4,10 @@
*/
#ifndef ABCALCSTACK_H
#define ABCALCSTACK_H
#include "abCalcExpr.h"
void abCalcStackInit(void);
@ -13,3 +17,8 @@ abCalcExpr *abCalcStackExprPush(abCalcExpr *expr);
abCalcExpr *abCalcStackExprPop(abCalcExpr *expr);
abCalcExpr *abCalcStackExprAt(abCalcExpr *expr, int depth);
int abCalcStackNumItems(void);
#endif