]> git.mdlowis.com Git - projs/awiki.git/commitdiff
nightly commit
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 17 Jun 2020 02:28:04 +0000 (22:28 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 17 Jun 2020 02:28:04 +0000 (22:28 -0400)
pages/20200616201537.md [new file with mode: 0644]
pages/20200616202142.md [new file with mode: 0644]
pages/20200616222406.md [new file with mode: 0644]
pages/notes/proglangs.md

diff --git a/pages/20200616201537.md b/pages/20200616201537.md
new file mode 100644 (file)
index 0000000..9f6bc7b
--- /dev/null
@@ -0,0 +1,142 @@
+@tags build-system
+# Build.ini
+## Sample Input File
+````
+[tool/CC]
+desc = CC $target
+cmd = $CC -c -o $target -MMD -MF $depfile $CPPPATH $CPPFLAGS $CFLAGS $CCFLAGS $sources
+takes = .c
+makes = .o
+CC = cc
+
+[tool/CXX]
+desc = CXX $target
+cmd = $CXX -c -o $target -MMD -MF $depfile $CPPPATH $CPPFLAGS $CXXFLAGS $CCFLAGS $sources
+takes = .cc .cpp .cxx .C
+makes = .o
+CXX = cxx
+
+[tool/Lib]
+desc = AR $target
+cmd = $AR $ARFLAGS $target $sources
+takes = .o
+makes = .a
+AR = ar
+ARFLAGS = rcs
+
+[tool/CApp]
+desc = LD $target
+cmd = $LD -o $target $LDFLAGS $sources $LIBPATH $LIBS
+takes = .o .a
+LD = cc
+
+[tool/CppApp]
+desc = LD $target
+cmd = $LD -o $target $LDFLAGS $sources $LIBPATH $LIBS
+takes = .o .a
+LD = c++
+
+[Targets]
+Lib libedit.a : src/lib/*.c
+CApp foo : foo.c libedit.a
+````
+
+## Ruby script to parse the file
+````
+#!/usr/bin/env ruby
+
+Cfg = {}
+
+obj = nil
+File.read(ARGV[0]).each_line do |ln|
+  if ln =~ /\[(.*)\]/ then
+    cfg = $1.split("/")
+    if cfg[0] == "tool" then
+      Cfg["tool"] ||= {}
+      Cfg["tool"][cfg[1]] ||= {  }
+      obj = Cfg["tool"][cfg[1]]
+    end
+  elsif ln =~ /([a-zA-Z0-9_]+)[ \t]*=[ \t]*(.*)$/
+    puts "'#{$1}' '#{$2}'"
+  end
+end
+
+Cfg = {
+  env: {
+    CC: ["cc"],
+    CXX: ["cxx"],
+  },
+  tools: {
+    CC: {
+      desc: ["CC", "$target"],
+      cmd: ["$CC", "-c", "-o$target", "-MMD", "-MF", "$depfile", "$CPPPATH", "$CPPFLAGS", "$CFLAGS", "$CCFLAGS", "$sources"],
+      takes: [".o", ".a"],
+      CC: ["cc"]
+    }
+    CXX: {
+      desc: ["CXX", "$target"],
+      cmd: ["$CXX", "-c", "-o$target", "-MMD", "-MF", "$depfile", "$CPPPATH", "$CPPFLAGS", "$CXXFLAGS", "$CCFLAGS", "$sources"],
+      takes: [".o", ".a"],
+      CC: ["cxx"]
+    }
+  },
+  recipes: {
+    ".o" => {
+      ".c" => :CC,
+      ".cc" => :CXX,
+      ".cpp" => :CXX,
+      ".cxx" => :CXX,
+      ".C" => :CXX,
+    }
+  },
+  targets: {
+
+  }
+}
+````
+
+## Alternative Syntax
+````
+tool CC:
+  desc = CC $target
+  cmd = $CC -c -o $target -MMD -MF $depfile $CPPPATH $CPPFLAGS $CFLAGS $CCFLAGS $sources
+  takes = .c
+  makes = .o
+  CC = cc
+
+tool CXX:
+  desc = CXX $target
+  cmd = $CXX -c -o $target -MMD -MF $depfile $CPPPATH $CPPFLAGS $CXXFLAGS $CCFLAGS $sources
+  takes = .cc .cpp .cxx .C
+  makes = .o
+  CXX = cxx
+
+tool Lib:
+  desc = AR $target
+  cmd = $AR $ARFLAGS $target $sources
+  takes = .o
+  makes = .a
+  AR = ar
+  ARFLAGS = rcs
+
+tool CApp:
+  desc = LD $target
+  cmd = $LD -o $target $LDFLAGS $sources $LIBPATH $LIBS
+  takes = .o .a
+  LD = cc
+
+tool CppApp:
+  desc = LD $target
+  cmd = $LD -o $target $LDFLAGS $sources $LIBPATH $LIBS
+  takes = .o .a
+  LD = c++
+
+build:
+  Lib libedit.a : src/lib/*.c
+  CApp foo : foo.c libedit.a
+
+install:
+  $PREFIX/bin/foo : foo
+````
+
+
diff --git a/pages/20200616202142.md b/pages/20200616202142.md
new file mode 100644 (file)
index 0000000..afc33e5
--- /dev/null
@@ -0,0 +1,700 @@
+@tags onward forth programming-language language language-design
+# Onward Redesign
+````
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+
+/* TODO
+
+    * Find should ignore hidden words
+
+*/
+
+typedef intptr_t value_t;
+
+typedef struct {
+    value_t memb;
+    value_t meme;
+    value_t asb;
+    value_t asp;
+    value_t rsb;
+    value_t rsp;
+    value_t pc;
+    value_t state;
+    value_t dict;
+    value_t here;
+    char name[64];
+    value_t mem[];
+} state_t;
+
+typedef struct {
+    char* name;
+    void (*func)(state_t*);
+} builtin_t;
+
+typedef struct dict_t {
+    value_t prevd;
+    value_t name;
+    value_t firstw;
+} dict_t;
+
+typedef struct word_t {
+    value_t prevw;
+    value_t flags;
+    value_t name;
+    value_t code[];
+} word_t;
+
+enum {
+    F_BUILTIN   = (1 << 0),
+    F_IMMEDIATE = (1 << 1),
+    F_HIDDEN    = (1 << 2),
+};
+
+static void onward_error(state_t* os, bool cond, char* msg)
+{
+    (void)os;
+    if (cond)
+    {
+        fprintf(stderr, "error: %s\n", msg);
+        exit(1);
+    }
+}
+
+static void onward_aspush(state_t* os, value_t val) {
+    onward_error(os, (os->asp >= os->rsb), "argument stack overflow");
+    *((value_t*)((char*)os + os->asp)) = val;
+    os->asp += sizeof(value_t);
+}
+
+static value_t onward_aspop(state_t* os) {
+    onward_error(os, (os->asp <= os->asb), "argument stack underflow");
+    os->asp -= sizeof(value_t);
+    value_t val = *((value_t*)((char*)os + os->asp));
+    return val;
+}
+
+static value_t onward_aspeek(state_t* os) {
+    onward_error(os, (os->asp <= os->asb), "argument stack underflow");
+    value_t asp = (os->asp - sizeof(value_t));
+    return *((value_t*)((char*)os + asp));
+}
+
+static void onward_rspush(state_t* os, value_t val) {
+    onward_error(os, (os->rsp >= os->memb), "return stack overflow");
+    *((value_t*)((char*)os + os->rsp)) = val;
+    os->rsp += sizeof(value_t);
+}
+
+static value_t onward_rspop(state_t* os) {
+    onward_error(os, (os->rsp <= os->rsb), "return stack underflow");
+    os->rsp -= sizeof(value_t);
+    value_t val = *((value_t*)((char*)os + os->rsp));
+    return val;
+}
+
+static void* onward_reserve(state_t* os, size_t nbytes) {
+    value_t aligned = (nbytes / sizeof(value_t));
+    if (nbytes % sizeof(value_t))
+    {
+        aligned += 1;
+    }
+    void* ptr = ((char*)os + os->here);
+    os->here += (aligned * sizeof(value_t));
+    onward_error(os, (os->here >= os->meme), "memory region exhausted");
+    return ptr;
+}
+
+static void* onward_getptr(state_t* os, value_t off)
+{
+    void* ptr = NULL;
+    if (off > 0)
+    {
+        onward_error(os, (off >= os->meme), "bad memory address");
+        ptr = (char*)os + off;
+    }
+    return ptr;
+}
+
+static value_t onward_getoff(state_t* os, void* ptr)
+{
+    value_t off = (char*)ptr - (char*)os;
+    onward_error(os, (off >= os->meme), "bad memory address");
+    return off;
+}
+
+static value_t onward_memcpy(state_t* os, void* data, size_t ndata)
+{
+    void* mem = onward_reserve(os, ndata);
+    memcpy(mem, data, ndata);
+    return onward_getoff(os, mem);
+}
+
+/****************************************/
+
+value_t system_key(state_t* os);
+void system_emit(state_t* os, value_t key);
+
+static void onward_key(state_t* os) {
+    onward_aspush(os, system_key(os));
+}
+
+static void onward_emit(state_t* os) {
+    system_emit(os, onward_aspop(os));
+}
+
+static void onward_dropline(state_t* os) { // remove?
+    value_t curr;
+    do {
+        curr = system_key(os);
+    } while(((char)curr != '\n') &amp;&amp; (curr != EOF));
+}
+
+static void onward_word(state_t* os) {
+    char* str = os->name;
+    char* end = os->name + sizeof(os->name) - 1;
+    value_t curr;
+    /* Skip any whitespace */
+    do
+    {
+        curr = system_key(os);
+    }
+    while (isspace(curr));
+    /* Copy characters into the buffer */
+    while(str < end &amp;&amp; ((int)curr != EOF) &amp;&amp; !isspace(curr))
+    {
+        *str++ = curr;
+        curr = system_key(os);
+    }
+    /* Terminate the string */
+    *str = '\0';
+    /* Return the internal buffer */
+    onward_aspush(os, (value_t)(os->name - (char*)os));
+}
+
+static void onward_num(state_t* os) {
+    value_t word_addr = onward_aspop(os);
+    char* word = ((char*)os + word_addr);
+    char* start = word;
+
+    /* TODO: Range check the word pointer here */
+
+    value_t success = 0;
+    value_t value = 0;
+    int sign = 1;
+    int base = 10;
+    char c;
+
+    /* Detect the sign of the number */
+    if (*start == '-') {
+        sign = -1;
+        start++;
+    }
+
+    /* Detect the base of the number to parse */
+    if (*start == '0') {
+        start++;
+        switch (*(start++)) {
+            case 'b': base = 2;     break;
+            case 'o': base = 8;     break;
+            case 'd': base = 10;    break;
+            case 'x': base = 16;    break;
+            case '\0':
+                success = 1;
+                base = -1;
+                break;
+            default:  base = -1;    break;
+        }
+    }
+
+    /* Parse the number */
+    if (base > 1) {
+        for (c = *start++; c != '\0'; c= *start++) {
+            /* Get the digit value */
+            if ((c >= '0') &amp;&amp; (c <= '9'))
+                c -= '0';
+            else if (((c >= 'a') &amp;&amp; (c <= 'f')) || ((c >= 'A') &amp;&amp; (c <= 'F')))
+                c -= (c >= 'A' &amp;&amp; c <= 'Z') ? 'A' - 10 : 'a' - 10;
+            else
+                break;
+            /* Bail if the digit value is too high */
+            if (c >= base) break;
+            /* Update the accumulated value */
+            value = (value * base) + c;
+            success = 1;
+        }
+
+        /* Convert to the required sign */
+        value *= sign;
+    }
+
+    /* Push the results back on the stack */
+    success = (success &amp;&amp; (*(start-1) == '\0'));
+    if (success)
+        onward_aspush(os, value);
+    else
+        onward_aspush(os, (value_t)word_addr);
+    onward_aspush(os, success);
+}
+
+static void onward_find(state_t* os) {
+    char* sname = onward_getptr(os, onward_aspop(os));
+    dict_t* dict = onward_getptr(os, os->dict);
+    while (dict)
+    {
+        word_t* word = onward_getptr(os, dict->firstw);
+        while (word)
+        {
+            char* name = onward_getptr(os, word->name);
+            if (!strcmp(sname, name))
+            {
+                onward_aspush(os, onward_getoff(os, word));
+                onward_aspush(os, 1);
+                return;
+            }
+            word = onward_getptr(os, word->prevw);
+        }
+        dict = onward_getptr(os, dict->prevd);
+    }
+    onward_aspush(os, 0);
+}
+
+static void onward_exec(state_t* os) {
+    word_t* word = onward_getptr(os, onward_aspop(os));
+//    onward_rspush(os->pc);
+    if (word->flags &amp; F_BUILTIN)
+    {
+        ((void (*)(state_t*))word->code[0])(os);
+    }
+//    onward_rspush(os->pc);
+}
+
+static void onward_lit(state_t* os) {
+    (void)os;
+}
+
+static void onward_create(state_t* os) {
+    char* wname = onward_getptr(os, onward_aspop(os));
+    value_t name = onward_memcpy(os, wname, strlen(wname)+1);
+    word_t* word = onward_reserve(os, sizeof(word_t));
+    (void)onward_reserve(os, sizeof(value_t));
+    dict_t* dict = onward_getptr(os, os->dict);
+    word->prevw = dict->firstw;
+    word->flags = F_HIDDEN;
+    word->name = name;
+    word->code[0] = 0;
+    dict->firstw = onward_getoff(os, word);
+}
+
+static void onward_comma(state_t* os) {
+    onward_aspush(os, *((value_t*)onward_getptr(os, os->pc)));
+}
+
+static void onward_lbrack(state_t* os) {
+    os->state = 1;
+}
+
+static void onward_rbrack(state_t* os) {
+    os->state = 0;
+}
+
+static void onward_colon(state_t* os) {
+    onward_word(os);
+    onward_create(os);
+    onward_lbrack(os);
+}
+
+static void onward_semicolon(state_t* os) {
+    dict_t* dict = onward_getptr(os, os->dict);
+    word_t* word = onward_getptr(os, dict->firstw);
+    word->flags &amp;= ~F_HIDDEN;
+}
+
+static void onward_tick(state_t* os) {
+    onward_aspush(os, *((value_t*)onward_getptr(os, os->pc)));
+}
+
+static void onward_branch(state_t* os) {
+    os->pc += *((value_t*)onward_getptr(os, os->pc));
+}
+
+static void onward_0branch(state_t* os) {
+    if (!onward_aspop(os))
+    {
+        onward_branch(os);
+    }
+    else
+    {
+        os->pc += sizeof(value_t);
+    }
+}
+
+static void onward_interp(state_t* os) {
+    onward_word(os);
+    char* word = onward_getptr(os, onward_aspeek(os));
+    if (*word)
+    {
+        onward_find(os);
+        word_t* word = NULL;
+        if (onward_aspop(os))
+        {
+            word = onward_getptr(os, onward_aspop(os));
+        }
+        else
+        {
+            onward_num(os);
+        }
+
+        /* if compilation mode active*/
+        if ((os->state == 1) &amp;&amp; (!word || ((word->flags &amp; F_IMMEDIATE) == 0)) )
+        {
+            if (!word)
+            {
+                /* compile lit */
+            }
+            /* compile it */
+            onward_comma(os);
+        }
+        /* else execute it */
+        else if (word)
+        {
+            onward_exec(os);
+        }
+    }
+}
+
+static builtin_t Core_Dict[] = {
+    { "key",    onward_key },
+    { "emit",   onward_emit },
+    { "\\",     onward_dropline },
+    { "word",   onward_word },
+    { "num",    onward_num },
+    { "find",   onward_find },
+    { "exec",   onward_exec },
+    { "lit",    onward_lit },
+    { "create", onward_create },
+    { ",",      onward_comma },
+    { "[",      onward_lbrack },
+    { "]",      onward_rbrack },
+    { ":",      onward_colon },
+    { ";",      onward_semicolon },
+    { "'",      onward_tick },
+    { "br",     onward_branch },
+    { "0br",    onward_0branch },
+    { "interp", onward_interp },
+    {0,0}
+};
+
+/****************************************/
+
+static void onward_adddict(state_t* os, char* name, builtin_t* p_builtins)
+{
+    value_t dictname = onward_memcpy(os, name, strlen(name)+1);
+    dict_t* dict = onward_reserve(os, sizeof(dict_t));
+    dict->prevd = 0;
+    dict->name = dictname;
+    dict->firstw = 0;
+    for (; p_builtins->name; p_builtins++)
+    {
+        value_t name = onward_memcpy(os, p_builtins->name, strlen(p_builtins->name)+1);
+        word_t* word = onward_reserve(os, sizeof(word_t));
+        (void)onward_reserve(os, sizeof(value_t));
+        word->prevw = dict->firstw;
+        word->flags = F_BUILTIN;
+        word->name = name;
+        word->code[0] = (value_t)p_builtins->func;
+        dict->firstw = onward_getoff(os, word);
+    }
+    os->dict = onward_getoff(os, dict);
+}
+
+static state_t* onward_init(void* mem, size_t nmem, size_t nstack)
+{
+    assert((sizeof(state_t) + nstack * 2) < nmem);
+    state_t* os = mem;
+    os->meme = nmem;
+    os->memb = (sizeof(state_t) + nstack * 2);
+    os->asb = sizeof(state_t);
+    os->asp = os->asb;
+    os->rsb = os->asb + nstack;
+    os->rsp = os->rsb;
+    os->pc = 0;
+    os->state = 0;
+    os->dict = 0;
+    os->here = os->memb;
+
+    /* key emit dropline word num find exec create */
+    onward_adddict(os, "core", Core_Dict);
+    return os;
+}
+
+/****************************************/
+
+#define INCLUDE_DEFS
+#include <atf.h>
+
+static char Memory[1024*1024];
+static char* Input = "";
+static value_t Output = 0;
+
+value_t system_key(state_t* os)
+{
+    (void)os;
+    return ((Input &amp;&amp; *Input) ? *(Input++) : EOF);
+}
+
+void system_emit(state_t* os, value_t key)
+{
+    (void)os;
+    Output = key;
+}
+
+TEST_SUITE(MachineOperations)
+{
+    TEST(onward_init should initialize block of memory for VM usage)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        CHECK(os->memb == (sizeof(state_t) + 4096));
+        CHECK(os->meme == sizeof(Memory));
+        CHECK(os->asb == sizeof(state_t));
+        CHECK(os->asp == os->asb);
+        CHECK(os->rsb == (os->asb + 2048));
+        CHECK(os->rsp == os->rsb);
+        CHECK(os->here >= os->memb);
+        CHECK(os->state == 0);
+        CHECK(os->pc == 0);
+    }
+
+    TEST(pushing and popping the argument stack)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        onward_aspush(os, 42);
+        CHECK(os->asp == (os->asb + (value_t)sizeof(value_t)));
+        value_t val1 = onward_aspeek(os);
+        CHECK(os->asp == (os->asb + (value_t)sizeof(value_t)));
+        CHECK(val1 == 42);
+        value_t val2 = onward_aspop(os);
+        CHECK(os->asp == os->asb);
+        CHECK(val2 == 42);
+    }
+
+    TEST(pushing and popping the return stack)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        onward_rspush(os, 42);
+        CHECK(os->rsp == (os->rsb + (value_t)sizeof(value_t)));
+        value_t val2 = onward_rspop(os);
+        CHECK(os->rsp == os->rsb);
+        CHECK(val2 == 42);
+    }
+
+    TEST(getting input from system)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        Input = "ABC";
+        onward_key(os);
+        CHECK('A' == onward_aspop(os));
+        onward_key(os);
+        CHECK('B' == onward_aspop(os));
+        onward_key(os);
+        CHECK('C' == onward_aspop(os));
+        onward_key(os);
+        CHECK(EOF == onward_aspop(os));
+    }
+
+    TEST(getting output to system)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        onward_aspush(os, 'A');
+        onward_emit(os);
+        CHECK(Output == 'A');
+        CHECK(os->asp == os->asb);
+    }
+
+    TEST(dropping lines from input)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        Input = "\\ this is a line that will be dropped\nA";
+        onward_dropline(os);
+        CHECK('A' == *Input);
+        CHECK(os->asp == os->asb);
+        Input = "\\ this is a line that will be dropped";
+        onward_dropline(os);
+        CHECK(os->asp == os->asb);
+    }
+
+    TEST(reading a word from input)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        Input = "abcdef";
+        onward_word(os);
+        value_t off = onward_aspop(os);
+        CHECK(off == (10 * sizeof(value_t)));
+        CHECK(!strcmp("abcdef", ((char*)os + off)));
+
+        Input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
+        onward_word(os);
+        off = onward_aspop(os);
+        CHECK(off == (10 * sizeof(value_t)));
+        CHECK(!strcmp(
+            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ((char*)os + off)));
+    }
+
+    TEST(reading a number from input)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        Input = "0";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(0 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "123";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(123 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "-123";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(-123 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "-0x2a";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(-42 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "-0x2a";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(-42 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "0x2a";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(42 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "-0d42";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(-42 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "0d42";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(42 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "-0o52";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(-42 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "0o52";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(42 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "-0b101010";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(-42 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+
+        Input = "0b101010";
+        onward_word(os);
+        onward_num(os);
+        CHECK(1 == onward_aspop(os));
+        CHECK(42 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+    }
+
+    TEST(finding a word in the dictionary)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        Input = "emit";
+        onward_word(os);
+        onward_find(os);
+        CHECK(1 == onward_aspop(os));
+        word_t* word = onward_getptr(os, onward_aspop(os));
+        CHECK(!strcmp(onward_getptr(os, word->name), "emit"));
+        CHECK(os->asb == os->asp);
+
+        Input = "foo";
+        onward_word(os);
+        onward_find(os);
+        CHECK(0 == onward_aspop(os));
+        CHECK(os->asb == os->asp);
+    }
+
+    TEST(executing word definitions)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        onward_aspush(os, 'A');
+        Input = "emit";
+        onward_word(os);
+        onward_find(os);
+        onward_exec(os);
+        CHECK(Output == 'A');
+    }
+
+    TEST(creating word definitions)
+    {
+        state_t* os = onward_init(Memory, sizeof(Memory), 2048);
+        dict_t* dict = onward_getptr(os, os->dict);
+        value_t prevw = dict->firstw;
+        Input = "foo";
+        onward_word(os);
+        onward_create(os);
+        CHECK(prevw != dict->firstw);
+        word_t* word = onward_getptr(os, dict->firstw);
+        CHECK(word->prevw == prevw);
+        CHECK(word->flags == F_HIDDEN);
+        CHECK(word->code[0] == 0);
+        CHECK(!strcmp(onward_getptr(os, word->name), "foo"));
+    }
+}
+
+//    { "lit",    onward_lit },
+//    { ",",      onward_comma },
+//    { "[",      onward_lbrack },
+//    { "]",      onward_rbrack },
+//    { ":",      onward_colon },
+//    { ";",      onward_semicolon },
+//    { "'",      onward_tick },
+//    { "br",     onward_branch },
+//    { "0br",    onward_0branch },
+//    { "interp", onward_interp },
+
+
+int main(int argc, char** argv)
+{
+    atf_init(argc, argv);
+    RUN_EXTERN_TEST_SUITE(MachineOperations);
+    return atf_print_results();
+}
+````
diff --git a/pages/20200616222406.md b/pages/20200616222406.md
new file mode 100644 (file)
index 0000000..515a57c
--- /dev/null
@@ -0,0 +1,13 @@
+@tags blog
+# Josh On Design
+* https://joshondesign.com/2018/07/10/independent-researcher
+* https://joshondesign.com/2019/07/21/thoughts_build_systems
+* https://joshondesign.com/2015/01/08/idealos
+* https://joshondesign.com/2015/01/10/idealos2
+* https://joshondesign.com/2015/01/14/idealos3
+* https://joshondesign.com/2014/09/10/cyberprog
+* https://joshondesign.com/2013/08/24/newblogagain
+* https://joshondesign.com/2012/07/02/thefutureofdesktopcomputing
+* https://joshondesign.com/2012/04/09/open-letter-language-designers
+* https://joshondesign.com/2019/06/28/markdown_vs_html
+* https://joshondesign.com/2018/05/09/modern-computer-annoyance
index f07c8f5a9b01b8aadfff00357ff0ddd33ba43e93..7d64652ba3f07666aac59f6162447090695bf0a0 100644 (file)
@@ -5,7 +5,7 @@
 ## Designs I'm Working On
 * [SCLPL Design Notes](sclpl.html)
 
-## Language For Inspiration
+## Languages For Inspiration
 * [Erlang](erlang.html)
 * [Scheme](scheme.html)
 * [OCaml](ocaml.html)
 * [Forth](forth.html)
 * [Lua](lua.html)
 * [Postfix](https://cs.wellesley.edu/~cs251/s05/postfix.pdf)
+* Delphi
+* Eiffel
+* Ada
+* Factor
+* Joy
+* Swift
+* Icon
 
 ## Compiler Design
 * https://inf.ethz.ch/personal/wirth/CompilerConstruction/index.html