Archive for the ‘syntax’ Tag

newLISP 組込関数の構文表示2...または、command-event を使って見る

 昨日の組込関数構文表示は如何でしょうか?
 関数primitivessyntax を作ったのは、こちらのフォーラムの投稿を見たからです。
 この問題は、以前から話題になっていて、すでに解決案が多数提案されてます。
 とくに、こちらで紹介されている関数は、正規表現だけでエレガントに構文を取り出しています
 わざわざ作るまでもない?
 そうとも言えますが、私が使うには、ちょっと足りない点があったからです。
 一つは、関数primitives のように組込関数を表示する仕組みが無いこと。と言っても、探せば、あるかもしれません、、、(汗)
 もう一つは、

> (syntax reverse)
reverse !
syntax: (reverse list)

syntax: (reverse string)
> (syntax char)
char utf8
syntax: (char str [int-index])
syntax: (char int)

 こんな風に、破壊的関数や文字列単位操作の関数を表示をさせたかったこと。
 それに、関数内容の一部も表示できるようにしたかったし、、、
 まっ、正規表現の使い方が下手で、手続き処理的な関数を書いた結果とも言えますが(笑)。
 ついで、マニュアルを日本語版にも簡単に変更できるようにしたのです、、、言い訳ですが。

 さて、今回は、組込command-event を使って、インタラクティブ環境で使いやすくします。
 内容は、組込関数を直接打ち込むと、構文を表示するというものです。
 こんな感じ。

> push
push ! utf8
syntax: (push exp list [int-index-1 [int-index-2 ... ]])
syntax: (push exp list [list-indexes])

syntax: (push str-1 str-2 [int-index])
> 

 どうでしょう。わざわざ関数syntax を呼び出す必要がありません。
 さて、組込command-event を使う前に、syntax を少しばかり改良します。

(context 'MAIN:syntax)
(setq lst (MAIN:primitives))    ; 2012/4/3 added.
(define (set-manual (text (read-file (string (env "NEWLISPDIR" ) "/newlisp_manual.html"))))
  (setq manual text))
(if-not manual (set-manual))
(define (set-flag flag)
  (setq ex-flag flag))
(set-flag nil)
(define (syntax:syntax func (flag ex-flag) (html manual))
  (if (primitive? func)
      (letn (tmp ((parse (string func) "@") 0)
             fname (or (lookup tmp
                        '(("-" "+") ("*" "+") ("/" "+") ("%" "+")
                          ("<" "&lt;") (">" "&lt;") ("=" "&lt;") ("<=" "&lt;") (">=" "&lt;") ("!=" "&lt;")
                          (">>" "&lt;&lt;") ("<<" "&lt;&lt;")
                          ("&" "&amp;")))
                       tmp)
             pre (find (string {} fname) html)
             post (find (if flag "</p>" "</h4>") html 1 pre)
             res (replace {<[^>]+>} (pre (- post pre) html) "" 1))
        (replace "&lt;" res "<")
        (replace "&gt;" res ">")
        (replace "&amp;" res "&")
        (replace "&mdash;" res "-")
        (replace "&nbsp;" res " ")
        (println res) "")
    "not primitive"
  ))
(context MAIN)

 変更内容は、関数内容表示用flag の設定関数を用意したのと、関数syntax の出力から silent を外して、戻り値を "" に変更したことです。これならコマンドラインに出てきても、悪さをしませんからね。(2012/4/3 syntax:lst を追加。関数primitives はこちらあります。)
 組込command-event の設定はこうなります。

(command-event 
  (fn (s)
    (let (x (replace {\n|\r} s "" 0))
      (if (find (sym x) syntax:lst)
        (syntax (eval-string x))))))

(2012/4/3 判定方法と評価時期を変更。)
 こうすれば、先ほどの例のように

> char
char utf8
syntax: (char str [int-index])
syntax: (char int)
> (syntax:set-flag true)
true
> char
char utf8
syntax: (char str [int-index])
syntax: (char int)

Given a string argument, extracts the character at int-index from str,
returning either the ASCII value of that character or the Unicode value on UTF-8 enabled 
versions of newLISP.  If int-index is omitted, 0 (zero) is assumed. The empty 
string returns nil. Both (char 0) and (char nil) will return 
"00".
> (char 65)
"A"
> 

 こんな感じ。

 以上、如何でしょうか?

newLISP 組込関数の構文を表示してみる...または、簡易マニュアル?

 昨日の primitives で組込関数名が判ったら、次は構文を知りたくなるもの(笑)。
 ということで、マニュアルから構文を抜き出す関数を作ってみました。

(context 'MAIN:syntax)
(if-not manual (setq manual (read-file (string (env "NEWLISPDIR" ) "/newlisp_manual.html"))))
(define (syntax:syntax func (html manual))
  (if (primitive? func)
    (letn (fname ((parse (string func) "@") 0)
           pre (find (string {} fname) html)
           post (find "</h4>" html 1 pre)
           ;post (find "</p>" html 1 pre)
           res (replace {<[^>]+>} (pre (- post pre) html) "" 1))
        (replace "&nbsp;" res " ")
        (silent (print res)))
    "not primitive"
  ))
(context MAIN)

 マニュアルは newLISP のインストール・ディレクトリにあるものを参照しています。
 使い方は、こんな感じ。

> (syntax find-all)
find-all
syntax: (find-all str-regex-pattern str-text [exp [int-regex-option]])
syntax: (find-all list-match-pattern list-lists [exp])
syntax: (find-all exp-key list exp func-compare)

 関数名がわからない場合は、昨日の primitives をどうぞ(笑)。
 また、silent を使って戻り値(文字列)表示を抑制していますので、表示後 return キー入力が必要です。
 たいていは、これで十分ですが、

> (syntax >)

ERR: value expected in function find : pre
called from user defined function syntax
> 

 あらら、、、特殊文字は苦手のようです。
 何故?

> (syntax &)
&lt;, &gt;, =, &lt;=, &gt;=, !=
syntax: (&lt; exp-1 exp-2 [exp-3 ... ])

syntax: (&gt; exp-1 exp-2 [exp-3 ... ])
syntax: (= exp-1 exp-2 [exp-3 ... ])
syntax: (&lt;= exp-1 exp-2 [exp-3 ... ])

syntax: (&gt;= exp-1 exp-2 [exp-3 ... ])
syntax: (!= exp-1 exp-2 [exp-3 ... ])

 どうやら、HTML の特殊文字を考慮しなければならないようです。
 その結果、完成形はこうなりました。

(context 'MAIN:syntax)
(define (set-manual (text (read-file (string (env "NEWLISPDIR" ) "/newlisp_manual.html"))))
  (setq manual text))
(if-not manual (set-manual))
(define (syntax:syntax func flag (html manual))
  (if (primitive? func)
      (letn (tmp ((parse (string func) "@") 0)
             fname (or (lookup tmp
                        '(("-" "+") ("*" "+") ("/" "+") ("%" "+")
                          ("" "&lt;") ("=" "&lt;") ("=" "&lt;") ("!=" "&lt;")
                          (">>" "&lt;&lt;") ("<<" "<<")
                          ("&" "&")))
                       tmp)
             pre (find (string {} fname) html)
             post (find (if flag "</p>" "</h4>") html 1 pre)
             res (replace {<[^>]+>} (pre (- post pre) html) "" 1))
        (replace "&lt;" res "")
        (replace "&amp;" res "&")
        (replace "&nbsp;" res " ")
        (silent (print res)))
    "not primitive"
  ))
(context MAIN)

 これなら、

> (syntax &)
&
syntax: (& int-1 int-2 [int-3 ... ])

 特殊記号を使った演算子も表示されます。
 さて、オプションの flag は変数 post の検索文字 "</h4>""</p>" にします。
 そうすることで、

> (syntax struct true)
struct
syntax: (struct symbol [str-data-type ... ])

The struct function can be used to define aggregate data types for 
usage with the extended syntax of import,
pack and unpack. This allows importing
functions which take C-language struct data types or pointers to these
aggregate data types.

 関数の内容の冒頭部分も表示されます。
 参照マニュアルを

(syntax:set-manual (get-url "http://www.newlisp.org/newlisp_manual-jp.html"))

 で日本語マニュアルに設定すれば、(要UTF-8版newLISP)

> (syntax struct true)
struct
syntax: (struct symbol [str-data-type ... ])

関数 struct は、
import、pack、unpack
の拡張構文で使用するためのデータ型の集合体を定義するのに使えます。
これは、C 言語の 構造体 データ型やデータ型の集合体のポインタを
取る関数の導入を可能にします。
The struct function can be used to define aggregate data types for 
usage with the extended syntax of import,
pack and unpack. This allows importing
functions which take C-language struct data types or pointers to these
aggregate data types.

 こんな感じに日本語の内容も出てきます。この場合、UTF-8版newLISP が必要です。お間違えなく。
 
 これで、インタラクティブ環境の簡易マニュアル完成、、、なんてね(笑)。

 以上、如何でしょうか?