From 91bdd22abc67a2575018399f6ebfba35ee9621c7 Mon Sep 17 00:00:00 2001 From: ben Date: Wed, 2 Mar 2016 14:21:51 -0500 Subject: [PATCH] [math] add espt --- math.rkt | 18 ++++++++++++++++++ math/no-colon.rkt | 4 +++- test/math-fail.rkt | 2 ++ test/math-pass.rkt | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/math.rkt b/math.rkt index 06040f4..98e10f1 100644 --- a/math.rkt +++ b/math.rkt @@ -7,6 +7,8 @@ +: -: *: /: ;; Same signature as the racket/base operators, ;; but try to simplify arguments during expansion. + + expt: ) (require (for-syntax @@ -43,6 +45,22 @@ (make-numeric-operator *) (make-numeric-operator /) +(define-syntax (expt: stx) + (syntax-parse stx + [(_ e1 e2) + #:with e1+ (expand-expr #'e1) + #:with e2+ (expand-expr #'e2) + (let ([n1 (quoted-stx-value? #'e1+)] + [n2 (quoted-stx-value? #'e2+)]) + (if (and (number? n1) + (number? n2)) + (quasisyntax/loc stx #,(expt n1 n2)) + (syntax/loc stx (expt e1+ e2+))))] + [_:id + (syntax/loc stx expt)] + [(_ e* ...) + (syntax/loc stx (expt e* ...))])) + ;; ----------------------------------------------------------------------------- (define-for-syntax (division-by-zero stx) diff --git a/math/no-colon.rkt b/math/no-colon.rkt index fba3512..911208b 100644 --- a/math/no-colon.rkt +++ b/math/no-colon.rkt @@ -6,4 +6,6 @@ [+: +] [-: -] [*: *] - [/: /])) + [/: /] + [expt: expt] +)) diff --git a/test/math-fail.rkt b/test/math-fail.rkt index 824ea3c..0bd7575 100644 --- a/test/math-fail.rkt +++ b/test/math-fail.rkt @@ -12,11 +12,13 @@ (ann (let ([n 2]) (-: 2 n)) Zero) (ann (let ([n 5]) (*: n 1/5 1)) One) (ann (let ([n 4]) (/: n n)) One) + (ann (let ([n 2]) (expt: 3 (-: n n))) One) ;; -- lambda => back to racket/base (ann ((lambda ([f : (-> Natural Natural Natural)]) (f 0 0)) +:) Zero) (ann ((lambda ([f : (-> Natural Natural Integer)]) (f 0 0)) -:) Zero) (ann ((lambda ([f : (-> Natural Natural Natural)]) (f 0 0)) *:) Zero) (ann ((lambda ([f : (-> Natural Natural Exact-Rational)]) (f 0 0)) /:) Zero) + (ann ((lambda ([f : (-> Natural Natural Natural)]) (f 0 1)) expt:) Zero) ;; -- dividing by zero => caught statically (/: 1 1 0) (/: 1 1 (+: 4 -2 -2)) diff --git a/test/math-pass.rkt b/test/math-pass.rkt index c8ceb91..8fa1d91 100644 --- a/test/math-pass.rkt +++ b/test/math-pass.rkt @@ -79,4 +79,18 @@ (check-equal? (ann (let ([n 5]) (*: 3 n (+: -1 2))) Natural) 15) (check-equal? (ann (let ([n 4]) (/: n n)) Positive-Exact-Rational) 1) + ;; -- expt + (check-equal? + (ann (expt: 5 3) Index) + 125) + (check-equal? + (ann (expt: 99 0) One) + 1) + (check-equal? + (ann (expt: (+: 5 -5) 78) Zero) + 0) + (check-equal? + (ann (expt: (*: 2 2) (expt: 2 2)) Index) + 256) + )