This content originally appeared on DEV Community and was authored by kojix2
Introduction
The Crystal compiler can be used as a library.
This document explains how to set it up and use it.
Creating the Project
First, create a new Crystal project.
crystal init app duck_egg
cd duck_egg
Editing shard.yml
Edit the shard.yml
file as follows.
In this example, we add markd
and reply
to the dependencies
section.
name: duck_egg
version: 0.1.0
targets:
🥚:
main: src/duck_egg.cr
dependencies:
markd:
github: icyleaf/markd
reply:
github: I3oris/reply
Creating duck_egg.cr
Create src/duck_egg.cr
and add the following code.
require "compiler/requires"
BIRDS = [
{ "🐔", "cluck!" },
{ "🐓", "cock-a-doodle-doo" },
{ "🦃", "gobble" },
{ "🦆", "quack" },
{ "🦉", "hoot" },
{ "🦜", "squawk" },
{ "🕊", "coo" },
{ "🦢", "honk" },
{ "🦩", "brrrrt" },
{ "🐧", "honk honk" },
{ "🦤", "boop" },
{ "🦕", "Bwooooon!!" },
{ "🦖", "Raaaaawr!!" }
]
bird, sound = BIRDS.sample
compiler = Crystal::Compiler.new
source = Crystal::Compiler::Source.new(bird, %Q(puts "#{bird} < #{sound}"))
compiler.compile source, bird
In this program, the Crystal compiler is embedded in the target .
When is executed, a random bird is selected.
The embedded compiler generates a binary that displays the bird and its sound.
Building and Running
First, build the program.
shards build
Next, check the CRYSTAL_PATH
environment variable to find the location of the Crystal standard library.
crystal env
The Crystal compiler requires the standard library even for very simple code such as puts 0
.
Therefore, CRYSTAL_PATH
must be set to include the path to the standard library.
export CRYSTAL_PATH=lib:/usr/local/bin/../share/crystal/src
Run the program:
bin/🥚
Example output:
🦖
Run the generated binary:
./🦖
Output:
🦖 < Raaaaawr!!
Summary
By using the Crystal compiler as a library, you can generate and compile code dynamically. This technique can be applied in many interesting ways.
This content originally appeared on DEV Community and was authored by kojix2