summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-06-13 19:10:07 -0400
committerJoe Crayne <joe@jerkface.net>2019-06-13 19:10:07 -0400
commit03b4ed79972046dc1397430ac7d96493eb9c2c3e (patch)
treed165c537e0c7070d670f72d169e156f119e23658
parent76e4b1bd5310f65608521967db653570bb73ecbe (diff)
crayne parser: variable substition in g,o,mtlib commands.
-rw-r--r--src/Wavefront.hs101
1 files changed, 60 insertions, 41 deletions
diff --git a/src/Wavefront.hs b/src/Wavefront.hs
index 74d0b39..ca4b497 100644
--- a/src/Wavefront.hs
+++ b/src/Wavefront.hs
@@ -147,48 +147,67 @@ findToken (ObjConfig args) bs = case L.dropWhile (\c -> isSpace c || c=='\\') bs
147 Just _ -> cs 147 Just _ -> cs
148 Nothing -> L.empty 148 Nothing -> L.empty
149 149
150findNewLine :: [L.ByteString] -> ObjConfig -> L.ByteString -> (L.ByteString,L.ByteString)
151findNewLine ps o@(ObjConfig args) bs = case L.break (\c -> c=='\n' || c=='\\' || c=='#' || c=='\\') bs of
152 (ts,cs) -> case L.uncons cs of
153 Just ('\n',ds) -> (L.concat $ reverse $ ts : ps,ds)
154 Just ('#',comment) -> findNewLine (ts:ps) o $ L.dropWhile (/='\n') comment
155 Just ('$',ref) -> case L.splitAt 5 ref of
156 (refp,ds) -> case I.readDecimal (L.toStrict refp) of
157 Just (i,es) -> case IntMap.lookup i args of
158 Just val -> findNewLine (val:ts:ps) o $ reconsChunk es ds
159 _ -> findNewLine (ts:ps) o $ reconsChunk es ds
160 _ -> findNewLine ("$":ts:ps) o ref
161 Just ('\\',ds) -> findNewLine (ts:ps) o $ if L.take 1 ds == "\n" then L.drop 1 ds
162 else ds
163 Nothing -> (L.concat $ reverse $ ts : ps,L.empty)
164
150{- 165{-
151 166
152 1 x bevel 167 1 x bevel
153 2 bmat 168 2 bmat
154 3 bzp 169 3 x bsp
155 4 x call 170 4 bzp
156 5 cdc 171 5 x call
157 6 x c_interp 172 6 cdc
158 7 con 173 7 x cdp
159 8 x csh -- for all except these, 174 8 x c_interp
160 9 cstype -- Two chars suffice to distinguish 175 9 con
161 10 ctech 176 10 x csh -- for all except these,
162 11 curv2 -- for all except these, 177 11 cstype -- Two chars suffice to distinguish
163 12 curv -- Two chars suffice to distinguish 178 12 ctech
164 13 deg 179 13 curv2 -- for all except these,
165 14 x d_interp 180 14 curv -- Two chars suffice to distinguish
166 15 end 181 15 deg
167 16 f 182 16 x d_interp
168 17 g 183 17 end
169 18 hole 184 18 f
170 19 x lod 185 19 g
171 20 x maplib 186 20 hole
172 21 mg 187 21 x lod
173 22 mtllib 188 22 x maplib
174 23 o 189 23 mg
175 24 p 190 24 mtllib
176 25 parm 191 25 o
177 26 s 192 26 p
178 27 scrv 193 27 parm
179 28 x shadow_obj 194 28 x res
180 29 sp 195 29 s
181 30 stech -- for all except these, 196 30 scrv
182 31 step -- Two chars suffice to distinguish 197 31 x shadow_obj
183 32 surf 198 32 sp
184 33 x trace_obj -- for all except these, 199 33 stech -- for all except these,
185 34 trim -- Two chars suffice to distinguish 200 34 step -- Two chars suffice to distinguish
186 35 x usemap -- for all except these, 201 35 surf
187 36 usemtl -- Two chars suffice to distinguish 202 36 x trace_obj -- for all except these,
188 37 v 203 37 trim -- Two chars suffice to distinguish
189 38 vn 204 38 x usemap -- for all except these,
190 39 vp 205 39 usemtl -- Two chars suffice to distinguish
191 40 vt 206 40 v
207 41 vn
208 42 vp
209 43 vt
210
192 211
193-} 212-}
194 213
@@ -313,7 +332,7 @@ parseOBJ builder args bs0
313 | lengthLessThan 2 bs = return () 332 | lengthLessThan 2 bs = return ()
314 | isSpace (L.index bs 1) = case L.head bs of 333 | isSpace (L.index bs 1) = case L.head bs of
315 'f' -> parseT face 2 334 'f' -> parseT face 2
316 'g' -> case L.break (=='\n') $ L.drop 1 bs of -- Newline required to terminate group name list. 335 'g' -> case findNewLine [] args $ L.drop 1 bs of -- Newline required to terminate group name list.
317 (gn,bs') -> do 336 (gn,bs') -> do
318 groups builder (map L.toStrict $ L.words gn) 337 groups builder (map L.toStrict $ L.words gn)
319 parseOBJ builder args bs' 338 parseOBJ builder args bs'
@@ -323,7 +342,7 @@ parseOBJ builder args bs0
323 parseOBJ builder args bs' 342 parseOBJ builder args bs'
324 'v' -> parseV vertex 2 343 'v' -> parseV vertex 2
325 'o' -> -- o object-name 344 'o' -> -- o object-name
326 case L.break (=='\n') $ findToken args $ L.drop 1 bs of 345 case findNewLine [] args $ L.drop 1 bs of
327 (objn,bs') -> do 346 (objn,bs') -> do
328 objectName builder (L.toStrict objn) 347 objectName builder (L.toStrict objn)
329 parseOBJ builder args bs' 348 parseOBJ builder args bs'
@@ -464,7 +483,7 @@ parseOBJ builder args bs0
464 usemtl builder (L.toStrict mtl) 483 usemtl builder (L.toStrict mtl)
465 parseOBJ builder args bs' 484 parseOBJ builder args bs'
466 "mt" -> -- mtllib 485 "mt" -> -- mtllib
467 case L.break (=='\n') $ next 2 bs of 486 case findNewLine [] args $ next 2 bs of
468 (fnn,bs') -> do 487 (fnn,bs') -> do
469 let slurp fnn = case L.break (=='.') fnn of 488 let slurp fnn = case L.break (=='.') fnn of
470 (fn,ext) | L.null (L.drop 1 ext) -> if L.null fn then [] 489 (fn,ext) | L.null (L.drop 1 ext) -> if L.null fn then []