Starting to write code in H2D2

So... my latest attempt at writing a programming language, which I'm currently caling H2D2 is taking shape. I can build loops, assign numeric variables and evaluate expressions. It is still only a subset of the syntax from my original DALIS language, but I am able to write some simple programs now. You know what's coming don't you...? Here's a little something that I've been working on, do you know what it is yet?

e=1.1
d=0
h=0
loop
  b=-2
  loop
    n=0
    r=0
    h=127
    loop
      r=r*r-n*n+b
      n=2*d*n+e
      d=r
      h=h-1
    repeat if ((r*r)+(n*n)<4) & h>32
    print h
    b=b+0.04
  repeat if b<1
  print 13
  e=e-0.1
repeat if e>-1.2

Yup, it's the famous ASCII mandelbrot. You'll also notice that I've switched to lower case for the keywords this time round. I got tired of feeling like I'm shouting when writing code. This version also uses '&' to mean 'logical and', instead of the actual word 'and'. This is the syntax tree that's created when I parse that code:

Well that's progress. It's not bad considering my C is still rusty, but it's coming back to me. I haven't timed anything yet, but it certainly feels faster, on my laptop this program draws the mandelbrot set in about one second I reckon. Of course, I can keep the syntax tree as a kind of compiled bytecode, meaning that the program can be run without the need for the parser, which would make it faster still.

More work on H2D2

Since I've been writing the parser for H2D2 - the continuation of my work on DALIS, I thought that it might be useful to see the syntax trees that are being generated. So I found a nifty tool called phpSyntaxTree which is a website that will draw a graphical version of a tree from bracketed notation.

So I added some code to H2D2 which will output the syntax tree created by the parser in bracketed notation, and now I can paste the resulting text into phpSyntaxTree and see what the results look like.

Whilst the H2D2 language doesn't have much of a syntax yet, I have been able to parse things like this example code:

an = 99
PRINT an
mynum = 88
PRINT mynum
PRINT 1 + 2*3
IF 1 PRINT 1 PRINT 0
PRINT (1+2)*3

That program tests the majority of things that I have written so far, simple things like branching, expression parsing and assigning numeric variables. This is how that program comes out:

You can see the difference between the two expressions, one with brackets and the other without, and when I run the program, the first result is 7 and the second result is 9, so it seems to be working fine. When H2D2 programs are executed I'm using a non-recursive algorithm, which means that the code can be frozen at any point and then resumed - even if the code was part way through evaluating an expression there's no problem in carrying on exactly where the code was paused. So far I've only tested all this in Pelles C on Windows, but I will put a quick makefile together soon so that I can compile it with GCC (on linux), I want to keep the C code for H2D2 as portable as I can. The next thing that I'm going to try and build is a loop, which is kinda important.

DALIS Reloaded: H2D2

I've recently been thinking that my DALIS programming language may have gone as far as I'm prepared to take it in its current incarnation. It was only supposed to be a proof of concept, so I probably went way past that stage some time ago. But some of the most recent features have been hard to implement because of decisions (and shortcuts) which I made at the start. Also, I've learned more about programming language implementation now, so I'd like to go back and change some things.

And since I've had the Raspberry Pi I've been reminded how much I really like programming in C, so I've decided that this time round I'll do the language in C and try to make it portable. I suppose there's an outside chance it may fit on a small microprocessor like one of the AVR ATMegas that I have lying around.

So... I've started again from scratch, bringing with me the things I learned from the DALIS proof of concept. This time round I'm not sure if I'll stick to the same syntax as the original DALIS or not. In my head the codename for this new language is H2D2.

Because the re-write is in C I'm hopeful that it will be easier to port and that it will be somewhat faster - even if speed isn't one of my main aims. At some point you *know* I'm going to render the Mandelbrot set as a benchmark don't you... be warned :-)

But many of the original ideas from DALIS are coming with me, programs should be able to be paused and resumed, and a paused program should be capable of being serialised before being restarted. This should allow me to continue running H2D2 programs on the cloud.

This time I'm going to generate syntax trees - my current thinking is that the source code can generate a syntax tree, and what I'm really building is a Virtual Machine which is capable of executing the syntax tree directly. The virtual machine can save the running state (the stack and the value of all variables) after any instruction which could become a resume point. The original DALIS didn't use syntax trees, it interpreted one line of source code at a time and used recursive functions to parse expressions. My new approach means that running a program won't need to keep parsing the source code, which will hopefully be more efficient.

So I've started all this from an empty project in the Pelles C IDE. I've not used any non-standard libraries, and I've written my own implementations of things like the stack and the tree traversal algorithm. So far I've implemented instructions like IF, ELSE, ADD, SUBTRACT, MULTIPLY, as well as something that will print an integer on the screen (which will eventually become PRINT or WRITE or whatever I call it). I can't assign variables yet though (but constant number values can be coded in the H2D2 source).

So currently I'm building the parser to see if I can construct the syntax trees from little bits of H2D2 source code. It's looking positive, I have some simple programs running, evaluating expressions and printing results, that type of thing. I've even been able to save a running program to disk and then resume the same program afterwards, which is cool.

The next big step has to be assigning variables because then I'll be able to try some more interesting stuff...