Initial checkin of Pika from heckimp

This commit is contained in:
2023-09-25 15:35:21 -07:00
commit 891e999216
6761 changed files with 5240685 additions and 0 deletions

View File

@ -0,0 +1,179 @@
; test atom->string function
; atom->string is not R5RS
; Instead, it is TinyScheme specific.
; atom->string works for atoms of type: number, char, string, byte, symbol.
; This is not the usual definition of atom.
; Others define atom as anything but list and pair.
; For atom of type number,
; accepts an optional second arg: <base> in [2,8,10,16]
; Meaning arithmetic base binary, octal, decimal, hexadecimal.
; For atoms of other types, passing a base returns an error.
; The REPL uses an internal C function atom2str()
; which is not exposed in the TS language.
; It *DOES* represent every object (all atoms) as strings.
; But the representation is sometimes a string that can
; be turned around and evaluated,
; which is not the same string as atom->string produces.
; !!! Note readstring() internal function
; accepts and reduces C "escaped" string representations
; i.e. \x07 or \t for tab.
; Thus in a test, a double-quoted string enclosing
; an escape sequence can be equivalent to a
; string for a char atom.
; normal tests (without error)
; number
; number, integer aka fixnum
(assert `(string=? (atom->string 1)
"1"))
; number, float aka flonum
(assert `(string=? (atom->string 1.0)
"1.0"))
; FIXME the above is known to fail in German:
; currently prints 1,0.
; To test, set locale to German and retest.
; There are no other numeric types in TinyScheme.
; Refer to discussions of "Lisp numeric tower"
; char
; ASCII, i.e. fits in 8-bit byte
; char, ASCII, printing and visible
(assert `(string=? (atom->string 'a)
"a"))
; char, ASCII, non-printing, whitespace
(assert `(string=? (atom->string #\space)
" "))
; Note the char between quotes is a tab char
; whose display when viewing this source depends on editor.
; Some editors will show just a single white glyph.
;
; Note also that the SF Console will print "\t"
; i.e. this is not a test of the REPL.
(assert `(string=? (atom->string #\tab)
" "))
; Note the char between quotes is a newline char
(assert `(string=? (atom->string #\newline)
"
"))
; Note between quotes is an escaped return char,
; which readstring() converts to a single char
; decimal 13, hex 0d
(assert `(string=? (atom->string #\return)
"\x0d"))
; char, ASCII, non-printing control
(assert `(string=? (atom->string #\x7)
""))
; !!! This also passes, because readstring converts
; the \x.. escape sequence to a char.
(assert `(string=? (atom->string #\x7)
"\x07"))
; !!! Note the REPL for (atom->string #\x7)
; yields "\x07" which is not a sharp char expr wrapped in quotes
; but is a string that can be turned around and evaluated
; to a string containing one character.
; multi-byte UTF-8 encoded chars
; see more tests in sharp-expr-unichar.scm
; char, unichar outside the ASCII range
(assert `(string=? (atom->string #\λ)
"λ"))
; symbol
(assert `(string=? (atom->string 'pika-message)
"pika-message"))
; symbol having multibyte char
(assert `(string=? (atom->string )
"λ"))
; string
(assert `(string=? (atom->string "foo")
"foo"))
; string having multibyte char
(assert `(string=? (atom->string "λ")
"λ"))
; byte
; Note that readstring() accepts and reduces \x.. notation.
; Test against a glyph
(assert `(string=? (atom->string (integer->byte 31))
""))
;Test for equivalence to reduced string
(assert `(string=? (atom->string (integer->byte 1))
"\x01"))
(assert `(string=? (atom->string (integer->byte 255))
"\xff"))
; integer->byte truncates a number that does not fit in 8-bits
(assert `(string=? (atom->string (integer->byte 256))
"\xff"))
; Note some TinyScheme C code uses printf ("%lu", var) where var is unsigned char,
; and that prints unsigned char in this format.
; The above tests are not a test of that code path.
; test optional base arg for numeric atom
; binary, octal, decimal, hexadecimal
(assert `(string=? (atom->string 15 2)
"1111"))
(assert `(string=? (atom->string 15 8)
"17"))
(assert `(string=? (atom->string 15 10)
"15"))
(assert `(string=? (atom->string 15 16)
"f"))
; passing <base> arg for non-numeric atom is error
(assert-error `(atom->string (integer->byte 255) 2)
"atom->string: bad base:")
; tests of abnormality i.e. error messages
; atom->string does not work for [#t, nil, closure, port, list, vector, foreign function]
; foreign function
(assert-error `(atom->string pika-message)
"atom->string: not an atom:")
; nil aka '()
(assert-error `(atom->string '() )
"atom->string: not an atom:")
; #t
(assert-error `(atom->string #t )
"atom->string: not an atom:")
; TODO port etc.

View File

@ -0,0 +1,78 @@
; Test cases for cond-expand in ScriptFu interpreter of PIKA app.
; cond-expand is SRFI-0
; https://www.gnu.org/software/mit-scheme/documentation/stable/mit-scheme-ref/cond_002dexpand-_0028SRFI-0_0029.html
; ScriptFu cond-expand is defined in the tail of script-fu.init
; This tests existing ScriptFu code, which is not a full implementation of cond-expand.
; ScriptFu omits "else" clause.
; PIKA issue #9729 proposes an enhancement that adds else clause to cond-expand, etc.
; *features* is a defined symbol that names features of language
(assert '(equal?
*features*
'(srfi-0 tinyscheme)))
; srfi-0 is not a defined symbol
(assert-error '(srfi-0)
"eval: unbound variable:")
; Note that *error-hook* erroneously omits tail of error message
; simple condition on one supported feature
(assert '(equal?
(cond-expand (tinyscheme "implements tinyscheme"))
"implements tinyscheme"))
; simple clause on one unsupported feature
; Since the condition fails there is no expansion.
; Since there is no 'else clause', there is no expansion for false condition.
; The cond-expand doc says:
; "It either expands into the body of one of its clauses or signals an error during syntactic processing."
; Yielding #t is not "signals an error" so is not correct.
; This documents what ScriptFu does, until we decide whether and how to fix it.
(assert '(equal?
(cond-expand (srfi-38 "implements srfi-38"))
#t))
; multiple clauses
(assert '(equal?
(cond-expand
(srfi-38 "implements srfi-38")
((not srfi-38) "not implements srfi-38"))
"not implements srfi-38"))
; clauses start with 'and', 'or', or 'not'
; 'not clause'
(assert '(equal?
(cond-expand ((not srfi-38) "not implements srfi-38"))
"not implements srfi-38"))
; 'and clause' having two logical conditions that are true
(assert '(equal?
(cond-expand ((and tinyscheme srfi-0) "implements both tinyscheme and srfi-0"))
"implements both tinyscheme and srfi-0"))
; 'or clause' having two logical conditions, one of which is false
(assert '(equal?
(cond-expand ((or tinyscheme srfi-38) "implements tinyscheme or srfi-38"))
"implements tinyscheme or srfi-38"))
; nested logical clauses
(assert '(equal?
(cond-expand ((or srfi-38 (and tinyscheme srfi-0)) "implements srfi-38 or tinyscheme and srfi-0"))
"implements srfi-38 or tinyscheme and srfi-0"))

View File

@ -0,0 +1,106 @@
; test integer->char function
; Is R5RS, but ScriptFu supports unicode
; Also test the inverse operation: char->integer
; TinyScheme does not implement some char functions in MIT Scheme.
; For example char->name char->digit
; TODO test char=? char-upcase
; General test strategy:
; Generate char atom using integer->char.
; Convert each such char atom to string.
; In all cases where it was possible to create such a string, test length is 1.
; See also number->string which is similar to (atom->string (integer->char <foo>) <base>)
; integer->char takes only unsigned (positive or zero) codepoints
; -1 in twos complement is out of range of UTF-8
(assert-error `(integer->char -1)
"integer->char: argument 1 must be: non-negative integer")
; ASCII NUL character.
; 0 is a valid codepoint.
; But ASCII null terminates the string early, so to speak.
; Since null byte terminates string early
; the repr in the REPL of codepoint 0 is #\
; re-test
; (integer->char 0)
; #\
(assert (= (char->integer (integer->char 0))
0))
; codepoint zero equals its sharp char hex repr
(assert (equal? (integer->char 0)
#\x0))
; Converting the atom to string yields an empty string
(assert `(string=? (atom->string (integer->char 0))
""))
; You can also represent as escaped hex "x\00"
(assert `(string=? "\x00"
""))
; Escaped hex must have more than one hex digit.
; Testing framework can't test: (assert-error `(string? "\x0") "Error reading string ")
; re-test REPL
; (null? "\x0")
; Error: Error reading string
; the first non-ASCII character (often the euro sign)
(assert (integer->char 128))
; converted string is equivalent to a string literal that displays
(assert `(string=? (atom->string (integer->char 128))
"€"))
; first Unicode character outside the 8-bit range
; evaluates without complaint
(assert (integer->char 256))
(assert (= (char->integer (integer->char 256))
256))
; length of converted string is 1
; The length is count of characters, not the count of bytes.
(assert `(= (string-length (atom->string (integer->char 256)))
1))
; converted string is equivalent to a string literal that displays
(assert `(string=? (atom->string (integer->char 256))
"Ā"))
; first Unicode character outside the Basic Multilingual Plane
(assert (integer->char 65536))
(assert (= (char->integer (integer->char 65536))
65536))
(assert `(= (string-length (atom->string (integer->char 65536)))
1))
; The usual glyph in some editors is a wide box with these digits inside:
; 010
; 000
; Other editors may display a small empty box.
(assert `(string=? (atom->string (integer->char 65536))
"𐀀"))
; re-test REPL yields a sharp char expr
; (integer->char 65536)
; #\𐀀

View File

@ -0,0 +1,55 @@
; test memory limits in TS
; TS is known to be non-robust in face of memory exhaustion.
; See Manual.txt which says "TinyScheme is known to misbehave when memory is exhausted."
; numeric constants from tinyscheme-private.h
; There is no document (only the source code itself)
; explaining the limits.
; The limits here are from experiments.
; These only test the limits.
; Methods on the objects (string, vector, etc.) are tested elsewhere.
; Symbol limits
; There is no defined limit on count of symbols.
; The objlist is a hash table, entries allocated from cells.
; The lists in the hash table are practically unlimited.
; String limits
; Strings are malloced.
; Limit on string size derives from OS malloc limits.
; No practical limit in ScriptFu.
; Seems to work
; (make-string 260000 #\A)
; Vector limits.
; A vector is contiguous cells.
; TS allocates in segments.
; A vector can be no larger than two segments?
; succeeds
(assert '(make-vector 25000))
; REPL shows as #(() () ... ()) i.e. a vector of NIL, not initialized
; might not crash?
(define testVector (make-vector 25001))
; ????
(assert `(vector-fill! ,testVector 1))
; seems to hang
; (assert '(make-vector 50001))
; seems to crash
; (assert '(make-vector 200000))

View File

@ -0,0 +1,233 @@
; Tests of sharp char expressions in ScriptFu
; This only tests:
; "sharp character" #\<c>
; "sharp character hex" #\x<hex digits>
; sharp expressions for whitespace
; See also:
; sharp-expr.scm
; sharp-expr-number.scm
; This also only tests a subset: the ASCII subset.
; See also: sharp-expr-unichar.scm
; #\<char> denotes a character constant where <char> is one character
; The one character may be multiple bytes in UTF-8,
; but should appear in the display as a single glyph,
; but may appear as a box glyph for unichar chars outside ASCII.
; #\x<x> denotes a character constant where <x> is a sequence of hex digits
; See mk_sharp_const()
; #\space #\newline #\return and #\tab also denote character constants.
; sharp backslash space "#\ " parses as a token and yields a char atom.
; See the code, there is a space here: " tfodxb\\"
; See the test below.
; #U+<x> notation for unichar character constants is not in ScriptFu
; Any sharp character followed by characters not described above
; MAY optionally be a sharp expression when a program
; uses the "sharp hook" by defining symbol *sharp-hook* .
; sharp constants for whitespace
; codepoints tab 9, newline 10, return 13, space 32 (aka whitespace)
; TinyScheme and ScriptFu prints these solitary unichars by a string representation,
; but only when they are not in a string!
; This subset of codepoints are ignored by the parser as whitespace.
; It is common for older scripts to use sharp expression constants for these codepoints.
(assert '(equal? (integer->char 9) #\tab))
(assert '(equal? (integer->char 10) #\newline))
(assert '(equal? (integer->char 13) #\return))
(assert '(equal? (integer->char 32) #\space))
; sharp constant character
; Unicode codepoints in range [33, 126]
; e.g. the letter A, ASCII 65
(assert '(equal? (integer->char 65) #\A))
(assert '(char? #\A))
(assert '(atom? #\A))
; Tests of functions using a non-printing, control character ASCII
; Codepoint BEL \x7
(assert '(equal? (integer->char 7) #\))
(assert '(char? #\))
(assert '(atom? #\))
; string function takes sequence of chars
(assert (equal? (string #\) ""))
; Unicode codepoints [0-8][11-12][14-31]
; (less than 32 excepting tab 9, newline 10, return 13)
; The "non-printing" characters
; e.g. 7, the character that in ancient times rang a bell sound
; Upstream TinyScheme prints these differently from ScriptFu, as a string repr of the char.
; since TinyScheme default compiles with option "USE_ASCII_NAMES"
;>(integer->char 7)
;#\bel
;>(integer->char 127)
;#\del
; ScriptFu prints solitary Unichars
; for codepoints below 32 and also 127 differently than upstream TinyScheme.
; Except ScriptFu is same as TinyScheme for tab, space, newline, return codepoints.
; ScriptFu shows a glyph that is a box with a hex number.
; Formerly (before the fixes for this test plan) Scriptfu printed these like TinyScheme,
; by a sharp constant hex e.g. #\x1f for 31
; Edge codepoint tests
; Tests of edge cases, near a code slightly different
; Codepoint US Unit Separator, edge case to 32, space
(assert '(equal? (integer->char 31) #\))
(assert '(equal? #\ #\x1f))
; codepoint 127 x7f (DEL), edge case to 128
(assert '(equal? (integer->char 127) #\x7f))
; sharp constant hex character
; Sharp char expr hex denotes char atom
; But not the REPL printed representation of characters.
; is-a char
(assert '(char? #\x65))
; equals a sharp character: lower case e
(assert '(equal? #\x65 #\e))
; sharp char hex notation accepts a single hex digit
(assert '(char? #\x3))
; sharp char hex notation accepts two hex digits
(assert '(char? #\x33))
; edge case, max hex that fits in 8-bits
(assert '(char? #\xff))
; sharp car expr hex accepts three digits
; when they are leading zeroes
(assert '(char? #\x033))
; Otherwise, three digits not leading zeros
; are unicode.
; codepoint x3bb is a valid character (greek lambda)
; but is outside ASCII range.
; See sharp-expr-unichar.scm
; sharp constant hex character: invalid unichar
; Unicode has a range, but sparsely populated with valid codes.
; Unicode is unsigned, range is [0,x10FFF]
; Greatest valid codepoint is x10FFFF (to match UTF-16)
; Sparsely populated: some codepoints in range are not valid
; because they are incorrectly encoded using UTF-8 algorithm.
; (This is a paraphrase: please consult the standard.)
; These tests are not a complete test of UTF-8 compliance !!!
; Edge case: max valid codepoint
(assert (equal? #\x10FFFF #\􏿿))
; Edge case: zero is considered a valid codepoint
; !!! Although also a string terminator.
(assert '(equal?
(integer->char 0)
#\x0))
; sharp constants for delimiter characters
; These test the sharp constant notation for characters space and parens
; These are in the ASCII range
; !!! A space char in a sharp constant expr
(assert (char? #\ ))
; Whose representation is a space character.
(assert (string=? (atom->string #\ )
" "))
; !!! A right paren char in a sharp constant expr
; Note that backslash captures the first right paren:
; the parens do not appear to match.
(assert (char? #\)))
; Ditto for left paren
(assert (char? #\())
; !!! But easy for author to confuse the parser
; assert-error can't catch syntax errors.
; So can only test in the REPL.
; > (char? #\)
; Error: syntax error: expected right paren, found EOF"
; #\# is the sharp or pound sign char
(assert (char? #\#))
(assert (string=? (atom->string #\# )
"#"))
; #\x is lower case x
(assert (char? #\x))
(assert (string=? (atom->string #\x )
"x"))
; see also integer2char.scm
; Common misunderstandings or typos
; #\t is a character, lower case t
; It is not the denotation for truth.
(assert `(not (equal? #\t #t)))
; It is not the denotation for #\tab.
(assert `(not (equal? #\t #\tab)))
; It is a char
(assert `(char? #\t))
; Its string representation is lower case t character
(assert `(string=? (atom->string #\t)
"t"))
; a number converted to string that is representation in base 16
; !!! This is not creating a Unichar.
; It is printing the hex representation of decimal 955, without a leading "\x"
(assert `(string=? (number->string 955 16)
"3bb"))
; Untestable sharp constant hex character
; Test framework can't test, these cases are syntax errors.
; These cases yield "syntax: illegal sharp constant expression" in REPL
; sharp constant hex having non-hex digit is an error
; z is not in [a-f0-9]
; > #\xz
; Error: syntax: illegal sharp constant expression
; Also prints warning "Hex literal has invalid digits" in stderr

View File

@ -0,0 +1,162 @@
; Test cases for sharp char expr for unicode chars outside ASCII range
; See sharp-expr-char.scm for sharp char expr inside ASCII range.
; See unichar.scm for tests of unichar without using sharp char expr
; This file also documents cases that the testing framework can't test
; since they are syntax errors
; or otherwise throw error in way that testing framework can't catch.
; Such cases are documented with pairs of comments in re-test format:
; First line starting with "; (" and next line "; <expected REPL display>"
; This is NOT a test of the REPL: ScriptFu Console.
; A REPL displays using obj2str,
; or internal atom2str() which this doesn't test.
; ScriptFu Console (the REPL) displays a "sharp char expression" to represent
; all atoms which are characters, e.g. #\a .
; A "sharp hex char expression" also
; represents a character, e.g. #\x32.
; But the REPL does not display that representation.
; conversion from number to character equal sharp char expr unicode
(assert `(equal? (integer->char 955) #\λ))
; char=? also works
(assert `(char=? (integer->char 955) #\λ))
; a sharp char expr unicode is-a char
(assert (char? #\λ))
; sharp char hex expr is same as sharp char expr
(assert (equal? #\x3bb #\λ))
; sharp char hex expr is-a char
(assert '(char? #\x3bb))
; Unichar extracted from string equals sharp char expr unicode
(assert (equal? (string-ref "λ" 0) #\λ))
; Edge cases for sharp char expressions: hex: Unicode
; see also integer2char.scm
; where same cases are tested
; extended ASCII 128-255
; 128 the euro sign
(assert #\x80)
; 255
(assert #\xff)
; 159 \xao is non-breaking space, not visible in most editors
; 256, does not fit in one byte
(assert #\x100)
; outside the Basic Multilingual Plane
; won't fit in two bytes
; Least outside: 65536
(assert #\x10000)
; max valid codepoint #\x10ffff
(assert #\x10ffff)
; Any 32-bit value greater than x10ffff yields a syntax error:
; syntax: illegal sharp constant expression
; and not testable in testing framework
; extra tests of sharp char expr in other constructed expressions
; sharp char expr unicode passed to string function
(assert (string=? (string #\λ) "λ"))
; sharp char expr unicode in a list
(assert (equal? (list (string-ref "λ" 0)) '(#\λ)))
; sharp char expr unicode in vector
(assert (equal? (vector (string-ref "λ" 0)) '#(#\λ)))
; atom->string
(assert `(string=? (atom->string #\λ)
"λ"))
; Quoted unichar
; quoted unichar is not type char
(assert `(not (char? )))
; quoted unichar is type symbol
(assert `(symbol? ))
; unichar tested in REPL
; What follows are tests that can't be tested by the "testing" framework
; but can be tested by the "re-test" framework
; Testing framework can't test side effects on display.
; re-test display unichar
; (display (string-ref "λ" 0))
; λ#t
; re-test
; (begin (display "Unicode lambda char: ") (string-ref "λ" 0))
; Unicode lambda char: #\λ
; Unicode character can be passed to error function and displayed
; Seems to be flaw in testing framework,
; this can't be tested:
;(assert-error `(error "Error λ")
; "Error: Error λ")
; re-test
; (error "Error λ")
; Error: Error: λ
; syntax errors in sharp char hex expr
; Syntax errors are not testable in testing framework.
; exceeding max range of int 32 codepoint
; longer than 8 hex digits \xf87654321
; > (assert '#\xf87654321
; re-test
; (null? #\xf87654321 )
; syntax: illegal sharp constant expression
; Also prints warning "Hex literal larger than 32-bit" to stderr
; A codepoint that fits in 32 bits but invalid UTF-8 encoding
; re-test
; (null? '#\xd800)
; syntax: illegal sharp constant expression
; Also prints warning "Failed make character from invalid codepoint." to stderr
; Edge error case: first invalid codepoint greater than max valid
; re-test
; (null? '#\x110000)
; syntax: illegal sharp constant expression
; Also prints warning "Failed make character from invalid codepoint." to stderr

View File

@ -0,0 +1,85 @@
; Tests of sharp expressions in ScriptFu
; This only tests:
; miscellaneous sharp expressions
; See also:
; sharp-expr-char.scm
; sharp-expr-number.scm
; Some "sharp expressions" e.g. #t and #f might not be explicitly tested,
; but tested "driveby" by other tests.
; Terminology:
; The code says "sharp constant expression".
; A "sharp expression" is text in the language that denotes a "sharp constant."
; A constant is an atom of various types: char, byte, number.
; The expression is distinct from the thing it denotes.
; A "sharp expression" is *recognized* by the interpreter.
; But also *printed* by the interpreter REPL.
; Mostly these are tests of recognition.
; The testing framework cannot test the REPL.
; See scheme.c, the token() function, about line 2000
; and the mk_sharp_constant() function, for sharp character constant
; #( token denotes start of a vector
; #! token denotes start of a comment terminated by newline
; aka shebang or hashbang, a notation that OS shells read
; #t denotes true
; #f denotes false
; #odxb<x> denotes a numeric constant in octal, decimal, hex, binary base
; where <x> are digits of that base
; #\<char> denotes a character constant where <char> is one character
; The one character may be multiple bytes in UTF-8,
; but should appear in the display as a single glyph,
; but may appear as a box glyph for unichar chars outside ASCII.
; #\x<x> denotes a character constant where <x> is a sequence of hex digits
; See mk_sharp_const()
; #\space #\newline #\return and #\tab also denote character constants.
; Note: sharp backslash followed by space/blank parses as a token,
; #U+<x> notation for unichar character constants is not in ScriptFu
; Any sharp character followed by characters not described above
; MAY optionally be a sharp expression when a program
; uses the "sharp hook" by defining symbol *sharp-hook* .
; block quote parses
; Seems only testable in REPL?
; Note there is a newline after foo
;(assert '#! foo
; )
; but is not testable by the framework
; #t denotes truth
(assert #t)
; #t denotes an atom
(assert (atom? #t))
; #t is type boolean
(assert (boolean? #t))
; #t is neither type number or symbol
(assert (not (number? #t)))
(assert (not (symbol? #t)))
; #t denotes constant, and constant means immutable
; You cannot redefine #t
(assert-error `(define #t 1)
"variable is not a symbol")
; You cannot set #t
(assert-error `(set! #t 1)
"set!: unbound variable:")
; error-hook omits suffix: #t
; There is no predicate immutable? in Scheme language?

View File

@ -0,0 +1,56 @@
; Test cases for string ports
; a string port is-a port (having read and write methods).
; a string port stores its contents in memory (unlike device ports).
; A read returns contents previously written.
; A string port is practically infinite.
; a string port is like a string
; a sequence of writes are like a sequence of appends to a string
; Note that each assert is in its own environment,
; so we can't define a global port outside????
; Why shouldn't this work?
; (define aStringPort (open-output-string))
; (assert `(port? aStringPort))
; open-output-string yields a port
(assert '(port? (open-output-string)))
; string read from port equals string written to port
; !!! with escaped double quote
(assert '(string=?
(let* ((aStringPort (open-output-string)))
(write "foo" aStringPort)
(get-output-string aStringPort))
"\"foo\""))
; string read from port equals string repr of symbol written to port
; !!! without escaped double quote
(assert '(string=?
(let* ((aStringPort (open-output-string)))
; !!! 'foo is-a symbol whose repr is three characters: foo
; write to a port writes the repr
(write 'foo aStringPort)
(get-output-string aStringPort))
(symbol->string 'foo)))
; What is read equals the string written.
; For edge case: writing more than 256 characters in two tranches
; where second write crosses end boundary of 256 char buffer.
; issue #9495
; Failing
;(assert '(string=?
; (let* ((aStringPort (open-output-string)))
; (write (string->symbol (make-string 250 #\A)) aStringPort)
; (write (string->symbol (make-string 7 #\B)) aStringPort)
; (get-output-string aStringPort))
; (string-append
; (make-string 250 #\A)
; (make-string 7 #\B))))

View File

@ -0,0 +1,52 @@
; test the testing framework
; assert stmt
; a result that is #t passes
(assert #t)
; other truthy results pass
(assert 1)
; 0 is truthy and passes
(assert 0)
; If you really want to assert that exactly #t is the result,
; you should eval a topmost predicate that yields only #t or #f
; For example, where eq? is equality of pointers:
(assert '(not (eq? 0 #t)))
; a symbol defined outside an assert is visible
; when you backquote and unquote it.
(define aTrue #t)
(assert `,aTrue)
; Here
; backquote passes the following expression as data without evaluating it
; singlequote makes a list literal instead of a function call
; unquote i.e. comma evaluates the following symbol before backquote passes expression as data
(assert `(car '(,aTrue)))
; assert-error statment
; assert-error tests for error messages
; assert-error omits the "Error: " prefix printed by the REPL
; case: Error1 called with pointer to errant atom
; symbol aFalse is not bound
(assert-error 'aFalse
"eval: unbound variable:")
; assert-error currently omits the suffix <repr of errant code>
; printed by the usual error mechanism.
; (Since I think error hook mechanism is broken.)
; case: Error0 called with null pointer
; numeric literal 1 is not a function
(assert-error '(1)
"illegal function")

View File

@ -0,0 +1,36 @@
; Complete test of TinyScheme
; This does NOT KNOW the directory organization of the test files in repo.
; When you add a test file, also add it to meson.build,
; which DOES KNOW the dirs of the repo, but flattens into /test.
; Name clash must be avoided on the leaf filenames.
; test the testing framework itself
(testing:load-test "testing.scm")
(testing:load-test "cond-expand.scm")
(testing:load-test "atom2string.scm")
(testing:load-test "integer2char.scm")
(testing:load-test "string-port.scm")
(testing:load-test "sharp-expr.scm")
(testing:load-test "sharp-expr-char.scm")
(testing:load-test "sharp-expr-unichar.scm")
; test unichar without using sharp char expr
(testing:load-test "unichar.scm")
(testing:load-test "vector.scm")
(testing:load-test "no-memory.scm")
; report the result
(testing:report)
; yield the session result
(testing:all-passed?)

View File

@ -0,0 +1,58 @@
; Test cases for unicode chars outside ASCII range
; !!! These tests don't use sharp char expr, but the chars themselves.
; See sharp-expr-unichar.scm for sharp char expr denoting unichars
; outside ASCII range.
; History: we avoid sharp char expr for unicode here
; because of bug #9660.
; Loosely speaking, ScriptFu was handling unichars,
; but not sharp char expr for them.
; Most test cases are for atoms that are type "char",
; meaning a component of a string.
; ScriptFu implementation uses a C type: gunichar,
; which holds a UTF-8 encoding of any Unicode code point.)
; A unichar is as many as four bytes, not always one byte.
; This is NOT a test of the REPL: ScriptFu Console.
; A REPL displays using obj2str,
; or internal atom2str() which this doesn't test.
; ScriptFu Console (the REPL) displays a "sharp char expression" to represent
; all atoms of type char, e.g. #\a .
; A "sharp hex char expression" also
; represents a character, e.g. #\x32.
; But the REPL does not display that representation.
; conversion from number to character equal sharp char
(assert `(equal? (integer->char 955)
(string-ref "λ" 0)))
; Unichar itself (a wide character) can be in the script
; but is unbound
(assert-error `(eval λ) "eval: unbound variable:")
; Note the error message is currently omitting the errant symbol
; Unichar in a string
(assert (string=? (string (string-ref "λ" 0)) "λ"))
; Omitted: a test of REPL
; display unichar
; > (display (string-ref "λ" 0))
; λ#t
; Quoted unichar
; These test that the script can contain unichars
; versus test that a script can process unichars.
; quoted unichar is not type char
(assert `(not (char? )))
; quoted unichar is type symbol
(assert (symbol? ))

View File

@ -0,0 +1,85 @@
; test vector methods of TS
; make-vector
; make-vector succeeds
(assert '(make-vector 25))
; Note vector is anonymous and will be garbage collected
; make-vector of size 0 succeeds
(assert '(make-vector 0))
(define testVector (make-vector 25))
; make-vector yields a vector
(assert `(vector? ,testVector))
; make-vector yields a vector of given length
(assert `(= (vector-length ,testVector)
25))
; make-vector initializes each element to empty list
(assert `(equal?
(vector-ref ,testVector 0)
'()))
; other vector construction methods
(assert '(equal?
(vector 'a 'b 'c)
#(a b c)))
(assert '(equal?
(list->vector '(dididit dah))
#(dididit dah)))
; fill
; fill succeeds
(assert `(vector-fill! ,testVector 99))
; fill effective
(assert `(=
(vector-ref ,testVector 0)
99))
; referencing out of bounds
; past end fails
(assert-error `(vector-ref ,testVector 25)
"vector-ref: out of bounds:")
; error msg omits repr of atom
; negative index fails
(assert-error `(vector-ref ,testVector -1)
"vector-ref: argument 2 must be: non-negative integer")
; undefined vector ops in TS
; make-initialized-vector
(assert-error '(equal?
(make-initialized-vector 5 (lambda (x) (* x x)))
#(0 1 4 9 16))
"eval: unbound variable:")
; error msg omits prefix "Error: " and suffix "make-initialized-vector"
; vector-copy
; equals the original
(assert-error
`(equal?
(vector-copy ,testVector)
,testVector)
"eval: unbound variable:")