Nested sumtypes work with match-ref too.

This commit is contained in:
Erik Svedäng 2020-04-30 12:42:23 +02:00
parent f006e6ed75
commit 4988b40945
3 changed files with 17 additions and 4 deletions

View File

@ -68,5 +68,11 @@
(Nothing) (IO.println "nada"))))
(defn f []
(let [s (Just @"Yo")]
(match s
(Just x) (IO.println &x)
(Nothing) (IO.println "nada"))))
(defn g []
(match-ref &(Just (Just @"foooo"))
(Just (Just x)) (IO.println x)))

View File

@ -304,7 +304,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
-- A better idea is to not specialise the names, which happens when calling 'concretize' on the lhs
-- This requires a bunch of extra machinery though, so this will do for now...
[var ++ periodOrArrow ++ "_tag == " ++ tagName caseTy (removeSuffix caseName)] ++
concat (zipWith (\c i -> tagCondition (var ++ "." ++ (removeSuffix caseName) ++ ".member" ++ show i) "." (forceTy c) c) caseMatchers [0..])
concat (zipWith (\c i -> tagCondition (var ++ periodOrArrow ++ (removeSuffix caseName) ++ ".member" ++ show i) "." (forceTy c) c) caseMatchers [0..])
tagCondition _ _ _ x =
[]
--error ("tagCondition fell through: " ++ show x)
@ -316,8 +316,8 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
let Just tt = t
in appendToSrc (addIndent indent' ++ tyToCLambdaFix tt ++ " " ++ pathToC path ++ " = "
++ ampersandOrNot ++ tempVarToAvoidClash ++ periodOrArrow ++ mangle caseName ++ ".member" ++ show index ++ ";\n")
emitCaseMatcher _ caseName xobj@(XObj (Lst (XObj (Sym (SymPath _ innerCaseName) _) _ _ : xs)) i t) index =
zipWithM_ (\x i -> emitCaseMatcher (".", "") (caseName ++ ".member" ++ show i ++ "." ++ (removeSuffix innerCaseName)) x index) xs [0..]
emitCaseMatcher periodOrArrow caseName xobj@(XObj (Lst (XObj (Sym (SymPath _ innerCaseName) _) _ _ : xs)) i t) index =
zipWithM_ (\x i -> emitCaseMatcher periodOrArrow (caseName ++ ".member" ++ show i ++ "." ++ (removeSuffix innerCaseName)) x index) xs [0..]
emitCaseMatcher _ _ xobj _ =
error ("Failed to emit case matcher for: " ++ pretty xobj)

View File

@ -289,7 +289,7 @@ genConstraintsForCaseMatcher matchMode = gen
let expected t n = XObj (Sym (SymPath [] ("Expected " ++ enumerate n ++ " argument to '" ++ getName caseName ++ "'")) Symbol) (info caseName) (Just t)
argConstraints = zipWith4 (\a t aObj n -> Constraint a t aObj (expected t n) xobj OrdFuncAppArg)
(List.map forceTy variables)
(fmap (wrapInRefTyIfMatchRef matchMode) argTys)
(zipWith refWrapper variables argTys)
variables
[0..]
Just xobjTy = ty xobj
@ -302,3 +302,10 @@ genConstraintsForCaseMatcher matchMode = gen
in return (wholeTypeConstraint : caseNameConstraints ++ variablesConstraints)
_ -> Left (NotAFunction caseName) -- | TODO: This error could be more specific too, since it's not an actual function call.
gen x = return []
-- | If this is a 'match-ref' statement we want to wrap the type of *symbols* (not lists matching nested sumtypes) in a Ref type
-- | to make the type inference think they are refs.
-- | This will make sure we don't take ownership over the sumtype:s members, which would be catastrophic due to it not being owned by the match.
refWrapper :: XObj -> Ty -> Ty
refWrapper (XObj (Sym _ _) _ _) wrapThisType = wrapInRefTyIfMatchRef matchMode wrapThisType
refWrapper _ t = t