generator

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 31, 2024 License: GPL-3.0 Imports: 13 Imported by: 0

README

generator

Responsibilities

Given a compilation target, turn a well-formed FSPL semantic tree into an LLVM IR module tree.

Organization

Generator defines the Target type, which contains information about the system that the program is being compiled for. The native sub-package uses Go's conditional compilation directives to provide a default Target that matches the system the compiler has been natively built for.

The entry point for all logic defined in this package is Target.Generate(). This method creates a new generator, and uses it to recursively generate and return an LLVM module. The details of the generator are hidden from other packages, and instances of it only last for the duration of Target.Generate().

The generator contains a stack of blockManagers, which plays a similar role to analyzer.scopeContextManager, except that the stack of blockManagers is managed directly by the generator, which contains appropriate methods for pushing/popping them.

Like the analyzer, the generator greedily generates code, and one function may be generated in the middle of the generation process of another function. Thus, each blockManager is tied to a specific LLVM function, and is in charge of variables/stack allocations and to a degree, control flow flattening (specifically loops). It also embeds the current active block, allowing for generator routines to call its methods to add new instructions to the current block, and switch between different blocks when necessary.

Operation

When Target.Generate() is called, a new generator is created. It is given the semantic tree to generate, as well as a copy of the Target. All data structure initialization within the generator happens at this point.

Then, the generate() method on the newly created generator is called. This is the entry point for the actual generation logic. This routine is comprised of two phases:

  • Function generation
  • Method generation

You'll notice that there is no step for type generation. This is because types are generated on-demand in order to reduce IR clutter.

Expression Generation

Since expressions make up the bulk of FSPL, expression generation makes up the bulk of the code generator. The generator is able to produce expressions in one of three modes:

  • Location: The generator will return an IR register that contains a pointer to the result of the expression.
  • Value: The generator will return an IR register that directly contains the result of the expression.
  • Any: The generator will decide which of these two options is best for the specific expression, and will let the caller know which was chosen, in case it cares. Some expressions are better suited to returning a pointer, such as array subscripting or member access. Other expressions are better suited to returning a value, such as arithmetic operators and function calls.

It is important to note that generating a Value expression may return a pointer, because FSPL pointers are first-class values. The distinction between location and value generation modes is purely to do with LLVM. It is similar to the concept of location expressions within the analyzer, but not 100% identical all of the time.

Whenever an expression needs to be generated, one of the following routines is called:

  • generator.generateExpression()
  • generator.generateAny()
  • generator.generateVal()
  • generator.generateLoc()

The generator.generateExpression() routine takes in a mode value and depending on it, calls one of the other more specific routines. Each of these routines, in turn, calls a more specialized generation routine depending on the specific expression.

If it is specifically requested to generate a value for an expression with only its location component defined or vice versa, generator.generateVal/Loc() will automatically perform the conversion.

Documentation

Overview

Package generator implements the code generation stage of the FSPL compiler. It converts a well formed semantic tree into LLVM IR code, and outputs it to an io.Writer.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Target

type Target struct {
	// WordSize is the size of the machine word. This determines the width
	// of the Word type.
	WordSize uint64

	// Arch specifies the machine architecture. Values must correspond
	// directly to those recognized by LLVM in a target triple.
	Arch string

	// OS specifies the machine operating system. Values must correspond
	// directly to those recognized by LLVM in a target triple.
	OS string
}

Target contains information about the machine the code is being written for.

func (Target) Generate

func (this Target) Generate(tree analyzer.Tree) (*llvm.Module, error)

Generate takes in a semantic tree and writes corresponding LLVM IR to the given io.Writer. It returns an error in case there is something wrong with the semantic tree that prevents the code generation process from occurring.

Directories

Path Synopsis
Package native provides a generator target describing the current system.
Package native provides a generator target describing the current system.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL