Commit d6ea8b9f authored by Drew's avatar Drew

Merge pull request #23 from AnarchyTools/substitution_engine

Implement a substition engine for variable expansion
parents 9afedad9 edafd8e4
Pipeline #1371 passed with stage
private enum ParseState {
case Initial
case Escaped
case Dollar
case SubstitutionName
}
private func evaluateSubstitution(substitution: String, package: Package) -> String {
//"prefix-like" substitions here
//collect sources substition
if substitution.hasPrefix("collect_sources:") {
let taskName = String(substitution.characters[substitution.characters.startIndex.advanced(by: 16)..<substitution.characters.endIndex])
guard let task = package.tasks[taskName] else {
fatalError("Cannot find task named \(taskName) for substition.")
}
guard let sources = task["sources"]?.vector else {
fatalError("No sources for task named \(taskName) for substition.")
}
var str_sources: [String] = []
for str in sources {
guard let str_s = str.string else {
fatalError("Non-string source \(str) for substition.")
}
str_sources.append(str_s)
}
let collectedSources = collectSources(str_sources, taskForCalculatingPath: task)
var output = ""
for (idx, source) in collectedSources.enumerated() {
output += source
if idx != collectedSources.count - 1 { output += " "}
}
return output
}
//"constant" substitions here
switch(substitution) {
case "test_substitution":
return "test_substitution"
default:
fatalError("Unknown substitiution \(substitution)")
}
}
public func evaluateSubstitutions(input: String, package: Package)-> String {
var output = ""
var currentSubstitionName = ""
var parseState = ParseState.Initial
//introducing, the world's shittiest parser
for char in input.characters {
switch(parseState) {
case .Initial:
switch(char) {
case "$":
parseState = .Dollar
case "\\":
parseState = .Escaped
default:
output.characters.append(char)
}
case .Escaped:
output.characters.append(char)
parseState = .Initial
case .Dollar:
switch(char) {
case "{":
parseState = .SubstitutionName
case "\\":
output.characters.append("$")
parseState = .Escaped
default:
output.characters.append("$")
output.characters.append(char)
parseState = .Initial
}
case .SubstitutionName:
switch(char) {
case "}":
output += evaluateSubstitution(currentSubstitionName, package: package)
currentSubstitionName = ""
parseState = .Initial
default:
currentSubstitionName.characters.append(char)
}
}
}
return output
}
\ No newline at end of file
......@@ -22,7 +22,7 @@ final public class Task {
}
///The package for the task
let package: Package
public let package: Package
public var dependencies: [String] = []
public var tool: String
......
;; This is the most basic of sample files.
(package
:name "collect_sources"
:version "0.1.0-dev"
:tasks {
:default {
:tool "nop"
:sources ["src/**.swift"]
}
}
)
;; End of the sample.
\ No newline at end of file
// a.swift
\ No newline at end of file
// b.swift
\ No newline at end of file
......@@ -55,7 +55,7 @@ extension Test {
let tests: [Test] = [
// NOTE: Add your test classes here...
SubstitutionTests(),
ScannerTests(),
LexerTests(),
ParserTests(),
......
// Copyright (c) 2016 Anarchy Tools Contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import atpkg
class SubstitutionTests: Test {
required init() {}
let tests = [
SubstitutionTests.testBasic,
SubstitutionTests.testCollectSources
]
let filename = #file
static func testBasic() throws {
let filepath = "./tests/collateral/basic.atpkg"
let package = try Package(filepath: filepath, overlay: [], focusOnTask: nil)
try test.assert(evaluateSubstitutions("${test_substitution}", package: package) == "test_substitution")
try test.assert(evaluateSubstitutions("foobly-doobly-doo ${test_substitution} doobly-doo", package: package) == "foobly-doobly-doo test_substitution doobly-doo")
try test.assert(evaluateSubstitutions("foobly-doobly-doo \\${test_substitution} doobly-doo", package: package) == "foobly-doobly-doo ${test_substitution} doobly-doo")
}
static func testCollectSources() throws {
let filepath = "./tests/collateral/collect_sources/build.atpkg"
let package = try Package(filepath: filepath, overlay: [], focusOnTask: nil)
try test.assert(evaluateSubstitutions("${collect_sources:default}", package: package) == "./tests/collateral/collect_sources/src/a.swift ./tests/collateral/collect_sources/src/b.swift")
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment