relax parser to not require blocks to end in an expression (instead get helpful msg from typechecker)

This commit is contained in:
Paul Chiusano 2018-09-21 17:50:09 -04:00
parent bc7b5ff0ce
commit af0eab0f49
2 changed files with 18 additions and 1 deletions

View File

@ -13,6 +13,7 @@ module Unison.PrintError where
import qualified Data.Char as Char
import Data.Foldable
import qualified Data.List.NonEmpty as Nel
import Data.List (isPrefixOf)
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe (catMaybes, fromMaybe)
@ -35,6 +36,7 @@ import Unison.Result (Note (..))
import qualified Unison.Type as Type
import qualified Unison.Typechecker.Context as C
import Unison.Typechecker.TypeError
import qualified Unison.TermParser as TermParser
import qualified Unison.TypeVar as TypeVar
import qualified Unison.Util.AnnotatedText as AT
import Unison.Util.ColorText (StyledText)
@ -267,6 +269,17 @@ renderTypeError env e src = AT.AnnotatedDocument . Seq.fromList $ case e of
, ". Make sure it's imported and spelled correctly:\n\n"
, annotatedAsErrorSite src typeSite
]
UnknownTerm {..} | TermParser.missingResult `isPrefixOf` Text.unpack (Var.name unknownTermV) ->
[ "I found a block that ends with a binding instead of an expression at "
, (fromString . annotatedToEnglish) termSite
, ":\n\n"
, annotatedAsErrorSite src termSite, "\n" ] ++
case expectedType of
Type.Existential' _ _ ->
["There aren't any constraints on the type of the expression that follows this binding.\n\n"]
_ -> [ "Based on the context, I'm expecting an expression of type "
, AT.Text . Color.style Color.Type1 $ (renderType' env) expectedType
, " after this binding. \n\n" ]
UnknownTerm {..} ->
[ "I'm not sure what "
, AT.Text . Color.style Color.ErrorSite $ (fromString . show) unknownTermV

View File

@ -387,13 +387,17 @@ block' s openBlock closeBlock = do
Binding ((a, v), _) : _ ->
pure $ Term.letRec (startAnnotation <> endAnnotation)
(finishBindings $ toBindings =<< reverse bs)
(Term.var a (Var.named $ "comes after " `mappend` Var.name v))
(Term.var a (Var.named $ (Text.pack missingResult) `mappend` Var.name v))
Action e : bs ->
pure $ Term.letRec (startAnnotation <> ann e)
(finishBindings $ toBindings =<< reverse bs)
e
[] -> customFailure $ EmptyBlock (const s <$> open)
-- hack: special variable name used if user gives a block with no result
missingResult :: String
missingResult =":missing-result"
number :: Var v => TermP v
number = number' (tok Term.int64) (tok Term.uint64) (tok Term.float)