/*
1+ 1-	increment, decrement
2* 2/	Double/ Divide by 2
/MOD	Modulo operation
= < > <= >= <>	relational operators
! +! -!	assignment operators
AND OR XOR	logical operators
<< U>>	bit shift
MIN MAX	compares 2 values at the top of the stack and returns the smaller number (MIN)/larger number (MAX)
.	prints the top most value on the stack
.S	prints all values in stack
@	the value on top of the stack points to a memory address which value is put on top of the current stack
+ - *	plus, minus, multiply
SWAP	swap 2 values on top of stack with each other
DUP	duplicate the value at the top of stack and place it on stack
DROP	delete the value at top of stack
OVER	copy the 2nd most value on top of stack and overwrite the first value in the stack
ROT	rotate the top 3 values in stack
2SWAP	Reverses the top two pairs of numbers.
2DUP	Duplicates the top pair of numbers.
2OVER	Makes a copy of the second pair of numbers and pushes it on top.
2DROP	Discards the top pair of numbers.
MOD	push the remainder into the stack
*/

const char * increment = "1+";
const char * decrement = "i-";
const char * double = "2*";
const char * split = "2/";
const char * modulo = "/MOD";
const char * equal = "=";
const char * smallerThan = "<";
const char * greaterThan = ">";
const char * smallerOrEqual = "<=";
const char * greaterOrEqual = ">=";
const char * notEqual = "<>";
const char * assign = "!";
const char * assignInc = "+!";
const char * assignDev = "-!";
const char * logicalAnd = "AND";
const char * logicalOr = "OR";
const char * logicalXor = "XOR";
const char * bitShiftLeft = "<<";
const char * bitShiftRight = "U>>";
const char * min = "MIN";
const char * max = "MAX";
const char * print = ".";
const char * printAll = ".S";
const char * at = "@";      //get at memory
const char * plus = "+";
const char * minus = "-";
const char * multiply = "*";
const char * swap = "SWAP";
const char * dup = "DUP";
const char * drop = "DROP";
const char * over = "OVER"; //dup second value overide first
const char * rotate = "ROT";
const char * swapPair = "2SWAP";
const char * dupPair = "2DUP";
const char * overPair = "2OVER";
const char * dropPair = "2DROP";
const char * modPush = "MOD";

/*var déclaration
VARIABLE {name}	Declare a variable. Using an variable will only return its memory address. use @ to return the value inside the address
{value} CONSTANT {name}	declare a constant value
: {name} {operation} ;	Declare a word. a new line can be started within operation.
."hello world"	print out a string
CR	print out a carriage return
{conditional statement} IF {true operation} THEN	if statement. can only be used when declaring a word. Can be nested
{conditional statement} IF {true operation} ELSE {false operation} THEN	same as above, but with else
{loop num} {initial value} DO {operation} LOOP	loop statement. same rules as if statement apply.
BEGIN {conditional statement} WHILE {operation} REPEAT	indefinite loop. Can not use counters or UNLOOP
BEGIN {operation} AGAIN	Infinite loop, to branch out use EXIT
I J	counters for loop
UNLOOP	get out of loop
EXIT	branch out while executing a WORD
SPACE	print out a space character
{num} EMIT	print out a character with ASCII code
{num} SPACES	print out a space num times
*/

const char * declareVar = "VARIABLE";
const char * constantVar = "CONSTANT";
const char * startFunc = ":";
const char * endFunc = ";";

const char * carriageReturn = "CR";
const char * space = "SPACE";
const char * ascii = "EMIT";
const char * spaces = "SPACES";

const char * condIf = "IF";
const char * condThen = "THEN";
const char * condElse = "ELSE";

const char * startLoop = "DO";
const char * endLoop = "LOOP";
const char * exitLoop = "UNLOOP";
const char * counterLoop = "I";
const char * counterLoop2 = "J";

const char * beginWhile = "BEGIN";
const char * doWhile = "WHILE";
const char * endWhile = "REPEAT";
const char * infiniteWhile = "REPEAT";
const char * exit = "EXIT";

/*redstone io
IOXADDR	set the bus ID of I/O Device you want to use
{value} IOX!	set the output of the I/O device
IOX@	get the input value from the I/O device
{value} IOXSET	turn on the set value
{value} IOXRST	turn off the set value
*/



/*
PAGE	clear screen
SAVE" name"	name an empty floppy
{value} TICKS	sleep, 1 tick = 1/20 second
{num} TIMES {word}	execute a WORD num times
DISKID	print the disk ID of the disk currently in drive
*/

/*IO expander color value
White	1
Orange	2
Magenta	4
Light Blue	8
Yellow	16
Lime	32
Pink	64
Gray	128
Light Gray	256
Cyan	512
Purple	1024
Blue	2048
Brown	4096
Green	8192
Red	16384
Black	32768
*/

#define push(SP) (SP--)
#define pop(SP) (++SP)

struct forthVM{
    int memory[600],
        sp,
        cnt;
};

//word is a "spc,cr or null terminated" character string 
struct forthVM * execute(struct forthVM * machine, char * word)
{
    
}
