1 //******************************************************************************
2 // MAL - types, implemented as a Swift "enum".
3 //******************************************************************************
7 // ===== Types / Constants / Variables =====
9 typealias MalProtocol = protocol<Equatable, CustomStringConvertible, Hashable>
11 typealias MalIntType = Int64
12 typealias MalFloatType = Double
13 typealias MalSymbolType = String
14 typealias MalKeywordType = String
15 typealias MalStringType = String
16 typealias MalVectorType = ArraySlice<MalVal>
17 typealias MalHashType = Dictionary<MalVal, MalVal>
19 typealias MalInteger = MalIntType
20 typealias MalFloat = MalFloatType
21 typealias MalSymbol = MalSymbolType
22 typealias MalKeyword = MalKeywordType
23 typealias MalString = MalStringType
25 private let kUnknown = MalVal.TypeUnknown
26 private let kNil = MalVal.TypeNil
27 private let kTrue = MalVal.TypeTrue
28 private let kFalse = MalVal.TypeFalse
29 private let kComment = MalVal.TypeComment
31 // ==================== MalSequence ====================
33 class MalSequence : MalProtocol, SequenceType {
38 init(_ seq: MalSequence) {
39 self.count = seq.count
40 self.isEmpty = seq.isEmpty
42 init(_ count: MalIntType) {
44 self.isEmpty = self.count == 0
47 // CustomStringConvertible
49 var description: String { die() }
53 var hashValue: Int { die() }
57 func generate() -> MalVectorType.Generator { die() }
64 func first() -> MalVal { die() }
65 func last() -> MalVal { die() }
66 func rest() -> MalVal { die() }
67 func nth(n: MalIntType) throws -> MalVal { die() }
68 func range_from(from: MalIntType, to: MalIntType) -> MalVal { die() }
69 func cons(element: MalVal) -> MalVal { die() }
70 func concat(seq: MalSequence) throws -> MalVal { die() }
71 func conj(seq: MalSequence) throws -> MalVal { die() }
72 func map<U>(@noescape transform: (MalVal) -> U) -> ArraySlice<U> { die() }
73 func reduce<U>(initial: U, @noescape combine: (U, MalVal) -> U) -> U { die() }
78 func ==(left: MalSequence, right: MalSequence) -> Bool {
79 if left.count != right.count { return false }
80 var left_gen = left.generate()
81 var right_gen = right.generate()
83 if let left = left_gen.next(), right = right_gen.next() {
94 // ==================== MalList ====================
96 final class MalList : MalSequence {
97 override convenience init() {
98 self.init(MalVectorType())
100 init(_ other: MalList, _ meta: MalVal?) {
101 self._slice = other._slice
105 override convenience init(_ seq: MalSequence) {
106 if let list = seq as? MalList { self.init(list._slice) }
108 if let vector = seq as? MalVector { self.init(vector._slice) }
110 { self.init(seq.reduce(MalVectorType()){ var s = $0; s.append($1); return s }) }
112 init(_ slice: MalVectorType) {
115 super.init(MalIntType(self._slice.count))
117 convenience init(_ array: Array<MalVal>) {
118 self.init(array[0..<array.count])
120 convenience init<T: SequenceType where T.Generator.Element == MalVal>(_ collection: T) {
121 self.init(collection.reduce(MalVectorType()){ var s = $0; s.append($1); return s })
124 // CustomStringConvertible
126 override var description: String { return "(" + self.map { pr_str($0) }.joinWithSeparator(" ") + ")" }
130 override var hashValue: Int { return description.hashValue }
134 override func generate() -> MalVectorType.Generator { return self._slice.generate() }
138 override func first() -> MalVal { return isEmpty ? make_nil() : try! nth(0) }
139 override func last() -> MalVal { return try! nth(count - 1) }
140 override func rest() -> MalVal { return range_from(MalIntType(1), to: MalIntType(count)) }
141 override func nth(n: MalIntType) throws -> MalVal { guard n < count else { try throw_error("index (\(n)) out of range (\(count))") }; return self._slice[self._slice.startIndex.advancedBy(Int(n))] }
142 override func range_from(from: MalIntType, to: MalIntType) -> MalVal {
143 return from <= to && to <= count
144 ? make_list(self._slice[self._slice.startIndex.advancedBy(Int(from))..<self._slice.startIndex.advancedBy(Int(to))])
147 override func cons(element: MalVal) -> MalVal {
148 var result = self._slice
149 result.insert(element, atIndex: result.startIndex)
150 return make_list(result)
152 override func concat(seq: MalSequence) throws -> MalVal {
153 var result = self._slice
154 if let list = as_listQ(seq) {
155 result.appendContentsOf(list._slice)
156 } else if let vector = as_vectorQ(seq) {
157 result.appendContentsOf(vector._slice)
159 try throw_error("Expected sequence, got \(seq)")
161 return make_list(result)
163 override func conj(seq: MalSequence) throws -> MalVal {
164 var result: Array<MalVal>
165 if let list = as_listQ(seq) {
166 result = list._slice.reverse()
167 } else if let vector = as_vectorQ(seq) {
168 result = vector._slice.reverse()
170 try throw_error("Expected sequence, got \(seq)")
172 result.appendContentsOf(self._slice)
173 return make_list(result)
175 override func map<U>(@noescape transform: (MalVal) -> U) -> ArraySlice<U> { return ArraySlice<U>(self._slice.map(transform)) }
176 override func reduce<U>(initial: U, @noescape combine: (U, MalVal) -> U) -> U { return self._slice.reduce(initial, combine: combine) }
180 var meta: MalVal? { return self._meta }
182 private let _slice: MalVectorType
183 private let _meta: MalVal?
188 func ==(left: MalList, right: MalList) -> Bool {
189 return (left as MalSequence) == (right as MalSequence)
192 // ==================== MalVector ====================
194 final class MalVector : MalSequence {
195 override convenience init() {
196 self.init(MalVectorType())
198 init(_ other: MalVector, _ meta: MalVal?) {
199 self._slice = other._slice
203 override convenience init(_ seq: MalSequence) {
204 if let list = seq as? MalList { self.init(list._slice) }
206 if let vector = seq as? MalVector { self.init(vector._slice) }
208 { self.init(seq.reduce(MalVectorType()){ var s = $0; s.append($1); return s }) }
210 init(_ slice: MalVectorType) {
213 super.init(MalIntType(self._slice.count))
215 convenience init(_ array: Array<MalVal>) {
216 self.init(array[0..<array.count])
218 convenience init<T: SequenceType where T.Generator.Element == MalVal>(_ collection: T) {
219 self.init(collection.reduce(MalVectorType()){ var s = $0; s.append($1); return s })
222 // CustomStringConvertible
224 override var description: String { return "[" + self.map { pr_str($0) }.joinWithSeparator(" ") + "]" }
228 override var hashValue: Int { return description.hashValue }
232 override func generate() -> MalVectorType.Generator { return self._slice.generate() }
236 override func first() -> MalVal { return isEmpty ? make_nil() : try! nth(0) }
237 override func last() -> MalVal { return try! nth(count - 1) }
238 override func rest() -> MalVal { return range_from(MalIntType(1), to: MalIntType(count)) }
239 override func nth(n: MalIntType) throws -> MalVal { guard n < count else { try throw_error("index (\(n)) out of range (\(count))") }; return self._slice[self._slice.startIndex.advancedBy(Int(n))] }
240 override func range_from(from: MalIntType, to: MalIntType) -> MalVal {
241 return from <= to && to <= count
242 ? make_list(self._slice[self._slice.startIndex.advancedBy(Int(from))..<self._slice.startIndex.advancedBy(Int(to))]) // Yes, make_list
243 : make_list() // Yes, make_list
245 override func cons(element: MalVal) -> MalVal {
246 var result = self._slice
247 result.insert(element, atIndex: result.startIndex)
248 return make_list(result) // Yes, make_list
250 override func concat(seq: MalSequence) throws -> MalVal {
251 var result = self._slice
252 if let list = as_listQ(seq) {
253 result.appendContentsOf(list._slice)
254 } else if let vector = as_vectorQ(seq) {
255 result.appendContentsOf(vector._slice)
257 try throw_error("Expected sequence, got \(seq)")
259 return make_vector(result)
261 override func conj(seq: MalSequence) throws -> MalVal {
262 var result = self._slice
263 if let list = as_listQ(seq) {
264 result.appendContentsOf(list._slice)
265 } else if let vector = as_vectorQ(seq) {
266 result.appendContentsOf(vector._slice)
268 try throw_error("Expected sequence, got \(seq)")
270 return make_vector(result)
272 override func map<U>(@noescape transform: (MalVal) -> U) -> ArraySlice<U> { return ArraySlice<U>(self._slice.map(transform)) }
273 override func reduce<U>(initial: U, @noescape combine: (U, MalVal) -> U) -> U { return self._slice.reduce(initial, combine: combine) }
277 var meta: MalVal? { return self._meta }
279 private let _slice: MalVectorType
280 private let _meta: MalVal?
285 func ==(left: MalVector, right: MalVector) -> Bool {
286 return (left as MalSequence) == (right as MalSequence)
289 // ==================== MalHashMap ====================
291 final class MalHashMap : MalProtocol, SequenceType {
293 self.init(MalHashType())
295 init(_ other: MalHashMap, _ meta: MalVal?) {
296 self._hash = other._hash
298 self.count = MalIntType(self._hash.count)
299 self.isEmpty = self._hash.isEmpty
301 init(_ hash: MalHashType) {
304 self.count = MalIntType(self._hash.count)
305 self.isEmpty = self._hash.isEmpty
307 convenience init(_ seq: MalSequence) {
308 var hash = MalHashType()
309 for var index: MalIntType = 0; index < seq.count; index += 2 {
310 hash[try! seq.nth(index)] = try! seq.nth(index + 1)
314 convenience init<T: CollectionType where T.Generator.Element == MalVal>(_ collection: T) {
315 var hash = MalHashType()
316 for var index = collection.startIndex; index != collection.endIndex; {
317 let key = collection[index++]
318 let value = collection[index++]
324 // CustomStringConvertible
326 var description: String {
328 for (k, v) in self._hash {
329 a.append("\(pr_str(k)) \(pr_str(v))")
331 let s = a.joinWithSeparator(" ")
337 var hashValue: Int { return description.hashValue }
341 func generate() -> MalHashType.Generator { return self._hash.generate() }
345 let count: MalIntType
347 var hash: MalHashType { return self._hash }
348 var keys: MalVal { return make_list(self._hash.keys) }
349 var values: MalVal { return make_list(self._hash.values) }
350 var meta: MalVal? { return self._meta }
352 func value_for(key: MalVal) -> MalVal? {
353 return self._hash[key]
356 private let _hash: MalHashType
357 private let _meta: MalVal?
362 func ==(left: MalHashMap, right: MalHashMap) -> Bool {
363 if left.count != right.count { return false }
364 var left_gen = left.generate()
365 var right_gen = right.generate()
367 if let left = left_gen.next(), right = right_gen.next() {
368 if left.0 != right.0 || left.1 != right.1 {
378 // ==================== MalAtom ====================
380 final class MalAtom : MalProtocol {
382 self.init(make_nil())
384 init(_ other: MalAtom, _ meta: MalVal?) {
385 self._object = other._object
388 init(_ object: MalVal) {
389 self._object = object
393 // CustomStringConvertible
395 var description: String { return "(atom \(pr_str(self._object)))" }
399 var hashValue: Int { return description.hashValue }
403 var object: MalVal { return self._object }
404 var meta: MalVal? { return self._meta }
406 func set_object(obj: MalVal) -> MalVal {
411 private var _object: MalVal
412 private let _meta: MalVal?
417 func ==(left: MalAtom, right: MalAtom) -> Bool { return left.object == right.object }
419 // ==================== MalFunction ====================
421 class MalFunction : MalProtocol {
424 init(_ other: MalFunction) {
427 // CustomStringConvertible
429 var description: String { die() }
433 var hashValue: Int { die() }
437 func apply(exprs: MalSequence) throws -> MalVal { die() }
442 func ==(left: MalFunction, right: MalFunction) -> Bool { return false }
444 // ==================== MalClosure ====================
447 final class MalClosure : MalFunction {
448 typealias Evaluator = (MalVal, Environment) throws -> MalVal
449 typealias Parameters = (eval: Evaluator, args: MalSequence, body: MalVal, env: Environment)
451 override convenience init() {
453 eval: {(a: MalVal, b: Environment) -> MalVal in make_nil() },
454 args: as_sequence(make_list()),
456 env: Environment(outer: nil)
459 init(_ other: MalClosure, _ meta: MalVal?) {
460 self._eval = other._eval
461 self._args = other._args
462 self._body = other._body
463 self._env = other._env
467 init(_ p: Parameters) {
476 // CustomStringConvertible
478 override var description: String { return "#<Closure>: (fn* \(self._args.description) \(self._body.description))" }
482 override var hashValue: Int { return description.hashValue }
486 override func apply(exprs: MalSequence) throws -> MalVal {
487 let new_env = Environment(outer: self._env)
488 let _ = try new_env.set_bindings(self._args, with_exprs: exprs)
489 // Calling EVAL indirectly via an 'eval' data member is a bit of a hack.
490 // We can't call EVAL directly because this file (types.swift) needs to
491 // be used with many different versions of the main MAL file
492 // (step[0-10]*.swift), and EVAL is declared differently across those
493 // versions. By using this indirection, we avoid that problem.
494 return try self._eval(self._body, new_env)
497 var args: MalSequence { return self._args }
498 var body: MalVal { return self._body }
499 var env: Environment { return self._env }
500 var meta: MalVal? { return self._meta }
502 private let _eval: Evaluator!
503 private let _args: MalSequence
504 private let _body: MalVal
505 private let _env: Environment
506 private let _meta: MalVal?
511 func ==(left: MalClosure, right: MalClosure) -> Bool { return false }
513 // ==================== MalBuiltin ====================
515 final class MalBuiltin : MalFunction {
516 typealias Signature = (MalSequence) throws -> MalVal
518 override convenience init() {
519 self.init( {(MalSequence) -> MalVal in make_nil()} )
521 init(_ other: MalBuiltin, _ meta: MalVal?) {
526 init(_ fn: Signature) {
532 // CustomStringConvertible
534 override var description: String { return "#<Builtin>" }
538 override var hashValue: Int { return description.hashValue }
542 override func apply(exprs: MalSequence) throws -> MalVal { return try self._fn(exprs) }
543 var meta: MalVal? { return self._meta }
545 private let _fn: Signature!
546 private let _meta: MalVal?
551 func ==(left: MalBuiltin, right: MalBuiltin) -> Bool { return false } // Can't compare function references in Swift
553 // ==================== MalMacro ====================
555 final class MalMacro : MalProtocol {
557 self.init(as_closure(make_closure()))
559 init(_ other: MalMacro, _ meta: MalVal?) {
560 self._closure = other._closure
563 init(_ closure: MalClosure) {
564 self._closure = closure
568 // CustomStringConvertible
570 var description: String { return self._closure.description }
574 var hashValue: Int { return description.hashValue }
576 var args: MalSequence { return self._closure.args }
577 var body: MalVal { return self._closure.body }
578 var env: Environment { return self._closure.env }
579 var meta: MalVal? { return self._meta }
581 private let _closure: MalClosure
582 private let _meta: MalVal?
587 func ==(left: MalMacro, right: MalMacro) -> Bool { return false }
589 // ==================== MalVal ====================
591 enum MalVal : MalProtocol {
597 case TypeInteger (MalInteger)
598 case TypeFloat (MalFloat)
599 case TypeSymbol (MalSymbol)
600 case TypeKeyword (MalKeyword)
601 case TypeString (MalString)
602 case TypeList (MalList)
603 case TypeVector (MalVector)
604 case TypeHashMap (MalHashMap)
605 case TypeAtom (MalAtom)
606 case TypeClosure (MalClosure)
607 case TypeBuiltin (MalBuiltin)
608 case TypeMacro (MalMacro)
610 // CustomStringConvertible
612 var description: String {
614 case .TypeUnknown: return "unknown"
615 case .TypeNil: return "nil"
616 case .TypeTrue: return "true"
617 case .TypeFalse: return "false"
618 case .TypeComment: return "comment"
619 case .TypeInteger (let v): return v.description
620 case .TypeFloat (let v): return v.description
621 case .TypeSymbol (let v): return v
622 case .TypeKeyword (let v): return v
623 case .TypeString (let v): return v
624 case .TypeList (let v): return v.description
625 case .TypeVector (let v): return v.description
626 case .TypeHashMap (let v): return v.description
627 case .TypeAtom (let v): return v.description
628 case .TypeClosure (let v): return v.description
629 case .TypeBuiltin (let v): return v.description
630 case .TypeMacro (let v): return v.description
638 case .TypeUnknown: return 0
639 case .TypeNil: return 0
640 case .TypeTrue: return 0
641 case .TypeFalse: return 0
642 case .TypeComment: return 0
643 case .TypeInteger (let v): return v.hashValue
644 case .TypeFloat (let v): return v.hashValue
645 case .TypeSymbol (let v): return v.hashValue
646 case .TypeKeyword (let v): return v.hashValue
647 case .TypeString (let v): return v.hashValue
648 case .TypeList (let v): return v.hashValue
649 case .TypeVector (let v): return v.hashValue
650 case .TypeHashMap (let v): return v.hashValue
651 case .TypeAtom (let v): return v.hashValue
652 case .TypeClosure (let v): return v.hashValue
653 case .TypeBuiltin (let v): return v.hashValue
654 case .TypeMacro (let v): return v.hashValue
661 func ==(left: MalVal, right: MalVal) -> Bool {
662 switch (left, right) {
663 case (.TypeUnknown, .TypeUnknown): return true
664 case (.TypeNil, .TypeNil): return true
665 case (.TypeTrue, .TypeTrue): return true
666 case (.TypeFalse, .TypeFalse): return true
667 case (.TypeComment, .TypeComment): return false
668 case (.TypeInteger (let vLeft), .TypeInteger (let vRight)): return vLeft == vRight
669 case (.TypeFloat (let vLeft), .TypeFloat (let vRight)): return vLeft == vRight
670 case (.TypeSymbol (let vLeft), .TypeSymbol (let vRight)): return vLeft == vRight
671 case (.TypeKeyword (let vLeft), .TypeKeyword (let vRight)): return vLeft == vRight
672 case (.TypeString (let vLeft), .TypeString (let vRight)): return vLeft == vRight
673 case (.TypeList (let vLeft), .TypeList (let vRight)): return vLeft == vRight
674 case (.TypeVector (let vLeft), .TypeVector (let vRight)): return vLeft == vRight
675 case (.TypeHashMap (let vLeft), .TypeHashMap (let vRight)): return vLeft == vRight
676 case (.TypeAtom (let vLeft), .TypeAtom (let vRight)): return vLeft == vRight
677 case (.TypeClosure (let vLeft), .TypeClosure (let vRight)): return vLeft == vRight
678 case (.TypeBuiltin (let vLeft), .TypeBuiltin (let vRight)): return vLeft == vRight
679 case (.TypeMacro (let vLeft), .TypeMacro (let vRight)): return vLeft == vRight
681 case (.TypeList (let vLeft), .TypeVector (let vRight)): return vLeft == vRight
682 case (.TypeVector (let vLeft), .TypeList (let vRight)): return vLeft == vRight
684 default: return false
688 func ==(left: MalList, right: MalVector) -> Bool {
689 if left.count != right.count { return false }
690 var left_gen = left.generate()
691 var right_gen = right.generate()
693 if let left = left_gen.next(), right = right_gen.next() {
704 func ==(left: MalVector, right: MalList) -> Bool {
705 if left.count != right.count { return false }
706 var left_gen = left.generate()
707 var right_gen = right.generate()
709 if let left = left_gen.next(), right = right_gen.next() {
720 // ==================== Constructors ====================
722 // ----- Default -----
724 func make_unknown () -> MalVal { return kUnknown }
725 func make_nil () -> MalVal { return kNil }
726 func make_true () -> MalVal { return kTrue }
727 func make_false () -> MalVal { return kFalse }
728 func make_comment () -> MalVal { return kComment }
729 func make_integer () -> MalVal { return make_integer (MalInteger()) }
730 func make_float () -> MalVal { return make_float (MalFloat()) }
731 func make_symbol () -> MalVal { return make_symbol (MalSymbol()) }
732 func make_keyword () -> MalVal { return make_keyword (MalKeyword()) }
733 func make_string () -> MalVal { return make_string (MalString()) }
734 func make_list () -> MalVal { return make_list (MalList()) }
735 func make_vector () -> MalVal { return make_vector (MalVector()) }
736 func make_hashmap () -> MalVal { return make_hashmap (MalHashMap()) }
737 func make_atom () -> MalVal { return make_atom (MalAtom()) }
738 func make_closure () -> MalVal { return make_closure (MalClosure()) }
739 func make_builtin () -> MalVal { return make_builtin (MalBuiltin()) }
740 func make_macro () -> MalVal { return make_macro (MalMacro()) }
744 func make_integer (v: MalInteger) -> MalVal { return MalVal.TypeInteger(v) }
745 func make_float (v: MalFloat) -> MalVal { return MalVal.TypeFloat(v) }
746 func make_symbol (v: MalSymbol) -> MalVal { return MalVal.TypeSymbol(v) }
747 func make_keyword (v: MalKeyword) -> MalVal { return MalVal.TypeKeyword(v) }
748 func make_string (v: MalString) -> MalVal { return MalVal.TypeString(v) }
749 func make_list (v: MalList) -> MalVal { return MalVal.TypeList(v) }
750 func make_vector (v: MalVector) -> MalVal { return MalVal.TypeVector(v) }
751 func make_hashmap (v: MalHashMap) -> MalVal { return MalVal.TypeHashMap(v) }
752 func make_atom (v: MalAtom) -> MalVal { return MalVal.TypeAtom(v) }
753 func make_closure (v: MalClosure) -> MalVal { return MalVal.TypeClosure(v) }
754 func make_builtin (v: MalBuiltin) -> MalVal { return MalVal.TypeBuiltin(v) }
755 func make_macro (v: MalMacro) -> MalVal { return MalVal.TypeMacro(v) }
757 // ----- Parameterized -----
759 func make_list (v: MalSequence) -> MalVal { return make_list(MalList(v)) }
760 func make_list (v: MalVectorType) -> MalVal { return make_list(MalList(v)) }
761 func make_list (v: Array<MalVal>) -> MalVal { return make_list(MalList(v)) }
762 func make_list_from (v: MalVal...) -> MalVal { return make_list(MalList(v)) }
763 func make_list<T: SequenceType where T.Generator.Element == MalVal>
764 (v: T) -> MalVal { return make_list(MalList(v)) }
765 func make_vector (v: MalSequence) -> MalVal { return make_vector(MalVector(v)) }
766 func make_vector (v: MalVectorType) -> MalVal { return make_vector(MalVector(v)) }
767 func make_vector (v: Array<MalVal>) -> MalVal { return make_vector(MalVector(v)) }
768 func make_vector_from (v: MalVal...) -> MalVal { return make_vector(MalVector(v)) }
769 func make_vector<T: SequenceType where T.Generator.Element == MalVal>
770 (v: T) -> MalVal { return make_vector(MalVector(v)) }
771 func make_hashmap (v: MalSequence) -> MalVal { return make_hashmap(MalHashMap(v)) }
772 func make_hashmap (v: MalHashType) -> MalVal { return make_hashmap(MalHashMap(v)) }
773 func make_hashmap<T: CollectionType where T.Generator.Element == MalVal>
774 (v: T) -> MalVal { return make_hashmap(MalHashMap(v)) }
775 func make_atom (v: MalVal) -> MalVal { return make_atom(MalAtom(v)) }
776 func make_closure (v: MalClosure.Parameters) -> MalVal { return make_closure(MalClosure(v)) }
777 func make_builtin (v: MalBuiltin.Signature) -> MalVal { return make_builtin(MalBuiltin(v)) }
778 func make_macro (v: MalClosure) -> MalVal { return make_macro(MalMacro(v)) }
780 // ==================== Predicates ====================
782 // ----- Simple -----
784 func is_unknown (v: MalVal) -> Bool { if case .TypeUnknown = v { return true } else { return false } }
785 func is_nil (v: MalVal) -> Bool { if case .TypeNil = v { return true } else { return false } }
786 func is_true (v: MalVal) -> Bool { if case .TypeTrue = v { return true } else { return false } }
787 func is_false (v: MalVal) -> Bool { if case .TypeFalse = v { return true } else { return false } }
788 func is_comment (v: MalVal) -> Bool { if case .TypeComment = v { return true } else { return false } }
789 func is_integer (v: MalVal) -> Bool { if case .TypeInteger = v { return true } else { return false } }
790 func is_float (v: MalVal) -> Bool { if case .TypeFloat = v { return true } else { return false } }
791 func is_symbol (v: MalVal) -> Bool { if case .TypeSymbol = v { return true } else { return false } }
792 func is_keyword (v: MalVal) -> Bool { if case .TypeKeyword = v { return true } else { return false } }
793 func is_string (v: MalVal) -> Bool { if case .TypeString = v { return true } else { return false } }
794 func is_list (v: MalVal) -> Bool { if case .TypeList = v { return true } else { return false } }
795 func is_vector (v: MalVal) -> Bool { if case .TypeVector = v { return true } else { return false } }
796 func is_hashmap (v: MalVal) -> Bool { if case .TypeHashMap = v { return true } else { return false } }
797 func is_atom (v: MalVal) -> Bool { if case .TypeAtom = v { return true } else { return false } }
798 func is_closure (v: MalVal) -> Bool { if case .TypeClosure = v { return true } else { return false } }
799 func is_builtin (v: MalVal) -> Bool { if case .TypeBuiltin = v { return true } else { return false } }
800 func is_macro (v: MalVal) -> Bool { if case .TypeMacro = v { return true } else { return false } }
802 // ----- Compound -----
804 func is_truthy (v: MalVal) -> Bool { return !is_falsey(v) }
805 func is_falsey (v: MalVal) -> Bool { switch v { case .TypeNil, .TypeFalse: return true; default: return false } }
806 func is_number (v: MalVal) -> Bool { switch v { case .TypeInteger, .TypeFloat: return true; default: return false } }
807 func is_sequence (v: MalVal) -> Bool { switch v { case .TypeList, .TypeVector: return true; default: return false } }
808 func is_function (v: MalVal) -> Bool { switch v { case .TypeClosure, .TypeBuiltin: return true; default: return false } }
810 // ==================== Converters/Extractors ====================
812 func as_integer (v: MalVal) -> MalInteger { if case .TypeInteger(let w) = v { return w }; die("expected integer, got \(v)") }
813 func as_float (v: MalVal) -> MalFloat { if case .TypeFloat(let w) = v { return w }; die("expected float, got \(v)") }
814 func as_symbol (v: MalVal) -> MalSymbol { if case .TypeSymbol(let w) = v { return w }; die("expected symbol, got \(v)") }
815 func as_keyword (v: MalVal) -> MalKeyword { if case .TypeKeyword(let w) = v { return w }; die("expected keyword, got \(v)") }
816 func as_string (v: MalVal) -> MalString { if case .TypeString(let w) = v { return w }; die("expected string, got \(v)") }
817 func as_list (v: MalVal) -> MalList { if case .TypeList(let w) = v { return w }; die("expected list, got \(v)") }
818 func as_vector (v: MalVal) -> MalVector { if case .TypeVector(let w) = v { return w }; die("expected vector, got \(v)") }
819 func as_hashmap (v: MalVal) -> MalHashMap { if case .TypeHashMap(let w) = v { return w }; die("expected hashmap, got \(v)") }
820 func as_atom (v: MalVal) -> MalAtom { if case .TypeAtom(let w) = v { return w }; die("expected atom, got \(v)") }
821 func as_closure (v: MalVal) -> MalClosure { if case .TypeClosure(let w) = v { return w }; die("expected closure, got \(v)") }
822 func as_builtin (v: MalVal) -> MalBuiltin { if case .TypeBuiltin(let w) = v { return w }; die("expected builtin, got \(v)") }
823 func as_macro (v: MalVal) -> MalMacro { if case .TypeMacro(let w) = v { return w }; die("expected macro, got \(v)") }
825 func as_sequence (v: MalVal) -> MalSequence {
827 case .TypeList(let v): return v
828 case .TypeVector(let v): return v
829 default: die("expected sequence, got \(v)")
832 func as_function (v: MalVal) -> MalFunction {
834 case .TypeClosure(let v): return v
835 case .TypeBuiltin(let v): return v
836 default: die("expected function, got \(v)")
840 func as_inttype (v: MalVal) -> MalIntType { return as_integer(v) }
841 func as_floattype (v: MalVal) -> MalFloatType { return as_float(v) }
842 func as_stringtype (v: MalVal) -> MalStringType { return as_string(v) }
844 func as_inttype (v: MalInteger) -> MalIntType { return v }
845 func as_floattype (v: MalFloat) -> MalFloatType { return v }
846 func as_stringtype (v: MalString) -> MalStringType { return v }
848 func as_integerQ (v: MalVal) -> MalInteger? { if case .TypeInteger(let w) = v { return w }; return nil }
849 func as_floatQ (v: MalVal) -> MalFloat? { if case .TypeFloat(let w) = v { return w }; return nil }
850 func as_symbolQ (v: MalVal) -> MalSymbol? { if case .TypeSymbol(let w) = v { return w }; return nil }
851 func as_keywordQ (v: MalVal) -> MalKeyword? { if case .TypeKeyword(let w) = v { return w }; return nil }
852 func as_stringQ (v: MalVal) -> MalString? { if case .TypeString(let w) = v { return w }; return nil }
853 func as_listQ (v: MalVal) -> MalList? { if case .TypeList(let w) = v { return w }; return nil }
854 func as_vectorQ (v: MalVal) -> MalVector? { if case .TypeVector(let w) = v { return w }; return nil }
855 func as_hashmapQ (v: MalVal) -> MalHashMap? { if case .TypeHashMap(let w) = v { return w }; return nil }
856 func as_atomQ (v: MalVal) -> MalAtom? { if case .TypeAtom(let w) = v { return w }; return nil }
857 func as_closureQ (v: MalVal) -> MalClosure? { if case .TypeClosure(let w) = v { return w }; return nil }
858 func as_builtinQ (v: MalVal) -> MalBuiltin? { if case .TypeBuiltin(let w) = v { return w }; return nil }
859 func as_macroQ (v: MalVal) -> MalMacro? { if case .TypeMacro(let w) = v { return w }; return nil }
861 func as_listQ (v: MalSequence) -> MalList? { return v as? MalList }
862 func as_vectorQ (v: MalSequence) -> MalVector? { return v as? MalVector }
864 func as_sequenceQ (v: MalVal) -> MalSequence? {
866 case .TypeList(let v): return v
867 case .TypeVector(let v): return v
871 func as_functionQ (v: MalVal) -> MalFunction? {
873 case .TypeClosure(let v): return v
874 case .TypeBuiltin(let v): return v
879 func as_inttypeQ (v: MalVal) -> MalIntType? { return as_integerQ(v) }
880 func as_floattypeQ (v: MalVal) -> MalFloatType? { return as_floatQ(v) }
881 func as_stringtypeQ (v: MalVal) -> MalStringType? { return as_stringQ(v) }
883 // ==================== Exceptions ====================
885 enum MalException: ErrorType, CustomStringConvertible {
890 var exception: MalVal {
894 case .Message(let v):
895 return make_string(v)
901 // CustomStringConvertible
903 var description: String {
906 return "NIL Exception"
907 case .Message(let v):
916 func throw_error(v: String) throws { throw MalException.Message(v) }
919 func throw_error(v: MalVal) throws { throw MalException.Object(v) }
921 // ==================== Utilities ====================
923 @noreturn private func die(msg: String) {
924 preconditionFailure(msg)
927 @noreturn private func die() {
928 die("Should not get here")
931 func get_meta(v: MalVal) -> MalVal? {
933 case .TypeUnknown: return nil
934 case .TypeNil: return nil
935 case .TypeTrue: return nil
936 case .TypeFalse: return nil
937 case .TypeComment: return nil
938 case .TypeInteger: return nil
939 case .TypeFloat: return nil
940 case .TypeSymbol: return nil
941 case .TypeKeyword: return nil
942 case .TypeString: return nil
943 case .TypeList (let v): return v.meta
944 case .TypeVector (let v): return v.meta
945 case .TypeHashMap (let v): return v.meta
946 case .TypeAtom (let v): return v.meta
947 case .TypeClosure (let v): return v.meta
948 case .TypeBuiltin (let v): return v.meta
949 case .TypeMacro (let v): return v.meta
953 func with_meta(obj: MalVal, _ meta: MalVal) -> MalVal {
955 case .TypeUnknown: return obj
956 case .TypeNil: return obj
957 case .TypeTrue: return obj
958 case .TypeFalse: return obj
959 case .TypeComment: return obj
960 case .TypeInteger: return obj
961 case .TypeFloat: return obj
962 case .TypeSymbol: return obj
963 case .TypeKeyword: return obj
964 case .TypeString: return obj
965 case .TypeList (let v): return make_list(MalList(v, meta))
966 case .TypeVector (let v): return make_vector(MalVector(v, meta))
967 case .TypeHashMap (let v): return make_hashmap(MalHashMap(v, meta))
968 case .TypeAtom (let v): return make_atom(MalAtom(v, meta))
969 case .TypeClosure (let v): return make_closure(MalClosure(v, meta))
970 case .TypeBuiltin (let v): return make_builtin(MalBuiltin(v, meta))
971 case .TypeMacro (let v): return make_macro(MalMacro(v, meta))
975 func unescape(s: String) -> String {
977 var prev_is_escape = false
979 let chars = s.characters
981 if index == chars.count - 1 { continue }
982 if index++ == 0 { continue }
984 prev_is_escape = false
985 if ch == "n" { str.appendContentsOf("\n") }
986 else if ch == "r" { str.appendContentsOf("\r") }
987 else if ch == "t" { str.appendContentsOf("\t") }
988 else { str.append(ch) }
989 } else if ch == "\\" {
990 prev_is_escape = true
998 func escape(s: String) -> String {
1000 let chars = s.characters
1002 if ch == "\n" { str.appendContentsOf("\\n"); continue }
1003 if ch == "\r" { str.appendContentsOf("\\r"); continue }
1004 if ch == "\t" { str.appendContentsOf("\\t"); continue }
1005 if ch == "\"" || ch == "\\" { str.appendContentsOf("\\") }
1008 str = "\"" + str + "\""