2016-12-16 09:44:05 -08:00
|
|
|
//
|
|
|
|
// Lexer.swift
|
|
|
|
// Sibil
|
|
|
|
//
|
|
|
|
// Created by Eryn Wells on 12/16/16.
|
|
|
|
// Copyright © 2016 Eryn Wells. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
|
2016-12-16 10:10:05 -08:00
|
|
|
struct Token: CustomDebugStringConvertible {
|
2016-12-16 09:44:05 -08:00
|
|
|
enum Kind {
|
|
|
|
case LeftParen
|
|
|
|
case RightParen
|
|
|
|
}
|
|
|
|
|
|
|
|
let kind: Kind
|
|
|
|
let value: String
|
|
|
|
|
2016-12-16 10:10:05 -08:00
|
|
|
// MARK: CustomDebugStringConvertible
|
|
|
|
|
|
|
|
var debugDescription: String {
|
|
|
|
return "Token(kind: .\(kind), value: \"\(value)\")"
|
|
|
|
}
|
|
|
|
}
|
2016-12-16 09:44:05 -08:00
|
|
|
|
|
|
|
|
2016-12-16 10:10:05 -08:00
|
|
|
class Lexer {
|
2016-12-16 09:44:05 -08:00
|
|
|
let input: String
|
|
|
|
|
2016-12-16 10:10:05 -08:00
|
|
|
var index: String.Index
|
2016-12-16 09:44:05 -08:00
|
|
|
|
|
|
|
init(input: String) {
|
|
|
|
self.input = input
|
|
|
|
self.index = input.startIndex
|
|
|
|
}
|
2016-12-16 10:10:05 -08:00
|
|
|
}
|
2016-12-16 09:44:05 -08:00
|
|
|
|
2016-12-16 10:10:05 -08:00
|
|
|
extension Lexer: Sequence, IteratorProtocol {
|
|
|
|
typealias Element = Token
|
|
|
|
|
|
|
|
func makeIterator() -> Lexer {
|
|
|
|
return self
|
|
|
|
}
|
2016-12-16 09:44:05 -08:00
|
|
|
|
|
|
|
func next() -> Token? {
|
2016-12-16 10:10:05 -08:00
|
|
|
guard index != input.endIndex else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-12-16 09:44:05 -08:00
|
|
|
var token: Token?
|
|
|
|
while token == nil {
|
|
|
|
let c = input[index]
|
|
|
|
switch c {
|
|
|
|
case "(":
|
|
|
|
token = Token(kind: .LeftParen, value: String(c))
|
|
|
|
case ")":
|
|
|
|
token = Token(kind: .RightParen, value: String(c))
|
|
|
|
default:
|
|
|
|
break
|
|
|
|
}
|
2016-12-16 10:10:05 -08:00
|
|
|
index = input.index(after: index)
|
2016-12-16 09:44:05 -08:00
|
|
|
}
|
|
|
|
return token
|
|
|
|
}
|
|
|
|
}
|