Monthly Archives: January 2014

Placeholders in parser rules

Inspired by a question at StackOverflow site I started new subproject in NLT — a set of ready to use file readers. The first was PBXProj format and when writing the syntax rules for it I quickly became tired of repeating the same names over and over. PBXProj is rather simple format (similar to JSON), and the rules are short, mostly with unique symbols:

dict_list -> (COMMA- d:dict)+ { d };

But why introduce a name for an object when in code symbol name would be a perfect fit? You know, “opportunity” is just another name for the “problem”.

dict_list -> (COMMA- dict)+ { $dict };

Once NLT spots a placeholder it tries to bind it to symbol (symbol has to be unique and anonymous, i.e. without object name specified). Once it does, it adds implicit object name for the symbol and uses it in the code.

I don’t recommend using placeholders in long syntax rules, but in short ones it is the way to go.

Advertisement
Tagged ,

Uncharted territory — symbol generics

I had a little problem with this feature — not only I’ve recently got a job and I have much less time for developing Skila, but I had no luck finding a source explaining how you usually implement generics in compiler. Nevertheless I started with the flavor which bugged me since C++, namely symbol generics.

Consider a pair for C++, taking regular approach you won’t make anything more than a structure with “first” and “second” fields. The code works of course, but the moment you pass such data you have to comment a lot of code, because “first” carries absolutely zero information. Is this an address? Or salary? Or weight?

In C++ I was not completely lost — I wrote “NamedTuple” macro and then I had regular fields as above plus reference fields with the names I passed. Thus I could pass named tuple to any template function which expected regular tuple (because I had “first”, “second”, and so on, fields). The downside was as usual with macros in C++ – they are harder to maintain.

I am not against introducing macros to Skila, but I’ll wait until they become necessity. And with symbol generics I can do more than I did in C++:

class Tuple<'ITEM1'>
  var _1 Int = 5;
  alias ITEM1 _1;
end

func main() Int
do
  var m = new Tuple<'Id'>();
  return m.Id;
end

First of all, you deal with compiler, not preprocessor. Second — you don’t use references, but aliases, they don’t take space at all, so there is no penalty in taken memory. And third — it works. Here, you can see I instantiate the “Tuple” class with symbol “Id” and from that point I don’t use meaningless “_1” but “Id”. No need for extra comment stating “_1 holds Id”.

One of my idées fixes… fixed!

Tagged , , , , ,

Something sweet about DSL — PuzzleScript

I’ve just read at Lambda the Ultimate (one of the must-subscribe blogs) about PuzzleScript:

It is an HTML5-based puzzle game engine that uses a simple language for patterns and substitutions to describe game rules. For example (taken from their introduction), the basic block-pushing logic of a Sokoban game can be given as:

[ > Player | Crate ] -> [ > Player | > Crate ]

This line says that when the engine sees the pattern to the left of ->, it should replace it with the pattern on the right. In this case, the rule can be read as something like: when there is a row or column ([]) that contains a player object (Player) next to (|) a crate object (Crate), and the player is trying to move toward the crate (>), then (->) make the crate move in the same direction.

The introduction given at the PuzzleScript webpage is very informative, full of animations. And those examples bring sweet memories of old games played in the 8-bit era. Take a look yourself!

Tagged , , ,