-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.rkt
34 lines (25 loc) · 1.66 KB
/
main.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#lang racket/base
(require (for-syntax racket/base) syntax/parse/define)
(provide (rename-out [parse #%app] [> gt?] [>= gte?] [< lt?] [<= lte?] [+ add] [- subtract] [* multiply] [/ divide])
: ~> ~~> && || iterate)
;; defining the syntax operators allows them to be renamed using (rename-in)
(define-syntax (: stx) (raise-syntax-error #f "expected param names before lambda shorthand operator" stx))
(define-syntax (~> stx) (raise-syntax-error #f "expected single form before function composition operator" stx))
(define-syntax (~~> stx) (raise-syntax-error #f "expected single form before function composition operator" stx))
;; match our parse cases and default to racket/base #%app
(define-syntax-parser parse #:literals (: ~> ~~>)
;; infix lambda operator
[(_ (~seq (~and params (~not :)) ...) : atom) #'(lambda (params ...) atom)]
[(_ (~seq (~and params (~not :)) ...) : expr ...) #'(lambda (params ...) (parse expr ...))]
;; function composition operators
[(_ data (~seq ~> proc (~and args (~not ~>) (~not ~~>)) ...)) #'(#%app proc data args ...)]
[(_ data (~seq ~> proc (~and args (~not ~>) (~not ~~>)) ...) rest ...) #'(parse (proc data args ...) rest ...)]
[(_ data (~seq ~~> proc (~and args (~not ~>) (~not ~~>)) ...)) #'(#%app proc args ... data)]
[(_ data (~seq ~~> proc (~and args (~not ~>) (~not ~~>)) ...) rest ...) #'(parse (proc args ... data) rest ...)]
;; default parser
[(_ rest ...) #'(#%app rest ...)])
;; function composition doesn't work with built-in racket macros and and or, so wrap them in a procedure
(define (&& a b) (and a b))
(define (|| a b) (or a b))
;; convenience procedures
(define (iterate list proc) (for-each proc list))