Skip to content

Latest commit

 

History

History
20 lines (11 loc) · 3.91 KB

20160629.md

File metadata and controls

20 lines (11 loc) · 3.91 KB

Quite a while ago, I thought: what would a programming language without reserved words look like. The idea stuck around, and some time later I finally set out to do the real work: start with a tokenizer, parser and abstract syntax tree, and then see where it leads me.

The surprising bonus has been that I'm free to design the language as I see fit. I wanted some things in, and some things out, but above all I want a clean sense of balance and if at all possible, little to no chance to have ambiguous logic, such as code that could be syntactically correct in more than one way.

The funny thing is that I'm actually a Pascal programmer. I've been doing years and years of work in Delphi, and really like the language. (Yes, I really don't mind all the extra typing.) But nothing really noteworthy in the broad C-family, except maybe a little JavaScript here and there. I guess it's a little like chess. I know about the game, I know the rules, but when we play you will probably win from me.

So I read more about progamming languages than actually code in them. Pascal is a nice language, and actually has a few things in there that show it's been designed by mathematicians. C and C++ are the top languages now, no way around them. To reach the broadest public, your new language design will be compared to C. Go looks good and has some things going for it. So has D and Rust. Ruby, Perl, Python are on the list to have a closer look at.

So for a specific example: I like that in Pascal and other languages the assignment operator is :=, and the comparison is =. In C a single equals-sign was selected for assignment, because on old computers it really mattered to select a single character for operations that would occur more. But it has since been set in stone, and forcing a two-character assignment operator upon people has become a big no-no. But I really dislike ==, but dislike possible ambiguity more, so went with := and == for now, and just to be on the safe side an assignment statement of the form a:=b by itself wouldn't resolve to a value. It's so in Pascal, and chaining assignments may be seen as a code smell. There's nothing wrong with writing (having to write) assignment statements one by one. If it's the same value you're assigning, smart register assignment and basic optimization should result to the same underlying logic.

So then it hit me. I could use = in both cases. Yes, I know this brings back queasy BASIC memories, but bear with me here. While parsing, and setting a node for a binary operator =, I could defer deciding between assignment and comparison until it's clear what's it for. If it's followed by a ; do an assignment. If the operator before or after with the closest priority needs a boolean, it's a comparison. What an idea!

In case you're wondering: do I know what is a boolean wile parsing? The strange thing with my current set-up is that I'm doing look-ups and resolving symbols while I'm parsing. A kind of linking-on-the-go. I'm curious wether I will see benifits down the road, or need to revisit this and move to separate linking (like almost any other language has, but do they have to?) but that's a whole other storey to tell sometime later.

Come to think of it, with := and == out of the way, I could do the same for && and ||! I recently noticed the bitwise and/or and logic and/or are on separate levels in most language's operator precendence table, so I want that too. I could do the same trick with letting the types in the context influence the parsing process, and have code like this do what you'd expect, without parentheses (below in Pascal for comparison):

:a:bool = b & 4 = 0 & c & mask = flags | c & mask = 0
//a := (((b and 4)=0) and ((c and mask)=flags)) or ((c and mask)=0);

Now for the time to put the work in to make this work and see if it'll work, hmm... (beuh, I'll probably first change linked lists in b-trees...)