14 karma · joined April 9, 2012
Wow, this really brings to light how well Ryzen really performs. My nvidia 950m put shame to whatever intel i7 I had on my last laptop lol. Now I'm not even sure why I got a GPU on this rig
I'll fix this soon.
I find that it's very hard to write "good code" when writing a language. I also found that the Abstract Syntax Tree didn't help me write good code. It appeared to, but the biggest stride I made was when I took out that middle man and abstracted the grammar and lexer instead.
I would never have taken out the AST if it weren't for one problem: lexer state changes at compile time. Now, it's possible to do that with an AST.. But in my case, I couldn't go back to the lexer and change states after the AST was generated. I was specifically working on regular expressions, string interpolation, and XML Tags, and managing precedence for all these things (you gotta remember, greater than and less than tokens hate XML...). My biggest problem was that in each of those "sub-syntax" features, each sub-syntax needed the entire feature set and complexity of the rest of the language. I solved all that. String interpolation was the straw that broke my delicate parser's back. Before I knew it, despite my attempted use of "good practice", the token ambiguity problem became far too big to solve without modifying the lexer. And modifying the lexer was simply too hard, as many sub-systems managed each other, and I noticed I somehow created a very deep dependency hell despite my efforts.
Today, my grammar isn't perfect. I did, however, gain the ability to entangle the lexer with an API that tries to achieve loose coupling between rules, but the coupling problem is inherit to language design- the issue is ingrained in the algorithm.
See, writing grammars are very susceptible to tight coupling. I guess that's my whole point.
We should talk sometime.
Everything in my language is an expression, so I guess you could say every literal in the language is first-class.
I was thinking for i/o, I could use promises. The promise would resolve to whatever type makes sense for that resource- defined either by a library or by the program.
Of course, that brings up "arbitrary operations at runtime". My target after transpiling is JavaScript, which has a wonderful JIT compiler already. I need to learn source mapping and stuff so I can make error-tracing work nicely, as it's simply not possible to catch any possible error at compile-time.