IRC channel logs

2023-05-12.log

back to list of logs

<oriansj>probie: well simple register based vm are not simple. atleast if you want universal behavior
<oriansj>take something like sweet16, which is simple to implement on 6502 but much harder to get matching behavior on say an armv7l system.
<oriansj>writing towards a 16bit vm is a great deal harder than a 32bit or 64bit machine
<oriansj>and implementing a 64bit vm on a 16bit machine is a nightmare
<oriansj>and for extra fun; sweet16 is bigger than builder-hex0's bootstrap binary and virtually all hex0 implementations and hex0 behavior is universally identical by specification (even on non-twos complement instruction sets)
<stikonas>well, the new builder-hex0 bootstrap seed is just 200 bytes
<stikonas>(or so)
<stikonas>hard to beat this
<stikonas>it's quite impressive to go this low
<oriansj>(The original knight was symmetric complement and its current code would have produced the exact same output even if it was one's complement)
<stikonas>I guess it's similar in size to hex0 posix seed but it doesn't have any ELF header and output is directly to memory
<oriansj>and sweet16 did not have *ANY* syscall or bare metal instruction support (you had to directly talk to native hardware's memory which is far less portable than even native assembly)
<oriansj>more often then not, you would pull a RTN (Return to 6502 mode)
<oriansj>and unless you are dealing with absolute garbage CPU architectures; there is no advantage to a VM and to be honest a FORTH would be easier to bootstrap a garbage architecture and is easier to program for than an instruction set.
<muurkha>probie: I've been thinking about the "simple register based vm" approach but without the interpreter, just the compilers
<muurkha>which is sort of what stage2 is
<muurkha>I don't think it's that hard to get 16-bit arithmetic on a 32-bit machine; the only basic operations where the high 16 bits of any register affect the low 16 bits of any other are shift right (and variants like rotate left and rotate right) and division
<muurkha>so in those cases you need to mask to 16 bits before doing the operation
<muurkha>the reason I was thinking about simple register-based VMs is last night's conversation with drakonis about uxn, where the objective is to be able to distribute roms that are guaranteed to run on a wide variety of platforms, including things like GBA and Nintendo DS
<muurkha>and I was thinking about how to design something like uxn to be more efficient with a simple compiler
<muurkha>I don't think my simple register-based VM compiler will be as small as SWEET16
<muurkha>drakonis: I think I have a clearer point to make about uxn
<muurkha>uxn is, like a video game, designed as a challenge. it's intended to be hard to do things in
<muurkha>arguably that's true of what most people do with Forth these days too: they're looking for a challenge, a weight to lift
<muurkha>and that runs counter to the goal to be 'something you could build in the event that access to complex hardware becomes limited'
<muurkha>if you have something heavy to lift, calling on your weightlifter friends might be a reasonable thing to try
<muurkha>but a barbell probably isn't going to help you. if you want machinery, you want a chain hoist
<muurkha>if you're trying to use a Gameboy DS because that's the best computer you have, uxn is more a barbell than a chain hoist
<drakonis>muurkha: i do agree with that
<drakonis>a lot of the interest in forth and concatenative languages is that they're powerful but not banal languages
<drakonis>something like uxn, in its glorious inefficiency proves to be somewhat of a challenge in a situation where the average hardware performance has greatly declined as we may have lost the ability to manufacture parts with the same level of performance as we do now
<muurkha>to my way of thinking, a "powerful" language is one that's like a chain hoist or a steam shovel
<muurkha>it makes hard problems easier
<muurkha>Forth can do that in some circumstances
<muurkha>I mean it can give you a multiuser IDE with an assembler, a high-level scripting language, and virtual memory in 16 kilobytes of memory
<drakonis>indeed
<muurkha>and it makes poking at the registers of your peripherals interactively pretty easy
<drakonis>there's nothing that can measure up to that power in the event of global catastrophe
<drakonis>it is a bit of doomerism, isnt it?
<muurkha>a pile of working gigabyte RAM chips would go pretty far
<drakonis>certainly
<muurkha>but I think a lot of people using Forth are trying to make easy things hard, not hard things easy
<drakonis>do tell
<drakonis>there's forth dialects that enable the latter
<drakonis>retro and factor
<drakonis>because they provide useful features that allow code to be more readable for a lack of a better word
<drakonis>quotations go a long way towards writing readable forth
<drakonis>as do combinators
<drakonis>although, as a more direct reply to your statement, i think what people end up using forth and related languages as some kind of exotic toy as opposed to actually writing meaningful code
<drakonis> https://retroforth.org/ and https://factorcode.org/
<muurkha>not sure combinators in general make code more readable
<drakonis> https://docs.factorcode.org/content/article-combinators.html
<drakonis>these kinds of combinators, that is.
<muurkha>they do make it shorter because you can write in point-free style
<drakonis>there are some that do improve readability because you don't have to do as much stack munging to do basic things
<drakonis>but it is not something absolute
<drakonis>mind you this is coming from me and my lack of experience
<muurkha>I think it's a good exercise to write some Forth without any stack manipulations except DROP
<muurkha>because the first thing everyone does is try to use the stack for local variables
<muurkha>and this is always possible in theory but unnecessarily difficult to debug
<muurkha>like, it's probably okay to store one local variable on the operand stack and one on the return stack? but to start out, don't, use zero
<muurkha>the return stack is the minimal mechanism for recursive subroutines. arguably if your subroutines don't recurse you only need one return address cell for each one, and e.g. MIX and the PDP-8 did work that way normally, but the return stack is both more space-efficient and arguably simpler
<muurkha>the operand stack is the minimal mechanism for nesting expressions
<muurkha>so that you can write m*x + b or m x * b + instead of mul m, x, t1; add t1, b, t2
<muurkha>this makes it pretty trivial to translate a line of C to a word of Forth, except that you have to choose a unique name
<drakonis>append a randomly generated string to the name when generating
<drakonis>gensym, basically?
<muurkha>no, choose a name you can remember
<muurkha>it doesn't have to be globally unique, but probably unique within a wordlist/vocabulary is a good idea
<muurkha>like, take the line const char *str = _Py_SourceAsString(source, "symtabl
<muurkha>e", "string or bytes", &cf, &source_copy);
<muurkha>you can translate that to something like : string-to-source source @ c" symtable" c" string or bytes" cf source-copy source-as-string ;
<muurkha>source, cf, and source-copy are VARIABLEs here
<drakonis>i see, its sufficiently understandable
<drakonis>alright, i think i'll go now, its getting late here
<muurkha>goodnight
<drakonis>thanks
<drakonis>a conversation at ##forth gave me a silly idea, writing a IR layer for a forth bootstrapping kit, in which it can output generated assembly for multiple ISAs
<drakonis>using forth for assembling binaries for fun and non profit
<stikonas>you can probably use macro assembler such as M0 to implement IR layer...
<stikonas>but we haven't tried that with cc_x86...
<drakonis>the point would be to then use forth as an assembler for generating arbitrary binaries
<drakonis>it'd be something
<river>that is a great idea
<drakonis>so it is, i suppose
<drakonis>just throwing out the inspiration
<river>we experimented with forth early on but unfortunately it wasnt used
<drakonis>i've seen that on stage0
<drakonis>it was shelved in stage2
<drakonis>the readme has a fairly antagonistic tone
<drakonis>the current iteration was written 2 years into the project anyways
<drakonis>i am not complaining about any of this, mind you.
<stikonas>stage0 hasn't seen much work recently anyway
<stikonas>everybody was working on stage0-posix
<drakonis>fair.
<[exa]>drakonis: actually forth may be viewed as assembly, it is possible to have a forth implementation where the forth words directly translate to instructions
<drakonis>indeed, but it is only useful if i actually bootstrap the implementation
<[exa]>:heaviestly_thinking_face:
<drakonis>ha
<drakonis>okay
<drakonis>i would like to amend that
<drakonis>if i actually get to the initial state, anything is possible, including writing an assembler powered by forth
<drakonis>which in turn can output anything i want into a binary
<[exa]>there are dirty tricks you can do there to save a lot of code and that don't generally hurt much
<[exa]>such as having only fixed-size 8character words (or 7+space)
<[exa]>I'm suddenly inspired to waste a weekend on this.
<muurkha>awesome :)
<muurkha>the traditional format, incidentally, was length + first three characters
<muurkha>whi-- fit- in 32 bit- and is eno--- inf-------- to mos--- und------- eng---- tex-
<muurkha>for StoneKnifeForth I just used the first character to save myself the work of writing a hash table
<muurkha>probably I should have just used linear search
<[exa]>lol cool
<Irvise_>theruran: I can confirm that the first GCC release with Ada files was 3.1
<Irvise_>I am now going to look into what it was required for compilation.
<Irvise_>From the GCC 3.1 documentation regading Ada:
<Irvise_>"... (full message at <https://libera.ems.host/_matrix/media/v3/download/libera.chat/b758676adfae8bb7d0281206eeff18a9d1ea9d80>)
<Irvise_>GNAT-3.15p also indicates that you need a previous working GNAT installation.
<muurkha>your message seems to have gotten truncated by Matrix
<muurkha>maybe you could paste a less-than-511-byte passage?
<probie>I think it's because it's multiline
<theruran>"@section Building the Ada compiler - In order to build GNAT, the Ada compiler, you need a working GNAT compiler (GNAT version 3.13 or later, or GCC version 3.1 or later), since the Ada front end is written in Ada (with some GNAT-specific extensions), and GNU make."
<theruran>in order to build GNAT, you need to pull an older GNAT out of your ass
<theruran>it's free software!
<probie>just roll your own Ada compiler to build it
<theruran>just need a hyperbolic time chamber
<probie>I think I'll give writing an Ada compiler a go, just right after I finish my Haskell compiler
<probie>So, should be ready in ~20 years
<theruran>;)
<stikonas>M2-Planet or mescc didn't take 20 years...
<probie>That's true. But ghc is a very different beast to tcc - I don't think there's any released version which has ever been build-able by other Haskell implementations.
<stikonas>yes, C is one of the simplest and lowest level languages...
<stikonas>still, it's probably not 20 years
<stikonas>one could probably convert some earlier version of GHC to C in a year
<stikonas>(assuming full-time work)
<stikonas>I think it's somewhere around 600k lines of code
<stikonas>hmm, that would be 2k lines of code per day
<probie>Well, 10 years, since there were two (Ada, and GHC), and that was part-time, so 2 years (but that was also meant as a joke, and not a serious estimate)
<probie>s/GHC/Haskell/
<probie>also slightly biased towards a high-estimate because the wiki https://bootstrapping.miraheze.org/wiki/Discarded_options_and_why gives 15 years for a team of 20 developers and I don't want to be shouted at
<stikonas>"Haskell in assembly from scratch". That will definitely take longer than writing it in a higher level language
<stikonas>probably C++ would be faster
<[exa]>haskell compilation ain't that hard but the compiler frontend with all the trick is insane
<[exa]>(and most of the utility is in the insane frontend)
<probie>Possibly? Naively I'd say once you've got something like Core, it's straightforward (SPJ wrote a tutorial on compiling lazy languages, and shows that it's remarkably simple to turn something Core-like into code for the g-machine, which is itself easy to turn into assembly for most architectures)
<probie> https://www.microsoft.com/en-us/research/wp-content/uploads/1992/01/student.pdf if anyone is curious about the tutorial
<probie>(it is rather dated though)
<muurkha>I don't think C is especially simple
<muurkha>probie: thanks!
<muurkha>oh yes, "Implementing Functional Languages: a tutorial"
<muurkha>this is what I was working from when I implemented my compiler from lambda calculus to combinator graphs
<muurkha>but I didn't finish reading it
<probie>muurkha: C isn't that simple - the C17 standard is about 500 pages, but the Ada2012 reference manual is nearly twice that (admittedly not quite the same, but I can't find the spec for free anywhere and I'm not paying for it)
<Irvise_>probie: the Ada spec is free! :D give me a sec
<Irvise_>Here http://www.ada-auth.org/arm.html
<Irvise_>The 2022 standard is still not published by the ARG, but it was released by ISO a couple of days ago
<probie>> The text of the Ada Reference manual is the source of the formal Ada Programming Language Standards.
<probie>Huh, for some reason I'd just assumed it was the other way around