#lang racket/unit ;; Implements I-Expressions from SRFI-49 and the extensions for ;; Sweet Expressions ;; An indented line is a parameter of its parent, later terms on a line are parameters of the first term, ;; and lists of lists are prefixed with the term "group". ;; A line with exactly one datum, and no child lines, is simply that item; otherwise that line and its ;; child lines are themselves a new list. Indentation is disabled inside the grouping pairs (), [], and {}, ;; whether they are prefixed or not. Lines with only leading whitespace and a ;-comment are completely ignored - ;; even their indentation is irrelevant. Empty lines, possibly with tabs and spaces, are ignored during reading ;; of the initial line of an expression; otherwise they end an expression. ;; A blank line always terminates a datum, so once you've entered a complete expression, "Enter Enter" will always end it. ;; The "blank lines at the beginning are ignored" rule eliminates a usability problem with the original I-expression spec, ;; in which two sequential blank lines surprisingly return (). (The sample implementation did end expressions on a blank line ;; - the problem was that the spec didn't capture this.) A function call with 0 parameters must be surrounded or ;; immediately followed by a pair of parentheses: (pi) or pi(). ;; Generally it's best to start each new expression on the left edge; if you choose not do to that, include a blank line ;; between each new expression. (require "read-sig.rkt" "util.rkt") (import read^) (export (rename read^ [iexp-read read] [iexp-read-syntax read-syntax])) ;; read-syntax for I-Expressions (define (iexp-read-syntax [source-name #f] [port (current-input-port)]) (when (not source-name) (set! source-name (object-name port))) (parameterize ([current-source-name source-name] [current-input-port port]) (read-syntax-helper 0))) ;; indent - indentation level as an e-n-i? (define (read-syntax-helper indent) (define-values (line col pos) (port-next-location)) (define c (peek-char)) (cond [(char-whitespace? c) (read-char) (read-syntax-helper (add1 indent))] [(comment-char? c) (skip-line)] [else (read-item)]))