PL_Design
u/PL_Design
I'm familiar with TAC, SSA, bytecode, continuation passing, AST, and source-to-source translators. What are some more exotic and unusual kinds of IRs that you've seen before?
In our language we allow programmers to define whatever operators they like, and we allow operator overloading. This lead us to an interesting situation where we noticed that if the precedence is defined per overload, then parsing expressions is either undecidable, or you need some disambiguating strategy that's almost certainly not something the programmer can predict. Our solution was to try mostly flat precedence, and we found that worked very well for the most part. We had to make some exceptions to make the language's notation read properly. For example, we noticed that indexing into structs or arrays was awkward because of situations like this:
a + foo.bar@2
. and @ are our d
A more accurate term than "technical debt" is probably an unhedged call option.
old.reddit.com/r/programming/comments/sodp0p/...As I do not use this project, I am not bound by its license. Therefore I will do as I please.
github.com/n4ru/1vyrainWe do not need to always start from AdamsTowel; there are many interesting towels out there, and you may also become skilled in the advanced technique of towel embroidery.
l42.is/tutorial.xhtmlIn particular I'm interested in the song that plays at the start of this video(and others): https://www.youtube.com/watch?v=5ga4PYMKwQ0
But more broadly I'd love a playlist of the music he uses. Jamez Dahl(https://www.youtube.com/channel/UCvgQE_C66Mqg2xqKvHIdYPQ) has done some of the music, but far from all of it because there's a lot of music that Quinn uses that I don't recognize from his work.
Thanks!
One thing that occurred to me is that there is a difference between ptrs and addresses: A ptr is a parameterized type, and an address is a location in memory. Therefore what our language actually needs to be able to support is just addressing, and ptrs can be a userland idea that's handled by defining the correct operators. See:
:ptr T
{
address: u64;
}
## in our language you can define if a function or macro returns an lvalue
## this is equivalent to wrapping the return value in #load
`*` :: #lvalue: #macro: (a: ptr{T}) T -> T
{
return a.address;
}
And the same kind of thing can be done for ptr arithmetic and getting the ptr of a value.
When looking into monads, you will either find obtuse theory, Haskell code, or nonsense analogies(i think i'll have a burrito for lunch tomorrow). These explanations all have the same problem: Intentional or not, they presume the reader basically already knows what a monad is. That's great for people who've been initiated into functional programming and need a refresher, but does little for anyone else. Someone from an imperative background is going to look at this stuff, see more stuff they don't have the context to understand, and walk away frustrated. This is strange because every imperative programmer can easily understand the option/maybe types that have been imported into imperative la
I've been reading this subreddit for several years now, and so often it bums me out. It seems like almost everyone is obsessed with reaching as high up the fruit tree as they can go, and everyone is trying to grab the exact same fruit. If that were the only fruit left, then I would understand that, but it's really, really not. There's still loads of low hanging fruit just begging to be picked. It would be nice to see a little more variety here, y'know? So here's my contribution:
The past couple of days I've been experimenting with a new global allocator for my personal library for our language. I call it the vspace allocator because its job is to track cells of virtual memory. Right now I'm
Background information:
-
I'm using 64 bit Arch.
-
I'm writing an experimental custom allocator, so portable code is a stretch goal, not a requirement.
-
I'm not using C or C++. I'm doing my syscalls directly.
According to this SO post: https://stackoverflow.com/questions/17671423/where-is-the-stack-memory-allocated-from-for-a-linux-process A program's virtual address space is organized like this:
------------------ <--- Top of the process address space
Stack (grows down)
v v v v v v v v v
------------------
(unmapped)
------------------ <--- Maximum stack size.
(unmapped)
-------------------
mmap
-------------------
(unmapped)
-------------------
^ ^ ^ ^
Background information:
-
I'm using 64 bit Arch.
-
I'm writing an experimental custom allocator, so portable code is a stretch goal, not a requirement.
-
I'm not using C or C++. I'm doing my syscalls directly.
According to this SO post: https://stackoverflow.com/questions/17671423/where-is-the-stack-memory-allocated-from-for-a-linux-process A program's virtual address space is organized like this:
------------------ <--- Top of the process address space
Stack (grows down)
v v v v v v v v v
------------------
(unmapped)
------------------ <--- Maximum stack size.
(unmapped)
-------------------
mmap
-------------------
(unmapped)
-------------------
^ ^ ^ ^
Background information:
-
I'm using 64 bit Arch.
-
I'm writing an experimental custom allocator, so portable code is a stretch goal, not a requirement.
-
I'm not using C or C++. I'm doing my syscalls directly.
According to this SO post: https://stackoverflow.com/questions/17671423/where-is-the-stack-memory-allocated-from-for-a-linux-process A program's virtual address space is organized like this:
------------------ <--- Top of the process address space
Stack (grows down)
v v v v v v v v v
------------------
(unmapped)
------------------ <--- Maximum stack size.
(unmapped)
-------------------
mmap
-------------------
(unmapped)
-------------------
^ ^ ^ ^
Several years ago I did some work on my own regex dialect that for now I'm calling Named Regions Regular Expressions, or something like NRegex for short. Here's an example of a regexp:
{radix:\d+}r{value:\w+}
This is equivalent to this in a more traditional regex dialect:
\d+r\w+
The idea behind this regex is to scrape the radix and value from a Smalltalk style integer literal. For example, 2r1010_1010. The way this works is that once the regexp is compiled to a DFA you're given a ptr to the state machine, and then you pump characters into the state machine manually. Something like this:
regex := compile_regex("{radix:\d+}r{value:\w+}");
state := 0; ## the initial stat