diff --git a/.vscode/settings.json b/.vscode/settings.json index cc4be24..f24f34c 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,9 @@ { "cSpell.words": [ + "autochurch", "freevar", "pyparsing", + "runstatus", "subvar" ], "python.analysis.typeCheckingMode": "basic" diff --git a/README.md b/README.md index cd72363..3659894 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,8 @@ - Python files: installable, package list, etc - $\alpha$-equivalence check - Versioning - - Automatic church numerals - Prettyprint functions (combine args, rename bound variables) - Documentation in README - - Don't crash on errors ## Todo: - live syntax check @@ -22,4 +20,5 @@ - Pin header to top of screen ## Mention in Docs - - lambda functions only work with single-letter arguments \ No newline at end of file + - lambda functions only work with single-letter arguments + - church numerals \ No newline at end of file diff --git a/parser.py b/parser.py index 6e75be1..919edbe 100755 --- a/parser.py +++ b/parser.py @@ -1,5 +1,6 @@ import pyparsing as pp import tokens +import utils class Parser: """ @@ -20,6 +21,9 @@ class Parser: pp_macro = pp.Word(pp.alphas + "_") pp_macro.set_parse_action(tokens.macro.from_parse) + pp_church = pp.Word(pp.nums) + pp_church.set_parse_action(utils.autochurch) + # Function definitions. # Right associative. # @@ -50,7 +54,7 @@ class Parser: pp_call <<= pp_expr[2, ...] pp_call.set_parse_action(tokens.lambda_apply.from_parse) - pp_expr <<= pp_lambda_fun ^ (lp + pp_expr + rp) ^ pp_macro ^ (lp + pp_call + rp) + pp_expr <<= pp_lambda_fun ^ (lp + pp_expr + rp) ^ pp_macro ^ (lp + pp_call + rp) ^ pp_church pp_all = pp_expr | pp_macro_def pp_command = pp.Suppress(":") + pp.Word(pp.alphas + "_") diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..8590300 --- /dev/null +++ b/utils.py @@ -0,0 +1,24 @@ +import tokens + +def autochurch(results): + """ + Makes a church numeral from an integer. + """ + + num = int(results[0]) + + f = tokens.bound_variable() + a = tokens.bound_variable() + + chain = a + + for i in range(num): + chain = tokens.lambda_apply(f, chain) + + return tokens.lambda_func( + f, + tokens.lambda_func( + a, + chain + ) + ) \ No newline at end of file