From 3287a322a644fead45c61d23879decf3f4255a40 Mon Sep 17 00:00:00 2001 From: Ricardo Silva Veloso Date: Wed, 13 Oct 2021 05:31:29 -0300 Subject: [PATCH 1/2] Add a new BF implementation in Swift and compile the matmul.swift --- brainfuck/Makefile | 4 + brainfuck/bf.swift | 191 +++++++++++++++++++++++++++++++++++++++++++++ common/commands.mk | 2 +- matmul/Makefile | 8 +- 4 files changed, 200 insertions(+), 5 deletions(-) create mode 100644 brainfuck/bf.swift diff --git a/brainfuck/Makefile b/brainfuck/Makefile index 5ff7ee2f..0c98a0ec 100644 --- a/brainfuck/Makefile +++ b/brainfuck/Makefile @@ -10,6 +10,7 @@ executables := \ target/bin_d_gdc \ target/bin_d_ldc \ target/bin_rs \ + target/bin_swift \ target/bin_nim_clang \ target/bin_nim_gcc \ target/bin_cr \ @@ -71,6 +72,9 @@ target/bin_rs: bf.rs | $(rs_fmt) $(RUST_CLIPPY) $(RUSTC_BUILD) +target/bin_swift: bf.swift | target + $(SWIFTC_BUILD) + target/bf_scala.jar: bf.scala | target $(SCALAC_BUILD) diff --git a/brainfuck/bf.swift b/brainfuck/bf.swift new file mode 100644 index 00000000..eb7f501d --- /dev/null +++ b/brainfuck/bf.swift @@ -0,0 +1,191 @@ +// Written by Ricardo Silva Veloso; distributed under the MIT license + +import Foundation +import Glibc + +enum Op { + case dec, inc, prev, next, print, loop([Op]) +} + +struct Tape { + var pos = 0 + var tape: ContiguousArray = [0] + var current: Int32 { + get { + tape[pos] + } + set(value) { + tape[pos] = value + } + } + + mutating func dec() { + current -= 1 + } + + mutating func inc() { + current += 1 + } + + mutating func prev() { + pos -= 1 + } + + mutating func next() { + pos += 1 + if pos >= tape.count { + tape.append(contentsOf: repeatElement(0, count: tape.capacity * 2)) + } + } +} + +class Printer { + var sum1: Int32 = 0 + var sum2: Int32 = 0 + var quiet: Bool = false + var checksum: Int32 { + get { + (sum2 << 8) | sum1 + } + } + + init(quiet: Bool) { + self.quiet = quiet + } + + func print(_ n: Int32) { + if quiet { + sum1 = (sum1 + n) % 255 + sum2 = (sum2 + sum1) % 255 + } else { + putc(n, stdout) + } + } +} + +struct Program { + let ops: [Op] + var p: Printer + + init(code: String, p: Printer) { + var it = code.makeIterator() + self.ops = Program.parse(&it) + self.p = p + } + + private static func parse(_ it: inout S) -> [Op] where + S.Element == Character + { + var buf: [Op] = [] + loop: while let c = it.next() { + switch c { + case "-": + buf.append(.dec) + case "+": + buf.append(.inc) + case "<": + buf.append(.prev) + case ">": + buf.append(.next) + case ".": + buf.append(.print) + case "[": + buf.append(.loop(parse(&it))) + case "]": + break loop + default: + continue + } + } + return buf + } + + mutating func run() { + var tape = Tape() + _run(ops, &tape) + } + + private mutating func _run(_ program: [Op], _ tape: inout Tape) { + for op in program { + switch op { + case .dec: + tape.dec() + case .inc: + tape.inc() + case .prev: + tape.prev() + case .next: + tape.next() + case .print: + p.print(tape.current) + case let .loop(program): + while tape.current > 0 { + _run(program, &tape) + } + } + } + } +} + +func notify(_ msg: String) { + let sock = socket(AF_INET, Int32(SOCK_STREAM.rawValue), 0) + var serv_addr = ( + sa_family_t(AF_INET), + in_port_t(htons(9001)), + in_addr(s_addr: 0), + (0,0,0,0,0,0,0,0)) + inet_pton(AF_INET, "127.0.0.1", &serv_addr.2) + let len = MemoryLayout.stride(ofValue: serv_addr) + let rc = withUnsafePointer(to: &serv_addr) { ptr -> Int32 in + return ptr.withMemoryRebound(to: sockaddr.self, capacity: 1) { + bptr in return connect(sock, bptr, socklen_t(len)) + } + } + if rc == 0 { + msg.withCString { (cstr: UnsafePointer) -> Void in + send(sock, cstr, Int(strlen(cstr)), 0) + close(sock) + } + } +} + +func verify() { + let s = """ + ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>\ + ---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++. + """ + + let p_left = Printer(quiet: true) + var program = Program(code: s, p: p_left) + program.run() + let left = p_left.checksum + + let p_right = Printer(quiet: true) + for c in "Hello World!\n" { + p_right.print(Int32(c.asciiValue!)) + } + let right = p_right.checksum + + if left != right { + fputs("\(left) != \(right)", stderr) + exit(EXIT_FAILURE) + } +} + +verify() +if CommandLine.argc < 2 { + exit(EXIT_FAILURE) +} +let text = try String(contentsOfFile: CommandLine.arguments[1]) +let process = ProcessInfo.processInfo +var p = Printer(quiet: process.environment["QUIET"] != nil) +setbuf(stdout, nil) + +notify("Swift\t\(process.processIdentifier)") +var program = Program(code: text, p: p) +program.run() +notify("stop") + +if p.quiet { + print("Output checksum: \(p.checksum)") +} diff --git a/common/commands.mk b/common/commands.mk index 7a15c51e..eb9e01ec 100644 --- a/common/commands.mk +++ b/common/commands.mk @@ -28,6 +28,7 @@ NIM_CLANG_BUILD = nim c -o:$@ --cc:clang $(NIM_FLAGS) $^ NIM_GCC_BUILD = nim c -o:$@ --cc:gcc $(NIM_FLAGS) $^ RUSTC_BUILD = rustc $(RUSTC_FLAGS) -C lto -C codegen-units=1 -o $@ $^ RUST_CLIPPY = clippy-driver -o $@.clippy $^ +SWIFTC_BUILD = swiftc -Ounchecked -cross-module-optimization -o $@ $^ SCALAC_BUILD = scalac -d $@ $^ VALAC_CLANG_BUILD = valac $^ --cc=clang -D CLANG_TEST $(VALAC_FLAGS) -o $@ VALAC_GCC_BUILD = valac $^ --cc=gcc -D GCC_TEST $(VALAC_FLAGS) -o $@ @@ -67,7 +68,6 @@ RACKET_RUN = PLT_CS_COMPILE_LIMIT=100000 $(XTIME) racket $^ RUBY_JIT_RUN = $(XTIME) ruby --jit $^ RUBY_RUN = $(XTIME) ruby $^ SCALA_RUN = $(XTIME) scala -J-Xss100m -cp $^ -SWIFT_RUN = $(XTIME) swift -O $^ TCLSH_RUN = $(XTIME) tclsh $^ TRUBY_JVM_RUN = $(XTIME) truffleruby --jvm $^ TRUBY_NATIVE_RUN = $(XTIME) truffleruby $^ diff --git a/matmul/Makefile b/matmul/Makefile index 51cae4c1..f8ddd29c 100644 --- a/matmul/Makefile +++ b/matmul/Makefile @@ -14,6 +14,7 @@ executables := \ target/matmul_go_gccgo \ target/matmul_c \ target/matmul_rs \ + target/matmul_swift \ target/matmul_d \ target/matmul_d_gdc \ target/matmul_d_ldc \ @@ -43,7 +44,6 @@ all_runners := $(patsubst %,run[%], $(artifacts)) \ run[matmul-numpy.py] \ run[matmul.pl] \ run[matmul.tcl] \ - run[matmul.swift] \ run[matmul.rb] \ run[jit][matmul.rb] \ run[truby-jvm][matmul.rb] \ @@ -68,6 +68,9 @@ target/matmul_rs: matmul.rs | $(rs_fmt) $(RUST_CLIPPY) $(RUSTC_BUILD) +target/matmul_swift: matmul.swift | target + $(SWIFTC_BUILD) + target/matmul_d: matmul.d | $(dfmt) $(DMD_BUILD) @@ -198,9 +201,6 @@ run[matmul.pl]:: run[%]: % run[matmul.tcl]:: run[%]: % $(TCLSH_RUN) $(MSIZE) -run[matmul.swift]:: run[%]: % - $(SWIFT_RUN) $(MSIZE) - run[matmul.rb]:: run[%]: % | $(rubocop) $(RUBY_RUN) $(MSIZE) From 585a13c2f708cba79548003ea07116f28601f7d7 Mon Sep 17 00:00:00 2001 From: Ricardo Silva Veloso Date: Wed, 13 Oct 2021 21:01:43 -0300 Subject: [PATCH 2/2] Use `@main` attribute and do some fixes --- brainfuck/bf.swift | 125 ++++++++++++++++++++++---------------------- common/commands.mk | 2 +- matmul/matmul.swift | 34 +++++++----- 3 files changed, 84 insertions(+), 77 deletions(-) diff --git a/brainfuck/bf.swift b/brainfuck/bf.swift index eb7f501d..72b1debb 100644 --- a/brainfuck/bf.swift +++ b/brainfuck/bf.swift @@ -4,27 +4,28 @@ import Foundation import Glibc enum Op { - case dec, inc, prev, next, print, loop([Op]) + case dec + case inc + case prev + case next + case print + case loop([Op]) } struct Tape { var pos = 0 var tape: ContiguousArray = [0] - var current: Int32 { - get { - tape[pos] - } - set(value) { - tape[pos] = value - } + var currentCell: Int32 { + get { tape[pos] } + set { tape[pos] = newValue } } mutating func dec() { - current -= 1 + currentCell -= 1 } mutating func inc() { - current += 1 + currentCell += 1 } mutating func prev() { @@ -44,9 +45,7 @@ class Printer { var sum2: Int32 = 0 var quiet: Bool = false var checksum: Int32 { - get { - (sum2 << 8) | sum1 - } + get { (sum2 << 8) | sum1 } } init(quiet: Bool) { @@ -63,9 +62,10 @@ class Printer { } } -struct Program { +@main +class Program { let ops: [Op] - var p: Printer + let p: Printer init(code: String, p: Printer) { var it = code.makeIterator() @@ -73,8 +73,50 @@ struct Program { self.p = p } - private static func parse(_ it: inout S) -> [Op] where - S.Element == Character + static func main() throws { + verify() + if CommandLine.argc < 2 { + exit(EXIT_FAILURE) + } + let text = try String(contentsOfFile: CommandLine.arguments[1]) + let process = ProcessInfo.processInfo + let p = Printer(quiet: process.environment["QUIET"] != nil) + setbuf(stdout, nil) + + notify("Swift\t\(process.processIdentifier)") + Program(code: text, p: p).run() + notify("stop") + + if p.quiet { + print("Output checksum: \(p.checksum)") + } + } + + static func verify() { + let s = """ + ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>\ + ---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++. + """ + let p_left = Printer(quiet: true) + Program(code: s, p: p_left).run() + let left = p_left.checksum + + let p_right = Printer(quiet: true) + for c in "Hello World!\n" { + p_right.print(Int32(c.asciiValue!)) + } + let right = p_right.checksum + + if left != right { + fputs("\(left) != \(right)", stderr) + exit(EXIT_FAILURE) + } + } + + private static func parse(_ it: inout I) -> [Op] + where + I: IteratorProtocol, + I.Element == Character { var buf: [Op] = [] loop: while let c = it.next() { @@ -100,12 +142,12 @@ struct Program { return buf } - mutating func run() { + func run() { var tape = Tape() _run(ops, &tape) } - private mutating func _run(_ program: [Op], _ tape: inout Tape) { + private func _run(_ program: [Op], _ tape: inout Tape) { for op in program { switch op { case .dec: @@ -117,9 +159,9 @@ struct Program { case .next: tape.next() case .print: - p.print(tape.current) + p.print(tape.currentCell) case let .loop(program): - while tape.current > 0 { + while tape.currentCell > 0 { _run(program, &tape) } } @@ -148,44 +190,3 @@ func notify(_ msg: String) { } } } - -func verify() { - let s = """ - ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>\ - ---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++. - """ - - let p_left = Printer(quiet: true) - var program = Program(code: s, p: p_left) - program.run() - let left = p_left.checksum - - let p_right = Printer(quiet: true) - for c in "Hello World!\n" { - p_right.print(Int32(c.asciiValue!)) - } - let right = p_right.checksum - - if left != right { - fputs("\(left) != \(right)", stderr) - exit(EXIT_FAILURE) - } -} - -verify() -if CommandLine.argc < 2 { - exit(EXIT_FAILURE) -} -let text = try String(contentsOfFile: CommandLine.arguments[1]) -let process = ProcessInfo.processInfo -var p = Printer(quiet: process.environment["QUIET"] != nil) -setbuf(stdout, nil) - -notify("Swift\t\(process.processIdentifier)") -var program = Program(code: text, p: p) -program.run() -notify("stop") - -if p.quiet { - print("Output checksum: \(p.checksum)") -} diff --git a/common/commands.mk b/common/commands.mk index eb9e01ec..7def16eb 100644 --- a/common/commands.mk +++ b/common/commands.mk @@ -28,7 +28,7 @@ NIM_CLANG_BUILD = nim c -o:$@ --cc:clang $(NIM_FLAGS) $^ NIM_GCC_BUILD = nim c -o:$@ --cc:gcc $(NIM_FLAGS) $^ RUSTC_BUILD = rustc $(RUSTC_FLAGS) -C lto -C codegen-units=1 -o $@ $^ RUST_CLIPPY = clippy-driver -o $@.clippy $^ -SWIFTC_BUILD = swiftc -Ounchecked -cross-module-optimization -o $@ $^ +SWIFTC_BUILD = swiftc -parse-as-library -Ounchecked -cross-module-optimization -o $@ $^ SCALAC_BUILD = scalac -d $@ $^ VALAC_CLANG_BUILD = valac $^ --cc=clang -D CLANG_TEST $(VALAC_FLAGS) -o $@ VALAC_GCC_BUILD = valac $^ --cc=gcc -D GCC_TEST $(VALAC_FLAGS) -o $@ diff --git a/matmul/matmul.swift b/matmul/matmul.swift index 6e9820de..77b95bfc 100644 --- a/matmul/matmul.swift +++ b/matmul/matmul.swift @@ -1,4 +1,5 @@ // Written by Kajal Sinha; distributed under the MIT license + import Glibc func matgen(_ n: Int, _ seed: Double) -> [[Double]] { @@ -19,7 +20,9 @@ func matmul(_ a : [[Double]], b : [[Double]]) ->[[Double]] { let p = b[0].count var x = Array(repeating: Array(repeating: 0, count: p), count: m) var c = Array(repeating: Array(repeating: 0, count: n), count: p) - for i in 0.. Double { return x[size / 2][size / 2] } -let _ = { () -> () in - let n = CommandLine.argc > 1 ? Int(CommandLine.arguments[1])! : 100 +@main +struct Matmul { + static func main() { + let n = CommandLine.argc > 1 ? Int(CommandLine.arguments[1])! : 100 - let left = calc(101) - let right = -18.67 - if abs(left - right) > 0.1 { - fputs("\(left) != \(right)\n", stderr) - exit(1) - } + let left = calc(101) + let right = -18.67 + if abs(left - right) > 0.1 { + fputs("\(left) != \(right)\n", stderr) + exit(EXIT_FAILURE) + } - notify("Swift\t\(getpid())") - let results = calc(n) - notify("stop") + notify("Swift\t\(getpid())") + let results = calc(n) + notify("stop") - print(results) -} () + print(results) + } +}