あらためてSwiftを始めませんか?
本稿を執筆しているのは
本連載はこれまで連載ということもあって、
安全、高速、豊かな表現力
いったいSwiftとはどういう言語なのでしょう? 公式サイトのAbout Swiftには3つの特長が掲げられています。
- 安全
(Safe) - 高速
(Fast) - 豊かな表現力
(Expressive)
Swiftは静的型を採用していますが、var i = 42
でInt
型として初期化されたものにi = "one"
とStringを代入しようとしても、
Getting Started
ではさっそくはじめてみましょう。え、
![図1 Swiftのsandbox 図1 Swiftのsandbox](/assets/images/dev/serial/01/swift-introduction/0022/thumb/TH800_001.png)
もともとはApple製品専用開発言語としてスタートしたSwiftですが、
とはいえ、
演習:言語処理系を実装してみる
では、
![図2 PlaygroundでBrainfuck 図2 PlaygroundでBrainfuck](/assets/images/dev/serial/01/swift-introduction/0022/thumb/TH800_002.png)
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
になった以外同じものが出力されるはずです。
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) - アーキテクチャごとに処理を変えたい場合はどうすればよいか
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 2022年9月号
2022年8月18日発売
B5判/192ページ
定価1,342円
(本体1,220円+税10%)
- 第1特集
MySQL アプリ開発者の必修5科目
不意なトラブルに困らないためのRDB基礎知識 - 第2特集
「知りたい」「使いたい」「発信したい」をかなえる
OSSソースコードリーディングのススメ - 特別企画
企業のシステムを支えるOSとエコシステムの全貌
[特別企画]Red Hat Enterprise Linux 9最新ガイド - 短期連載
今さら聞けないSSH
[前編]リモートログインとコマンドの実行 - 短期連載
MySQLで学ぶ文字コード
[最終回]文字コードのハマりどころTips集 - 短期連載
新生「Ansible」徹底解説
[4]Playbookの実行環境(基礎編)