Skip to content

Commit 5190c60

Browse files
committed
Add compact lambdas
1 parent 33e1fbf commit 5190c60

5 files changed

Lines changed: 46 additions & 2 deletions

File tree

lapse.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 3.0
22
name: lapse
3-
version: 2.0.2
3+
version: 2.0.4
44
license: GPL-3.0-only
55
license-file: LICENSE
66
author: ProggerX

src/Lapse/Lambda.hs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
13
module Lapse.Lambda where
24

35
import Control.Monad ((<=<))
46
import Control.Monad.State (get, gets, put)
7+
import Data.List (sort)
58
import Data.Map.Strict (empty, fromList)
69
import Lapse.Eval (eval)
710
import Lapse.Operators (lset)
11+
import Lapse.Scopes (getValueM)
812
import Lapse.Types (Func, LapseM, Scopes, Value (..))
913

1014
data UnList m = Proper [Value] | Improper ([Value], Value) | Single Value deriving (Show)
@@ -77,3 +81,18 @@ macro _ = error "Wrong macro expression"
7781
defmacro :: Func
7882
defmacro (Pair (Name fname) ls@(Pair _ (Pair _ Nil))) = macro ls >>= \x -> lset (Pair (Name fname) (Pair x Nil))
7983
defmacro _ = error "Wrong defmacro expression"
84+
85+
findFree :: Value -> LapseM [String]
86+
findFree = \case
87+
Name x ->
88+
getValueM x >>= \case
89+
Just _ -> pure []
90+
Nothing -> pure [x]
91+
Pair x y -> concat <$> sequence [findFree x, findFree y]
92+
_ -> pure []
93+
94+
compact :: Func
95+
compact v = do
96+
freeVars <- sort <$> findFree v
97+
let args = foldr (Pair . Name) Nil freeVars
98+
Function <$> mkFunction args v

src/Lapse/Modules.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Data.ByteString.Char8 qualified as BC
99
import Data.FileEmbed (embedFileRelative)
1010
import Data.Map.Strict (Map, empty, fromList, (!?))
1111
import Lapse.Eval (eval)
12-
import Lapse.Lambda (define, defmacro, lambda, macro)
12+
import Lapse.Lambda (compact, define, defmacro, lambda, macro)
1313
import Lapse.Modules.FS qualified as FS
1414
import Lapse.Modules.Json qualified as Json
1515
import Lapse.Modules.Web qualified as Web
@@ -63,6 +63,7 @@ std =
6363
, ("float", Function lflt)
6464
, ("floor", Function lfloor)
6565
, ("throw", Function lthr)
66+
, ("compact", Macros compact)
6667
]
6768

6869
io :: Scope

src/Lapse/Parser.hs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ stringToken (c : cs) cur = case c of
2121
)
2222
_ -> stringToken cs (cur ++ [c])
2323

24+
compactLambda :: String -> String -> (String, String)
25+
compactLambda [] _ = error "Tokenize error in compactLambda"
26+
compactLambda (c : cs) cur = case c of
27+
'}' -> (('{' : cur) ++ ['}'], cs)
28+
_ -> compactLambda cs (cur ++ [c])
29+
2430
tokenize' :: String -> [String] -> String -> [String]
2531
tokenize' cur tokens (c : cs) = case c of
2632
'(' -> tokenize' "" ("(" : add' cur tokens) cs
@@ -32,6 +38,11 @@ tokenize' cur tokens (c : cs) = case c of
3238
new = stringToken cs ""
3339
newTokens = fst new : tokens
3440
newCs = snd new
41+
'{' -> tokenize' "" newTokens newCs
42+
where
43+
new = compactLambda cs ""
44+
newTokens = fst new : tokens
45+
newCs = snd new
3546
_ ->
3647
if isSpace c
3748
then tokenize' "" (add' cur tokens) cs
@@ -67,6 +78,9 @@ endsWith = (==) . last
6778
isString :: String -> Bool
6879
isString t = (t `endsWith` '"') && (t `startsWith` '"')
6980

81+
isCompactLambda :: String -> Bool
82+
isCompactLambda t = (t `endsWith` '}') && (t `startsWith` '{')
83+
7084
trim :: String -> String
7185
trim = init . tail
7286

@@ -75,6 +89,7 @@ parseToken t
7589
| all (\c -> isDigit c || c == '-') t && t /= "-" = Number $ read t
7690
| all (\c -> isDigit c || c == '-' || c == '.') t && t /= "-" && t /= "." = Float $ read t
7791
| isString t = String $ trim t
92+
| isCompactLambda t = Pair (Name "compact") (head $ parse $ "(" <> trim t <> ")")
7893
| otherwise = Name t
7994

8095
parse' :: [Value] -> [String] -> Value

src/Lapse/Scopes.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,14 @@ getValue' k (s : ss) = case s !? k of
3232
Just x -> x
3333
getValue' k [] = error $ "getValue: no such key: " ++ k ++ "!"
3434

35+
getValueM' :: String -> Scopes -> Maybe Value
36+
getValueM' k (s : ss) = case s !? k of
37+
Nothing -> getValueM' k ss
38+
Just x -> Just x
39+
getValueM' _ [] = Nothing
40+
3541
getValue :: String -> LapseM Value
3642
getValue = gets . getValue'
43+
44+
getValueM :: String -> LapseM (Maybe Value)
45+
getValueM = gets . getValueM'

0 commit comments

Comments
 (0)