view src/operations.c @ 26:c1ad124f2aaf

Re-did errors for pop, added some nice testing for dynamic memory I now have a decent test program for dynamic memory implemented as a separate program (dynamic.c) The stack now stores its current size, this is used in operations.c to check the size Pop should now also be called with a pointer to an eltType. Description of behavior is in stack.h
author Jonathan Pevarnek <pevarnj@gmail.com>
date Sun, 20 Mar 2011 14:17:24 -0400
parents 2b19746a4e97
children 1a070e843bf6
line wrap: on
line source

#include <operations.h>
#include <std.h>
#include <stack.h>
#include <math.h>

const char operationNames[MAXOP][10] = {".", "+", "-", "*", "/", "**", "dup", "drop", "log", "exp", "swap"};
void (*operation[MAXOP])(Stack*) = {op_print, op_add, op_sub, op_mult,
	op_div, op_pow, op_dup, op_drop, op_log, op_exp, op_swap};

static void error_unk()
{
	sPrint("ERROR: CAUSE UNKNOWN\n");
}

static void error_small()
{
	sPrint("ERROR: STACK TOO SMALL\n");
}

void op_math1(Stack *stack, eltType (*mathop)(eltType))
{
	if(stack->size >= 1) {
		eltType val;
		if(pop(stack, &val)) error_unk();
		else push(stack, mathop(val));
	} else error_small();
}

void op_math2(Stack *stack, eltType (*mathop)(eltType, eltType))
{
	if(stack->size >= 2) {
		eltType val1, val2;
		if(pop(stack, &val2) || pop(stack, &val1)) error_unk();
		else push(stack, mathop(val1, val2));
	} else error_small();
}

void op_print(Stack *stack)
{
	if(stack->size >= 1) {
		char output[30];
		eltType val;
		if(pop(stack, &val)) error_unk();
		else sPrint(append(ftoa(val, output, 10), "\n"));
	} else error_small();
}

void op_add(Stack *stack)
{
	op_math2(stack, math_add);
}

void op_sub(Stack *stack)
{
	op_math2(stack, math_sub);
}

void op_mult(Stack *stack)
{
	op_math2(stack, math_mult);
}

void op_div(Stack *stack)
{
	op_math2(stack, math_div);
}

void op_pow(Stack *stack)
{
	op_math2(stack, math_pow);
}

void op_dup(Stack *stack)
{
	if(stack->size >= 1) {
		eltType val;
		if(pop(stack, &val)) error_unk();
		else {
			push(stack, val);
			push(stack, val);
		}
	} else error_small();
}

void op_drop(Stack *stack)
{
	if(stack->size >= 1) {
		eltType val;
		pop(stack, &val);
	} else error_small();
}

void op_log(Stack *stack)
{
	op_math1(stack, math_log);
}

void op_exp(Stack *stack)
{
	op_math1(stack, math_exp);
}

void op_swap(Stack *stack)
{
	if(stack->size >= 2) {
		eltType val1, val2;
		if(pop(stack, &val2) || pop(stack, &val1)) error_unk();
		else {
			push(stack, val2);
			push(stack, val1);
		}
	} else error_small();
}