nano Shell

AWK˜plus for Android II - nano Shell

 nano Shell birth - Specification

AWK˜plus for Android II は、 などの特徴を持つ次世代スクリプト実行環境です。

AWK˜plus for Android II is It is a next-generation script execution environment with features such as.

 気になるガジェット (Anxious gadget)

Year Price($) Product
1958 ー  ALGOL (大学で遊んでいました。 I was playing in college)
1964 2,368 Ford Mustang (高校生のナンパ車として購入されました。 It was purchased as a pick-up car for high school students)
1976 776 ワンボードマイコン TK-80 (¥89k 給料1ヶ月分) (One board microcomputer)
1972 395 (¥45k) HP-35 関数電卓 (Scientific calculator, RPN: 逆ポーランド記法)
1976 115 電子ブロック(復刻版) (Electronic block(Reprint))
1976 666.66 Apple I (ガレージで製造された初号機です。 The first machine manufactured in the garage)
1978 ー  UCSD Pascal (ALGOLの後継言語で p-code インタプリタで動作します。憧れてマクロアセンブラで構造化命令、空白圧縮するエディタを作りました。後に新聞社からオファーが来ました)
(It works with the p-code interpreter in the successor language of ALGOL. I longed to make a structured instruction and blank compression editor with a macro assembler. Later, an offer came from a newspaper company)
1979 4,526 Apple II (衝撃的な マイコン、価格も Ford Mustang の倍です。 A shocking microcomputer. Double the price of the Ford Mustang)
1983 456 MSX 初めて購入したマイコン。(The first microcomputer I bought)
2010 6 AWK˜plus for Java, Android
2020 500 PlayStation 5
2021 27 (¥3k)  AWK˜plus for Android II  (Source code edition: $146,¥16k, 2 days worth of part-time job)

 BNF (Backus-Naur form) implementation (Syntax checker)

BNF 記法は、ALGOLの仕様定義用に開発されたツールですが、正規表現を使用した実装は、yacc/lex (コンパイラ・コンパイラ、bison) 以来久しぶりの登場です。
BNF is a tool developed for ALGOL's specification definition, but the implementation using regular expressions hasn't appeared in a long time since yacc/lex (compiler/compiler).

Token Definition
WORD (ANY) ::= </.+/> (※ 単一ワードもしくはクォートされた文字列。 Single word or quoted string. *)
MANY ::= </.../> (※ '...' is the UTF-8 symbol. *)
PARENTHESES ::= </(...)/> (※ 括弧で囲まれた複数ワード。 (Multiple words in parentheses) *)
BYTE ::= </[-+]?\d{1,3}/>
NUMBER ::= </[-+]?(?:\d+[.]?\d*|\d+[.]|[.]\d+)(?:[eE][-+]?\d+)?/>
BOOLEAN ::= <true | false>
STRONG_STRING ::= </'(.*?)'/> (※ 文字列、変数を置き換えません。(Does not replace variables) *)
WEAK_STRING ::= </"(.*?)"/> (※ 文字列、変数を置き換えます。(Replace variable) *)
REGEX ::= </(.+?)/> (※ 正規表現、変数を置き換えます。(It's a regular expression, Replace variable) *)
AWK_COMMAND ::= </`(.+)`/> (※ AWK スクリプトコマンド、変数を置き換えます。(AWK script command, Replace variable) *)
VAR ::= </\w+/> (※ 変数。(Variable) *)
INDEX ::= <a[n] | a[n1-n2] | a[-n] | a[n-] | a[*] | a[-]> (※ (n: 1...size, n1 <= n2)
csh の '-' の使い方には感心しましたが、[*] は統一性に欠けているため [-](all) を追加しました。 (I was impressed with how csh uses '-', but I added [-] because [*](all) is inconsistent) *)
ARRAY ::= </VAR(?:\[<INDEX>\])?/>
CONTAINER ::= <STACK | QUEUE>
RANGE ::= <`range(start,end[,incremental])`> (※ 開始、終了、増分を指定して数列を生成します。
(Generate a sequence by specifying start, end, and increment) *)
WORD_LIST ::= < ( ARRAY | CONTAINER | RANGE | stdout | stderr | &WORD...) >
(※ &サイレントモード: ログ表示を抑えるために単純変数に限り、$var の代わりに &var 指定が可能。
&Silent mode: Only simple variables can be specified as &var instead of $var to suppress log display. *)
ARITHMETIC_OPERATOR ::= 算術演算子 </(?:[-+*/%&|^]|<<|>>)=?|=/>
LOGICAL_OPERATOR ::= 論理演算子 /<BOOLEAN | NUMBER | AWK_COMMAND>/
SCRIPT ::= </["']?/.+[.](awk|.*sh.*?)/["']?/>
COMMAND ::= <AWK_COMMAND | SCRIPT | BUILTIN_COMMAND>
EXPRESSION ::= <BOOLEAN (BOOLEAN | NUMBER | STRING) | AWK_COMMAND (LOGICAL_OPERATOR)>
※ Control statement
IF ::= <[else] if ( EXPRESSION ) <then | BREAK | CONTINUE | COMMAND>
(※ COMMAND 部分が曲者で、真なら COMMAND(制御文は不可) をパースした後に if 文を書き換えます。 (If the COMMAND part is a songwriter and is true, rewrite the if statement after parsing COMMAND (control statements are not allowed) *)
ELSE ::= <else>
END ::= <end> (※ 単一の end は、他のシェルと決定的に異なる部分です。 (A single end is a decisive difference from the others) *)
FOREACH ::= <foreach VAR ( &WORD_LIST )>
WHILE ::= <while ( EXPRESSION )>
BREAK ::= <break>
CONTINUE ::= <continue>

※ BNF の実装を正規表現で行うことにより、nano パーサーが完成しました。 シンタックスチェッカーは、簡素化され、エラーを投げているだけです。
 ※ By implementing BNF with regular expressions, the nano parser was completed. The syntax checker has been simplified and just throwing an error.

 nano Machine architecture (Assembler)

instruction jump general1 general2
break parent end+1
continue parent  end+1 
if ... break parent end+1
if ... continue parent  end+1 
[else] if ... then next block
foreach end+1 flags
while end+1 flags
while ... end parent
if ... end end+1
nano end if+1
伏兵登場 (Ambush appeared)
  if (`$foo`) then
    foreach i (bar)
      ...
    end    #1 jump to parent
    ☆nano  # <- insert, jump to end-if
  else if (`$baz`) then
    ...
  else
    ...
  end

#1 の end は、親 (foreach, while) と end-if へジャンプする必要が有り矛盾しています。そこで最良の方式として、オプティマイザを実装し nano 命令を else の手前に挿入しました。
 The end of #1 must implement a jump to the parent (foreach) and end-if. So, the best way to do this is to implement an optimizer and insert the nano instruction before else.
(Ref. nano X instruction)

※ break の parent は、フラグのリセットに使用します。(break parent is used for flag reset)
※ アドレス解消のためのスタックは、if、while 別でなく親子 2本で処理しています。 (複数 end の必要性は、理解不能です)
※ The stack for address resolution is processed by two parents and children, not by if and while. (The need for multiple ends is incomprehensible)

※ 命令セットの直交性に配慮しました。これによりアセンブラが簡素化されます。 (入社時に使用したミニコンのアーキテクチャがこれでした)
※ Consideration was given to the orthogonality of the instruction set. This simplifies the assembler. (This was the architecture of the minicomputer I used when I joined the company)

 Built-in commands

算術演算の高速化および文字列操作の充実を図りました。
(I have speeded up arithmetic operations and enhanced character string operations)
array VAR <SIZE>
配列変数を作成します(空文字で初期化)。 Allocate an array. (Subscript is 1...size, Initialize with empty string)
assert <BOOLEAN> [<WORD>]
論理値が false のときエラーをスローします。 (Throw an error when the boolean is false)
copy <"INPUT FILE" | stdout | stderr | &WORD> <"OUTPUT FILE" | VAR | ARRAY>
ファイル、変数または文字列を複写します。 Copy the file or variable. (Ref. nano Color Chart.sh)
※ 新規ファイル名は、フルパスで指定します。(Specify the new file name with the full path)
echo [-nl] [<WORD...>]
シェルの標準出力に書き出します。
'-n' を指定すると改行しません。 (If '-n' is specified, no line break will occur)
'-l' を指定するとログにも出力します。 ('-l' also outputs to the log)
exit [<EXPRESSION>]
シェルスクリプトを終了し、状態変数(status)または式 expression の値を返します。
Set the status code and exit the command.
export <VAR> = <VAR | WORD>
環境変数に値 (オブジェクトを含む)を設定します。
Set the value (including the object) in the environment variable.
flush
最新のログを表示します。 View the latest logs. (like, 'tail -f')
ls [<file> | <folder>]
ファイルやフォルダを一覧表示します。 List files and folders. (状態変数 $status をセット)
loadHTML <&WORD>
html または、URL を 'WebView' にロードします。 (Load the html or URL into the 'WebView')
messageLevel [<silence | error | warning | information | verbose | BYTE>]
Message level.
※ パーサーメッセージをカットするためには、スクリプトの先頭に、’messageLevel warning’ を入力します。 (To cut the parser message, enter ’messageLevel warning’ at the beginning of the script)
pop ARRAY = <CONTAINER> [ <CONTAINER_TYPE> ]
<CONTAINER_TYPE> ::= 'queue' | 'stack' (大小文字を問わない。)
タイプ省略時は、コンテナ名から推論。('que'が存在すれば'queue')
(If the type is omitted, it is inferred from the container name. ('queue' if 'que' exists, Large and small) )
※ CONTAINER から 1つ取り出します。空の場合は、$NULL を返す。 (Extract one from the beginning of CONTAINER. Returns $NULL if the CONTAINER is empty)
printenv <[VAR...]>
VAR を省略した場合は、全ての環境変数の値を表示。また、env と重複したローカル変数は、削除します。
If VAR is omitted, the values of all environment variables are displayed. Also, Duplicate local variables are removed.
push (1) CONTAINER /[+]?=/ ( <&WORD_LIST> )
foreach と同じパラメータ指定で、スタックまたは、キューで使用するコンテナを作成します。
(Create a container to be used in the stack or queue with the same parameters as foreach)
※ push(1) と set(3) を使用すれば相互にコンテナ変換が可能。 (Container conversion between each other is possible using push(1) and set(3))
push (2) CONTAINER = <&WORD>  (WORDを括弧で囲みません)
このコマンドは、push(1) のシンタックス・シュガー(エリアス)で追加専用です。
(This command is for addition only in push(1) syntax sugar (Elias). Do not enclose WORD in parentheses)
read VAR <default value> [<prompt>]
ダイアログから入力した値を変数に設定します。
Set the value entered from the dialog to the variable. (Ref. √2, CawSay.sh...)
remove <VAR | File | Folder> ...
変数 (ローカル・環境変数)、ファイルまたは、フォルダを削除します。 (状態変数 $status をセット)
(Delete variables (local/environment variables), files or folders.)
※ エラー発生時は、メッセージを出力しスローしません。(When an error occurs, a message is output and it is not thrown) これは、存在が不明でとりあえず削除する場合の考慮です。 (This is a consideration when the existence is unknown and it is deleted for the time being) (Ref. 'AWK˜nano T.remove.bsh')
replace ARRAY = <&WORD> </regex/> [<replacement>]
文字列を置換します。 String replacement. (The default value for replacement is '')
set (1) ARRAY /(?:[-+*/%&|^]|<<|>>)=?|=/ <val1>
第一オペランドに対して演算を行う。 (Performs an operation on the first operand)
演算は、double で行い、文字列の場合は、'+=' で追加します。
The operation is performed with double, and in the case of a character string, it is added with '+='.
set (2) ARRAY = <val1> /[-+*/%&|^]|<<|>>/ <val2>
変数を2つ指定できるバージョン。ただし、set var = `expr` とやれば何でもありで面白くないですね。
(Version that can specify two variables. However, if you do set var = `expr`, you can do anything and it's not interesting) (Ref. √2III.sh)
set (3) VAR /[+]?=/ ( <&WORD_LIST> )
foreach と同じパラメータ指定で配列を作成します。('+='の場合は追加)
Create an array with the same parameters as foreach. (Append if '+=')
sleep [<seconds>]
Sleep for a specified time (Attribute is double).
split VAR = <stdout | stderr | &WORD> [<fs (If omitted, FS)>]
文字列を配列に分解します。 (Decomposes a string into an array)
※ stdout | stderr の場合は、セパレータは、不要です。 (No separator required for stdout or stderr)
※ fs が "" の場合は、1文字ずつに分解します。 (gawk specification, If fs is "", decompose it character by character)
wait
loadHTML と対で使用し、戻るボタン押下を待ちます。
(Use with loadHTML and wait for the back button to be pressed)
※ ファイルは、パスを指定しない設計です。重複ファイルを扱う場合は、フルパスで指定します。
  (A file is designed with no path specified. When handling duplicate files, specify the full path)

※ ARRAY: 配列の要素への代入が可能。(Can be assigned to array elements)
※ &WORD: Log 出力抑制の為に単純変数の参照($var)の代わりに(&var)指定が可能。(サイレントモード)
  (You can specify (&var) instead of the simple variable reference ($var) to suppress Log output. (Silent mode))

 External commands (AWK utilitys)

Linux でよく利用されているらしいコマンドを作成しました。 (I created a command that seems to be commonly used in Linux)
Command Description
cat file... (1) Displays the contents of the file. The shortest script '1' in the world.
csv [-Fs] [-v OFS=s] [-v col=<columns>] [-v fmt="<output formats>"] file... (17) CSV utility、デリミッタの変更(AWK標準機能)、列の入れ替え、sort の為のフォーマット変換が可能で今まで無かったのが不思議です。 (It is strange that it has never been possible to change the delimiter (AWK standard function), replace columns, and convert the format for sort)
Eratosthenes <number> (28) プログラムコンテストで使用したアルゴリズムで、探索する素数の数に制限は有りません。
There is no limit to the number of prime numbers that can be searched by the algorithm used in the program contest.
grep <regex> [-x <exclude>] file... (16) Can be extracted and excluded.
head [-<number of lines>] file... (8) Outputs the specified number of lines from the beginning of the file.
sort [-r] [-i] [-u] file... (40) It has reverse, ignore case, and unique features.
tac [-<number of lines>] file... (18) cat の逆順出力。 It works in reverse of 'cat'.
tee file... (6) Outputs the stream to standard output and error output.
wc file... (19) Word count.
(※ (n) は、ステップ数です。これが今でも AWK が使われている理由です。 (n) is the number of steps. That's why AWK is still used. *)
※ 標準入力から読み込む場合は、ファイル名に '-' を指定します。 (When reading from standard input, specify'-' for the file name)

 Built-in functions (Performance tuning)

nano Shell の論理判定は、AWKコマンド(`...`)を使用しますが、nano が解釈できる単純な判定に限り、魔法の呪文を用意しました.
The nano Shell's logical verdict uses the AWK command (`...`), but i've provided a magic spell for simple verdicts that nano can interpret.

Before(AWK) After(Magic spell) Explanation
`!$a` `(?:!$a)` | `(?:!($a))` 単一の論理判定を行う。 (Make a single logical decision) (※ TRUE ::= true | !=0 | Non-empty string is true *)
`$b<=$c` `(?:$b<=$c)` | `(?:!($b>$c))` 二つの値を比較する。(Compare the two values) (※ LOGICAL_OP ::= /([<>!]=?)|==/ *)
`length(s)` `(?:length(s))` 文字列 s の長さを返す。 (Returns the length of the string s)
`substr(s,i[,n])` `(?:substr(s,i[,n]))` 文字列 s の i(1...) 番目から始まる n 文字を返す。 (Returns n characters starting from the i of the string s)
`match(s,regex)` `(?:match(s,regex))` regex が s に適合する位置(1...)を、適合しない場合は、0 (false) を返す。 (Returns the position (1...) where regex matches s, 0 if it does not)
  ー `(?:range(s,e[,i]))` | `range(s,e[,i])` 開始、終了 [、増分]を指定して数列を生成する。 (Generate a sequence by specifying start, end, and increment)
(?:X) は、正規表現グループ表記を再利用しました。 (Reused regular expression group notation)
※ AWK組み込み関数でよく使う関数は、ここに実装します。 (Functions that are often used in AWK built-in functions are implemented here)

 Constants

Constant Explanation
infinite | -infinite Maximum and minimum integers (※ Cannot be used for range *)
0:silence | 1:error | 2:warning | 3:information | 4:verbose Message level
true | false Logical value

 Environmental variables (環境変数)

Variable Explanation
$BASE App ストレージパス "../$HOME" (APP storage path)
$FS フィールドセパレータ、 初期値は、" " で /[ \t]+/ の意味。 (AWK 仕様)
Field Separator, The initial value is " ", which means /[\ t]+/. (AWK specifications)
$HOME ("~/") App home path "$BASE/AWK~plus"  e.g. "$HOME/foo/bar" or "~/foo/bar"
$NULL null value (Ref. Built-in commands#pop)

※ 環境変数は、親子シェルで変数共有するために使用します。
    (Environment variables are used to share variables in the parent-child shell)
    export VAR = var を使用すると、コンテナ(配列、スタック、キュー)の共有が可能です。
    (Container (arrays, stacks, queues) can be shared)
(Ref. AWK˜nano T.ENV.bsh)

※ 同名のローカル変数が存在する場合は、ローカル変数を削除しエラーメッセージを出力します。
    (If a local variable with the same name exists, the local variable is deleted and an error message is output)

    export, printenv,

※ 環境変数の更新が可能なコマンドは、以下の通り(配列要素への代入をサポートしているコマンド)です。
    (The commands that can update environment variables are as follows (commands that support assignment to array element)

    copy, pop, replace, set (1), set (2)

※ 変数の命名規約のガイドラインは下記のスタイルを提案します。
    (Variable naming convention guidelines suggest the following styles)

    e.g. FIXED_VALUE, variableValue (Java style), VariableValue (C style)

 Local variables

Variable Explanation
$1...n 子スクリプトに渡される argv。 (Argument vector passed to child shell script)
$argv[n] 同上 (Same as above)
$messageLevel Message level (Passed from parent to child)
$status Exit status of the last exit command
$systime Returns the current time (ms.)
stdout, stderr Standard output, error (※ これらは、生データのため次のコマンドで利用します。 (These are raw data and will be used in the following command) *)  foreach, set(3), push(1), copy, split

 Path expansion (パス展開)

  e.g. …/home/foo/bar/file
Value Example Explanation
<file> file ファイル名が重複していない場合は、これを使用します。 (Use this if the filename is unique)
※ この方式は、フォルダアクセスするため負荷が高いがキャッシュ化によりパフォーマンス向上 (10倍) しました。 (This method has a high load due to folder access, but performance has improved (10 times) due to caching.)
$HOME $HOME/foo/bar/file home を展開します。 (Expand home)
~/ ~/foo/bar/file 同上(チルダ展開)。 (Same as above)
*/ */bar/file 後方一致で展開します。 (Expands with a suffix match)
※ '文字列' (STRONG_STRING) の場合は、展開されません。 (If it is a 'string', it will not be expanded)

 Add-on function

アドオン機能により外部テキストエディタを起動できます。 これは、足りない機能を世界中のアプリから調達可能ということです。
(The add-on feature allows you to launch an external text editor. This means that you can source the missing features from apps around the world)

(※ お勧めは、QuickEdit pro で 40以上の言語をサポートしています。 I recommend that QuickEdit pro supports over 40 languages) *)

 User-defined AWK functions (Macro)

これは、AWK の足りない機能を自分自身で作成できるという事です。
(This means that you can create the missing AWK features yourself) For user-defined functions, create '/lib/user.awk' and define the function. (Ref. 最大公約数、/lib/predefJ.awk#gcd, Water.sh#gcd)

(※ 定義した関数は、AWK˜plus 及び `nano Shell` から利用可能です。 (This function is available from AWK˜plus and `nano Shell`) *)


※ こうして言語作りの集大成となる『気になる』アプリ、メジャー入りを狙ったアプリが完成しました。
 ※ In this way, the "worrisome" app, which is the culmination of language creation,
   and the app aimed at entering the major were completed.

nano Shell birth
  1. Anxious gadget (気になるガジェット)
  2. BNF (Backus-Naur form) implementation (Syntax checker)
  3. nano Machine architecture (Assembler)
  4. Built-in commands (nano commands)
  5. External commands (AWK utilitys)
  6. Built-in functions (Performance tuning)
  7. Constants (定数)
  8. Environmental variables (環境変数)
  9. Local variables (ローカル変数)
  10. Path expansion (パス展開)
  11. Add-on function (アドオン)
  12. User-defined functions (Macro、マクロ)