85 lines
2.4 KiB
Swift
85 lines
2.4 KiB
Swift
import XCTest
|
|
@testable import KiteCore
|
|
|
|
final class MacroTests: XCTestCase {
|
|
private func evalShow(_ src: String) throws -> String {
|
|
displayString(try Interpreter().evalString(src))
|
|
}
|
|
|
|
func testWhenUnlessFromPrelude() throws {
|
|
XCTAssertEqual(try evalShow("(when (> 5 3) 'yes)"), "yes")
|
|
XCTAssertEqual(try evalShow("(when (< 5 3) 'yes)"), "#f")
|
|
XCTAssertEqual(try evalShow("(unless (< 5 3) 'ok)"), "ok")
|
|
}
|
|
|
|
func testUserSwapMacro() throws {
|
|
let program = """
|
|
(define-syntax swap!
|
|
(syntax-rules ()
|
|
((_ a b) (let ((tmp a)) (set! a b) (set! b tmp)))))
|
|
(define x 1)
|
|
(define y 2)
|
|
(swap! x y)
|
|
(list x y)
|
|
"""
|
|
XCTAssertEqual(try evalShow(program), "(2 1)")
|
|
}
|
|
|
|
func testSwapMacroHygiene() throws {
|
|
let program = """
|
|
(define-syntax swap!
|
|
(syntax-rules ()
|
|
((_ a b) (let ((tmp a)) (set! a b) (set! b tmp)))))
|
|
(define tmp 10)
|
|
(define other 20)
|
|
(swap! tmp other)
|
|
(list tmp other)
|
|
"""
|
|
XCTAssertEqual(try evalShow(program), "(20 10)")
|
|
}
|
|
|
|
func testEllipsisMacro() throws {
|
|
let program = """
|
|
(define-syntax my-list
|
|
(syntax-rules ()
|
|
((_ e ...) (list e ...))))
|
|
(my-list 1 2 3 4 5)
|
|
"""
|
|
XCTAssertEqual(try evalShow(program), "(1 2 3 4 5)")
|
|
}
|
|
|
|
func testRecursiveMacro() throws {
|
|
let program = """
|
|
(define-syntax my-or
|
|
(syntax-rules ()
|
|
((_) #f)
|
|
((_ e) e)
|
|
((_ e rest ...) (let ((t e)) (if t t (my-or rest ...))))))
|
|
(list (my-or #f #f 7) (my-or) (my-or 3))
|
|
"""
|
|
XCTAssertEqual(try evalShow(program), "(7 #f 3)")
|
|
}
|
|
|
|
func testMacroWithLiterals() throws {
|
|
let program = """
|
|
(define-syntax classify
|
|
(syntax-rules (zero)
|
|
((_ zero) 'was-zero)
|
|
((_ x) 'was-other)))
|
|
(list (classify zero) (classify 5))
|
|
"""
|
|
XCTAssertEqual(try evalShow(program), "(was-zero was-other)")
|
|
}
|
|
|
|
func testNestedEllipsisTemplate() throws {
|
|
let program = """
|
|
(define-syntax my-let
|
|
(syntax-rules ()
|
|
((_ ((name val) ...) body ...)
|
|
((lambda (name ...) body ...) val ...))))
|
|
(my-let ((a 1) (b 2) (c 3)) (+ a b c))
|
|
"""
|
|
XCTAssertEqual(try evalShow(program), "6")
|
|
}
|
|
}
|