My recent foray into the world of XML-markup code reminded me of something I had written 3 years ago. It was called 'XCBL' - an acronym for 'eXtensible Common Base Language'. Something I can't help but smile nostalgically about - though I want to hide my head in shame every time I think to one of the multiple goof-ups I had made :)
Background
The first time I worked on a modern computer was in early 2000. It was a Windows 98 machine at a computer training center that I had been forced to go to. Till then, my only knowledge of programming came from Basic code snippets hastily learnt before exams. I actually wanted to be a writer and become the next Michael Crichton. 5 years and tons of grammatical boo-boos later, here I am, talking about Avalon and .NET and Python.
I got my first computer right after my high school exams. This was in early-2001. For the first time, I could actually sit in my own room and crank out VB programs (that and Java were the languages I got started on). The thing that kept me back was the lack of an internet connection - I didn't get one till sometime in late 2002. But the lack of packets flowing through my modem didn't stop me at all. I hacked away happily at my computer, cranking out one VB app after another. Going through those archives, I see that I wrote among other things, a tabbed interface for IE with Mozilla-like extensions :)
Soon, I got pretty good at VB 6 (relatively speaking - I still hadn't managed to go online). Dan Appleman and other hardcore VB books were my bibles. I was of the firm opinion that C/C++ were for old fogeys and VB was the way to go. Theoretically speaking, there is nothing you can't do with VB6 (hmm.. device drivers,perhaps. Reliable multithreading comes a close second).
The Concept
Around this time,a friend (Prashanth Ellina) and I were writing several software applications together. One fine day, while having yet another phone conversation on trying to figure out the next big thing, we came up with this system of making several languages work together in a new (or so we thought) way. There were 2 distinct goals
1.Prashanth's idea was to have programmers writing code in various languages..which would then be 'translated' to our language. This way, programmers could use multiple languages seamlessly on the same project.
2.My idea was slightly different - I wanted to have a form of 'executable HTML'. I realized that HTML (declarative markup to be more precise) was way better than VB6 or AWT or Swing for laying out GUIs.
Now, we had no idea that stuff like this had been done before. In fact, we were trying to write our own version of .NET's IL and the CLR and we didn't even know it. All I knew about .NET was that it was this Java competitor from Microsoft that did something called 'web services'. Oh well..not being online can do that to you.
XCBL is Born
Both these ideas meshed together and XCBL was born. The name was actually a joke - I joked about how Microsoft would name it with a 'X' and somehow the name stuck. Looking back, it was probably a mistake to try and aim for one solution to what were two distinct problems. But then, who cares? :)
The idea was to write an interpreter for XCBL and 'translators' for various languages. We also wrote up a paper and won prizes at a few local symposiums. This was a *big* deal back then.
The Language
We started working on our 'base language' which all languages would 'translate' to. I chose a XML-based syntax..for no particular reason. I had got a new XML book back then - and wanted to put it to good use. Somehow , I get the feeling that I'm not the only person to have committed this crime.:)
I don't remember whether we designed the language up front or whether I made it up as I went along. To Ellina's credit, he was staunchly against the idea of having a XML-based syntax. Among other things, it was a pain to type out. But what can I say - I can be very persuasive at times :)
We had only loop construct - as we figured out that all loops are based on one fundamental model.
By now, I'm sure you want a glimpse of what XCBL code looks like - so here's a sample
<class Name="HelloClass">
<function Name="Main" Access="Public">
<out>Hello World!</out>
</function>
</class>
Now, imagine typing out reams and reams of such code..not a pleasant task (Yes, Vivek, you're right :-) ).
I later came to know that our design wasn't that new. XPP and other languages have a similar syntax.And of course, XAML is the big new guy in town. The first time I saw XAML code, I jumped up and down - it was almost the exact same thing that I had visualized. And we were 4 years ahead of Microsoft :-)
So one fine day, with Ellina off on vacation, I sat down in front of my computer to start coding
The Code
I never had any doubt as to what language this interpreter should be written in - VB of course! Keep in mind that at this time, I had been programming for just over a year, so I was definitely young and foolish. People still say I'm young and foolish..but that's a different story.
Since I had never written any 'big' VB application, I thought it would be prudent to design it out beforehand. My 'design' consisted of 2 pages of paper with scribbled diagrams on them.Besides, I wanted to try out this cool, new thing called 'classes' in VB :)
I really wish I had heard of things like 'lexical analysis', 'the Dragon book','lex and yacc' and stuff like that back then. It would have saved me tons of headaches. Instead of using a simple grammar file and generating my parser, in the end, I wound up writing my own XML parser. And it wasn't easy.
The first problem I had was about parsing expressions themselves. Not until several months later would I hear of terms like 'lexical analysis' and 'top-down parsing' . I did some thinking and came up with this recursive way of evaluating expressions. I had actually written my own recursive-descent parser - only that I didn't know it was called that back then. I open up a Java reference book to figure out what operator precedence should be. :)
Representation
My initial idea was to eliminate the need for data types and 'figure out the proper type at runtime'. I had written some code earlier in Javascript and I liked that weakly-typed model. In a way, my affection for dynamic programming and duck-typing had started back then.
I wrote up a class called 'XcblVar' which represented a variable. Here are the comments from the top of that file
'The base variable class ... implemented internally as a variant.In XCBL, even
'variables are objects , kind of like Smalltalk so that everything is clean.
'Performance is not an important consideration in XCBL.
'We map strings and doubles to Vb's inbuilt types but for
'booleans , we have to handle it differently as having -1 for true
'is idiotic. Therefore we do some translation. Check out
'BoolValue Let procedure
'IMPORTANT: XcblVar can contain XCBL objects
Hmm...as you can see, I didn't think highly of VB's using XOR for True and False back then and had to do hacks to map to and from VB's boolean representation. That comment about performance was due to us thinking that Moore's Law would take care of all our performance problems.Hmm..too bard Rico Mariani wasn't around me back then to give me a sound spanking.
One more thing that you can see from those comments is that I intended XCBL to be completely OO. However, I never got around to fully implementing all that.
I also wrote 'XcblFunction' and the collection classes for both the variables and the functions.
Lexer
I soon started hitting obstacles. For those of you who have never written a lexical analyzer by hand, trust me, it's tough. For those among you who didn't know what a lexer was and still tried to write one...you know what I mean.
My first problem was with XML itself (or the way I wanted to use XML). The code I wanted was like this
<function name="">
-- Code block-
</function>
But XML wouldn't let me do that unless I wrapped my code blocks in CDATA sections. Which was just plain ugly. At this point of time, I was still hoping that human beings should be able to edit XCBL files by hand. So typing out CDATA was a big no-no. From XML syntax,we went to a XML-like syntax. I started writing my own XML parser. At that point of time , I would have wagered that I knew VB's string handling functions better than most people.:)
One small problem.
XML uses angle brackets. Relational operators use angle brackets. This confuses the heck out of your lexers.At this point of time, I should have probably given up the XML syntax and moved on, but me being the stubborn jackass that I am, wrote the first of several hacks to get around issues like this.
By now, I had been coding for over a week non-stop, day and night. I could get simple expressions to evaluate properly - but nothing more than that.
The Preprocessor
If you're not laughing by now, you will be after reading about this. To solve this lexing problem, I started preprocessing the text. I would replace relational operators with something like '@@##greater_than@@##'. All that fancy decoration is to ensure that I can recognize these things easily - and in the hope no one would use anything like that in their source code.
This idea seemed so good that I started doing this all over the place. In fact, my lexer and the preprocessor became one. So
<function name="Something">
<return>5 + 3</return>
</function>
would become
@@##Function@@##Something
@@##CodeBlock@@##
@@##Return@@##
@@##Expression@@## 5 + 3
In a way, this was our byte code . Most of the work was done in converting source code to this form. Once I had it in this form, I could easily run it through my 'runtime' (which I called 'Parser' due to a sad misunderstanding of what a Parser's work is).
Ok. Stop laughing now.
My first virtual machine
Now, I had something in a runnable form. All I had to do was to go and run it. Here's how my virtual machine worked
My runtime would look at any executable code (just like Python) jumping over methods,etc. When it finds that code, it would create a new 'scope'. Each scope has its own set of variables(maintained in XcblVarTables). Think of a scope as a cross between a stack-frame and a normal definition of 'scope' (as in local scope, global scope,etc).
Whenever any variable was referred to, I would look in the current scope - and then its parent, and so on. This let me do things like overloading and shadowing pretty easily.Functions were converted to byte-code the first time they were called and then that byte-code was used then on (you could draw a parallel to how .NET's JIT works).
Garbage collection was done through reference counting.Cyclic references? What are those? :)
Heaven
I still remember the first time I got a function to run. I was ecstatic and called my mom into my room to look at it. You have to experience this to understand- the feeling of code running on *something you've written' gives you a great high.I soon got recursion to work and wrote a recursive factorial program. I could calculate upto 170! before VB's Double datatype overflowed. I also used this for performance evaluation - and I was very happy when XCBL ran this function only a second slower than the compiled VB equivalent!
<var>x</var>
<function name="factorial" returns="var">
<arguments><var>n</var></arguments>
<if cond="n == 0 or 0 == 1">
<yes>
return 1
</yes>
<no>
return n * factorial(n - 1)
</no>
</if>
</function>
x = factorial(170)
Epilogue
Well..I wish I could come up with a happy ending but there is none. Though Ellina wrote our first 'translator' which converted QBasic code to XCBL and Vivek came up with a totally different syntax,we soon abandoned the project for a variety of reasons. (I guess it took us a long time for us to come to our senses).
Recently, I tried using the VB Upgrade wizard, but I had abused Arrays and Redims and weird VarPtr code so much that I gave up doing a .NET port.
In a way, we were right about certain things
- The importance of multiple languages working together
- That declarative programming is the way to go for UI design.
I'm still left wanting a way of combining HTML-like syntax with easy GUI design. XAML *might* be the answer - only time will tell.
Do I regret all the work and the half-assed design? Absolutely not. For the first time, I wrote a lot of code (Over 5000 lines with over 3000 lines of comments :)). I learnt a lot and had tremendous fun. Seeing that factorial program run gave me such a high - something I'll never get out writing event handlers on ASP.NET pages.
And yes- I would probably do it differently if I could get a chance to do it again. Make that 'very differently' :).