Created
July 31, 2014 12:53
-
-
Save quinnj/8bdcab6d2f2a092f4835 to your computer and use it in GitHub Desktop.
Macro-generated binary tree with if statements
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Recursively build binary search tree w/ known lookup values | |
# A is sorted array of lookup values | |
# R is return values for each index of A | |
# i.e. R[1] is returned for values < A[1], R[2] for < A[2], etc. | |
function searchsortedlasttree(A,R,var_name) | |
l = length(A) | |
mid = iseven(l) ? l>>>1 : (l>>>1)+1 | |
# Handle base case | |
if mid == 1 | |
if l == 1 | |
return :($var_name < $(A[1]) ? $(R[1]) : $(R[2])) | |
else # l == 2 | |
return :($var_name < $(A[1]) ? $(R[1]) : | |
$var_name < $(A[2]) ? $(R[2]) : $(R[3])) | |
end | |
end | |
iftree = Expr(:if) | |
iftree.args = Array(Any,3) | |
iftree.args[1] = :($var_name < $(A[mid])) # condition | |
iftree.args[2] = searchsortedlasttree(A[1:mid-1],R[1:mid],var_name) | |
iftree.args[3] = searchsortedlasttree(A[mid+1:end],R[mid+1:end],var_name) | |
return iftree | |
end | |
macro leapstree(a,r,var_name) | |
# var_name is the variable name that will be passed in thru the parent function | |
A = eval(a) # safe to eval here because 'a' is known at compile time | |
R = eval(r) # same here | |
ret = Expr(:block) # we'll store everything in a big block expression | |
# First we manually handle before and after the ends of our leaps array | |
push!(ret.args,:($var_name < $(A[1]) && return 0)) | |
push!(ret.args,:($var_name >= $(A[end]) && return $(endof(A)*1000))) | |
# Now we call the recursive searchsortedlasttree to get the rest | |
push!(ret.args,searchsortedlasttree(A[2:(endof(A)-1)],R,var_name)) | |
return ret | |
end | |
const SETLEAPS = [62214480000000,62230377600000,62261913600000, 62293449600000,62324985600000,62356608000000,62388144000000, 62419680000000,62451216000000,62498476800000,62530012800000, 62561548800000,62624707200000,62703676800000,62766835200000, 62798371200000,62845632000000,62877168000000,62908704000000, 62956137600000,63003398400000,63050832000000,63271756800000, 63366451200000,63476784000000] | |
function setleaps(ms) | |
# @leapstree as a macro ensures everything gets expanded | |
# at compile time | |
@leapstree(SETLEAPS,[1000:1000:((endof(SETLEAPS)-1)*1000)],ms) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment