Skip to content

Instantly share code, notes, and snippets.

View asterite's full-sized avatar

Ary Borenszweig asterite

  • NoRedInk
  • Buenos Aires, Argentina
View GitHub Profile
deps do
github "manastech/frank"
end
alias RecursiveArray = Int32 | Array(RecursiveArray)
a = [1, 2, 3] of RecursiveArray
a << a
p a

Crystal's type inference algorithm

The type inference starts at type_inference.cr. Here, the program's AST is visited with a TypeVisitor. This visitor's does many things:

  1. It declares classes and defs (when the visitor visits a ClassDef node it declares a class, etc.). Note that the visitor doesn't visits a def's contents.
  2. It types literals. For example the number 1, represented by a NumberLiteral node, is assigned the type Int32. Every ASTNode has a type, which initially is nil.
  3. It keeps track of variables defined a method (or at the top level) and their types. For example, when the visitor finds an assignment like a = 1 it first visits 1 and assigns the type Int32 to it. Then it binds the node a to the
class Array(T)
def map(&block : T -> U)
ary = [] of U
each { |e| ary << yield e }
ary
end
end
class Foo
end
# Ported from Rust from https://gist.github.com/joshmarinacci/c84d0979e100d107f685
record Vector, x, y, z do
def scale(s)
Vector.new(x * s, y * s, z * s)
end
def +(other)
Vector.new(x + other.x, y + other.y, z + other.z)
end
struct Enum
include Comparable(self)
macro def to_s(io : IO) : Nil
{% if @enum_flags %}
found = false
{% for member in @enum_members %}
if value & {{member}}.value != 0
io << ", " if found
io << {{member.stringify}}
require "json"
class Object
macro json_schema(properties)
{% for key, value in properties %}
property :{{key.id}}
{% end %}
def self.new(_pull : Json::PullParser)
{% for key, value in properties %}
def foo(&block)
block
end
block = foo do
{0, 0, 42, 0}
end
block.call
@asterite
asterite / wtf.cr
Last active August 29, 2015 14:07
class Context
def initialize
@x = self
end
def x
@x
end
def it(&block)
require "compiler/crystal/**"
include Crystal
class MyVisitor < Visitor
def initialize
@str = StringIO.new
end
def visit(node : ClassDef)