addType :: Term -> Term -> Term
addType (MixTypeTerm q ty ps) t = TypedTerm t q ty ps
addType _ _ = error "addType"
-- | try to reparse terms as a compound list
isCompoundList ::
Set.Set [Id] -> [Term] -> Bool
maybe False (`
Set.member` compIds) . mapM reparseAsId
isTypeList :: Env -> [Term] -> Bool
isTypeList e l = case mapM termToType l of
let Result ds ml = mapM ( \ t -> anaTypeM (Nothing, t) e) ts
in isJust ml && not (hasErrors ds)
termToType :: Term -> Maybe Type
>> parseType <<
P.eof) (emptyAnnos ()) "" $ showDoc t "" of
anaPolyId :: PolyId -> TypeScheme -> State Env (Maybe TypeScheme)
anaPolyId (PolyId i@(Id _ cs _) _ _) sc = do
Nothing -> return Nothing
Just newSc@(TypeScheme tvars _ _) -> do
addDiags $ map (mkDiag (if null tvars then Hint else Warning)
"unexpected identifier in compound list") es
unless (null cs || null tvars)
$ addDiags [mkDiag Hint "is polymorphic compound identifier" i]
resolveQualOp :: PolyId -> TypeScheme -> State Env TypeScheme
resolveQualOp i@(PolyId j _ _) sc = do
Nothing -> return sc -- and previous
$ addDiags [mkDiag Error "operation not found" j]
-> Chart Term -> State Env (Chart Term)
iterateCharts ga sIds compIds terms chart = do
let self = iterateCharts ga sIds compIds
oneStep = nextChart addType (toMixTerm e) ga chart
t : tt -> let recurse trm = self tt $ oneStep
(trm, exprTok {tokPos = getRange trm}) in case t of
MixfixTerm ts -> self (ts ++ tt) chart
MixTypeTerm q typ ps -> do
Just nTyp -> self tt $ oneStep
(MixTypeTerm q (monoType nTyp) ps, typeTok {tokPos = ps})
let bres = self (expandPos TermToken
(getBrackets b) ts ps ++ tt) chart in case (b, ts, tt) of
| isCompoundList compIds ts -> do
addDiags [mkDiag Hint "is compound list" t]
let testChart = oneStep (t, typeInstTok {tokPos = ps})
if null $ solveDiags testChart then do
addDiags [mkDiag Hint "is type list" t]
(Parens, [QualOp b2 v sc [] _ ps2], hd@(BracketTerm Squares
addDiags [mkDiag Hint "is type list" ts2]
nSc <- resolveQualOp v sc
( QualOp b2 v nSc (bracketTermToTypes e hd) UserGiven ps2
, exprTok {tokPos = appRange ps ps3})
QualVar (VarDecl v typ ok ps) -> do
recurse $ maybe t ( \ nType -> QualVar $ VarDecl v (monoType nType)
QualOp b v sc [] k ps -> do
nSc <- resolveQualOp v sc
recurse $ QualOp b v nSc [] k ps
QuantifiedTerm quant decls hd ps -> do
newDs <- mapM (anaddGenVarDecl False) decls
recurse $ QuantifiedTerm quant (catMaybes newDs) (fromMaybe hd mt) ps
LambdaTerm decls part hd ps -> do
mDecls <- mapM resolve decls
let anaDecls = catMaybes mDecls
bs = concatMap extractVars anaDecls
mapM_ (addLocalVar False) bs
recurse $ LambdaTerm anaDecls part (fromMaybe hd mt) ps
newEs <- resolveCaseEqs eqs
recurse $ CaseTerm (fromMaybe hd mt) newEs ps
LetTerm b eqs hd ps -> do
newEs <- resolveLetEqs eqs
recurse $ LetTerm b newEs (fromMaybe hd mt) ps
let (ds1, trm) = convertMixfixToken (literal_annos ga)
(flip ResolvedMixTerm []) TermToken tok
self tt $ oneStep $ case trm of
TermToken _ -> (trm, tok)
_ -> (trm, exprTok {tokPos = tokPos tok})
recurse $ AsPattern vd (fromMaybe p mp) ps
TypedTerm trm k ty ps -> do
-- assume that type is analysed
recurse $ TypedTerm (fromMaybe trm mt) k ty ps
_ -> error ("iterCharts: " ++ show t)
resolveCaseEq :: ProgEq -> State Env (Maybe ProgEq)
resolveCaseEq (ProgEq p t ps) = do
Nothing -> return Nothing
let bs = extractVars newP
mapM_ (addLocalVar False) bs
Just newT -> Just $ ProgEq newP newT ps
resolveCaseEqs :: [ProgEq] -> State Env [ProgEq]
resolveCaseEqs eqs = case eqs of
reqs <- resolveCaseEqs rt
Just newEq -> newEq : reqs
resolveLetEqs :: [ProgEq] -> State Env [ProgEq]
resolveLetEqs eqs = case eqs of
ProgEq pat trm ps : rt -> do
let bs = extractVars newPat
mapM_ (addLocalVar False) bs
Nothing -> resolveLetEqs rt
return $ ProgEq newPat newTrm ps : reqs
mkPatAppl :: Term -> Term -> Range -> Term
mkPatAppl op arg qs = case op of
QualVar (VarDecl i (MixfixType []) _ _) -> ResolvedMixTerm i [] [arg] qs
bracketTermToTypes :: Env -> Term -> [Type]
bracketTermToTypes e t = case t of
BracketTerm Squares tys _ ->
map (monoType . snd) $ fromMaybe (error "bracketTermToTypes")
$ maybeResult $ mapM ( \ ty -> anaTypeM (Nothing, ty) e)
$ fromMaybe (error "bracketTermToTypes1") $ mapM termToType tys
_ -> error "bracketTermToTypes2"
toMixTerm :: Env -> Id -> [Term] -> Range -> Term
| i == applId = assert (length ar == 2) $
let [op, arg] = ar in mkPatAppl op arg qs
| elem i [tupleId, unitId] = mkTupleTerm ar qs
| otherwise = case unPolyId i of
Just j@(Id ts _ _) -> if isMixfix j && isSingle ar then
ResolvedMixTerm j (bracketTermToTypes e $ head ar) [] qs
else assert (length ar == 1 + placeCount j) $
splitAt (placeCount $ mkId $ fst $ splitMixToken ts) ar
in ResolvedMixTerm j (bracketTermToTypes e tar) (far ++ sar) qs
_ -> ResolvedMixTerm i [] ar qs
resolve :: Term -> State Env (Maybe Term)
(addRule, ruleS, sIds) = makeRules ga (preIds e) (getPolyIds ass)
chart <- iterateCharts ga sIds (getCompoundLists e) [trm]
$ initChart addRule ruleS
let Result ds mr = getResolved (showDoc . parenTerm) (getRange trm)
getPolyIds :: Assumps ->
Set.Set Id
builtinIds = [unitId, parenId, tupleId, exprId, typeId, applId]
makeRules ga ps@(p, _) polyIds aIds =
in ( \ tok -> if isSimpleToken tok && not (
Set.member tok ks)
, partitionRules $ listRules m2 ga ++
initRules :: (PrecMap,
Set.Set Id) -> [Id] -> [Id] -> [Id] -> [Rule]
initRules (p, ps) polyIds bs is =
map ( \ i -> mixRule (getIdPrec p ps i) i)
map ( \ i -> (protect i, maxWeight p + 3, getPlainTokenList i))
-- identifiers with a positive number of type arguments
map ( \ i -> ( polyId i, getIdPrec p ps i
, getPolyTokenList i)) polyIds ++
map ( \ i -> ( protect $ polyId i, maxWeight p + 3
, getPlainPolyTokenList i)) (filter isMixfix polyIds)