| | 794 | possiblyBuildMetaopVCode ('&':'p':'r':'e':'f':'i':'x':':':'[':op') = do |
| | 795 | -- Strip the trailing "]" from op |
| | 796 | let op = init op' |
| | 797 | trace (show $ invs) return () |
| | 798 | trace (show $ args) return () |
| | 799 | -- We try to find the userdefined sub. |
| | 800 | -- We use the first two elements of invs as invocants, as these are the |
| | 801 | -- types of the op. |
| | 802 | userdefined_sub <- findSub ("&infix:" ++ op) (take 2 invs) [] |
| | 803 | subbody <- return $ case userdefined_sub of |
| | 804 | -- If we've found a userdefined sub, we use it. |
| | 805 | (Just sub) -> Prim $ \_ -> do |
| | 806 | list_of_args <- return $ map evaluate invs |
| | 807 | list_of_args' <- mapM (\a -> do { z <- a; return z }) list_of_args |
| | 808 | op2Fold (VList list_of_args') (VCode sub) |
| | 809 | -- Else, we use the code as defined in Pugs.Prim |
| | 810 | _ -> Prim $ f op |
| | 811 | -- Now we construct the sub. Is there a more simple way to do it? |
| | 812 | code <- return $ mkPrim |
| | 813 | { subName = "&prefix:[" ++ op ++ "]" |
| | 814 | , subType = SubPrim |
| | 815 | , subAssoc = "spre" |
| | 816 | , subParams = params |
| | 817 | , subReturns = mkType "Str" |
| | 818 | , subBody = subbody |
| | 819 | } |
| | 820 | return $ Just code |
| | 821 | where |
| | 822 | -- Taken from Pugs.Prim. Probably this should be refactored. (?) |
| | 823 | f op = \[a] -> op1 ("[" ++ op ++ "]") a |
| | 824 | prms' = map takeWord ["(List)"] |
| | 825 | prms'' = foldr foldParam [] prms' |
| | 826 | params = map (\p -> p{ isWritable = isLValue p }) prms'' |
| | 827 | takeWord = takeWhile isWord . dropWhile (not . isWord) |
| | 828 | isWord = not . (`elem` "(),:") |
| | 829 | possiblyBuildMetaopVCode _ = return Nothing |