sylex banner

sylex

4 devlogs
16h 23m 8s

A simple programming language as a library no, yet another executable, at least this for once can actually report syntax errors in a human-readable manner. It is only expressions at this point, but there are plans to add a lot more stuff, like s…

A simple programming language as a library no, yet another executable, at least this for once can actually report syntax errors in a human-readable manner. It is only expressions at this point, but there are plans to add a lot more stuff, like statements, structs, functions, …
ASCII-Art from here: https://patorjk.com/software/taag/

This project uses AI

GitHub Copilot for Autocomplete + Chat for review/best practices + generating the README

Demo Repository

Loading README...

Andraaal

First off a correction: In my previous devlog I wrote “Writing the parser”, when I was obviously writing the
interpreter. Sorry for that. (Maybe I should stop writing these after midnight… - Me writing this at 1:30 AM)

Probably the last devlog for sylex

Since flavortown is going to end tomorrow this is likely the last devlog I will make for sylex. I did mainly two things:

  • Allow execution from CLI
  • Add some builtins
  • I also changed a lot of small things to give the project some polish

CLI execution

This was a rather straightforward feature to implement. I added two modes of execution: Files and REPL. In file mode you
just specify a file and it will execute it. REPL mode though is like a mini interactive enhanced calculator-like thingy.
Semicolon rules are relaxed and everything gets printed by default.

Builtins

I only did a few builtins, but it feels so good having finally something a bit more advanced than just basic arithmetic.
There is now sin, cos and tan, a print function: print. And then I realized that a REPL without an exit
function will cause anyone to give me a 1 in usability, so I added that too.

Random other enhancements too

I added the ternary operator to have some useful things in my language and so that strings are not completely useless.
Then I copied my GitHub Actions workflows from my other projects (still took my 3 tries to get everything right). I also
expanded the README, so people know what I even did. Also probably twenty more little tweaky I don’t remember anymore.
And 0 isn’t truthy anymore.

Well that’s it for now. I am going the create an actually useful pic and then this bad boy gets shipped!

Attachment
Attachment
0
Andraaal

Next Devlog

There is your next devlog; have fun reading it

Adding more expressions

I added logical and/or operators and all eight of the comparison operators. For those of you wonder what the heck the other two operators are, they are the three-way comparisons: <=> and >=<. They evaluate to -1, 0 and 1 depending on if their values are greater/smaller/equal. Adding them was really easy, because all the architecture needed to support them was already there. I’m talking about 1 minute or 2; I spent more time writing this paragraph than implementing
them.

Printing lexer errors

This was a really stupid mistake, I noticed that comment tokens are not filtered out and crash the parser, so I quickly fixed that.

Writing the parser

First I create a Value type, which can currently be either a number (float or int), a string or a bool. Then I wanted to recursively match the expression, but I ran into a problem: If you have two types of number, and you want to do arithmetic with an arbitrary combination of them you are gonna need a lot of matches. Luckily this can be reduced a bit by using function pointers, but I still had to write everything twice: Once for floats and once for ints.

Then came the three-way-comparators and I discovered that they are actually four-way-comparators, because there is this case where there is no ordering. Like when on of the operands is NAN. That means three-way-comparison is off the table for now, since there is no sane way to represent the results with my rather limited datatypes. Anyways the rest of the Parser should work now (I hope - I haven’t tested it yet).

Dear flavortown team

what’s up with your markdown? I just noticed that single linebreaks are rendered in my devlogs. Why? That’s not supposed to be the case in markdown for a reason. Editing your paragraphs in a single long line is just obnoxious.

Attachment
0
Andraaal

Since I got feedback, that I don’t write enough devlogs I will try to improve that and do one every 5h. (Not sure if I can keep that up, but we’ll see…).

What did I do

This was not my first time writing a parser, specifically a Pratt-Parser, so kind of knew what I was doing, but at the same time wanted to do a bit too much. I decided, since I already had experience, that I wanted to do some nice error handling this time, so that the error messages can at least point you into the right direction.

Testing

Then I started to write some tests for the parser, but quickly stopped again, because I realized that it would be a huge pain creating all these nested data-structures by hand, so I threw my concept of a library overboard and turned it into an executable. Not the “correct” choice, I know, and yes, I could have done it with AI, but I didn’t feel like doing either of that, so I just skipped it. Maybe I will generate some test-cases later on.

What did I learn

Even though I already did one of these things, creating one with proper error handling was quite the experience. First I just wanted to create my own error type, but then Copilot told me to use a library instead, so I spent about an hour figuring out how that worked and which library to use (There are some massive differences between thiserror and anyhow).

static vs const

After that was done I wanted to create a truly const parsing table this time after just using a function with hard-coded values last time. I again tried to ask AI and it told me to use static for that. Of course, shortly after I discovered that static is not the way to go and const is actually preferable here. Who would have thought that you use const for constants…

refactoring error-handling

I again tried using AI for refactoring the creation of errors (I know, I should have learned my lesson by now), as constructing one takes 5 lines and is quite verbose. Of course I first tried myself, but all of my solutions were rejected by the borrow-checker, so eventually I gave up. The AI however managed to create something that worked: A static function that takes every single field of my Error struct as arguments, puts them together and returns the product. Using that would save exactly 0 lines of code and make it even more confusing. Well done Copilot!

Attachment
Attachment
0
Andraaal

For having spent so much time here I have done surprisingly little. A lot of it was spent setting the project up, fighting with Cargo, rust’s package manager (Still my favourite package manager by far) and going back and forth on if this should be an executable or a library. Decisions have been made, but are subject to change. The rest of the time was spent actually coding. I am happy to report, here is my new Scanner/Tokenizer:

Features

  • A ton of different tokens (why did I make so many?), no tokens for keywords yet
  • Turning a String into tokens
  • Somewhat reasonable error messages with line numbers/columns
  • I just noticed: No String literals yet either
  • A bunch of tests to verify behaviour (actually found a bug while writing them)

Keeping it short this time, because there wasn’t really anything noteworthy, just parsing strings as usual. Screenshots are also just some random objects and tests

Attachment
Attachment
0