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