#lang racket
(provide check-indent)
(require "../utilities.rkt")
(define checking-indent? (make-parameter #t))
(provide checking-indent?)
(define SLGC-min-offset 2)
(define (SLSC l1 c1 l2 c2)
(or (= l1 l2) (= c1 c2)))
(define (SLGC l1 c1 l2 c2)
(or (= l1 l2)
(>= (- c2 c1) SLGC-min-offset)))
(define (SLGEC l1 c1 l2 c2)
(or (= l1 l2)
(<= c1 c2)))
(define-syntax-rule (ms s1 s2)
(vector (syntax-source s1)
(syntax-line s1)
(syntax-column s1)
(syntax-position s1)
(- (+ (syntax-span s2) (syntax-position s2)) (syntax-position s1))))
(define (check-indent mode stx1 stx2)
(if (not (checking-indent?))
#t
(let ([l1 (syntax-line stx1)]
[c1 (syntax-column stx1)]
[l2 (syntax-line stx2)]
[c2 (syntax-column stx2)])
(if (and l1 c1 l2 c2)
(let ([proc (case mode
[(SLSC) SLSC]
[(SLGC) SLGC]
[(SLGEC) SLGEC]
[else #f])])
(if proc
(if (and (equal? (syntax-source stx1)
(syntax-source stx2))
(syntax-source stx1))
(if (proc l1 c1 l2 c2)
#t
(raise-pyret-error "this code is not well-indented"
(ms stx1 stx2)))
#t)
(error 'check-indent
"invalid mode ~S"
mode)))
#t))))