misc/kforth: Add system status, work on vocab, better write_num.
- Now system structure includes a status variable and an associated function for writing the status out. - Adding more words to the builtin dictionary. - write_num round 3. - Include option to not print the stack each iteration.
This commit is contained in:
		
							parent
							
								
									3b284b7c08
								
							
						
					
					
						commit
						6a49675314
					
				
							
								
								
									
										7
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										7
									
								
								Makefile
								
								
								
								
							| 
						 | 
					@ -1,7 +1,9 @@
 | 
				
			||||||
CXXSTD :=	c++14
 | 
					CXXSTD :=	c++14
 | 
				
			||||||
CXXFLAGS :=	-std=$(CXXSTD) -Wall -Werror -g -O0
 | 
					CXXFLAGS :=	-std=$(CXXSTD) -Wall -Werror -Os -static
 | 
				
			||||||
 | 
					LDFLAGS :=	-static
 | 
				
			||||||
OBJS :=		linux/io.o	\
 | 
					OBJS :=		linux/io.o	\
 | 
				
			||||||
		io.o		\
 | 
							io.o		\
 | 
				
			||||||
 | 
							system.o	\
 | 
				
			||||||
		parser.o	\
 | 
							parser.o	\
 | 
				
			||||||
		word.o		\
 | 
							word.o		\
 | 
				
			||||||
		dict.o		\
 | 
							dict.o		\
 | 
				
			||||||
| 
						 | 
					@ -11,7 +13,8 @@ TARGET :=	kforth
 | 
				
			||||||
all: $(TARGET)
 | 
					all: $(TARGET)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(TARGET): $(OBJS)
 | 
					$(TARGET): $(OBJS)
 | 
				
			||||||
	$(CXX) $(CFLAGS) -o $@ $(OBJS)
 | 
						$(CXX) $(CXXFLAGS) -o $@ $(OBJS)
 | 
				
			||||||
 | 
						strip $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean:
 | 
					clean:
 | 
				
			||||||
	rm -f $(OBJS) $(TARGET)
 | 
						rm -f $(OBJS) $(TARGET)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								defs.h
								
								
								
								
							
							
						
						
									
										1
									
								
								defs.h
								
								
								
								
							| 
						 | 
					@ -5,6 +5,7 @@
 | 
				
			||||||
#include "linux/defs.h"
 | 
					#include "linux/defs.h"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
typedef int KF_INT;
 | 
					typedef int KF_INT;
 | 
				
			||||||
 | 
					typedef long KF_LONG;
 | 
				
			||||||
constexpr uint8_t STACK_SIZE = 16;
 | 
					constexpr uint8_t STACK_SIZE = 16;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								dict.h
								
								
								
								
							
							
						
						
									
										9
									
								
								dict.h
								
								
								
								
							| 
						 | 
					@ -6,14 +6,9 @@
 | 
				
			||||||
#include "system.h"
 | 
					#include "system.h"
 | 
				
			||||||
#include "word.h"
 | 
					#include "word.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum _LOOKUP_ : uint8_t {
 | 
					 | 
				
			||||||
	LOOKUP_OK = 0,	     // Lookup executed properly.
 | 
					 | 
				
			||||||
	LOOKUP_NOTFOUND = 1, // The token isn't in the dictionary.
 | 
					 | 
				
			||||||
	LOOKUP_FAILED = 2    // The word failed to execute.
 | 
					 | 
				
			||||||
} LOOKUP;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void	init_dict(System *);
 | 
					void	init_dict(System *);
 | 
				
			||||||
LOOKUP	lookup(struct Token *, System *);
 | 
					void	reset_system(System *);
 | 
				
			||||||
 | 
					bool	lookup(struct Token *, System *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
Write You a Forth, 0x05
 | 
					Write You a Forth, 0x05
 | 
				
			||||||
-----------------------
 | 
					-----------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:date: 2018-02-24 12:23
 | 
					:date: 2018-02-27 08:06
 | 
				
			||||||
:tags: wyaf, forth
 | 
					:tags: wyaf, forth
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NB: Today's update was pretty large, so I don't show all of the code; this is
 | 
					NB: Today's update was pretty large, so I don't show all of the code; this is
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								io.cc
								
								
								
								
							
							
						
						
									
										40
									
								
								io.cc
								
								
								
								
							| 
						 | 
					@ -8,21 +8,12 @@ static constexpr size_t	nbuflen = 11;
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
write_num(IO *interface, KF_INT n)
 | 
					write_num(IO *interface, KF_INT n)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// TODO(kyle): make the size of the buffer depend on the size of
 | 
					 | 
				
			||||||
	// KF_INT.
 | 
					 | 
				
			||||||
	char buf[nbuflen];
 | 
						char buf[nbuflen];
 | 
				
			||||||
	uint8_t i = nbuflen;
 | 
						uint8_t i = nbuflen - 1;
 | 
				
			||||||
	memset(buf, 0, i);
 | 
						memset(buf, 0, nbuflen);
 | 
				
			||||||
	bool neg = n < 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (n < 0) {
 | 
						if (n < 0) {
 | 
				
			||||||
		interface->wrch('-');
 | 
							interface->wrch('-');
 | 
				
			||||||
		n = ~n;
 | 
					 | 
				
			||||||
		if (n == 0) {
 | 
					 | 
				
			||||||
			neg = false;
 | 
					 | 
				
			||||||
			n++;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (n == 0) {
 | 
						else if (n == 0) {
 | 
				
			||||||
		interface->wrch('0');
 | 
							interface->wrch('0');
 | 
				
			||||||
| 
						 | 
					@ -30,13 +21,28 @@ write_num(IO *interface, KF_INT n)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (n != 0) {
 | 
						while (n != 0) {
 | 
				
			||||||
		char ch = (n % 10) + '0';
 | 
							char x = n % 10;
 | 
				
			||||||
		if (neg && (i == nbuflen)) ch++;
 | 
							x = x < 0 ? -x : x;
 | 
				
			||||||
		buf[i-1] = ch;
 | 
							x += '0';
 | 
				
			||||||
		i--;
 | 
							buf[i--] = x;
 | 
				
			||||||
		n /= 10;
 | 
							n /= 10;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t buflen = nbuflen - i % nbuflen;
 | 
						interface->wrbuf(buf+i, nbuflen - i);
 | 
				
			||||||
	interface->wrbuf(buf+i, buflen);
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					write_dstack(IO *interface, Stack<KF_INT> dstack)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						KF_INT	tmp;
 | 
				
			||||||
 | 
						interface->wrch('<');
 | 
				
			||||||
 | 
						for (size_t i = 0; i < dstack.size(); i++) {
 | 
				
			||||||
 | 
							if (i > 0) {
 | 
				
			||||||
 | 
								interface->wrch(' ');
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dstack.get(i, tmp);
 | 
				
			||||||
 | 
							write_num(interface, tmp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						interface->wrch('>');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										4
									
								
								io.h
								
								
								
								
							
							
						
						
									
										4
									
								
								io.h
								
								
								
								
							| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
#define __KF_IO_H__
 | 
					#define __KF_IO_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "defs.h"
 | 
					#include "defs.h"
 | 
				
			||||||
 | 
					#include "stack.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IO {
 | 
					class IO {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
| 
						 | 
					@ -19,9 +20,12 @@ public:
 | 
				
			||||||
	// Line I/O
 | 
						// Line I/O
 | 
				
			||||||
	virtual bool	rdln(char *buf, size_t len, size_t *readlen) = 0;
 | 
						virtual bool	rdln(char *buf, size_t len, size_t *readlen) = 0;
 | 
				
			||||||
	virtual void	wrln(char *buf, size_t len) = 0;
 | 
						virtual void	wrln(char *buf, size_t len) = 0;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						virtual void	newline(void) = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void	write_num(IO *, KF_INT);
 | 
					void	write_num(IO *, KF_INT);
 | 
				
			||||||
 | 
					void	write_dstack(IO *, Stack<KF_INT>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // __KF_IO_H__
 | 
					#endif // __KF_IO_H__
 | 
				
			||||||
							
								
								
									
										59
									
								
								kforth.cc
								
								
								
								
							
							
						
						
									
										59
									
								
								kforth.cc
								
								
								
								
							| 
						 | 
					@ -10,25 +10,10 @@
 | 
				
			||||||
#include "linux.h"
 | 
					#include "linux.h"
 | 
				
			||||||
#endif // __linux__
 | 
					#endif // __linux__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char     ok[] = "ok.\n";
 | 
					 | 
				
			||||||
static System	sys;
 | 
					static System	sys;
 | 
				
			||||||
 | 
					#ifndef TRACE_STACK
 | 
				
			||||||
 | 
					#define TRACE_STACK false
 | 
				
			||||||
static void
 | 
					#endif
 | 
				
			||||||
write_dstack()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	KF_INT	tmp;
 | 
					 | 
				
			||||||
	sys.interface->wrch('<');
 | 
					 | 
				
			||||||
	for (size_t i = 0; i < sys.dstack.size(); i++) {
 | 
					 | 
				
			||||||
		if (i > 0) {
 | 
					 | 
				
			||||||
			sys.interface->wrch(' ');
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sys.dstack.get(i, tmp);
 | 
					 | 
				
			||||||
		write_num(sys.interface, tmp);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	sys.interface->wrch('>');
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool
 | 
					static bool
 | 
				
			||||||
parser(const char *buf, const size_t buflen)
 | 
					parser(const char *buf, const size_t buflen)
 | 
				
			||||||
| 
						 | 
					@ -36,8 +21,6 @@ parser(const char *buf, const size_t buflen)
 | 
				
			||||||
	static size_t		offset = 0;
 | 
						static size_t		offset = 0;
 | 
				
			||||||
	static struct Token	token;
 | 
						static struct Token	token;
 | 
				
			||||||
	static PARSE_RESULT	result = PARSE_FAIL;
 | 
						static PARSE_RESULT	result = PARSE_FAIL;
 | 
				
			||||||
	static LOOKUP		lresult = LOOKUP_FAILED;
 | 
					 | 
				
			||||||
	static bool		stop = false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	offset = 0;
 | 
						offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,34 +29,17 @@ parser(const char *buf, const size_t buflen)
 | 
				
			||||||
	token.length = 0;
 | 
						token.length = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ((result = parse_next(buf, buflen, &offset, &token)) == PARSE_OK) {
 | 
						while ((result = parse_next(buf, buflen, &offset, &token)) == PARSE_OK) {
 | 
				
			||||||
		lresult = lookup(&token, &sys);
 | 
							if (!lookup(&token, &sys)) {
 | 
				
			||||||
		switch (lresult) {
 | 
					 | 
				
			||||||
		case LOOKUP_OK:
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		case LOOKUP_NOTFOUND:
 | 
					 | 
				
			||||||
			sys.interface->wrln((char *)"word not found", 15);
 | 
					 | 
				
			||||||
			stop = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case LOOKUP_FAILED:
 | 
					 | 
				
			||||||
			sys.interface->wrln((char *)"execution failed", 17);
 | 
					 | 
				
			||||||
			stop = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			sys.interface->wrln((char *)"*** the world is broken ***", 27);
 | 
					 | 
				
			||||||
			exit(1);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if (stop) {
 | 
					 | 
				
			||||||
			stop = false;
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						system_write_status(&sys);
 | 
				
			||||||
 | 
						sys.interface->newline();
 | 
				
			||||||
	switch (result) {
 | 
						switch (result) {
 | 
				
			||||||
	case PARSE_OK:
 | 
						case PARSE_OK:
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	case PARSE_EOB:
 | 
						case PARSE_EOB:
 | 
				
			||||||
		sys.interface->wrbuf(ok, 4);
 | 
					 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	case PARSE_LEN:
 | 
						case PARSE_LEN:
 | 
				
			||||||
		sys.interface->wrln((char *)"parse error: token too long", 27);
 | 
							sys.interface->wrln((char *)"parse error: token too long", 27);
 | 
				
			||||||
| 
						 | 
					@ -94,8 +60,10 @@ interpreter()
 | 
				
			||||||
	static char linebuf[81];
 | 
						static char linebuf[81];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (true) {
 | 
						while (true) {
 | 
				
			||||||
		write_dstack();
 | 
							if (TRACE_STACK) {
 | 
				
			||||||
		sys.interface->wrch('\n');
 | 
								write_dstack(sys.interface, sys.dstack);
 | 
				
			||||||
 | 
								sys.interface->newline();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		sys.interface->wrch('?');
 | 
							sys.interface->wrch('?');
 | 
				
			||||||
		sys.interface->wrch(' ');
 | 
							sys.interface->wrch(' ');
 | 
				
			||||||
		buflen = sys.interface->rdbuf(linebuf, 80, true, '\n');
 | 
							buflen = sys.interface->rdbuf(linebuf, 80, true, '\n');
 | 
				
			||||||
| 
						 | 
					@ -103,18 +71,19 @@ interpreter()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char	banner[] = "kforth interpreter\n";
 | 
					static char	banner[] = "kforth interpreter";
 | 
				
			||||||
const size_t	bannerlen = 19;
 | 
					const size_t	bannerlen = 18;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
main(void)
 | 
					main(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						reset_system(&sys);
 | 
				
			||||||
	init_dict(&sys);
 | 
						init_dict(&sys);
 | 
				
			||||||
#ifdef __linux__
 | 
					#ifdef __linux__
 | 
				
			||||||
	Console interface;
 | 
						Console interface;
 | 
				
			||||||
	sys.interface = &interface;
 | 
						sys.interface = &interface;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	sys.interface->wrbuf(banner, bannerlen);
 | 
						sys.interface->wrln(banner, bannerlen);
 | 
				
			||||||
	interpreter();
 | 
						interpreter();
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,8 @@
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef int32_t KF_INT;
 | 
					typedef int32_t KF_INT;
 | 
				
			||||||
 | 
					typedef int64_t	KF_LONG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr uint8_t	STACK_SIZE = 128;
 | 
					constexpr uint8_t	STACK_SIZE = 128;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,8 @@ public:
 | 
				
			||||||
	// Line I/O
 | 
						// Line I/O
 | 
				
			||||||
	bool	rdln(char *buf, size_t len, size_t *readlen);
 | 
						bool	rdln(char *buf, size_t len, size_t *readlen);
 | 
				
			||||||
	void	wrln(char *buf, size_t len);
 | 
						void	wrln(char *buf, size_t len);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						void	newline(void) { this->wrch('\n'); };
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@
 | 
				
			||||||
#include <ctype.h>
 | 
					#include <ctype.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static inline void
 | 
				
			||||||
reset(struct Token *t)
 | 
					reset(struct Token *t)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	t->token = nullptr;
 | 
						t->token = nullptr;
 | 
				
			||||||
| 
						 | 
					@ -48,9 +48,7 @@ parse_next(const char *buf, const size_t length, size_t *offset,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t	 cursor = *offset;
 | 
						size_t	 cursor = *offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Clear the token.
 | 
					 | 
				
			||||||
	reset(token);
 | 
						reset(token);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (cursor == length) {
 | 
						if (cursor == length) {
 | 
				
			||||||
		return PARSE_EOB;
 | 
							return PARSE_EOB;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								stack.h
								
								
								
								
							
							
						
						
									
										18
									
								
								stack.h
								
								
								
								
							| 
						 | 
					@ -9,6 +9,7 @@ public:
 | 
				
			||||||
        bool   push(T val);
 | 
					        bool   push(T val);
 | 
				
			||||||
	bool   pop(T *val);
 | 
						bool   pop(T *val);
 | 
				
			||||||
	bool   get(size_t, T &);
 | 
						bool   get(size_t, T &);
 | 
				
			||||||
 | 
						bool   remove(size_t, T *);
 | 
				
			||||||
	size_t size(void) { return this->arrlen; }
 | 
						size_t size(void) { return this->arrlen; }
 | 
				
			||||||
	void   clear(void) { this->arrlen = 0; }
 | 
						void   clear(void) { this->arrlen = 0; }
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
| 
						 | 
					@ -56,4 +57,21 @@ Stack<T>::get(size_t i, T &val)
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// remove returns false on invalid bounds
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					bool
 | 
				
			||||||
 | 
					Stack<T>::remove(size_t i, T *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (i > this->arrlen) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*val = this->arr[i];
 | 
				
			||||||
 | 
						for (; i < (arrlen - 1); i++) {
 | 
				
			||||||
 | 
							this->arr[i] = this->arr[i+1];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						arrlen--;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // __KF_STACK_H__
 | 
					#endif // __KF_STACK_H__
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,64 @@
 | 
				
			||||||
 | 
					#include "defs.h"
 | 
				
			||||||
 | 
					#include "system.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr static char	STATE_STR_OK[] = "ok";
 | 
				
			||||||
 | 
					constexpr static char   STATE_STR_STACK_OVERFLOW[] = "stack overflow";
 | 
				
			||||||
 | 
					constexpr static char   STATE_STR_STACK_UNDERFLOW[] = "stack underflow";
 | 
				
			||||||
 | 
					constexpr static char   STATE_STR_EXECUTION_FAILURE[] = "execution failure";
 | 
				
			||||||
 | 
					constexpr static char	STATE_STR_UNKNOWN_WORD[] = "unknown word";
 | 
				
			||||||
 | 
					constexpr static char	STATE_STR_UNKNOWN_STATE[] = "undefined state";
 | 
				
			||||||
 | 
					constexpr static char	STATE_STR_ERROR_CODE[] = " (error code ";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					system_clear_error(System *sys)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						sys->status = STATUS_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					system_write_status(System *sys)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char	*buf = nullptr;
 | 
				
			||||||
 | 
						size_t	 len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sys->interface == nullptr) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						switch (sys->status) {
 | 
				
			||||||
 | 
						case STATUS_OK:
 | 
				
			||||||
 | 
							buf = (char *)(STATE_STR_OK);
 | 
				
			||||||
 | 
							len = sizeof STATE_STR_OK;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case STATUS_STACK_OVERFLOW:
 | 
				
			||||||
 | 
							buf = (char *)(STATE_STR_STACK_OVERFLOW);
 | 
				
			||||||
 | 
							len = sizeof STATE_STR_STACK_OVERFLOW;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case STATUS_STACK_UNDERFLOW:
 | 
				
			||||||
 | 
							buf = (char *)(STATE_STR_STACK_UNDERFLOW);
 | 
				
			||||||
 | 
							len = sizeof STATE_STR_STACK_UNDERFLOW;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case STATUS_EXECUTION_FAILURE:
 | 
				
			||||||
 | 
							buf = (char *)(STATE_STR_EXECUTION_FAILURE);
 | 
				
			||||||
 | 
							len = sizeof STATE_STR_EXECUTION_FAILURE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case STATUS_UNKNOWN_WORD:
 | 
				
			||||||
 | 
							buf = (char *)(STATE_STR_UNKNOWN_WORD);
 | 
				
			||||||
 | 
							len = sizeof STATE_STR_UNKNOWN_WORD;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							buf = (char *)(STATE_STR_UNKNOWN_STATE);
 | 
				
			||||||
 | 
							len = sizeof STATE_STR_UNKNOWN_STATE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						sys->interface->wrbuf(buf, len);
 | 
				
			||||||
 | 
						if (sys->status != STATUS_OK) {
 | 
				
			||||||
 | 
							sys->interface->wrbuf((char *)STATE_STR_ERROR_CODE, sizeof STATE_STR_ERROR_CODE);
 | 
				
			||||||
 | 
							write_num(sys->interface, (KF_INT)sys->status);
 | 
				
			||||||
 | 
							sys->interface->wrch(')');
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sys->interface->wrch('.');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								system.h
								
								
								
								
							
							
						
						
									
										15
									
								
								system.h
								
								
								
								
							| 
						 | 
					@ -5,11 +5,24 @@
 | 
				
			||||||
#include "io.h"
 | 
					#include "io.h"
 | 
				
			||||||
#include "stack.h"
 | 
					#include "stack.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum _SYS_STATUS : uint8_t {
 | 
				
			||||||
 | 
						STATUS_OK = 0,
 | 
				
			||||||
 | 
						STATUS_STACK_OVERFLOW = 1,
 | 
				
			||||||
 | 
						STATUS_STACK_UNDERFLOW = 2,
 | 
				
			||||||
 | 
						STATUS_EXECUTION_FAILURE = 3,
 | 
				
			||||||
 | 
						STATUS_UNKNOWN_WORD = 4
 | 
				
			||||||
 | 
					} SYS_STATUS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Word;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct _System {
 | 
					typedef struct _System {
 | 
				
			||||||
	Stack<KF_INT>	 dstack;
 | 
						Stack<KF_INT>	 dstack;
 | 
				
			||||||
	IO		*interface;
 | 
						IO		*interface;
 | 
				
			||||||
	struct Word	*dict;
 | 
						Word		*dict;
 | 
				
			||||||
 | 
						SYS_STATUS	 status;
 | 
				
			||||||
} System;
 | 
					} System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	system_clear_error(System *sys);
 | 
				
			||||||
 | 
					void	system_write_status(System *sys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // __KF_CORE_H__
 | 
					#endif // __KF_CORE_H__
 | 
				
			||||||
		Loading…
	
		Reference in New Issue