#include "node.h"
// calculate the size of an array of any type
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))
// operations in descending priority
char mvd[] = { '*', '/', '+', '-', '=' };
// index in numInput array
uint8_t numIdx = 0;
// max length for number
const uint8_t maxNumLength = 7;
// array to store a number as text
char numInput[maxNumLength + 1];
char buf[64];
const uint8_t maxNodes = 20;
Node node;
struct LIST
{
// number of nodes currently in list
uint8_t size;
// array of nodes
Node nodes[maxNodes];
/* calculates the outcome of a sum.
In: nothing
Returns: nothing
*/
void calculate() {
if (nodes[size - 1].op != '=')
{
Serial.println(F("Geen '=' aan het eind"));
return;
}
Serial.println(__FUNCTION__);
Serial.println("ik ben nu aan het rekenen");
bool complete = false;
for (uint8_t prioCnt = 0; prioCnt < NUMELEMENTS(mvd) && complete == false; prioCnt++)
{
Serial.print(F("prioCnt = "));
Serial.println(prioCnt);
Serial.println("nu naar de operators aan het kijken");
Serial.print("De lijst bevat :");
Serial.print(size);
Serial.println(" items");
for (int i = 0; i < size; i++)
{
if (nodes[i].op == mvd[prioCnt]) {
Serial.println("ben nu in de loop");
Serial.print(F("i = "));
Serial.println(i);
Serial.println("Huidige item: ");
nodes[i].print(" ");
float n1 = nodes[i].val;
float n2 = nodes[i + 1].val;
switch (nodes[i].op)
{
case '*':
Serial.println(F("Vermenigvuldigen"));
update( i + 1, n1 * n2);
remove(i);
Serial.println(F("Na vermenigvuldigen"));
print();
break;
case '/':
Serial.println(F("Delen"));
if (n2 == 0)
{
Serial.println("delen door nul mag niet");
clear();
print();
return;
}
nodes[i + 1].val = n1 / n2;
remove(i);
Serial.println(F("Na delen"));
print();
break;
case '=':
complete = true;
break;
case '+' :
Serial.println(F("Optellen")) ;
nodes[i + 1].val = n1 + n2 ;
remove(i);
Serial.println(F("na optellen"));
print();
break;
case '-' :
Serial.println(F("Aftrekken")) ;
nodes[i + 1].val = n1 - n2 ;
remove(i);
Serial.println(F("na aftrekken"));
print();
break;
}
}
}
}
if (complete == true)
{
Serial.print(" Resultaat = ");
Serial.println(nodes[0].val, 6);
}
remove(0);
Serial.print("Einde van ");
Serial.println(__FUNCTION__);
}
/* clear thw whole list
In: nothing
Returns:
true is sucees
*/
bool clear() {
size = 0;
return true;
}
/* updates the value of a node with the value of another node
In:
index of the node which needs to be updated
A node with the new values
Returns:
true in success, else false
*/
bool update(uint8_t idx, Node node) {
// validate index
if (idx >= size) {
return false;
}
// update the value
nodes[idx].val = node.val ;
// update the operator
nodes[idx].op = node.op ;
return true;
}
/* updates the value of a node with new float value
In:
index of the node which needs to be updated
A float value
Returns:
true in success, else false
*/
bool update(uint8_t idx, float f) {
if (idx >= size) {
return false;
}
nodes[idx].val = f;
return true;
}
/*
removes a node to the 'list'
In:
index of the node to remove
Returns:
true in sucess, else false
*/
bool remove(uint8_t idx)
{
// validate index
if (idx >= size)
{
Serial.println(F("Ongeldige index"));
return false;
};
// move all tokens one place from index to end one-by-one
for (uint8_t cnt = idx; cnt < size - 1; cnt++)
{
// debug
Serial.print(F("Copy "));
Serial.print(cnt + 1);
Serial.print(F(" to "));
Serial.println(cnt);
// copy
nodes[cnt] = nodes[cnt + 1];
}
// decrement size
size--;
return true;
}
/*
Add a node to the 'list'
In:
node to add
Returns:
true in success, else false
*/
bool add(Node node)
{
// check
if (size == NUMELEMENTS(nodes))
{
Serial.println(F("Lijst van bewerkingen is vol"));
return false;
}
// copy the specified node to the end of the list
memcpy(&nodes[size], &node, sizeof(Node));
size++;
return true;
}
/*
Print the current nodes in the list
*/
void print()
{
// if the list is empty
if (size == 0)
{
Serial.println(F("De lijst is leeg"));
return;
}
Serial.println(F("Lijst van nodes"));
// loop through the array of nodes
for (uint8_t cnt = 0; cnt < size; cnt++)
{
Serial.print(F(" Index = "));
Serial.println(cnt);
nodes[cnt].print(" ");
}
}
};
LIST list;
void setup()
{
Serial.begin(115200);
Serial.println(F("Rekenmachine"));
}
void loop()
{
// if there is user input
if (Serial.available() > 0)
{
// process it
processInput();
list.calculate();
}
}
void processInput()
{
// read input
char ch = Serial.read();
Serial.print(__FUNCTION__);
Serial.print(F(" '"));
Serial.print(ch);
Serial.println(F("'"));
// if it's numeric
if ((ch >= '0' && ch <= '9') || ch == '.')
{
// check if we can still store digits
if (numIdx > maxNumLength - 1)
{
// number input is full
Serial.println(F(" Maximaal aantal cijfers bereikt; bewerking verwacht"));
}
// still space, add to number
else
{
Serial.println(F(" Numeriek"));
numInput[numIdx] = ch;
numIdx++;
Serial.print(F(" numInput = \""));
Serial.print(numInput);
Serial.println(F("\""));
}
}
// if it's '-' )
else if (ch == '-')
{
// '-' only accepted as first character of number
if (numIdx == 0)
{
Serial.println(F(" Negatief nummmer"));
numInput[numIdx] = ch;
numIdx++;
Serial.print(F(" numInput = \""));
Serial.print(numInput);
Serial.println(F("\""));
}
// it's an operation
else
{
Serial.println(F(" Bewerking '-'"));
getOperation(ch);
}
}
// it's a possible operation
else
{
Serial.print(F(" Mogelijke bewerking '"));
Serial.print(ch);
Serial.println(F("'"));
getOperation(ch);
}
}
/*
Check for a possible operation
In:
character to check
*/
void getOperation(char ch)
{
// flag to indicate that a valid operation was detected
// prevents numerous 'Ongeldige bewerking' messages
bool validOperation = false;
Serial.print(__FUNCTION__);
Serial.print(F(" '"));
Serial.print(ch);
Serial.println(F("'"));
for (uint8_t cnt = 0; cnt < NUMELEMENTS(mvd); cnt++)
{
// if the input is in mvd
if (ch == mvd[cnt])
{
validOperation = true;
Serial.println(F(" Geldige bewerking"));
Serial.print(F(" Getal = "));
Serial.println(numInput);
Serial.print(F(" Bewerking = '"));
Serial.print(ch);
Serial.println(F("'"));
// TODO roelofw
// convert number input to float
list.add({ atof(numInput), ch });
// reset index
numIdx = 0;
// clear number input
memset(numInput, '\0', sizeof(numInput));
break;
}
}
if (validOperation == false)
{
// invalid operation
Serial.println(F(" Ongeldige bewerking"));
}
}