Show
Ignore:
Timestamp:
09/26/06 14:15:58 (2 years ago)
Author:
audreyt
Message:

* Pugs.Prim.List: Add support for list-associative reductions, such as [|].
* Also added identity values for the builtin reduceable operators from S03.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Prim/List.hs

    r12436 r13678  
    166166 
    167167op2Reduce :: Bool -> Val -> Val -> Eval Val 
    168 op2Reduce keep sub@(VCode _) list = op2Reduce keep list sub 
     168op2Reduce keep sub@VCode{} list = op2Reduce keep list sub 
    169169op2Reduce keep list sub = do 
    170170    code <- fromVal sub 
    171171    args <- fromVal list 
     172    if null args then identityVal (subName code) else do 
    172173    -- cxt  <- asks envContext 
    173     let (reduceM, reduceMn) = if keep then (scanM, scanMn) else (foldM, foldMn) 
    174174    let arity = length $ subParams code 
     175        (reduceM, reduceMn) = if keep then (scanM, scanMn) else (foldM, foldMn) 
     176        applyListAssoc = do 
     177            evl <- asks envEval 
     178            evl $ App (Val $ VCode code{ subParams = length args `replicate` head (subParams code)}) Nothing (map Val args) 
     179    if subAssoc code == A_list then applyListAssoc else do 
    175180    if arity < 2 then fail "Cannot reduce() using a unary or nullary function." else do 
    176181    -- n is the number of *additional* arguments to be passed to the sub. 
     
    179184    let n = arity - 1 
    180185    -- Break on empty list. 
    181     if null args then return undef else do 
    182186    let doFold xs = do 
    183187        evl <- asks envEval 
     
    218222            rest <- fromVal =<< scanM f fqx xs 
    219223            return $ VList (q:rest) 
     224    identityVal name = case nameStr of 
     225        "**"    -> _1 
     226        "*"     -> _1 
     227        "/"     -> _fail 
     228        "%"     -> _fail 
     229        "x"     -> _fail 
     230        "xx"    -> _fail 
     231        "+&"    -> _neg1 
     232        "+<"    -> _fail 
     233        "+>"    -> _fail 
     234        "~&"    -> _fail 
     235        "~<"    -> _fail 
     236        "~>"    -> _fail 
     237        "+"     -> _0 
     238        "-"     -> _0 
     239        "~"     -> _'' 
     240        "+|"    -> _0 
     241        "+^"    -> _0 
     242        "~|"    -> _'' 
     243        "~^"    -> _'' 
     244        "&"     -> _junc JAll 
     245        "|"     -> _junc JAny 
     246        "^"     -> _junc JOne 
     247        "!="    -> _false 
     248        "=="    -> _true 
     249        "<"     -> _true 
     250        "<="    -> _true 
     251        ">"     -> _true 
     252        ">="    -> _true 
     253        "~~"    -> _true 
     254        "eq"    -> _true 
     255        "ne"    -> _false 
     256        "lt"    -> _true 
     257        "le"    -> _true 
     258        "gt"    -> _true 
     259        "ge"    -> _true 
     260        "=:="   -> _true 
     261        "==="   -> _true 
     262        "eqv"   -> _true 
     263        "&&"    -> _true 
     264        "||"    -> _false 
     265        "^^"    -> _false 
     266        ","     -> _list 
     267        "Y"     -> _list 
     268     -- "\xA5"      -> _list 
     269        "\xC2\xA5"  -> _list 
     270        ('!':_) -> _false 
     271        _           -> _undef 
     272        where 
     273        nameStr = cast name 
     274        _0      = return (VInt 0) 
     275        _1      = return (VInt 1) 
     276        _undef  = return undef 
     277        _false  = return (VBool False) 
     278        _true   = return (VBool True) 
     279        _list   = return (VList []) 
     280        _neg1   = return (VInt (toInteger (complement 0 :: Word))) 
     281        _junc   = \jtyp -> return . VJunc $ MkJunc jtyp Set.empty Set.empty 
     282        _''     = return (VStr "") 
     283        _fail   = fail $ "reduce is nonsensical for " ++ cast name 
    220284 
    221285op2Grep :: Val -> Val -> Eval Val