Building Common Lisp parser from example code

Hi. I’m working on expanding the sample language code to support Common Lisp. In CL most forms should indent like this:

(list 1 2 3
      4 5 6)

(+ 1 2
   (* 3 4 (min 5
      8 9))

To accomplish this, I’m using this code for indentation:

  Application: context =>
    + (context.node.firstChild && context.node.firstChild.nextSibling
       && context.node.firstChild.nextSibling.nextSibling
       ? -
       : 0)

It works correctly sometimes, as with the above cases. But there are problems in other cases:

(setf abc 1
        def 2)

Does anyone know what could cause this uneven spacing? For now my goal is to always align with the beginning of the second atom in a form. Later there will be some other cases.

I don’t see the problem, at a glance. But it seems like you could simplify that code a lot by directly using cx.column on the position of the child you’re interested in, rather than doing this adding and subtracting. Maybe that’ll help debug it.

Thanks, it turns out I was using the wrong .to somewhere in the arithmetic. The problem was with atoms of length > 1. For example:

(+ 10 20
    30 40)

Now I’m using this code:

Application: context =>
  context.node.firstChild && context.node.firstChild.nextSibling
  && context.node.firstChild.nextSibling.nextSibling
  && context.node.firstChild.nextSibling.nextSibling.nextSibling
  ? context.column(context.node.firstChild.nextSibling.nextSibling.from)
  : 1

It seems to work perfectly and supports the case of a newline right after the first atom:


Next, to support some of the language’s more complex indentation conventions, I’ll need to count siblings within a node. The way I do it above is rather unwieldy. Is there a way to look for something like nthChild(n) or do I just have to use a recursive function that grabs .nextSibling for n iterations? I can only see the childBefore and childAfter methods of the SyntaxNode class but they go by character position. Appreciate the help.

In most languages you can use getChild to get a specific child of a construct pretty well, but I guess CL is too regular for that to be much use. The library doesn’t provide an nthChild-like accessor, no.