Changeset 15296 for src/Pugs/Prim.hs
- Timestamp:
- 02/18/07 15:56:10 (21 months ago)
- Files:
-
- 1 modified
-
src/Pugs/Prim.hs (modified) (61 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Pugs/Prim.hs
r15201 r15296 1 {-# OPTIONS_GHC -fglasgow-exts -fno-warn-orphans -fno-full-laziness -fno-cse -fallow-overlapping-instances #-}1 {-# OPTIONS_GHC -fglasgow-exts -fno-warn-orphans -fno-full-laziness -fno-cse -fallow-overlapping-instances -foverloaded-strings #-} 2 2 3 3 {-| … … 55 55 import GHC.Unicode 56 56 import qualified Data.HashTable as H 57 import qualified UTF8 as Str 57 58 58 59 constMacro :: Exp -> [Val] -> Eval Val … … 65 66 op0 "^" = fmap opJuncOne . mapM fromVal 66 67 op0 "|" = fmap opJuncAny . mapM fromVal 67 op0 "want" = const $ fmap VStr (asks (maybe "Void" envWant . envCaller))68 op0 "want" = const $ fmap _VStr (asks (maybe "Void" envWant . envCaller)) 68 69 op0 "Bool::True" = const . return $ VBool True 69 70 op0 "Bool::False" = const . return $ VBool False … … 82 83 op0 "File::Spec::cwd" = const $ do 83 84 cwd <- guardIO getCurrentDirectory 84 return $ VStr cwd85 return $ _VStr cwd 85 86 op0 "File::Spec::tmpdir" = const $ do 86 87 tmp <- guardIO getTemporaryDirectory 87 return $ VStr tmp88 return $ _VStr tmp 88 89 op0 "Pugs::Internals::pi" = const $ return $ VNum pi 89 90 op0 "self" = const $ expToEvalVal (_Var "&self") … … 116 117 str <- fromVal x 117 118 return $ if null str 118 then VStr str119 else VStr $ init str119 then _VStr str 120 else _VStr $ init str 120 121 op1 "Scalar::chomp" = \x -> do 121 122 str <- fromVal x 122 123 return $ op1Chomp str 123 124 op1 "Str::split" = op1Cast (castV . words) 124 op1 "lc" = op1Cast ( VStr . map toLower)125 op1 "lc" = op1Cast (_VStr . map toLower) 125 126 op1 "lcfirst" = op1StrFirst toLower 126 op1 "uc" = op1Cast ( VStr . map toUpper)127 op1 "uc" = op1Cast (_VStr . map toUpper) 127 128 op1 "ucfirst" = op1StrFirst toUpper 128 op1 "capitalize" = op1Cast $ VStr . (mapEachWord capitalizeWord)129 op1 "capitalize" = op1Cast $ _VStr . (mapEachWord capitalizeWord) 129 130 where 130 131 mapEachWord _ [] = [] … … 135 136 capitalizeWord [] = [] 136 137 capitalizeWord (c:cs) = toUpper c:(map toLower cs) 137 op1 "quotemeta" = op1Cast ( VStr . concat . map toQuoteMeta)138 op1 "quotemeta" = op1Cast (_VStr . concat . map toQuoteMeta) 138 139 op1 "undef" = const $ return undef 139 140 op1 "undefine" = \x -> do … … 160 161 val <- fromVal x 161 162 val' <- case val of 162 (VStr str) -> return ( VStr $ strInc str)163 (VStr str) -> return (_VStr $ strInc (cast str)) 163 164 _ -> op1Numeric (+1) val 164 165 writeRef ref val' 165 166 case val of 166 (VStr _)-> return val167 VStr{} -> return val 167 168 _ -> op1 "+" val 168 169 op1 "++" = \mv -> do … … 192 193 _ -> return (args, Nothing) 193 194 sortBy <- case sortByGiven of 194 Nothing -> readVar ( cast "&infix:cmp")195 Nothing -> readVar (_cast "&infix:cmp") 195 196 Just subVal -> return subVal 196 197 sub <- fromVal sortBy … … 202 203 op1 "Scalar::reverse" = \v -> do 203 204 str <- fromVal v 204 return ( VStr $ reverse str)205 return (_VStr $ reverse str) 205 206 op1 "List::reverse" = \v -> do 206 207 vlist <- fromVal v … … 208 209 op1 "list" = op1Cast VList 209 210 op1 "pair" = op1Cast $ VList . (map $ \(k, v) -> castV ((VStr k, v) :: VPair)) 210 op1 "~" = op1Cast VStr211 op1 "~" = op1Cast _VStr 211 212 op1 "?" = op1Cast VBool 212 213 op1 "int" = op1Cast VInt 213 214 op1 "+^" = op1Cast (VInt . pred . negate) -- Arbitrary precision complement- 0 ==> -1 / 1 ==> -2 214 op1 "~^" = op1Cast ( VStr . mapStr complement)215 op1 "~^" = op1Cast (_VStr . mapStr complement) 215 216 op1 "?^" = op1 "!" 216 217 op1 "\\" = \v -> do … … 338 339 op1 "take" = \v -> assertFrame FrameGather $ do 339 340 glob <- askGlobal 340 arr <- findSymRef ( cast "$*TAKE") glob341 arr <- findSymRef (_cast "$*TAKE") glob 341 342 push <- doArray (VRef arr) array_push 342 343 push (listVal v) … … 364 365 op1 "IO::next" = \v -> do 365 366 fh <- fromVal v 366 guardIO $ fmap (VStr . (++ "\n") . decodeUTF8) (hGetLine fh)367 guardIO (fmap _VStr (hGetLine fh)) 367 368 op1 "Pugs::Safe::safe_print" = \v -> do 368 369 str <- fromVal v 369 guardIO . putStr $ encodeUTF8str370 guardIO $ Str.putStr str 370 371 return $ VBool True 371 372 op1 "die" = \v -> do … … 374 375 retShift $! VError (errmsg $! v') [pos] 375 376 where 376 errmsg VUndef = VStr "Died"377 errmsg VType{} = VStr "Died"378 errmsg (VStr "") = VStr "Died"379 errmsg (VList []) = VStr "Died"377 errmsg VUndef = _VStr "Died" 378 errmsg VType{} = _VStr "Died" 379 errmsg (VStr "") = _VStr "Died" 380 errmsg (VList []) = _VStr "Died" 380 381 errmsg (VList [x]) = x 381 382 errmsg x = x 382 383 op1 "warn" = \v -> do 383 384 strs <- fromVal v 384 errh <- readVar $ cast "$*ERR"385 errh <- readVar $ _cast "$*ERR" 385 386 pos <- asks envPos 386 op2 "IO::say" errh $ VList [ VStr $ pretty (VError (errmsg strs) [pos]) ]387 where 388 errmsg "" = VStr "Warning: something's wrong"389 errmsg x = VStr x387 op2 "IO::say" errh $ VList [ _VStr $ pretty (VError (errmsg strs) [pos]) ] 388 where 389 errmsg "" = _VStr "Warning: something's wrong" 390 errmsg x = _VStr x 390 391 op1 "fail" = op1 "fail_" -- XXX - to be replaced by Prelude later 391 392 op1 "fail_" = \v -> do 392 throw <- fromVal =<< readVar ( cast "$*FAIL_SHOULD_DIE")393 throw <- fromVal =<< readVar (_cast "$*FAIL_SHOULD_DIE") 393 394 if throw then op1 "die" (errmsg v) else do 394 395 pos <- asks envPos … … 397 398 op1Return (retControl (ControlLeave (<= SubRoutine) 0 dieThunk)) 398 399 where 399 errmsg VUndef = VStr "Failed"400 errmsg VType{} = VStr "Failed"401 errmsg (VStr "") = VStr "Failed"402 errmsg (VList []) = VStr "Failed"400 errmsg VUndef = _VStr "Failed" 401 errmsg VType{} = _VStr "Failed" 402 errmsg (VStr "") = _VStr "Failed" 403 errmsg (VList []) = _VStr "Failed" 403 404 errmsg (VList [x]) = x 404 405 errmsg x = x … … 406 407 op1 "readlink" = \v -> do 407 408 str <- fromVal v 408 guardIO $ fmap VStr (readSymbolicLink str)409 guardIO $ fmap _VStr (readSymbolicLink str) 409 410 op1 "sleep" = \v -> do 410 411 x <- fromVal v :: Eval VNum … … 431 432 path <- fromVal v 432 433 files <- guardIO $ getDirectoryContents path 433 retSeq (map VStr files)434 retSeq (map _VStr files) 434 435 op1 "slurp" = \v -> do 435 436 ifValTypeIsa v "IO" 436 437 (do h <- fromVal v 437 438 ifListContext (strictify $! op1 "=" v) $ do 438 content <- guardIO $ hGetContents h439 return . VStr $ decodeUTF8 content)439 content <- guardIO $ Str.hGetContents h 440 return (VStr content)) 440 441 (do 441 442 fileName <- fromVal v … … 447 448 VList lines <- action 448 449 return $ VList (length lines `seq` lines) 449 slurpList file = strictify $! op1 "=" (VList [ VStr file])450 slurpList file = strictify $! op1 "=" (VList [_VStr file]) 450 451 slurpScalar file = do 451 content <- guardIO $ readFile file452 return . VStr $ decodeUTF8 content452 content <- guardIO $ Str.readFile file 453 return (VStr content) 453 454 op1 "opendir" = \v -> do 454 455 str <- fromVal v … … 471 472 if null this then return [] else do 472 473 rest <- readDirStreamList dir 473 return ( VStr this:rest)474 return (_VStr this:rest) 474 475 op1 "Pugs::Internals::runShellCommand" = \v -> do 475 476 str <- fromVal v … … 483 484 handleExitCode exitCode 484 485 return $ case cxt of 485 CxtSlurpy{} -> VList (map VStr $ lines res)486 _ -> VStr res486 CxtSlurpy{} -> VList (map _VStr $ lines res) 487 _ -> _VStr res 487 488 where 488 489 -- XXX - crude CRLF treatment … … 589 590 op1 "max" = op1Max 590 591 op1 "uniq" = op1Uniq 591 op1 "chr" = op1Cast ( VStr . (:[]) . chr)592 op1 "chr" = op1Cast (_VStr . (:[]) . chr) 592 593 op1 "ord" = op1Cast $ \str -> if null str then undef else (castV . ord . head) str 593 594 op1 "hex" = fail "hex() is not part of Perl 6 - use :16() instead." … … 641 642 op1 "Pugs::Internals::rule_pattern" = \v -> do 642 643 case v of 643 VRule MkRulePGE{rxRule=re} -> return $ VStr re644 VRule MkRulePCRE{rxRuleStr=re} -> return $ VStr re644 VRule MkRulePGE{rxRule=re} -> return $ _VStr re 645 VRule MkRulePCRE{rxRuleStr=re} -> return $ _VStr re 645 646 _ -> fail $ "Not a rule: " ++ show v 646 647 op1 "Pugs::Internals::rule_adverbs" = \v -> do … … 670 671 glob <- filterPrim =<< asks envGlobal 671 672 yml <- liftIO $ showYaml (filterUserDefinedPad glob, v) 672 return $ VStr yml673 return $ _VStr yml 673 674 op1 "Object::HOW" = \v -> do 674 675 typ <- evalValType v … … 697 698 op1SigilHyper sig val = do 698 699 vs <- fromVal val 699 evalExp $ Syn "," (map (\x -> Syn (shows sig "{}") [Val x]) vs)700 evalExp $ Syn "," (map (\x -> _Syn (shows sig "{}") [Val x]) vs) 700 701 701 702 retSeq :: VList -> Eval Val … … 705 706 handleExitCode exitCode = do 706 707 glob <- askGlobal 707 errSV <- findSymRef ( cast "$!") glob708 errSV <- findSymRef (_cast "$!") glob 708 709 writeRef errSV $ case exitCode of 709 710 ExitFailure x -> VInt $ toInteger x … … 711 712 return (VBool $ exitCode == ExitSuccess) 712 713 713 cascadeMethod :: ([ VStr] -> [VStr]) -> VStr-> Val -> Val -> Eval Val714 cascadeMethod :: ([String] -> [String]) -> String -> Val -> Val -> Eval Val 714 715 cascadeMethod f meth v args = do 715 716 typ <- evalValType v … … 737 738 op1Return :: Eval Val -> Eval Val 738 739 op1Return action = assertFrame FrameRoutine $ do 739 sub <- fromVal =<< readVar ( cast "&?ROUTINE")740 sub <- fromVal =<< readVar (_cast "&?ROUTINE") 740 741 -- If this is a coroutine, reset the entry point 741 742 case subCont sub of … … 751 752 op1Yield :: Eval Val -> Eval Val 752 753 op1Yield action = assertFrame FrameRoutine $ do 753 sub <- fromVal =<< readVar ( cast "&?ROUTINE")754 sub <- fromVal =<< readVar (_cast "&?ROUTINE") 754 755 case subCont sub of 755 756 Nothing -> fail $ "cannot yield() from a " ++ pretty (subType sub) … … 772 773 773 774 op1StrFirst :: (Char -> Char) -> Val -> Eval Val 774 op1StrFirst f = op1Cast $ VStr .775 op1StrFirst f = op1Cast $ _VStr . 775 776 \str -> case str of 776 777 [] -> [] … … 789 790 Just str -> do 790 791 ~(VList rest) <- getLines fh 791 return $ VList ( VStr str:rest)792 return $ VList (_VStr str:rest) 792 793 _ -> return (VList []) 793 794 getLine :: VHandle -> Eval Val … … 795 796 line <- liftIO $! doGetLine fh 796 797 case line of 797 Just str -> return $! VStr $! (length str `seq` str)798 Just str -> return $! _VStr $! (length str `seq` str) 798 799 _ -> return undef 799 doGetLine :: VHandle -> IO (Maybe VStr)800 doGetLine :: VHandle -> IO (Maybe String) 800 801 doGetLine fh = guardIOexcept [(isIOError isEOFError, Nothing)] $ do 801 802 line <- hGetLine fh … … 814 815 char <- hGetChar fh 815 816 str <- getChar' fh char 816 return $ VStr $ decodeUTF8 str817 return $ _VStr $ decodeUTF8 str 817 818 -- We may have to read more than one byte, as one utf-8 char can span 818 819 -- multiple bytes. … … 848 849 handleOf VUndef = handleOf (VList []) 849 850 handleOf (VList []) = do 850 argsGV <- readVar ( cast "$*ARGS")851 argsGV <- readVar (_cast "$*ARGS") 851 852 gv <- fromVal argsGV 852 853 if defined gv 853 854 then handleOf gv 854 855 else do 855 args <- readVar ( cast "@*ARGS")856 args <- readVar (_cast "@*ARGS") 856 857 files <- fromVal args 857 858 if null files 858 859 then return stdin 859 860 else do 860 hdl <- handleOf ( VStr (head files)) -- XXX wrong861 writeVar ( cast "$*ARGS") (VHandle hdl)861 hdl <- handleOf (_VStr (head files)) -- XXX wrong 862 writeVar (_cast "$*ARGS") (VHandle hdl) 862 863 return hdl 863 864 handleOf (VStr x) = do 864 return =<< guardIO $ openFile xReadMode865 return =<< guardIO $ openFile (cast x) ReadMode 865 866 handleOf (VList [x]) = handleOf x 866 867 handleOf v = fromVal v … … 895 896 mapStr f = map (chr . fromEnum . f) 896 897 897 mapStr2 :: (Word8 -> Word8 -> Word8) -> [Word8] -> [Word8] -> String898 mapStr2 f x y = map (chr . fromEnum . uncurry f) $ x `zip` y899 900 mapStr2Fill :: (Word8 -> Word8 -> Word8) -> [Word8] -> [Word8] -> String901 mapStr2Fill f x y = map (chr . fromEnum . uncurry f) $ x `zipFill` y898 mapStr2 :: (Word8 -> Word8 -> Word8) -> [Word8] -> [Word8] -> VStr 899 mapStr2 f x y = __ . map (chr . fromEnum . uncurry f) $ x `zip` y 900 901 mapStr2Fill :: (Word8 -> Word8 -> Word8) -> [Word8] -> [Word8] -> VStr 902 mapStr2Fill f x y = __ . map (chr . fromEnum . uncurry f) $ x `zipFill` y 902 903 where 903 904 zipFill [] [] = [] … … 906 907 zipFill (a:as) (b:bs) = (a,b) : zipFill as bs 907 908 908 op1Chomp :: VStr-> Val909 op1Chomp "" = VStr ""909 op1Chomp :: String -> Val 910 op1Chomp "" = _VStr "" 910 911 op1Chomp str 911 | last str == '\n' = VStr (init str)912 | otherwise = VStr str912 | last str == '\n' = _VStr (init str) 913 | otherwise = _VStr str 913 914 914 915 -- |Implementation of 2-arity primitive operators and functions … … 920 921 op2 "/" = op2Divide 921 922 op2 "%" = op2Modulus 922 op2 "x" = op2Cast (\x y -> VStr . concat $ (y :: VInt) `genericReplicate` x)923 op2 "x" = op2Cast (\x y -> _VStr . concat $ (y :: VInt) `genericReplicate` x) 923 924 op2 "xx" = op2Cast (\x y -> VList . concat $ (y :: VInt) `genericReplicate` x) 924 925 op2 "+&" = op2Int (.&.) … … 926 927 op2 "+>" = op2Int shiftR 927 928 op2 "~&" = op2Str $ mapStr2 (.&.) 928 op2 "~<" = op2Cast (\x y -> VStr $ mapStr (`shiftL` y) x)929 op2 "~>" = op2Cast (\x y -> VStr $ mapStr (`shiftR` y) x)929 op2 "~<" = op2Cast (\x y -> _VStr $ mapStr (`shiftL` y) x) 930 op2 "~>" = op2Cast (\x y -> _VStr $ mapStr (`shiftR` y) x) 930 931 op2 "**" = op2Exp 931 932 op2 "+" = op2Numeric (+) 932 933 op2 "-" = op2Numeric (-) 933 934 op2 "atan" = op2Num atan2 934 op2 "~" = op2Str (++ )935 op2 "~" = op2Str (+++) 935 936 op2 "+|" = op2Int (.|.) 936 937 op2 "+^" = op2Int xor … … 997 998 op2 "reduce" = op2ReduceL False 998 999 op2 "produce" = op2ReduceL True 999 op2 "reverse" = op2MaybeListop (VList . reverse) ( VStr . reverse)1000 op2 "reverse" = op2MaybeListop (VList . reverse) (_VStr . reverse) 1000 1001 op2 "chomp" = op2MaybeListop (VList . map op1Chomp) op1Chomp 1001 1002 op2 "kill" = \s v -> do … … 1011 1012 op2 "isa" = \x y -> do 1012 1013 typY <- case y of 1013 VStr str -> return $ mkTypestr1014 VStr str -> return $ cast str 1014 1015 _ -> fromVal y 1015 1016 typX <- fromVal x -- XXX consider line 224 of Pugs.Prim.Match case too … … 1018 1019 op2 "does" = \x y -> do 1019 1020 typY <- case y of 1020 VStr str -> return $ mkTypestr1021 VStr str -> return $ cast str 1021 1022 _ -> fromVal y 1022 1023 op2Match x (VType typY) … … 1069 1070 str <- fromVal x 1070 1071 arg <- fromVal y 1071 return $ VStr $ case arg of1072 return $ _VStr $ case arg of 1072 1073 VNum n -> printf str n 1073 1074 VRat r -> printf str ((fromRational r)::Double) 1074 1075 VInt i -> printf str i 1075 VStr s -> printf str s1076 VStr s -> printf str (cast s :: String) 1076 1077 _ -> fail "should never be reached given the type declared below" 1077 1078 op2 "system" = \x y -> do … … 1131 1132 1132 1133 baseDigit :: Char -> Maybe Val 1133 baseDigit '.' = return ( VStr ".")1134 baseDigit '.' = return (_VStr ".") 1134 1135 baseDigit ch | ch >= '0' && ch <= '9' = return (castV (ord ch - ord '0')) 1135 1136 baseDigit ch | ch >= 'a' && ch <= 'z' = return (castV (ord ch - ord 'a' + 10)) … … 1147 1148 return $ VRat (asFractional (0:post') + (asIntegral pre' % 1)) 1148 1149 where 1149 (pre, post) = break (== VStr ".") $ filter (/=VStr "_") vs1150 (pre, post) = break (== _VStr ".") $ filter (/= _VStr "_") vs 1150 1151 asIntegral = foldl (\x d -> base * x + d) 0 1151 1152 asFractional :: [VInt] -> VRat … … 1159 1160 _ -> return [v] 1160 1161 guardIO $ do 1161 forM_ strs ( hPutStr handle . encodeUTF8)1162 when wantNewline ( hPutStr handle "\n")1162 forM_ strs (Str.hPut handle) 1163 when wantNewline (Str.hPut handle (__"\n")) 1163 1164 return $ VBool True 1164 1165 … … 1175 1176 return $ split' delim str 1176 1177 where 1177 split' :: VStr -> VStr-> Val1178 split' [] xs = VList $ map ( VStr . (:[])) xs1179 split' glue xs = VList $ map VStr $ split glue xs1178 split' :: String -> String -> Val 1179 split' [] xs = VList $ map (_VStr . (:[])) xs 1180 split' glue xs = VList $ map _VStr $ split glue xs 1180 1181 1181 1182 op2MaybeListop :: forall tlist titem. (Value tlist, Value [tlist], Value titem) => … … 1213 1214 --kind <- fromVal =<< op1 "WHAT" x 1214 1215 kind <- case x of 1215 VStr str -> return $ mkTypestr1216 VStr str -> return $ cast str 1216 1217 _ -> fromVal x 1217 1218 skip <- fromVal y … … 1226 1227 return . VInt $ doIndex 0 str sub pos 1227 1228 where 1228 doIndex :: VInt -> VStr -> VStr-> VInt -> VInt1229 doIndex :: VInt -> String -> String -> VInt -> VInt 1229 1230 doIndex n a b p 1230 1231 | p > 0, null a = doIndex n a b 0 … … 1241 1242 return . VInt $ doRindex str sub skip 1242 1243 where 1243 doRindex :: VStr -> VStr-> Int -> VInt1244 doRindex :: String -> String -> Int -> VInt 1244 1245 doRindex a b skip 1245 1246 | skip > 0 = doRindex (init a) b (skip-1) … … 1284 1285 1285 1286 defs <- fetchMetaInfo "attrs" (showType typ) 1286 attrs <- liftIO $ H.new (==) H.hashString1287 attrs <- liftIO $ hashNew 1287 1288 writeIVar (IHash attrs) (named `Map.union` defs) 1288 1289 uniq <- newObjectId … … 1303 1304 (VObject o) <- fromVal t 1304 1305 attrs <- readIVar (IHash $ objAttrs o) 1305 attrs' <- liftIO $ H.new (==) H.hashString1306 attrs' <- liftIO $ hashNew 1306 1307 uniq <- newObjectId 1307 1308 writeIVar (IHash attrs') (named `Map.union` attrs) … … 1313 1314 pico <- fromVal z 1314 1315 c <- guardIO $ toCalendarTime $ TOD (offset + sec) pico 1315 if wantString then return $ VStr $ calendarTimeToString c else1316 if wantString then return $ _VStr $ calendarTimeToString c else 1316 1317 retSeq $ [ vI $ ctYear c 1317 1318 , vI $ (1+) $ fromEnum $ ctMonth c … … 1323 1324 , vI $ (1+) $ fromEnum $ ctWDay c 1324 1325 , vI $ ctYDay c 1325 , VStr $ ctTZName c1326 , _VStr $ ctTZName c 1326 1327 , vI $ ctTZ c 1327 1328 , VBool $ ctIsDST c … … 1373 1374 return $ split' delim str limit 1374 1375 where 1375 split' :: VStr -> VStr-> Int -> Val1376 split' [] xs n = VList $ (map ( VStr . (:[])) (take (n-1) xs)) ++ [VStr $ drop (n-1) xs ]1377 split' glue xs n = VList $ map VStr $ split_n glue xs n1376 split' :: String -> String -> Int -> Val 1377 split' [] xs n = VList $ (map (_VStr . (:[])) (take (n-1) xs)) ++ [ _VStr $ drop (n-1) xs ] 1378 split' glue xs n = VList $ map _VStr $ split_n glue xs n 1378 1379 1379 1380 -- XXX - The "String" below wants to be Type. 1380 fetchMetaInfo :: Value a => String -> [Char]-> Eval a1381 fetchMetaInfo :: Value a => String -> String -> Eval a 1381 1382 fetchMetaInfo key typ = do 1382 1383 meta <- readRef =<< fromVal =<< evalExp (_Var (':':'*':typ)) 1383 1384 fetch <- doHash meta hash_fetchVal 1384 fromVal =<< fetch key1385 fromVal =<< fetch (cast key) 1385 1386 1386 1387 -- |Implementation of 4-arity primitive operators and functions. … … 1397 1398 var <- fromVal x 1398 1399 rep <- fromVal new 1399 writeRef var ( VStr $ concat [pre, rep, post])1400 writeRef var (_VStr $ concat [pre, rep, post]) 1400 1401 -- If the replacement is given in w, change the str. 1401 1402 when (defined w && not (defined result)) $ change w … … 1403 1404 return $ VRef . MkRef $ proxyScalar (return result) change 1404 1405 where 1405 doSubstr :: VStr -> Int -> Int -> (VStr, Val, VStr)1406 doSubstr :: String -> Int -> Int -> (String, Val, String) 1406 1407 doSubstr str pos len 1407 1408 | abs pos > length str = ("", VUndef, "") 1408 1409 | pos < 0 = doSubstr str (length str + pos) len 1409 1410 | len < 0 = doSubstr str pos (length str - pos + len) 1410 | otherwise = ((take pos str), VStr (take len $ drop pos str), (drop (pos + len) str))1411 | otherwise = ((take pos str), _VStr (take len $ drop pos str), (drop (pos + len) str)) 1411 1412 1412 1413 -- op4 "splice" = \x y z w-> do … … 1422 1423 1423 1424 op1Range :: Val -> Eval Val 1424 op1Range (VStr s) = return . VList $ map VStr $ strRangeInf s1425 op1Range (VStr s) = return . VList $ map _VStr $ strRangeInf (cast s) 1425 1426 op1Range (VRat n) = return . VList $ map VRat [n ..] 1426 1427 op1Range (VNum n) = return . VList $ map VNum [n ..] … … 1433 1434 op2Range (VStr s) y = do 1434 1435 y' <- fromVal y 1435 return . VList $ map VStr $ strRange sy'1436 return . VList $ map _VStr $ strRange (cast s) y' 1436 1437 op2Range (VNum n) y = do 1437 1438 y' <- fromVal y … … 1515 1516 op2OrdNumStr x y 1516 1517 | isNumeric x && isNumeric y = op2Ord vCastRat x y 1517 | otherwise = op2Ord Numeric comparex y1518 | otherwise = op2Ord vCastStr x y 1518 1519 1519 1520 op3Caller :: Type -> Int -> Val -> Eval Val … … 1526 1527 formatFrame [] = retEmpty 1527 1528 formatFrame ((env, Just sub):_) = retSeq 1528 [ VStr $ cast (envPackage env) -- .package1529 , VStr $ posName $ envPos env -- .file1529 [ _VStr $ cast (envPackage env) -- .package 1530 , _VStr $ posName $ envPos env -- .file 1530 1531 , VInt $ toInteger $ posBeginLine $ envPos env -- .line 1531 , VStr $ cast (subName sub) -- .subname1532 , VStr $ show $ subType sub -- .subtype1532
