diff --git a/doc/index.rst b/doc/index.rst index 07991af..5d45de7 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -14,6 +14,7 @@ Contents: part-0x06 part-0x07 part-0x08 + part-0x09 Indices and tables ================== diff --git a/doc/part-0x09.rst b/doc/part-0x09.rst new file mode 100644 index 0000000..6ce1f4b --- /dev/null +++ b/doc/part-0x09.rst @@ -0,0 +1,79 @@ +Write You a Forth, 0x03 +----------------------- + +:date: 2018-03-09 13:10 +:tags: wyaf, forth + +So the last post had some issues and I hadn't updated the front end to use the +new tooling. I removed the arena and switched to the internal dictionary:: + + #include "defs.h" + #include "eval.h" + #include "stack.h" + #include "word.h" + + #include + #include + #include + + void + hello(void) + { + printf("hello, world\n"); + } + + int + main(void) + { + dstack_push(2); + dstack_push(3); + + append_native_word("hello", 5, hello); + uintptr_t hwb = 0; + + if (!lookup("hello", 5, &hwb)) { + fprintf(stderr, "failed to lookup 'hello'\n"); + exit(1); + } + printf("hello: 0x%lx\n", (unsigned long)hwb); + if (!execute("hello", 5)) { + fprintf(stderr, "failed to execute 'hello'\n"); + exit(1); + } + + printf("finished\n"); + } + +Also, there's a (not-so) subtle bug in ``word.c``: the header is overwritten by the function +body, which is the path to segfaulting. I've also added an offset variable to make tracking +the offset easier:: + + 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)); + + size_t offset = 2 + len + sizeof(size_t); + + size_t link = offset + (2 * sizeof(uintptr_t)); + + /* write the header */ + entry[0] = len; + @@ -45,8 +66,9 @@ store_native(uint8_t *entry, const char *name, const uint8_t len, void(*target)( + 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)); + + memcpy(entry+offset, (uint8_t *)(&nexec_p), sizeof(uintptr_t)); + + offset += sizeof(uintptr_t); + + memcpy(entry+offset, (uint8_t *)(&target_p), sizeof(uintptr_t)); + } + +The header file ``word.h`` didn't contain ``append_native_word``, ``lookup``, +or ``execute``, so that gets updated too. The end result is:: + + $ ./kf-default + hello: 0x6cbc6f + hello, world + finished +