diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2026-05-01 20:25:20 +0200 |
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2026-05-02 20:54:00 +0200 |
| commit | 0905fe68591a3dad83f87d5ac805b674c0b88c76 (patch) | |
| tree | 3463598b6e4fb2f3d639ddca92c90146495d19a0 /src/Parser/Expr.hs | |
| parent | 62b65e16f5ef4e59dcfbdc10ae2b3cd419d79d7a (diff) | |
Diffstat (limited to 'src/Parser/Expr.hs')
| -rw-r--r-- | src/Parser/Expr.hs | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/src/Parser/Expr.hs b/src/Parser/Expr.hs index c12d004..16c2b45 100644 --- a/src/Parser/Expr.hs +++ b/src/Parser/Expr.hs @@ -162,7 +162,7 @@ quotedString = label "string" $ lexeme $ do regex :: TestParser (Expr Regex) regex = label "regular expression" $ lexeme $ do off <- stateOffset <$> getParserState - void $ char '/' + void $ try $ char '/' <* notFollowedBy (char '=') -- TODO: better parsing rules for regexes let inner = choice [ char '/' >> return [] , takeWhile1P Nothing (`notElem` ['/', '\\', '$']) >>= \s -> (Pure (RegexPart (TL.toStrict s)) :) <$> inner @@ -418,12 +418,27 @@ constructor = label "constructor" $ do functionCall :: TestParser SomeExpr functionCall = do sline <- getSourceLine - (variable <|> constructor) >>= \case - SomeExpr e'@(FunVariable argTypes _ _) -> do - let check = checkFunctionArguments argTypes - args <- functionArguments check (someExpr FunctionTerm) literal (\poff -> lookupVarExpr poff sline . VarName) - return $ SomeExpr $ ArgsApp args e' - e -> return e + off <- stateOffset <$> getParserState + + fun <- variable <|> constructor + FunctionArguments margs <- functionArguments (\poff _ e -> return ( poff, e )) (someExpr FunctionTerm) literal (\poff -> lookupVarExpr poff sline . VarName) + if M.null margs + then return fun + else do + dict <- newTypeVar + res <- newTypeVar + SomeExpr (expr :: Expr fa) <- unifySomeExpr off (ExprTypeFunction (ExprTypeVar dict) (ExprTypeVar res)) fun + Just (ExprTypeArguments argTypes) <- M.lookup dict <$> gets testTypeUnif + args <- fmap (FunctionArguments . M.fromAscList) $ mapM (\( kw, ( poff, e ) ) -> ( kw, ) <$> checkFunctionArguments argTypes poff kw e) $ M.toAscList margs + M.lookup res <$> gets testTypeUnif >>= \case + Just (ExprTypePrim (_ :: Proxy a)) + | Just (Refl :: FunctionType a :~: fa) <- eqT + -> return $ SomeExpr $ ArgsApp args expr + | otherwise -> error $ "type mismatch after function unification: " <> show ( typeRep (Proxy @(FunctionType a)), typeRep (Proxy @fa) ) + _ + | Just (Refl :: FunctionType DynamicType :~: fa) <- eqT + -> return $ SomeExpr $ ArgsApp args expr + | otherwise -> error $ "type mismatch after function unification: " <> show ( typeRep (Proxy @(FunctionType DynamicType)), typeRep (Proxy @fa) ) recordSelector :: SomeExpr -> TestParser SomeExpr recordSelector (SomeExpr expr) = do |