Changeset 3473

Show
Ignore:
Timestamp:
05/20/05 00:14:37 (4 years ago)
Author:
autrijus
svk:copy_cache_prev:
5016
Message:

* associativity-preserving reduction over left, right

and chain infix operators.

Location:
src/Pugs
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Eval.hs

    r3469 r3473  
    809809        -- We use the first two elements of invs as invocants, as these are the 
    810810        -- types of the op. 
    811         userdefined_sub <- findSub ("&infix:" ++ op) (take 2 invs) [] 
    812         subbody <- return $ case userdefined_sub of 
    813             -- If we've found a userdefined sub, we use it. 
    814             (Just sub) -> Prim $ \_ -> do 
    815                               list_of_args <- return $ map evaluate invs 
    816                               list_of_args' <- mapM (\a -> do { z <- a; return z }) list_of_args 
    817                               op2Fold (VList list_of_args') (VCode sub) 
    818             -- Else, we use the code as defined in Pugs.Prim 
    819             _          -> Prim $ f op 
     811        code <- findSub ("&infix:" ++ op) (take 2 (invs ++ [Val undef, Val undef])) [] 
     812        if isNothing code then return Nothing else do 
     813        let subBody = const $ do 
     814                list_of_args    <- mapM evaluate invs 
     815                op2Fold (VList list_of_args) (VCode $ fromJust code) 
    820816        -- Now we construct the sub. Is there a more simple way to do it? 
    821         code <- return $ mkPrim 
    822                             { subName     = "&prefix:[" ++ op ++ "]" 
    823                             , subType     = SubPrim 
    824                             , subAssoc    = "spre" 
    825                             , subParams   = params 
    826                             , subReturns  = mkType "Str" 
    827                             , subBody     = subbody 
    828                             } 
    829         return $ Just code 
     817        return . Just $ mkPrim 
     818            { subName     = "&prefix:[" ++ op ++ "]" 
     819            , subType     = SubPrim 
     820            , subAssoc    = "spre" 
     821            , subParams   = params 
     822            , subReturns  = mkType "Str" 
     823            , subBody     = Prim subBody 
     824            } 
    830825        where 
    831826        -- Taken from Pugs.Prim. Probably this should be refactored. (?) 
    832         f op     = \[a] -> op1 ("[" ++ op ++ "]") a 
    833827        prms'    = map takeWord ["(List)"] 
    834828        prms''   = foldr foldParam [] prms' 
  • src/Pugs/Prim.hs

    r3466 r3473  
    252252    else return undef 
    253253 
    254 op1 ('[':op) = op1Fold . op2 . init $ op 
    255254op1 "rand"  = \v -> do 
    256255    x    <- fromVal v 
     
    11971196\\n   Str       left    ~^      (Str, Str)\ 
    11981197\\n   Str       left    ?|      (Str, Str)\ 
    1199 \\n   Pair      non     =>      (Any, Any)\ 
     1198\\n   Pair      right   =>      (Any, Any)\ 
    12001199\\n   Int       non     cmp     (Str, Str)\ 
    12011200\\n   Int       non     <=>     (Num, Num)\ 
  • src/Pugs/Prim/List.hs

    r3372 r3473  
    11module Pugs.Prim.List ( 
    2     op0Zip, op1Fold, op1Pick, op1Sum, 
     2    op0Zip, op1Pick, op1Sum, 
    33    op2Fold, op2Grep, op2Map, op2Join, 
    44    sortByM, 
     
    2222    zipRest  []     = [] 
    2323    zipRest  (_:xs) = xs 
    24  
    25 op1Fold :: (Val -> Val -> Eval Val) -> Val -> Eval Val 
    26 op1Fold op v = do 
    27     args    <- fromVal v 
    28     case args of 
    29         (a:as)  -> foldM op a as 
    30         _       -> return undef 
    3124 
    3225op1Pick :: Val -> Eval Val 
     
    5851op2Fold sub@(VCode _) list = op2Fold list sub 
    5952op2Fold list sub = do 
     53    code <- fromVal sub 
    6054    args <- fromVal list 
    6155    if null args then return undef else do 
     
    6458        local (\e -> e{ envContext = cxtItemAny }) $ do 
    6559            evl (App (Val sub) [Val x, Val y] []) 
    66     foldM doFold (head args) (tail args) 
     60    case subAssoc code of 
     61        "left"  -> foldM doFold (head args) (tail args) 
     62        "right" -> do 
     63            let args' = reverse args 
     64            foldM (flip doFold) (head args') (tail args') 
     65        "chain" -> callCC $ \esc -> do 
     66            let doFold' x y = do 
     67                val <- doFold x y 
     68                case val of 
     69                    VBool False -> esc val 
     70                    _           -> return val 
     71            foldM doFold' (head args) (tail args) 
     72        _ -> fail $ "Cannot reduce over associativity:" ++ show (subAssoc code) 
    6773 
    6874op2Grep :: Val -> Val -> Eval Val