Before LISPs Just Part of the Past ~#13 Reader pub~

35
Before LISPs Just Part of the Past #13 reader

Transcript of Before LISPs Just Part of the Past ~#13 Reader pub~

BeforeLISPs

Just Part of the Past

〜 #13 reader 〜

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築 ()

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

alphabetic[2]なConstituent Symbol Tokenの構築を開始

()

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

alphabetic[2]なConstituent Symbol Tokenの要素

()

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

alphabetic[2]なConstituent Symbol Tokenの要素

()

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

alphabetic[2]なConstituent Symbol Tokenの要素

()

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

alphadigitなConstituent Symbol Tokenの要素

()

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

whitespace[2] Tokenの区切り

(PRIN1)

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

Macro Character READの返した値をQUOTEする

(PRIN1)

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

Macro Character READの返した値をQUOTEする

(PRIN1)

()Macro Character READを用いたList構築

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

Macro Character READの返した値をQUOTEする

Single Escape: 次の文字を

alphabetic[2]なConstituentにする

(PRIN1)

()Macro Character READを用いたList構築

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

Macro Character READの返した値をQUOTEする

alphabetic[2]なConstituent Symbol Tokenの構築を開始

(PRIN1)

()Macro Character READを用いたList構築

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

Macro Character READの返した値をQUOTEする

alphabetic[2]なConstituent Symbol Tokenの要素

(PRIN1)

()Macro Character READを用いたList構築

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

Macro Character READの返した値をQUOTEする

Macro Character READを用いたList構築

whitespace[2]: Tokenの区切り

(PRIN1)

(| X|)

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

Macro Character READの返した値をQUOTEする

Macro Character READを用いたList構築

alphabetic[2]なConstituent Symbol Tokenの構築を開始

(PRIN1)

(| X|)

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

Macro Character READの返した値をQUOTEする

Macro Character READを用いたList構築

Listの終端

(PRIN1)

(| X| Y)

readerことはじめ

)( p r i n 1 ' ( \ x y )

Macro Character: 設定された関数を呼び出す

READを用いたList構築

Listの終端

(PRIN1 (QUOTE (| X| Y))

Motivation

区切りとして機能する文字は?

Motivation

入力しちゃいけない

文字は?

Motivation

Symbolにアクセスする方法のすべては?

Syntax Types

● macro character● constituent● single escape, multiple escape● whitespace[2]● invalid

Macro Character● READ中に発見されると関数が呼び出される● Terminating

– Tokenの区切り文字になる– ex) x'y

● Non-Terminating– Token構築中に発見されるとConstituent– ex) x#y

Constituent

● Tokenの構成要素– symbolと数

● READ中に発見されるとTokenの構築を開始する

● Token構築中に発見された場合の振る舞いはConstituent Traitで決まる

Constituent Traits

● alphabetic[2]● dot● package marker● invalid

● alphadigit● digit● plus sign● minus sign● decimal point● ratio marker● exponent marker

Constituent Traits

● alphabetic[2]● dot● package marker● invalid

● alphadigit● digit● plus sign● minus sign● decimal point● ratio marker● exponent marker

数トークンに使用

Constituent Traits

● alphabetic[2]● dot● package marker● invalid

● alphadigit● digit● plus sign● minus sign● decimal point● ratio marker● exponent markerreader macroで

再現できない

Escape● Traitがalphabetic[2]であるようなConstituent Characterに変更する

● caseの変更を抑止● 'x\ y ; => X Y● '|x y| ; => |x y|● Reader macroでは再現できない

whitespace[2]● 区切り文字の一種

– Token構築中ならTokenの区切り– それ以外なら単に無視される

● Terminating Macro Characterとして実装可能

(set-macro-character #\$ (lambda (stream c) (values)))

invalid● READ中に出現するとエラー

– (read-from-string (string #\Rubout)) ; Error– (char (symbol-name (read-from-string (concatenate 'string "x\\" (string #\Rubout)))) 1); => #\Rubout

– (set-macro-character #\Space #'identity t)– (read-from-string "a b") ; Error

● Terminating Macro Characterとして実装可能● (set-macro-character #\$ (lambda (stream n) (error 'reader-error :stream stream))

もっとreader macroを● 文字列からsource codeを構築する際の問題はreader macroで対処すべき– INTERNが早すぎるとか– read中にreaderの挙動を変えたいとか

● *READ-BASE*● *READTABLE*● *PACKAGE*● etc.

名前の使用を制限する ● (defparameter *sandbox* (copy-readtable nil))

– (copy-readtable)は不適切● (set-macro-character #\: (lambda (stream c) (values)) nil *sandbox*)

● (defpackage :void)● (let ((*package* (find-package :void)) (*readtable* *sandbox*)) (eval (read stream)))

INTERNしないREAD● Tokenの代わりにその元になる文字列を返す

– cf) *READ-SUPRRESS*● (read (subread stream)) == (read stream)● 区切り文字

– whitespace[2]● #\Tab, #\Newline, #\Linefeed, #\Page, #\Return, #\Space

– Terminating Macro Character– (invalid)

● Terminating Macro Characterを効率的に列挙する方法が必要– 特にBASE-CHAR以外の文字

Mismatches● Syntax TypeおよびConstituent Traitの自由な変更

– (sb-impl::set-cat-entry #\$ sb-impl::+char-attr-whitespace+ *sandbox*)

– SBCLでは、Syntax TypeとConstituent TraitはどちらもCharacter attribute

– SET-CAT-ENTRYはBASE-CHAR以外はグローバルに変更する● alphadigitはpredecessorを指定する

Mismatches● reader macroでの読み込み履歴へのアクセス

– package markerやEscapeなど、マクロ文字が実装できる● Syntax typeのinvalid

– Constituentとすべき● Constituent Traitのalphadigit

– digit, alphabeticで良いのでは– Tokenの読み込み開始時に決定しているかどうかで分けているのかも

misc

● cl-user::(print 1)– SBCL拡張

● 外から来たファイルをREAD-EVALしたいならもうちょっと考察がいる

– #.の抑制、NILの扱い、など