From: Michael D. Lowis Date: Wed, 17 Jun 2020 02:28:04 +0000 (-0400) Subject: nightly commit X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=d10589d99e4378cbb3cacd6b79549ffbada41a95;p=projs%2Fawiki.git nightly commit --- diff --git a/pages/20200616201537.md b/pages/20200616201537.md new file mode 100644 index 0000000..9f6bc7b --- /dev/null +++ b/pages/20200616201537.md @@ -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 index 0000000..afc33e5 --- /dev/null +++ b/pages/20200616202142.md @@ -0,0 +1,700 @@ +@tags onward forth programming-language language language-design +# Onward Redesign +```` +#include +#include +#include +#include +#include +#include +#include + +/* 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') && (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 && ((int)curr != EOF) && !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') && (c <= '9')) + c -= '0'; + else if (((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F'))) + c -= (c >= 'A' && 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 && (*(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 & 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 &= ~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) && (!word || ((word->flags & 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 + +static char Memory[1024*1024]; +static char* Input = ""; +static value_t Output = 0; + +value_t system_key(state_t* os) +{ + (void)os; + return ((Input && *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 index 0000000..515a57c --- /dev/null +++ b/pages/20200616222406.md @@ -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 diff --git a/pages/notes/proglangs.md b/pages/notes/proglangs.md index f07c8f5..7d64652 100644 --- a/pages/notes/proglangs.md +++ b/pages/notes/proglangs.md @@ -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) @@ -13,6 +13,13 @@ * [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