- // Another pass to hook up the elsif/else chains.
- t = start;
- while(t) {
- if(t->type == TOK_IF) {
- while(t->next && t->next->type == TOK_ELSIF)
- addNewChild(t, t->next);
- if(t->next && t->next->type == TOK_ELSE)
- addNewChild(t, t->next);
+static struct Token* parseToken(struct Parser* p, struct Token** list)
+{
+ struct Token *t = *list;
+ *list = t->next;
+ if(t->next) t->next->prev = 0;
+ t->next = t->prev = 0;
+ p->errLine = t->line;
+
+ if(!t) return 0;
+ if(isOpenBrace(t->type)) {
+ parseBlock(p, t, endBrace(t->type), list);
+ } else if(isBlockoid(t->type)) {
+ /* Read an optional paren expression */
+ if(!*list) oops(p);
+ if((*list)->type == TOK_LPAR)
+ addChild(t, parseToken(p, list));
+
+ /* And the code block, which might be implicit/braceless */
+ if(!*list) oops(p);
+ if((*list)->type == TOK_LCURL) {
+ addChild(t, parseToken(p, list));
+ } else {
+ /* Context dependency: if we're reading a braceless block,
+ * and the first (!) token is itself a "blockoid"
+ * expression, it is parsed alone, otherwise, read to the
+ * terminating semicolon. */
+ struct Token *blk = newToken(p, TOK_LCURL);
+ if(isBlockoid((*list)->type)) addChild(blk, parseToken(p, list));
+ else parseBlock(p, blk, TOK_SEMI, list);
+ addChild(t, blk);