1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
|
# This file is a testcase for the highlighting of Crystal code
# It's not executable code, but a collection of code snippets
#
require "lib_z"
require "./digest"
module Digest::Adler32
def self.initial : UInt32
LibZ.adler32(0, nil, 0).to_u32
end
def self.checksum(data) : UInt32
update(data, initial)
end
def self.update(data, adler32 : UInt32) : UInt32
slice = data.to_slice
LibZ.adler32(adler32, slice, slice.size).to_u32
end
def self.combine(adler1 : UInt32, adler2 : UInt32, len) : UInt32
LibZ.adler32_combine(adler1, adler2, len).to_u32
end
end
struct BigRational
Number.expand_div [Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128], BigRational
Number.expand_div [Float32, Float64], BigRational
end
module Crystal::Repl::Closure
VAR_NAME = ".closure_var"
ARG_NAME = ".closure_arg"
end
class FunctionType
getter arg_types : Array(ArgType)
getter return_type : ArgType
@@cvar = 3
@ivar = 7
def initialize(@arg_types, @return_type)
end
def //(other : Int::Unsigned) : BigInt
check_division_by_zero other
unsafe_floored_div(other)
end
def //(other : Int) : BigInt
check_division_by_zero other
if other < 0
(-self).unsafe_floored_div(-other)
@cvar += 1
else
unsafe_floored_div(other)
@ivar += 10
end
end
end
require "llvm/enums/atomic"
struct Atomic(T)
# Creates an Atomic with the given initial value.
def compare_and_set(cmp : T, new : T) : {T, Bool}
{% if T.union? && T.union_types.all? { |t| t == Nil || t < Reference } %}
address, success = Ops.cmpxchg(pointerof(@value).as(LibC::SizeT*), LibC::SizeT.new(cmp.as(T).object_id), LibC::SizeT.new(new.as(T).object_id), :sequentially_consistent, :sequentially_consistent)
{address == 0 ? nil : Pointer(T).new(address).as(T), success}
{% elsif T < Reference %}
# Use addresses again (but this can't return nil)
address, success = Ops.cmpxchg(pointerof(@value).as(LibC::SizeT*), LibC::SizeT.new(cmp.as(T).object_id), LibC::SizeT.new(new.as(T).object_id), :sequentially_consistent, :sequentially_consistent)
{Pointer(T).new(address).as(T), success}
{% else %}
Ops.cmpxchg(pointerof(@value), cmp, new, :sequentially_consistent, :sequentially_consistent)
{% end %}
end
def swap(value : T)
{% if T.union? && T.union_types.all? { |t| t == Nil || t < Reference } || T < Reference %}
address = Ops.atomicrmw(:xchg, pointerof(@value).as(LibC::SizeT*), LibC::SizeT.new(value.as(T).object_id), :sequentially_consistent, false)
Pointer(T).new(address).as(T)
{% else %}
Ops.atomicrmw(:xchg, pointerof(@value), value, :sequentially_consistent, false)
{% end %}
end
end
class Deque(T)
include Indexable::Mutable(T)
@start = 0
protected setter size
private getter buffer
def initialize(size : Int, value : T)
if size < 0
raise ArgumentError.new("Negative deque size: #{size}")
end
@size = size.to_i
@capacity = size.to_i
unless @capacity == 0
@buffer = Pointer(T).malloc(@capacity, value)
end
end
# Returns a new `Deque` that has this deque's elements cloned.
# That is, it returns a deep copy of this deque.
#
# Use `#dup` if you want a shallow copy.
def clone
{% if T == ::Bool || T == ::Char || T == ::String || T == ::Symbol || T < ::Number::Primitive %}
Deque(T).new(size) { |i| self[i].clone.as(T) }
{% else %}
exec_recursive_clone do |hash|
clone = Deque(T).new(size)
each do |element|
clone << element.clone
end
clone
end
{% end %}
end
def delete_at(index : Int) : T
unless 0 <= index < @size
raise IndexError.new
end
return shift if index == 0
if index > @size // 2
# Move following items to the left, starting with the first one
# [56-01234] -> [6x-01235]
dst = rindex
finish = (@start + @size - 1) % @capacity
loop do
src = dst + 1
src -= @capacity if src >= @capacity
@buffer[dst] = @buffer[src]
break if src == finish
dst = src
end
(@buffer + finish).clear
end
end
def each(& : T ->) : Nil
halfs do |r|
r.each do |i|
yield @buffer[i]
end
end
end
def pop : T
pop { raise IndexError.new }
end
macro [](*args)
array = uninitialized Array(Int32)
{% for arg, i in args %}
array.to_unsafe[{{i}}] = {{arg}}
{% end %}
array
end
def message : String
case self
when SUCCESS then "No error occurred. System call completed successfully."
when TXTBSY then Errno::ETXTBSY
when NOTCAPABLE then Errno::ENOTCAPABLE
else Errno::EINVAL
end
end
enum Signal
KILL = 0
BILL = 101
end
end
# :nodoc:
module Ops
# Defines methods that directly map to LLVM instructions related to atomic operations.
@[Primitive(:cmpxchg)]
def self.cmpxchg(ptr : T*, cmp : T, new : T, success_ordering : LLVM::AtomicOrdering, failure_ordering : LLVM::AtomicOrdering) : {T, Bool} forall T
end
@[Primitive(:atomicrmw)]
def self.atomicrmw(op : LLVM::AtomicRMWBinOp, ptr : T*, val : T, ordering : LLVM::AtomicOrdering, singlethread : Bool) : T forall T
end
end
@[Link("z")]
lib LibZ
alias Char = LibC::Char
alias SizeT = LibC::SizeT
fun zlibVersion : Char*
fun crc32_combine(crc1 : ULong, crc2 : ULong, len : Long) : ULong
alias AllocFunc = Void*, UInt, UInt -> Void*
alias FreeFunc = (Void*, Void*) ->
struct ZStream
next_in : Bytef*
avail_in : UInt
next_out : Bytef*
total_out : ULong
msg : Char*
state : Void*
zalloc : AllocFunc
zfree : FreeFunc
opaque : Void*
data_type : Int
adler : Long
end
# error codes
enum Error
OK = 0
VERSION_ERROR = -6
end
enum Flush
NO_FLUSH = 0
TREES = 6
end
MAX_BITS = 15
fun deflateInit2 = deflateInit2_(stream : ZStream*, level : Int32, method : Int32,
window_bits : Int32, mem_level : Int32, strategy : Int32,
version : UInt8*, stream_size : Int32) : Error
fun deflate(stream : ZStream*, flush : Flush) : Error
fun deflateSetDictionary(stream : ZStream*, dictionary : UInt8*, len : UInt) : Int
fun inflateInit2 = inflateInit2_(stream : ZStream*, window_bits : Int32, version : UInt8*, stream_size : Int32) : Error
fun inflate(stream : ZStream*, flush : Flush) : Error
fun inflateSetDictionary(stream : ZStream*, dictionary : UInt8*, len : UInt) : Error
end
|