書いて覚えるSwift入門
第22回 謹賀新言語
あらためてSwiftを始めませんか?
本稿を執筆しているのは
本連載はこれまで連載ということもあって,
安全, 高速, 豊かな表現力
いったいSwiftとはどういう言語なのでしょう? 公式サイトのAbout Swiftには3つの特長が掲げられています。
- 安全
(Safe) - 高速
(Fast) - 豊かな表現力
(Expressive)
Swiftは静的型を採用していますが,var i = 42
でInt
型として初期化されたものにi = "one"
とStringを代入しようとしても,
Getting Started
ではさっそくはじめてみましょう。え,
もともとはApple製品専用開発言語としてスタートしたSwiftですが,
とはいえ,
演習:言語処理系を実装してみる
では,
リスト1 brainfuck.
let datasize = 65536
var framework = "Darwin"
#if os(Linux)
framework = "Glibc"
#endif
let bf2swift:[Character:String] = [
">": "sp += 1",
"<": "sp -= 1",
"+": "data[sp] += 1",
"-": "data[sp] -= 1",
"[": "while data[sp] != CChar(0) {",
"]": "}",
".": "putchar(Int32(data[sp]))",
",": "data[sp] = {c in CChar(c < 0 ? 0 : c)}
(getchar())"
]
func bf2swift(src:String) -> String {
var lines = [
"import \(framework)",
"var data = [CChar](repeating:CChar(0),count:ュ
¥(datasize))",
"var (sp, pc) = (0, 0)",
]
for c in src.characters {
if let l = bf2swift[c] {
lines.append(l)
}
}
lines.append("")
return lines.joined(separator: "¥n")
}
extension String {
func bfCompile()->String {
return bf2swift(src: self)
}
}
let src = "+[,<>.]-"
print(src.bfCompile())
リスト1を実行してみると,Darwin
がGlibc
になった以外同じものが出力されるはずです。
図3 brainfuck.
import Darwin var data = [CChar](repeating:CChar(0), count:65536) var (sp, pc) = (0, 0) data[sp] += 1 while data[sp] != CChar(0) { data[sp] = {c in CChar(c < 0 ? 0 : c)}(getchar()) sp -= 1 sp += 1 putchar(Int32(data[sp])) } data[sp] -= 1
これをたとえばecho.
というテキストファイルにセーブしたうえで,
$ swiftc echo.swift $ ./echo < echo.swift
echo.
の中身がそのまま出力されれば成功です。
では処理系中の最後から2番目のsrc
を+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.
にしたうえで,Hello, world!
と表示されましたか?
それではあらためて処理系のソースコードを見てみましょう。こんな小さなコードからでも,
- 変数
( var
)や定数 ( let
)を定義するにはどうすればよいか - 文字列中に変数を展開
(interpolate) するにはどうすればよいか - 型を指定すればどうなるか
- →指定しない場合はどうなるか?
- →
bf2swift:[Character:String]
の:[Character:String]
を消したらどんなエラーが出るか
- 辞書
(Dictionary) をどう初期化してどう使うか - 配列
(Array) をどう初期化してどう使うか - 文字列を1文字ごとに処理するにはどうすればよいか
- 既存のデータ型
(String) にメソッドを追加するにはどうすればよいか (extension) - アーキテクチャごとに処理を変えたい場合はどうすればよいか
(#if)
表1 CとSwift実装比較
BF | C | Swift |
---|---|---|
> | sp++; | sp += 1 |
< | sp--; | sp -= 1 |
+ | data[sp]++; | data[sp] += 1 |
- | data[sp]-- | data[sp] -= 1 |
[ | while(data[sp]){ | while data[sp] != CChar(0) { |
] | } | } |
. | putchar(data[sp]) | putchar(Int32(data[sp])) |
, | data[sp] = getchar() | data[sp] = {c in CChar(c < 0 ? 0 : c)}(getchar()) |
※ BF:Brainfuck
余裕があったら,
- BrainfuckにはBrainfuck自身で書かれた処理系が存在するが,
その処理系を本処理系で生成してみる - 現状ソースコード中の
src
にハードコードされたBrainfuckコードではなく,任意のソースファイルをコンパイルできるようにしてみる - Swift処理系をBrainfuckで実装してみる
最後はさすがに冗談ですが,
では,
本誌最新号をチェック!
Software Design 2021年4月号
2021年3月18日発売
B5判/192ページ
定価1,342円
(本体1,220円+税10%)
- 第1特集
正しく説明できますか? ps,ls -lの出力,sudoの意味
新人教育に役立つLinux総復習 - 第2特集
実務に活かせるSSL/TLS入門
基本からおさらい,Let's Encryptで実践 - 特別企画
世界で戦うプログラマーになる!
アルゴリズム系プログラミングコンテスト大全