summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Olsen <scg.olsen@gmail.com>2022-12-28 01:16:56 -0600
committerGitHub <noreply@github.com>2022-12-28 08:16:56 +0100
commit25f50c92a57cc91b6cb4ec48df658439f936b641 (patch)
tree15d1d8c0bcc6b34a9449ed802f73b0762dfbb803
parent8c5845ea656b80980e8f6b3b39a9477097d6291e (diff)
chore: make Carp compile w/ GHC 9.2 + stack lts20.0 (#1449)
-rw-r--r--src/ArrayTemplates.hs406
-rw-r--r--src/AssignTypes.hs10
-rw-r--r--src/BoxTemplates.hs106
-rw-r--r--src/Concretize.hs46
-rw-r--r--src/Emit.hs201
-rw-r--r--src/Env.hs8
-rw-r--r--src/Eval.hs17
-rw-r--r--src/Expand.hs3
-rw-r--r--src/GenerateConstraints.hs198
-rw-r--r--src/Info.hs9
-rw-r--r--src/InitialTypes.hs11
-rw-r--r--src/Interfaces.hs4
-rw-r--r--src/Memory.hs36
-rw-r--r--src/Meta.hs10
-rw-r--r--src/Obj.hs71
-rw-r--r--src/Parsing.hs25
-rw-r--r--src/Polymorphism.hs5
-rw-r--r--src/Primitives.hs19
-rw-r--r--src/Project.hs69
-rw-r--r--src/Qualify.hs42
-rw-r--r--src/RenderDocs.hs13
-rw-r--r--src/StartingEnv.hs9
-rw-r--r--src/StaticArrayTemplates.hs115
-rw-r--r--src/Sumtypes.hs16
-rw-r--r--src/Template.hs12
-rw-r--r--src/TypeError.hs4
26 files changed, 855 insertions, 610 deletions
diff --git a/src/ArrayTemplates.hs b/src/ArrayTemplates.hs
index 2cf8e325..35fc4065 100644
--- a/src/ArrayTemplates.hs
+++ b/src/ArrayTemplates.hs
@@ -36,11 +36,15 @@ templateEMap =
Template
templateType
(templateLiteral "Array $NAME(Lambda *f, Array a)")
- ( \(FuncTy [_, StructTy (ConcreteNameTy (SymPath [] "Array")) [memberTy]] _ _) ->
- handleUnits memberTy
+ ( \case
+ (FuncTy [_, StructTy (ConcreteNameTy (SymPath [] "Array")) [memberTy]] _ _) ->
+ handleUnits memberTy
+ _ -> error "array templates: emap called on non array"
)
- ( \(FuncTy [RefTy t@(FuncTy fArgTys fRetTy _) _, _] _ _) ->
- [defineFunctionTypeAlias t, defineFunctionTypeAlias (FuncTy (lambdaEnvTy : fArgTys) fRetTy StaticLifetimeTy)]
+ ( \case
+ (FuncTy [RefTy t@(FuncTy fArgTys fRetTy _) _, _] _ _) ->
+ [defineFunctionTypeAlias t, defineFunctionTypeAlias (FuncTy (lambdaEnvTy : fArgTys) fRetTy StaticLifetimeTy)]
+ _ -> error "array templates: emap called on non array"
)
where
elt = "((($a*)a.data)[i])"
@@ -96,16 +100,20 @@ templateEFilter = defineTypeParameterizedTemplate templateCreator path t docs
Template
t
(const (toTemplate "Array $NAME(Lambda *predicate, Array a)")) -- Lambda used to be $(Fn [(Ref a)] Bool)
- ( \(FuncTy [RefTy (FuncTy [RefTy insideTy _] BoolTy _) _, _] _ _) ->
- let deleteCall = insideArrayDeletion typeEnv env insideTy
- in ( case insideTy of
- UnitTy -> declaration " insertIndex++; /* ignore () member; just increment length. */" deleteCall
- _ -> declaration " ((($a*)a.data)[insertIndex++]) = (($a*)a.data)[i];" deleteCall
- )
+ ( \case
+ (FuncTy [RefTy (FuncTy [RefTy insideTy _] BoolTy _) _, _] _ _) ->
+ let deleteCall = insideArrayDeletion typeEnv env insideTy
+ in ( case insideTy of
+ UnitTy -> declaration " insertIndex++; /* ignore () member; just increment length. */" deleteCall
+ _ -> declaration " ((($a*)a.data)[insertIndex++]) = (($a*)a.data)[i];" deleteCall
+ )
+ _ -> error "array tempaltes: efilter called on non-array"
)
- ( \(FuncTy [RefTy ft@(FuncTy fArgTys@[RefTy insideType _] BoolTy _) _, _] _ _) ->
- [defineFunctionTypeAlias ft, defineFunctionTypeAlias (FuncTy (lambdaEnvTy : fArgTys) BoolTy StaticLifetimeTy)]
- ++ depsForDeleteFunc typeEnv env insideType
+ ( \case
+ (FuncTy [RefTy ft@(FuncTy fArgTys@[RefTy insideType _] BoolTy _) _, _] _ _) ->
+ [defineFunctionTypeAlias ft, defineFunctionTypeAlias (FuncTy (lambdaEnvTy : fArgTys) BoolTy StaticLifetimeTy)]
+ ++ depsForDeleteFunc typeEnv env insideType
+ _ -> error "array tempaltes: efilter called on non-array"
)
templatePushBack :: (String, Binder)
@@ -133,17 +141,24 @@ templatePushBack =
\_ _ ->
Template
t
- ( \(FuncTy [_, valueTy] _ _) ->
- case valueTy of
- UnitTy -> toTemplate "Array $NAME(Array a)"
- _ -> toTemplate "Array $NAME(Array a, $a value)"
+ ( \case
+ (FuncTy [_, valueTy] _ _) ->
+ case valueTy of
+ UnitTy -> toTemplate "Array $NAME(Array a)"
+ _ -> toTemplate "Array $NAME(Array a, $a value)"
+ _ -> error "array tempaltes: push back called on non array"
)
- ( \(FuncTy [_, valueTy] _ _) ->
- case valueTy of
- UnitTy -> declaration " /* ignore () member */"
- _ -> declaration " (($a*)a.data)[a.len - 1] = value;"
+ ( \case
+ (FuncTy [_, valueTy] _ _) ->
+ case valueTy of
+ UnitTy -> declaration " /* ignore () member */"
+ _ -> declaration " (($a*)a.data)[a.len - 1] = value;"
+ _ -> error "array tempaltes: push back called on non array"
+ )
+ ( \case
+ (FuncTy [_, _] _ _) -> []
+ _ -> error "array tempaltes: push back called on non array"
)
- (\(FuncTy [_, _] _ _) -> [])
templatePushBackBang :: (String, Binder)
templatePushBackBang =
@@ -169,17 +184,24 @@ templatePushBackBang =
\_ _ ->
Template
t
- ( \(FuncTy [_, valueTy] _ _) ->
- case valueTy of
- UnitTy -> toTemplate "void $NAME(Array *aRef)"
- _ -> toTemplate "void $NAME(Array *aRef, $a value)"
+ ( \case
+ (FuncTy [_, valueTy] _ _) ->
+ case valueTy of
+ UnitTy -> toTemplate "void $NAME(Array *aRef)"
+ _ -> toTemplate "void $NAME(Array *aRef, $a value)"
+ _ -> error "array templates pushback bang called on non array"
)
- ( \(FuncTy [_, valueTy] _ _) ->
- case valueTy of
- UnitTy -> declaration " /* ignore () member */"
- _ -> declaration " (($a*)aRef->data)[aRef->len - 1] = value;"
+ ( \case
+ (FuncTy [_, valueTy] _ _) ->
+ case valueTy of
+ UnitTy -> declaration " /* ignore () member */"
+ _ -> declaration " (($a*)aRef->data)[aRef->len - 1] = value;"
+ _ -> error "array templates: pushbackbang called on non array"
+ )
+ ( \case
+ (FuncTy [_, _] _ _) -> []
+ _ -> error "array templates: pushbackbang called on non array"
)
- (\(FuncTy [_, _] _ _) -> [])
templatePopBack :: (String, Binder)
templatePopBack = defineTypeParameterizedTemplate templateCreator path t docs
@@ -192,23 +214,27 @@ templatePopBack = defineTypeParameterizedTemplate templateCreator path t docs
Template
t
(const (toTemplate "Array $NAME(Array a)"))
- ( \(FuncTy [StructTy _ [insideTy]] _ _) ->
- let deleteElement = insideArrayDeletion typeEnv env insideTy
- in toTemplate
- ( unlines
- [ "$DECL { ",
- " assert(a.len > 0);",
- " a.len--;",
- " " ++ deleteElement "a.len",
- templateShrinkCheck "a",
- " return a;",
- "}"
- ]
- )
+ ( \case
+ (FuncTy [StructTy _ [insideTy]] _ _) ->
+ let deleteElement = insideArrayDeletion typeEnv env insideTy
+ in toTemplate
+ ( unlines
+ [ "$DECL { ",
+ " assert(a.len > 0);",
+ " a.len--;",
+ " " ++ deleteElement "a.len",
+ templateShrinkCheck "a",
+ " return a;",
+ "}"
+ ]
+ )
+ _ -> error "array templates: pop back called on non array"
)
- ( \(FuncTy [arrayType@(StructTy _ [insideTy])] _ _) ->
- depsForDeleteFunc typeEnv env arrayType
- ++ depsForCopyFunc typeEnv env insideTy
+ ( \case
+ (FuncTy [arrayType@(StructTy _ [insideTy])] _ _) ->
+ depsForDeleteFunc typeEnv env arrayType
+ ++ depsForCopyFunc typeEnv env insideTy
+ _ -> error "array templates: pop back called on non array"
)
templatePopBackBang :: (String, Binder)
@@ -224,27 +250,32 @@ templatePopBackBang =
Template
t
(templateLiteral "$a $NAME(Array *aRef)")
- ( \(FuncTy _ returnTy _) ->
- case returnTy of
- UnitTy ->
- multilineTemplate
- [ "$DECL { ",
- " assert(aRef->len > 0);",
- " aRef->len--;",
- "}"
- ]
- _ ->
- multilineTemplate
- [ "$DECL { ",
- " $a ret;",
- " assert(aRef->len > 0);",
- " ret = (($a*)aRef->data)[aRef->len - 1];",
- " aRef->len--;",
- " return ret;",
- "}"
- ]
+ ( \case
+ (FuncTy _ returnTy _) ->
+ case returnTy of
+ UnitTy ->
+ multilineTemplate
+ [ "$DECL { ",
+ " assert(aRef->len > 0);",
+ " aRef->len--;",
+ "}"
+ ]
+ _ ->
+ multilineTemplate
+ [ "$DECL { ",
+ " $a ret;",
+ " assert(aRef->len > 0);",
+ " ret = (($a*)aRef->data)[aRef->len - 1];",
+ " aRef->len--;",
+ " return ret;",
+ "}"
+ ]
+ _ -> error "array tempaltes: pop back bang called on non array"
+ )
+ ( \case
+ (FuncTy [_] _ _) -> []
+ _ -> error "array templates: pop back bang called on non array"
)
- (\(FuncTy [_] _ _) -> [])
templateNth :: (String, Binder)
templateNth =
@@ -264,8 +295,9 @@ templateNth =
"}"
]
)
- ( \(FuncTy [RefTy _ _, _] _ _) ->
- []
+ ( \case
+ (FuncTy [RefTy _ _, _] _ _) -> []
+ _ -> error "array templates: nth called on non array"
)
templateRaw :: (String, Binder)
@@ -276,7 +308,10 @@ templateRaw =
"returns an array `a` as a raw pointer—useful for interacting with C."
(toTemplate "$t* $NAME (Array a)")
(toTemplate "$DECL { return a.data; }")
- (\(FuncTy [_] _ _) -> [])
+ ( \case
+ (FuncTy [_] _ _) -> []
+ _ -> error "array templates: raw called on non array"
+ )
templateUnsafeRaw :: (String, Binder)
templateUnsafeRaw =
@@ -286,7 +321,10 @@ templateUnsafeRaw =
"returns an array `a` as a raw pointer—useful for interacting with C."
(toTemplate "$t* $NAME (Array* a)")
(toTemplate "$DECL { return a->data; }")
- (\(FuncTy [RefTy _ _] _ _) -> [])
+ ( \case
+ (FuncTy [RefTy _ _] _ _) -> []
+ _ -> error "array templates: unsafe raw called on non array"
+ )
-- Several setter functions need to ensure the array's member type isn't Unit
-- Such setters only run a side effect, so we can even drop bounds checks.
@@ -308,29 +346,35 @@ templateAset = defineTypeParameterizedTemplate templateCreator path t docs
\typeEnv env ->
Template
t
- ( \(FuncTy [_, _, insideTy] _ _) ->
- case insideTy of
- UnitTy -> toTemplate "Array $NAME (Array a, int n)"
- _ -> toTemplate "Array $NAME (Array a, int n, $t newValue)"
+ ( \case
+ (FuncTy [_, _, insideTy] _ _) ->
+ case insideTy of
+ UnitTy -> toTemplate "Array $NAME (Array a, int n)"
+ _ -> toTemplate "Array $NAME (Array a, int n, $t newValue)"
+ _ -> error "array templates: aset called with non array"
)
- ( \(FuncTy [_, _, insideTy] _ _) ->
- case insideTy of
- -- Just return the same array for unit members.
- UnitTy -> toTemplate "$DECL { return a; }"
- _ ->
- let deleter = insideArrayDeletion typeEnv env insideTy
- in multilineTemplate
- [ "$DECL {",
- " assert(n >= 0);",
- " assert(n < a.len);",
- deleter "n",
- " (($t*)a.data)[n] = newValue;",
- " return a;",
- "}"
- ]
+ ( \case
+ (FuncTy [_, _, insideTy] _ _) ->
+ case insideTy of
+ -- Just return the same array for unit members.
+ UnitTy -> toTemplate "$DECL { return a; }"
+ _ ->
+ let deleter = insideArrayDeletion typeEnv env insideTy
+ in multilineTemplate
+ [ "$DECL {",
+ " assert(n >= 0);",
+ " assert(n < a.len);",
+ deleter "n",
+ " (($t*)a.data)[n] = newValue;",
+ " return a;",
+ "}"
+ ]
+ _ -> error "array templates: aset called with non array"
)
- ( \(FuncTy [_, _, insideTy] _ _) ->
- depsForDeleteFunc typeEnv env insideTy
+ ( \case
+ (FuncTy [_, _, insideTy] _ _) ->
+ depsForDeleteFunc typeEnv env insideTy
+ _ -> error "array templates: aset called with non array"
)
templateAsetBang :: (String, Binder)
@@ -343,28 +387,34 @@ templateAsetBang = defineTypeParameterizedTemplate templateCreator path t docs
\typeEnv env ->
Template
t
- ( \(FuncTy [_, _, valueType] _ _) ->
- case valueType of
- UnitTy -> toTemplate "void $NAME (Array *aRef, int n)"
- _ -> toTemplate "void $NAME (Array *aRef, int n, $t newValue)"
+ ( \case
+ (FuncTy [_, _, valueType] _ _) ->
+ case valueType of
+ UnitTy -> toTemplate "void $NAME (Array *aRef, int n)"
+ _ -> toTemplate "void $NAME (Array *aRef, int n, $t newValue)"
+ _ -> error "array templates: asetbang called on non array"
)
- ( \(FuncTy [_, _, insideTy] _ _) ->
- case insideTy of
- UnitTy -> unitSetterTemplate
- _ ->
- let deleter = insideArrayDeletion typeEnv env insideTy
- in multilineTemplate
- [ "$DECL {",
- " Array a = *aRef;",
- " assert(n >= 0);",
- " assert(n < a.len);",
- deleter "n",
- " (($t*)a.data)[n] = newValue;",
- "}"
- ]
+ ( \case
+ (FuncTy [_, _, insideTy] _ _) ->
+ case insideTy of
+ UnitTy -> unitSetterTemplate
+ _ ->
+ let deleter = insideArrayDeletion typeEnv env insideTy
+ in multilineTemplate
+ [ "$DECL {",
+ " Array a = *aRef;",
+ " assert(n >= 0);",
+ " assert(n < a.len);",
+ deleter "n",
+ " (($t*)a.data)[n] = newValue;",
+ "}"
+ ]
+ _ -> error "array templates: asetbang called on non array"
)
- ( \(FuncTy [RefTy arrayType _, _, _] _ _) ->
- depsForDeleteFunc typeEnv env arrayType
+ ( \case
+ (FuncTy [RefTy arrayType _, _, _] _ _) ->
+ depsForDeleteFunc typeEnv env arrayType
+ _ -> error "array templates: asetbang called on non array"
)
-- | This function can set uninitialized memory in an array (used together with 'allocate').
@@ -379,23 +429,27 @@ templateAsetUninitializedBang = defineTypeParameterizedTemplate templateCreator
\_ _ ->
Template
t
- ( \(FuncTy [_, _, valueType] _ _) ->
- case valueType of
- UnitTy -> toTemplate "void $NAME (Array *aRef, int n)"
- _ -> toTemplate "void $NAME (Array *aRef, int n, $t newValue)"
+ ( \case
+ (FuncTy [_, _, valueType] _ _) ->
+ case valueType of
+ UnitTy -> toTemplate "void $NAME (Array *aRef, int n)"
+ _ -> toTemplate "void $NAME (Array *aRef, int n, $t newValue)"
+ _ -> error "array templates: aset called on non array"
)
- ( \(FuncTy [_, _, valueType] _ _) ->
- case valueType of
- UnitTy -> unitSetterTemplate
- _ ->
- multilineTemplate
- [ "$DECL {",
- " Array a = *aRef;",
- " assert(n >= 0);",
- " assert(n < a.len);",
- " (($t*)a.data)[n] = newValue;",
- "}"
- ]
+ ( \case
+ (FuncTy [_, _, valueType] _ _) ->
+ case valueType of
+ UnitTy -> unitSetterTemplate
+ _ ->
+ multilineTemplate
+ [ "$DECL {",
+ " Array a = *aRef;",
+ " assert(n >= 0);",
+ " assert(n < a.len);",
+ " (($t*)a.data)[n] = newValue;",
+ "}"
+ ]
+ _ -> error "array templates: aset called on non array"
)
(const [])
@@ -411,8 +465,10 @@ templateLength = defineTypeParameterizedTemplate templateCreator path t docs
t
(const (toTemplate "int $NAME (Array *a)"))
(const (toTemplate "$DECL { return (*a).len; }"))
- ( \(FuncTy [RefTy arrayType _] _ _) ->
- depsForDeleteFunc typeEnv env arrayType
+ ( \case
+ (FuncTy [RefTy arrayType _] _ _) ->
+ depsForDeleteFunc typeEnv env arrayType
+ _ -> error "array template: length called on non array"
)
templateAllocate :: (String, Binder)
@@ -426,23 +482,27 @@ templateAllocate = defineTypeParameterizedTemplate templateCreator path t docs
Template
t
(const (toTemplate "Array $NAME (int n)"))
- ( \(FuncTy [_] arrayType _) ->
- toTemplate $
- unlines
- ( [ "$DECL {",
- " Array a;",
- " a.len = n;",
- " a.capacity = n;",
- " a.data = CARP_MALLOC(n*sizeof($t));"
- ]
- ++ initTy arrayType
- ++ [ " return a;",
- "}"
- ]
- )
+ ( \case
+ (FuncTy [_] arrayType _) ->
+ toTemplate $
+ unlines
+ ( [ "$DECL {",
+ " Array a;",
+ " a.len = n;",
+ " a.capacity = n;",
+ " a.data = CARP_MALLOC(n*sizeof($t));"
+ ]
+ ++ initTy arrayType
+ ++ [ " return a;",
+ "}"
+ ]
+ )
+ _ -> error "array template: allocate called on non array"
)
- ( \(FuncTy [_] arrayType _) ->
- depsForDeleteFunc typeEnv env arrayType
+ ( \case
+ (FuncTy [_] arrayType _) ->
+ depsForDeleteFunc typeEnv env arrayType
+ _ -> error "array template: allocate called on non array"
)
templateDeleteArray :: (String, Binder)
@@ -456,13 +516,17 @@ templateDeleteArray = defineTypeParameterizedTemplate templateCreator path t doc
Template
t
(const (toTemplate "void $NAME (Array a)"))
- ( \(FuncTy [arrayType] UnitTy _) ->
- [TokDecl, TokC "{\n"]
- ++ deleteTy typeEnv env arrayType
- ++ [TokC "}\n"]
+ ( \case
+ (FuncTy [arrayType] UnitTy _) ->
+ [TokDecl, TokC "{\n"]
+ ++ deleteTy typeEnv env arrayType
+ ++ [TokC "}\n"]
+ _ -> error "array template: delete called with non array"
)
- ( \(FuncTy [StructTy (ConcreteNameTy (SymPath [] "Array")) [insideType]] UnitTy _) ->
- depsForDeleteFunc typeEnv env insideType
+ ( \case
+ (FuncTy [StructTy (ConcreteNameTy (SymPath [] "Array")) [insideType]] UnitTy _) ->
+ depsForDeleteFunc typeEnv env insideType
+ _ -> error "array template: delete called with non array"
)
deleteTy :: TypeEnv -> Env -> Ty -> [Token]
@@ -518,15 +582,17 @@ templateCopyArray = defineTypeParameterizedTemplate templateCreator path t docs
Template
t
(const (toTemplate "Array $NAME (Array* a)"))
- ( \(FuncTy [RefTy arrayType _] _ _) ->
- [TokDecl, TokC "{\n"]
- ++ [TokC " Array copy;\n"]
- ++ [TokC " copy.len = a->len;\n"]
- ++ [TokC " copy.capacity = a->capacity;\n"]
- ++ [TokC " copy.data = CARP_MALLOC(sizeof(", TokTy (VarTy "a") Normal, TokC ") * a->capacity);\n"]
- ++ copyTy typeEnv env arrayType
- ++ [TokC " return copy;\n"]
- ++ [TokC "}\n"]
+ ( \case
+ (FuncTy [RefTy arrayType _] _ _) ->
+ [TokDecl, TokC "{\n"]
+ ++ [TokC " Array copy;\n"]
+ ++ [TokC " copy.len = a->len;\n"]
+ ++ [TokC " copy.capacity = a->capacity;\n"]
+ ++ [TokC " copy.data = CARP_MALLOC(sizeof(", TokTy (VarTy "a") Normal, TokC ") * a->capacity);\n"]
+ ++ copyTy typeEnv env arrayType
+ ++ [TokC " return copy;\n"]
+ ++ [TokC "}\n"]
+ err -> error ("CAN'T MATCH: " ++ show err)
)
( \case
(FuncTy [RefTy arrayType@(StructTy (ConcreteNameTy (SymPath [] "Array")) [insideType]) _] _ _) ->
@@ -576,13 +642,19 @@ templateStrArray = defineTypeParameterizedTemplate templateCreator path t docs
Template
t
(const (toTemplate "String $NAME (Array* a)"))
- ( \(FuncTy [RefTy arrayType _] StringTy _) ->
- [TokDecl, TokC " {\n"]
- ++ strTy typeEnv env arrayType
- ++ [TokC "}\n"]
+ ( \ft ->
+ case ft of
+ (FuncTy [RefTy arrayType _] StringTy _) ->
+ [TokDecl, TokC " {\n"]
+ ++ strTy typeEnv env arrayType
+ ++ [TokC "}\n"]
+ _ -> error "array templates: str called w/ non array"
)
- ( \(FuncTy [RefTy (StructTy (ConcreteNameTy (SymPath [] "Array")) [insideType]) _] StringTy _) ->
- depsForPrnFunc typeEnv env insideType
+ ( \ft ->
+ case ft of
+ (FuncTy [RefTy (StructTy (ConcreteNameTy (SymPath [] "Array")) [insideType]) _] StringTy _) ->
+ depsForPrnFunc typeEnv env insideType
+ _ -> error "array templates: str called w/ non array"
)
path = SymPath ["Array"] "str"
t = FuncTy [arrayRef] StringTy StaticLifetimeTy
diff --git a/src/AssignTypes.hs b/src/AssignTypes.hs
index 44b0ea5a..f7bfe9c7 100644
--- a/src/AssignTypes.hs
+++ b/src/AssignTypes.hs
@@ -56,12 +56,16 @@ isArrayTypeOK _ = True
-- | TODO: Only change variables that are machine generated.
beautifyTypeVariables :: XObj -> Either TypeError XObj
beautifyTypeVariables root =
- let Just t = xobjTy root
- tys = nub (typeVariablesInOrderOfAppearance t)
+ let tys = case xobjTy root of
+ Just t -> nub (typeVariablesInOrderOfAppearance t)
+ Nothing -> []
mappings =
Map.fromList
( zip
- (map (\(VarTy name) -> name) tys)
+ (map go tys)
(map (VarTy . (: [])) ['a' ..])
)
in assignTypes mappings root
+ where
+ go (VarTy name) = name
+ go _ = "" -- called with non var type
diff --git a/src/BoxTemplates.hs b/src/BoxTemplates.hs
index 2ef6803b..d31bd391 100644
--- a/src/BoxTemplates.hs
+++ b/src/BoxTemplates.hs
@@ -96,12 +96,18 @@ copy =
Template
t
decl
- ( \(FuncTy [RefTy (StructTy (ConcreteNameTy (SymPath [] "Box")) [inner]) _] _ _) ->
- innerCopy tenv env inner
+ ( \ft ->
+ case ft of
+ (FuncTy [RefTy (StructTy (ConcreteNameTy (SymPath [] "Box")) [inner]) _] _ _) ->
+ innerCopy tenv env inner
+ _ -> error "box templates: copy called with non box"
)
- ( \(FuncTy [RefTy boxType@(StructTy (ConcreteNameTy (SymPath [] "Box")) [inner]) _] _ _) ->
- depsForCopyFunc tenv env inner
- ++ depsForDeleteFunc tenv env boxType
+ ( \ft ->
+ case ft of
+ (FuncTy [RefTy boxType@(StructTy (ConcreteNameTy (SymPath [] "Box")) [inner]) _] _ _) ->
+ depsForCopyFunc tenv env inner
+ ++ depsForDeleteFunc tenv env boxType
+ _ -> error "box templates: copy called with non box"
)
in defineTypeParameterizedTemplate template path t docs
where
@@ -138,15 +144,21 @@ delete =
Template
t
decl
- ( \(FuncTy [bTy] UnitTy _) ->
- multilineTemplate
- [ "$DECL {",
- " " ++ innerDelete tenv env bTy,
- "}"
- ]
+ ( \ft ->
+ case ft of
+ (FuncTy [bTy] UnitTy _) ->
+ multilineTemplate
+ [ "$DECL {",
+ " " ++ innerDelete tenv env bTy,
+ "}"
+ ]
+ _ -> error "box templates: delete called with non box"
)
- ( \(FuncTy [StructTy (ConcreteNameTy (SymPath [] "Box")) [insideType]] UnitTy _) ->
- depsForDeleteFunc tenv env insideType
+ ( \ft ->
+ case ft of
+ (FuncTy [StructTy (ConcreteNameTy (SymPath [] "Box")) [insideType]] UnitTy _) ->
+ depsForDeleteFunc tenv env insideType
+ _ -> error "box templates: delete called with non box"
)
in defineTypeParameterizedTemplate templateCreator path t docs
where
@@ -175,21 +187,27 @@ prn =
Template
t
decl
- ( \(FuncTy [boxT] StringTy _) ->
- multilineTemplate
- [ "$DECL {",
- " if(!box){",
- " String buffer = CARP_MALLOC(4);",
- " sprintf(buffer, \"Nil\");",
- " return buffer;",
- " }",
- innerStr tenv env boxT,
- " return buffer;",
- "}"
- ]
+ ( \ft ->
+ case ft of
+ (FuncTy [boxT] StringTy _) ->
+ multilineTemplate
+ [ "$DECL {",
+ " if(!box){",
+ " String buffer = CARP_MALLOC(4);",
+ " sprintf(buffer, \"Nil\");",
+ " return buffer;",
+ " }",
+ innerStr tenv env boxT,
+ " return buffer;",
+ "}"
+ ]
+ _ -> error "box templates: prn called with non box"
)
- ( \(FuncTy [(StructTy (ConcreteNameTy (SymPath [] "Box")) [inner])] StringTy _) ->
- depsForPrnFunc tenv env inner
+ ( \ft ->
+ case ft of
+ (FuncTy [(StructTy (ConcreteNameTy (SymPath [] "Box")) [inner])] StringTy _) ->
+ depsForPrnFunc tenv env inner
+ _ -> error "box tempaltes: prn called with non box"
)
)
in defineTypeParameterizedTemplate templateCreator path t docs
@@ -206,21 +224,27 @@ str =
Template
t
(templateLiteral "String $NAME ($t** box)")
- ( \(FuncTy [RefTy boxT _] StringTy _) ->
- multilineTemplate
- [ "$DECL {",
- " if(!box){",
- " String buffer = CARP_MALLOC(4);",
- " sprintf(buffer, \"Nil\");",
- " return buffer;",
- " }",
- innerStr tenv env boxT,
- " return buffer;",
- "}"
- ]
+ ( \ft ->
+ case ft of
+ (FuncTy [RefTy boxT _] StringTy _) ->
+ multilineTemplate
+ [ "$DECL {",
+ " if(!box){",
+ " String buffer = CARP_MALLOC(4);",
+ " sprintf(buffer, \"Nil\");",
+ " return buffer;",
+ " }",
+ innerStr tenv env boxT,
+ " return buffer;",
+ "}"
+ ]
+ _ -> error "box templates: str called with non box ref"
)
- ( \(FuncTy [RefTy (StructTy (ConcreteNameTy (SymPath [] "Box")) [inner]) _] StringTy _) ->
- depsForPrnFunc tenv env inner
+ ( \ft ->
+ case ft of
+ (FuncTy [RefTy (StructTy (ConcreteNameTy (SymPath [] "Box")) [inner]) _] StringTy _) ->
+ depsForPrnFunc tenv env inner
+ _ -> error "box templates: str template called with non box type"
)
)
in defineTypeParameterizedTemplate templateCreator path t docs
diff --git a/src/Concretize.hs b/src/Concretize.hs
index bd2ead10..b3127203 100644
--- a/src/Concretize.hs
+++ b/src/Concretize.hs
@@ -126,9 +126,12 @@ envWithFunctionArgs :: Env -> [XObj] -> Either EnvironmentError Env
envWithFunctionArgs env arr =
let functionEnv = Env Map.empty (Just env) Nothing Set.empty InternalEnv (envFunctionNestingLevel env)
in foldM
- (\e arg@(XObj (Sym path _) _ _) -> insertX e path arg)
+ go
functionEnv
arr
+ where
+ go e arg@(XObj (Sym path _) _ _) = insertX e path arg
+ go e _ = pure e
-- | Concretely type a function definition.
--
@@ -255,7 +258,7 @@ mkLambda visited allowAmbig _ tenv env root@(ListPat (FnPat fn arr@(ArrPat args)
-- Its name will contain the name of the (normal, non-lambda) function it's contained within,
-- plus the identifier of the particular s-expression that defines the lambda.
SymPath spath name = (last visited)
- Just funcTy = xobjTy root
+ funcTy = fromMaybe (error "concretize: can't concretize a lambda without type") $ xobjTy root
lambdaPath = SymPath spath ("_Lambda_" ++ lambdaToCName name (envFunctionNestingLevel env) ++ "_" ++ show (maybe 0 infoIdentifier (xobjInfo root)) ++ "_env")
lambdaNameSymbol = XObj (Sym lambdaPath Symbol) (Just dummyInfo) Nothing
-- Anonymous functions bound to a let name might call themselves. These recursive instances will have already been qualified as LookupRecursive symbols.
@@ -286,8 +289,11 @@ mkLambda visited allowAmbig _ tenv env root@(ListPat (FnPat fn arr@(ArrPat args)
-- (if it captures at least one variable)
structMemberPairs =
concatMap
- ( \(XObj (Sym path _) _ (Just symTy)) ->
- [XObj (Sym path Symbol) Nothing Nothing, reify symTy]
+ ( \x ->
+ case x of
+ (XObj (Sym path _) _ (Just symTy)) ->
+ [XObj (Sym path Symbol) Nothing Nothing, reify symTy]
+ _ -> error "concretize: struct member pair is a non symbol"
)
capturedVars
environmentStructTy = StructTy (ConcreteNameTy tyPath) []
@@ -365,7 +371,7 @@ visitSymbol visited allowAmbig tenv env xobj@(SymPat path mode) =
Right (foundEnv, binder)
| envIsExternal foundEnv ->
let theXObj = binderXObj binder
- Just theType = xobjTy theXObj
+ theType = fromMaybe (error "concretize: can't concretize a symbol without a type") $ xobjTy theXObj
typeOfVisited = fromMaybe (error ("Missing type on " ++ show xobj ++ " at " ++ prettyInfoFromXObj xobj ++ " when looking up path " ++ show path)) (xobjTy xobj)
in if --(trace $ "CHECKING " ++ getName xobj ++ " : " ++ show theType ++ " with visited type " ++ show typeOfVisited ++ " and visited definitions: " ++ show visitedDefinitions) $
(isTypeGeneric theType && not (isTypeGeneric typeOfVisited))
@@ -389,7 +395,7 @@ visitMultiSym visited allowAmbig tenv env xobj@(MultiSymPat name paths) =
[x] -> go x
_ -> pure (Right xobj)
where
- Just actualType = xobjTy xobj
+ actualType = fromMaybe (error "concretize: can't concretize a multisym without a type") $ xobjTy xobj
tys = map (typeFromPath env) paths
modes = map (modeFromPath env) paths
tysToPathsDict = zip tys paths
@@ -417,19 +423,19 @@ visitInterfaceSym :: [SymPath] -> Bool -> TypeEnv -> Env -> XObj -> State [XObj]
visitInterfaceSym visited allowAmbig tenv env xobj@(InterfaceSymPat name) =
either (pure . const (Left (CannotConcretize xobj))) go (getTypeBinder tenv name)
where
- Just actualType = (xobjTy xobj)
+ actualType = fromMaybe (error "concretize: can't concretize an interface without type") $ (xobjTy xobj)
go :: Binder -> State [XObj] (Either TypeError XObj)
go (Binder _ (ListPat (InterfacePat _ paths))) =
let tys = map (typeFromPath env) paths
modes = map (modeFromPath env) paths
tysModesPathsDict = zip3 tys modes paths
in case filter (\(t, _, p) -> matchingSignature actualType (t, p)) tysModesPathsDict of
- [] -> pure $ if allowAmbig then Right xobj else Left (NoMatchingSignature xobj name actualType (map (\(t, _, p) -> (t,p)) tysModesPathsDict))
+ [] -> pure $ if allowAmbig then Right xobj else Left (NoMatchingSignature xobj name actualType (map (\(t, _, p) -> (t, p)) tysModesPathsDict))
[x] -> updateSym x
- xs -> case filter (\(t,_,_) -> typeEqIgnoreLifetimes actualType t) xs of
+ xs -> case filter (\(t, _, _) -> typeEqIgnoreLifetimes actualType t) xs of
[] -> pure (Right xobj) -- No exact match of types
[y] -> updateSym y
- ps -> pure (Left (SeveralExactMatches xobj name actualType (map (\(t, _, p) -> (t,p)) ps)))
+ ps -> pure (Left (SeveralExactMatches xobj name actualType (map (\(t, _, p) -> (t, p)) ps)))
go _ = pure (Left (CannotConcretize xobj))
-- TODO: Should we also check for allowAmbig here?
updateSym (_, mode, path) = if isTypeGeneric actualType then pure (Right xobj) else replace mode path
@@ -577,7 +583,7 @@ renameGenericTypeSymbolsOnSum varpairs x@(XObj (Lst (caseNm : [a@(XObj (Arr arr)
mapp = Map.fromList varpairs
replacer mem@(XObj (Sym (SymPath [] name) _) _ _) =
- let Just perhapsTyVar = xobjToTy mem
+ let perhapsTyVar = fromMaybe (error "concretize: can't replace generics on sum without type") $ xobjToTy mem
in if isFullyGenericType perhapsTyVar
then case Map.lookup (VarTy name) mapp of
Just new -> reify new
@@ -592,7 +598,7 @@ renameGenericTypeSymbolsOnProduct vars members =
concatMap (\(var, (v, t)) -> [v, rename var t]) (zip vars (pairwise members))
where
rename var mem =
- let Just perhapsTyVar = xobjToTy mem
+ let perhapsTyVar = fromMaybe (error "concretize: can't replace generics on product without type") $ xobjToTy mem
in if isFullyGenericType perhapsTyVar
then reify var
else mem
@@ -606,8 +612,12 @@ instantiateGenericStructType typeEnv env originalStructTy@(StructTy _ _) generic
where
fake1 = XObj (Sym (SymPath [] "a") Symbol) Nothing Nothing
fake2 = XObj (Sym (SymPath [] "b") Symbol) Nothing Nothing
- XObj (Arr memberXObjs) _ _ = head membersXObjs
- rename@(StructTy _ renamedOrig) = evalState (renameVarTys originalStructTy) 0
+ memberXObjs = case head membersXObjs of
+ XObj (Arr xs) _ _ -> xs
+ _ -> error "can't instantiate non array member objects"
+ (rename, renamedOrig) = case evalState (renameVarTys originalStructTy) 0 of
+ (StructTy n ro) -> ((StructTy n ro), ro)
+ _ -> error "concretize: can't instantiate a non struct type"
solution = solve [Constraint originalStructTy genericStructTy fake1 fake2 fake1 OrdMultiSym]
go mappings = do
mappings' <- replaceLeft (FailedToInstantiateGenericType originalStructTy) (solve [Constraint rename genericStructTy fake1 fake2 fake1 OrdMultiSym])
@@ -643,7 +653,9 @@ instantiateGenericSumtype :: TypeEnv -> Env -> Ty -> Ty -> [XObj] -> Either Type
instantiateGenericSumtype typeEnv env originalStructTy@(StructTy _ originalTyVars) genericStructTy cases =
let fake1 = XObj (Sym (SymPath [] "a") Symbol) Nothing Nothing
fake2 = XObj (Sym (SymPath [] "b") Symbol) Nothing Nothing
- rename@(StructTy _ renamedOrig) = evalState (renameVarTys originalStructTy) 0
+ (rename, renamedOrig) = case evalState (renameVarTys originalStructTy) 0 of
+ (StructTy n ro) -> ((StructTy n ro), ro)
+ _ -> error "concretize: can't instantiate non struct type"
nameFixedCases = map (renameGenericTypeSymbolsOnSum (zip originalTyVars renamedOrig)) cases
fixLeft l = replaceLeft (FailedToInstantiateGenericType originalStructTy) l
in do
@@ -692,7 +704,7 @@ replaceGenericTypeSymbolsOnMembers mappings memberXObjs =
replaceGenericTypeSymbols :: Map.Map String Ty -> XObj -> XObj
replaceGenericTypeSymbols mappings xobj@(XObj (Sym (SymPath _ name) _) _ _) =
- let Just perhapsTyVar = xobjToTy xobj
+ let perhapsTyVar = fromMaybe (error "concretize: can't replace generics on xobj with no type") $ xobjToTy xobj
in if isFullyGenericType perhapsTyVar
then maybe xobj reify (Map.lookup name mappings)
else xobj
@@ -758,7 +770,7 @@ modeFromPath env p =
concretizeDefinition :: Bool -> TypeEnv -> Env -> [SymPath] -> XObj -> Ty -> Either TypeError (XObj, [XObj])
concretizeDefinition allowAmbiguity typeEnv globalEnv visitedDefinitions definition concreteType =
let SymPath pathStrings name = getPath definition
- Just polyType = xobjTy definition
+ polyType = fromMaybe (error "concretize: definition without a type") $ xobjTy definition
suffix = polymorphicSuffix polyType concreteType
newPath = SymPath pathStrings (name ++ suffix)
in case definition of
diff --git a/src/Emit.hs b/src/Emit.hs
index 814bcadd..a41c85d3 100644
--- a/src/Emit.hs
+++ b/src/Emit.hs
@@ -204,7 +204,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
visitSymbol _ (XObj (Sym _ (LookupGlobalOverride overrideWithName)) _ _) =
pure overrideWithName
visitSymbol indent xobj@(XObj sym@(Sym path lookupMode) (Just i) ty) =
- let Just t = ty
+ let t = fromMaybe (error "emit: symbol has no type") $ ty
in if isTypeGeneric t
then
error
@@ -237,7 +237,9 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
_ ->
do
let innerIndent = indent + indentAmount
- Just (FuncTy _ retTy _) = ty
+ retTy = case ty of
+ Just (FuncTy _ rt _) -> rt
+ _ -> error "emit: defn has no return type"
defnDecl = defnToDeclaration meta path argList retTy
isMain = name == "main"
appendToSrc (defnDecl ++ " {\n")
@@ -255,7 +257,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
do
let retVar = freshVar info
capturedVars = Set.toList set
- Just callback = name
+ callback = fromMaybe (SymPath [] "") name
callbackMangled = pathToC callback
needEnv = not (null capturedVars)
lambdaEnvTypeName = (SymPath [] (callbackMangled ++ "_ty")) -- The name of the struct is the callback name with suffix '_ty'.
@@ -277,17 +279,20 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
++ "));\n"
)
mapM_
- ( \(XObj (Sym path lookupMode) _ _) ->
- appendToSrc
- ( addIndent indent ++ lambdaEnvName ++ "->"
- ++ pathToC path
- ++ " = "
- ++ ( case lookupMode of
- LookupLocal (Capture _) -> "_env->" ++ pathToC path
- _ -> pathToC path
- )
- ++ ";\n"
- )
+ ( \xobj ->
+ case xobj of
+ (XObj (Sym path lookupMode) _ _) ->
+ appendToSrc
+ ( addIndent indent ++ lambdaEnvName ++ "->"
+ ++ pathToC path
+ ++ " = "
+ ++ ( case lookupMode of
+ LookupLocal (Capture _) -> "_env->" ++ pathToC path
+ _ -> pathToC path
+ )
+ ++ ";\n"
+ )
+ _ -> appendToSrc ""
)
(remove (isUnit . forceTy) capturedVars)
appendToSrc (addIndent indent ++ "Lambda " ++ retVar ++ " = {\n")
@@ -317,7 +322,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
[XObj Let _ _, XObj (Arr bindings) _ _, body] ->
let indent' = indent + indentAmount
in do
- let Just bodyTy = xobjTy body
+ let bodyTy = fromMaybe (error "emit: let body has no type") $ xobjTy body
isNotVoid = bodyTy /= UnitTy
letBodyRet = freshVar info
when isNotVoid $ -- Must be declared outside the scope
@@ -326,7 +331,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
let letBindingToC (XObj (Sym (SymPath _ symName) _) _ _) expr =
do
ret <- visit indent' expr
- let Just bindingTy = xobjTy expr
+ let bindingTy = fromMaybe (error "emit: let binding value has no type") $ xobjTy expr
unless (isUnit bindingTy) $
appendToSrc (addIndent indent' ++ tyToCLambdaFix bindingTy ++ " " ++ mangle symName ++ " = " ++ ret ++ ";\n")
letBindingToC _ _ = error "Invalid binding."
@@ -344,18 +349,18 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
let isNotVoid = xobjTy ifTrue /= Just UnitTy
ifRetVar = freshVar info
when isNotVoid $
- let Just ifT = xobjTy ifTrue
+ let ifT = fromMaybe (error "emit: if true branch has no type") $ xobjTy ifTrue
in appendToSrc (addIndent indent ++ tyToCLambdaFix ifT ++ " " ++ ifRetVar ++ ";\n")
exprVar <- visit indent expr
appendToSrc (addIndent indent ++ "if (" ++ exprVar ++ ") {\n")
trueVar <- visit indent' ifTrue
- let Just ifTrueInfo = xobjInfo ifTrue
+ let ifTrueInfo = infoOrUnknown $ xobjInfo ifTrue
delete indent' ifTrueInfo
when isNotVoid $
appendToSrc (addIndent indent' ++ ifRetVar ++ " = " ++ trueVar ++ ";\n")
appendToSrc (addIndent indent ++ "} else {\n")
falseVar <- visit indent' ifFalse
- let Just ifFalseInfo = xobjInfo ifFalse
+ let ifFalseInfo = infoOrUnknown $ xobjInfo ifFalse
delete indent' ifFalseInfo
when isNotVoid $
appendToSrc (addIndent indent' ++ ifRetVar ++ " = " ++ falseVar ++ ";\n")
@@ -384,7 +389,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
tempVarToAvoidClash = freshVar exprInfo ++ "_temp"
emitCaseMatcher :: (String, String) -> String -> XObj -> Integer -> State EmitterState ()
emitCaseMatcher (periodOrArrow, ampersandOrNot) caseName (XObj (Sym path _) _ t) index =
- let Just tt = t
+ let tt = fromMaybe (error "emit: case matcher has no type") $ t
in appendToSrc
( addIndent indent' ++ tyToCLambdaFix tt ++ " " ++ pathToC path ++ " = "
++ ampersandOrNot
@@ -446,13 +451,13 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
caseExprRetVal <- visit indent' caseExpr
when isNotVoid $
appendToSrc (addIndent indent' ++ retVar ++ " = " ++ caseExprRetVal ++ ";\n")
- let Just caseLhsInfo' = caseLhsInfo
+ let caseLhsInfo' = infoOrUnknown caseLhsInfo
delete indent' caseLhsInfo'
appendToSrc (addIndent indent ++ "}\n")
in do
exprVar <- visit indent expr
when isNotVoid $
- let Just t = ty
+ let t = fromMaybe (error "emit: match expression has no type") $ ty
in appendToSrc (addIndent indent ++ tyToCLambdaFix t ++ " " ++ retVar ++ ";\n")
zipWithM_ (emitCase exprVar) (True : repeat False) (pairwise rest)
appendToSrc (addIndent indent ++ "else UNHANDLED(\"" ++ takeFileName (infoFile info) ++ "\", " ++ show (infoLine info) ++ ");\n")
@@ -462,9 +467,9 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
-- While
[XObj While _ _, expr, body] ->
let indent' = indent + indentAmount
- Just exprTy = xobjTy expr
+ exprTy = fromMaybe (error "emit: called on while expression has no type") $ xobjTy expr
conditionVar = freshVar info
- Just exprInfo = xobjInfo expr
+ exprInfo = infoOrUnknown $ xobjInfo expr
in do
exprRetVar <- visitWhileExpression indent
appendToSrc (addIndent indent ++ tyToCLambdaFix exprTy ++ " " ++ conditionVar ++ " = " ++ exprRetVar ++ ";\n")
@@ -496,7 +501,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
let lastExpr = last expressions
retVar = freshVar info
mapM_ (visit indent) (init expressions)
- let (Just lastTy) = xobjTy lastExpr
+ let lastTy = fromMaybe (error "emit: final expression in do has no type") $ xobjTy lastExpr
if lastTy == UnitTy
then do
_ <- visit indent lastExpr
@@ -514,7 +519,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
(XObj (Lst (XObj (Sym (SymPath _ "copy") _) _ _ : (XObj (Sym sym _) _ _) : _)) _ _) -> "*" ++ pathToC sym
(XObj (Sym sym _) _ _) -> pathToC sym
_ -> error (show (CannotSet variable))
- Just varInfo = xobjInfo variable
+ varInfo = infoOrUnknown $ xobjInfo variable
--appendToSrc (addIndent indent ++ "// " ++ show (length (infoDelete varInfo)) ++ " deleters for " ++ properVariableName ++ ":\n")
delete indent varInfo
appendToSrc
@@ -530,7 +535,7 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
[XObj The _ _, _, value] ->
do
var <- visit indent value
- let Just t = ty
+ let t = fromMaybe (error "emit: called emit on the with no type") ty
fresh = mangle (freshVar info)
unless
(isUnit t)
@@ -540,7 +545,9 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
[XObj Ref _ _, value] ->
do
var <- visit indent value
- let Just t = ty
+ let t = case ty of
+ Just typ -> typ
+ _ -> error "emit: called emit on ref with no type"
fresh = mangle (freshVar info)
case t of
(RefTy UnitTy _) -> appendToSrc ""
@@ -548,7 +555,9 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
if isNumericLiteral value
then do
let literal = freshVar info ++ "_lit"
- Just literalTy = xobjTy value
+ literalTy = case xobjTy value of
+ Just typ -> typ
+ _ -> error "called emit on ref without value type"
appendToSrc (addIndent indent ++ "static " ++ tyToCLambdaFix literalTy ++ " " ++ literal ++ " = " ++ var ++ ";\n")
appendToSrc (addIndent indent ++ tyToCLambdaFix t ++ " " ++ fresh ++ " = &" ++ literal ++ "; // ref\n")
else appendToSrc (addIndent indent ++ tyToCLambdaFix t ++ " " ++ fresh ++ " = &" ++ var ++ "; // ref\n")
@@ -573,10 +582,13 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
pure ""
_ ->
do
- let Just t = ty
- appendToSrc (templateToC template path t)
- pure ""
- -- Alias
+ case ty of
+ Just t ->
+ do
+ appendToSrc (templateToC template path t)
+ pure ""
+ _ -> pure "" -- called with no type
+ -- Alias
XObj (Defalias _) _ _ : _ ->
pure ""
-- External
@@ -612,10 +624,9 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
func@(XObj (Sym _ (LookupGlobalOverride overriddenName)) _ _) : args ->
do
argListAsC <- createArgList indent True args -- The 'True' means "unwrap lambdas" which is always the case for functions with overriden names (they are external)
- let funcTy = case xobjTy func of
- Just actualType -> actualType
+ let retTy = case xobjTy func of
+ Just (FuncTy _ rt _) -> rt
_ -> error ("No type on func " ++ show func)
- FuncTy _ retTy _ = funcTy
callFunction = overriddenName ++ "(" ++ argListAsC ++ ");\n"
if isUnit retTy
then do
@@ -629,7 +640,9 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
func@(XObj (Sym path (LookupGlobal mode AFunction)) _ _) : args ->
do
argListAsC <- createArgList indent (mode == ExternalCode) args
- let Just (FuncTy _ retTy _) = xobjTy func
+ let retTy = case xobjTy func of
+ Just (FuncTy _ rt _) -> rt
+ _ -> error "failed to emit function application for non-function type."
funcToCall = pathToC path
if isUnit retTy
then do
@@ -647,10 +660,9 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
XObj (Sym _ (LookupGlobal ExternalCode _)) _ _ -> True
_ -> False
argListAsC <- createArgList indent unwrapLambdas args
- let funcTy = case xobjTy func of
- Just actualType -> actualType
+ let (argTys, retTy) = case xobjTy func of
+ Just (FuncTy at rt _) -> (at, rt)
_ -> error ("No type on func " ++ show func)
- FuncTy argTys retTy _ = funcTy
voidless = remove isUnit argTys
castToFn =
if unwrapLambdas
@@ -700,23 +712,26 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
do
let arrayVar = freshVar i
len = length xobjs
- Just (StructTy (ConcreteNameTy (SymPath [] "Array")) [innerTy]) = t
- appendToSrc
- ( addIndent indent ++ "Array " ++ arrayVar
- ++ " = { .len = "
- ++ show len
- ++ ","
- ++ " .capacity = "
- ++ show len
- ++ ","
- ++ " .data = CARP_MALLOC(sizeof("
- ++ tyToCLambdaFix innerTy
- ++ ") * "
- ++ show len
- ++ ") };\n"
- )
- zipWithM_ (visitArrayElement indent arrayVar innerTy) [0 ..] xobjs
- pure arrayVar
+ case t of
+ Just (StructTy (ConcreteNameTy (SymPath [] "Array")) [innerTy]) ->
+ do
+ appendToSrc
+ ( addIndent indent ++ "Array " ++ arrayVar
+ ++ " = { .len = "
+ ++ show len
+ ++ ","
+ ++ " .capacity = "
+ ++ show len
+ ++ ","
+ ++ " .data = CARP_MALLOC(sizeof("
+ ++ tyToCLambdaFix innerTy
+ ++ ") * "
+ ++ show len
+ ++ ") };\n"
+ )
+ zipWithM_ (visitArrayElement indent arrayVar innerTy) [0 ..] xobjs
+ pure arrayVar
+ _ -> pure "" -- called with non-array type
visitArray _ _ = error "Must visit array!"
visitArrayElement :: Int -> String -> Ty -> Int -> XObj -> State EmitterState ()
visitArrayElement indent arrayVar innerTy index xobj =
@@ -741,21 +756,24 @@ toC toCMode (Binder meta root) = emitterSrc (execState (visit startingIndent roo
retVar = arrayVar ++ "_retref"
arrayDataVar = arrayVar ++ "_data"
len = length xobjs
- Just tt@(RefTy (StructTy (ConcreteNameTy (SymPath [] "StaticArray")) [innerTy]) _) = t
- appendToSrc (addIndent indent ++ tyToCLambdaFix innerTy ++ " " ++ arrayDataVar ++ "[" ++ show len ++ "];\n")
- appendToSrc
- ( addIndent indent ++ "Array " ++ arrayVar
- ++ " = { .len = "
- ++ show len
- ++ ","
- ++ " /* .capacity = DOES NOT MATTER, STACK ALLOCATED ARRAY, */"
- ++ " .data = "
- ++ arrayDataVar
- ++ " };\n"
- )
- zipWithM_ (visitStaticArrayElement indent arrayDataVar innerTy) [0 ..] xobjs
- appendToSrc (addIndent indent ++ tyToCLambdaFix tt ++ " " ++ retVar ++ " = &" ++ arrayVar ++ ";\n")
- pure retVar
+ case t of
+ Just tt@(RefTy (StructTy (ConcreteNameTy (SymPath [] "StaticArray")) [innerTy]) _) ->
+ do
+ appendToSrc (addIndent indent ++ tyToCLambdaFix innerTy ++ " " ++ arrayDataVar ++ "[" ++ show len ++ "];\n")
+ appendToSrc
+ ( addIndent indent ++ "Array " ++ arrayVar
+ ++ " = { .len = "
+ ++ show len
+ ++ ","
+ ++ " /* .capacity = DOES NOT MATTER, STACK ALLOCATED ARRAY, */"
+ ++ " .data = "
+ ++ arrayDataVar
+ ++ " };\n"
+ )
+ zipWithM_ (visitStaticArrayElement indent arrayDataVar innerTy) [0 ..] xobjs
+ appendToSrc (addIndent indent ++ tyToCLambdaFix tt ++ " " ++ retVar ++ " = &" ++ arrayVar ++ ";\n")
+ pure retVar
+ _ -> pure "" -- called with non-array type
visitStaticArray _ _ = error "Must visit static array!"
visitStaticArrayElement :: Int -> String -> Ty -> Int -> XObj -> State EmitterState ()
visitStaticArrayElement indent arrayDataVar _ index xobj =
@@ -785,7 +803,9 @@ delete indent i = mapM_ deleterToC (infoDelete i)
defnToDeclaration :: MetaData -> SymPath -> [XObj] -> Ty -> String
defnToDeclaration meta path@(SymPath _ name) argList retTy =
let override = Meta.getString (Meta.getCompilerKey Meta.CNAME) meta
- (XObj (Lst annotations) _ _) = fromMaybe emptyList (Meta.get "annotations" meta)
+ annotations = case fromMaybe emptyList (Meta.get "annotations" meta) of
+ (XObj (Lst xs) _ _) -> xs
+ _ -> []
annotationsStr = joinWith " " (map strToC annotations)
sep = if not (null annotationsStr) then " " else ""
fullname = if (null override) then (pathToC path) else override
@@ -895,15 +915,18 @@ toDeclaration :: Binder -> String
toDeclaration (Binder meta xobj@(XObj (Lst xobjs) _ ty)) =
case xobjs of
[XObj (Defn _) _ _, XObj (Sym path _) _ _, XObj (Arr argList) _ _, _] ->
- let (Just (FuncTy _ retTy _)) = ty
- in defnToDeclaration meta path argList retTy ++ ";\n"
+ case ty of
+ (Just (FuncTy _ retTy _)) -> defnToDeclaration meta path argList retTy ++ ";\n"
+ _ -> "" -- called with non-function type, emit nothing.
[XObj Def _ _, XObj (Sym path _) _ _, _] ->
- let Just t = ty
- cname = (Meta.getString (Meta.getCompilerKey Meta.CNAME) meta)
- fullname = if (null cname) then pathToC path else cname
- in if (isUnit t)
- then ""
- else tyToCLambdaFix t ++ " " ++ fullname ++ ";\n"
+ case ty of
+ Just t ->
+ let cname = (Meta.getString (Meta.getCompilerKey Meta.CNAME) meta)
+ fullname = if (null cname) then pathToC path else cname
+ in if (isUnit t)
+ then ""
+ else tyToCLambdaFix t ++ " " ++ fullname ++ ";\n"
+ _ -> "" -- called with no type, emit nothing.
XObj (Deftype t) _ _ : XObj (Sym path _) _ _ : rest ->
defStructToDeclaration t path rest
XObj (DefSumtype t) _ _ : XObj (Sym _ _) _ _ : rest ->
@@ -917,8 +940,9 @@ toDeclaration (Binder meta xobj@(XObj (Lst xobjs) _ ty)) =
XObj DefDynamic _ _ : _ ->
""
[XObj (Instantiate template) _ _, XObj (Sym path _) _ _] ->
- let Just t = ty
- in templateToDeclaration template path t
+ case ty of
+ Just t -> templateToDeclaration template path t
+ _ -> "" -- called with no type, emit nothing.
[XObj (Defalias aliasTy) _ _, XObj (Sym path _) _ _] ->
defaliasToDeclaration aliasTy path
[XObj (Interface _ _) _ _, _] ->
@@ -1015,14 +1039,9 @@ globalsToC globalEnv =
typeEnvToDeclarations :: TypeEnv -> Env -> Either ToCError String
typeEnvToDeclarations typeEnv global =
let -- We need to carry the type environment to pass the correct environment on the binderToDeclaration call.
- addEnvToScore tyE = (sortDeclarationBinders tyE global (map snd (Map.toList (binders tyE))))
bindersWithScore = (addEnvToScore typeEnv)
mods = (findModules global)
- folder =
- ( \sorted (XObj (Mod e t) _ _) ->
- sorted ++ (foldl folder (addEnvToScore t) (findModules e))
- )
- allScoredBinders = sortOn fst (foldl folder bindersWithScore mods)
+ allScoredBinders = sortOn fst (foldl go bindersWithScore mods)
in do
okDecls <-
mapM
@@ -1033,6 +1052,10 @@ typeEnvToDeclarations typeEnv global =
)
allScoredBinders
pure (concat okDecls)
+ where
+ addEnvToScore tyE = (sortDeclarationBinders tyE global (map snd (Map.toList (binders tyE))))
+ go sorted (XObj (Mod e t) _ _) = sorted ++ (foldl go (addEnvToScore t) (findModules e))
+ go xs _ = xs
envToDeclarations :: TypeEnv -> Env -> Either ToCError String
envToDeclarations typeEnv env =
diff --git a/src/Env.hs b/src/Env.hs
index cc5fa03d..04d96f13 100644
--- a/src/Env.hs
+++ b/src/Env.hs
@@ -8,6 +8,7 @@ module Env
empty,
new,
parent,
+ parentOrEmpty,
setParent,
nested,
recursive,
@@ -148,6 +149,13 @@ binders = envBindings . prj
parent :: Environment e => e -> Maybe e
parent = fmap inj . envParent . prj
+-- Attempts to retrieve the parent from an environment.
+-- If the environment has no parent, returns the empty environment.
+parentOrEmpty :: Environment e => e -> e
+parentOrEmpty e = case envParent (prj e) of
+ Just p -> inj p
+ Nothing -> empty
+
-- | Set the parent of an environment.
setParent :: Environment e => e -> e -> e
setParent e p = inj ((prj e) {envParent = Just (prj p)})
diff --git a/src/Eval.hs b/src/Eval.hs
index ac6988fd..660b69a0 100644
--- a/src/Eval.hs
+++ b/src/Eval.hs
@@ -279,7 +279,7 @@ eval ctx xobj@(XObj o info ty) preference resolver =
Left err -> pure (ctx, Left err)
Right newCtx -> do
(finalCtx, evaledBody) <- eval newCtx body (PreferLocal (map (\(name, _) -> (SymPath [] name)) binds)) ResolveLocal
- let Just e = contextInternalEnv finalCtx
+ let e = fromMaybe E.empty $ contextInternalEnv finalCtx
parentEnv = envParent e
pure
( replaceInternalEnvMaybe finalCtx parentEnv,
@@ -301,7 +301,7 @@ eval ctx xobj@(XObj o info ty) preference resolver =
-- (let [f (fn [x] (if (= x 1) x (f (dec x))))] (f 10))
let origin = (contextInternalEnv ctx')
recFix = (E.recursive origin (Just "let-rec-env") 0)
- Right envWithSelf = if isFn x then E.insertX recFix (SymPath [] n) x else Right recFix
+ envWithSelf = fromRight recFix $ if isFn x then E.insertX recFix (SymPath [] n) x else Right recFix
ctx'' = replaceInternalEnv ctx' envWithSelf
(newCtx, res) <- eval ctx'' x preference resolver
case res of
@@ -350,18 +350,21 @@ eval ctx xobj@(XObj o info ty) preference resolver =
evaluateCommand (AppPat (CommandPat (UnaryCommandFunction unary) _ _) [x]) = do
(c, evaledArgs) <- foldlM successiveEval (ctx, Right []) [x]
case evaledArgs of
- Right args -> let [x'] = take 1 args in unary c x'
+ Right [x'] -> unary c x'
Left err -> pure (ctx, Left err)
+ _ -> error "eval: failed to evaluate command arguments"
evaluateCommand (AppPat (CommandPat (BinaryCommandFunction binary) _ _) [x, y]) = do
(c, evaledArgs) <- foldlM successiveEval (ctx, Right []) [x, y]
case evaledArgs of
- Right args -> let [x', y'] = take 2 args in binary c x' y'
+ Right [x', y'] -> binary c x' y'
Left err -> pure (ctx, Left err)
+ _ -> error "eval: failed to evaluate command arguments"
evaluateCommand (AppPat (CommandPat (TernaryCommandFunction ternary) _ _) [x, y, z]) = do
(c, evaledArgs) <- foldlM successiveEval (ctx, Right []) [x, y, z]
case evaledArgs of
- Right args' -> let [x', y', z'] = take 3 args' in ternary c x' y' z'
+ Right [x', y', z'] -> ternary c x' y' z'
Left err -> pure (ctx, Left err)
+ _ -> error "eval: failed to evaluate command arguments"
evaluateCommand (AppPat (CommandPat (VariadicCommandFunction variadic) _ _) args) = do
(c, evaledArgs) <- foldlM successiveEval (ctx, Right []) args
case evaledArgs of
@@ -629,12 +632,12 @@ catcher ctx exception =
specialCommandWith :: Context -> XObj -> SymPath -> [XObj] -> IO (Context, Either EvalError XObj)
specialCommandWith ctx _ path forms = do
- let Just env = contextInternalEnv ctx <|> maybeId (innermostModuleEnv ctx) <|> Just (contextGlobalEnv ctx)
+ let env = fromMaybe (contextGlobalEnv ctx) $ contextInternalEnv ctx <|> maybeId (innermostModuleEnv ctx) <|> Just (contextGlobalEnv ctx)
useThese = envUseModules env
env' = env {envUseModules = Set.insert path useThese}
ctx' = replaceGlobalEnv ctx env'
ctxAfter <- liftIO $ foldM folder ctx' forms
- let Just envAfter = contextInternalEnv ctxAfter <|> maybeId (innermostModuleEnv ctxAfter) <|> Just (contextGlobalEnv ctxAfter)
+ let envAfter = fromMaybe (contextGlobalEnv ctxAfter) (contextInternalEnv ctxAfter <|> maybeId (innermostModuleEnv ctxAfter) <|> Just (contextGlobalEnv ctxAfter))
-- undo ALL use:s made inside the 'with'.
ctxAfter' = replaceGlobalEnv ctx (envAfter {envUseModules = useThese})
pure (ctxAfter', dynamicNil)
diff --git a/src/Expand.hs b/src/Expand.hs
index ef9c58f3..233b4d81 100644
--- a/src/Expand.hs
+++ b/src/Expand.hs
@@ -2,6 +2,7 @@ module Expand (expandAll, replaceSourceInfoOnXObj) where
import Context
import Control.Monad.State (State, evalState, get, put)
+import Data.Either (fromRight)
import Data.Foldable (foldlM)
import Env
import EvalError
@@ -221,7 +222,7 @@ expand eval ctx xobj =
if isSpecialSym f
then do
(ctx', s) <- eval ctx f
- let Right sym = s
+ let sym = fromRight (error "expand: failed to expand special symbol") $ s
expand eval ctx' (XObj (Lst (sym : args)) (xobjInfo xobj) (xobjTy xobj))
else do
(_, expandedF) <- expand eval ctx f
diff --git a/src/GenerateConstraints.hs b/src/GenerateConstraints.hs
index 9fe9cbe7..3474423d 100644
--- a/src/GenerateConstraints.hs
+++ b/src/GenerateConstraints.hs
@@ -21,35 +21,37 @@ genConstraints _ root rootSig = fmap sort (gen root)
insideBodyConstraints <- gen body
xobjType <- toEither (xobjTy xobj) (DefnMissingType xobj)
bodyType <- toEither (xobjTy body) (ExpressionMissingType xobj)
- let (FuncTy argTys retTy lifetimeTy) = xobjType
- bodyConstr = Constraint retTy bodyType xobj body xobj OrdDefnBody
- argConstrs = zipWith3 (\a b aObj -> Constraint a b aObj xobj xobj OrdArg) (List.map forceTy args) argTys args
- -- The constraint generated by type signatures, like (sig foo (Fn ...)):
- -- This constraint is ignored for any xobj != rootxobj (ie. (fn) let bindings)
- sigConstr =
- if root == xobj
- then case rootSig of
- Just (rootSigTy, rootSigXObj) -> [Constraint rootSigTy xobjType rootSigXObj xobj xobj OrdSignatureAnnotation]
- Nothing -> []
- else []
- captureList :: [XObj]
- captureList = Set.toList captures
- capturesConstrs =
- catMaybes
- ( zipWith
- ( \captureTy captureObj ->
- case captureTy of
- RefTy _ refLt ->
- --trace ("Generated constraint between " ++ show lifetimeTy ++ " and " ++ show refLt) $
- Just (Constraint lifetimeTy refLt captureObj xobj xobj OrdCapture)
- _ ->
- --trace ("Did not generate constraint for captured variable " ++ show captureObj) $
- Nothing
+ case xobjType of
+ (FuncTy argTys retTy lifetimeTy) ->
+ let bodyConstr = Constraint retTy bodyType xobj body xobj OrdDefnBody
+ argConstrs = zipWith3 (\a b aObj -> Constraint a b aObj xobj xobj OrdArg) (List.map forceTy args) argTys args
+ -- The constraint generated by type signatures, like (sig foo (Fn ...)):
+ -- This constraint is ignored for any xobj != rootxobj (ie. (fn) let bindings)
+ sigConstr =
+ if root == xobj
+ then case rootSig of
+ Just (rootSigTy, rootSigXObj) -> [Constraint rootSigTy xobjType rootSigXObj xobj xobj OrdSignatureAnnotation]
+ Nothing -> []
+ else []
+ captureList :: [XObj]
+ captureList = Set.toList captures
+ capturesConstrs =
+ catMaybes
+ ( zipWith
+ ( \captureTy captureObj ->
+ case captureTy of
+ RefTy _ refLt ->
+ --trace ("Generated constraint between " ++ show lifetimeTy ++ " and " ++ show refLt) $
+ Just (Constraint lifetimeTy refLt captureObj xobj xobj OrdCapture)
+ _ ->
+ --trace ("Did not generate constraint for captured variable " ++ show captureObj) $
+ Nothing
+ )
+ (List.map forceTy captureList)
+ captureList
)
- (List.map forceTy captureList)
- captureList
- )
- pure (bodyConstr : argConstrs ++ insideBodyConstraints ++ capturesConstrs ++ sigConstr)
+ in pure (bodyConstr : argConstrs ++ insideBodyConstraints ++ capturesConstrs ++ sigConstr)
+ _ -> Left (DefnMissingType xobj) -- TODO: Better error here.
gen xobj =
case xobjObj xobj of
Lst lst -> case lst of
@@ -76,21 +78,23 @@ genConstraints _ root rootSig = fmap sort (gen root)
insideBodyConstraints <- gen body
insideBindingsConstraints <- fmap join (mapM gen bindings)
bodyType <- toEither (xobjTy body) (ExpressionMissingType body)
- let Just xobjTy' = xobjTy xobj
- wholeStatementConstraint = Constraint bodyType xobjTy' body xobj xobj OrdLetBody
- bindingsConstraints =
- zipWith
- ( \(symTy, exprTy) (symObj, exprObj) ->
- Constraint symTy exprTy symObj exprObj xobj OrdLetBind
- )
- (List.map (forceTy *** forceTy) (pairwise bindings))
- (pairwise bindings)
- pure
- ( wholeStatementConstraint :
- insideBodyConstraints
- ++ bindingsConstraints
- ++ insideBindingsConstraints
- )
+ case xobjTy xobj of
+ Just xobjTy' ->
+ let wholeStatementConstraint = Constraint bodyType xobjTy' body xobj xobj OrdLetBody
+ bindingsConstraints =
+ zipWith
+ ( \(symTy, exprTy) (symObj, exprObj) ->
+ Constraint symTy exprTy symObj exprObj xobj OrdLetBind
+ )
+ (List.map (forceTy *** forceTy) (pairwise bindings))
+ (pairwise bindings)
+ in pure
+ ( wholeStatementConstraint :
+ insideBodyConstraints
+ ++ bindingsConstraints
+ ++ insideBindingsConstraints
+ )
+ Nothing -> Left (ExpressionMissingType xobj)
-- If
[XObj If _ _, expr, ifTrue, ifFalse] ->
do
@@ -103,16 +107,18 @@ genConstraints _ root rootSig = fmap sort (gen root)
let expected = XObj (Sym (SymPath [] "Condition in if value") Symbol) (xobjInfo expr) (Just BoolTy)
let conditionConstraint = Constraint exprType BoolTy expr expected xobj OrdIfCondition
sameReturnConstraint = Constraint trueType falseType ifTrue ifFalse xobj OrdIfReturn
- Just t = xobjTy xobj
- wholeStatementConstraint = Constraint trueType t ifTrue xobj xobj OrdIfWhole
- pure
- ( conditionConstraint :
- sameReturnConstraint :
- wholeStatementConstraint :
- insideConditionConstraints
- ++ insideTrueConstraints
- ++ insideFalseConstraints
- )
+ in case xobjTy xobj of
+ Just t ->
+ let wholeStatementConstraint = Constraint trueType t ifTrue xobj xobj OrdIfWhole
+ in pure
+ ( conditionConstraint :
+ sameReturnConstraint :
+ wholeStatementConstraint :
+ insideConditionConstraints
+ ++ insideTrueConstraints
+ ++ insideFalseConstraints
+ )
+ Nothing -> Left (ExpressionMissingType xobj)
-- Match
XObj (Match matchMode) _ _ : expr : cases ->
do
@@ -242,9 +248,11 @@ genConstraints _ root rootSig = fmap sort (gen root)
argTys
args
[0 ..]
- Just xobjTy' = xobjTy xobj
- retConstraint = Constraint xobjTy' retTy xobj func xobj OrdFuncAppRet
- in pure (retConstraint : funcConstraints ++ argConstraints ++ variablesConstraints)
+ in case xobjTy xobj of
+ Just xobjTy' ->
+ let retConstraint = Constraint xobjTy' retTy xobj func xobj OrdFuncAppRet
+ in pure (retConstraint : funcConstraints ++ argConstraints ++ variablesConstraints)
+ Nothing -> Left (ExpressionMissingType xobj)
funcVarTy@(VarTy _) ->
let fabricatedFunctionType = FuncTy (List.map forceTy args) (forceTy xobj) (VarTy "what?!")
expected = XObj (Sym (SymPath [] ("Calling '" ++ getName func ++ "'")) Symbol) (xobjInfo func) Nothing
@@ -258,42 +266,50 @@ genConstraints _ root rootSig = fmap sort (gen root)
[] -> Right []
x : xs -> do
insideExprConstraints <- fmap join (mapM gen arr)
- let Just headTy = xobjTy x
- genObj o n =
- XObj
- (Sym (SymPath [] ("Whereas the " ++ enumerate n ++ " element in the array is " ++ show (getPath o))) Symbol)
- (xobjInfo o)
- (xobjTy o)
- headObj =
- XObj
- (Sym (SymPath [] ("I inferred the type of the array from its first element " ++ show (getPath x))) Symbol)
- (xobjInfo x)
- (Just headTy)
- Just (StructTy (ConcreteNameTy (SymPath [] "Array")) [t]) = xobjTy xobj
- betweenExprConstraints = zipWith (\o n -> Constraint headTy (forceTy o) headObj (genObj o n) xobj OrdArrBetween) xs [1 ..]
- headConstraint = Constraint headTy t headObj (genObj x 1) xobj OrdArrHead
- pure (headConstraint : insideExprConstraints ++ betweenExprConstraints)
- -- THIS CODE IS VERY MUCH A DUPLICATION OF THE 'ARR' CODE FROM ABOVE:
+ case xobjTy x of
+ Nothing -> Left (ExpressionMissingType x)
+ Just headTy ->
+ let genObj o n =
+ XObj
+ (Sym (SymPath [] ("Whereas the " ++ enumerate n ++ " element in the array is " ++ show (getPath o))) Symbol)
+ (xobjInfo o)
+ (xobjTy o)
+ headObj =
+ XObj
+ (Sym (SymPath [] ("I inferred the type of the array from its first element " ++ show (getPath x))) Symbol)
+ (xobjInfo x)
+ (Just headTy)
+ in case xobjTy xobj of
+ Just (StructTy (ConcreteNameTy (SymPath [] "Array")) [t]) ->
+ let betweenExprConstraints = zipWith (\o n -> Constraint headTy (forceTy o) headObj (genObj o n) xobj OrdArrBetween) xs [1 ..]
+ headConstraint = Constraint headTy t headObj (genObj x 1) xobj OrdArrHead
+ in pure (headConstraint : insideExprConstraints ++ betweenExprConstraints)
+ _ -> Left (ExpressionMissingType xobj) -- TODO: better error here.
+ -- THIS CODE IS VERY MUCH A DUPLICATION OF THE 'ARR' CODE FROM ABOVE:
(StaticArr arr) ->
case arr of
[] -> Right []
x : xs -> do
insideExprConstraints <- fmap join (mapM gen arr)
- let Just headTy = xobjTy x
- genObj o n =
- XObj
- (Sym (SymPath [] ("Whereas the " ++ enumerate n ++ " element in the array is " ++ show (getPath o))) Symbol)
- (xobjInfo o)
- (xobjTy o)
- headObj =
- XObj
- (Sym (SymPath [] ("I inferred the type of the static array from its first element " ++ show (getPath x))) Symbol)
- (xobjInfo x)
- (Just headTy)
- Just (RefTy (StructTy (ConcreteNameTy (SymPath [] "StaticArray")) [t]) _) = xobjTy xobj
- betweenExprConstraints = zipWith (\o n -> Constraint headTy (forceTy o) headObj (genObj o n) xobj OrdArrBetween) xs [1 ..]
- headConstraint = Constraint headTy t headObj (genObj x 1) xobj OrdArrHead
- pure (headConstraint : insideExprConstraints ++ betweenExprConstraints)
+ case xobjTy x of
+ Nothing -> Left (ExpressionMissingType x)
+ Just headTy ->
+ let genObj o n =
+ XObj
+ (Sym (SymPath [] ("Whereas the " ++ enumerate n ++ " element in the array is " ++ show (getPath o))) Symbol)
+ (xobjInfo o)
+ (xobjTy o)
+ headObj =
+ XObj
+ (Sym (SymPath [] ("I inferred the type of the static array from its first element " ++ show (getPath x))) Symbol)
+ (xobjInfo x)
+ (Just headTy)
+ in case xobjTy xobj of
+ Just (RefTy (StructTy (ConcreteNameTy (SymPath [] "StaticArray")) [t]) _) ->
+ let betweenExprConstraints = zipWith (\o n -> Constraint headTy (forceTy o) headObj (genObj o n) xobj OrdArrBetween) xs [1 ..]
+ headConstraint = Constraint headTy t headObj (genObj x 1) xobj OrdArrHead
+ in pure (headConstraint : insideExprConstraints ++ betweenExprConstraints)
+ _ -> Left (ExpressionMissingType xobj) -- TODO: Better error here.
_ -> Right []
genConstraintsForCaseMatcher :: MatchMode -> XObj -> Either TypeError [Constraint]
@@ -317,9 +333,11 @@ genConstraintsForCaseMatcher matchMode = gen
(zipWith refWrapper variables argTys)
variables
[0 ..]
- Just xobjTy' = xobjTy xobj
- retConstraint = Constraint xobjTy' retTy xobj caseName xobj OrdFuncAppRet
- in pure (retConstraint : caseNameConstraints ++ argConstraints ++ variablesConstraints)
+ in case xobjTy xobj of
+ Nothing -> Left (ExpressionMissingType xobj)
+ Just t ->
+ let retConstraint = Constraint t retTy xobj caseName xobj OrdFuncAppRet
+ in pure (retConstraint : caseNameConstraints ++ argConstraints ++ variablesConstraints)
funcVarTy@(VarTy _) ->
let fabricatedFunctionType = FuncTy (List.map forceTy variables) (forceTy xobj) (VarTy "what?!") -- TODO: Fix
expected = XObj (Sym (SymPath [] ("Matchin on '" ++ getName caseName ++ "'")) Symbol) (xobjInfo caseName) Nothing
diff --git a/src/Info.hs b/src/Info.hs
index 45fc1dd4..02993d9a 100644
--- a/src/Info.hs
+++ b/src/Info.hs
@@ -13,13 +13,14 @@ module Info
setDeletersOnInfo,
addDeletersToInfo,
uniqueDeleter,
+ infoOrUnknown,
)
where
+import Data.List (unionBy)
import Path (takeFileName)
import qualified Set
import SymPath
-import Data.List (unionBy)
-- | Information about where the Obj originated from.
data Info = Info
@@ -90,6 +91,12 @@ instance Show FilePathPrintLength where
dummyInfo :: Info
dummyInfo = Info 0 0 "dummy-file" Set.empty (-1)
+-- | Attempts to pull the Info out of a Maybe Info, otherwise, returns an Info
+-- object representing the fact that Info is missing for the binding.
+infoOrUnknown :: Maybe Info -> Info
+infoOrUnknown (Just i) = i
+infoOrUnknown Nothing = Info 0 0 "unknown" Set.empty (-1)
+
-- | Returns the line number, column number, and filename associated with an
-- Info.
getInfo :: Info -> (Int, Int, String)
diff --git a/src/InitialTypes.hs b/src/InitialTypes.hs
index bd044640..a4d1f251 100644
--- a/src/InitialTypes.hs
+++ b/src/InitialTypes.hs
@@ -1,6 +1,7 @@
module InitialTypes where
import Control.Monad.State
+import Data.Either (fromRight)
import Env as E
import Info
import qualified Map
@@ -202,7 +203,7 @@ initialTypes typeEnv rootEnv root = evalState (visit rootEnv root) 0
let funcTy = Just (FuncTy argTypes returnType StaticLifetimeTy)
typedNameSymbol = nameSymbol {xobjTy = funcTy}
-- TODO! After the introduction of 'LookupRecursive' this env shouldn't be needed anymore? (but it is for some reason...)
- Right envWithSelf = E.insertX funcScopeEnv (SymPath [] name) typedNameSymbol
+ envWithSelf = fromRight funcScopeEnv (E.insertX funcScopeEnv (SymPath [] name) typedNameSymbol)
visitedBody <- visit envWithSelf body
visitedArgs <- mapM (visit envWithSelf) argList
pure $ do
@@ -220,7 +221,7 @@ initialTypes typeEnv rootEnv root = evalState (visit rootEnv root) 0
lt <- genVarTy
let funcTy = Just (FuncTy argTypes returnType lt)
typedNameSymbol = XObj (Sym path LookupRecursive) si funcTy
- Right envWithSelf = E.insertX funcScopeEnv path typedNameSymbol
+ envWithSelf = fromRight funcScopeEnv (E.insertX funcScopeEnv path typedNameSymbol)
visitedBody <- visit envWithSelf body
visitedArgs <- mapM (visit envWithSelf) argList
pure $ do
@@ -401,8 +402,10 @@ initialTypes typeEnv rootEnv root = evalState (visit rootEnv root) 0
| otherwise -> genVarTy
pure $ do
okValue <- visitedValue
- let Just valueTy = xobjTy okValue
- pure (XObj (Lst [refExpr, okValue]) i (Just (RefTy valueTy lt)))
+ let valueTy = case xobjTy okValue of
+ Just vt -> (Just (RefTy vt lt))
+ Nothing -> Nothing
+ pure (XObj (Lst [refExpr, okValue]) i valueTy)
-- Deref (error!)
[XObj Deref _ _, _] ->
pure (Left (CantUseDerefOutsideFunctionApplication xobj))
diff --git a/src/Interfaces.hs b/src/Interfaces.hs
index 05395e96..7d2dfedc 100644
--- a/src/Interfaces.hs
+++ b/src/Interfaces.hs
@@ -151,7 +151,9 @@ retroactivelyRegisterInInterface ctx interface =
where
env = contextGlobalEnv ctx
impls = concat (rights (fmap ((flip Env.findImplementations) (getPath (binderXObj interface))) (env : (Env.lookupChildren env))))
- (resultCtx, err) = foldl' (\(Right context, _) binder -> registerInInterface context binder interface) (Right ctx, Nothing) impls
+ (resultCtx, err) = foldl' go (Right ctx, Nothing) impls
+ go (Right context, _) binder = registerInInterface context binder interface
+ go e _ = e
-- | Checks whether an interface is implemented for a certain type signature,
-- | e.g. Is "delete" implemented for `(Fn [String] ())` ?
diff --git a/src/Memory.hs b/src/Memory.hs
index 43ed489b..91d37407 100644
--- a/src/Memory.hs
+++ b/src/Memory.hs
@@ -3,6 +3,7 @@
module Memory (manageMemory) where
import Control.Monad.State
+import Data.Maybe (fromMaybe)
import Forms
import Info
import Managed
@@ -93,7 +94,9 @@ manageMemory typeEnv globalEnv root =
whenRight (sequence results) $ do
-- We know that we want to add a deleter for the static array here
let var = varOfXObj xobj
- Just (RefTy t@(StructTy (ConcreteNameTy (SymPath [] "StaticArray")) [_]) _) = xobjTy xobj
+ t = case xobjTy xobj of
+ Just (RefTy (StructTy (ConcreteNameTy (SymPath [] "StaticArray")) [vs]) _) -> (StructTy (ConcreteNameTy (SymPath [] "StaticArray")) [vs])
+ _ -> error "memory: can't visit static array of non static array type"
deleter = case nameOfPolymorphicFunction typeEnv globalEnv (FuncTy [t] UnitTy StaticLifetimeTy) "delete" of
Just pathOfDeleteFunc ->
ProperDeleter pathOfDeleteFunc (getDropFunc typeEnv globalEnv (xobjInfo xobj) t) var
@@ -487,7 +490,7 @@ manage typeEnv globalEnv xobj =
Just deleter -> do
MemState deleters deps lifetimes <- get
let newDeleters = Set.insert deleter deleters
- Just t = xobjTy xobj
+ t = fromMaybe (error "memory: can't manage xobj without type") $ xobjTy xobj
newDeps = Set.insert t deps
put (MemState newDeleters newDeps lifetimes)
Nothing -> pure ()
@@ -495,7 +498,7 @@ manage typeEnv globalEnv xobj =
-- | Remove `xobj` from the set of alive variables, in need of deletion at end of scope.
unmanage :: TypeEnv -> Env -> XObj -> State MemState (Either TypeError ())
unmanage typeEnv globalEnv xobj =
- let Just t = xobjTy xobj
+ let t = fromMaybe (error "memory: can't unmange xobj without type") $ xobjTy xobj
in if isManaged typeEnv globalEnv t && not (isGlobalFunc xobj)
then do
MemState deleters deps lifetimes <- get
@@ -528,19 +531,20 @@ transferOwnership typeEnv globalEnv from to =
-- see issue #597
exclusiveTransferOwnership :: TypeEnv -> Env -> XObj -> XObj -> State MemState (Either TypeError ())
exclusiveTransferOwnership tenv genv from to =
- do result <- unmanage tenv genv from
- whenRight result $ do
- MemState pre deps lts <- get
- put (MemState Set.empty deps lts) -- add just this new deleter to the set
- manage tenv genv to
- MemState post postDeps postLts <- get
- put (MemState (uniqueDeleter post pre) postDeps postLts) -- replace any duplicates and union with the prior set
- pure (Right ())
+ do
+ result <- unmanage tenv genv from
+ whenRight result $ do
+ MemState pre deps lts <- get
+ put (MemState Set.empty deps lts) -- add just this new deleter to the set
+ manage tenv genv to
+ MemState post postDeps postLts <- get
+ put (MemState (uniqueDeleter post pre) postDeps postLts) -- replace any duplicates and union with the prior set
+ pure (Right ())
-- | Control that an `xobj` is OK to reference
canBeReferenced :: TypeEnv -> Env -> XObj -> State MemState (Either TypeError ())
canBeReferenced typeEnv globalEnv xobj =
- let Just t = xobjTy xobj
+ let t = fromMaybe (error "memory: xobj without type") $ xobjTy xobj
isGlobalVariable = case xobj of
XObj (Sym _ (LookupGlobal _ _)) _ _ -> True
_ -> False
@@ -590,9 +594,11 @@ refTargetIsAlive xobj =
[] ->
--trace ("Can't use reference " ++ pretty xobj ++ " (with lifetime '" ++ lt ++ "', depending on " ++ show deleterName ++ ") at " ++ prettyInfoFromXObj xobj ++ ", it's not alive here:\n" ++ show xobj ++ "\nMappings: " ++ prettyLifetimeMappings lifetimeMappings ++ "\nAlive: " ++ show deleters ++ "\n") $
--pure (Right xobj)
- pure (case xobjObj xobj of
- (Lst (LetPat _ _ body)) -> (Left (UsingDeadReference body deleterName))
- _ -> (Left (UsingDeadReference xobj deleterName)))
+ pure
+ ( case xobjObj xobj of
+ (Lst (LetPat _ _ body)) -> (Left (UsingDeadReference body deleterName))
+ _ -> (Left (UsingDeadReference xobj deleterName))
+ )
_ ->
--trace ("CAN use reference " ++ pretty xobj ++ " (with lifetime '" ++ lt ++ "', depending on " ++ show deleterName ++ ") at " ++ prettyInfoFromXObj xobj ++ ", it's not alive here:\n" ++ show xobj ++ "\nMappings: " ++ prettyLifetimeMappings lifetimeMappings ++ "\nAlive: " ++ show deleters ++ "\n") $
pure (Right xobj)
diff --git a/src/Meta.hs b/src/Meta.hs
index 5eadfe40..f51fb84c 100644
--- a/src/Meta.hs
+++ b/src/Meta.hs
@@ -11,17 +11,17 @@ module Meta
getString,
getCompilerKey,
validateAndSet,
- CompilerKey(..),
+ CompilerKey (..),
)
where
+import Data.Either (fromRight)
+import Data.Maybe (fromMaybe)
import Info
import qualified Map
import Obj
import SymPath
import Types
-import Data.Maybe(fromMaybe)
-import Data.Either(fromRight)
--------------------------------------------------------------------------------
-- builtin special meta key values
@@ -31,7 +31,7 @@ data CompilerKey = CNAME
-- Given a compiler key, returns the key name as a string along with a default value.
toKeyValue :: CompilerKey -> (String, XObj)
-toKeyValue CNAME = ("c-name", (XObj (Str "") Nothing Nothing))
+toKeyValue CNAME = ("c-name", (XObj (Str "") Nothing Nothing))
-- | Get the key associated with a compiler Meta key as a string.
getCompilerKey :: CompilerKey -> String
@@ -51,7 +51,7 @@ validateCompilerKeyValue CNAME _ = False
validateAndSet :: MetaData -> CompilerKey -> XObj -> Either MetaData MetaData
validateAndSet meta key val
| validateCompilerKeyValue key (xobjObj val) =
- Right (set (getCompilerKey key) val meta)
+ Right (set (getCompilerKey key) val meta)
| otherwise = Left meta
--------------------------------------------------------------------------------
diff --git a/src/Obj.hs b/src/Obj.hs
index 8f200b0a..1372fbfa 100644
--- a/src/Obj.hs
+++ b/src/Obj.hs
@@ -332,12 +332,11 @@ machineReadableInfoFromXObj fppl xobj =
Nothing -> ""
-- | Obj with eXtra information.
-data XObj
- = XObj
- { xobjObj :: Obj,
- xobjInfo :: Maybe Info,
- xobjTy :: Maybe Ty
- }
+data XObj = XObj
+ { xobjObj :: Obj,
+ xobjInfo :: Maybe Info,
+ xobjTy :: Maybe Ty
+ }
deriving (Show, Eq, Ord)
setObj :: XObj -> Obj -> XObj
@@ -720,15 +719,14 @@ data EnvMode = ExternalEnv | InternalEnv | RecursionEnv deriving (Show, Eq, Gene
instance Hashable EnvMode
-- | Environment
-data Env
- = Env
- { envBindings :: Map.Map String Binder,
- envParent :: Maybe Env,
- envModuleName :: Maybe String,
- envUseModules :: Set.Set SymPath,
- envMode :: EnvMode,
- envFunctionNestingLevel :: Int -- Normal defn:s have 0, lambdas get +1 for each level of nesting
- }
+data Env = Env
+ { envBindings :: Map.Map String Binder,
+ envParent :: Maybe Env,
+ envModuleName :: Maybe String,
+ envUseModules :: Set.Set SymPath,
+ envMode :: EnvMode,
+ envFunctionNestingLevel :: Int -- Normal defn:s have 0, lambdas get +1 for each level of nesting
+ }
deriving (Show, Eq, Generic)
instance Hashable Env
@@ -911,13 +909,12 @@ polymorphicSuffix signature actualType =
type VisitedTypes = [Ty]
-- | Templates are like macros, but defined inside the compiler and with access to the types they are instantiated with
-data Template
- = Template
- { templateSignature :: Ty,
- templateDeclaration :: Ty -> [Token], -- Will this parameterization ever be useful?
- templateDefinition :: Ty -> [Token],
- templateDependencies :: Ty -> [XObj]
- }
+data Template = Template
+ { templateSignature :: Ty,
+ templateDeclaration :: Ty -> [Token], -- Will this parameterization ever be useful?
+ templateDefinition :: Ty -> [Token],
+ templateDependencies :: Ty -> [XObj]
+ }
instance Hashable Template where
hashWithSalt s Template {..} = s `hashWithSalt` templateSignature
@@ -937,7 +934,7 @@ data Token
= TokTy Ty TokTyMode -- Some kind of type, will be looked up if it's a type variable.
| TokC String -- Plain C code.
| TokDecl -- Will emit the declaration (i.e. "foo(int x)"), this is useful
- -- for avoiding repetition in the definition part of the template.
+ -- for avoiding repetition in the definition part of the template.
| TokName -- Will emit the name of the instantiated function/variable.
deriving (Eq, Ord)
@@ -995,19 +992,25 @@ forceTy xobj = fromMaybe (error ("No type in " ++ show xobj)) (xobjTy xobj)
data ExecutionMode = Repl | Build | BuildAndRun | Install String | Check deriving (Show, Eq)
-- | Information needed by the REPL
-data Context
- = Context
- { contextGlobalEnv :: Env,
- contextInternalEnv :: Maybe Env,
- contextTypeEnv :: TypeEnv,
- contextPath :: [String],
- contextProj :: Project,
- contextLastInput :: String,
- contextExecMode :: ExecutionMode,
- contextHistory :: ![XObj]
- }
+data Context = Context
+ { contextGlobalEnv :: Env,
+ contextInternalEnv :: Maybe Env,
+ contextTypeEnv :: TypeEnv,
+ contextPath :: [String],
+ contextProj :: Project,
+ contextLastInput :: String,
+ contextExecMode :: ExecutionMode,
+ contextHistory :: ![XObj]
+ }
deriving (Show, Generic)
+-- required for Hashable >= 1.4.0.0
+instance Eq Context where
+ c == c' =
+ (contextGlobalEnv c) == (contextGlobalEnv c')
+ && (contextInternalEnv c) == (contextInternalEnv c')
+ && (contextTypeEnv c) == (contextTypeEnv c')
+
instance Hashable Context where
hashWithSalt s Context {..} =
s
diff --git a/src/Parsing.hs b/src/Parsing.hs
index eb4d8d0d..9a4388c5 100644
--- a/src/Parsing.hs
+++ b/src/Parsing.hs
@@ -292,22 +292,26 @@ escaped = do
'v' -> pure "\v"
'x' -> do
hex <- Parsec.many1 (Parsec.oneOf "0123456789abcdefABCDEF")
- let [(p, "")] = readHex hex
- return [chr p]
+ case readHex hex of
+ [(p, "")] -> pure [chr p]
+ _ -> pure []
'u' -> do
hex <- Parsec.count 4 (Parsec.oneOf "0123456789abcdefABCDEF")
- let [(p, "")] = readHex hex
- return [chr p]
+ case readHex hex of
+ [(p, "")] -> pure [chr p]
+ _ -> pure []
'U' -> do
hex <- Parsec.count 8 (Parsec.oneOf "0123456789abcdefABCDEF")
- let [(p, "")] = readHex hex
- return [chr p]
+ case readHex hex of
+ [(p, "")] -> pure [chr p]
+ _ -> pure []
_ ->
if elem c "01234567"
then do
hex <- Parsec.many1 (Parsec.oneOf "01234567")
- let [(p, "")] = readHex (c : hex)
- return [chr p]
+ case readHex (c : hex) of
+ [(p, "")] -> pure [chr p]
+ _ -> pure []
else pure ('\\' : [c])
escapedQuoteChar :: Parsec.Parsec String ParseState Char
@@ -357,8 +361,9 @@ escapedHexChar = do
_ <- Parsec.char 'u'
hex <- Parsec.count 4 (Parsec.oneOf "0123456789abcdefABCDEF")
incColumn 5
- let [(parsed, "")] = readHex hex
- pure (toEnum parsed)
+ case readHex hex of
+ [(parsed, "")] -> pure (toEnum parsed)
+ _ -> pure '\0'
aChar :: Parsec.Parsec String ParseState XObj
aChar = do
diff --git a/src/Polymorphism.hs b/src/Polymorphism.hs
index d66856c3..4b1d4217 100644
--- a/src/Polymorphism.hs
+++ b/src/Polymorphism.hs
@@ -9,6 +9,7 @@ where
import Data.Either (fromRight, rights)
import Data.List (unionBy)
+import Data.Maybe (fromMaybe)
import Env
import Managed
import Obj
@@ -32,7 +33,7 @@ nameOfPolymorphicFunction _ env functionType functionName =
Right (_, (Binder _ (XObj (Lst (XObj (External (Just name)) _ _ : _)) _ _))) ->
Just (SymPath [] name)
Right (_, (Binder _ single)) ->
- let Just t' = xobjTy single
+ let t' = fromMaybe (error "polymorphism: binder without type") $ xobjTy single
(SymPath pathStrings name) = getPath single
suffix = polymorphicSuffix t' functionType
concretizedPath = SymPath pathStrings (name ++ suffix)
@@ -124,7 +125,7 @@ findFunctionForMemberIncludePrimitives typeEnv env functionName functionType (me
-- its generic ancestor.
getConcretizedPath :: XObj -> Ty -> SymPath
getConcretizedPath defn functionType =
- let Just t' = xobjTy defn
+ let t' = fromMaybe (error "polymorphism: defn without type") $ xobjTy defn
SymPath pathStrings name = getPath defn
suffix = polymorphicSuffix t' functionType
in SymPath pathStrings (name ++ suffix)
diff --git a/src/Primitives.hs b/src/Primitives.hs
index c10cf843..eac35fb6 100644
--- a/src/Primitives.hs
+++ b/src/Primitives.hs
@@ -135,7 +135,9 @@ primitiveImplements _ ctx x@(XObj (Sym interface@(SymPath _ _) _) _ _) (XObj (Sy
warn = emitWarning (show (NonExistentInterfaceWarning x))
addToInterface :: Binder -> Binder -> IO (Context, Either EvalError XObj)
addToInterface inter impl =
- let (Right newCtx, maybeErr) = registerInInterface ctx impl inter
+ let (newCtx, maybeErr) = case registerInInterface ctx impl inter of
+ (Right nc, me) -> (nc, me)
+ _ -> error "primitives: failed to register in interface"
in maybe (updateMeta impl newCtx) (handleError newCtx impl) maybeErr
handleError :: Context -> Binder -> InterfaceError -> IO (Context, Either EvalError XObj)
handleError context impl e@(AlreadyImplemented _ oldImplPath _ _) =
@@ -210,7 +212,9 @@ define hidden ctx qualifiedXObj =
pure
( Meta.getBinderMetaValue "implements" binder
-- TODO: Direct qualification!
- >>= \(XObj (Lst interfaces) _ _) -> pure (map Qualified interfaces)
+ >>= \x -> case x of
+ (XObj (Lst interfaces) _ _) -> pure (map Qualified interfaces)
+ _ -> pure []
)
>>= \maybeinterfaces ->
pure (rights (fmap (lookupBinderInTypeEnv ctx . getQualifiedPath) (fromMaybe [] maybeinterfaces)))
@@ -264,7 +268,7 @@ primitiveRegisterTypeWithFields ctx x t override members =
let typeDefinition = XObj (Lst [XObj (ExternalType override) Nothing Nothing, XObj (Sym path Symbol) Nothing Nothing]) Nothing (Just TypeTy)
path' = (qualifyPath ctx (SymPath [] typeModuleName))
update = \c -> insertInGlobalEnv' path' (toBinder typeModuleXObj) c >>= insertTypeBinder' path' (toBinder typeDefinition)
- Right ctx' = update ctx
+ ctx' = fromRight (error "primitives: failed to update context in register type") $ update ctx
-- TODO: Another case where define does not get formally qualified deps!
contextWithDefs <- liftIO $ foldM (define True) ctx' (map Qualified deps)
autoDerive
@@ -325,7 +329,10 @@ primitiveInfo _ ctx target@(XObj (Sym path@(SymPath _ name) _) _ _) =
implementsInterface binder binder' =
maybe
False
- (\(XObj (Lst impls) _ _) -> getBinderPath binder `elem` map getPath impls)
+ ( \x -> case x of
+ (XObj (Lst impls) _ _) -> getBinderPath binder `elem` map getPath impls
+ _ -> False
+ )
(Meta.getBinderMetaValue "implements" binder')
printIfFound :: Either ContextError Binder -> IO ()
printIfFound = either (const (pure ())) printer
@@ -475,8 +482,8 @@ primitiveDefinterface xobj ctx nameXObj@(XObj (Sym path@(SymPath [] name) _) _ _
defInterface =
let interface = defineInterface name t [] (xobjInfo nameXObj)
binder = toBinder interface
- Right ctx' = insertTypeBinder ctx (markQualified (SymPath [] name)) binder
- Right newCtx = retroactivelyRegisterInInterface ctx' binder
+ ctx' = fromRight (error "primitives: couldn't insert type binder for interface") $ insertTypeBinder ctx (markQualified (SymPath [] name)) binder
+ newCtx = fromRight (error "primitives: couldn't retroactively register in interface") $ retroactivelyRegisterInInterface ctx' binder
in (newCtx, dynamicNil)
updateInterface binder = case binder of
Binder _ (XObj (Lst (XObj (Interface foundType _) _ _ : _)) _ _) ->
diff --git a/src/Project.hs b/src/Project.hs
index e10017d2..726a1eee 100644
--- a/src/Project.hs
+++ b/src/Project.hs
@@ -24,41 +24,40 @@ instance Show Target where
--
-- Otherwise, if the field is truly private and only for internal use in the
-- compiler, add the field to the Project record but omit it from the keyMap.
-data Project
- = Project
- { projectTitle :: String,
- projectIncludes :: [Includer],
- projectPreproc :: [String],
- projectCFlags :: [String],
- projectLibFlags :: [String],
- projectPkgConfigFlags :: [String],
- projectFiles :: [(FilePath, ReloadMode)],
- projectAlreadyLoaded :: [FilePath],
- projectEchoC :: Bool,
- projectLibDir :: FilePath,
- projectCarpDir :: FilePath,
- projectOutDir :: FilePath,
- projectDocsDir :: FilePath,
- projectDocsLogo :: FilePath,
- projectDocsPrelude :: String,
- projectDocsURL :: String,
- projectDocsGenerateIndex :: Bool,
- projectDocsStyling :: String,
- projectPrompt :: String,
- projectCarpSearchPaths :: [FilePath],
- projectPrintTypedAST :: Bool,
- projectCompiler :: String,
- projectTarget :: Target,
- projectCore :: Bool,
- projectEchoCompilationCommand :: Bool,
- projectCanExecute :: Bool,
- projectFilePathPrintLength :: FilePathPrintLength,
- projectGenerateOnly :: Bool,
- projectBalanceHints :: Bool,
- projectForceReload :: Bool, -- Setting this to true will make the `load-once` command work just like `load`.
- projectCModules :: [FilePath],
- projectLoadStack :: [FilePath]
- }
+data Project = Project
+ { projectTitle :: String,
+ projectIncludes :: [Includer],
+ projectPreproc :: [String],
+ projectCFlags :: [String],
+ projectLibFlags :: [String],
+ projectPkgConfigFlags :: [String],
+ projectFiles :: [(FilePath, ReloadMode)],
+ projectAlreadyLoaded :: [FilePath],
+ projectEchoC :: Bool,
+ projectLibDir :: FilePath,
+ projectCarpDir :: FilePath,
+ projectOutDir :: FilePath,
+ projectDocsDir :: FilePath,
+ projectDocsLogo :: FilePath,
+ projectDocsPrelude :: String,
+ projectDocsURL :: String,
+ projectDocsGenerateIndex :: Bool,
+ projectDocsStyling :: String,
+ projectPrompt :: String,
+ projectCarpSearchPaths :: [FilePath],
+ projectPrintTypedAST :: Bool,
+ projectCompiler :: String,
+ projectTarget :: Target,
+ projectCore :: Bool,
+ projectEchoCompilationCommand :: Bool,
+ projectCanExecute :: Bool,
+ projectFilePathPrintLength :: FilePathPrintLength,
+ projectGenerateOnly :: Bool,
+ projectBalanceHints :: Bool,
+ projectForceReload :: Bool, -- Setting this to true will make the `load-once` command work just like `load`.
+ projectCModules :: [FilePath],
+ projectLoadStack :: [FilePath]
+ }
projectFlags :: Project -> String
projectFlags proj = joinWithSpace (projectCFlags proj ++ projectLibFlags proj)
diff --git a/src/Qualify.hs b/src/Qualify.hs
index d9a09ac4..3a65fe5e 100644
--- a/src/Qualify.hs
+++ b/src/Qualify.hs
@@ -23,11 +23,11 @@ import Data.Either (fromRight)
import qualified Env as E
import Info
import qualified Map
+import qualified Meta
import Obj
import qualified Set
import SymPath
import Util
-import qualified Meta
--------------------------------------------------------------------------------
-- Errors
@@ -205,11 +205,14 @@ qualifyFunctionDefinition typeEnv globalEnv env x@(XObj (Lst [defn@(XObj (Defn _
envWithSelf <- fixLeft (E.insertX recursionEnv (SymPath [] functionName) sym)
-- Copy the use modules from the local env to ensure they are available from the function env.
functionEnv <- fixLeft (pure ((E.nested (Just envWithSelf) (Just (functionName ++ "-function-env")) 0) {envUseModules = (envUseModules env)}))
- envWithArgs <- fixLeft (foldM (\e arg@(XObj (Sym path _) _ _) -> E.insertX e path arg) functionEnv argsArr)
+ envWithArgs <- fixLeft (foldM go functionEnv argsArr)
qualifiedBody <- liftM unQualified (setFullyQualifiedSymbols typeEnv globalEnv envWithArgs body)
pure (Qualified (XObj (Lst [defn, sym, args, qualifiedBody]) i t))
where
fixLeft = replaceLeft (FailedToQualifyDeclarationName x)
+ go :: Env -> XObj -> Either E.EnvironmentError Env
+ go e arg@(XObj (Sym path _) _ _) = E.insertX e path arg
+ go e _ = pure e
qualifyFunctionDefinition _ _ _ xobj = Left $ FailedToQualifyDeclarationName xobj
-- | Qualify the symbols in a lambda body.
@@ -217,10 +220,14 @@ qualifyLambda :: Qualifier
qualifyLambda typeEnv globalEnv env x@(XObj (Lst [fn@(XObj (Fn _ _) _ _), args@(XObj (Arr argsArr) _ _), body]) i t) =
let lvl = envFunctionNestingLevel env
functionEnv = Env Map.empty (Just env) Nothing Set.empty InternalEnv (lvl + 1)
- in (replaceLeft (FailedToQualifySymbols x) (foldM (\e arg@(XObj (Sym path _) _ _) -> E.insertX e path arg) functionEnv argsArr))
+ in (replaceLeft (FailedToQualifySymbols x) (foldM go functionEnv argsArr))
>>= \envWithArgs ->
liftM unQualified (setFullyQualifiedSymbols typeEnv globalEnv envWithArgs body)
>>= \qualifiedBody -> pure (Qualified (XObj (Lst [fn, args, qualifiedBody]) i t))
+ where
+ go :: Env -> XObj -> Either E.EnvironmentError Env
+ go e arg@(XObj (Sym path _) _ _) = E.insertX e path arg
+ go e _ = pure e
qualifyLambda _ _ _ xobj = Left $ FailedToQualifySymbols xobj
-- | Qualify the symbols in a The form's body.
@@ -246,7 +253,7 @@ qualifyLet typeEnv globalEnv env x@(XObj (Lst [letExpr@(XObj Let _ _), bind@(XOb
| not (all isSym (evenIndices bindings)) = Right $ Qualified $ XObj (Lst [letExpr, bind, body]) i t -- Leave it untouched for the compiler to find the error.
| otherwise =
do
- let Just ii = i
+ let ii = infoOrUnknown i
lvl = envFunctionNestingLevel env
innerEnv = Env Map.empty (Just env) (Just ("let-env-" ++ show (infoIdentifier ii))) Set.empty InternalEnv lvl
(innerEnv', qualifiedBindings) <- foldM qualifyBinding (innerEnv, []) (pairwise bindings)
@@ -264,7 +271,7 @@ qualifyLet typeEnv globalEnv env x@(XObj (Lst [letExpr@(XObj Let _ _), bind@(XOb
-- However, we also need to ensure captured variables are still marked
-- as such, which is based on env nesting level, and we need to ensure
-- the recursive reference isn't accidentally captured.
- let Just origin = E.parent e
+ let origin = E.parentOrEmpty e
recursionEnv <- fixLeft (pure (E.recursive (Just e) (Just ("let-recurse-env")) 0))
envWithSelf <- fixLeft (E.insertX recursionEnv path s)
qualified <- liftM unQualified (setFullyQualifiedSymbols typeEnv globalEnv (E.setParent e (E.setParent origin envWithSelf)) o)
@@ -291,7 +298,7 @@ qualifyMatch typeEnv globalEnv env (XObj (Lst (matchExpr@(XObj (Match _) _ _) :
qualifiedCases <- pure . map (map unQualified) =<< mapM qualifyCases (pairwise casesXObjs)
pure (Qualified (XObj (Lst (matchExpr : qualifiedExpr : concat qualifiedCases)) i t))
where
- Just ii = i
+ ii = infoOrUnknown i
lvl = envFunctionNestingLevel env
-- Create an inner environment for each case.
innerEnv :: Env
@@ -378,18 +385,19 @@ qualifySym typeEnv globalEnv localEnv xobj@(XObj (Sym path@(SymPath _ name) _) i
nakedInit modenv
resolve origin found (Binder meta xobj') =
let cname = (Meta.getString (Meta.getCompilerKey Meta.CNAME) meta)
- modality = if (null cname)
- then (LookupGlobal (if isExternalFunction xobj' then ExternalCode else CarpLand) (definitionMode xobj'))
- else (LookupGlobalOverride cname)
+ modality =
+ if (null cname)
+ then (LookupGlobal (if isExternalFunction xobj' then ExternalCode else CarpLand) (definitionMode xobj'))
+ else (LookupGlobalOverride cname)
in if (isTypeDef xobj')
- then
- ( (replaceLeft (FailedToFindSymbol xobj') (fmap (globalEnv,) (E.searchValue globalEnv path)))
- >>= \(origin', (e', binder)) -> resolve (E.prj origin') (E.prj e') binder
- )
- else case envMode (E.prj found) of
- RecursionEnv -> pure (XObj (Sym (getPath xobj') LookupRecursive) i t)
- InternalEnv -> pure (XObj (Sym (getPath xobj') (LookupLocal (captureOrNot found origin))) i t)
- ExternalEnv -> pure (XObj (Sym (getPath xobj') modality) i t)
+ then
+ ( (replaceLeft (FailedToFindSymbol xobj') (fmap (globalEnv,) (E.searchValue globalEnv path)))
+ >>= \(origin', (e', binder)) -> resolve (E.prj origin') (E.prj e') binder
+ )
+ else case envMode (E.prj found) of
+ RecursionEnv -> pure (XObj (Sym (getPath xobj') LookupRecursive) i t)
+ InternalEnv -> pure (XObj (Sym (getPath xobj') (LookupLocal (captureOrNot found origin))) i t)
+ ExternalEnv -> pure (XObj (Sym (getPath xobj') modality) i t)
resolveMulti :: (Show e, E.Environment e) => SymPath -> [(e, Binder)] -> Either QualificationError XObj
resolveMulti _ [] =
Left (FailedToFindSymbol xobj)
diff --git a/src/RenderDocs.hs b/src/RenderDocs.hs
index 56cee97c..092002e5 100644
--- a/src/RenderDocs.hs
+++ b/src/RenderDocs.hs
@@ -7,6 +7,7 @@ import Control.Monad (when)
import qualified Data.List as List
import Data.Maybe (fromMaybe)
import Data.Text as Text
+import qualified Env as E
import qualified Map
import qualified Meta
import Obj
@@ -27,10 +28,14 @@ beautifyType t =
mappings =
Map.fromList
( List.zip
- (List.map (\(VarTy name) -> name) tys)
+ (List.map go tys)
(List.map (VarTy . (: [])) ['a' ..])
)
in replaceTyVars mappings t
+ where
+ go :: Ty -> String
+ go (VarTy name) = name
+ go _ = "" -- called on a non var type.
saveDocsForEnvs :: Project -> [(SymPath, Binder)] -> IO ()
saveDocsForEnvs ctx pathsAndEnvBinders =
@@ -63,7 +68,11 @@ saveDocsForEnvs ctx pathsAndEnvBinders =
)
)
in envs
- ++ getDependenciesForEnvs (Prelude.map (\(n, Binder _ (XObj (Mod env _) _ _)) -> (n, env)) envs)
+ ++ getDependenciesForEnvs (Prelude.map go envs)
+ where
+ go :: (SymPath, Binder) -> (SymPath, Env)
+ go (n, Binder _ (XObj (Mod env _) _ _)) = (n, env)
+ go _ = ((SymPath [] ""), E.empty)
-- | This function expects a binder that contains an environment, anything else is a runtime error.
getEnvAndMetaFromBinder :: Binder -> (Env, MetaData)
diff --git a/src/StartingEnv.hs b/src/StartingEnv.hs
index 7770cac3..066dcd6f 100644
--- a/src/StartingEnv.hs
+++ b/src/StartingEnv.hs
@@ -3,6 +3,7 @@ module StartingEnv where
import qualified ArrayTemplates
import qualified BoxTemplates
import Commands
+import Data.Maybe (fromMaybe)
import qualified Env as E
import Eval
import Info
@@ -148,7 +149,7 @@ functionModule =
}
where
bindEnv env =
- let Just name = envModuleName env
+ let name = fromMaybe (error "env has no module name") $ envModuleName env
meta = Meta.set "hidden" trueXObj emptyMeta
in (name, Binder meta (XObj (Mod env E.empty) Nothing Nothing))
bindings = Map.fromList (map (bindEnv . generateInnerFunctionModule) [0 .. maxArity])
@@ -380,7 +381,7 @@ dynamicStringModule =
where
path = ["Dynamic", "String"]
bindings =
- Map.fromList $unaries ++ binaries ++ ternaries
+ Map.fromList $ unaries ++ binaries ++ ternaries
spath = SymPath path
unaries =
let f = addUnaryCommand . spath
@@ -429,7 +430,7 @@ dynamicSymModule =
}
where
path = ["Dynamic", "Symbol"]
- bindings = Map.fromList $unaries ++ binaries
+ bindings = Map.fromList $ unaries ++ binaries
spath = SymPath path
unaries =
let f = addUnaryCommand . spath
@@ -455,7 +456,7 @@ dynamicProjectModule =
}
where
path = ["Dynamic", "Project"]
- bindings = Map.fromList $unaries ++ binaries
+ bindings = Map.fromList $ unaries ++ binaries
spath = SymPath path
unaries =
let f = addUnaryCommand . spath
diff --git a/src/StaticArrayTemplates.hs b/src/StaticArrayTemplates.hs
index fff8f86d..e9edaa2b 100644
--- a/src/StaticArrayTemplates.hs
+++ b/src/StaticArrayTemplates.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE LambdaCase #-}
+
module StaticArrayTemplates where
import qualified ArrayTemplates
@@ -31,8 +33,9 @@ templateUnsafeNth =
"}"
]
)
- ( \(FuncTy [RefTy _ _, _] _ _) ->
- []
+ ( \case
+ (FuncTy [RefTy _ _, _] _ _) -> []
+ _ -> error "static array templates: nth called on non array"
)
templateLength :: (String, Binder)
@@ -47,8 +50,10 @@ templateLength = defineTypeParameterizedTemplate templateCreator path t docs
t
(const (toTemplate "int $NAME (Array *a)"))
(const (toTemplate "$DECL { return (*a).len; }"))
- ( \(FuncTy [RefTy arrayType _] _ _) ->
- depsForDeleteFunc typeEnv env arrayType
+ ( \case
+ (FuncTy [RefTy arrayType _] _ _) ->
+ depsForDeleteFunc typeEnv env arrayType
+ _ -> error "static array templates: length called on non array"
)
templateDeleteArray :: (String, Binder)
@@ -62,13 +67,17 @@ templateDeleteArray = defineTypeParameterizedTemplate templateCreator path t doc
Template
t
(const (toTemplate "void $NAME (Array a)"))
- ( \(FuncTy [arrayType] UnitTy _) ->
- [TokDecl, TokC "{\n"]
- ++ deleteTy typeEnv env arrayType
- ++ [TokC "}\n"]
+ ( \case
+ (FuncTy [arrayType] UnitTy _) ->
+ [TokDecl, TokC "{\n"]
+ ++ deleteTy typeEnv env arrayType
+ ++ [TokC "}\n"]
+ _ -> error "static array templates: delete called on non array"
)
- ( \(FuncTy [StructTy _ [insideType]] UnitTy _) ->
- depsForDeleteFunc typeEnv env insideType
+ ( \case
+ (FuncTy [StructTy _ [insideType]] UnitTy _) ->
+ depsForDeleteFunc typeEnv env insideType
+ _ -> error "static array templates: delete called on non array"
)
deleteTy :: TypeEnv -> Env -> Ty -> [Token]
@@ -90,22 +99,26 @@ templateAsetBang = defineTypeParameterizedTemplate templateCreator path t docs
Template
t
(const (toTemplate "void $NAME (Array *aRef, int n, $t newValue)"))
- ( \(FuncTy [_, _, insideTy] _ _) ->
- let deleter = ArrayTemplates.insideArrayDeletion typeEnv env insideTy
- in ( toTemplate $
- unlines
- [ "$DECL {",
- " Array a = *aRef;",
- " assert(n >= 0);",
- " assert(n < a.len);",
- deleter "n",
- " (($t*)a.data)[n] = newValue;",
- "}"
- ]
- )
+ ( \case
+ (FuncTy [_, _, insideTy] _ _) ->
+ let deleter = ArrayTemplates.insideArrayDeletion typeEnv env insideTy
+ in ( toTemplate $
+ unlines
+ [ "$DECL {",
+ " Array a = *aRef;",
+ " assert(n >= 0);",
+ " assert(n < a.len);",
+ deleter "n",
+ " (($t*)a.data)[n] = newValue;",
+ "}"
+ ]
+ )
+ _ -> error "static array templates: aset bang called on non array"
)
- ( \(FuncTy [RefTy arrayType _, _, _] _ _) ->
- depsForDeleteFunc typeEnv env arrayType
+ ( \case
+ (FuncTy [RefTy arrayType _, _, _] _ _) ->
+ depsForDeleteFunc typeEnv env arrayType
+ _ -> error "static array templates: aset bang called on non array"
)
templateAsetUninitializedBang :: (String, Binder)
@@ -118,23 +131,27 @@ templateAsetUninitializedBang = defineTypeParameterizedTemplate templateCreator
\_ _ ->
Template
t
- ( \(FuncTy [_, _, valueType] _ _) ->
- case valueType of
- UnitTy -> toTemplate "void $NAME (Array *aRef, int n)"
- _ -> toTemplate "void $NAME (Array *aRef, int n, $t newValue)"
+ ( \case
+ (FuncTy [_, _, valueType] _ _) ->
+ case valueType of
+ UnitTy -> toTemplate "void $NAME (Array *aRef, int n)"
+ _ -> toTemplate "void $NAME (Array *aRef, int n, $t newValue)"
+ _ -> error "static array templates: aset called on non array"
)
- ( \(FuncTy [_, _, valueType] _ _) ->
- case valueType of
- UnitTy -> ArrayTemplates.unitSetterTemplate
- _ ->
- multilineTemplate
- [ "$DECL {",
- " Array a = *aRef;",
- " assert(n >= 0);",
- " assert(n < a.len);",
- " (($t*)a.data)[n] = newValue;",
- "}"
- ]
+ ( \case
+ (FuncTy [_, _, valueType] _ _) ->
+ case valueType of
+ UnitTy -> ArrayTemplates.unitSetterTemplate
+ _ ->
+ multilineTemplate
+ [ "$DECL {",
+ " Array a = *aRef;",
+ " assert(n >= 0);",
+ " assert(n < a.len);",
+ " (($t*)a.data)[n] = newValue;",
+ "}"
+ ]
+ _ -> error "static array templates: aset called on non array"
)
(const [])
@@ -146,13 +163,17 @@ templateStrArray = defineTypeParameterizedTemplate templateCreator path t docs
Template
t
(const (toTemplate "String $NAME (Array* a)"))
- ( \(FuncTy [RefTy arrayType _] StringTy _) ->
- [TokDecl, TokC " {\n"]
- ++ ArrayTemplates.strTy typeEnv env arrayType
- ++ [TokC "}\n"]
+ ( \case
+ (FuncTy [RefTy arrayType _] StringTy _) ->
+ [TokDecl, TokC " {\n"]
+ ++ ArrayTemplates.strTy typeEnv env arrayType
+ ++ [TokC "}\n"]
+ _ -> error "static array templates: str called on non array"
)
- ( \(FuncTy [RefTy (StructTy _ [insideType]) _] StringTy _) ->
- depsForPrnFunc typeEnv env insideType
+ ( \case
+ (FuncTy [RefTy (StructTy _ [insideType]) _] StringTy _) ->
+ depsForPrnFunc typeEnv env insideType
+ _ -> error "static array templates: str called on non array"
)
path = SymPath ["StaticArray"] "str"
t = FuncTy [RefTy (StructTy concreteArray [VarTy "a"]) (VarTy "q")] StringTy StaticLifetimeTy
diff --git a/src/Sumtypes.hs b/src/Sumtypes.hs
index 634ca4b9..a9760432 100644
--- a/src/Sumtypes.hs
+++ b/src/Sumtypes.hs
@@ -137,9 +137,13 @@ initers candidate = mapM binderForCaseInit (TC.getFields candidate)
ft = FuncTy tys generic StaticLifetimeTy
binderPath = SymPath (TC.getFullPath candidate) fieldname
t = (FuncTy tys (VarTy "p") StaticLifetimeTy)
- decl = \(FuncTy _ concrete _) -> tokensForCaseInitDecl generic concrete field
- body = \(FuncTy _ concrete _) -> tokensForCaseInit alloc generic concrete field
- deps tenv env = \(FuncTy _ concrete _) -> either (const []) id (concretizeType tenv env concrete)
+ decl (FuncTy _ concrete _) = tokensForCaseInitDecl generic concrete field
+ decl _ = error "sumtypes: genericCaseInit called with non function type"
+ body (FuncTy _ concrete _) = tokensForCaseInit alloc generic concrete field
+ body _ = error "sumtypes: genericCaseInit called with non function type"
+ deps tenv env = \typ -> case typ of
+ (FuncTy _ concrete _) -> either (const []) id (concretizeType tenv env concrete)
+ _ -> []
temp = TemplateCreator $ \tenv env -> Template t decl body (deps tenv env)
in defineTypeParameterizedTemplate temp binderPath ft docs
genericCaseInit _ _ = error "genericCaseInit"
@@ -148,8 +152,10 @@ initers candidate = mapM binderForCaseInit (TC.getFields candidate)
binderForTag :: BinderGen
binderForTag candidate =
let t = FuncTy [RefTy (TC.toType candidate) (VarTy "q")] IntTy StaticLifetimeTy
- decl = \(FuncTy [RefTy struct _] _ _) -> toTemplate $ proto struct
- body = \(FuncTy [RefTy struct _] _ _) -> toTemplate $ proto struct ++ " { return p->_tag; }"
+ decl (FuncTy [RefTy struct _] _ _) = toTemplate $ proto struct
+ decl _ = error "sumtypes: binderForTag called with non function type"
+ body (FuncTy [RefTy struct _] _ _) = toTemplate $ proto struct ++ " { return p->_tag; }"
+ body _ = error "sumtypes: binderForTag called with non function type"
deps = const []
path' = SymPath (TC.getFullPath candidate) "get-tag"
temp = Template t decl body deps
diff --git a/src/Template.hs b/src/Template.hs
index 3bc0a4f6..5fb8e604 100644
--- a/src/Template.hs
+++ b/src/Template.hs
@@ -69,9 +69,8 @@ concretizeTypesInToken mappings cName decl token =
-- | The code needed to correctly call a lambda from C.
templateCodeForCallingLambda :: String -> Ty -> [String] -> String
-templateCodeForCallingLambda functionName t args =
- let FuncTy argTys retTy lt = t
- castToFnWithEnv = tyToCast (FuncTy (lambdaEnvTy : argTys) retTy lt)
+templateCodeForCallingLambda functionName t@(FuncTy argTys retTy lt) args =
+ let castToFnWithEnv = tyToCast (FuncTy (lambdaEnvTy : argTys) retTy lt)
castToFn = tyToCast t
in functionName ++ ".env ? "
++ "(("
@@ -92,12 +91,13 @@ templateCodeForCallingLambda functionName t args =
++ ".callback)("
++ joinWithComma args
++ ")"
+templateCodeForCallingLambda _ _ _ = "" -- called w/ non function type, emit nothing.
-- | Must cast a lambda:s .callback member to the correct type to be able to call it.
tyToCast :: Ty -> String
-tyToCast t =
- let FuncTy argTys retTy _ = t
- in "§(Fn [" ++ joinWithSpace (map show argTys) ++ "] " ++ show retTy ++ ")" -- Note! The '§' means that the emitted type will be "raw" and not converted to 'Lambda'.
+tyToCast (FuncTy argTys retTy _) =
+ "§(Fn [" ++ joinWithSpace (map show argTys) ++ "] " ++ show retTy ++ ")" -- Note! The '§' means that the emitted type will be "raw" and not converted to 'Lambda'.
+tyToCast _ = "" -- called w/ non function type. Emit nothing.
----------------------------------------------------------------------------------------------------------
-- ACTUAL TEMPLATES
diff --git a/src/TypeError.hs b/src/TypeError.hs
index f3470a06..da954bae 100644
--- a/src/TypeError.hs
+++ b/src/TypeError.hs
@@ -525,10 +525,12 @@ beautifyTy mappings = f
bmappings = beautification mappings
beautification :: TypeMappings -> Map.Map String String
beautification m =
- Map.fromList $ zip (map (\(VarTy name) -> name) tys) beautList
+ Map.fromList $ zip (map go tys) beautList
where
tys = nub $ concat $ typeVariablesInOrderOfAppearance <$> tys'
tys' = snd <$> Map.assocs m
+ go (VarTy name) = name
+ go _ = "" -- called on a non var type. Emit nothing.
beautList = [c : s | s <- "" : beautList, c <- ['a' .. 'z']]
typeVariablesInOrderOfAppearance :: Ty -> [Ty]