lambda-repl 1.1.0__py3-none-any.whl → 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lambda_repl/__init__.py +26 -1
- lambda_repl/grammar.lark +5 -3
- lambda_repl/parsing.py +12 -7
- {lambda_repl-1.1.0.dist-info → lambda_repl-1.2.1.dist-info}/METADATA +14 -9
- lambda_repl-1.2.1.dist-info/RECORD +12 -0
- {lambda_repl-1.1.0.dist-info → lambda_repl-1.2.1.dist-info}/WHEEL +1 -2
- lambda_repl-1.1.0.dist-info/RECORD +0 -13
- lambda_repl-1.1.0.dist-info/top_level.txt +0 -1
- {lambda_repl-1.1.0.dist-info → lambda_repl-1.2.1.dist-info}/entry_points.txt +0 -0
- {lambda_repl-1.1.0.dist-info → lambda_repl-1.2.1.dist-info/licenses}/LICENSE +0 -0
lambda_repl/__init__.py
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
from cmd import Cmd
|
|
7
|
+
from importlib import import_module
|
|
7
8
|
from typing import Any
|
|
8
9
|
from lambda_calculus.terms import Term
|
|
9
10
|
from lambda_calculus.visitors.normalisation import (
|
|
@@ -14,7 +15,7 @@ from lark.exceptions import UnexpectedInput
|
|
|
14
15
|
from .parsing import LambdaTransformer
|
|
15
16
|
from .aliases import Aliases
|
|
16
17
|
|
|
17
|
-
__version__ = "1.1
|
|
18
|
+
__version__ = "1.2.1"
|
|
18
19
|
__author__ = "Eric Niklas Wolf"
|
|
19
20
|
__email__ = "eric_niklas.wolf@mailbox.tu-dresden.de"
|
|
20
21
|
__all__ = (
|
|
@@ -51,6 +52,19 @@ class LambdaREPL(Cmd):
|
|
|
51
52
|
self.stdout.write(error.get_context(term))
|
|
52
53
|
return None
|
|
53
54
|
|
|
55
|
+
def import_term(self, location: str) -> Term[str] | None:
|
|
56
|
+
"""import a term and handle error display"""
|
|
57
|
+
module, _, name = location.strip().rpartition(".")
|
|
58
|
+
try:
|
|
59
|
+
term = getattr(import_module(module), name)
|
|
60
|
+
except Exception as error: # pylint: disable=W0718
|
|
61
|
+
self.stdout.write(f"Error while importing: {error}\n")
|
|
62
|
+
return None
|
|
63
|
+
if not isinstance(term, Term):
|
|
64
|
+
self.stdout.write(f"Error: object {term} is not a lambda term\n")
|
|
65
|
+
return None
|
|
66
|
+
return term
|
|
67
|
+
|
|
54
68
|
def emptyline(self) -> bool:
|
|
55
69
|
"""ignore empty lines"""
|
|
56
70
|
return False
|
|
@@ -95,6 +109,17 @@ class LambdaREPL(Cmd):
|
|
|
95
109
|
self.stdout.write("invalid Command: missing alias value\n")
|
|
96
110
|
return False
|
|
97
111
|
|
|
112
|
+
def do_import(self, arg: str) -> bool:
|
|
113
|
+
"""import an alias from a module with name = module.name"""
|
|
114
|
+
match arg.partition("="):
|
|
115
|
+
case (alias, "=", location):
|
|
116
|
+
term = self.import_term(location)
|
|
117
|
+
if term is not None:
|
|
118
|
+
self.aliases[alias.strip()] = term
|
|
119
|
+
case _:
|
|
120
|
+
self.stdout.write("invalid Command: missing import location\n")
|
|
121
|
+
return False
|
|
122
|
+
|
|
98
123
|
def do_aliases(self, _: object) -> bool:
|
|
99
124
|
"""list defined aliases"""
|
|
100
125
|
for alias, term in self.aliases.items():
|
lambda_repl/grammar.lark
CHANGED
|
@@ -4,8 +4,10 @@ VARIABLE: /[^\s().λ\\]+/
|
|
|
4
4
|
|
|
5
5
|
abstraction: ("\\" | "λ") VARIABLE "." term
|
|
6
6
|
|
|
7
|
-
application:
|
|
7
|
+
application: _application_term _WHITESPACE (abstraction | _simple_term)
|
|
8
8
|
|
|
9
|
-
?
|
|
9
|
+
?term: abstraction | _application_term
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
_application_term: application | _simple_term
|
|
12
|
+
|
|
13
|
+
_simple_term: VARIABLE | "(" term ")"
|
lambda_repl/parsing.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
from collections import deque
|
|
7
|
-
from collections.abc import Iterator
|
|
7
|
+
from collections.abc import Iterator
|
|
8
8
|
from itertools import chain
|
|
9
9
|
from lambda_calculus.terms import Abstraction, Application, Term, Variable
|
|
10
10
|
from lark import Lark, Token
|
|
@@ -52,10 +52,10 @@ class LambdaTransformer(Transformer[Token, Term[str]]):
|
|
|
52
52
|
"""parse a string and return the transformed lambda term"""
|
|
53
53
|
# the parser sometimes return tokens directly instead of a tree
|
|
54
54
|
match PARSER.parse(string):
|
|
55
|
-
case Token(type="VARIABLE") as name:
|
|
56
|
-
return self.VARIABLE(name)
|
|
57
|
-
case Token() as token:
|
|
58
|
-
raise UnexpectedToken(token, {"VARIABLE",})
|
|
55
|
+
case Token(type="VARIABLE") as name:
|
|
56
|
+
return self.VARIABLE(name)
|
|
57
|
+
case Token() as token:
|
|
58
|
+
raise UnexpectedToken(token, {"VARIABLE", })
|
|
59
59
|
case tree:
|
|
60
60
|
return self.transform(tree)
|
|
61
61
|
|
|
@@ -63,6 +63,10 @@ class LambdaTransformer(Transformer[Token, Term[str]]):
|
|
|
63
63
|
"""handle unknown nodes"""
|
|
64
64
|
raise UnexpectedInput(f"unknown node: {data}")
|
|
65
65
|
|
|
66
|
+
def __default_token__(self, token: Token) -> Token:
|
|
67
|
+
"""handle unknown tokens"""
|
|
68
|
+
raise UnexpectedInput(f"unknown token: {token}")
|
|
69
|
+
|
|
66
70
|
def VARIABLE(self, name: Token) -> Variable[str]:
|
|
67
71
|
"""transform a variable node"""
|
|
68
72
|
return Variable(name.value)
|
|
@@ -72,9 +76,10 @@ class LambdaTransformer(Transformer[Token, Term[str]]):
|
|
|
72
76
|
"""transform an abstraction"""
|
|
73
77
|
return Abstraction(variable.name, body)
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
@v_args(inline=True)
|
|
80
|
+
def application(self, abstraction: Term[str], argument: Term[str]) -> Application[str]:
|
|
76
81
|
"""transform an application"""
|
|
77
|
-
return Application
|
|
82
|
+
return Application(abstraction, argument)
|
|
78
83
|
|
|
79
84
|
|
|
80
85
|
PARSER = Lark.open_from_package(
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
2
|
-
Name:
|
|
3
|
-
Version: 1.1
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lambda_repl
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: REPL for the lambda calculus
|
|
5
|
-
Author-email: Eric Niklas Wolf <eric_niklas.wolf@mailbox.tu-dresden.de>
|
|
6
5
|
Project-URL: Repository, https://github.com/Deric-W/lambda_repl
|
|
7
6
|
Project-URL: Bugtracker, https://github.com/Deric-W/lambda_repl/issues
|
|
7
|
+
Author-email: Eric Niklas Wolf <eric_niklas.wolf@mailbox.tu-dresden.de>
|
|
8
|
+
License-File: LICENSE
|
|
8
9
|
Classifier: Intended Audience :: Education
|
|
9
10
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
10
11
|
Classifier: Operating System :: OS Independent
|
|
@@ -13,23 +14,25 @@ Classifier: Topic :: Education
|
|
|
13
14
|
Classifier: Topic :: Utilities
|
|
14
15
|
Classifier: Typing :: Typed
|
|
15
16
|
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: lambda-calculus~=3.0
|
|
18
|
+
Requires-Dist: lark~=1.0
|
|
16
19
|
Description-Content-Type: text/markdown
|
|
17
|
-
License-File: LICENSE
|
|
18
|
-
Requires-Dist: lambda-calculus (~=2.0)
|
|
19
|
-
Requires-Dist: lark (~=1.0)
|
|
20
20
|
|
|
21
21
|
# lambda_repl
|
|
22
22
|
|
|
23
|
+
[](https://github.com/pypa/hatch)
|
|
23
24
|

|
|
24
25
|
[](https://codecov.io/gh/Deric-W/lambda_repl)
|
|
25
26
|
|
|
26
|
-
The `lambda_repl` package contains a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)
|
|
27
|
+
The `lambda_repl` package contains a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)
|
|
28
|
+
for the [lambda calculus](https://en.wikipedia.org/wiki/Lambda_calculus).
|
|
27
29
|
|
|
28
30
|
To use it, execute `lambda-repl` or `python3 -m lambda_repl` and enter commands.
|
|
29
31
|
|
|
30
32
|
## Requirements
|
|
31
33
|
|
|
32
|
-
Python >= 3.10 and the `lambda_calculus`
|
|
34
|
+
Python >= 3.10 and the packages [`lambda_calculus`](https://github.com/Deric-W/lambda_calculus)
|
|
35
|
+
and [`lark`](https://github.com/lark-parser/lark) are required to use this package.
|
|
33
36
|
|
|
34
37
|
## Installation
|
|
35
38
|
|
|
@@ -44,9 +47,11 @@ python3 -m lambda_repl
|
|
|
44
47
|
Welcome to the the Lambda REPL, type 'help' for help
|
|
45
48
|
λ alias I = \x.x
|
|
46
49
|
λ alias K = λx.λy.x
|
|
50
|
+
λ import SUCC = lambda_calculus.terms.arithmetic.SUCCESSOR
|
|
47
51
|
λ aliases
|
|
48
52
|
I = (λx.x)
|
|
49
53
|
K = (λx.(λy.x))
|
|
54
|
+
SUCC = (λn.(λf.(λx.(f ((n f) x)))))
|
|
50
55
|
λ trace K a b
|
|
51
56
|
β ((λy.a) b)
|
|
52
57
|
β a
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
lambda_repl/__init__.py,sha256=3cAdjhU-P2CvQ7-Yww1ag8OawfcrW1uONab9J6XDsdQ,4823
|
|
2
|
+
lambda_repl/__main__.py,sha256=0R69kMLopBXwWwgiq_kB8vdvUXHWF_95iRIrPYMtidg,103
|
|
3
|
+
lambda_repl/aliases.py,sha256=U0-JFP3fI-9-su0M3DiTqp6fMfZQfcdmOxxdzE5iHgQ,1815
|
|
4
|
+
lambda_repl/grammar.lark,sha256=C3Cn24FyOBQERwLvgZ2iYnspA9of2OQKJoFVNlD3DE0,291
|
|
5
|
+
lambda_repl/main.py,sha256=SrxFQwUfQFWCpXYgyCn1h-cHyJnBYee-kIdZn0CbbBU,1229
|
|
6
|
+
lambda_repl/parsing.py,sha256=eZuHX7qR0aAqeIxX83SHM_Az8MvdROL7KmplS1zFGTM,3112
|
|
7
|
+
lambda_repl/py.typed,sha256=rVxfNzv1aKmfThIlRztkUwWiKeYa4XTdtNMh3FV-dGM,25
|
|
8
|
+
lambda_repl-1.2.1.dist-info/METADATA,sha256=uI6qGfcbmt6zfcVcJ19L3-I-ra_fFSgz2CtsPmmjWz8,1986
|
|
9
|
+
lambda_repl-1.2.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
10
|
+
lambda_repl-1.2.1.dist-info/entry_points.txt,sha256=k_lpUdSJyLWmOpBUiJG569al7o5XOZNeGJBrBqYBaNc,58
|
|
11
|
+
lambda_repl-1.2.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
12
|
+
lambda_repl-1.2.1.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
lambda_repl/__init__.py,sha256=r8q0eqyRnsAalTxsEjmi5nbNy1gC-Dkj8fq2itOXeEU,3781
|
|
2
|
-
lambda_repl/__main__.py,sha256=0R69kMLopBXwWwgiq_kB8vdvUXHWF_95iRIrPYMtidg,103
|
|
3
|
-
lambda_repl/aliases.py,sha256=U0-JFP3fI-9-su0M3DiTqp6fMfZQfcdmOxxdzE5iHgQ,1815
|
|
4
|
-
lambda_repl/grammar.lark,sha256=yE3sSoIpEShOzplMIWnDeS5e4o7ODA_JJtMLzsTlUUs,279
|
|
5
|
-
lambda_repl/main.py,sha256=SrxFQwUfQFWCpXYgyCn1h-cHyJnBYee-kIdZn0CbbBU,1229
|
|
6
|
-
lambda_repl/parsing.py,sha256=1pWv_C0KMLeTXcaoFPRDFJgypFpo1IuueUEJkAQ1mE0,3025
|
|
7
|
-
lambda_repl/py.typed,sha256=rVxfNzv1aKmfThIlRztkUwWiKeYa4XTdtNMh3FV-dGM,25
|
|
8
|
-
lambda_repl-1.1.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
9
|
-
lambda_repl-1.1.0.dist-info/METADATA,sha256=V_vD35_eGvdTebqHxYmNGHIlZBTy0a2NNRMcW6-oVE0,1686
|
|
10
|
-
lambda_repl-1.1.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
|
11
|
-
lambda_repl-1.1.0.dist-info/entry_points.txt,sha256=k_lpUdSJyLWmOpBUiJG569al7o5XOZNeGJBrBqYBaNc,58
|
|
12
|
-
lambda_repl-1.1.0.dist-info/top_level.txt,sha256=S7zlQx9MQUHM6OzLqKf8U6pW1ucdFKOMe-WHYK0T2N0,12
|
|
13
|
-
lambda_repl-1.1.0.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
lambda_repl
|
|
File without changes
|
|
File without changes
|