Skip to content

module Crystal

Here lies the logic of the representation of the MixedUnionType.

Which structure is used to represent them is defined in LLVMTyper#create_llvm_type.

The #union_type_and_value_pointer will allow to read the current value of the union. The #store*_in_union operations allow to write the value in a unions. The #{assign|downcast|upcast}_distinct_union_types operation matches the semantics described in ./

Together these operations should encapsulate the binary representation of the MixedUnionType.

Other unions like ReferenceUnionType that have a more trivial representation are not handled here.


BUILD_COMMIT = "dd40a2442"

BUILD_DATE = "2021-03-22"

CACHE_DIR = "/home/runner/.cache/crystal"


DESCRIPTION = "Crystal 1.0.0 [dd40a2442] (2021-03-22)\n\nLLVM: 10.0.0\nDefault target: x86_64-unknown-linux-gnu"

GET_EXCEPTION_NAME = "__crystal_get_exception"

LIBRARY_PATH = "/home/runner/work/_temp/crystal-latest-true-undefined/bin/../lib/crystal/lib"

LLVM_VERSION = "10.0.0"

MAIN_NAME = "__crystal_main"

MALLOC_ATOMIC_NAME = "__crystal_malloc_atomic64"

MALLOC_NAME = "__crystal_malloc64"

ONCE = "__crystal_once"

ONCE_INIT = "__crystal_once_init"

PATH = "lib:/home/runner/work/crystal-book/crystal-book/crystal/src"

RAISE_NAME = "__crystal_raise"

RAISE_OVERFLOW_NAME = "__crystal_raise_overflow"

REALLOC_NAME = "__crystal_realloc64"

VERSION = "1.0.0"

Class methods

.check_type_can_be_stored(node, type, msg)

View source

.error(msg, color, exit_code = 1, stderr = STDERR, leading_error = true)

View source

.format(source, filename = nil)

View source


Defines the main routine run by normal Crystal programs:

  • Initializes the GC
  • Invokes the given block
  • Handles unhandled exceptions
  • Invokes at_exit handlers
  • Flushes STDOUT and STDERR

This method can be invoked if you need to define a custom main (as in C main) function, doing all the above steps.

For example:

fun main(argc : Int32, argv : UInt8**) : Int32
  Crystal.main do
    elapsed = Time.measure do
      Crystal.main_user_code(argc, argv)
    puts "Time to execute program: #{elapsed}"

Note that the above is really just an example, almost the same can be accomplished with at_exit. But in some cases redefinition of C's main is needed.

View source

.main(argc : Int32, argv : Pointer(Pointer(UInt8)))

Main method run by all Crystal programs at startup.

This setups up the GC, invokes your program, rescuing any handled exception, and then runs at_exit handlers.

This method is automatically invoked for you, so you don't need to invoke it.

However, if you need to define a special main C function, you can redefine main and invoke Crystal.main from it:

fun main(argc : Int32, argv : UInt8**) : Int32
  # some setup before Crystal main
  Crystal.main(argc, argv)
  # some cleanup logic after Crystal main

The Crystal.main can also be passed as a callback:

fun main(argc : Int32, argv : UInt8**) : Int32
  LibFoo.init_foo_and_invoke_main(argc, argv, ->Crystal.main(Int32, UInt8**))

Note that before Crystal.main is invoked the GC is not setup yet, so nothing that allocates memory in Crystal (like new for classes) can be used.

View source

.main_user_code(argc : Int32, argv : Pointer(Pointer(UInt8)))

Executes the main user code. This normally is executed after initializing the GC and before executing at_exit handlers.

You should never invoke this method unless you need to redefine C's main function. See Crystal.main for more details.

View source


View source

.print_hierarchy(program, exp, format)

View source


View source


View source

.safe_mangling(program, name)

View source


View source


View source

.with_line_numbers(source : String | Array(String), highlight_line_number = nil, color = false, line_number_start = 1)

View source