Code to parse an STL file added by alexshendi on Sat Jul 27 18:37:11 2013

(define (lexer-aux inport res)
  (let ((token (read inport)))
    (if (eof-object? token)
        (reverse res)
        (lexer-aux inport (cons token res)))))

(define (lexer filename)
  (call-with-input-file filename
     (lambda (inport) 
        (lexer-aux inport '()))))

(define (parse-success val)
  (lambda (tokens idx)
    (list val idx)))

(define (parse-fail) 
  (lambda (tokens idx)
     (list #f #f)))

(define (parse-if pred?)
  (lambda (tokens idx)
     (let ((v (list-ref tokens idx)))
       (if (pred? v)
           (list v (+ idx 1))
           (list #f #f)))))

(define (parse-seq . parsers)
  (lambda (tokens idx)
     (let seq-loop ((parsers parsers)
                    (start idx)
                    (stop idx)
                    (seq-val '()))
         (if (null? parsers)
             (list (reverse seq-val) stop)
             (let ((v1 ((car parsers) tokens stop)))
                (if (cadr v1)
                    (seq-loop (cdr parsers) start (cadr v1)
                              (cons (car v1) seq-val))
                    (list #f #f)))))))

(define (parse-choice . parsers)
  (lambda (tokens idx)
     (let choice-loop ((parsers parsers))
         (if (null? parsers)
             (list #f #f)
             (let ((v1 ((car parsers) tokens idx)))
                (if (cadr v1)
                    v1 
                    (choice-loop (cdr parsers))))))))

(define (parse-repetition parser)
  (lambda (tokens idx)
    (let rep-loop ((start idx)
                   (res '()))
       (let ((v1 (parser tokens start)))
          (if (cadr v1)
              (rep-loop (cadr v1) (cons (car v1) res))
              (list (reverse res) start))))))

(define (parse-number n)
  (parse-if (lambda (x) (and (number? x) (= x n)))))

(define (parse-symbol s)
  (parse-if (lambda (x) (and (symbol? x) (eq? x s)))))
  
(define my-parser (parse-seq (parse-if (lambda (x) (eq? x 'hurz)))
                             (parse-if (lambda (x) (and (number? x) (= x 42))))))

(define my-parser-1
   (parse-seq (parse-if (lambda (x) (eq? x 'hurz)))
              (parse-if (lambda (x) (and (number? x) (= x 42))))
              (parse-if (lambda (x) (and (number? x) (= x 33))))))

(define my-parser-2 
   (parse-seq (parse-if (lambda (x) (eq? x 'hurz)))
              (parse-number 42)
              (parse-choice (parse-number 666) (parse-number 33))))

(display (my-parser '(hurz 42 33) 0))
(newline)
(display (my-parser-1 '(hurz 42 33) 0))
(newline)
(display (my-parser-2 '(hurz 42 33) 0))
(newline)
(display (my-parser-2 '(hurz 42 666) 0))
(newline)
(display (my-parser-2 '(hurz 42 555) 0))
(newline)

(define stl-parser
  (parse-seq (parse-symbol 'solid)
             (parse-if symbol?)
             (parse-repetition
               (parse-seq (parse-symbol 'facet)
                          (parse-seq (parse-symbol 'normal)
                                     (parse-if number?)
                                     (parse-if number?)
                                     (parse-if number?))
                          (parse-symbol 'outer)
                          (parse-symbol 'loop)
                          (parse-seq (parse-symbol 'vertex)
                                     (parse-if number?)
                                     (parse-if number?)
                                     (parse-if number?))
                          (parse-seq (parse-symbol 'vertex)
                                     (parse-if number?)
                                     (parse-if number?)
                                     (parse-if number?))
                          (parse-seq (parse-symbol 'vertex)
                                     (parse-if number?)
                                     (parse-if number?)
                                     (parse-if number?))
                          (parse-symbol 'endloop)
                          (parse-symbol 'endfacet)))
               (parse-symbol 'endsolid)
               (parse-if symbol?)))

(define (transform-expr expr)
  (map (lambda (facet)
         (list (cadr facet)
               (cons 'vertex-1 (transform-point (cdr (list-ref facet 4))))
               (cons 'vertex-2 (transform-point (cdr (list-ref facet 5))))
               (cons 'vertex-3 (transform-point (cdr (list-ref facet 6))))))
       (list-ref expr 2)))

(define (transform-point p)
  (let* ((x0 55.0)
         (y0 55.0)
         (z0 25.0)
         (x (* 0.001 (- (car p) x0)))
         (y (* 0.001 (- (cadr p) y0)))
         (z (* 0.001 (- (caddr p) z0))))
     (list x y z)))

(define (read-mesh meshfile)
  (let* ((res (stl-parser (lexer (cadr (command-line))) 0))
         (ntokens (cadr res))
         (exp (car res)))
    (transform-expr exp)))

(define (go)
  (display (read-mesh (cadr (command-line))))
  (newline))

(go)