Skip to content

LLVM IR Emission(2): Statement and Declaration

In the previous blog LLVM IR Emission(1): Overall and Type Emission, we talks about the overall about llvm ir emission. In this blog, I will continue to introduce the code LLVM IR generation for the statement and declaration.

Statement

Empty Statement

For compiler, an empty statement doesn't make any sense, so it simply ignore empty statements.

Define a New Variable

Defining a variable requires three items:

  1. the variable identifier,tuple deconstructor or strcut deconstructor.
    let a: i16 = 1;
    let (a,b) = tuple_value;
    let Demo { a: i16, b: f16} = demo;
    
  2. the type of the variable(optional)
  3. the value expression(optional)

During emit, the compiler resolves the variable type first if user doesn't provide it. If it's unkonwn yet, it will be marked as Unknown type, but after the expression value is emitted, the compiler could resolve the variable type.

TODO: how the variable is added into the symbol table

Assign a Variable

The left part of an assignment statement might be a pointer or a value, so it requires two branches to handle them separatedly.

To assign a pointer, we need to emit the pointer first to get its type and value, then we need to emit the expression to get its value as well with type check to ensure the assignment correctness. Finally, we use try_load2var to operate the memory direct and the assignment has been done.

Then, the raw refers the assignment for deconstruction of tuple and structure, we can ignore it now.

Statements and Terminator

Statements holds a lot of statement together, it loops each field to emit the llvm ir until one of the statement is a terminator or all statements are done.

/// StatementsNode stands for several statements
pub struct StatementsNode {
    /// statements is a vector of all statements under a statement block
    /// the order is same of the code, from top to bottom
    pub statements: Vec<Box<NodeEnum>>,
}

Declaration in LLVM

Mentioned in Type Emission

The function, structure emissions are mentioned during the type generation, so we needn't introduce them now.

Impl Declaration

The implementation declaration are constitued by the following fields: generics, target structure(receiver), implemented functions and the implemented trait.

The differences between implementations and function are: - The implement has a target - The implement might have a triat to implement - The implement functions have self as the first arguments

Hence, during LLVM IR emission, we need to handle the additional cases.