From 88b66f82aae2d7784002b07bfc7877932da3ec94 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 19 Mar 2023 00:47:11 +0900 Subject: fix(content): fix XML notations --- .../index.html | 36 +++---- .../python-unbound-local-error/index.html | 18 ++-- .../ruby-detect-running-implementation/index.html | 22 ++-- .../ruby-then-keyword-and-case-in/index.html | 82 +++++++-------- .../rust-where-are-primitive-types-from/index.html | 116 ++++++++++----------- .../index.html | 38 +++---- .../vim-swap-order-of-selected-lines/index.html | 86 +++++++-------- 7 files changed, 199 insertions(+), 199 deletions(-) (limited to 'public/posts/2021-10-02') diff --git a/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html b/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html index dc9d084..76806ba 100644 --- a/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html +++ b/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html @@ -9,7 +9,7 @@ 【C++】 属性構文の属性名にはキーワードが使える | REPL: Rest-Eat-Program Loop - + @@ -57,7 +57,7 @@

- この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/94090937bcf860cfa93b + この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/94090937bcf860cfa93b

@@ -66,7 +66,7 @@

- タイトル落ち。まずはこのコードを見て欲しい。 + タイトル落ち。まずはこのコードを見て欲しい。

#include <iostream>
@@ -86,25 +86,25 @@
 [[virtual]] [[void]] [[volatile]] [[wchar_t]] [[while]] [[xor]] [[xor_eq]]
 // [[using]]
 int main() {
-std::cout << "Hello, World!" << std::endl;
+    std::cout << "Hello, World!" << std::endl;
 }

- コンパイラのバージョン $ clang++ –version Apple clang version 11.0.0 (clang-1100.0.33.8) Target: x86_64-apple-darwin19.6.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin + コンパイラのバージョン $ clang++ –version Apple clang version 11.0.0 (clang-1100.0.33.8) Target: x86_64-apple-darwin19.6.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

- コンパイルコマンド (C17指定) $ clang –std=c++17 hoge.cpp + コンパイルコマンド (C17指定) $ clang –std=c++17 hoge.cpp

- この記事から得られるものはこれ以上ないので以下は蛇足になる。 + この記事から得られるものはこれ以上ないので以下は蛇足になる。

- 別件で cppreference.com の identifier のページ を読んでいた時、次の文が目に止まった。 + 別件で cppreference.com の identifier のページ を読んでいた時、次の文が目に止まった。

@@ -121,40 +121,40 @@ std::cout << "Hello, World!" &l

- キーワードでも属性として指定する場合は非キーワードとして使えるらしい。 実際にやってみる。 + キーワードでも属性として指定する場合は非キーワードとして使えるらしい。 実際にやってみる。

- 同サイトの keywords のページ から一覧を拝借し、上のコードが出来上がった (C++17 においてキーワードでないものなど、一部省いている)。 大量の警告 (unknown attribute `〇〇' ignored) がコンパイラから出力されるが、コンパイルできる。 + 同サイトの keywords のページ から一覧を拝借し、上のコードが出来上がった (C++17 においてキーワードでないものなど、一部省いている)。 大量の警告 (unknown attribute `〇〇' ignored) がコンパイラから出力されるが、コンパイルできる。

- 上のコードでは [[using]] をコメントアウトしているが、これは using キーワードのみ属性構文の中で意味を持つからであり、このコメントアウトを外すとコンパイルに失敗する。 + 上のコードでは [[using]] をコメントアウトしているが、これは using キーワードのみ属性構文の中で意味を持つからであり、このコメントアウトを外すとコンパイルに失敗する。

// using の例
 [[using foo: attr1, attr2]] int x; // [[foo::attr1, foo::attr2]] の糖衣構文

- C++17 の仕様も見てみる (正確には標準化前のドラフト)。 + C++17 の仕様も見てみる (正確には標準化前のドラフト)。

- 引用元: https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4 + 引用元: https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4

- If a keyword or an alternative token that satisfies the syntactic requirements of an identifier is contained in an attribute-token, it is considered an identifier. + If a keyword or an alternative token that satisfies the syntactic requirements of an identifier is contained in an attribute-token, it is considered an identifier.

- 「identifier の構文上の要件を満たすキーワードまたは代替トークンが attribute-token に含まれている場合、identifier とみなされる」とある。どうやら間違いないようだ。 + 「identifier の構文上の要件を満たすキーワードまたは代替トークンが attribute-token に含まれている場合、identifier とみなされる」とある。どうやら間違いないようだ。

- ところで、代替トークン (alternative token) とは and (&) や bitor (|) などのことだが、identifier の構文上の要件を満たさないような代替トークンなどあるのか? 疑問に思って調べたところ、代替トークンという語にはダイグラフも含まれるらしい (参考: 同ドラフト) + ところで、代替トークン (alternative token) とは and (&) や bitor (|) などのことだが、identifier の構文上の要件を満たさないような代替トークンなどあるのか? 疑問に思って調べたところ、代替トークンという語にはダイグラフも含まれるらしい (参考: 同ドラフト)

- 「identifier の構文上の要件を満たさないような代替トークン」はこれらが当てはまると思われる。 + 「identifier の構文上の要件を満たさないような代替トークン」はこれらが当てはまると思われる。

- 調べた感想: 字句解析器か構文解析器が辛そう + 調べた感想: 字句解析器か構文解析器が辛そう

diff --git a/public/posts/2021-10-02/python-unbound-local-error/index.html b/public/posts/2021-10-02/python-unbound-local-error/index.html index 5d06a25..fe3b020 100644 --- a/public/posts/2021-10-02/python-unbound-local-error/index.html +++ b/public/posts/2021-10-02/python-unbound-local-error/index.html @@ -9,7 +9,7 @@ 【Python】 クロージャとUnboundLocalError: local variable 'x' referenced before assignment | REPL: Rest-Eat-Program Loop - + @@ -57,7 +57,7 @@

- この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/5d733703afcb35bbf399 + この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/5d733703afcb35bbf399

@@ -66,11 +66,11 @@

- 本記事は Python 3.7.6 の動作結果を元にして書かれている。 + 本記事は Python 3.7.6 の動作結果を元にして書かれている。

- Python でクロージャを作ろうと、次のようなコードを書いた。 + Python でクロージャを作ろうと、次のようなコードを書いた。

def f():
@@ -82,17 +82,17 @@ g()
 f()

- 関数 g から 関数 f のスコープ内で定義された変数 x を参照し、それに 1 を足そうとしている。 これを実行すると x += 1 の箇所でエラーが発生する。 + 関数 g から 関数 f のスコープ内で定義された変数 x を参照し、それに 1 を足そうとしている。 これを実行すると x += 1 の箇所でエラーが発生する。

- UnboundLocalError: local variable `x' referenced before assignment + UnboundLocalError: local variable `x' referenced before assignment

- local変数 x が代入前に参照された、とある。これは、fx を参照するのではなく、新しく別の変数を g 内に作ってしまっているため。 前述のコードを宣言と代入を便宜上分けて書き直すと次のようになる。var を変数宣言のための構文として擬似的に利用している。 + local変数 x が代入前に参照された、とある。これは、fx を参照するのではなく、新しく別の変数を g 内に作ってしまっているため。 前述のコードを宣言と代入を便宜上分けて書き直すと次のようになる。var を変数宣言のための構文として擬似的に利用している。

# 注: var は正しい Python の文法ではない。上記参照のこと
@@ -107,7 +107,7 @@ x += 1      #  x に
 g()

- 当初の意図を表現するには、次のように書けばよい。 + 当初の意図を表現するには、次のように書けばよい。

def f():
@@ -118,7 +118,7 @@ x += 1
 g()

- (*) のように、nonlocal を追加する。これにより一つ外側のスコープ (g の一つ外側 = f) で定義されている x を探しに行くようになる。 + (*) のように、nonlocal を追加する。これにより一つ外側のスコープ (g の一つ外側 = f) で定義されている x を探しに行くようになる。

diff --git a/public/posts/2021-10-02/ruby-detect-running-implementation/index.html b/public/posts/2021-10-02/ruby-detect-running-implementation/index.html index 59bf445..3557c4a 100644 --- a/public/posts/2021-10-02/ruby-detect-running-implementation/index.html +++ b/public/posts/2021-10-02/ruby-detect-running-implementation/index.html @@ -9,7 +9,7 @@ 【Ruby】 自身を実行している処理系の種類を判定する | REPL: Rest-Eat-Program Loop - + @@ -54,7 +54,7 @@

- この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/74d7ffeeebc51b20d791 + この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/74d7ffeeebc51b20d791

@@ -63,19 +63,19 @@

- Ruby という言語には複数の実装があるが、それらをスクリプト上からどのようにして programmatically に見分ければよいだろうか。 + Ruby という言語には複数の実装があるが、それらをスクリプト上からどのようにして programmatically に見分ければよいだろうか。

- Object クラスに定義されている RUBY_ENGINE という定数がこの用途に使える。 + Object クラスに定義されている RUBY_ENGINE という定数がこの用途に使える。

- 参考: Object::RUBY_ENGINE + 参考: Object::RUBY_ENGINE

- 上記ページの例から引用する: + 上記ページの例から引用する:

$ ruby-1.9.1 -ve 'p RUBY_ENGINE'
@@ -86,11 +86,11 @@ jruby 1.2.0 (ruby 1.8.6 patchlevel 287) (2009-03-16 rev 9419) [i386-java]
 "jruby"

- それぞれの処理系がどのような値を返すかだが、stack overflow に良い質問と回答があった。 + それぞれの処理系がどのような値を返すかだが、stack overflow に良い質問と回答があった。

- What values for RUBY_ENGINE correspond to which Ruby implementations? より引用: + What values for RUBY_ENGINE correspond to which Ruby implementations? より引用:

@@ -192,15 +192,15 @@ jruby 1.2.0 (ruby 1.8.6 patchlevel 287) (2009-03-16 rev 9419) [i386-java]

- なお、この質問・回答は 2014年になされたものであり、値は変わっている可能性がある。MRI (aka CRuby) については執筆時現在 (2020/12/8) も 'ruby' が返ってくることを確認済み。 + なお、この質問・回答は 2014年になされたものであり、値は変わっている可能性がある。MRI (aka CRuby) については執筆時現在 (2020/12/8) も 'ruby' が返ってくることを確認済み。

- この表にない主要な処理系として、https://mruby.org[mruby] は 'mruby' を返す。 + この表にない主要な処理系として、https://mruby.org[mruby] は 'mruby' を返す。

- mruby 該当部分のソース より引用: + mruby 該当部分のソース より引用:

/*
diff --git a/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html b/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html
index 31107fc..097d417 100644
--- a/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html
+++ b/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html
@@ -9,7 +9,7 @@
     
     
     【Ruby】 then キーワードと case in | REPL: Rest-Eat-Program Loop
-    
+    
     
   
   
@@ -57,7 +57,7 @@
             
           
           

- この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/787a8cf888a304497223 + この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/787a8cf888a304497223

@@ -68,58 +68,58 @@

TL; DR

- case - in によるパターンマッチング構文でも、case - when と同じように then が使える (場合によっては使う必要がある)。 + case - in によるパターンマッチング構文でも、case - when と同じように then が使える (場合によっては使う必要がある)。

then とは

- 使われることは稀だが、Ruby では then がキーワードになっている。次のように使う: + 使われることは稀だが、Ruby では then がキーワードになっている。次のように使う:

if cond then
   puts "Y"
-  else
+else
   puts "N"
-  end
+end

- このキーワードが現れうる場所はいくつかあり、ifunlessrescuecase 構文がそれに当たる。 上記のように、何か条件を書いた後 then を置き、式がそこで終了していることを示すマーカーとして機能する。 + このキーワードが現れうる場所はいくつかあり、ifunlessrescuecase 構文がそれに当たる。 上記のように、何か条件を書いた後 then を置き、式がそこで終了していることを示すマーカーとして機能する。

# Example:
 
 if x then
-a
+  a
 end
 
 unless x then
-a
+  a
 end
 
 begin
-a
+  a
 rescue then
-b
+  b
 end
 
 case x
 when p then
-a
+  a
 end

なぜ普段は書かなくてもよいのか

- 普通 Ruby のコードで then を書くことはない。なぜか。次のコードを実行してみるとわかる。 + 普通 Ruby のコードで then を書くことはない。なぜか。次のコードを実行してみるとわかる。

if true puts 'Hello, World!' end

- 次のような構文エラーが出力される。 + 次のような構文エラーが出力される。

20:1: syntax error, unexpected local variable or method, expecting `then' or ';' or '\n'
@@ -129,31 +129,31 @@ if true puts 'Hello, World!' end
 ...f true puts 'Hello, World!' end

- 二つ目のメッセージは無視して一つ目を読むと、then; か改行が来るはずのところ変数だかメソッドだかが現れたことによりエラーとなっているようだ。 + 二つ目のメッセージは無視して一つ目を読むと、then; か改行が来るはずのところ変数だかメソッドだかが現れたことによりエラーとなっているようだ。

- ポイントは改行が then (や ;) の代わりとなることである。true の後に改行を入れてみる。 + ポイントは改行が then (や ;) の代わりとなることである。true の後に改行を入れてみる。

if true
 puts 'Hello, World!' end

- 無事 Hello, World! と出力されるようになった。 + 無事 Hello, World! と出力されるようになった。

なぜ then; や改行が必要か

- なぜ then; や改行 (以下 「then 等」) が必要なのだろうか。次の例を見てほしい: + なぜ then; や改行 (以下 「then 等」) が必要なのだろうか。次の例を見てほしい:

if a b end

- then; も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。 この例は二通りに解釈できる。 + then; も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。 この例は二通りに解釈できる。

# a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価
@@ -167,18 +167,18 @@ b
 end

- then 等はこの曖昧性を排除するためにあり、条件式は if から then 等までの間にある、ということを明確にする。 C系の if 後に来る (/) や、Python の :、Rust/Go/Swift などの { も同じ役割を持つ。 + then 等はこの曖昧性を排除するためにあり、条件式は if から then 等までの間にある、ということを明確にする。 C系の if 後に来る (/) や、Python の :、Rust/Go/Swift などの { も同じ役割を持つ。

- Ruby の場合、プログラマーが書きやすいよう改行でもって then が代用できるので、ほとんどの場合 then は必要ない。 + Ruby の場合、プログラマーが書きやすいよう改行でもって then が代用できるので、ほとんどの場合 then は必要ない。

case - in における then

- ようやく本題にたどり着いた。来る Ruby 3.0 では casein キーワードを使ったパターンマッチングの構文が入る予定である。この構文でもパターン部との区切りとして then 等が必要になる。 (現在の) Ruby には formal な形式での文法仕様は存在しないので、yacc の定義ファイルを参照した (yacc の説明は省略)。 + ようやく本題にたどり着いた。来る Ruby 3.0 では casein キーワードを使ったパターンマッチングの構文が入る予定である。この構文でもパターン部との区切りとして then 等が必要になる。 (現在の) Ruby には formal な形式での文法仕様は存在しないので、yacc の定義ファイルを参照した (yacc の説明は省略)。

@@ -186,45 +186,45 @@ b

p_case_body : keyword_in
-  {
+{
   SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
   p->command_start = FALSE;
   $<ctxt>1 = p->ctxt;
   p->ctxt.in_kwarg = 1;
   $<tbl>$ = push_pvtbl(p);
-  }
-  {
+}
+{
   $<tbl>$ = push_pktbl(p);
-  }
-  p_top_expr then
-  {
+}
+p_top_expr then
+{
   pop_pktbl(p, $<tbl>3);
   pop_pvtbl(p, $<tbl>2);
   p->ctxt.in_kwarg = $<ctxt>1.in_kwarg;
-  }
-  compstmt
-  p_cases
-  {
+}
+compstmt
+p_cases
+{
   /*%%%*/
   $$ = NEW_IN($4, $7, $8, &@$);
   /*% %*/
   /*% ripper: in!($4, $7, escape_Qundef($8)) %*/
-  }
-  ;
+} +;

- 簡略版: + 簡略版:

p_case_body : keyword_in p_top_expr then compstmt p_cases
 ;

- ここで、keyword_in は文字通り inp_top_expr はいわゆるパターン、thenthen キーワードのことではなく、この記事で then 等と呼んでいるもの、つまり then キーワード、;、改行のいずれかである。 + ここで、keyword_in は文字通り inp_top_expr はいわゆるパターン、thenthen キーワードのことではなく、この記事で then 等と呼んでいるもの、つまり then キーワード、;、改行のいずれかである。

- これにより、case - when による従来の構文と同じように、then 等をパターンの後ろに挿入すればよいことがわかった。つまり次の3通りのいずれかになる: + これにより、case - when による従来の構文と同じように、then 等をパターンの後ろに挿入すればよいことがわかった。つまり次の3通りのいずれかになる:

case x
@@ -235,11 +235,11 @@ b
 
 case x
 in 1
-a
+  a
 in 2
-b
+  b
 in 3
-c
+  c
 end
 
 case x
@@ -249,7 +249,7 @@ c
 end

- ところで、p_top_expr には if による guard clause が書けるので、その場合は if - then と似たような見た目になる。 + ところで、p_top_expr には if による guard clause が書けるので、その場合は if - then と似たような見た目になる。

case x
diff --git a/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html b/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
index 5bb46a0..9e77a85 100644
--- a/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
+++ b/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
@@ -9,7 +9,7 @@
     
     
     Rust のプリミティブ型はどこからやって来るか | REPL: Rest-Eat-Program Loop
-    
+    
     
   
   
@@ -54,7 +54,7 @@
             
           

- この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/9a429432258bbcd6c565 + この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/9a429432258bbcd6c565

@@ -65,7 +65,7 @@

前置き

- Rust において、プリミティブ型の名前は予約語でない。したがって、次のコードは合法である。 + Rust において、プリミティブ型の名前は予約語でない。したがって、次のコードは合法である。

#![allow(non_camel_case_types)]
@@ -90,12 +90,12 @@
 struct str;

- では、普段単に bool と書いたとき、この bool は一体どこから来ているのか。rustc のソースを追ってみた。 + では、普段単に bool と書いたとき、この bool は一体どこから来ているのか。rustc のソースを追ってみた。

- 前提知識: 一般的なコンパイラの構造、用語。rustc そのものの知識は不要 (というよりも筆者自身がよく知らない) + 前提知識: 一般的なコンパイラの構造、用語。rustc そのものの知識は不要 (というよりも筆者自身がよく知らない)

@@ -103,7 +103,7 @@

調査

- 調査に使用したソース (調査時点での最新 master) + 調査に使用したソース (調査時点での最新 master)

@@ -111,15 +111,15 @@

- どのようにして調べるか。rustc の構造には詳しくないため、すぐに当たりをつけるのは難しい。 + どのようにして調べるか。rustc の構造には詳しくないため、すぐに当たりをつけるのは難しい。

- 大雑把な構造としては、compiler フォルダ以下に rustc_* という名前のクレートが数十個入っている。これがどうやら rustc コマンドの実装部のようだ。 + 大雑把な構造としては、compiler フォルダ以下に rustc_* という名前のクレートが数十個入っている。これがどうやら rustc コマンドの実装部のようだ。

- rustc はセルフホストされている (= rustc 自身が Rust で書かれている) ので、boolchar などで適当に検索をかけてもノイズが多すぎて話にならない。 しかし、お誂え向きなことに i128/u128 というコンパイラ自身が使うことがなさそうな型が存在するのでこれを使って git grep してみる。 + rustc はセルフホストされている (= rustc 自身が Rust で書かれている) ので、boolchar などで適当に検索をかけてもノイズが多すぎて話にならない。 しかし、お誂え向きなことに i128/u128 というコンパイラ自身が使うことがなさそうな型が存在するのでこれを使って git grep してみる。

$ git grep "\bi128\b" | wc      # i128
@@ -132,7 +132,7 @@ $ git grep "\bbool\b" | wc      # cf. bool の結果
 3563   23577  294659

- 165 程度であれば探すことができそうだ。今回は、クレート名を見ておおよその当たりをつけた。 + 165 程度であれば探すことができそうだ。今回は、クレート名を見ておおよその当たりをつけた。

$ git grep "\bi128\b"
@@ -141,7 +141,7 @@ rustc_resolve/src/lib.rs:        table.insert(sym::i128, Int(IntTy::I128));
 ...

- rustc_resolve というのはいかにも名前解決を担いそうなクレート名である。該当箇所を見てみる。 + rustc_resolve というのはいかにも名前解決を担いそうなクレート名である。該当箇所を見てみる。

/// Interns the names of the primitive types.
@@ -149,84 +149,84 @@ rustc_resolve/src/lib.rs:        table.insert(sym::i128, Int(IntTy::I128));
 /// All other types are defined somewhere and possibly imported, but the primitive ones need
 /// special handling, since they have no place of origin.
 struct PrimitiveTypeTable {
-primitive_types: FxHashMap<Symbol, PrimTy>,
+    primitive_types: FxHashMap<Symbol, PrimTy>,
 }
 
 impl PrimitiveTypeTable {
-fn new() -> PrimitiveTypeTable {
-let mut table = FxHashMap::default();
+    fn new() -> PrimitiveTypeTable {
+        let mut table = FxHashMap::default();
 
-table.insert(sym::bool, Bool);
-table.insert(sym::char, Char);
-table.insert(sym::f32, Float(FloatTy::F32));
-table.insert(sym::f64, Float(FloatTy::F64));
-table.insert(sym::isize, Int(IntTy::Isize));
-table.insert(sym::i8, Int(IntTy::I8));
-table.insert(sym::i16, Int(IntTy::I16));
-table.insert(sym::i32, Int(IntTy::I32));
-table.insert(sym::i64, Int(IntTy::I64));
-table.insert(sym::i128, Int(IntTy::I128));
-table.insert(sym::str, Str);
-table.insert(sym::usize, Uint(UintTy::Usize));
-table.insert(sym::u8, Uint(UintTy::U8));
-table.insert(sym::u16, Uint(UintTy::U16));
-table.insert(sym::u32, Uint(UintTy::U32));
-table.insert(sym::u64, Uint(UintTy::U64));
-table.insert(sym::u128, Uint(UintTy::U128));
-Self { primitive_types: table }
-}
+        table.insert(sym::bool, Bool);
+        table.insert(sym::char, Char);
+        table.insert(sym::f32, Float(FloatTy::F32));
+        table.insert(sym::f64, Float(FloatTy::F64));
+        table.insert(sym::isize, Int(IntTy::Isize));
+        table.insert(sym::i8, Int(IntTy::I8));
+        table.insert(sym::i16, Int(IntTy::I16));
+        table.insert(sym::i32, Int(IntTy::I32));
+        table.insert(sym::i64, Int(IntTy::I64));
+        table.insert(sym::i128, Int(IntTy::I128));
+        table.insert(sym::str, Str);
+        table.insert(sym::usize, Uint(UintTy::Usize));
+        table.insert(sym::u8, Uint(UintTy::U8));
+        table.insert(sym::u16, Uint(UintTy::U16));
+        table.insert(sym::u32, Uint(UintTy::U32));
+        table.insert(sym::u64, Uint(UintTy::U64));
+        table.insert(sym::u128, Uint(UintTy::U128));
+        Self { primitive_types: table }
+    }
 }

- これは初めに列挙したプリミティブ型の一覧と一致している。doc comment にも、 + これは初めに列挙したプリミティブ型の一覧と一致している。doc comment にも、

- All other types are defined somewhere and possibly imported, but the primitive ones need special handling, since they have no place of origin. + All other types are defined somewhere and possibly imported, but the primitive ones need special handling, since they have no place of origin.

- とある。次はこの struct の使用箇所を追う。追うと言っても使われている箇所は次の一箇所しかない。なお説明に不要な箇所は大きく削っている。 + とある。次はこの struct の使用箇所を追う。追うと言っても使われている箇所は次の一箇所しかない。なお説明に不要な箇所は大きく削っている。

-
    /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
+            
/// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
 /// (略)
 fn resolve_ident_in_lexical_scope(
-&mut self,
-mut ident: Ident,
-ns: Namespace,
-// (略)
+    &mut self,
+    mut ident: Ident,
+    ns: Namespace,
+    // (略)
 ) -> Option<LexicalScopeBinding<'a>> {
-// (略)
+    // (略)
 
-if ns == TypeNS {
-if let Some(prim_ty) = self.primitive_type_table.primitive_types.get(&ident.name) {
-let binding =
-(Res::PrimTy(*prim_ty), ty::Visibility::Public, DUMMY_SP, ExpnId::root())
-.to_name_binding(self.arenas);
-return Some(LexicalScopeBinding::Item(binding));
-}
-}
+    if ns == TypeNS {
+        if let Some(prim_ty) = self.primitive_type_table.primitive_types.get(&ident.name) {
+            let binding =
+                (Res::PrimTy(*prim_ty), ty::Visibility::Public, DUMMY_SP, ExpnId::root())
+                  .to_name_binding(self.arenas);
+            return Some(LexicalScopeBinding::Item(binding));
+        }
+    }
 
-None
+    None
 }

- 関数名や doc comment が示している通り、この関数は識別子 (identifier, ident) を現在のレキシカルスコープ内で解決 (resolve) する。 if ns == TypeNS のブロック内では、primitive_type_table (上記の PrimitiveTypeTable::new() で作られた変数) に含まれている識別子 (booli32 など) かどうか判定し、そうであればそれに紐づけられたプリミティブ型を返している。 + 関数名や doc comment が示している通り、この関数は識別子 (identifier, ident) を現在のレキシカルスコープ内で解決 (resolve) する。 if ns == TypeNS のブロック内では、primitive_type_table (上記の PrimitiveTypeTable::new() で作られた変数) に含まれている識別子 (booli32 など) かどうか判定し、そうであればそれに紐づけられたプリミティブ型を返している。

- なお、ns は「名前空間」を示す変数である。Rust における名前空間はC言語におけるそれとほとんど同じで、今探している名前が関数名/変数名なのか型なのかマクロなのかを区別している。この if は、プリミティブ型に解決されるのは型を探しているときだけだ、と言っている。 + なお、ns は「名前空間」を示す変数である。Rust における名前空間はC言語におけるそれとほとんど同じで、今探している名前が関数名/変数名なのか型なのかマクロなのかを区別している。この if は、プリミティブ型に解決されるのは型を探しているときだけだ、と言っている。

- 重要なのは、これが resolve_ident_in_lexical_scope() の最後に書かれている点である。つまり、最初に挙げたプリミティブ型の識別子は、「名前解決の最終段階で」、「他に同名の型が見つかっていなければ」プリミティブ型として解決される。 + 重要なのは、これが resolve_ident_in_lexical_scope() の最後に書かれている点である。つまり、最初に挙げたプリミティブ型の識別子は、「名前解決の最終段階で」、「他に同名の型が見つかっていなければ」プリミティブ型として解決される。

- 動作がわかったところで、例として次のコードを考える。 + 動作がわかったところで、例として次のコードを考える。

#![allow(non_camel_case_types)]
@@ -234,18 +234,18 @@ ns: Namespace,
 struct bool;
 
 fn main() {
-let _: bool = bool;
+    let _: bool = bool;
 }

- ここで main()boolstruct bool として解決される。なぜなら、プリミティブ型の判定をする前に bool という名前の別の型が見つかるからだ。 + ここで main()boolstruct bool として解決される。なぜなら、プリミティブ型の判定をする前に bool という名前の別の型が見つかるからだ。

まとめ

- Rust のプリミティブ型は予約語ではない。名前解決の最終段階で特別扱いされ、他に同名の型が見つかっていなければ対応するプリミティブ型に解決される。 + Rust のプリミティブ型は予約語ではない。名前解決の最終段階で特別扱いされ、他に同名の型が見つかっていなければ対応するプリミティブ型に解決される。

diff --git a/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html b/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html index 3c6342b..44ee689 100644 --- a/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html +++ b/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html @@ -9,7 +9,7 @@ 【Vim】 autocmd events の BufWrite/BufWritePre の違い | REPL: Rest-Eat-Program Loop - + @@ -54,7 +54,7 @@

- この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/79ab4db8564032de0b25 + この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/79ab4db8564032de0b25

@@ -65,14 +65,14 @@

TL; DR

- 違いはない。ただのエイリアス。 + 違いはない。ただのエイリアス。

調査記録

- Vim の autocmd events には似通った名前のものがいくつかある。大抵は :help に説明があるが、この記事のタイトルにある2つを含めた以下のイベントには、その違いについて説明がない。 + Vim の autocmd events には似通った名前のものがいくつかある。大抵は :help に説明があるが、この記事のタイトルにある2つを含めた以下のイベントには、その違いについて説明がない。

    @@ -90,43 +90,43 @@

- このうち、BufAdd/BufCreate に関しては、:help BufCreate に + このうち、BufAdd/BufCreate に関しては、:help BufCreate

- The BufCreate event is for historic reasons. + The BufCreate event is for historic reasons.

- とあり、おそらくは BufAdd のエイリアスであろうということがわかる。他の2組も同様ではないかと予想されるが、確認のため vim と neovim のソースコードを調査した。 + とあり、おそらくは BufAdd のエイリアスであろうということがわかる。他の2組も同様ではないかと予想されるが、確認のため vim と neovim のソースコードを調査した。

- ソースコードへのリンク vim (調査時点での master branch) neovim (上に同じ) + ソースコードへのリンク vim (調査時点での master branch) neovim (上に同じ)

vim のソースコード

- 以下は、autocmd events の名前と内部で使われている整数値とのマッピングを定義している箇所である。見ての通り、上でエイリアスではないかと述べた3組には、それぞれ同じ内部値が使われている。 + 以下は、autocmd events の名前と内部で使われている整数値とのマッピングを定義している箇所である。見ての通り、上でエイリアスではないかと述べた3組には、それぞれ同じ内部値が使われている。

https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L85-L86

-
    {"BufAdd",      EVENT_BUFADD},
+              
{"BufAdd",      EVENT_BUFADD},
 {"BufCreate",   EVENT_BUFADD},

https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L95-L97

-
    {"BufRead",     EVENT_BUFREADPOST},
+              
{"BufRead",     EVENT_BUFREADPOST},
 {"BufReadCmd",  EVENT_BUFREADCMD},
 {"BufReadPost", EVENT_BUFREADPOST},
@@ -134,7 +134,7 @@ https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L103-L105

-
    {"BufWrite",    EVENT_BUFWRITEPRE},
+              
{"BufWrite",    EVENT_BUFWRITEPRE},
 {"BufWritePost",    EVENT_BUFWRITEPOST},
 {"BufWritePre", EVENT_BUFWRITEPRE},
@@ -142,14 +142,14 @@

neovim のソースコード

- neovim の場合でも同様のマッピングが定義されているが、こちらの場合は Lua で書かれている。以下にある通り、はっきり aliases と書かれている。 + neovim の場合でも同様のマッピングが定義されているが、こちらの場合は Lua で書かれている。以下にある通り、はっきり aliases と書かれている。

https://github.com/neovim/neovim/blob/71d4f5851f068eeb432af34850dddda8cc1c71e3/src/nvim/auevents.lua#L119-L124

-
  aliases = {
+              
aliases = {
 BufCreate = 'BufAdd',
 BufRead = 'BufReadPost',
 BufWrite = 'BufWritePre',
@@ -157,18 +157,18 @@ FileEncoding = 'EncodingChanged',
 },

- ところで、上では取り上げなかった FileEncoding だが、これは :help FileEncoding にしっかりと書いてある。 + ところで、上では取り上げなかった FileEncoding だが、これは :help FileEncoding にしっかりと書いてある。

                                                           *FileEncoding*
-FileEncoding                    Obsolete.  It still works and is equivalent
-to |EncodingChanged|.
+ FileEncoding Obsolete. It still works and is equivalent + to |EncodingChanged|.

まとめ

- 記事タイトルについて言えば、どちらも変わらないので好きな方を使えばよい。あえて言えば、次のようになるだろう。 + 記事タイトルについて言えば、どちらも変わらないので好きな方を使えばよい。あえて言えば、次のようになるだろう。

    @@ -210,7 +210,7 @@ to |EncodingChanged|.

- ところでこの調査で知ったのだが、BufReadBufWrite は上にある通り発火するタイミングが「後」と「前」で対称性がない。可能なら Pre/Post 付きのものを使った方が分かりやすいだろう。 + ところでこの調査で知ったのだが、BufReadBufWrite は上にある通り発火するタイミングが「後」と「前」で対称性がない。可能なら Pre/Post 付きのものを使った方が分かりやすいだろう。

diff --git a/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html b/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html index 48b57ac..6b9e423 100644 --- a/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html +++ b/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html @@ -9,7 +9,7 @@ Vimで選択した行の順番を入れ替える | REPL: Rest-Eat-Program Loop - + @@ -54,7 +54,7 @@

- この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/4fefb361d9a693803520 + この記事は Qiita から移植してきたものです。 元 URL: https://qiita.com/nsfisis/items/4fefb361d9a693803520

@@ -65,12 +65,12 @@

バージョン情報

- :version の一部 + :version の一部

- VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Jan 26 2020 11:30:30) macOS version Included patches: 1-148 Huge version without GUI. + VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Jan 26 2020 11:30:30) macOS version Included patches: 1-148 Huge version without GUI.

@@ -80,60 +80,60 @@

tac / tail

- tactail -r などの外部コマンドを ! を使って呼び出し、置き換える。 + tactail -r などの外部コマンドを ! を使って呼び出し、置き換える。

- :h v_! + :h v_!

- tac コマンドや tail-r オプションは環境によって利用できないことがあり、複数の環境を行き来する場合に採用しづらい + tac コマンドや tail-r オプションは環境によって利用できないことがあり、複数の環境を行き来する場合に採用しづらい

:g/^/m0

- こちらは外部コマンドに頼らず、Vim の機能のみを使う。g:global コマンドの、m:move コマンドの略 + こちらは外部コマンドに頼らず、Vim の機能のみを使う。g:global コマンドの、m:move コマンドの略

- :global コマンドは :[range]global/{pattern}/[command] のように使い、[range] で指定された範囲の行のうち、{pattern} で指定された検索パターンにマッチする行に対して、順番に [command] で指定された Ex コマンドを呼び出す。 + :global コマンドは :[range]global/{pattern}/[command] のように使い、[range] で指定された範囲の行のうち、{pattern} で指定された検索パターンにマッチする行に対して、順番に [command] で指定された Ex コマンドを呼び出す。

- :h :global + :h :global

- :move コマンドは [range]:move {address} のように使い、[range] で指定された範囲の行を {address} で指定された位置に移動させる。 + :move コマンドは [range]:move {address} のように使い、[range] で指定された範囲の行を {address} で指定された位置に移動させる。

- :h :move + :h :move

- :g/^/m0 のように組み合わせると、「すべての行を1行ずつ 0行目(1行目の上)に動かす」という動きをする。これは確かに行の入れ替えになっている。 + :g/^/m0 のように組み合わせると、「すべての行を1行ずつ 0行目(1行目の上)に動かす」という動きをする。これは確かに行の入れ替えになっている。

- なお、:g/^/m0 は全ての行を入れ替えるが、:N,Mg/^/mN-1 とすることで N行目から M行目を処理範囲とするよう拡張できる。手でこれを入力するわけにはいかないので、次のようなコマンドを用意する。 + なお、:g/^/m0 は全ての行を入れ替えるが、:N,Mg/^/mN-1 とすることで N行目から M行目を処理範囲とするよう拡張できる。手でこれを入力するわけにはいかないので、次のようなコマンドを用意する。

command! -bar -range=%
-\ Reverse
-\ <line1>,<line2>g/^/m<line1>-1
+ \ Reverse + \ <line1>,<line2>g/^/m<line1>-1

- これは望みの動作をするが、実際に実行してみると全行がハイライトされてしまう。次節で詳細を述べる。 + これは望みの動作をするが、実際に実行してみると全行がハイライトされてしまう。次節で詳細を述べる。

@@ -141,12 +141,12 @@

:g/^/m0 の問題点

- :global コマンドは各行に対してマッチングを行う際、現在の検索パターンを上書きしてしまう。^ は行の先頭にマッチするため、結果として全ての行がハイライトされてしまう。'hlsearch' オプションを無効にしている場合その限りではないが、その場合でも直前の検索パターンが失われてしまうと n コマンドなどの際に不便である。 + :global コマンドは各行に対してマッチングを行う際、現在の検索パターンを上書きしてしまう。^ は行の先頭にマッチするため、結果として全ての行がハイライトされてしまう。'hlsearch' オプションを無効にしている場合その限りではないが、その場合でも直前の検索パターンが失われてしまうと n コマンドなどの際に不便である。

- :h @/ + :h @/

@@ -155,60 +155,60 @@

解決策

- [2020/9/28追記] より簡潔な方法を見つけたので次節に追記した + [2020/9/28追記] より簡潔な方法を見つけたので次節に追記した

- 前述した :Reverse コマンドの定義を少し変えて、次のようにする: + 前述した :Reverse コマンドの定義を少し変えて、次のようにする:

function! s:reverse_lines(from, to) abort
-  execute printf("%d,%dg/^/m%d", a:from, a:to, a:from - 1)
-  endfunction
+    execute printf("%d,%dg/^/m%d", a:from, a:to, a:from - 1)
+endfunction
 
-  command! -bar -range=%
-  \ Reverse
-  \ call <SID>reverse_lines(<line1>, <line2>)
+command! -bar -range=% + \ Reverse + \ call <SID>reverse_lines(<line1>, <line2>)

- 実行しているコマンドが変わったわけではないが、関数呼び出しを経由するようにした。これだけで前述の問題が解決する。 + 実行しているコマンドが変わったわけではないが、関数呼び出しを経由するようにした。これだけで前述の問題が解決する。

- この理由は、ユーザー定義関数を実行する際は検索パターンが一度保存され、実行が終了したあと復元されるため。結果として検索パターンが ^ で上書きされることがなくなる。 + この理由は、ユーザー定義関数を実行する際は検索パターンが一度保存され、実行が終了したあと復元されるため。結果として検索パターンが ^ で上書きされることがなくなる。

- Vim のヘルプから該当箇所を引用する (強調は筆者による)。 + Vim のヘルプから該当箇所を引用する (強調は筆者による)。

- :h autocmd-searchpat + :h autocmd-searchpat

- Autocommands do not change the current search patterns. Vim saves the current search patterns before executing autocommands then restores them after the autocommands finish. This means that autocommands do not affect the strings highlighted with the `hlsearch' option. + Autocommands do not change the current search patterns. Vim saves the current search patterns before executing autocommands then restores them after the autocommands finish. This means that autocommands do not affect the strings highlighted with the `hlsearch' option.

- これは autocommand の実行に関しての記述だが、これと同じことがユーザー定義関数の実行時にも適用される。このことは :nohlsearch のヘルプにある。同じく該当箇所を引用する (強調は筆者による)。 + これは autocommand の実行に関しての記述だが、これと同じことがユーザー定義関数の実行時にも適用される。このことは :nohlsearch のヘルプにある。同じく該当箇所を引用する (強調は筆者による)。

- :h :nohlsearch + :h :nohlsearch

- (略) This command doesn’t work in an autocommand, because the highlighting state is saved and restored when executing autocommands |autocmd-searchpat|. Same thing for when invoking a user function. + (略) This command doesn’t work in an autocommand, because the highlighting state is saved and restored when executing autocommands |autocmd-searchpat|. Same thing for when invoking a user function.

- この仕様により、:g/^/m0 の呼び出しをユーザー定義関数に切り出すことで上述の問題を解決できる。 + この仕様により、:g/^/m0 の呼び出しをユーザー定義関数に切り出すことで上述の問題を解決できる。

@@ -216,21 +216,21 @@

解決策 (改訂版)

- [2020/9/28追記] より簡潔な方法を見つけたため追記する + [2020/9/28追記] より簡潔な方法を見つけたため追記する

command! -bar -range=%
-  \ Reverse
-  \ keeppatterns <line1>,<line2>g/^/m<line1>-1
+ \ Reverse + \ keeppatterns <line1>,<line2>g/^/m<line1>-1

- まさにこのための Exコマンド、:keeppatterns が存在する。:keeppatterns {command} のように使い、読んで字の如く、後ろに続く Exコマンドを「現在の検索パターンを保ったまま」実行する。はるかに分かりやすく意図を表現できる。 + まさにこのための Exコマンド、:keeppatterns が存在する。:keeppatterns {command} のように使い、読んで字の如く、後ろに続く Exコマンドを「現在の検索パターンを保ったまま」実行する。はるかに分かりやすく意図を表現できる。

- :h :keeppatterns + :h :keeppatterns

@@ -239,9 +239,9 @@

コピペ用再掲

" License: Public Domain
 
-  command! -bar -range=%
-  \ Reverse
-  \ keeppatterns <line1>,<line2>g/^/m<line1>-1
+command! -bar -range=% + \ Reverse + \ keeppatterns <line1>,<line2>g/^/m<line1>-1 -- cgit v1.2.3-70-g09d2