Wednesday, December 22, 2010

JavaScript: Meta-programming Example

Currently in vogue is to have code writing code, this is often called meta-programming. There are many different techniques, and many objectives when applying the technique, and it's often very powerful.

Here is a scrap from a little expression engine I wrote in JavaScript that uses a map of regular expressions to represent the various tokens.

    var lexeme_patterns = {
"integer": /^\s*(\d+)/,
"plusminus": /^\s*([\+-])/,
"multdiv": /^\s*([\*\/])/,
"open": /^\s*(\()/,
"close": /^\s*(\))/
};


There are a number of functions that I want that correspond to each of these tokens. For example I want a function that that I can ask if the next token is of a particularly type: lexer.is_plusminus() or lexer.is_integer().

Rather than manually construct these functions, I generate them using new Function(..) during the construction of my lexer. That way when I add a new token I get the functions I want automatically:

    function extend_for_token_set(proto, tokens) {
var is_token = "return this.current_token['type'] === '!!!';";
tokens.forEach(function(token) {
proto["is_"+token] = new Function(is_token.replace("!!!", token));
});
}(lexer, _.keys(lexeme_patterns);


Is it any use? Is it safe? Well, I find it useful to eliminate manual steps as I evolved my expression engine, and if I wanted to change behaviour there was a minimum of code to change, while still getting all the function I wanted for an easy to read style in my parser. But! it is tricky to figure out what code like this is doing if you don't already know what it's supposed to be doing, and that is a big negative.

So, good or bad, I don't want to say, but I do think it's worth knowing how to do it; it's a powerful tool in the modern programmer's tool kit.

No comments:

Post a Comment