misc/kforth: Restart the world.
This commit is contained in:
		
							parent
							
								
									a1149654d4
								
							
						
					
					
						commit
						7a2ed45857
					
				
							
								
								
									
										29
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										29
									
								
								Makefile
								
								
								
								
							| 
						 | 
					@ -1,23 +1,28 @@
 | 
				
			||||||
CXXSTD :=	c++14
 | 
					PLATFORM ?=	default
 | 
				
			||||||
CXXFLAGS :=	-std=$(CXXSTD) -Wall -Werror -O0 -g
 | 
					CSTD :=		c99
 | 
				
			||||||
 | 
					CFLAGS ?=	-std=$(CSTD) -Wall -Werror -O0 -g -DPLATFORM_$(PLATFORM)
 | 
				
			||||||
LDFLAGS :=	-static
 | 
					LDFLAGS :=	-static
 | 
				
			||||||
OBJS :=		linux/io.o	\
 | 
					OBJS :=		stack.o		\
 | 
				
			||||||
		io.o		\
 | 
							eval.o		\
 | 
				
			||||||
		system.o	\
 | 
					 | 
				
			||||||
		parser.o	\
 | 
					 | 
				
			||||||
		word.o		\
 | 
							word.o		\
 | 
				
			||||||
		dict.o		\
 | 
							kf.o
 | 
				
			||||||
		kforth.o
 | 
					TARGET :=	kf-$(PLATFORM)
 | 
				
			||||||
TARGET :=	kforth
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
all: $(TARGET)
 | 
					all: $(TARGET)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(TARGET): $(OBJS)
 | 
					$(TARGET): $(OBJS)
 | 
				
			||||||
	$(CXX) $(LDFLAGS) -o $@ $(OBJS)
 | 
						$(CC) $(LDFLAGS) -o $@ $(OBJS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean:
 | 
					clean-objs:
 | 
				
			||||||
	rm -f $(OBJS) $(TARGET)
 | 
						rm -f $(OBJS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					clean: clean-objs
 | 
				
			||||||
 | 
						rm -f kf-pc kf-default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
install: $(TARGET)
 | 
					install: $(TARGET)
 | 
				
			||||||
	cp $(TARGET) ~/bin
 | 
						cp $(TARGET) ~/bin
 | 
				
			||||||
	chmod 0755 ~/bin/$(TARGET)
 | 
						chmod 0755 ~/bin/$(TARGET)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cross:
 | 
				
			||||||
 | 
						make PLATFORM=default clean-objs all
 | 
				
			||||||
 | 
						make PLATFORM=pc clean-objs all
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,14 +1,12 @@
 | 
				
			||||||
#ifndef __KF_PLATFORM_DEFAULT_H__
 | 
					#ifndef __KF_DEFAULT_DEFS_H__
 | 
				
			||||||
#define __KF_PLATFORM_DEFAULT_H__
 | 
					#define __KF_DEFAULT_DEFS_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdint.h>
 | 
					typedef int	KF_INT;
 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef int KF_INT;
 | 
					 | 
				
			||||||
typedef uintptr_t KF_ADDR;
 | 
					typedef uintptr_t KF_ADDR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr static size_t STACK_SIZE = 48 / sizeof(KF_INT);
 | 
					static const size_t	DSTACK_SIZE = 12;
 | 
				
			||||||
constexpr static size_t	DICT_SIZE  = 4096;
 | 
					static const size_t	RSTACK_SIZE = 12;
 | 
				
			||||||
constexpr static size_t	ARENA_SIZE = 256;
 | 
					static const size_t	DICT_SIZE = 4096;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __KF_DEFAULT_DEFS_H__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // __KF_PLATFORM_DEFAULT_H__
 | 
					 | 
				
			||||||
							
								
								
									
										7
									
								
								defs.h
								
								
								
								
							
							
						
						
									
										7
									
								
								defs.h
								
								
								
								
							| 
						 | 
					@ -1,12 +1,15 @@
 | 
				
			||||||
#ifndef __KF_DEFS_H__
 | 
					#ifndef __KF_DEFS_H__
 | 
				
			||||||
#define __KF_DEFS_H__
 | 
					#define __KF_DEFS_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if PLATFORM == PC
 | 
					#ifdef PLATFORM_pc
 | 
				
			||||||
#include "pc/defs.h"
 | 
					#include "pc/defs.h"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#include "default/defs.h"
 | 
					#include "default/defs.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif __KF_DEFS_H__
 | 
					#endif /* __KF_DEFS_H__ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,3 +16,17 @@ Some design choices that didn't really work out:
 | 
				
			||||||
+ my linked list approach to the dictionary
 | 
					+ my linked list approach to the dictionary
 | 
				
			||||||
+ my class-based approach to words
 | 
					+ my class-based approach to words
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					I get the distinct feeling that I could (maybe should) be doing this in C99, so
 | 
				
			||||||
 | 
					I think I'll switch to that.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The new design
 | 
				
			||||||
 | 
					^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					I'll need to provide a few initial pieces:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. eval.c
 | 
				
			||||||
 | 
					2. stack.c
 | 
				
			||||||
 | 
					3. the platform parts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					I'll skip the parser at first and hand hack some things, then try to
 | 
				
			||||||
 | 
					port over my I/O layer from before.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					#include "defs.h"
 | 
				
			||||||
 | 
					#include "eval.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cwexec(uintptr_t entry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uintptr_t	target = 0;
 | 
				
			||||||
 | 
						uintptr_t	codeword = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy(&codeword, (void *)entry, sizeof(uintptr_t));	
 | 
				
			||||||
 | 
						memcpy(&target, (void *)(entry + sizeof(uintptr_t)), sizeof(uintptr_t));	
 | 
				
			||||||
 | 
						((void(*)(uintptr_t))codeword)(target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					nexec(uintptr_t target)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						((void(*)(void))target)();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					#ifndef __KF_EVAL_H__
 | 
				
			||||||
 | 
					#define __KF_EVAL_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "defs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * cwexec is the codeword executor. It assumes that the uintptr_t
 | 
				
			||||||
 | 
					 * passed into it points to the correct executor (e.g. nexec), 
 | 
				
			||||||
 | 
					 * which is called with the next address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void	cwexec(uintptr_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * nexec is the native executor. 
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * It should take a uintptr_t containing the address of a code block
 | 
				
			||||||
 | 
					 * and will execute the function starting there. The function should
 | 
				
			||||||
 | 
					 * half the signature void(*target)(void) - a function returning
 | 
				
			||||||
 | 
					 * nothing and taking no arguments.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void	nexec(uintptr_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uintptr_t	nexec_p = (uintptr_t)&nexec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __KF_EVAL_H__ */
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					#include "defs.h"
 | 
				
			||||||
 | 
					#include "eval.h"
 | 
				
			||||||
 | 
					#include "stack.h"
 | 
				
			||||||
 | 
					#include "word.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					hello(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						printf("hello, world\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					main(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dstack_push(2);
 | 
				
			||||||
 | 
						dstack_push(3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t	arena[128] = {0};
 | 
				
			||||||
 | 
						uintptr_t arena_p = (uintptr_t)arena;
 | 
				
			||||||
 | 
						store_native(arena, hello);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cwexec(arena_p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("finished\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								pc/defs.h
								
								
								
								
							
							
						
						
									
										17
									
								
								pc/defs.h
								
								
								
								
							| 
						 | 
					@ -1,14 +1,11 @@
 | 
				
			||||||
#ifndef __KF_PLATFORM_PC_H__
 | 
					#ifndef __KF_PC_DEFS_H__
 | 
				
			||||||
#define __KF_PLATFORM_PC_H__
 | 
					#define __KF_PC_DEFS_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdint.h>
 | 
					typedef int32_t	KF_INT;
 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef int32_t KF_INT;
 | 
					 | 
				
			||||||
typedef uintptr_t KF_ADDR;
 | 
					typedef uintptr_t KF_ADDR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr static size_t STACK_SIZE = 65535;
 | 
					static const size_t	DSTACK_SIZE = 65535;
 | 
				
			||||||
constexpr static size_t	DICT_SIZE  = 65535;
 | 
					static const size_t	RSTACK_SIZE = 65535;
 | 
				
			||||||
constexpr static size_t	ARENA_SIZE = 65535;
 | 
					static const size_t	DICT_SIZE   = 65535;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __KF_PC_DEFS_H__ */
 | 
				
			||||||
#endif // __KF_PLATFORM_PC_H__
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,98 @@
 | 
				
			||||||
 | 
					#include "defs.h"
 | 
				
			||||||
 | 
					#include "stack.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static KF_INT	dstack[DSTACK_SIZE] = {0};
 | 
				
			||||||
 | 
					static size_t	dstack_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool
 | 
				
			||||||
 | 
					dstack_pop(KF_INT *a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (dstack_len == 0) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*a = dstack[--dstack_len];
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool
 | 
				
			||||||
 | 
					dstack_push(KF_INT a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (dstack_len == DSTACK_SIZE) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dstack[dstack_len++] = a;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool
 | 
				
			||||||
 | 
					dstack_get(size_t i, KF_INT *a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (i >= dstack_len) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*a = dstack[dstack_len - i - 1];
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					dstack_size()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dstack_len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					dstack_clear()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dstack_len = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static KF_ADDR	rstack[RSTACK_SIZE] = {0};
 | 
				
			||||||
 | 
					static size_t	rstack_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool
 | 
				
			||||||
 | 
					rstack_pop(KF_ADDR *a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (rstack_len == 0) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*a = rstack[--rstack_len];
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool
 | 
				
			||||||
 | 
					rstack_push(KF_ADDR a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (rstack_len == DSTACK_SIZE) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rstack[rstack_len++] = a;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool
 | 
				
			||||||
 | 
					rstack_get(size_t i, KF_ADDR *a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (i >= rstack_len) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*a = rstack[rstack_len - i - 1];
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					rstack_size()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return rstack_len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					rstack_clear()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						rstack_len = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								stack.h
								
								
								
								
							
							
						
						
									
										17
									
								
								stack.h
								
								
								
								
							| 
						 | 
					@ -1,9 +1,18 @@
 | 
				
			||||||
#ifndef __KF_STACK_H__
 | 
					#ifndef __KF_STACK_H__
 | 
				
			||||||
#define __KF_STACK_H__
 | 
					#define __KF_STACK_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* data stack interaction */
 | 
				
			||||||
 | 
					bool	dstack_pop(KF_INT *);
 | 
				
			||||||
 | 
					bool	dstack_push(KF_INT);
 | 
				
			||||||
 | 
					bool	dstack_get(size_t, KF_INT *);
 | 
				
			||||||
 | 
					size_t	dstack_size(void);
 | 
				
			||||||
 | 
					void	dstack_clear(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return stack interaction */
 | 
				
			||||||
 | 
					bool	rstack_pop(KF_ADDR *);
 | 
				
			||||||
 | 
					bool	rstack_push(KF_ADDR);
 | 
				
			||||||
 | 
					bool	rstack_get(size_t, KF_ADDR *);
 | 
				
			||||||
 | 
					size_t	rstack_size(void);
 | 
				
			||||||
 | 
					void	rstack_clear(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static
 | 
					#endif /* __KF_STACK_H__ */
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // __KF_STACK_H__
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,82 @@
 | 
				
			||||||
 | 
					#include "defs.h"
 | 
				
			||||||
 | 
					#include "eval.h"
 | 
				
			||||||
 | 
					#include "word.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t	dict[DICT_SIZE] = {0};
 | 
				
			||||||
 | 
					static size_t	last = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					append_word(const char *name, const uint8_t len, void(*target)(void))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						store_native(dict+last, name, len, target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool
 | 
				
			||||||
 | 
					execute(const char *name, const uint8_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						size_t	offset = 0;
 | 
				
			||||||
 | 
						size_t	body = 0;
 | 
				
			||||||
 | 
						while (true) {
 | 
				
			||||||
 | 
							if (!match_word(dict+offset, name, len)) {
 | 
				
			||||||
 | 
								if ((offset = word_link(dict+offset)) == 0) {
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							body = word_body(dict+offset);
 | 
				
			||||||
 | 
							cwexec(dict + body + offset);
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					store_native(uint8_t *entry, const char *name, const uint8_t len, void(*target)(void))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uintptr_t	target_p = (uintptr_t)target;
 | 
				
			||||||
 | 
						size_t		link = 2 + len + (2 * sizeof(uintptr_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* write the header */
 | 
				
			||||||
 | 
						entry[0] = len;
 | 
				
			||||||
 | 
						entry[1] = 0; // flags aren't used yet
 | 
				
			||||||
 | 
						memcpy(entry+2, name, len);
 | 
				
			||||||
 | 
						memcpy(entry+2+len, &link, sizeof(link));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* write the native executor codeword and the function pointer */
 | 
				
			||||||
 | 
						memcpy(entry, (uint8_t *)(&nexec_p), sizeof(uintptr_t));
 | 
				
			||||||
 | 
						memcpy(entry + sizeof(uintptr_t), (uint8_t *)(&target_p), sizeof(uintptr_t));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool
 | 
				
			||||||
 | 
					match_word(uint8_t *entry, const char *name, const uint8_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (entry[0] != len) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (memcmp(entry+2, name, len) != 0) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					word_link(uint8_t *entry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						size_t	link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (entry[0] == 0) {
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						memcpy(&link, entry+2+entry[0], sizeof(link));
 | 
				
			||||||
 | 
						return link;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					word_body(uint8_t *entry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return 2 + entry[0] + sizeof(size_t);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					#ifndef __KF_WORD_H__
 | 
				
			||||||
 | 
					#define __KF_WORD_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Every word in the dictionary starts with a header:
 | 
				
			||||||
 | 
					 * uint8_t	 length;
 | 
				
			||||||
 | 
					 * uint8_t	 flags;
 | 
				
			||||||
 | 
					 * char		*name;
 | 
				
			||||||
 | 
					 * uintptr_t	 next;
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The body looks like the following:
 | 
				
			||||||
 | 
					 * uintptr_t	 codeword;
 | 
				
			||||||
 | 
					 * uintptr_t	 body[];
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The codeword is the interpreter for the body. This is defined in
 | 
				
			||||||
 | 
					 * eval.c. Note that a native (or builtin function) has only a single
 | 
				
			||||||
 | 
					 * body element.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The body of a native word points to a function that's compiled in already.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * store_native writes a new dictionary entry for a native-compiled
 | 
				
			||||||
 | 
					 * function.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void	store_native(uint8_t *, const char *, const uint8_t, void(*)(void));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * match_word returns true if the current dictionary entry matches the
 | 
				
			||||||
 | 
					 * token being searched for.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool	match_word(uint8_t *, const char *, const uint8_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * word_link returns the offset to the next word.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					size_t	word_link(uint8_t *);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					size_t	word_body(uint8_t *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __KF_WORD_H__ */
 | 
				
			||||||
		Loading…
	
		Reference in New Issue