~arivigo/scalc

0c195d7bb37ee98c87874404a30a360005664a2d — Ariadna Vigo a month ago debec03
First implementation of mem registers
4 files changed, 87 insertions(+), 5 deletions(-)

M Makefile
A mem.c
A mem.h
M scalc.c
M Makefile => Makefile +6 -4
@@ 4,7 4,7 @@

include config.mk

SRC = op.c scalc.c stack.c strlcpy.c
SRC = mem.c op.c scalc.c stack.c strlcpy.c
OBJ = ${SRC:%.c=%.o}

all: options scalc


@@ 22,9 22,11 @@ config.h:
.c.o:
	${CC} -c ${CFLAGS} $<

mem.o: mem.h

op.o: op.h

scalc.o: config.h op.h stack.h strlcpy.h
scalc.o: config.h mem.h op.h stack.h strlcpy.h

stack.o: stack.h



@@ 40,8 42,8 @@ clean:

dist: clean
	mkdir -p scalc-${VERSION}
	cp -R LICENSE Makefile README.md config.def.h config.mk op.h stack.h \
	   strlcpy.h scalc.1 ${SRC} scalc-${VERSION}
	cp -R LICENSE Makefile README.md config.def.h config.mk mem.h op.h \
	   stack.h strlcpy.h scalc.1 ${SRC} scalc-${VERSION}
	tar -cf scalc-${VERSION}.tar scalc-${VERSION}
	gzip scalc-${VERSION}.tar
	rm -rf scalc-${VERSION}

A mem.c => mem.c +47 -0
@@ 0,0 1,47 @@
/* See LICENSE file for copyright and license details. */

#include <ctype.h>

#include "mem.h"

static int mem_var_to_i(char var);

static double mem[MEM_SIZE];

static int
mem_var_to_i(char var)
{
	int i;

	i = tolower(var) - 'a';
	if ((i < 0) || (i >= MEM_SIZE))
		return -1;

	return i;
}

int
mem_get(double *val, char var)
{
	int i;

	if ((i = mem_var_to_i(var)) < 0)
		return -1;

	*val = mem[i];

	return 0;
}

int
mem_set(char var, double val)
{
	int i;

	if ((i = mem_var_to_i(var)) < 0)
		return -1;

	mem[i] = val;

	return 0;
}

A mem.h => mem.h +6 -0
@@ 0,0 1,6 @@
/* See LICENSE file for copyright and license details. */

#define MEM_SIZE 10

int mem_get(double *val, char var);
int mem_set(char var, double val);

M scalc.c => scalc.c +28 -1
@@ 7,6 7,7 @@
#include <unistd.h>

#include "config.h"
#include "mem.h"
#include "op.h"
#include "stack.h"
#include "strlcpy.h"


@@ 16,6 17,7 @@
enum cmd_type {
	CMD_NULL,
	CMD_CMD,
	CMD_MEM,
	CMD_STK
};



@@ 24,6 26,7 @@ typedef struct {
	enum cmd_type type;
	union {
		int (*cmd)(void);
		int (*mem)(char var, double val);
		int (*stk)(Stack *stk);
	} func;
} CmdReg;


@@ 47,6 50,7 @@ static const CmdReg cmd_defs[] = {
	{ ":list", CMD_CMD, { .cmd = cmd_list } },
	{ ":p", CMD_STK, { .stk = cmd_print } },
	{ ":swp", CMD_STK, { .stk = stack_swap } },
	{ ":mem", CMD_MEM, { .mem = mem_set } },
	{ ":q", CMD_CMD, { .cmd = cmd_quit } },
	{ "", CMD_NULL, { .cmd = NULL } }
};


@@ 81,12 85,17 @@ static void
run_cmd(Stack *stack, const char *expr)
{
	int err;
	double mem_val;
	char expr_cpy[STK_EXPR_SIZE];
	char *expr_ptr;
	const CmdReg *cmd_ptr;

	err = 0;

	strlcpy(expr_cpy, expr, STK_EXPR_SIZE);
	expr_ptr = strtok(expr_cpy, " ");
	for (cmd_ptr = cmd_defs; cmd_ptr->type != CMD_NULL; ++cmd_ptr) {
		if (strncmp(cmd_ptr->id, expr, CMD_ID_SIZE) == 0)
		if (strncmp(cmd_ptr->id, expr_ptr, CMD_ID_SIZE) == 0)
			break;
	}



@@ 94,6 103,21 @@ run_cmd(Stack *stack, const char *expr)
	case CMD_CMD:
		err = (*cmd_ptr->func.cmd)();
		break;
	case CMD_MEM:
		if ((expr_ptr = strtok(NULL, " ")) == NULL) {
			fprintf(stderr, "%s: register required.\n", expr);
			return;
		}

		if((err = stack_peek(&mem_val, *stack)) < 0)
			break;

		if ((*cmd_ptr->func.mem)(expr_ptr[0], mem_val) < 0) {
			fprintf(stderr, "%s: bad register.\n", expr);
			return;
		}

		break;
	case CMD_STK:
		err = (*cmd_ptr->func.stk)(stack);
		break;


@@ 164,6 188,9 @@ eval_math(const char *expr, Stack *stack)
		if (endptr[0] == '\0')
			goto pushnum; /* If number, skip further parsing */

		if (mem_get(&dx, ptr[0]) == 0)
			goto pushnum;

		if ((op_ptr = op(ptr)) == NULL) {
			fprintf(stderr, "%s: undefined operation.\n", ptr);
			return;