Carp/src/PrimitiveError.hs

97 lines
3.3 KiB
Haskell
Raw Normal View History

module PrimitiveError where
import Obj
import TypeError
import Types
data PrimitiveError
= ArgumentTypeError String String String XObj
| ArgumentArityError XObj String [XObj]
| MissingInfo XObj
| ForewardImplementsMeta
| RegisterTypeError
| SymbolNotFoundError SymPath
Refactor: clean up Env module, store type environments in modules (#1207) * refactor: major environment mgmt refactor This big refactor primarily changes two things in terms of behavior: 1. Stores a SymPath on concretely named (non-generic) struct types; before we stored a string. 2. The SymPath mentioned in (1.) designates where the struct is stored in the current environment chain. Modules now carry a local type environment in addition to their local value environments. Any types defined in the module are added to this environment rather than the global type environment. To resolve a type such as `Foo.Bar` we now do the following: - Search the *global value environment* for the Foo module. - Get the type environment stored in the Foo module. - Search for Bar in the Foo module's type environment. Additionally, this commit eliminates the Lookup module entirely and refactors the Env module to handle all aspects of environment management in hopefully a more reusable fashion. I also took the opportunity to refactor primitiveDeftype in Primitives and qualifySym in Qualify, both of which were hefty functions that I found difficult to grok and needed refactoring anyway as a result of lookup changes (lookups now return an Either instead of a Maybe). Subsequent commits will clean up and clarify this work further. This does include one minor regression. Namely, an implementation of `hash` in core/Color that was maximally generic now needs type casting. * refactor: clean up recent Env changes This commit removes some redundant functions, unifies some logic, and renames some routines across the Env module in efforts to make it cleaner. Call sites have been updated accordingly. * chore: format code with ormolu * fix: update lookup tests Changes references to renamed functions in the Env module. * refactor: style + additional improvements from eriksvedang@ - Rename arrayTy -> arrayTyA in ArrayTemplates.hs to disambiguate. - Add maybeId util function. - Remove commented code. - Refactor a few functions for readability. * fix: fix type inference regression Recent commits introduced one minor regression whereby an instance of type inference in core/Color.carp no longer worked and required explicit type annotation. The problem ultimately had to do with qualification: - Prior to the recent changes, type inference worked because the call in question was qualified to Color.Id.get-tag, fixing the type. - Failing to copy over a local envs Use modules to function envs resulted in finding more than just Color.Id.get-tag for this instance. We now copy use modules over to function envs generated during qualification to ensure we resolve to Use'd definitions before more general cases. Similarly, I made a small change to primitiveUse to support contextual use calls (e.g. the `(use Id)` in Color.carp, which really means `(use Color.Id)`) * chore: Update some clarificatory comments * chore: fix inline comment
2021-05-19 20:20:48 +03:00
| BadDeftypeMembers
| QualifiedTypeMember [XObj]
| InvalidTypeName XObj
| InvalidTypeVariables XObj
| MetaSetFailed XObj String
| StructNotFound XObj
| NonTypeInTypeEnv SymPath XObj
| InvalidSumtypeCase XObj
| TooManySumtypeCases
data PrimitiveWarning
= NonExistentInterfaceWarning XObj
| DefinitionTypeChangeWarning XObj Ty
instance Show PrimitiveError where
show (ArgumentTypeError fun ty position actual) =
"`" ++ fun ++ "` expected " ++ ty ++ " as its " ++ position
++ " argument, but got `"
++ pretty actual
++ "`"
show (ArgumentArityError fun numberExpected args) =
2020-12-22 19:44:44 +03:00
"`" ++ show (getPath fun) ++ "`" ++ "expected " ++ numberExpected
++ " arguments "
++ ", but got "
++ show (length args)
show (MissingInfo x) =
"No information about object: " ++ pretty x
2020-12-22 19:44:44 +03:00
show ForewardImplementsMeta =
"Can't set the `implements` meta on a global definition before it is declared."
2020-12-22 19:44:44 +03:00
show RegisterTypeError =
"I don't understand this usage of `register-type`.\n\n"
++ "Valid usages :\n"
++ " (register-type Name)\n"
++ " (register-type Name [field0 Type, ...])\n"
++ " (register-type Name c-name)\n"
++ " (register-type Name c-name [field0 Type, ...]"
show (SymbolNotFoundError path) =
"I cant find the symbol `" ++ show path ++ "`"
Refactor: clean up Env module, store type environments in modules (#1207) * refactor: major environment mgmt refactor This big refactor primarily changes two things in terms of behavior: 1. Stores a SymPath on concretely named (non-generic) struct types; before we stored a string. 2. The SymPath mentioned in (1.) designates where the struct is stored in the current environment chain. Modules now carry a local type environment in addition to their local value environments. Any types defined in the module are added to this environment rather than the global type environment. To resolve a type such as `Foo.Bar` we now do the following: - Search the *global value environment* for the Foo module. - Get the type environment stored in the Foo module. - Search for Bar in the Foo module's type environment. Additionally, this commit eliminates the Lookup module entirely and refactors the Env module to handle all aspects of environment management in hopefully a more reusable fashion. I also took the opportunity to refactor primitiveDeftype in Primitives and qualifySym in Qualify, both of which were hefty functions that I found difficult to grok and needed refactoring anyway as a result of lookup changes (lookups now return an Either instead of a Maybe). Subsequent commits will clean up and clarify this work further. This does include one minor regression. Namely, an implementation of `hash` in core/Color that was maximally generic now needs type casting. * refactor: clean up recent Env changes This commit removes some redundant functions, unifies some logic, and renames some routines across the Env module in efforts to make it cleaner. Call sites have been updated accordingly. * chore: format code with ormolu * fix: update lookup tests Changes references to renamed functions in the Env module. * refactor: style + additional improvements from eriksvedang@ - Rename arrayTy -> arrayTyA in ArrayTemplates.hs to disambiguate. - Add maybeId util function. - Remove commented code. - Refactor a few functions for readability. * fix: fix type inference regression Recent commits introduced one minor regression whereby an instance of type inference in core/Color.carp no longer worked and required explicit type annotation. The problem ultimately had to do with qualification: - Prior to the recent changes, type inference worked because the call in question was qualified to Color.Id.get-tag, fixing the type. - Failing to copy over a local envs Use modules to function envs resulted in finding more than just Color.Id.get-tag for this instance. We now copy use modules over to function envs generated during qualification to ensure we resolve to Use'd definitions before more general cases. Similarly, I made a small change to primitiveUse to support contextual use calls (e.g. the `(use Id)` in Color.carp, which really means `(use Color.Id)`) * chore: Update some clarificatory comments * chore: fix inline comment
2021-05-19 20:20:48 +03:00
show (BadDeftypeMembers) =
"All fields must have a name and a type."
++ "Example:\n"
++ "```(deftype Name [field1 Type1, field2 Type2, field3 Type3])```\n"
show (QualifiedTypeMember xobjs) =
"Type members must be unqualified symbols, but got `"
++ concatMap pretty xobjs
++ "`"
show (InvalidTypeName xobj) =
("Invalid name for type definition: " ++ pretty xobj)
show (InvalidTypeVariables xobj) =
("Invalid type variables for type definition: " ++ pretty xobj)
show (MetaSetFailed xobj e) =
"`meta-set!` failed on `" ++ pretty xobj
++ "` "
++ show e
show (StructNotFound xobj) =
"Couldn't find a type named '" ++ (show (getPath xobj))
++ "' in the type environment."
show (NonTypeInTypeEnv path xobj) =
"Can't get members for: " ++ show path
++ " found a non-type in the type environment: "
++ (pretty xobj)
show (PrimitiveError.InvalidSumtypeCase xobj) =
"Can't get members for an invalid sumtype case: "
++ pretty xobj
show TooManySumtypeCases =
"Got too many sumtype cases (>128) for type"
instance Show PrimitiveWarning where
show (NonExistentInterfaceWarning x) =
"The interface "
++ show (getPath x)
++ " is not defined."
++ " Did you define it using `definterface`?"
show (DefinitionTypeChangeWarning annXObj previousType) =
"Definition at " ++ prettyInfoFromXObj annXObj ++ " changed type of '" ++ show (getPath annXObj)
++ "' from "
++ show previousType
++ " to "
++ show (forceTy annXObj)
toEvalError :: Context -> XObj -> PrimitiveError -> (Context, Either EvalError XObj)
toEvalError ctx xobj perr =
evalError ctx (show perr) (xobjInfo xobj)