Changed the occam type checker to handle checking user defined operators better
They are now recursed into with no type context, then afterwards the type is deduced. This seems to be how they were meant to work, and is also much faster than what I was doing.
This commit is contained in:
parent
7031ab7fb8
commit
a8c9802f5d
|
@ -720,35 +720,28 @@ inferTypes = occamOnlyPass "Infer types"
|
||||||
2 -> "binary"
|
2 -> "binary"
|
||||||
n -> show n ++ "-ary"
|
n -> show n ++ "-ary"
|
||||||
|
|
||||||
|
es' <- noTypeContext $ mapM recurse es
|
||||||
|
tes <- sequence [astTypeOf e `catchError` (const $ return A.Infer) | e <- es']
|
||||||
|
|
||||||
cs <- getCompState
|
cs <- getCompState
|
||||||
|
|
||||||
-- The nubBy will ensure that only one definition remains for each
|
-- The nubBy will ensure that only one definition remains for each
|
||||||
-- set of type-arguments, and will keep the first definition in the
|
-- set of type-arguments, and will keep the first definition in the
|
||||||
-- list (which will be the most recent)
|
-- list (which will be the most recent)
|
||||||
possibles <- sequence
|
possibles <- return
|
||||||
[ (do es' <- sequence
|
[ ((opFuncName, es'), ts)
|
||||||
[do e' <- doActual m direct t e
|
|
||||||
checkActual (A.Formal A.ValAbbrev t (A.Name m "x"))
|
|
||||||
(A.ActualExpression e')
|
|
||||||
return e'
|
|
||||||
| (t, e) <- zip ts es]
|
|
||||||
return $ Right ((opFuncName, es'), ts)
|
|
||||||
) `catchError` (return . Left)
|
|
||||||
| (raw, opFuncName, ts) <- nubBy ((==) `on` (\(op,_,ts) -> (op,ts))) $ csOperators cs
|
| (raw, opFuncName, ts) <- nubBy ((==) `on` (\(op,_,ts) -> (op,ts))) $ csOperators cs
|
||||||
-- Must be right operator:
|
-- Must be right operator:
|
||||||
, raw == A.nameName n
|
, raw == A.nameName n
|
||||||
-- Must be right arity:
|
-- Must be right arity:
|
||||||
, length ts == length es]
|
, length ts == length es
|
||||||
case splitEither possibles of
|
-- Must have right types:
|
||||||
-- We want to be helpful and give the user an idea
|
, ts == tes
|
||||||
-- of what we thought the types were, but we must
|
]
|
||||||
-- also be careful not to die while getting the
|
case possibles of
|
||||||
-- types (and thus missing the real error!)
|
[] -> diePC m $ formatCode ("No matching " ++ opDescrip ++ " operator definition found for types: %") tes
|
||||||
(errs,[]) -> do tes <- sequence [astTypeOf e `catchError` (const $ return A.Infer) | e <- es]
|
[poss] -> return $ fst poss
|
||||||
diePC m $ formatCode ("No matching " ++ opDescrip ++ " operator definition found for types: %"
|
posss -> dieP m $ "Ambigious " ++ opDescrip ++ " operator, matches definitions: "
|
||||||
++ " errors were: " ++ show errs) tes
|
|
||||||
(_, [poss]) -> return $ fst poss
|
|
||||||
(_, posss) -> dieP m $ "Ambigious " ++ opDescrip ++ " operator, matches definitions: "
|
|
||||||
++ show (map (transformPair (A.nameMeta . fst) showOccam) posss)
|
++ show (map (transformPair (A.nameMeta . fst) showOccam) posss)
|
||||||
else
|
else
|
||||||
do (_, fs) <- checkFunction m n
|
do (_, fs) <- checkFunction m n
|
||||||
|
|
Loading…
Reference in New Issue
Block a user