Skip to content

Commit a8d3820

Browse files
authored
Merge pull request #36 from owenv/immediate-mode
Add a bare-bones implementation of immediate mode
2 parents 22835b0 + 66c7f8f commit a8d3820

File tree

6 files changed

+105
-5
lines changed

6 files changed

+105
-5
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public struct Driver {
205205

206206
self.driverKind = try Self.determineDriverKind(args: &args)
207207
self.optionTable = OptionTable()
208-
self.parsedOptions = try optionTable.parse(Array(args))
208+
self.parsedOptions = try optionTable.parse(Array(args), forInteractiveMode: self.driverKind == .interactive)
209209

210210
let explicitTarget = (self.parsedOptions.getLastArgument(.target)?.asSingle)
211211
.map {
@@ -844,6 +844,9 @@ extension Driver {
844844
case .repl, .deprecatedIntegratedRepl, .lldbRepl:
845845
compilerOutputType = nil
846846

847+
case .interpret:
848+
compilerOutputType = nil
849+
847850
default:
848851
fatalError("unhandled output mode option \(outputOption)")
849852
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===--------------- InterpretJob.swift - Swift Immediate Mode ------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
extension Driver {
14+
mutating func interpretJob(inputs allInputs: [TypedVirtualPath]) throws -> Job {
15+
var commandLine: [Job.ArgTemplate] = swiftCompilerPrefixArgs.map { Job.ArgTemplate.flag($0) }
16+
var inputs: [TypedVirtualPath] = []
17+
18+
commandLine.appendFlags("-frontend", "-interpret")
19+
20+
// Add the inputs.
21+
for input in allInputs {
22+
commandLine.append(.path(input.file))
23+
inputs.append(input)
24+
}
25+
26+
if parsedOptions.hasArgument(.parseStdlib) {
27+
commandLine.appendFlag(.disableObjcAttrRequiresFoundationModule)
28+
}
29+
30+
try addCommonFrontendOptions(commandLine: &commandLine)
31+
// FIXME: MSVC runtime flags
32+
33+
try commandLine.appendLast(.parseSil, from: &parsedOptions)
34+
try commandLine.appendAll(.l, .framework, from: &parsedOptions)
35+
36+
// The immediate arguments must be last.
37+
try commandLine.appendLast(.DASHDASH, from: &parsedOptions)
38+
39+
// FIXME: Set [DY]LD_LIBRARY_PATH, DYLD_FRAMEWORK_PATH if needed.
40+
41+
return Job(
42+
kind: .interpret,
43+
tool: .absolute(try toolchain.getToolPath(.swiftCompiler)),
44+
commandLine: commandLine,
45+
inputs:inputs,
46+
outputs: []
47+
)
48+
}
49+
}

Sources/SwiftDriver/Jobs/Job.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public struct Job: Codable, Equatable {
2020
case generateDSYM = "generate-dsym"
2121
case autolinkExtract = "autolink-extract"
2222
case emitModule = "emit-module"
23+
case interpret
2324
}
2425

2526
public enum ArgTemplate: Equatable {

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,12 @@ extension Driver {
144144
public mutating func planBuild() throws -> [Job] {
145145
// Plan the build.
146146
switch compilerMode {
147-
case .immediate, .repl:
147+
case .repl:
148148
fatalError("Not yet supported")
149149

150+
case .immediate:
151+
return [try interpretJob(inputs: inputFiles)]
152+
150153
case .standardCompile, .batchCompile, .singleCompile:
151154
return try planStandardCompile()
152155
}

Sources/SwiftDriver/Options/OptionParsing.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ extension OptionTable {
1818
/// Parse the given command-line arguments into a set of options.
1919
///
2020
/// Throws an error if the command line contains any errors.
21-
public func parse(_ arguments: [String]) throws -> ParsedOptions {
21+
public func parse(_ arguments: [String],
22+
forInteractiveMode isInteractiveMode: Bool = false) throws -> ParsedOptions {
2223
var trie = PrefixTrie<String.UTF8View, Option>()
2324
for opt in options {
2425
trie[opt.spelling.utf8] = opt
@@ -39,6 +40,13 @@ extension OptionTable {
3940
// If this is not a flag, record it as an input.
4041
if argument == "-" || argument.first! != "-" {
4142
parsedOptions.addInput(argument)
43+
44+
// In interactive mode, synthesize a "--" argument for all args after the first input.
45+
if isInteractiveMode && index < arguments.endIndex {
46+
parsedOptions.addOption(.DASHDASH, argument: .multiple(Array(arguments[index...])))
47+
break
48+
}
49+
4250
continue
4351
}
4452

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,11 @@ final class SwiftDriverTests: XCTestCase {
148148
}
149149

150150
func testInputFiles() throws {
151-
let driver1 = try Driver(args: ["swift", "a.swift", "/tmp/b.swift"])
151+
let driver1 = try Driver(args: ["swiftc", "a.swift", "/tmp/b.swift"])
152152
XCTAssertEqual(driver1.inputFiles,
153153
[ TypedVirtualPath(file: .relative(RelativePath("a.swift")), type: .swift),
154154
TypedVirtualPath(file: .absolute(AbsolutePath("/tmp/b.swift")), type: .swift) ])
155-
let driver2 = try Driver(args: ["swift", "a.swift", "-working-directory", "/wobble", "/tmp/b.swift"])
155+
let driver2 = try Driver(args: ["swiftc", "a.swift", "-working-directory", "/wobble", "/tmp/b.swift"])
156156
XCTAssertEqual(driver2.inputFiles,
157157
[ TypedVirtualPath(file: .absolute(AbsolutePath("/wobble/a.swift")), type: .swift),
158158
TypedVirtualPath(file: .absolute(AbsolutePath("/tmp/b.swift")), type: .swift) ])
@@ -875,6 +875,42 @@ final class SwiftDriverTests: XCTestCase {
875875

876876
}
877877

878+
func testImmediateMode() throws {
879+
do {
880+
var driver = try Driver(args: ["swift", "foo.swift"])
881+
let plannedJobs = try driver.planBuild()
882+
XCTAssertEqual(plannedJobs.count, 1)
883+
let job = plannedJobs[0]
884+
XCTAssertEqual(job.inputs.count, 1)
885+
XCTAssertEqual(job.inputs[0].file, .relative(RelativePath("foo.swift")))
886+
XCTAssertEqual(job.outputs.count, 0)
887+
XCTAssertTrue(job.commandLine.contains(.flag("-frontend")))
888+
XCTAssertTrue(job.commandLine.contains(.flag("-interpret")))
889+
XCTAssertTrue(job.commandLine.contains(.flag("-module-name")))
890+
XCTAssertTrue(job.commandLine.contains(.flag("foo")))
891+
892+
XCTAssertFalse(job.commandLine.contains(.flag("--")))
893+
}
894+
895+
do {
896+
var driver = try Driver(args: ["swift", "foo.swift", "-some", "args", "-for=foo"])
897+
let plannedJobs = try driver.planBuild()
898+
XCTAssertEqual(plannedJobs.count, 1)
899+
let job = plannedJobs[0]
900+
XCTAssertEqual(job.inputs.count, 1)
901+
XCTAssertEqual(job.inputs[0].file, .relative(RelativePath("foo.swift")))
902+
XCTAssertEqual(job.outputs.count, 0)
903+
XCTAssertTrue(job.commandLine.contains(.flag("-frontend")))
904+
XCTAssertTrue(job.commandLine.contains(.flag("-interpret")))
905+
XCTAssertTrue(job.commandLine.contains(.flag("-module-name")))
906+
XCTAssertTrue(job.commandLine.contains(.flag("foo")))
907+
XCTAssertTrue(job.commandLine.contains(.flag("--")))
908+
XCTAssertTrue(job.commandLine.contains(.flag("-some")))
909+
XCTAssertTrue(job.commandLine.contains(.flag("args")))
910+
XCTAssertTrue(job.commandLine.contains(.flag("-for=foo")))
911+
}
912+
}
913+
878914
func testTargetTriple() throws {
879915
let driver1 = try Driver(args: ["swiftc", "-c", "foo.swift", "-module-name", "Foo"])
880916

0 commit comments

Comments
 (0)