• SUBLEQ and EForth

    From anthk@21:1/5 to All on Wed May 14 09:31:12 2025
    SUBLEQ from this author it's a 16 bit virtual machine with just one instruction:

    https://github.com/howerj/sublec

    subtract 'a' from 'b', store it under 'b' and if it's equal or less
    than 0, jump to whatever address it's being pointed at 'c'.

    https://en.wikipedia.org/wiki/One-instruction_set_computer

    The programmer wrote an Eforth image runnable under Subleq.

    This is a whole subleq program in C:

    #include <stdio.h>
    int main
    (int x, char **v) {
    FILE *f = fopen(v[1], "r");
    short p = 0, m[1 << 16], *i = m;
    while (fscanf(f, "%hd", i++) > 0);
    for (; p >= 0;) {
    int a = m[p++], b = m[p++], c = m[p++];
    a < 0 ? m[b] =
    getchar() : b < 0 ? putchar(m[a]) : (m[b] -= m[a]) <= 0 ? p = c : 0;
    }
    }

    Here's the subleq image: https://raw.githubusercontent.com/howerj/subleq/master/subleq.dec

    Run it as ./subleq ./subleq.dec

    It you want speed, there's muxleq, which runs a lot faster than subleq.
    Muxleq multiplexes instructions. Again:

    https://github.com/howerj/muxleq

    He created a book too, but I didn't get it yet, altough
    subleq.fth and muxleq.fth are highly documented.

    If you want float numbers support among other nice addons,
    edit the fth files (the opt.* parts at the beginning)
    and redo the image. For instance:

    1 constant opt.control

    will add do...loop support instead of just the eforth words
    with for...next (which can be added to pforth too).

    Regenerate it:

    ./subleq ./sublec.dec < sublec.fth > new.fth

    It will last for LONG on older machines; so you maybe
    ask someone to recreate the SUBLEQ image for you.

    Under muxleq the generation speed will be a bit faster.

    The overall speed with Muxleq under an ATOM can be taken
    as a machine between a Altair 8800/S100 BUS machine with CP/M
    and a boosted up Jupiter ACE. Not bad at all.

    Subleq (even muxleq) emulators are very slow under Perl and
    Python implementations, and the Forth one it's even slower
    under PForth, but it might run fast enough under GForth or
    some optimized ANS Forth for Windows:

    https://github.com/howerj/subleq-forth

    As a hint, I compiled C muxleq like this:

    cc -o muxleq muxleq.c -ffast-math -O3 -march=atom

    because the float numbers are not done with
    the system math library at all.

    Finally, there's an EForth+Subleq port as an OS,
    from a bootable X86 image. I'd guess a PentiumIII
    would be needed to get usable speeds (if not more):

    https://github.com/pbrochard/subleq-eForthOS

    Obviously it can't compare to a bare X86 bootable Forth
    or CiForth under SVARDOS, but maybe running SUBLEQ
    natively gets somehow to 386 or low end 486 speeds
    under a Pentium III.

    It's an interesting concept to get a mega-portable
    Forth, because a Subleq interpreter can run everywhere
    with very few lines, even AWK.

    But forget about performance under pre SSE2 machines
    or non C/ASM SUBLEQ virtual machines and any other
    SUBLEQ implementation than MUXLEQ. SUBLEQ it's usable
    but MUXLEQ with just two lines more gets a big boost.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From anthk@21:1/5 to Hans Bezemer on Thu May 15 14:34:53 2025
    On 2025-05-14, Hans Bezemer <the.beez.speaks@gmail.com> wrote:
    On 14-05-2025 11:31, anthk wrote:
    Run it as ./subleq ./subleq.dec

    I can't - it complains:

    $ pp4th -x subleq.4th < subleq.dec
    Error: Not a 16-bit SUBLEQ VM

    Hint - no, it's not YOUR subleq interpreter ;-)

    Hans Bezemer



    Yes, it's not mine; but I understand it fine.
    You need a 16 bit wide VM for Subleq. Most of them
    from Howe (if not all) work as is. The fastest
    one OFC it's the C one (altough the gawk and
    mawk ones can be really good for being interpreted
    languages, much faster than the Perl VM,
    which I extended for muxleq (and avoiding
    creating stating variables with "my" every
    loop, which is far slower than globally
    declaring a variable and giving a new value).

    Still, GAWK (and MAWK even more) emulating a Subleq VM ran much
    faster than Perl doing a Muxleq one.

    Also, as for...next, I have it under
    PForth for testing some code. Hackey, but it's fine:

    : >MARK ( --A ) HERE 0 , ;
    : AHEAD ( --A ) COMPILE branch >MARK ; IMMEDIATE
    : AFT ( a --a A ) DROP [COMPILE] AHEAD [COMPILE] BEGIN SWAP ; IMMEDIATE

    : FOR ( RUNTIME: N -- )
    COMPILE ABS \ NO NEGATIVES
    COMPILE LIT 0 , COMPILE SWAP
    [COMPILE] ?DO ; IMMEDIATE

    : NEXT
    COMPILE LIT -1 ,
    [COMPILE] +LOOP ; IMMEDIATE

    I spawn pfe as "pforth -q -i ~/.pferc" and most of the stuff
    on eforth runs on pforth, except for the weird float syntax
    Also I found some double multiplying works missing, so
    I tried to set ones in my own by looking up
    elsewhere, as I'm still learning Forth with the
    ANS Forth web book from Leo Bordie.

    : t* tuck um* 2swap um* swap >r 0 d+ r> rot rot ;
    : t/ dup >r um/mod rot rot r> um/mod nip swap ;
    : m*/ >r t* r> t/ ; ( d n n -- d * n / n )
    : d* 1 m*/ ; ( d d -- d * d )
    : d/ 1 swap m*/ ; ( d -- d / d )

    Hacky, but it works. I didn't find issues on using
    'integers' and doubles as arguments for m*/ and
    the double words bound to that.

    Yes, Eforth under subleq it's slow, but usable;
    and with muxleq the CPU usage plummets down.

    Would it run fast under a physical CPU made of TTL's?
    IDK, but the Minix 2 under http://magic-1.org it's fairly usable
    at 4MHZ and running vi and even ed it's far more CPU
    intensive than a Forth; so in the they would be pretty even.

    But what I'd love it's some EForth for the Magic-1 CPU,
    a native one, even with multiple users support.

    No, not for Minix 2, native. It could run faster than
    a Unix-like I'd guess. No Rogue, nor advent; but these could
    be rewritten. Maybe even with less complexity than a C+Yacc
    maze madness. Yes, it would use more storage, even with blocks,
    but the code size would be smaller.

    A floppy sized storage would allow tons of extra free size
    for applications.

    AWK? Forth. ed? Trivially reimplemented for editing blocks.
    Unix pipes/composability? Forth words.
    Copy and mv would be implemented
    in the same way on a screen basis.
    No directories, no timestamps, no FS.
    Accesing serial ports it's barely a single step
    over parsing them in Unix as files.

    On multitasking:

    https://www.bradrodriguez.com/papers/mtasking.html

    So, this can be fun if the Magic-1 autor gets into it.
    At least he won't need to target a new compiler/linker
    and tons of C headers/libraries to match his new arch :D

    Oh, and maybe the terminals won't lock as often as it
    happened under ed while editing as simple gopher client
    as it happened to me. Not vi, ed.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From anthk@21:1/5 to Hans Bezemer on Sat May 17 05:59:46 2025
    On 2025-05-14, Hans Bezemer <the.beez.speaks@gmail.com> wrote:
    On 14-05-2025 11:31, anthk wrote:
    Run it as ./subleq ./subleq.dec

    I can't - it complains:

    $ pp4th -x subleq.4th < subleq.dec
    Error: Not a 16-bit SUBLEQ VM

    Hint - no, it's not YOUR subleq interpreter ;-)

    Hans Bezemer



    The Eforth code from the repo requires a 16 bit wide subleq machine.
    Both subleq and muxleq (the last one it's much faster) in C
    from Richard James Howe (same author) work seamlessly.

    https://github.com/howerj/subleq/

    No, is not my interpreter, I barely expanded the Perl one for Muxleq
    and it was just slightly faster but Perl had atrocious performance.
    Even gawk (mawk ran really well) ran it much faster.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)