misc/kforth: Starting work on writeup.
This commit is contained in:
		
							parent
							
								
									342bacdf01
								
							
						
					
					
						commit
						3991bb353b
					
				
							
								
								
									
										13
									
								
								defs.h
								
								
								
								
							
							
						
						
									
										13
									
								
								defs.h
								
								
								
								
							| 
						 | 
					@ -10,5 +10,18 @@ constexpr uint8_t STACK_SIZE = 16;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr size_t	MAX_TOKEN_LENGTH = 16;
 | 
					constexpr size_t	MAX_TOKEN_LENGTH = 16;
 | 
				
			||||||
 | 
					constexpr size_t dshift = (sizeof(KF_INT) * 8) - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline KF_INT
 | 
				
			||||||
 | 
					mask(size_t bits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						KF_INT m = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < bits; i++) {
 | 
				
			||||||
 | 
							m += 1 << i;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return m;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // __KF_DEFS_H__
 | 
					#endif // __KF_DEFS_H__
 | 
				
			||||||
| 
						 | 
					@ -3,3 +3,124 @@ Write You a Forth, 0x07
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:date: 2018-03-01 19:31
 | 
					:date: 2018-03-01 19:31
 | 
				
			||||||
:tags: wyaf, forth
 | 
					:tags: wyaf, forth
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					At this point, I've finished most of the nucleus layer. All that's left to
 | 
				
			||||||
 | 
					implement are ``EXIT``, ``I``, and ``J`` --- the first requires better
 | 
				
			||||||
 | 
					execution support, which I'll talk about at the end. The other two, I'm not so
 | 
				
			||||||
 | 
					sure about yet.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					However, I made some large changes, so let's dive in. Here's the new Linux
 | 
				
			||||||
 | 
					definitions file::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #ifndef __KF_LINUX_DEFS_H__
 | 
				
			||||||
 | 
					        #define __KF_LINUX_DEFS_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #include <stddef.h>
 | 
				
			||||||
 | 
					        #include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        typedef int32_t KF_INT;
 | 
				
			||||||
 | 
					        typedef uint32_t KF_UINT;
 | 
				
			||||||
 | 
					        typedef int64_t	KF_LONG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        typedef uintptr_t KF_ADDR;
 | 
				
			||||||
 | 
					        constexpr uint8_t STACK_SIZE = 128;
 | 
				
			||||||
 | 
					        constexpr size_t ARENA_SIZE = 65535;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					I've also updated the main ``defs.h`` file to move some constants there::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #ifndef __KF_DEFS_H__
 | 
				
			||||||
 | 
					        #define __KF_DEFS_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #ifdef __linux__
 | 
				
			||||||
 | 
					        #include "linux/defs.h"
 | 
				
			||||||
 | 
					        #else
 | 
				
			||||||
 | 
					        typedef int KF_INT;
 | 
				
			||||||
 | 
					        typedef long KF_LONG;
 | 
				
			||||||
 | 
					        constexpr uint8_t STACK_SIZE = 16;
 | 
				
			||||||
 | 
					        #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        constexpr size_t	MAX_TOKEN_LENGTH = 16;
 | 
				
			||||||
 | 
					        constexpr size_t dshift = (sizeof(KF_INT) * 8) - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static inline KF_INT
 | 
				
			||||||
 | 
					        mask(size_t bits)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					                KF_INT m = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for (size_t i = 0; i < bits; i++) {
 | 
				
			||||||
 | 
					                        m += 1 << i;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                return m;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endif // __KF_DEFS_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Addresses
 | 
				
			||||||
 | 
					^^^^^^^^^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The first major change is the addition of the ``KF_ADDR`` type. This is needed
 | 
				
			||||||
 | 
					to implement the memory manipulation words. I've added some additional utility
 | 
				
			||||||
 | 
					functions for pushing and popping addresses from the data stack; they're stored
 | 
				
			||||||
 | 
					as double numbers::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static bool
 | 
				
			||||||
 | 
					    pop_addr(System *sys, KF_ADDR *a)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					            KF_LONG	b;
 | 
				
			||||||
 | 
					            if (!pop_long(sys, &b)) {
 | 
				
			||||||
 | 
					                    // Status is already set.
 | 
				
			||||||
 | 
					                    return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            *a = static_cast<KF_ADDR>(b);
 | 
				
			||||||
 | 
					            sys->status = STATUS_OK;
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static bool
 | 
				
			||||||
 | 
					    push_addr(System *sys, KF_ADDR a)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					            KF_LONG	b = static_cast<KF_LONG>(a);
 | 
				
			||||||
 | 
					            if (!push_long(sys, b)) {
 | 
				
			||||||
 | 
					                    // Status is already set.
 | 
				
			||||||
 | 
					                    return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            sys->status = STATUS_OK;
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now I can actually implement ``!`` and so forth::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static bool
 | 
				
			||||||
 | 
					        store(System *sys)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					                KF_ADDR	a = 0; // address
 | 
				
			||||||
 | 
					                KF_INT	b = 0; // value
 | 
				
			||||||
 | 
					                KF_LONG	c = 0; // temporary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!pop_long(sys, &c)) {
 | 
				
			||||||
 | 
					                        sys->status = STATUS_STACK_UNDERFLOW;
 | 
				
			||||||
 | 
					                        return false;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                a = static_cast<KF_ADDR>(c);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (!sys->dstack.pop(&b)) {
 | 
				
			||||||
 | 
					                        sys->status = STATUS_STACK_UNDERFLOW;
 | 
				
			||||||
 | 
					                        return false;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                *((KF_INT *)a) = b;
 | 
				
			||||||
 | 
					                sys->status = STATUS_OK;
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There's definitely a sense of finangling here.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The return stack
 | 
				
			||||||
 | 
					^^^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The ``>R`` series of words requires a 
 | 
				
			||||||
							
								
								
									
										13
									
								
								linux/defs.h
								
								
								
								
							
							
						
						
									
										13
									
								
								linux/defs.h
								
								
								
								
							| 
						 | 
					@ -7,22 +7,9 @@
 | 
				
			||||||
typedef int32_t KF_INT;
 | 
					typedef int32_t KF_INT;
 | 
				
			||||||
typedef uint32_t KF_UINT;
 | 
					typedef uint32_t KF_UINT;
 | 
				
			||||||
typedef int64_t	KF_LONG;
 | 
					typedef int64_t	KF_LONG;
 | 
				
			||||||
constexpr size_t dshift = (sizeof(KF_INT) * 8) - 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef uintptr_t KF_ADDR;
 | 
					typedef uintptr_t KF_ADDR;
 | 
				
			||||||
constexpr uint8_t STACK_SIZE = 128;
 | 
					constexpr uint8_t STACK_SIZE = 128;
 | 
				
			||||||
constexpr size_t ARENA_SIZE = 65535;
 | 
					constexpr size_t ARENA_SIZE = 65535;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline KF_INT
 | 
					 | 
				
			||||||
mask(size_t bits)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	KF_INT m = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (size_t i = 0; i < bits; i++) {
 | 
					 | 
				
			||||||
		m += 1 << i;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return m;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		Loading…
	
		Reference in New Issue