module GcodeRel(gcodeRel) where
import Gcode
import GcodeLow(gcodeSize,wsize,align)
import AssocTree
import Util.Extra(sndOf)
gcodeRel gcode = fixOne gcode
fixOne [] = []
fixOne (g@(STARTFUN pos fun):gs) =
gRel (gLabels initAT 0 gs) 0 gs
fixOne (ALIGN:gs) = -- must be aligned here!
fixOne gs
fixOne (g@ALIGN_CONST:gs) = -- must be aligned here!
g:fixOne gs
fixOne (g:gs) =
g : fixOne gs
nops = NOP:nops
gLabels :: AssocTree Int Int -> Int -> [Gcode] -> AssocTree Int Int
gLabels at p [] = at
gLabels at p (LABEL i:gs) =
gLabels (addAT at sndOf i p) p gs
gLabels at p (TABLESWITCH size _ _:gs) = -- DAVID
let p1 = p + 2 in
let p2 = p1 + align 2 p1 + 2 * size
in seq p2 (gLabels at p2 gs)
gLabels at p (LOOKUPSWITCH size _ _ _:gs) = -- DAVID
let p1 = p + 2 in
let p2 = p1 + align 2 p1 + 4 * size + 2
in seq p2 (gLabels at p2 gs)
{------------- DAVID ------------
gLabels at p (g@JUMPS_T:gs) =
let p' = gcodeSize g + p
in seq p' (gLabels at (p' + align 2 p') gs)
gLabels at p (g@JUMPS_L:gs) =
let p' = gcodeSize g + p
in seq p' (gLabels at (p' + align 4 p') gs)
------------- DAVID --------------}
gLabels at p (g@PRIMITIVE:gs) =
let p' = gcodeSize g + p
in seq p' (gLabels at (p' + align wsize p') gs)
gLabels at p (g@(ALIGN):gs) =
gLabels at (p + align wsize p) gs
gLabels at p (ALIGN_CONST:gs) = -- Only const table left
at
gLabels at p (g:gs) =
let p' = gcodeSize g + p
in seq p' (gLabels at p' gs)
gRel :: AssocTree Int Int -> Int -> [Gcode] -> [Gcode]
gRel at p [] = take (align wsize p) nops
gRel at p (g@(JUMP i):gs) =
let p' = gcodeSize g + p
in case lookupAT at i of
Just i -> JUMP (i-p-1) : gRel at p' gs
gRel at p (g@(JUMPFALSE i):gs) = -- DAVID
let p' = gcodeSize g + p
in case lookupAT at i of
Just i -> JUMPFALSE (i-p-1) : gRel at p' gs -- DAVID
Nothing -> error "label not found"
gRel at p (TABLESWITCH size _ ls:gs) = -- DAVID
TABLESWITCH size pad (map adjust ls) :
gRel at (pt+2*size) gs
where
p1 = p + 2
pad = align 2 p1
pt = p1 + pad
adjust l = case lookupAT at l of Just p1 -> (p1-pt)
gRel at p (LOOKUPSWITCH size _ tls def:gs) = -- DAVID
LOOKUPSWITCH size pad (map (\(t,l) -> (t, adjust l)) tls) (adjust def) :
gRel at (pt+4*size+2) gs
where
p1 = p + 2
pad = align 2 p1
pt = p1 + pad
adjust l = case lookupAT at l of Just p1 -> (p1-pt)
{-------------- DAVID --------------------
gRel at p (g@JUMPS_T:gs) =
g : take f nops ++ gRel' pt gs
where
p' = p + gcodeSize g
f = align 2 p'
pt = p' + f
gRel' p [] = []
gRel' p (g@(JUMPTABLE l1):gs) =
case lookupAT at l1 of
Just p1 ->
JUMPTABLE (p1-pt) : gRel' (p+gcodeSize g) gs
gRel' p gs = gRel at p gs
gRel at p (g@(JUMPS_L):gl@(JUMPLENGTH s l1):gs) =
case lookupAT at l1 of
Just p1 -> g : take f nops ++ JUMPLENGTH s (p1-pt) : gRel' (gcodeSize gl + pt) gs
where
p' = p + gcodeSize g
pt = p' + f
f = align 4 p'
gRel' p [] = []
gRel' p (g@(JUMPLIST v l1):gs) =
case lookupAT at l1 of
Just p1 ->
JUMPLIST v (p1-pt) : gRel' (p + gcodeSize g) gs
gRel' p gs = gRel at p gs
------------------------ DAVID ---------------- -}
gRel at p (g@PRIMITIVE:gs) =
g : take f nops ++ gRel at (p'+f) gs
where
p' = p + gcodeSize g
f = align 4 p'
gRel at p (ALIGN:gs) =
let f = align wsize p
in take f nops ++ gRel at (p+f) gs
gRel at p gss@(ALIGN_CONST:gs) = -- only constant table left !
gss
gRel at p (g:gs) =
let p' = gcodeSize g + p
in seq p' (g : gRel at p' gs)
|