chibicc - Simple c compiler if statement

Commit history for if statement feature

What is changed ?

For parser, new node type called ND_IF is introduced. Three new nodes are introduced for Node type in parser. They are called cond, then, els which corresponds to code in if(cond){ } else {}. New production rule is introduced to deal with if statement

// stmt = "return" expr ";" 
//        | "{" compound_stmt
//        | expr_stmt
//        | "if" "(" expr ")" stmt ("else" stmt)?
static Node* stmt(Token**rest, Token* tok) {
  if(equal(tok, "return")) {
    Node* node = new_unary(ND_RETURN, expr(&tok, tok->next));
    *rest = skip(tok, ";");
    return node;
  }

  if(equal(tok, "{")) {
    return compound_stmt(rest, tok->next);
  }

  if(equal(tok, "if")) {
    tok = skip(tok->next, "(");
    Node* node = new_node(ND_IF);
    node->cond = expr(&tok, tok);
    tok = skip(tok, ")");
    node->then = stmt(&tok, tok);
    if(equal(tok, "else")) {
      node->els = stmt(&tok, tok->next);
    }
    *rest = tok;
    return node;
  }

  return expr_stmt(rest, tok);
}

For code generator, assembly code generation for if condition is introduced in gen_stmt. First we generate assembly code for cond node, and then we generate je $0, %rax to check condtion of cond node, and call jump .L.else.%d to do them instruction jump, %d is used to uniquly identify each else block. Because multiple if statement can be nested at the same time.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Learning-based memory allocation for C++ server workloads summary
  • my question:
  • Binary search algorithm variant
  • Docker Rocksdb build
  • Difference between Dockerfile and Docker Compose