| | 370 | buildReduce var keep = do |
| | 371 | let rv = fmap (either (const Nothing) Just) $ |
| | 372 | findSub var Nothing firstTwoArgs |
| | 373 | maybeM rv $ \code -> return $ metaPrim |
| | 374 | { subAssoc = ANil |
| | 375 | , subParams = makeParams $ |
| | 376 | if any isLValue (subParams code) |
| | 377 | then ["rw!List"] -- XXX - does not yet work for the [=] case |
| | 378 | else ["List"] |
| | 379 | , subReturns = anyType |
| | 380 | , subBody = Prim $ \[vs] -> do |
| | 381 | list_of_args <- fromVal vs |
| | 382 | op2Reduce keep list_of_args (VCode code) |
| | 383 | } |
| | 384 | |
| 374 | | possiblyBuildMetaopVCode var@MkVar{ v_categ = cat, v_name = name } |
| 375 | | | C_prefix <- cat, __"\194\171" `Str.isSuffixOf` buf = do |
| 376 | | buildPrefixHyper buf var{ v_name = cast $ dropEnd 2 buf } |
| 377 | | | C_prefix <- cat, __"<<" `Str.isSuffixOf` buf = do |
| 378 | | buildPrefixHyper buf var{ v_name = cast $ dropEnd 2 buf } |
| 379 | | | C_postfix <- cat, __"\194\187" `Str.isPrefixOf` buf = do |
| 380 | | buildPostfixHyper buf var{ v_name = cast $ Str.drop 2 buf } |
| 381 | | | C_postfix <- cat, __">>" `Str.isPrefixOf` buf = do |
| 382 | | buildPostfixHyper buf var{ v_name = cast $ Str.drop 2 buf } |
| 383 | | | C_infix <- cat |
| 384 | | , __"\194\187" `Str.isPrefixOf` buf |
| 385 | | , __"\194\171" `Str.isSuffixOf` buf = do |
| 386 | | buildInfixHyper buf var{ v_name = cast $ Str.drop 2 (dropEnd 2 buf) } |
| 387 | | | C_infix <- cat |
| 388 | | , __">>" `Str.isPrefixOf` buf |
| 389 | | , __"<<" `Str.isSuffixOf` buf = do |
| 390 | | buildInfixHyper buf var{ v_name = cast $ Str.drop 2 (dropEnd 2 buf) } |
| 391 | | | C_prefix <- cat, '[' <- Str.head buf, ']' <- Str.last buf = do |
| 392 | | -- Strip the trailing "]" from op |
| 393 | | let (op, keep) |
| 394 | | | Str.index buf 1 == '\\' = (Str.drop 2 (Str.init buf), True) |
| 395 | | | otherwise = (Str.tail (Str.init buf), False) |
| 396 | | |
| 397 | | -- We try to find the userdefined sub. |
| 398 | | -- We use the first two elements of invs as invocants, as these are the |
| 399 | | -- types of the op. |
| 400 | | rv = fmap (either (const Nothing) Just) $ |
| 401 | | findSub (var{ v_categ = C_infix, v_name = cast op }) Nothing |
| 402 | | firstTwoArgs |
| 403 | | maybeM rv $ \code -> return $ mkPrim |
| 404 | | { subName = buf |
| 405 | | , subType = SubPrim |
| 406 | | , subAssoc = ANil |
| 407 | | , subParams = makeParams $ |
| 408 | | if any isLValue (subParams code) |
| 409 | | then ["rw!List"] -- XXX - does not yet work for the [=] case |
| 410 | | else ["List"] |
| 411 | | , subReturns = anyType |
| 412 | | , subBody = Prim $ \[vs] -> do |
| 413 | | list_of_args <- fromVal vs |
| 414 | | op2Reduce keep list_of_args (VCode code) |
| 415 | | } |
| 416 | | -- Now we construct the sub. Is there a more simple way to do it? |
| 417 | | | otherwise = return Nothing |
| | 386 | possiblyBuildMetaopVCode var@MkVar{ v_name = name, v_meta = meta } |
| | 387 | | MPost <- meta = buildPrefixHyper var' -- +<< |
| | 388 | | MPre <- meta = buildPostfixHyper var' -- >>+ |
| | 389 | | MHyper <- meta = buildInfixHyper var' -- >>+<< |
| | 390 | | MFold <- meta = buildReduce varInfix False -- [+] |
| | 391 | | MScan <- meta = buildReduce varInfix True -- [\+] |
| | 392 | | otherwise = return Nothing |