fiddle with `case-pattern`

pull/10/head
Matthew Butterick 7 years ago
parent 17785714fe
commit 706e20b5fb

@ -2,11 +2,24 @@
(require "go.rkt")
(provide b-if b-comp-expr b-logic-expr)
;; b-if : /"if" b-expr /"then" b-expr [/"else" b-expr]
(define (b-if cond-expr then-expr [else-expr #f])
(cond
[(not (zero? cond-expr)) (b-goto then-expr)]
[else-expr => b-goto]))
#|
explain why this won't work due to premature eval of THEN & ELSE
(define (b-if COND THEN ELSE)
(let ([result (if (not (zero? COND))
THEN
ELSE)])
(when (exact-positive-integer? result)
(b-goto result))))
|#
(define-macro-cases b-if
[(_ COND THEN) #'(b-if COND THEN #f)]
[(_ COND THEN ELSE) #'(let ([result (if (not (zero? COND))
THEN
ELSE)])
(when (exact-positive-integer? result)
(b-goto result)))])
(define bool-int (λ (val) (if val 1 0)))
(define bi= (compose1 bool-int =))

@ -3,7 +3,7 @@
(define-lex-abbrev digits (:+ (char-set "0123456789")))
(define-lex-abbrev reserved-terms (:or "print" "goto" "end" "+" ":" ";" "let" "=" "input" "-" "*" "/" "^" "mod" "(" ")" "def" "if" "then" "else" "and" "or" "<" ">" "!" "gosub" "return" "for" "to" "step" "next"))
(define-lex-abbrev reserved-terms (:or "print" "goto" "end" "+" ":" ";" "let" "=" "input" "-" "*" "/" "^" "mod" "(" ")" "def" "if" "then" "else" "and" "or" "not" "<" ">" "<>" "gosub" "return" "for" "to" "step" "next"))
(define basic-lexer
(lexer-srcloc

@ -12,7 +12,7 @@ b-print : /"print" [b-printable] (/";" [b-printable])*
@b-printable : STRING | b-expr
b-goto : /"goto" b-expr
b-let : [/"let"] b-id /"=" (STRING | b-expr)
b-if : /"if" b-expr /"then" b-expr [/"else" b-expr]
b-if : /"if" b-expr /"then" (b-statement | b-expr) [/"else" (b-statement | b-expr)]
b-gosub : /"gosub" b-expr
b-return : /"return"
b-input : /"input" b-id
@ -22,8 +22,8 @@ b-for : /"for" b-id /"=" b-expr /"to" b-expr [/"step" b-expr]
b-next : /"next" [b-id]
b-expr : b-logic-expr
b-logic-expr : [b-logic-expr ("and" | "or")] b-comp-expr
b-comp-expr : [b-comp-expr ("=" | "<" | ">")] b-sum
b-logic-expr : [b-logic-expr ("and"|"or"|"not")] b-comp-expr
b-comp-expr : [b-comp-expr ("="|"<"|">"|"<>")] b-sum
b-sum : [b-sum ("+"|"-")] b-product
b-product : [b-product ("*"|"/"|"mod")] b-neg
b-neg : ["-"] b-expt

@ -26,10 +26,22 @@
(require rackunit))
(define-macro (syntax-match STX-ARG [(syntax PATTERN) BODY ...] ...)
#'(syntax-case STX-ARG ()
[PATTERN BODY ...] ...))
(define-macro-cases case-pattern
[(_ STX-ARG
[PAT . BODY]
...
[else . ELSEBODY]) (with-syntax ([(LITERAL ...) (generate-literals #'(PAT ...))])
#'(syntax-case STX-ARG (LITERAL ...)
[PAT . BODY]
...
[else . ELSEBODY]))]
[(_ STX-ARG
PAT+BODY
...) #'(case-pattern STX-ARG
PAT+BODY
...
[else (raise-syntax-error 'case-pattern
(format "unable to match pattern for ~v" (syntax->datum STX-ARG)))])])
(define-macro-cases with-pattern
[(_ () . BODY) #'(begin . BODY)]

Loading…
Cancel
Save