From a587cb68e3ad937743eb47a1ef964c784c28c343 Mon Sep 17 00:00:00 2001 From: zongor Date: Sun, 21 Dec 2025 11:11:29 -0800 Subject: [PATCH] Add inital documentation, starter code. --- README.md | 3 -- README.org | 58 +++++++++++++++++++++++++++++++++++ ROADMAP.org | 2 ++ SPECIFICATION.org | 1 + arch/linux/gui/main.c | 0 arch/linux/tui/main.c | 0 arch/web/main.c | 0 build | 2 ++ imgs/convert.sh | 3 ++ imgs/favicon.ico | Bin 0 -> 305664 bytes imgs/undar.png | Bin 0 -> 7936 bytes imgs/undar.svg | 56 ++++++++++++++++++++++++++++++++++ libc.c | 68 ++++++++++++++++++++++++++++++++++++++++++ libc.h | 33 ++++++++++++++++++++ vm.c | 0 vm.h | 22 ++++++++++++++ 16 files changed, 245 insertions(+), 3 deletions(-) delete mode 100644 README.md create mode 100644 README.org create mode 100644 ROADMAP.org create mode 100644 SPECIFICATION.org create mode 100644 arch/linux/gui/main.c create mode 100644 arch/linux/tui/main.c create mode 100644 arch/web/main.c create mode 100644 build create mode 100755 imgs/convert.sh create mode 100644 imgs/favicon.ico create mode 100644 imgs/undar.png create mode 100644 imgs/undar.svg create mode 100644 libc.c create mode 100644 libc.h create mode 100644 vm.c create mode 100644 vm.h diff --git a/README.md b/README.md deleted file mode 100644 index 209e5f0..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# undar-lang - -A statically-typed permacomputing-oriented language for the purpose of creating 3D programs that work on constrained systems, retro consoles, and the web. \ No newline at end of file diff --git a/README.org b/README.org new file mode 100644 index 0000000..72ee99c --- /dev/null +++ b/README.org @@ -0,0 +1,58 @@ +#+TITLE: Undâr Programming Language + +#+BEGIN_SRC +[ᚢ ᛫ ᛫ ᛫ + ᛫ ᚾ ᛫ ᛫ + ᛫ ᛫ ᛞ ᛫ + ᛫ ᛫ ᛫ ᚱ] +#+END_SRC + +* Philosophy + +Undâr conforms to permacomputing principles. + +Permacomputing as defined by the [[https://wiki.xxiivv.com/site/permacomputing.html][xxiivv wiki]]: "permacomputing encourages the maximization of hardware lifespan, minimization of energy usage and focuses on the use of already available computational resources. +it values maintenance and refactoring of systems to keep them efficient, instead of planned obsolescence, permacomputing practices planned longevity. +it is about using computation only when it has a strengthening effect on ecosystems." + +Undâr is designed to ensure that programs will last indefinitly, but it is likely they will only last 'a very long time'. + +The VM specification is the core of the language. It should be able to fit on a napkin and be able to be implemented in a weekend. + +This implementation of the VM is written in freestanding C89 to maximize the chance that obscure C compilers will be able to compile it. + +Once the VM is implemented it can be integrated into a architecutre specific code. + +Undâr is intended to run on anything with a C compiler. From constrained systems like: retro consoles, microcontrollers to the web using emscripten. + +* Getting Started + +** + +** Build (linux version) + +#+BEGIN_SRC sh +git clone https://git.alfrescocavern.com/zongor/undar-lang.git +cd undar-lang && ./build +#+END_SRC + +* Roadmap + +[[./ROADMAP.org][Compiler, Plex, Immidate mode GUI, Constructive solid geometry, Tunnels, Actor model]] + +* License + +[[./LICENSE][GPLv3]] + +* Inspirations + +- [[https://plan9.io/][Plan 9]] : 9P, Unified I/O, Tunnels. +- [[https://en.wikipedia.org/wiki/Lisp_(programming_language)][Lisp]] : REPL, introspection. +- [[https://fortran-lang.org/][Fortran]] : Array semantics. +- [[https://en.wikipedia.org/wiki/C_(programming_language)][C]] / [[https://ziglang.org/][Zig]] : Efficentcy, simplicity. +- [[https://lua.org][Lua]] - Friendly syntax, portable, and minimalism. +- [[https://www.craftinginterpreters.com/the-lox-language.html][Lox]] - The start of my programming language creation journey. +- [[https://wiki.xxiivv.com/site/uxn.html][Uxn]] - Major inspiration, espeically around the design for devices. +- [[http://duskos.org/][Dusk OS]] - A much better system for doing permacomputing. +- [[https://doc.cat-v.org/inferno/4th_edition/dis_VM_specification][Dis VM]] - Ideas on VM structure +- Retro Systems - N64, PS1, Mac Classic, Windows 95, Especially Classic MacOS UI esthetics diff --git a/ROADMAP.org b/ROADMAP.org new file mode 100644 index 0000000..c0e4a7a --- /dev/null +++ b/ROADMAP.org @@ -0,0 +1,2 @@ +#+TITLE Project Roadmap + diff --git a/SPECIFICATION.org b/SPECIFICATION.org new file mode 100644 index 0000000..066983d --- /dev/null +++ b/SPECIFICATION.org @@ -0,0 +1 @@ +#+TITLE Project Specification diff --git a/arch/linux/gui/main.c b/arch/linux/gui/main.c new file mode 100644 index 0000000..e69de29 diff --git a/arch/linux/tui/main.c b/arch/linux/tui/main.c new file mode 100644 index 0000000..e69de29 diff --git a/arch/web/main.c b/arch/web/main.c new file mode 100644 index 0000000..e69de29 diff --git a/build b/build new file mode 100644 index 0000000..13f4793 --- /dev/null +++ b/build @@ -0,0 +1,2 @@ +#!/bin/sh + diff --git a/imgs/convert.sh b/imgs/convert.sh new file mode 100755 index 0000000..5394537 --- /dev/null +++ b/imgs/convert.sh @@ -0,0 +1,3 @@ +#!/bin/sh +magick -background none -density 384 undar.svg -define icon:auto-resize favicon.ico +magick -background none -density 100 undar.svg -define icon:auto-resize undar.png \ No newline at end of file diff --git a/imgs/favicon.ico b/imgs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7a815a889f1cf0270deb727e6b5eb4d01b7bb25f GIT binary patch literal 305664 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 literal 0 HcmV?d00001 diff --git a/imgs/undar.png b/imgs/undar.png new file mode 100644 index 0000000000000000000000000000000000000000..cb50d0bed2ac6b31424ee6d787ace2b1fb19a7aa GIT binary patch literal 7936 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 IoUyv|A9s5&oB#j- literal 0 HcmV?d00001 diff --git a/imgs/undar.svg b/imgs/undar.svg new file mode 100644 index 0000000..4e34255 --- /dev/null +++ b/imgs/undar.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + diff --git a/libc.c b/libc.c new file mode 100644 index 0000000..bee9c11 --- /dev/null +++ b/libc.c @@ -0,0 +1,68 @@ +#include "libc.h" + +void mcpy(u8 *to, const u8 *from, u32 length) { + u32 i; + if (to == nil || from == nil) return; + for (i = 0; i < length; i++) { + to[i] = from[i]; + } + return; +} + +i32 scpy(char *to, const char *from, u32 length) { + u32 i; + if (to == nil || from == nil) return -1; + if (length == 0) {return 0;} + for (i = 0; i < length - 1 && from[i] != '\0'; i++) { + to[i] = from[i]; + } + to[i] = '\0'; + return 0; +} + +bool seq(const char *s1, const char *s2) { + if (s1 == nil && s2 == nil) return true; + if (s1 == nil || s2 == nil) return false; + + while (*s1 && *s2) { + if (*s1 != *s2) return false; + s1++; + s2++; + } + + return (*s1 == '\0' && *s2 == '\0'); +} + +bool sleq(const char *s1, const char *s2, u32 length) { + u32 i; + if (s1 == nil && s2 == nil) return true; + if (s1 == nil || s2 == nil) return false; + + i = 0; + while (i < length && *s1 && *s2) { + if (*s1 != *s2) return false; + s1++; + s2++; + i++; + } + if (i == length) return true; + return (*s1 == '\0' && *s2 == '\0'); +} + +u32 slen(const char *str) { + u32 i; + if (str == nil) {return 0;} + for (i = 0; str[i] != '\0'; i++) { + ; + } + return i; +} + +u32 snlen(const char *str, u32 max_len) { + u32 i; + if (str == nil) {return 0;} + for (i = 0; i < max_len && str[i] != '\0'; i++) { + ; + } + return i; +} diff --git a/libc.h b/libc.h new file mode 100644 index 0000000..89d702e --- /dev/null +++ b/libc.h @@ -0,0 +1,33 @@ +#ifndef UNDAR_LIBC_H +#define UNDAR_LIBC_H + +#include +#include + +typedef uint8_t u8; +typedef int8_t i8; +typedef uint16_t u16; +typedef int16_t i16; +typedef uint32_t u32; +typedef int32_t i32; +typedef float f32; + +#define true 1 +#define false 0 +#define bool u8 + +#define nil NULL + +#define USED(x) ((void)(x)) + +#define AS_INT(v) ((i32)(v)) +#define AS_NAT(v) ((u32)(v)) + +void mcpy(u8 *dest, const u8 *src, u32 n); +i32 scpy(char* to, const char *from, u32 length); +bool seq(const char *s1, const char *s2); +bool sleq(const char *s1, const char *s2, u32 length); +u32 slen(const char *str); +u32 snlen(const char *str, u32 max_len); + +#endif diff --git a/vm.c b/vm.c new file mode 100644 index 0000000..e69de29 diff --git a/vm.h b/vm.h new file mode 100644 index 0000000..9ea32e8 --- /dev/null +++ b/vm.h @@ -0,0 +1,22 @@ +#ifndef UNDAR_VM_H +#define UNDAR_VM_H + +#include "libc.h" + +typedef enum { + NOOP, +} Opcode; + +typedef struct vm_s VM; + +#define MEM_SIZE 65536 + +struct vm_s { + u32 pc; + u8 mem[MEM_SIZE]; +}; + +bool init_vm(VM *vm); +bool step_vm(VM *vm); + +#endif