CompilerKit

View the Project on GitHub amyinorbit/CompilerKit

Semantics

The types documented on this page provide the tools needed to build the semantic analysis portion of your compiler: types, symbols and scopes, as well as a skeletton from which to derive your semantic analyser, Sema.

CompilerKit::Type

An enumerator that describes the type of a language object.

CompilerKit::Symbol

struct Symbol {
    Token token;
    Type type;
};

A small value type that represents a symbol in a symbol table. The available fields are:

CompilerKit::Scope

This class represents declaration scope in the parsed language. Unlike other classes in CompilerKit, instances of Scope are not created by calling the constructor. Instead, the static functions open() and close() are provided, and ensure that newly-created scopes are enclosed by older ones.

Instances of scope are used to declare symbols, and query already-declared symbols.

Static API

Scope::open() -> Scope*

Opens a new scope and returns it. If there is already an open scope, makes the new scope the current one and ensures that the previous scope encloses it.

Scope::close() -> void

Closes the current scope if there is one, and make the enclosing scope the currentone. Once a scope is closed, it cannot be recovered.

Scope::current() -> Scope*

Returns the deepest scope currently open, or nullptr if none is open.

Public API

define(const Token& token, Type type) -> bool

Defines a new symbol with a given token and type in the current scope. If no other symbol is defined in the current scope, or any of its enclosing ones, with the same name, returns true. Otherwise, defines nothing and returns false.

Parameters:

isDefined(const std::string& name) const -> bool

Returns whether the current scope, or any of its enclosing scopes, contains a symbol declared for the given name.

Parameters:

get(const std::string& name) const -> const Symbol*

Returns the symbol defined in the current scope or any of its enclosing scopes for a given name, or nullptr if the name doesn’t match any symbols.

Parameters:

CompilerKit::Sema

Sema is the class from which your semantic analyser will derive. It provides an API that can be used to emit various types of semantic errors.

Public API

Sema(Parser& parser)

Creates a new instance of Sema that uses the given parser to emit and record errors.

Parameters:

Protected API

semanticError(const Token& token, const std::string& message) -> void

Emits a generic semantic error at a token’s location.

Parameters:

binaryExprError(const Token& op, Type lhs, Type rhs) -> void

Emits a type mismatch error in a binary expression:

semantic error at 10:23: invalid operands to binary expression: ‘Integer’ + ‘Boolean’

Parameters:

booleanExprError(const Token& op, Type lhs, Type rhs) -> void

Emits a type mismatch error in a boolean expression.

semantic error at 10:23: invalid operands to boolean expression: ‘Integer’ < ‘Boolean’

Parameters:

assignmentError(const Token& var, Type lhs, Type rhs) -> void

Emits a type mismatch error in a variable assignment

semantic error at 10:23: assigning variable ‘abc’ of type ‘Integer’ from incompatible type ‘Boolean’

Parameters:

undeclaredError(const Token& var) -> void

Emits an undeclared-variable error.

use of undeclared variable ‘abc’

Parameters:

redeclaredError(const Token& var) -> void

Emits a variable re-declaration error.

redefinition of variable ‘abc’

Parameters: