Refactor token parser to return enum

This commit is contained in:
Kyle Fuller
2014-10-26 16:14:56 +00:00
parent 6fd3fec141
commit 0b1ce61647
2 changed files with 31 additions and 27 deletions

View File

@@ -88,7 +88,7 @@ public class VariableNode : Node {
public class NowNode : Node { public class NowNode : Node {
public let format:Variable public let format:Variable
public class func parse(parser:TokenParser, token:Token) -> (node:Node?, error:Error?) { public class func parse(parser:TokenParser, token:Token) -> TokenParser.Result {
var format:Variable? var format:Variable?
let components = token.components() let components = token.components()
@@ -96,7 +96,7 @@ public class NowNode : Node {
format = Variable(components[1]) format = Variable(components[1])
} }
return (NowNode(format:format), nil) return .Success(node:NowNode(format:format))
} }
public init(format:Variable?) { public init(format:Variable?) {
@@ -131,7 +131,7 @@ public class ForNode : Node {
let loopVariable:String let loopVariable:String
let nodes:[Node] let nodes:[Node]
public class func parse(parser:TokenParser, token:Token) -> (node:Node?, error:Error?) { public class func parse(parser:TokenParser, token:Token) -> TokenParser.Result {
let components = token.components() let components = token.components()
let count = countElements(components) let count = countElements(components)
@@ -142,7 +142,7 @@ public class ForNode : Node {
var emptyNodes = [Node]() var emptyNodes = [Node]()
if let error = error { if let error = error {
return (nil, error) return .Error(error: error)
} }
if let token = parser.nextToken() { if let token = parser.nextToken() {
@@ -151,7 +151,7 @@ public class ForNode : Node {
parser.nextToken() parser.nextToken()
if let error = error { if let error = error {
return (nil, error) return .Error(error: error)
} }
if let nodes = nodes { if let nodes = nodes {
@@ -159,13 +159,13 @@ public class ForNode : Node {
} }
} }
} else { } else {
return (nil, NodeError(token: token, message: "`endfor` was not found.")) return .Error(error: NodeError(token: token, message: "`endfor` was not found."))
} }
return (ForNode(variable: variable, loopVariable: loopVariable, nodes: nodes!, emptyNodes:emptyNodes), nil) return .Success(node:ForNode(variable: variable, loopVariable: loopVariable, nodes: nodes!, emptyNodes:emptyNodes))
} }
return (nil, NodeError(token: token, message: "Invalid syntax. Expected `for x in y`.")) return .Error(error: NodeError(token: token, message: "Invalid syntax. Expected `for x in y`."))
} }
public init(variable:String, loopVariable:String, nodes:[Node], emptyNodes:[Node]) { public init(variable:String, loopVariable:String, nodes:[Node], emptyNodes:[Node]) {
@@ -204,12 +204,12 @@ public class IfNode : Node {
public let trueNodes:[Node] public let trueNodes:[Node]
public let falseNodes:[Node] public let falseNodes:[Node]
public class func parse(parser:TokenParser, token:Token) -> (node:Node?, error:Error?) { public class func parse(parser:TokenParser, token:Token) -> TokenParser.Result {
let variable = token.components()[1] let variable = token.components()[1]
let (trueNodes, error) = parser.parse(until(["endif", "else"])) let (trueNodes, error) = parser.parse(until(["endif", "else"]))
if let error = error { if let error = error {
return (nil, error) return .Error(error:error)
} }
var falseNodes = [Node]() var falseNodes = [Node]()
@@ -220,7 +220,7 @@ public class IfNode : Node {
parser.nextToken() parser.nextToken()
if let error = error { if let error = error {
return (nil, error) return .Error(error:error)
} }
if let nodes = nodes { if let nodes = nodes {
@@ -228,18 +228,18 @@ public class IfNode : Node {
} }
} }
} else { } else {
return (nil, NodeError(token: token, message: "`endif` was not found.")) return .Error(error:NodeError(token: token, message: "`endif` was not found."))
} }
return (IfNode(variable: variable, trueNodes: trueNodes!, falseNodes: falseNodes), nil) return .Success(node:IfNode(variable: variable, trueNodes: trueNodes!, falseNodes: falseNodes))
} }
public class func parse_ifnot(parser:TokenParser, token:Token) -> (node:Node?, error:Error?) { public class func parse_ifnot(parser:TokenParser, token:Token) -> TokenParser.Result {
let variable = token.components()[1] let variable = token.components()[1]
let (falseNodes, error) = parser.parse(until(["endif", "else"])) let (falseNodes, error) = parser.parse(until(["endif", "else"]))
if let error = error { if let error = error {
return (nil, error) return .Error(error:error)
} }
var trueNodes = [Node]() var trueNodes = [Node]()
@@ -247,7 +247,7 @@ public class IfNode : Node {
if token.contents == "else" { if token.contents == "else" {
let (nodes, error) = parser.parse(until(["endif"])) let (nodes, error) = parser.parse(until(["endif"]))
if let error = error { if let error = error {
return (nil, error) return .Error(error:error)
} }
if let nodes = nodes { if let nodes = nodes {
@@ -257,10 +257,10 @@ public class IfNode : Node {
parser.nextToken() parser.nextToken()
} }
} else { } else {
return (nil, NodeError(token: token, message: "`endif` was not found.")) return .Error(error: NodeError(token: token, message: "`endif` was not found."))
} }
return (IfNode(variable: variable, trueNodes: trueNodes, falseNodes: falseNodes!), nil) return .Success(node: IfNode(variable: variable, trueNodes: trueNodes, falseNodes: falseNodes!))
} }
public init(variable:String, trueNodes:[Node], falseNodes:[Node]) { public init(variable:String, trueNodes:[Node], falseNodes:[Node]) {

View File

@@ -13,8 +13,15 @@ public func until(tags:[String])(parser:TokenParser, token:Token) -> Bool {
} }
public class TokenParser { public class TokenParser {
public enum Result {
case Success(node: Node)
case Error(error: Stencil.Error)
}
typealias TagParser = (TokenParser, Token) -> Result
private var tokens:[Token] private var tokens:[Token]
private var tags = Dictionary<String, ((TokenParser, Token) -> ((node:Node?, error:Error?)))>() private var tags = Dictionary<String, TagParser>()
public init(tokens:[Token]) { public init(tokens:[Token]) {
self.tokens = tokens self.tokens = tokens
@@ -51,14 +58,11 @@ public class TokenParser {
if let tag = tag { if let tag = tag {
if let parser = self.tags[tag] { if let parser = self.tags[tag] {
let (node, error) = parser(self, token) switch parser(self, token) {
case .Success(let node):
if let error = error { nodes.append(node)
return (nil, error) case .Error(let error):
} return (nil, error)
if let node = node {
nodes.append(node)
} }
} }
} }