Created
May 31, 2015 16:42
-
-
Save setupminimal/a1346094aedcf2685f08 to your computer and use it in GitHub Desktop.
Racket RPN Transformation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket | |
(require syntax/strip-context) | |
; A '#lang reader' language must provide read and read-syntax, which return a module form | |
; The idea is that "3 4 +:2 7 eq?:2" gets turned into '(module anything racket (eq? (+ 3 4) 7)) | |
(provide (rename-out [rpn-read read] | |
[rpn-read-syntax read-syntax])) | |
(define (rpn-read in) | |
(syntax->datum | |
(rpn-read-syntax #f in))) | |
(define (rpn-read-syntax src in) | |
(strip-context | |
(construct-module (parse-to-sexps src in)))) | |
(define (construct-module body) | |
`(module anything racket ,@body)) | |
(define (parse-to-sexps src in) | |
(flip-around (map read-string (string-split (port->string in))) '())) | |
(define (read-string str) | |
(read (open-input-string str))) | |
; flip-around: if the first symbol ends in :(number), put (symbol de-stack de-stack de-stack . . .) on stack, | |
; otherwise put symbol on stack | |
(define (with-n n sym list) | |
(cons (cons sym (reverse (take list n))) (list-tail list n))) | |
(define (split-symbol item) | |
(cons (string->symbol (car (regexp-match "[^:]+" (symbol->string item)))) | |
(string->number (car (regexp-match "[0-9]+" (symbol->string item)))))) | |
(define (swap-onto item stack) | |
(let ((n (cdr (split-symbol item))) | |
(first-bit (car (split-symbol item)))) | |
(with-n n first-bit stack))) | |
(define (ends-correctly item) | |
; The appropriate regular expression: #rx"[.]+:[0-9]+" | |
(and (symbol? item) | |
(regexp-match? #rx"[.]*:[0-9]*" (symbol->string item)))) | |
(define (shuffle source stack) | |
(let ((first (car source)) | |
(rest (cdr source))) | |
(if (ends-correctly first) | |
(list rest (swap-onto first stack)) | |
(list rest (cons first stack))))) | |
(define (flip-around source stack) | |
(if (eq? source '()) | |
stack | |
(apply flip-around (shuffle source stack)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment