#ifndef _CODE_H
#define _CODE_H

#include "ktypes.h"

/* ----------------------------------------------------- */

// The CODE unit has the responsibility to:

//	organize and save KCODE instructions
//	to maintain extern references within KCODE
//	to maintain global references within KCODE
//	to maintain label references within KCODE
//	to maintain the program counter PC
//	to maintain the program FLAGS

// Initial declarations specify table structures for:

//	extern references
//	global references
//	label references: name and instruction location
//	kcode instructions: opcode, oper1, oper2, oper3

// Final declaration specifies the strucute of CODE:

// Most of the methods listed are self-explanatory.
// However, the following are of special note:

// searchLabels
//	check for duplicates
//	   and retrieve instruction location
// addInstruction
//	create instruction list in precise order
//	maintain instruction location (for labels)
// fetchInstruction
//	critical at execution time
//	retrieve proper item from the instruction list

/* ----------------------------------------------------- */

struct labelData
{
   char*		name;
   long long		location;
};

struct labelEntry
{
  struct labelData	data;
  struct labelEntry*	next;
};

struct labelEntry*	LABELS;

void		displayLabels	(void);

long long	labelAddress    (char*);

struct nameEntry
{
  char*			data;
  struct nameEntry*	next;
};

struct nameEntry*       GLOBALS;
struct nameEntry*	EXTERNS;

void		displayGlobals	(void);
void		displayExterns	(void);

void		_LABEL          (char*);
void		_EXTERN         (char*);
void		_GLOBAL         (char*);

int		isLabel         (char*);
int		isExtern        (char*);
int		isGlobal        (char*);

/* ----------------------------------------------------- */

// important CPU flags
//    PC = program counter
//    EQ = equal flag
//    GT = greater than flag
//    LT = less than flag

// INSTRUCTION_COUNTER maintains instruction count
//    current size of instruction list
//    necessary for proper definition of labels

long long	PC;
int		EQ;
int		GT;
int		LT;

long long	INSTRUCTION_COUNTER;

void		setPC		(long long);

void		setEQ		(void);
void		setGT		(void);
void		setLT		(void);

/* ----------------------------------------------------- */

struct codeData
{
   char*	opcode;
   char*	oper1;
   char*	oper2;
   char*	oper3;
};

#define	MAXCODE 5000
struct codeData	INSTRUCTIONS[MAXCODE];

void		displayCode	(void);

void		addInstruction	(char*,char*,char*,char*);

struct codeData	fetchInstruction (void);

/* ----------------------------------------------------- */

#endif
