Character and string literal support for the elisp lexer.
[bpt/guile.git] / test-suite / tests / elisp-reader.test
1 ;;;; elisp-reader.test --- Test the reader used by the Elisp compiler.
2 ;;;;
3 ;;;; Copyright (C) 2009 Free Software Foundation, Inc.
4 ;;;; Daniel Kraft
5 ;;;;
6 ;;;; This library is free software; you can redistribute it and/or
7 ;;;; modify it under the terms of the GNU Lesser General Public
8 ;;;; License as published by the Free Software Foundation; either
9 ;;;; version 3 of the License, or (at your option) any later version.
10 ;;;;
11 ;;;; This library is distributed in the hope that it will be useful,
12 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ;;;; Lesser General Public License for more details.
15 ;;;;
16 ;;;; You should have received a copy of the GNU Lesser General Public
17 ;;;; License along with this library; if not, write to the Free Software
18 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
20 (define-module (test-elisp-reader)
21 :use-module (test-suite lib)
22 :use-module (language elisp lexer))
23
24
25 ; ==============================================================================
26 ; Test the lexer.
27
28 ; This is of course somewhat redundant with the full parser checks, but probably
29 ; can't hurt and is useful in developing the lexer itself.
30
31 (define (get-string-lexer str)
32 (call-with-input-string str get-lexer))
33
34 (define (lex-string str)
35 (let ((lexer (get-string-lexer str)))
36 (let iterate ((result '()))
37 (let ((token (lexer)))
38 (if (eq? token '*eoi*)
39 (reverse result)
40 (iterate (cons token result)))))))
41
42 (with-test-prefix "Lexer"
43
44 (let ((lexer (get-string-lexer "")))
45 (pass-if "end-of-input"
46 (and (eq? (lexer) '*eoi*)
47 (eq? (lexer) '*eoi*)
48 (eq? (lexer) '*eoi*))))
49
50 (pass-if "single character tokens"
51 (equal? (lex-string "()[]'`, . ")
52 '((paren-open . #f) (paren-close . #f)
53 (square-open . #f) (square-close . #f)
54 (quote . #f) (backquote . #f) (unquote . #f) (dot . #f))))
55
56 (pass-if "whitespace and comments"
57 (equal? (lex-string " (\n\t) ; this is a comment\n. ; until eof")
58 '((paren-open . #f) (paren-close . #f) (dot . #f))))
59
60 (pass-if "source properties"
61 (let ((x (car (lex-string "\n\n \n . \n"))))
62 (and (= (source-property x 'line) 4)
63 (= (source-property x 'column) 3))))
64
65 (pass-if "symbols"
66 (equal? (lex-string "foo FOO char-to-string 1+ \\+1
67 \\(*\\ 1\\ 2\\)
68 +-*/_~!@$%^&=:<>{}
69 abc(def)ghi .e5")
70 `((symbol . foo) (symbol . FOO) (symbol . char-to-string)
71 (symbol . 1+) (symbol . ,(string->symbol "+1"))
72 (symbol . ,(string->symbol "(* 1 2)"))
73 (symbol . +-*/_~!@$%^&=:<>{})
74 (symbol . abc) (paren-open . #f) (symbol . def)
75 (paren-close . #f) (symbol . ghi) (symbol . .e5))))
76
77 ; Here we make use of the property that exact/inexact numbers are not equal?
78 ; even when they have the same numeric value!
79 (pass-if "integers"
80 (equal? (lex-string "-1 1 1. +1 01234")
81 '((integer . -1) (integer . 1) (integer . 1) (integer . 1)
82 (integer . 1234))))
83 (pass-if "floats"
84 (equal? (lex-string "1500.0 15e2 15.e2 1.5e3 .15e4 -.345e-2")
85 '((float . 1500.0) (float . 1500.0) (float . 1500.0)
86 (float . 1500.0) (float . 1500.0)
87 (float . -0.00345))))
88
89 ; Check string lexing, this also checks basic character escape sequences
90 ; that are then (hopefully) also correct for character literals.
91 (pass-if "strings"
92 (equal? (lex-string "\"foo\\nbar
93 test\\
94 \\\"ab\\\"\\\\ ab\\ cd
95 \\418\\0415\\u0041\\U0000000A\\Xab\\x0000000000000004fG.\" ")
96 '((string . "foo\nbar
97 test\"ab\"\\ abcd
98 !8!5A\nXabOG."))))
99 (pass-if "ASCII control characters and meta in strings"
100 (equal? (lex-string "\"\\^?\\C-a\\C-A\\^z\\M-B\\M-\\^@\\M-\\C-a\"")
101 '((string . "\x7F\x01\x01\x1A\xC2\x80\x81"))))
102
103 ; Character literals, taking into account that some escape sequences were
104 ; already checked in the strings.
105 (pass-if "characters"
106 (equal? (lex-string "?A?\\z ? ?\\x21 ?\\^j ?\\\\?\\n?\\\n")
107 `((character . 65) (character . ,(char->integer #\z))
108 (character . 32) (character . ,(char->integer #\!))
109 (character . 10) (character . ,(char->integer #\\))
110 (character . 10) (character . 10))))
111 (pass-if "meta characters"
112 (equal? (map cdr (lex-string "?\\C-[?\\M-\\S-Z?\\^X?\\A-\\s-\\H-\\s"))
113 `(,(+ (expt 2 26) (char->integer #\[))
114 ,(+ (expt 2 27) (expt 2 25) (char->integer #\Z))
115 ,(- (char->integer #\X) (char->integer #\@))
116 ,(+ (expt 2 22) (expt 2 23) (expt 2 24) 32)))))