From fa8991082ab4ca037238cf14cb1cb0c55dec6b44 Mon Sep 17 00:00:00 2001 From: hellerve Date: Thu, 27 Feb 2020 17:22:03 +0100 Subject: [PATCH] initial --- README.md | 21 +++++++++++++++++++++ infix.carp | 28 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 README.md create mode 100644 infix.carp diff --git a/README.md b/README.md new file mode 100644 index 0000000..b73edae --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# infix + +A sketch for an infix-to-prefix transformer in Carp (used for match). + +It’s based on my sketchy recollection of something I’ve maybe seen in SICP, +and something I implemented years ago for zepto’s standard library. + +It’s mostly instructional and I don’t recommend you actually use it. + +## Usage + +After loading `infix.carp`, you’ll be able to use it like this: + +```clojure +(infix 10 * 5 + 3 / 12 pow 2) +; will transform into (+ (* 10 5) (/ 3 (pow 12 2))) +``` + +
+ +Have fun! diff --git a/infix.carp b/infix.carp new file mode 100644 index 0000000..1da0aa0 --- /dev/null +++ b/infix.carp @@ -0,0 +1,28 @@ +(defndynamic null? [l] (= (length l) 0)) + +(defndynamic infix-prec [op] + (if (Dynamic.or (= op '+) (= op '-)) 1 + (if (= 'pow op) 3 + 2))) + +(defndynamic infix-op [expr operators operands] + (infix-parse expr + (cdr operators) + (cons (list (car operators) (cadr operands) (car operands)) + (cddr operands)))) + +(defndynamic infix-parse [expr operators operands] + (if (null? expr) + (if (null? operators) + (car operands) + (infix-op expr operators operands)) + (if (list? (car expr)) + (infix:parse (cdr expr) operators (cons (infix:parse (car expr)) operands)) + (if (symbol? (car expr)) + (if (Dynamic.or (null? operators) + (> (infix-prec (car expr)) (infix-prec (car operators)))) + (infix-parse (cdr expr) (cons (car expr) operators) operands) + (infix-op expr operators operands)) + (infix-parse (cdr expr) operators (cons (car expr) operands)))))) + +(defmacro infix [:rest args] (infix-parse args '() '()))