December Adventure

The goal is to write a little piece of code every day in december. See here.

Mine is to experiment a way of representing trees that i learnt in this talk by Aaron Hsu : Dyalog '18: High-performance Tree Wrangling, the APL Way. The APL language is used in this video, but it is accessible even if you don't know it (which is my case, i only played a tiny little bit on tryapl.org). The key idea is to represent a tree as a 1-dimensional array of nodes, each node contains its data, and a reference to its parent (and eventually one to its left sibling).

At the end of the talk i was thinking "what about parsing ? it would be neat if we could do it the same say", and a couple of days ago, i've stumbled upon this talk, by Aaron Hsu again : Text Processing in APL // Aaron Hsu // Dyalog '22. It's very interesting and completely different from other parsing techniques. This section is my preferred part of the talk. He explains that no recursion is used : instead of a call stack, the AST being built is used as a "reified" stack, and it becomes also easy to do good error reporting. (mind blown). I've watched this section several times. Not sure i've understood everything yet.

I've tried a little bit in C, but for the December Adventure i'll give it a try with uxntal. I am not very good at uxntal, it will be an opportunity to get a little bit better. I really don't know what I am doing, but i think it will be fun.

The repository is here: https://github.com/max22-/dal

01/12 and 02/12

I've tried several times to write a little language inspired by Joy. I'll try to parse that :
[dup 0 = [1 drop] [dup 1 - fac *] ifte] ' fac def

So i've set up a uxntal skeleton. Hardcoded that line of code. The idea of the parsing technique of Aaron Hsu is that a string can be thought of a tree where each character is a tiny little branch (and then multiple passes refine the structure of the tree). Then i've implemented a function to add nodes to a tree, and another to transform a string into a tree. Tonight i've started writing another to display a node, which is not finished yet. Beetbug was very useful :)

03/12

Today i've implemented tree displaying (and corrected some bugs). I can now print a tree where the leaves can only be characters. Tomorrow i will maybe add other types like integers, etc. And i will generate a tree with a more complex structure to see if it displays correctly. I also have to find why there is a #02 remaining on the working stack at the end of the program...

04/12

Today I have hard-coded this to create an example tree:

        
#0000 .type/LIST #0000 ;tree1 add-node
#00 LIT "a .type/CHARACTER #0000 ;tree1 add-node
#00 LIT "b .type/CHARACTER #0000 ;tree1 add-node
#00 LIT "c .type/CHARACTER #0000 ;tree1 add-node
#0000 .type/LIST #0000 ;tree1 add-node
#00 LIT "d .type/CHARACTER #0004 ;tree1 add-node
#00 LIT "e .type/CHARACTER #0004 ;tree1 add-node
#00 LIT "f .type/CHARACTER #0004 ;tree1 add-node
#04d2 .type/INTEGER #0004 ;tree1 add-node
#162e .type/INTEGER #0000 ;tree1 add-node
;tree1 print-tree
        
        

The prototype of the add-node function is this :

@add-node ( data* type parent* tree* -: )

And the output of print-tree is this :

        
        
00010 nodes
LIST
    a
    b
    c
    LIST
        d
        e
        f
        01234
    05678
        
        
It took me quite some time because i've found some bugs in the code.

08/12

The last 3 days i didn't have much time to work on the december adventure. And i've been distracted by another project...

Today i've corrected a tiny bug i mentioned earlier : now the working stack is empty at the end of the program. (one of the functions was not balanced properly). I have also started to write a lexer, but it is not working yet and i have nothing to show for the moment.

09/12

Today i've done a lot of debugging. Now the lexer sort of works, but isn't completely complete :) It only handles brackets and integers, I need to add words tomorrow. But at least today i can show something :

10/12

I've finished the lexer (i've added 'word' lexing), and debugged it. It looks like it works ! Here is the output :

        
[dup 0 = [1 drop] [dup 1 - fac *] ifte] ' fac def
00049 nodes
LIST
    LEFT_BRACKET
    WORD
        d
        u
        p
    00000
    WORD
        =
    LEFT_BRACKET
    00001
    WORD
        d
        r
        o
        p
    RIGHT_BRACKET
    LEFT_BRACKET
    WORD
        d
        u
        p
    00001
    WORD
        -
    WORD
        f
        a
        c
    WORD
        *
    RIGHT_BRACKET
    WORD
        i
        f
        t
        e
    RIGHT_BRACKET
    WORD
        '
    WORD
        f
        a
        c
    WORD
        d
        e
        f
    EOF
Goodbye.
wst  00  00  00  00 [00] 01  0e  00  02 
rst  00  00  00  00 [00] 01  28  16  da
        
    
Nothing left on the stack, cool !