module compiler.assembler
Idea for an assembler
class Tokenizer
pub fn set_line(line: str)
pub fn next_token() -> Token
class Token
pub fn to_string() -> str
enum TokenKind
Id(str)Number(int64)String(str)ColonCommaComment(str)End
module compiler.ast
pub struct NodeId
name: uint32id: int64
fn node_id_equal(node_id1: NodeId, node_id2: NodeId) -> bool
fn node_id_hash(a?: NodeId) -> uint32
pub struct DocString
A docstring (like this one 8-))
pub class Type
pub fn change_to(to_type: Type)
pub fn get_enum_variant_from_type(attr: uint32) -> Option
pub fn get_enum_variant_names() -> List[uint32]
pub fn is_class() -> bool
pub fn is_interface() -> bool
pub fn is_signed_int() -> bool
pub fn get_bits() -> int64
pub fn is_unreachable() -> bool
pub fn is_undefined() -> bool
pub fn is_float() -> bool
pub fn is_base_type() -> bool
pub fn is_opaque() -> bool
pub fn is_array() -> bool
pub fn get_element_type() -> Type
pub fn get_array_size() -> int64
pub fn is_struct() -> bool
pub fn is_union_struct() -> bool
pub fn has_field(attr: uint32) -> bool
pub fn get_field_type(attr: uint32) -> Type
pub fn maybe_get_field_type(attr: uint32, also_private: bool) -> Option
pub fn has_method(name?: uint32) -> bool
pub fn is_nullable() -> bool
pub fn is_function_type() -> bool
pub fn get_return_type() -> Type
pub fn get_except_type() -> Type
pub fn is_tycon_app() -> bool
pub fn get_tycon() -> TyCon
pub fn is_type_parameter() -> bool
pub fn is_type_var() -> bool
fn change_type_to(ty: Type, to_type: Type)
pub fn is_some_integer_type(ty?: Type) -> bool
pub fn get_bits_from_some_integer_type(ty?: Type) -> int64
pub fn deref_type_var(ty?: Type) -> Type
pub fn get_enum_variant(enum_def: EnumDef, attr: uint32) -> Option
pub fn get_struct_field_index(ty: Type, attr: uint32) -> int64
pub fn get_method_ref_from_type(ty: Type, attr: uint32, location: int64) -> Expression
enum BaseType
BoolInt(bool, int64)StrCharFloat(int64)
fn base_type_to_str(base: BaseType) -> str
pub fn tycon_equal(tycon1: TyCon, tycon2: TyCon) -> bool
pub class TypeContext
Global type context with all types.
pub fn get_type(index: int64) -> Type
pub fn undefined_type() -> Type
pub fn opaque_type() -> Type
Opaque type, void*
pub fn void_type() -> Type
pub fn bool_type() -> Type
pub fn int_type() -> Type
pub fn str_type() -> Type
pub fn float_type() -> Type
pub fn char_type() -> Type
pub fn unreachable_type() -> Type
pub fn specific_int_type(signed: bool, bits: int64) -> Type
pub fn uint8_type() -> Type
pub fn uint16_type() -> Type
pub fn uint32_type() -> Type
pub fn uint64_type() -> Type
pub fn int8_type() -> Type
pub fn int16_type() -> Type
pub fn int32_type() -> Type
pub fn int64_type() -> Type
pub fn specific_float_type(bits: int64) -> Type
pub fn float32_type() -> Type
pub fn float64_type() -> Type
pub fn undefined_type() -> Type
fn pointer_type(pointed_type: Type) -> Type
pub fn array_type(element_type: Type, size: int64) -> Type
pub fn new_empty_module(libname: Option, namespace: List[uint32], location: int64) -> ModuleDef
pub class Scope
pub fn define(is_pub: bool, name: uint32, kind: SymbolKind, location: int64)
pub fn is_empty() -> bool
pub fn is_defined(name: uint32) -> bool
pub fn lookup(name: uint32) -> Option
pub class Symbol
pub fn add_reference(location: int64)
Register a reference this symbol
pub fn get_references() -> int64
pub struct MacroDef
name: uint32location: int64
pub enum VariableDefValue
Intern(Option)Extern(str, bool)
pub fn new_type_parameter(name: uint32, id: int64, location: int64) -> TypeParameter
pub class StructBuilder
pub fn set_name(name: uint32)
pub fn set_id(id?: int64)
pub fn set_pub(is_pub?: bool)
pub fn set_is_union(is_union?: bool)
pub fn add_type_parameter(name: uint32, id: int64, location: int64) -> Type
pub fn add_field(name: uint32, ty: Type, location: int64)
pub fn parameter_def(name: uint32, id: int64, label_is_optional: bool, ty: Type, location: int64) -> ParameterDef
pub fn variable(name: uint32, id: int64, ty: Type, location: int64) -> Variable
pub class Statement
pub fn is_breakable() -> bool
Can we use break / continue within this statement?
pub fn last_is_expr() -> bool
Determine if the last statement is an expression
pub fn pass_statement(location: int64) -> Statement
pub fn break_statement(location: int64) -> Statement
pub fn continue_statement(location: int64) -> Statement
pub fn unreachable_statement(location: int64) -> Statement
pub class Expression
pub fn is_this(strtab: StringTable) -> bool
Check if the expression is a reference to the 'this' parameter
pub fn get_attr_typed(attr: uint32, location: int64) -> Expression
pub enum ExpressionKind
Call(FunctionCall)GetAttr(Expression, uint32)GetIndex(Expression, List[Expression])Binop(BinopExpression)Unop(UnaryOperator, Expression)NameRef(uint32)VariableRef(Variable)FunctionRef(FunctionDef, Vector[Type])ParameterRef(ParameterDef)LoadSymbol(Symbol)IntLiteral(int64)FloatLiteral(float64)StringLiteral(str)CharLiteral(char)BoolLiteral(bool)StructLiteral(Type, List[Expression])UnionLiteral(Type, uint32, Expression)ClassLiteral(Type, List[LabeledExpression])ArrayLiteral(List[Expression])ArrayLiteral2(Expression, Type)TypeCast(Type, Expression)Box(Expression)Unbox(Expression, Type)ToString(Expression)Typ(Type)Variant(Type, EnumVariant)EnumLiteral(Type, EnumVariant, List[Expression])Stmt(Statement)If(IfExpression)Null
pub enum BinaryOperator
AndOrLessLessEqualsGreaterGreaterEqualsEqualsNotEqualsBitAndBitXorBitOrShiftLeftShiftRightAddSubMulDivMod
pub enum UnaryOperator
NotMinus
pub struct Visitor[D]
data: Don_definition: fn (D, Definition, VisitPhase)on_type: fn (D, Type, VisitPhase)on_statement: fn (D, Statement, VisitPhase)on_expression: fn (D, Expression, VisitPhase)on_node: fn (D, VisitNode, VisitPhase)
pub enum VisitPhase
PreMidPost
module compiler.bc_to_sil
Transform BC into SIL
Features of this pass:
- Compile structured types into pointers with load/store operations
- Implement multiply and divide by either physical instructions or a function call to a library
pub struct SilGenOptions
Target specific options
has_div: boolhas_mul: boolhas_fpu: boolword_size: int64
struct StructLayout
Information how a structure is mapped into memory
class SilGen
fn calc_struct_layout(struct_def: Struct)
fn get_size_of(ty?: Type) -> int64
fn get_word_size() -> int64
fn get_ptr_type() -> Type
fn get_word_type() -> Type
fn get_int_type(bits: int64) -> Type
fn get_float_type(bits: int64) -> Type
fn make_label(x?: uint32) -> str
fn get_function_name(index: int64) -> str
fn call_rt_function_1(name: str, ty: Type, argument: Value)
fn call_rt_function(name: str, ty: Type, arguments: Vector[Value])
Invoke runtime helper function
fn load_int(value: int64) -> Value
fn new_block(name: str) -> Block
fn new_stack_slot(size: int64) -> Address
fn new_tmp_id() -> uint32
fn new_global(name?: str) -> Address
fn push_int(value?: int64)
fn set_current_block(block?: Block)
fn pack_f64(value: float64) -> Bytes
Place 64 bits float into 8 bytes
fn pack_f32(value: float32) -> Bytes
Place 32 bits float into 4 bytes
fn pack_i64(value: int64) -> Bytes
Place 64 bits integer into 8 bytes
fn pack_i32(value: int32) -> Bytes
Place 64 bits integer into 8 bytes
fn pack_i16(value: int16) -> Bytes
Place 64 bits integer into 8 bytes
fn pack_i8(value: int8) -> Bytes
Place 64 bits integer into 8 bytes
fn pack_u64(value: uint64) -> Bytes
Place 64 bits integer into 8 bytes
fn pack_u32(value: uint32) -> Bytes
Place 64 bits integer into 8 bytes
fn pack_u16(value: uint16) -> Bytes
Place 64 bits integer into 8 bytes
fn pack_u8(value: uint8) -> Bytes
Place 64 bits integer into 8 bytes
fn pack_str(text: str) -> Bytes
module compiler.c_gen
C code backend
Translate bytecode into C code.
pub fn gen_c_code(program: Program, output_filename: Option, create_header: bool)
fn is_heap(ty?: Type) -> bool
Test if type is heap like type
fn has_heap_field(struct_def: Struct) -> bool
class CGenerator
pub fn gen_program(program: Program)
fn gen_struct_def(struct_def: Struct)
fn gen_vm_value(ty: Type, value: Value) -> str
fn gen_function_decl(function: Function)
fn gen_to_opaque(ty3: Type)
fn gen_from_opaque(ty: Type)
fn get_function_callee(index: int64) -> str
fn gen_field_access(index: int64, field: TypedName)
fn gen_typed_name(ty: Type, name: str)
fn gen_typed_name_2(is_const: bool, ty: Type, name: str)
fn gen_label_str(index?: uint32)
fn gen_goto(label?: uint32)
fn new_local_var() -> str
fn new_named_local_var(name: str) -> str
module compiler.c_gen_v2
Generate C code directly from AST.
This is similar to the way python code is generated.
Alternative to c_gen module
class CGenerator2
fn gen_global_expression(expression?: Expression) -> str
fn gen_struct_decl(struct_def: StructDef) -> str
fn gen_struct_ctor_decl(struct_def: StructDef)
fn gen_typed_name(ty: Type, name: str)
fn gen_typed_name2(ty: Type, name: str) -> str
fn unwind_blocks(stop_on_loop: bool)
fn gen_unbox_value(to_type: Type)
fn new_var(name: str) -> str
module compiler.backend.codegen
Machine code generation.
class Codegen[C,V]
Machine independent code generator
module compiler.dwarf
DWARF debug info.
See also: www.dwarfstd.org
class DwarfWriter
pub fn write_abbrevs(abbrevs: List[Abbrev])
Write abbreviations to .debug_abbrev section
fn write_abbrev(abbrev: Abbrev)
pub fn write_string_table()
fn write_byte(value?: int64)
fn write_u16(value?: int64)
fn write_u32(value?: int64)
fn uleb128(value?: int64)
Encode as unsigend LEB128 in output
struct SubProgram
name: strline: int64column: int64begin: strend: str
module compiler.elf
ELF file format
pub fn section_header_type_to_string(t?: int64) -> str
pub fn program_header_flags_to_string(flags?: int64) -> str
pub fn program_header_type_to_string(t?: int64) -> str
pub fn flags_to_string(flags?: int64) -> str
pub fn write_elf(filename: Path, object: Object)
Write ELF file.
fn is_global_symbol(symbol: Symbol) -> bool
pub fn write_section_headers(writer: ElfWriter)
pub struct ElfHeader
e_type: int64e_machine: int64e_version: int64e_entry: int64e_phoff: int64e_shoff: int64e_flags: int64e_ehsize: int64e_phentsize: int64e_phnum: int64e_shentsize: int64e_shnum: int64e_shstrndx: int64
pub struct ProgramHeader
p_type: int64p_flags: int64p_offset: int64p_vaddr: int64p_paddr: int64p_filesz: int64p_memsz: int64p_align: int64
pub struct SectionHeader
sh_name: int64sh_type: int64sh_flags: int64sh_addr: int64sh_offset: int64sh_size: int64sh_link: int64sh_info: int64sh_addralign: int64sh_entsize: int64
struct SymbolTableEntry
st_name: int64st_value: int64st_size: int64st_info: int64st_other: int64st_shndx: int64
pub struct Error
message: str
pub class ElfReader
fn read_bytes(n: int64) -> Bytes
fn read_size_t() -> int64
pub class ElfWriter
pub fn set_bitsize(bits: int64)
pub fn get_section_index(name: str) -> int64
pub fn write_section_data(sh: SectionHeader, data: Bytes)
Write data, recording offset and size
pub fn write_bytes(data?: Bytes)
fn write_u8_array(buffer: [uint8], bufsize: int64)
fn write_array(value?: [int64], size: int64)
fn write32(value?: int64)
fn write16(value?: int64)
fn write64(value?: int64)
fn write_size_t(value?: int64)
pub class StringTable
pub fn add_name(name?: str) -> int64
pub fn get_name(index?: int64) -> str
pub fn get_data() -> Bytes
pub fn set_data(data: Bytes)
module compiler.hexfile
Implement INTEL HEX format.
See also: https://en.wikipedia.org/wiki/Intel_HEX
pub class HexFile
pub fn add_bytes(address: int64, data: Bytes)
fn add_record(address: int64, record: int64, data: Bytes)
fn hex_line_to_text(line: HexLine) -> str
module compiler.html
Module to create documentation from parsed code
class HtmlGenerator
pub fn gen_docstring(docstring?: Option)
fn gen_name(name?: uint32)
fn spanned(t?: str, cls: str)
module compiler.igraph
Interference graph.
typedef-LiveSet$2718:class(BitSet$72)
pub class IGNode
Node in the interference graph.
pub fn set_color(c?: int64)
pub fn is_colored() -> bool
pub fn to_string() -> str
pub class AdjecentIter
Dedicated iterator over adjecent nodes
module compiler.ir_gen
generate bytecode
struct Loop
continue_label: uint32break_label: uint32
struct Try
except_label: uint32except_var_index: int64
class BytecodeGenerator
fn gen_global_variable(variable_def: VariableDef)
Create global variable
fn gen_global_init(variable_def: VariableDef)
Initialize global variable
fn goto_inner_loop() -> Loop
fn gen_return(opt_val: Option)
fn actual_do_raise()
Do local jump, or return special marker value, which lives on top of stack now.
fn gen_condition(condition: Expression, true_label: uint32, false_label: uint32)
fn jump_if_true(true_label: uint32, false_label: uint32)
fn set_label(label?: uint32)
fn translate_label(label?: uint32) -> uint32
fn add_local(variable: Variable, writable: bool) -> int64
fn new_local(name: str, ty: Type, writable: bool) -> int64
fn is_local_variable(variable: Variable) -> bool
fn get_local_index(variable: Variable) -> int64
fn get_global_index(variable: Variable) -> int64
fn get_parameter_index(parameter_def: ParameterDef) -> int64
fn get_name(id?: NodeId) -> str
fn get_attr_index(ty: Type, attr: uint32) -> int64
module compiler.isel
Instruction selection related code.
pub struct Backend[C,V]
Backend based on first instruction selection, then register allocation.
ctx: Cbits: int64all_regs: Vector[Vector[int64]]enter: fn (C, SelectionContext[V], Function)selector: fn (C, SelectionContext[V], Instruction)to_str: fn (V) -> strmaterializer: fn (SelectionContext[V], Instruction[V], BinaryOutput)emit_prologue: fn (Frame, BinaryOutput)emit_epilogue: fn (Frame, BinaryOutput)fixer: fn (ByteArray, int64, int64, int64, int64)is_pic_reloc: fn (int64) -> boolemit_data: fn (DataItem, BinaryOutput)
pub class SelectionContext[V]
pub fn get_pre_colored(color: int64, kind: int64) -> Register
pub fn emit(instruction?: V)
fn emit_full(instruction?: V)
pub fn new_vreg(kind: int64, color: int64) -> Register
module compiler.mil
Machine intermediate language.
Machine instructions are selected in this representation.
pub struct Block[X]
Basic block
pub struct Register
id: uint32kind: int64color: int64
pub fn dump_mfunc[V](report: Report, mfunc: Function, to_str: fn (V) -> str)
module compiler.opt
Optimize SIL program.
pub fn optimize_sil(program: Program, level: int64)
fn optimize_function(function: Function)
pub fn skip_jump_blocks(function: Function) -> bool
If a block contains a single jump, we can bypass that block.
We can rewrite this:
jmp foo
...
foo:
jmp bar
...
bar:
To this:
jmp bar
...
bar:
fn block_fusion(function: Function, m: HashMap[str,Block]) -> bool
Combine blocks, if possible.
Criteria:
- block B must have only a single predecessor: block A
fn inc_pred(pred_count: HashMap[str,int64], target: str)
module compiler.outstream
Logic for binary object code.
Use the Outstream to contrapt an Object struct, with code and data section.
pub struct Relocation
symbol: stroffset: int64typ: int64addend: int64
fn make_section(name: str) -> Section
struct Fixup
symbol: strsection: Sectionoffset: int64typ: int64addend: int64
pub class BinaryOutput
pub fn set_bitsize(bits: int64)
pub fn select_section(name: str)
fn get_current_section() -> Section
pub fn import_symbol(name?: str)
Define symbol which lives externally
pub fn export_symbol(name?: str)
Define symbol, which can be used elsewhere
pub fn local_symbol(name?: str)
pub fn define_label(name?: str)
fn define(name: str, global: bool)
Define a symbol at the current cursor
pub fn is_extern_symbol(name: str) -> bool
pub fn add_fixup(symbol: str, typ: int64, addend: int64)
Add relocation information at the current position.
pub fn do_fixups(fixer: fn (ByteArray, int64, int64, int64, int64), is_pic_reloc: fn (int64) -> bool)
pub fn write_byte(value?: int64)
pub fn write_bytes(data: Bytes)
pub fn write_u32_le(value?: int64)
pub fn write_u64_le(value?: int64)
pub fn get_offset() -> int64
pub fn write_bytes_at(data: Bytes, offset: int64)
pub fn get_section(name: str) -> Section
pub enum DataItem
Raw(Bytes)AbsPointer64(str)RelPointer32(str, int64)
module compiler.pygenerator
Generate python code from AST.
class PyGenerator
fn gen_definition_variables(definition: Definition)
fn gen_expression(expression?: Expression, parens: bool) -> str
fn name_ref(name?: uint32) -> str
fn wrap_int(value: str, ty: Type) -> str
fn binary_operator_to_str(op: BinaryOperator, float_division: bool) -> str
pub fn escape_string(text?: str) -> str
Prefix double quotes and backslashes with an extra backslash
pub fn needs_escaping(c: char) -> bool
pub fn escape_char(c: char) -> str
module compiler.register_allocation
Register allocation
This function is machine independant.
It assigns colors to use / def registers.
class RegisterAllocator[C,V]
Perform graph coloring
Take out nodes that can be colored
When the graph is empty, place the nodes back in reverse order,
and assign them a color
fn spill(mfunc: Function)
Spill nodes with too many edges into memory locations.
fn rewrite_program(mfunc: Function, register: Register)
Introduce load before each use and store each definition
fn assign_colors()
Assign colors
fn is_colorable(m?: IGNode) -> bool
fn calculate_num_blocked(m?: IGNode) -> int64
fn q(B: int64, C: int64) -> int64
Number of registers from class B that can be block by a register in class C.
fn is_move_related(m?: IGNode) -> bool
module compiler.report
Internal reporting.
Useful for debugging the compilation stages.
pub class Report
pub fn set_enabled(v?: bool)
pub fn is_enabled() -> bool
pub fn heading(text?: str)
pub fn writeln(text?: str)
module compiler.riscv
RISCV encoding.
There are a couple of formats:
R/I/S/U
Register conventions:
register | name | saver | description
x0 | zero | - | zero constant
x1 | ra | callee | return address
x2 | sp | callee | stack pointer
x3 | gp | - | global pointer
x4 | tp | - | thread pointer
x5-x7 | t0-t2 | caller | temporaries
x8 | s0/fp | callee | saved / frame pointer
x9 | s1 | callee | saved register
x10-x11 | a0-a1 | caller | function arguments / return values
x12-x17 | a2-a7 | caller | function arguments
x18-x27 | s2-s11| callee | Saved registers
x28-x31 | t3-t6 | caller | temporaries
fn encode_R_type(funct7: int64, rs2: int64, rs1: int64, funct3: int64, rd: int64, opcode: int64) -> int64
fn encode_I_type(imm: int64, rs1: int64, funct3: int64, rd: int64, opcode: int64) -> int64
fn encode_S_type(imm: int64, rs2: int64, rs1: int64, funct3: int64, opcode: int64) -> int64
fn encode_U_type(imm: int64, rd: int64, opcode: int64) -> int64
fn encode_J_type(imm: int64, rd: int64, opcode: int64) -> int64
fn encode_B_type(imm: int64, rs2: int64, rs1: int64, funct3: int64, opcode: int64) -> int64
pub enum Instruction
LUI(int64, int64)AUIPC(int64, int64)JAL(int64, int64)JALR(int64, int64, int64)Branch(Cond, int64, int64, str)Load(LoadOp, int64, int64, int64)Store(StoreOp, int64, int64, int64)RegImm(ImmOp, int64, int64, int64)SLLI(int64, int64, int64)SRLI(int64, int64, int64)SRAI(int64, int64, int64)ThreeRegsOp(RegOp, int64, int64, int64)ECALLEBREAKLA(int64, str)LI(int64, int64)MOV(int64, int64)J(str)CALL(str)RET
pub enum Cond
EQNELTGELTUGEU
pub enum LoadOp
LBLHLWLBULHU
pub enum ImmOp
ADDISLTISLTIUXORIORIANDI
pub enum RegOp
ADDSUBSLLSLTSLTUXORSRLSRAORAND
fn cond_code(cond: Cond) -> int64
fn imm_op_code(op: ImmOp) -> int64
fn reg_op_code(op: RegOp) -> int64
fn load_op_code(op: LoadOp) -> int64
fn store_op_code(op: StoreOp) -> int64
pub fn instruction_to_string(instruction: Instruction) -> str
pub fn cond_to_string(cond: Cond) -> str
pub fn imm_op_to_string(op: ImmOp) -> str
pub fn reg_op_to_string(op: RegOp) -> str
pub fn load_op_to_string(op: LoadOp) -> str
pub fn store_op_to_string(op: StoreOp) -> str
fn reg_to_string(reg?: int64) -> str
pub enum Relocation
Abs64(str)
pub fn is_pic_reloc(typ: int64) -> bool
Check if the relocation type is position independant
pub fn apply_reloc(data: ByteArray, offset: int64, typ: int64, addend: int64, symbol: int64)
fn read_int_at(data: ByteArray, offset: int64) -> int64
fn write_int_at(data: ByteArray, offset: int64, value: int64)
module compiler.riscv_gen
Generate riscv code
Register usage convention: (saver)
x0 -> zero -> hardwired 0
x1 -> ra -> return address (caller)
x2 -> sp -> stack pointer (caller)
x3 -> gp -> global pointer
x4 -> tp -> thread pointer
x5-x7 -> temporaries (caller)
x8
x9
x18-x27 -> s2-11 -> saved registers (callee)
x28-31 -> t3-6 -> temporaries (caller)
Pseudo instructions:
NOP > ADDI x0, x0, 0
RET > JALR x0, 0(ra)
J offset > JAL x0, offset
MV rd, rs > ADDI rd, rs, 0
enum VirtInst
JalExitBranch(Cond, Register, Register, str)Mov(Register, Register)LoadImmediate(Register, int64)LoadAddress(Register, str)RegRegImm(ImmOp, Register, Register, int64)RegRegReg(RegOp, Register, Register, Register)Load(LoadOp, Register, Address)Store(StoreOp, Register, Address)Actual(Instruction)
fn addr_to_str(addr: Address) -> str
module compiler.sil
SIL (slang intermediate language)
An intermediate language for an abstract register based machine.
Properties:
- SSA (static single assignment)
- Closer to hardware, but still abstract (infinite registers)
- Basic operators
- basic types, integers and floating points
- Load and store from memory
Optimizers might operate on SIL
SSA IL
Similar to QBE IL
See: https://c9x.me/compile/doc/il.html
pub class Function
A graph of control flow between blocks
pub fn to_string() -> str
pub class Block
A linear flow of instructions
pub fn to_string() -> str
pub enum OpCode
Const(Value, int64)Binop(Value, BinaryOp, Value, Value)Bitop(Value, BitwiseOp, Value, Value)GetAddress(Value, Address)Load(Value, Address)Store(Address, Value)Convert(bool, Value, Value)Jump(str)JumpIf(Value, CompOp, Value, str, str)Call(Option, Address, Vector[Value])Return(Option)Halt
pub fn is_terminating_op(op: OpCode) -> bool
pub enum BinaryOp
AddSubMulDivMod
pub enum BitwiseOp
AndOrXorShlShrSar
pub enum CompOp
EqNeqGtLtGteLte
fn comparison_to_string(op?: CompOp) -> str
pub enum Type
F64F32I64I32I16I8
pub fn type_to_string(ty?: Type) -> str
pub enum Address
Global(str, bool)StackSlot(int64)Ptr(Value)
pub fn value_to_string(value?: Value) -> str
pub fn address_to_string(address?: Address) -> str
pub fn print_sil_program_to_file(program: Program, filename: Option)
module compiler.slang_gen
Slang backend
Idea: This backend emits slang code, sort of a no-op operation?
Also useful for debugging transformed code
module compiler.text_gen
Helper class to emit text code
module compiler.wasm_gen
WebAssembly backend
===================
Generate WebAssembly from AST.
WASM 3.0:
- strings are javascript strings via (ref extern)
- opaque pointers are (ref any)
- structs are mapped to GC structs
WASM 1.0:
- Pointers are mapped to i32 type
- floats are mapped to f64
- ints are mapped to i64
- linear memory is imported from javascript side
class WasmGenerator
fn add_num_box_type(num_type?: NumType) -> int64
fn get_struct_def_index(struct_def: StructDef) -> int64
fn get_array_type_index(element_type: Type) -> int64
fn reg_signature(parameter_types: Vector[Type], return_type: Type) -> int64
fn gen_condition(expression?: Expression)
Generate condition, keeping track of short circuit logic.
fn unbox_value(to_type: Type)
fn gen_type_cast(from_type: Type, to_type: Type)
fn get_local_index(id: NodeId) -> int64
fn create_parameter(id: NodeId, ty: Type) -> int64
fn create_anonymous_local(ty: Type) -> int64
fn enter_block(is_loop: bool)
module compiler.x86
X86 instruction set
Calling conventions 64 bit / system V ABI
arguments: rdi, rsi, rdx, rcx, r8, r9
return value: rax
callee save: rbx, rsp, rbp, r12, r13, r14, r15
caller save: the other registers
SSE (linux/mac/unix):
arguments: xmm0 .. xmm7
return value: xmm0
callee save: -
caller save: xmm0 .. xmm15
pub enum Instruction
OpRmReg(BitMode, Op, Rm, int64)OpRegRm(BitMode, Op, int64, Rm)MulRegRm(int64, Rm)CqoDivMul(DivMulOp, Rm)Call(str)CallRm(Rm)Jmp(str)Jcc(Cond, str)AddRmImm(Rm, int64)SubRmImm(Rm, int64)ShiftRmCl(ShiftOp, Rm)Lea(int64, Rm)MovRegImm64(int64, int64)MovRegImm32(int64, int64)Push(int64)Pop(int64)RetInt3Movsx8(BitMode, int64, Rm)Movsx16(BitMode, int64, Rm)Movsxd(int64, Rm)Movzx8(BitMode, int64, Rm)Movzx16(BitMode, int64, Rm)CvtSi2Sx(BitMode, SseMode, int64, Rm)CvtSx2Si(bool, SseMode, BitMode, int64, Rm)CvtSd2Ss(int64, Rm)CvtSs2Sd(int64, Rm)Ucomisd(int64, Rm)SseOpRegRm(SseMode, SseOp, int64, Rm)SseMovRegRm(SseMode, int64, Rm)SseMovRmReg(SseMode, Rm, int64)
pub enum Op
AddSubAdcSbbCmpAndOrXorMov
pub enum Cond
JbJaeJzJnzJbeJaJlJgeJleJg
pub enum SseOp
AddMulSubMinDivMax
pub enum DivMulOp
MulIMulDivIDiv
pub enum ShiftOp
RolRorRclRcrShlShrSar
pub enum BitMode
R8R16R32R64
pub enum SseMode
SingleDouble
pub enum Rm
Mem(int64)MemDisp8(int64, int64)MemDisp32(int64, int64)RipDisp32(str, bool)Reg(int64)
pub fn instruction_to_string(instruction: Instruction) -> str
pub fn div_mul_op_to_str(op: DivMulOp) -> str
pub fn sse_mode_to_str(sse_mode: SseMode) -> str
fn sse_op_to_str(op: SseOp) -> str
pub fn op_to_str(op: Op) -> str
fn cc_to_string(condition: Cond) -> str
pub fn shift_op_to_string(op: ShiftOp) -> str
fn rm_reg_to_str(mnemonic?: str, rm: Rm, reg: int64) -> str
fn reg_rm_to_str(mnemonic?: str, reg: int64, rm: Rm) -> str
fn rm_imm_to_str(opcode?: str, rm: Rm, imm: int64) -> str
fn rm_to_str(rm: Rm) -> str
fn reg64_to_str(reg: int64) -> str
fn reg_to_str(reg: int64) -> str
fn reg16_to_str(reg: int64) -> str
fn reg8_to_str(reg: int64) -> str
enum X86RelocationType
R_NONER_64(str, int64)R_PC32(str, int64)
fn write_mod_rm_byte(mod: int64, rm: int64, reg: int64, out: BinaryOutput)
fn get_sse_opcode(op: SseOp) -> int64
fn get_opcode(mode: BitMode, op: Op) -> int64
fn get_cc_code(condition: Cond) -> int64
fn get_shift_code(op: ShiftOp) -> int64
pub fn is_pic_reloc(typ: int64) -> bool
pub fn apply_reloc(data: ByteArray, offset: int64, typ: int64, addend: int64, symbol: int64)
module compiler.x86_gen
X86 backend
pub enum VirtInst
EntryRmReg(BitMode, Op, VirtRm, Register)RegRm(BitMode, Op, Register, VirtRm)MulRegRm(Register, VirtRm)DivMul(DivMulOp, VirtRm)Mov(BitMode, Register, Register)MovImm(Register, int64)Lea(Register, VirtRm)ShiftRmReg(ShiftOp, VirtRm, Register)Push(Register)Pop(Register)CallRm(VirtRm)Movsx8(BitMode, Register, VirtRm)Movsx16(BitMode, Register, VirtRm)Movsxd(Register, VirtRm)Movzx8(BitMode, Register, VirtRm)Movzx16(BitMode, Register, VirtRm)CvtSi2Sx(BitMode, SseMode, Register, VirtRm)CvtSx2Si(bool, SseMode, BitMode, Register, VirtRm)CvtSs2Sd(Register, VirtRm)CvtSd2Ss(Register, VirtRm)Ucomisd(Register, VirtRm)SseMov(SseMode, Register, Register)SseOpRegRm(SseMode, SseOp, Register, VirtRm)SseMovRegRm(SseMode, Register, VirtRm)SseMovRmReg(SseMode, VirtRm, Register)Actual(Instruction)Exit
fn vrm_to_str(vrm?: VirtRm) -> str
fn stack_round_up16(value?: int64, taken: int64) -> int64
Given the fact that we already took 'taken' bytes, round value to a multiple of 16 bytes.
fn mat_rm(rm: VirtRm) -> Rm
Materialize a Rm
module compiler.basepass
module compiler.bc
pub struct Local
ty: Typename: strwritable: bool
pub fn get_element_type_from_type(ty?: Type) -> Type
pub enum Instruction
NopDupSwapLiteral(LiteralValue)NotNegBinop(BinaryOperator, Type)Bitop(BitOperator, Type)IntCast(bool, int64)FloatCast(int64)IntToFloat(int64)FloatToInt(bool, int64)ToOpaque(Type)FromOpaque(Type)Jump(uint32)JumpIf(ComparisonOperator, uint32, uint32)Call(int64)CallIndirect(Vector[TypedName], Vector[Type])Return(int64)DecRef(int64)UnreachableLocalGet(int64)LocalSet(int64)ParameterGet(int64)ParameterSet(int64)GetAttr(int64)SetAttr(int64)GetIndexSetIndexGlobalGet(int64)GlobalSet(int64)LoadFunc(int64)StructLiteral(int64)ArrayLiteral(Type)
pub fn get_target_labels(instructions: Vector[Instruction]) -> Set[uint32]
Get a set of labels to which is being jumped
pub enum LiteralValue
Int(int64)Str(str)Float(float64)Bool(bool)Char(char)Null
pub enum BinaryOperator
AddSubDivideModuloMultiply
pub enum ComparisonOperator
LessLessEqualsGreaterGreaterEqualsEqualsNotEquals
pub enum BitOperator
ShrShlXorAndOr
pub fn instruction_to_string(instruction?: Instruction) -> str
pub fn print_bc_program_to_file(program: Program, filename: Option)
pub fn print_bc_program(program: Program)
pub fn type_to_string(ty?: Type) -> str
module compiler.builtins
module compiler.dbginfo
pub class DbgInfo
pub fn add_source(filename: Path, code: str)
pub fn add_function(name: str, filename: Path, location: int64)
pub fn has_function(name: str) -> bool
pub fn get_function_by_name(name: str) -> Function
pub struct Function
name: strlocation: int64source: Sourcestart_label: strend_label: str
module compiler.driver
Main compilation driver.
pub struct CompilationOptions
dump_ast: boolbackend: Backendadd_imports: List[Path]output_filename: Optiongen_export: Optionverbosity: int64optimization_level: int64check_unused_symbols: boolrun_code: booltime_trace: boolreport: booldebug: bool
pub enum Backend
BytecodeCC2PythonSlangWebAssembly(bool)NullSilRiscvX86Html
class Builder
pub fn do_transform() except CompilationError
Perform type checking and transformation on the added modules
pub fn get_sil_program(bits: int64) -> Program
module compiler.errors
enum Severity
ErrorWarning
pub class ErrorCollector
pub fn enter_file(filename: Option)
pub fn add_error(location: int64, message: str)
pub fn add_warning(location: int64, message: str)
fn count_leading_tabs(text: str) -> int64
module compiler.escape_analysis
Analyze variables, and mark variables that escape
fn mark_escaping_vars(value?: Expression)
This expression escapes
module compiler.namebinding
class NameBinder
Helper class to fill scopes, and resolve names from scopes.
pub fn define_variable(is_pub: bool, variable: Variable)
pub fn register_module_into_namespace(module_def: ModuleDef)
Register module into the namespace hierarchy
pub fn define(is_pub: bool, name: uint32, kind: SymbolKind, location: int64)
pub fn enter_scope(scope: Scope)
pub fn add_error(location: int64, message: str)
pub fn add_warning(location: int64, message: str)
module compiler.parsing.lexer
Turn source text into a sequence of tokens
enum LexerMode
NormalString
pub class Lexer
pub fn next_token() -> Token
fn on_newline(tok: Token)
fn emit_token(kind: TokenKind, location: int64)
fn next_token2() -> Token
fn parse_doc_string() -> TokenKind
Parse a doc string, like this one :)
fn parse_exponent(base: int64, exponent: int64, is_hex: bool) -> TokenKind
Parse the exponent notation after the 'e'
fn create_float(base: int64, exponent: int64) -> TokenKind
fn create_hex_float(base: int64, exponent: int64) -> TokenKind
fn peek_n(n: int64) -> char
fn match(txt?: char) -> bool
fn fill_keyword_dictionary()
fn is_id(c: char) -> bool
fn is_id_or_digit(c: char) -> bool
module compiler.location
typedef-Location$6363:Int64
pub fn new_location(begin: int64, end: int64) -> int64
pub fn location_default() -> int64
pub fn get_begin(x?: int64) -> int64
pub fn get_end(x?: int64) -> int64
pub fn merge_locations(begin: int64, end: int64) -> int64
pub fn location_at(offset: int64) -> int64
pub struct Position
row: int64column: int64
pub fn offset_to_position(offset: int64, code: str) -> Position
Calculate row and column from offset in string.
module compiler.parsing.parsing
Recursive descent slang-lang parser.
class Parser
An attempt at a recursive descent parser.
fn has_parsed_question() -> bool
fn parse_function_type() -> Type except ParseError
Parse function signature.
fn parse_big_expression() -> Expression except ParseError
A potentially big multi-line expression occurring at the end of the line.
fn parse_raw_string() -> str except ParseError
Parse string without interpolation
fn parse_string(location: int64) -> Expression except ParseError
Parse possibly interpolated string.
fn try_parse_dedent() -> bool
module compiler.parsing.token
pub fn default_token() -> Token
pub enum TokenKind
Identifier(uint32)KwAndKwBreakKwCaseKwClassKwContinueKwElseKwElifKwEnumKwExceptKwExternKwFnKwForKwFromKwIfKwImportKwImplKwInKwInterfaceKwLetKwLoopKwMacroKwModuleKwNotKwOrKwPassKwPubKwRaiseKwReturnKwStructKwSwitchKwTryKwTypeKwVarKwWhileKwUnreachableKwBoxKwUnboxKwNullFloat(float64, str)Integer(int64, str)Char(char)EscapedChar(char, CharEscapeMode, str)Bool(bool)StringStartStringContent(str)StringEndDocString(List[str])ColonCommaDotArrowQuestionParenthesisOpenParenthesisCloseBracketOpenBracketCloseBraceOpenBraceCloseEqualsBraceClose(str)PlusMinusSlashPercentAsterixLessGreaterLessEqualsGreaterEqualsEqualsEqualsEqualsShiftRightShiftLeftBitOrBitAndBitXorNotEqualsPlusEqualsMinusEqualsAsterixEqualsSlashEqualsSpace(uint32)Tab(uint32)NewLineComment(str)TabbedComment(uint32, str)IndentDedentEofNoneError(str)
pub enum CharEscapeMode
SimpleOctalHex
pub fn token_to_string(strtab: StringTable, tok: Token) -> str
Convert token to txt
module compiler.pass3
This pass runs after names have been resolved, and before types can be checked.
class NewOp
pub fn add_error(location: int64, message: str)
pub fn turn_tycon_to_type(tycon: TyCon) -> Type
module compiler.string_table
pub class StringTable
String table used for string interning
pub fn intern(name?: str) -> uint32
Perform string interning on identifier
pub fn get(index?: uint32) -> str
module compiler.transforms
Available transformations:
- Turn for-loops into while-loops
- Turn classes into structs with functions
- Turn enums into tagged unions
- Turn switch-statement into chain of if-statements
Ideas for transformations:
- Transform try/except into something else
class ClassRewriter
pub fn rewrite_class_def(class_def: ClassDef)
pub fn prefix_name(prefix: str, name: uint32) -> uint32
fn get_unique_id() -> int64
fn new_variable(name: str, ty: Type, location: int64) -> Variable
pub fn load_std_function(name: str, location: int64) -> Expression
fn load_rt_symbol(name: str) -> Symbol
fn create_invoker_helper(this_ty: Type, function_def: FunctionDef) -> FunctionDef
Create a function that takes a vtable/data pair, which calls the proper function.
pub fn rewrite_impl_def(impl_def: ImplDef)
Create a global variable initialized with a vtable.
Move implementing function to toplevel
pub fn rewrite_cast_to_interface(value: Expression, ty: Type) -> Expression
Turn cast to interface into struct literal with data + vtable
pub fn transform_for_loop(for_statement: ForStatement, location: int64) -> Statement
Turn for loop into iterator and while loop
pub fn rewrite_enum_def(enum_def: EnumDef)
pub fn transform_case(case_statement: CaseStatement) -> Statement
Transform case statement into switch case over tag values.
fn needs_opaque_cast(ty?: Type) -> bool
module compiler.typechecking
Type checking logic.
class TypeChecker
pub fn check_statement_mid(statement: Statement)
fn check_may_raise_exception(ty: Type, location: int64)
fn check_type(given_ty: Type, expected_ty: Type, location: int64)
fn add_error(location: int64, message: str)
fn add_warning(location: int64, message: str)
module compiler.typedb
Functions to serialize type definitions to JSON.
class SymbolSaver
fn save_type_def(type_def: TypeDef)
fn save_enum_def(enum_def: EnumDef)
fn save_impl_def(impl_def: ImplDef)
fn save_doc_string(docstring: Option)
fn save_type_if_non_void(attr: str, ty: Type)
fn save_type(attr: str, ty: Type)
fn save_tycon(tycon: TyCon)
fn save_name_list(attr: str, values?: List[uint32])
fn save_string_list(attr: str, values?: List[str])
class SymbolLoader
fn load_variable_def(def_name: uint32, def_id: int64) -> VariableDef
fn load_function(def_name: uint32, def_id: int64) -> FunctionDef
fn load_struct_def(def_name: uint32, def_id: int64) -> StructDef
fn load_type_def(def_name: uint32, def_id: int64) -> TypeDef
fn load_enum_def(def_name: uint32, def_id: int64) -> EnumDef
fn load_class_def(def_name: uint32, def_id: int64) -> ClassDef
fn load_docstring() -> Option
Load optional docstring
fn load_type_or_void(attr: str) -> Type
Load type from attribute, or void, if attribute is absent
fn load_type(attr: str) -> Type
fn load_name_list(attr: str) -> List[uint32]
fn load_string_list(attr: str) -> List[str]
module compiler.vm
Virtual machine for bytecode.
pub enum Value
Int64(int64)Int32(int32)Int16(int16)Int8(int8)Uint64(uint64)Uint32(uint32)Uint16(uint16)Uint8(uint8)Str(str)Char(char)Float(float64)Bool(bool)List(ListValue)NullUndefined
pub fn value_to_string(value?: Value) -> str
fn bool_from_value(value?: Value) -> bool
fn str_from_value(value?: Value) -> str
fn int64_from_value(value?: Value) -> int64
fn int32_from_value(value?: Value) -> int32
fn uint64_from_value(value?: Value) -> uint64
fn uint32_from_value(value?: Value) -> uint32
fn char_from_value(value?: Value) -> char
fn float_from_value(value?: Value) -> float64
pub fn run_bytecode(program: Program, entry_function: str)
pub class VirtualMachine
fn push_empty_list(count: int64)
fn get_local(index: int64) -> Value
fn set_local(index: int64, value: Value)
fn get_parameter(index: int64) -> Value
fn set_parameter(index: int64, value: Value)
fn get_global(index: int64) -> Value
fn set_global(index: int64, value: Value)
pub fn pop_frame() -> Frame
pub fn push_frame(frame: Frame)
fn eval_binop_int64(op: BinaryOperator, lhs: int64, rhs: int64) -> int64
fn eval_binop_int32(op: BinaryOperator, lhs: int32, rhs: int32) -> int32
fn eval_binop_uint64(op: BinaryOperator, lhs: uint64, rhs: uint64) -> uint64
fn eval_binop_uint32(op: BinaryOperator, lhs: uint32, rhs: uint32) -> uint32
fn eval_binop_float(op: BinaryOperator, lhs: float64, rhs: float64) -> float64
fn eval_bitop_int64(op: BitOperator, lhs: int64, rhs: int64) -> int64
fn eval_bitop_int32(op: BitOperator, lhs: int32, rhs: int32) -> int32
fn eval_bitop_uint64(op: BitOperator, lhs: uint64, rhs: uint64) -> uint64
fn eval_bitop_uint32(op: BitOperator, lhs: uint32, rhs: uint32) -> uint32
module compiler.webassembly
WebAssembly
===========
WebAssembly support.
pub enum NumType
i32i64f32f64
pub fn ref_extern_type() -> RefType
pub enum HeapType
Anyi31FuncExternTypeIdx(int64)
fn value_type_to_string(ty?: ValueType) -> str
fn num_type_to_string(ty?: NumType) -> str
fn ref_type_to_string(ty?: RefType) -> str
fn heap_type_to_string(heap_type?: HeapType) -> str
pub fn comp_type_to_string(comp_type?: CompType) -> str
fn field_type_to_string(field_type: FieldType) -> str
fn packed_type_to_string(ty?: PackType) -> str
pub struct Tag
typeidx: int64
pub enum ExportKind
Func(int64)Global(int64)Tag(int64)Memory(int64)Table(int64)
pub enum CatchItem
Catch(int64, int64)
pub enum Instruction
ctrl_unreachablectrl_nopdropctrl_block(BlockType)ctrl_loop(BlockType)ctrl_if(BlockType)ctrl_elsectrl_endctrl_br(int64)ctrl_br_if(int64)ctrl_br_tablectrl_returnctrl_call(int64)ctrl_call_ref(int64)ctrl_call_indirect(int64)ctrl_throw(int64)ctrl_try_table(BlockType, List[CatchItem])local_get(int64)local_set(int64)local_tee(int64)global_get(int64)global_set(int64)i32_load(int64, int64)i64_load(int64, int64)f32_load(int64, int64)f64_load(int64, int64)i32_store(int64, int64)i64_store(int64, int64)f32_store(int64, int64)f64_store(int64, int64)i32_const(int64)i64_const(int64)f32_const(float32)f64_const(float64)i32_eqzi32_eqi32_nei32_lt_si32_lt_ui32_gt_si32_gt_ui32_le_si32_le_ui32_ge_si32_ge_ui64_eqzi64_eqi64_nei64_lt_si64_lt_ui64_gt_si64_gt_ui64_le_si64_le_ui64_ge_si64_ge_uf32_eqf32_nef32_ltf32_gtf32_lef32_gef64_eqf64_nef64_ltf64_gtf64_lef64_gei32_clzi32_ctzi32_popcnti32_addi32_subi32_muli32_div_si32_div_ui32_rem_si32_rem_ui32_andi32_ori32_xori32_shli32_shr_si32_shr_ui32_rotli32_rotri64_clzi64_ctzi64_popcnti64_addi64_subi64_muli64_div_si64_div_ui64_rem_si64_rem_ui64_andi64_ori64_xori64_shli64_shr_si64_shr_ui64_rotli64_rotrf32_absf32_negf32_ceilf32_floorf32_truncf32_nearestf32_sqrtf32_addf32_subf32_mulf32_divf32_minf32_maxf32_copysignf64_absf64_negf64_ceilf64_floorf64_truncf64_nearestf64_sqrtf64_addf64_subf64_mulf64_divf64_minf64_maxf64_copysigni32_wrap_i64i32_trunc_f32_si32_trunc_f32_ui32_trunc_f64_si32_trunc_f64_ui64_extend_i32_si64_extend_i32_ui64_trunc_f32_si64_trunc_f32_ui64_trunc_f64_si64_trunc_f64_uf32_convert_i32_sf32_convert_i32_uf32_convert_i64_sf32_convert_i64_uf32_demote_f64f64_convert_i32_sf64_convert_i32_uf64_convert_i64_sf64_convert_i64_uf64_promote_f32i32_reinterpret_f32i64_reinterpret_f64f32_reinterpret_i32f64_reinterpret_i64i32_extend8_si32_extend16_si64_extend8_si64_extend16_si64_extend32_sref_func(int64)ref_null(HeapType)ref_is_nullref_as_non_nullref_eqref_cast(RefType)struct_new(int64)struct_get(int64, int64)struct_set(int64, int64)array_new_fixed(int64, int64)array_new_data(int64, int64)array_new_elem(int64, int64)array_new_default(int64)array_get(int64)array_set(int64)ref_i31i31_get(bool)extern_convert_anyany_convert_extern
class Writer
pub fn write_u32(value?: int64)
pub fn write_s32(value?: int64)
pub fn write_f32(value?: float32)
pub fn write_f64(value?: float64)
pub fn write_byte(b?: int64)
pub fn write_data(data?: Bytes)
pub fn pack_memarg(align: int64, offset: int64)
pub fn get_bytes() -> Bytes
fn pack_str(writer: Writer, text?: str)
fn write_header(writer: Writer)
fn write_section(writer: Writer, id: int64, data: Bytes)
Write a section with given ID and data.
fn create_type_section(wasm_module: Module) -> Bytes
Create data for the type section
fn write_data_count_section(wasm_module: Module) -> Bytes
pub fn to_wasm(wasm_module: Module) -> Bytes
Create binary representation of wasm module.
fn block_type_to_string(block_type: BlockType) -> str
pub fn to_wat(wasm_module: Module, out: TextGenerator)
Write webassembly module in text format (WAT)
fn escape_binary(data?: Bytes) -> str