Skip to content

Instantly share code, notes, and snippets.

@simonster
Last active August 29, 2015 14:07
Show Gist options
  • Save simonster/606718a857ea7e6c1600 to your computer and use it in GitHub Desktop.
Save simonster/606718a857ea7e6c1600 to your computer and use it in GitHub Desktop.
alist
immutable AListWrapper{Name}; end
immutable AList{Keys<:(AListWrapper...),Types} <: Associative
v::Types
end
macro alist(args...)
keys = Array(Any, length(args))
values = Array(Any, length(args))
for i = 1:length(args)
if !Base.Meta.isexpr(args[i], :(=>))
error("unexpected non-pair in @alist")
else
key = args[i].args[1]
if isa(key, Expr) && key.head == :quote && length(key.args) == 1
key = key.args[1]
end
if isa(key, Expr)
xdump(args[i].args[1])
error("key $(args[i].args[1]) is not static")
end
end
keys[i] = AListWrapper{key}
values[i] = args[i].args[2]
end
quote
AList{$(tuple(keys...)),$(esc(Expr(:tuple, [:(typeof($x)) for x in values]...)))}($(esc(Expr(:tuple, values...))))
end
end
macro aidx(ref)
Base.Meta.isexpr(ref, :ref) || error("not an indexing expression")
Expr(:ref, esc(ref.args[1]), :(AListWrapper{$(esc(ref.args[2]))}))
end
Base.getindex(x::AList, idx) = x[AListWrapper{idx}]
stagedfunction getindex{T}(A::AList, x::Type{AListWrapper{T}})
keys = A.parameters[1]
types = A.parameters[2]
key = x.parameters[1]
for i = 1:length(keys)
if keys[i] === key
return :(A.v[$i])
end
end
errstr = "key not found: $(key)"
:(throw($errstr))
end
function f()
a = @alist(:a => 1, :b => 2)
@aidx a[:a]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment