mirror of
https://github.com/jeremysrand/abCalc.git
synced 2025-02-06 10:30:11 +00:00
Add .h file guards and a basic integer implementation
This commit is contained in:
parent
b691e28672
commit
b8e9fd0c9c
1
Makefile
1
Makefile
@ -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)
|
||||
|
12
abCalcExpr.h
12
abCalcExpr.h
@ -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
|
||||
|
243
abCalcExprInt.c
243
abCalcExprInt.c
@ -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
14
abCalcExprInt.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
abCalcExprInt.h
|
||||
By: Jeremy Rand
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ABCALCEXPRINT_H
|
||||
#define ABCALCEXPRINT_H
|
||||
|
||||
|
||||
void abCalcExprIntInit(void);
|
||||
|
||||
|
||||
#endif
|
@ -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);
|
||||
|
@ -4,5 +4,11 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ABCALCEXPRREAL_H
|
||||
#define ABCALCEXPRREAL_H
|
||||
|
||||
|
||||
void abCalcExprRealInit(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
10
abCalcMode.h
10
abCalcMode.h
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user