From 1aca426b414e38e909fb589fb5d801359f9434a6 Mon Sep 17 00:00:00 2001 From: rockofox Date: Sun, 15 Dec 2024 15:56:19 +0100 Subject: [PATCH] Thunk lambdas (fixes #18) --- lib/BytecodeCompiler.hs | 5 +++-- lib/Parser.hs | 10 +++++----- lib/Verifier.hs | 2 +- share/std/test.in | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/BytecodeCompiler.hs b/lib/BytecodeCompiler.hs index 50738a9..164b363 100644 --- a/lib/BytecodeCompiler.hs +++ b/lib/BytecodeCompiler.hs @@ -634,9 +634,10 @@ compileExpr (Parser.Impl name for methods) expectedType = do compileExpr (Parser.Lambda args body) expectedType = do fId <- allocId curCon <- gets currentContext + let args' = if args == [Parser.Placeholder] then [] else args let name = "__lambda" ++ show fId - let def = Parser.FuncDef name args body - let dec = Parser.FuncDec name (replicate (length args + 1) expectedType) [] + let def = Parser.FuncDef name args' body + let dec = Parser.FuncDec name (replicate (length args' + 1) Parser.Any) [] let fun = Parser.Function [def] dec _ <- compileExpr fun expectedType lets' <- gets functions diff --git a/lib/Parser.hs b/lib/Parser.hs index df7a94b..4e7cf1c 100644 --- a/lib/Parser.hs +++ b/lib/Parser.hs @@ -85,13 +85,13 @@ binOpTable = , [binary "as" Cast] , [prefix "$" StrictEval] , [prefix "!" Not] + , [binary "++" ListAdd] + , [binary "**" Power, binary "*" Mul, binary "/" Div] + , [binary "+" Add, binary "-" Sub] , [binaryAny binaryFunctionCall] , -- , [prefix "-" UnaryMinus] - [binary "**" Power, binary "*" Mul, binary "/" Div] - , [binary "%" Modulo] + [binary "%" Modulo] , [binary ":" ListConcat] - , [binary "++" ListAdd] - , [binary "+" Add, binary "-" Sub] , -- , [binary ">>" Then] [binary "|>" Pipeline] , [binary ">>=" bindExpr] @@ -488,7 +488,7 @@ listPattern = do lambda :: Parser Expr lambda = do symbol "\\" - args <- some (var <|> parens listPattern <|> array) "lambda arguments" + args <- some (var <|> parens listPattern <|> array <|> placeholder) "lambda arguments" symbol "->" Lambda args <$> expr "lambda body" diff --git a/lib/Verifier.hs b/lib/Verifier.hs index b7c3114..a6e283e 100644 --- a/lib/Verifier.hs +++ b/lib/Verifier.hs @@ -377,7 +377,7 @@ verifyExpr (FuncCall name args (Position (start, _))) = do let eTypes = concatMap (\matchingBinding -> ([FancyError start (Set.singleton (ErrorFail ("Argument types do not match on " ++ name ++ ", expected: " ++ show matchingBinding.args ++ ", got: " ++ show argumentTypes))) | not fta])) matchingBindings return $ [FancyError start (Set.singleton (ErrorFail $ "Could not find relevant binding for " ++ name)) | null matchingBindings] ++ eArgs ++ eTypes ++ eNoMatchi verifyExpr (Lambda args body) = do - let argsAsBindings = map (\(Var name' _) -> VBinding{name = name', args = [], ttype = Any, generics = []}) args + let argsAsBindings = map (\case (Var name' _) -> VBinding{name = name', args = [], ttype = Any, generics = []}; Placeholder -> VBinding{name = "__placeholder", args = [], ttype = Any, generics = []}; _ -> error "Invalid lambda argument") args modify (\state -> state{frames = (VerifierFrame{bindings = Set.fromList argsAsBindings, ttypes = Map.empty, ftype = Any, fname = "__lambda"}) : frames state}) bodyErrors <- verifyExpr body modify (\state -> state{frames = tail (frames state)}) diff --git a/share/std/test.in b/share/std/test.in index c14a6ea..05b67a0 100644 --- a/share/std/test.in +++ b/share/std/test.in @@ -7,7 +7,7 @@ impl Monad for TestSuite = do sequence TestSuite{name: n, results: r} TestSuite{name: n2, results: r2} = TestSuite{name: n, results: r ++ r2} end -let testCase (n: String f: (Any -> Bool)) : TestSuite = TestSuite{results: [TestResult{name: n, result: f 1}]} +let testCase (n: String f: (Bool)) : TestSuite = TestSuite{results: [TestResult{name: n, result: f _}]} let evalTestSuite (suite: TestSuite) : IO = do let resultss = suite.results