Create lexer and template

This commit is contained in:
Kyle Fuller
2014-10-24 14:25:53 +01:00
parent bf67ea3e5f
commit 652a4f9c88
7 changed files with 110 additions and 3 deletions

View File

@@ -14,6 +14,10 @@
7725B3D519F9438F002CF74B /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7725B3D419F9438F002CF74B /* Node.swift */; }; 7725B3D519F9438F002CF74B /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7725B3D419F9438F002CF74B /* Node.swift */; };
7725B3D719F94A43002CF74B /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7725B3D619F94A43002CF74B /* Parser.swift */; }; 7725B3D719F94A43002CF74B /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7725B3D619F94A43002CF74B /* Parser.swift */; };
7725B3D919F94A61002CF74B /* ParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7725B3D819F94A61002CF74B /* ParserTests.swift */; }; 7725B3D919F94A61002CF74B /* ParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7725B3D819F94A61002CF74B /* ParserTests.swift */; };
77EB082519F96E88001870F1 /* Template.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77EB082419F96E88001870F1 /* Template.swift */; };
77EB082719F96E9C001870F1 /* TemplateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77EB082619F96E9C001870F1 /* TemplateTests.swift */; };
77EB082919FA85F2001870F1 /* LexerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77EB082819FA85F2001870F1 /* LexerTests.swift */; };
77EB082B19FA8600001870F1 /* Lexer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77EB082A19FA8600001870F1 /* Lexer.swift */; };
77FAAE5819F91E480029DC5E /* Stencil.h in Headers */ = {isa = PBXBuildFile; fileRef = 77FAAE5719F91E480029DC5E /* Stencil.h */; settings = {ATTRIBUTES = (Public, ); }; }; 77FAAE5819F91E480029DC5E /* Stencil.h in Headers */ = {isa = PBXBuildFile; fileRef = 77FAAE5719F91E480029DC5E /* Stencil.h */; settings = {ATTRIBUTES = (Public, ); }; };
77FAAE5E19F91E480029DC5E /* Stencil.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77FAAE5219F91E480029DC5E /* Stencil.framework */; }; 77FAAE5E19F91E480029DC5E /* Stencil.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77FAAE5219F91E480029DC5E /* Stencil.framework */; };
77FAAE6519F91E480029DC5E /* StencilTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FAAE6419F91E480029DC5E /* StencilTests.swift */; }; 77FAAE6519F91E480029DC5E /* StencilTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FAAE6419F91E480029DC5E /* StencilTests.swift */; };
@@ -39,6 +43,10 @@
7725B3D419F9438F002CF74B /* Node.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Node.swift; sourceTree = "<group>"; }; 7725B3D419F9438F002CF74B /* Node.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Node.swift; sourceTree = "<group>"; };
7725B3D619F94A43002CF74B /* Parser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; }; 7725B3D619F94A43002CF74B /* Parser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
7725B3D819F94A61002CF74B /* ParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParserTests.swift; sourceTree = "<group>"; }; 7725B3D819F94A61002CF74B /* ParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParserTests.swift; sourceTree = "<group>"; };
77EB082419F96E88001870F1 /* Template.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Template.swift; sourceTree = "<group>"; };
77EB082619F96E9C001870F1 /* TemplateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TemplateTests.swift; sourceTree = "<group>"; };
77EB082819FA85F2001870F1 /* LexerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LexerTests.swift; sourceTree = "<group>"; };
77EB082A19FA8600001870F1 /* Lexer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Lexer.swift; sourceTree = "<group>"; };
77FAAE5219F91E480029DC5E /* Stencil.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Stencil.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 77FAAE5219F91E480029DC5E /* Stencil.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Stencil.framework; sourceTree = BUILT_PRODUCTS_DIR; };
77FAAE5619F91E480029DC5E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 77FAAE5619F91E480029DC5E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
77FAAE5719F91E480029DC5E /* Stencil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Stencil.h; sourceTree = "<group>"; }; 77FAAE5719F91E480029DC5E /* Stencil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Stencil.h; sourceTree = "<group>"; };
@@ -95,6 +103,8 @@
7725B3CE19F94214002CF74B /* Tokenizer.swift */, 7725B3CE19F94214002CF74B /* Tokenizer.swift */,
7725B3D419F9438F002CF74B /* Node.swift */, 7725B3D419F9438F002CF74B /* Node.swift */,
7725B3D619F94A43002CF74B /* Parser.swift */, 7725B3D619F94A43002CF74B /* Parser.swift */,
77EB082A19FA8600001870F1 /* Lexer.swift */,
77EB082419F96E88001870F1 /* Template.swift */,
77FAAE5519F91E480029DC5E /* Supporting Files */, 77FAAE5519F91E480029DC5E /* Supporting Files */,
); );
path = Stencil; path = Stencil;
@@ -116,6 +126,8 @@
7725B3CA19F92B4F002CF74B /* VariableTests.swift */, 7725B3CA19F92B4F002CF74B /* VariableTests.swift */,
7725B3D219F9437F002CF74B /* NodeTests.swift */, 7725B3D219F9437F002CF74B /* NodeTests.swift */,
7725B3D819F94A61002CF74B /* ParserTests.swift */, 7725B3D819F94A61002CF74B /* ParserTests.swift */,
77EB082819FA85F2001870F1 /* LexerTests.swift */,
77EB082619F96E9C001870F1 /* TemplateTests.swift */,
77FAAE6219F91E480029DC5E /* Supporting Files */, 77FAAE6219F91E480029DC5E /* Supporting Files */,
); );
path = StencilTests; path = StencilTests;
@@ -237,8 +249,10 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
77FAAE6F19F920750029DC5E /* Context.swift in Sources */, 77FAAE6F19F920750029DC5E /* Context.swift in Sources */,
77EB082B19FA8600001870F1 /* Lexer.swift in Sources */,
7725B3CF19F94214002CF74B /* Tokenizer.swift in Sources */, 7725B3CF19F94214002CF74B /* Tokenizer.swift in Sources */,
7725B3D719F94A43002CF74B /* Parser.swift in Sources */, 7725B3D719F94A43002CF74B /* Parser.swift in Sources */,
77EB082519F96E88001870F1 /* Template.swift in Sources */,
7725B3CD19F92B61002CF74B /* Variable.swift in Sources */, 7725B3CD19F92B61002CF74B /* Variable.swift in Sources */,
7725B3D519F9438F002CF74B /* Node.swift in Sources */, 7725B3D519F9438F002CF74B /* Node.swift in Sources */,
); );
@@ -251,7 +265,9 @@
77FAAE6519F91E480029DC5E /* StencilTests.swift in Sources */, 77FAAE6519F91E480029DC5E /* StencilTests.swift in Sources */,
7725B3D319F9437F002CF74B /* NodeTests.swift in Sources */, 7725B3D319F9437F002CF74B /* NodeTests.swift in Sources */,
7725B3D919F94A61002CF74B /* ParserTests.swift in Sources */, 7725B3D919F94A61002CF74B /* ParserTests.swift in Sources */,
77EB082719F96E9C001870F1 /* TemplateTests.swift in Sources */,
7725B3CB19F92B4F002CF74B /* VariableTests.swift in Sources */, 7725B3CB19F92B4F002CF74B /* VariableTests.swift in Sources */,
77EB082919FA85F2001870F1 /* LexerTests.swift in Sources */,
77FAAE7119F9208C0029DC5E /* ContextTests.swift in Sources */, 77FAAE7119F9208C0029DC5E /* ContextTests.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

21
Stencil/Lexer.swift Normal file
View File

@@ -0,0 +1,21 @@
//
// Lexer.swift
// Stencil
//
// Created by Kyle Fuller on 24/10/2014.
// Copyright (c) 2014 Cocode. All rights reserved.
//
import Foundation
public struct Lexer {
public let templateString:String
public init(templateString:String) {
self.templateString = templateString
}
public func tokenize() -> [Token] {
return [Token.Text(value: templateString)]
}
}

View File

@@ -35,7 +35,7 @@ extension Array {
} }
} }
public func render(nodes:[Node], context:Context) -> (String?, Error?) { public func renderNodes(nodes:[Node], context:Context) -> (String?, Error?) {
let result:(results:[String]?, error:Error?) = nodes.map { let result:(results:[String]?, error:Error?) = nodes.map {
return $0.render(context) return $0.render(context)
} }

24
Stencil/Template.swift Normal file
View File

@@ -0,0 +1,24 @@
//
// Template.swift
// Stencil
//
// Created by Kyle Fuller on 23/10/2014.
// Copyright (c) 2014 Cocode. All rights reserved.
//
import Foundation
public struct Template {
let nodes:[Node]
public init(templateString:String) {
let lexer = Lexer(templateString: templateString)
let tokens = lexer.tokenize()
let parser = TokenParser(tokens: tokens)
nodes = parser.parse()
}
public func render(context:Context) -> (String?, Error?) {
return renderNodes(nodes, context)
}
}

View File

@@ -0,0 +1,23 @@
//
// LexerTests.swift
// Stencil
//
// Created by Kyle Fuller on 24/10/2014.
// Copyright (c) 2014 Cocode. All rights reserved.
//
import Cocoa
import XCTest
import Stencil
class LexerTests: XCTestCase {
func testTokenizeText() {
let lexer = Lexer(templateString:"Hello World")
let tokens = lexer.tokenize()
XCTAssertEqual(tokens.count, 1)
XCTAssertEqual(tokens.first!, Token.Text(value: "Hello World"))
}
}

View File

@@ -62,7 +62,7 @@ class VariableNodeTests: NodeTests {
class RenderNodeTests: NodeTests { class RenderNodeTests: NodeTests {
func testRenderingNodes() { func testRenderingNodes() {
let nodes = [TextNode(text:"Hello "), VariableNode(variable: "name")] as [Node] let nodes = [TextNode(text:"Hello "), VariableNode(variable: "name")] as [Node]
let (result:String?, error:Error?) = render(nodes, context) let (result:String?, error:Error?) = renderNodes(nodes, context)
XCTAssertEqual(result!, "Hello Kyle") XCTAssertEqual(result!, "Hello Kyle")
XCTAssertTrue(error == nil) XCTAssertTrue(error == nil)
@@ -70,7 +70,7 @@ class RenderNodeTests: NodeTests {
func testRenderingNodesWithFailure() { func testRenderingNodesWithFailure() {
let nodes = [TextNode(text:"Hello "), VariableNode(variable: "name"), ErrorNode()] as [Node] let nodes = [TextNode(text:"Hello "), VariableNode(variable: "name"), ErrorNode()] as [Node]
let (result:String?, error:Error?) = render(nodes, context) let (result:String?, error:Error?) = renderNodes(nodes, context)
XCTAssertEqual(error!.description, "Node Error") XCTAssertEqual(error!.description, "Node Error")
XCTAssertTrue(result == nil) XCTAssertTrue(result == nil)

View File

@@ -0,0 +1,23 @@
//
// TemplateTests.swift
// Stencil
//
// Created by Kyle Fuller on 23/10/2014.
// Copyright (c) 2014 Cocode. All rights reserved.
//
import Cocoa
import XCTest
import Stencil
class TemplateTests: XCTestCase {
func testTemplate() {
let context = Context(dictionary: [ "name": "Kyle" ])
let template = Template(templateString: "Hello World")
let (string, error) = template.render(context)
XCTAssertEqual(string!, "Hello World")
XCTAssertTrue(error == nil)
}
}