OSDN Git Service

・presentaion : 日本語訳の追加 (odp/pdf)
[ring-lang-081/ring.git] / docs / ja-jp / source / languagedesign.txt
1 .. index:: 
2         single: 言語設計; はじめに
3
4 ========
5 言語設計
6 ========
7
8 言語設計の背景にある基本概念を学びます。
9
10 .. index:: 
11         pair: 言語設計; Ring を選ぶ理由は?
12
13 Ring を選ぶ理由は?
14 ===================
15
16 プログラミング言語 Ring には簡明、違和感の排除、組織化の奨励、
17 および透過性とビジュアル実装があります。
18 簡潔なシンタックス、そして自然なインタフェースの作成を可能にする機能群、
19 短時間で作成・構築できる宣言型ドメイン特化言語機能を標準装備しています。
20 非常に小規模、高速なスマートガベージコレクターにより、
21 プログラマはメモリを制御下に置くことができます。
22 また、多種多様なプログラミングパラダイムに対応しており、便利で実用的なライブラリが付属しています。
23 Ring は生産性と拡張性に優れた高品質な解決方法の開発のために設計しました。
24
25 .. index:: 
26         pair: 言語設計; 明確な設計目標
27
28 明確な設計目標
29 ==============
30
31 * アプリケーション開発用のプログラミング言語です。
32 * ドメイン特化ライブラリ、フレームワーク、およびツールを作成できる汎用プログラミング言語です。
33 * ビジュアル・プログラミング言語 Programming Without Coding Technology (PWCT) ソフトウェアの次世代版の開発用に設計した実用プログラミング言語です。 
34 * 小規模・高速な言語で C/C++ プロジェクトへ組み込めます。
35 * 学習と入門 (文教用途、およびコンパイラ・仮想計算機の概念) に使用できる単純明快な言語です。
36 * 生産性と拡張性に優れた高品質な解決方法の開発。
37
38 .. index:: 
39         pair: 言語設計; 簡明
40
41 簡明
42 ====
43
44 Ring は非常に簡明な言語であり、非常に単純明快なシンタックスで構成しています。プログラマには、ボイラープレートコードのないプログラムの記述を奨励しています。 
45
46 'See' 命令はメッセージを標準出力へ表示します。
47
48 .. code-block:: ring
49
50         See "Hello, World!" 
51
52 Main 関数はオプション扱いであり、ステートメントの後に実行するため、ローカルスコープで便利です。
53
54 .. code-block:: ring
55
56         Func Main
57                 See "Hello, World!" 
58                 
59 動的型付け、およびレキシカルスコープを使用しています。変数名の先頭に $ は不要です!
60
61 文字列の連結は‘+’演算子です。弱い型付け言語であり、文字列はコンテキストに基づいて数値と文字列との間で自動的に変換します。
62
63 .. code-block:: ring
64
65         nCount = 10     # グローバル変数
66         Func Main
67                 nID = 1 # ローカル変数
68                 See "Count = " + nCount + nl + " ID = " + nID
69
70 .. index:: 
71         pair: 言語設計; 違和感の排除
72
73 違和感の排除
74 ============
75
76 Ring は英数大小文字を区別しません。
77
78 .. code-block:: ring
79
80
81         See "Enter your name ? " 
82         Give name
83         See "Hello " + Name     # Name は name と同じです。
84                         
85 リストのインデックス (添字番号) は 1 から開始します。
86
87 .. code-block:: ring
88
89         aList = ["one","two","three"]
90         See aList[1]    # one を表示
91                         
92 定義前の関数呼び出し:
93
94 .. code-block:: ring
95
96
97         one() 
98         two() 
99         three()
100         Func one 
101                 See "One" + nl
102         Func two 
103                 See "two" + nl
104         Func three 
105                 See "three" + nl
106                         
107 代入演算子は深いコピーを使用します (この操作は参照ではありません)。
108
109 .. code-block:: ring
110
111         aList = ["one","two","three"]
112         aList2 = aList
113         aList[1] = 1
114         see alist[1]    # 1 を表示
115         see aList2[1]   # one を表示
116                                 
117 数値と文字列は値渡しですが、リストとオブジェクトは参照渡しです。 
118 For in ループ でリストの項目 (アイテム、要素とも言います) を更新できます。
119
120 .. code-block:: ring
121
122         Func Main
123                 aList = [1,2,3]
124                 update(aList)
125                 see aList       # one two three を表示
126
127         Func update aList
128                 for x in aList
129                         switch x
130                         on 1 x = "one"
131                         on 2 x = "two"
132                         on 3 x = "three"
133                         off
134                 next
135                         
136 定義時のリスト使用:
137
138 .. code-block:: ring
139
140         aList = [ [1,2,3,4,5] , aList[1] , aList[1] ]
141         see aList       # 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 を表示
142                         
143 一階層以上のループから脱出
144
145 .. code-block:: ring
146
147         for x = 1 to 10
148                         for y = 1 to 10
149                                         see "x=" + x + " y=" + y + nl
150                                         if x = 3 and y = 5
151                                                         exit 2     # 二階層のループから脱出
152                                         ok
153                         next
154         next
155         
156 .. index:: 
157         pair: 言語設計; 組織化の奨励
158
159 組織化の奨励
160 ============
161
162 Ring ではプログラムの組織化を奨励しています。まずは関数、次にクラス、
163 そして、関数とヘンテコなモノと組み合わせるプログラミング言語を使用していた悪夢の日々を忘却の彼方へ追いやります! 
164
165 ソースファイルの構造は:
166
167 * ファイルの読み込み
168 * ステートメントとグローバル変数
169 * 関数
170 * パッケージとクラス
171
172 これにより、構成要素で end キーワードを記述しなくてもパッケージ、
173 クラスと関数を使えます。
174
175 一行コメント、または複数行コメントを使えます。
176 一行コメントは # あるいは // で始まります。
177 複数行コメントは /* ~ \*/ の間に記述します。
178
179 .. code-block:: ring
180
181         /* 
182                 プログラムの名前    : はじめての Ring プログラム
183                 日付                : 2015.05.08
184         */
185
186         See "What is your name? "   # 画面へメッセージを表示
187         give cName                  # ユーザからの標準入力を取得
188         see "Hello " + cName        # こんにちわ!
189
190         // See "Bye!"
191                                 
192
193 .. index:: 
194         pair: 言語設計; 簡潔なシンタックス
195
196 簡潔なシンタックス
197 ==================
198
199 行の区別はしませんので、ステートメントの後に ; は不要です。または ENTER や TAB の打鍵は不要ですので、このようなコードを記述可能です。
200
201 .. code-block:: ring
202
203
204         See "The First Message" See " Another message in the same line! " + nl
205         See "Enter your name?" Give Name See "Hello " + Name
206                         
207 このコードは三種類の属性 X, Y および Z を有する Point クラスを作成します。クラス、パッケージ、関数の定義を終了するために end キーワードは使用していません。また、クラス名の直下に属性名を書くことができます。
208
209 .. code-block:: ring
210
211         Class Point X Y Z
212                         
213 定義前にクラスと関数を使えます。
214 この用例では、オブジェクトの新規作成と属性の設定、および値を表示します。
215
216 .. code-block:: ring
217
218         o1 = New point  o1.x=10    o1.y=20   o1.z=30    See O1  Class Point X Y Z
219                         
220 ドット演算子‘.’でオブジェクトの属性とメソッドへアクセスするのではなく、括弧 { } でオブジェクトへアクセスできます。その後にオブジェクトの属性とメソッドを使えます。
221
222 .. code-block:: ring
223
224         o1 = New point { x=10 y=20 z=30 } See O1  Class Point X Y Z
225                          
226 メソッドの呼び出し後に { } でオブジェクトへアクセスします。
227
228 .. code-block:: ring
229
230          
231         oPerson = new Person
232         {
233                 Name = "Somebody"
234                 Address = "Somewhere"
235                 Phone = "0000000"
236                 Print()                 # ここでは Print() メソッドを呼び出します。
237         }
238         Class Person Name Address Phone
239                 Func Print
240                         See "Name :" + name + nl +
241                                 "Address :" + Address + nl +
242                                 "Phone : " + phone + nl
243
244 { } で、オブジェクトへアクセスしてからオブジェクト名を記述するとき、自動的に呼び出される全ての setter/getter メソッドに対してクラスを検査します。
245
246 .. code-block:: ring
247
248
249         New Number {
250                         See one         # GetOne() の実行
251                         See two         # GetTwo() の実行
252                         See three       # GetThree() の実行
253         }
254         Class Number one two three
255                 Func GetOne
256                         See "Number : One" + nl
257                         return 1
258                 Func GetTwo
259                         See "Number : Two" + nl
260                         return 2
261                 Func GetThree
262                         See "Number : Three" + nl
263                         return 3        
264                         
265 .. index:: 
266         pair: 言語設計; 自然言語ステートメントの定義
267
268 自然言語ステートメントの定義
269 ============================
270
271 { } でオブジェクトへアクセス後に、クラスに BraceEnd() メソッドがあれば BraceEnd() メソッドを実行します!
272
273 .. code-block:: ring
274
275
276         TimeForFun = new journey
277         # あっと驚く!
278         TimeForFun {
279                 Hello it is me          # なんと美しいプログラミングの世界でしょう!
280         }
281         # クラス本体
282         Class journey
283                 hello=0 it=0 is=0 me=0
284                 func GetHello
285                         See "Hello" + nl
286                 func braceEnd
287                         See "Goodbye!" + nl
288
289 Eval() 関数は、文字列に記述されたコードを実行します。
290
291 .. code-block:: ring
292
293
294         cCode = "See 'Code that will be executed later!' "
295         Eval(cCode)     # コードを実行してメッセージを表示します。
296
297 リストの作成後に、実行用のコードをリストから生成できます。
298
299 .. code-block:: ring
300
301         aWords = ["hello","it","is","me"]
302         for word in aWords cCode=word+"=0" eval(cCode) next
303
304 Read(cFileName) 関数は、テキストファイルを読み取ります。また Write(cFileName,cString) 関数はファイルへ書き込みます。
305
306 .. code-block:: ring
307
308         See "Enter File Name:" Give cFileName See Read(cFileName) # ファイルの内容を表示
309
310 この用例は、二つの命令を定義するクラスの作成方法です。
311
312 * 最初の命令は : I want window
313
314 * 次の命令は : Window title = <式>
315
316 * ‘the’キーワードなどは無視されます。
317
318 .. code-block:: ring
319
320
321         New App
322         {
323                 I want window
324                 The window title = "hello world"
325         }
326
327         Class App
328
329                 # I want window 命令の属性
330                         i want window
331                         nIwantwindow = 0
332                 # Window title 命令の属性
333                 # ここでは window 属性を再定義しません。
334                         title
335                         nWindowTitle = 0
336                 # 値を与えると、キーワードを無視します。
337                         the=0
338
339                 func geti
340                                 if nIwantwindow = 0
341                                         nIwantwindow++
342                                 ok
343
344                 func getwant
345                                 if nIwantwindow = 1
346                                         nIwantwindow++
347                                 ok
348
349                 func getwindow
350                                 if nIwantwindow = 2
351                                         nIwantwindow= 0
352                                         see "Instruction : I want window" + nl
353                                 ok
354                                 if nWindowTitle = 0
355                                         nWindowTitle++
356                                 ok
357
358                 func settitle cValue
359                                 if nWindowTitle = 1
360                                         nWindowTitle=0
361                                         see "Instruction : Window Title = " + cValue + nl
362                                 ok
363
364                 
365 前述の用例を完了するには read() でファイルの内容を取得します。
366
367 .. code-block:: ring
368
369         I want window
370         The window title = "hello world"
371
372 そして eval() でファイルの内容を実行します!
373
374 また、 GUI ライブラリでウィンドウを作成するには GetWindow() と SetTitle() メソッドを更新します。
375
376
377 .. index:: 
378         pair: 言語設計; 宣言型言語の定義
379
380 宣言型言語の定義
381 ================
382
383
384 自然言語ステートメントによるコードの実行、および入れ子構造によるコードの実行方法について既に学んでいます。
385
386 この用例は Web ライブラリからの引用です。 Bootstrap ライブラリで HTML ドキュメントを生成します。
387 この用例では、 HTML コードを直接記述せずに、類似言語を作成しています (ただの用例です)。その後、宣言型言語を使用するために入れ子構造で HTML ドキュメントを生成しています。この用例での考えかたとして GetDiv() および GetH1() メソッドは { } でアクセスできるオブジェクトを返します。各オブジェクトへのアクセス後に BraceEnd() メソッドが実行されると、生成された HTML を BraceEnd() の出力表示がルートに到達するまで親オブジェクトへ送信します。
388
389 .. code-block:: ring
390
391         Load "weblib.ring"
392         Import System.Web
393
394         Func Main
395
396           BootStrapWebPage()
397           {
398                 div
399                 {
400                   classname = :container
401                   div
402                   {
403                         classname = :jumbotron
404                         H1 {   text("Bootstrap Page")   }
405                   }
406                   div
407                   {
408                         classname = :row
409                         for x = 1 to 3
410                           div
411                           {
412                             classname = "col-sm-4"
413                             H3 { html("Welcome to the Ring programming language") }
414                             P  { html("Using a scripting language is very fun!") }
415                           }
416                         next
417                   }
418                 }
419           }
420
421 このようなクラスで宣言型インタフェースを強化します。
422
423 .. code-block:: ring
424
425         Class Link from ObjsBase
426                 title  link
427                 Func braceend                   
428                         cOutput = nl+GetTabs() + "<a href='" + 
429                                   Link + "'> "+ Title + " </a> " + nl                   
430
431         Class Div from ObjsBase 
432                 Func braceend
433                         cOutput += nl+'<div'
434                         addattributes()
435                         AddStyle()
436                         getobjsdata()
437                         cOutput += nl+"</div>" + nl
438                         cOutput = TabMLString(cOutput)
439
440 .. index:: 
441         pair: 言語設計; 柔軟性のあるシンタックス
442
443 柔軟性のあるシンタックス
444 ========================
445
446 様々なソースコードの記法があります!
447
448 また、言語のキーワードと演算子を変更することで、お好みの記法を作成できます!
449
450          
451 .. index:: 
452         pair: 言語設計; 透過型実装
453
454 透過型実装
455 ==========
456
457 Ring は透過型実装です。 コンパイラの処理段階、および仮想計算機による実行中の処理内容を把握できます。
458
459 例えば : ring helloworld.ring -tokens -rules -ic
460
461 .. code-block:: ring
462
463         See "Hello, World!" 
464                         
465 実行結果
466
467 .. code-block:: ring
468
469
470         ==================================================================
471         Tokens - Generated by the Scanner
472         ==================================================================
473
474            Keyword : SEE
475            Literal : Hello, World!
476            EndLine
477
478         ==================================================================
479
480         ==================================================================
481         Grammar Rules Used by The Parser
482         ==================================================================
483
484         Rule : Program --> {Statement}
485
486         Line 1
487         Rule : Factor --> Literal
488         Rule : Range --> Factor
489         Rule : Term --> Range
490         Rule : Arithmetic --> Term
491         Rule : BitShift --> Arithmetic
492         Rule : BitAnd --> BitShift
493         Rule : BitOrXOR -->  BitAnd
494         Rule : Compare --> BitOrXOR
495         Rule : EqualOrNot --> Compare
496         Rule : LogicNot -> EqualOrNot
497         Rule : Expr --> LogicNot
498         Rule : Statement  --> 'See' Expr
499
500         ==================================================================
501
502
503
504         ==================================================================
505         Byte Code - Before Execution by the VM
506         ==================================================================
507
508                  PC      OPCode        Data
509
510                   1     FuncExE
511                   2       PushC   Hello, World!
512                   3       Print
513                   4  ReturnNull
514
515         ==================================================================
516
517         Hello, World!
518                                 
519 .. index:: 
520         pair: 言語設計; ビジュアル実装
521
522 ビジュアル実装
523 ==============
524
525 Ring は、ビジュアル・プログラミングツール Programming Without Coding Technology (PWCT) で設計しました。
526 Ring のビジュアルソースは、 “visualsrc” フォルダの \*.ssf ファイルにあります。
527 生成された C 言語ソースコードは src フォルダ、
528 および include フォルダにあります。
529
530 このスクリーンショットは、 ring_vm.ssf ファイルからの引用です (ring_vm.c および ring_vm.h が生成されます)。
531
532 .. image:: visualsrc1.jpg
533
534 このスクリーンショットは、 ring_list.ssf ファイルからの引用です (ring_list.c および ring_list.h が生成されます)。
535
536 .. image:: visualsrc2.jpg
537
538 .. index:: 
539         pair: 言語設計; スマートガベージコレクター
540
541 スマートガベージコレクター
542 ==========================
543
544 わずらわしいメモリ操作関連の問題から解放します。
545
546 * メモリへの不正アクセス
547 * メモリリーク
548 * 未初期化メモリへのアクセス
549 * ダングリングポインタ
550
551 規則:
552
553 * グローバル変数は、代入ステートメントで削除するまでメモリに存在し続けます。
554 * 関数の処理終了後に、ローカル変数を削除します。
555 * プログラマは、代入ステートメントでメモリから変数を削除する時期を完全に制御できます。
556
557
558 用例:
559
560 .. code-block:: ring
561
562         aList = [1,2,3,4,5]
563         aList = "nice"
564                         
565 二行目の直後、リスト [1,2,3,4,5] はメモリから削除され、文字列 “nice” が残ります。
566
567 * プログラマは callgc() 関数を呼び出すことで、ガベージコレクターを強制実行できます。
568 * 変数参照時 (関数へオブジェクト、およびリストを渡すとき)、参照カウントに基づいて変数を削除します。未参照では全て削除されますが、参照しているときはデータはメモリに残ります。
569
570
571 .. index:: 
572         pair: 言語設計; インタプリタ (VM) 全体の停止なし (GIL なし)
573
574 インタプリタ (VM) 全体の停止なし (GIL なし)
575 ===========================================
576
577 アプリケーションでスレッドを使うとき、インタプリタ (VM) 全体の停止 (global interpreter (VM) lock) は起こりません (GIL なし)。
578
579 よって、スレッドは並列動作可能であり、Ring 命令は同時実行されます。
580
581 これは、スレッドと平行性において最良のものです (さらなる高速化が実現できます!)
582
583
584 .. index:: 
585         pair: 言語設計; ほとんどのアプリケーションで十分に高速動作します
586
587 ほとんどのアプリケーションで十分に高速動作します
588 ================================================
589
590 プログラミング言語 Ring は単純明快、小規模、柔軟性のある最先端の設計です。また、ほとんどのアプリケーションで十分に高速動作します。 
591
592 これまで、市販の電子計算機で Ring を使用してきました。下記の処理は約1秒で完了します。
593
594 (1) 100,000 行コードのコンパイル
595 (2) 1 ~ 10,000,000 まで数え上げる空ループの実行
596 (3) 100,000 項目から成るリストで最後の項目を見つけようとして、線形検索で 1000 回の検索処理を実行 (最悪値)
597 (4) 1,000,000 項目から成るリストを作成後にリスト全項目の合計を計算
598 (5) GUI アプリケーションで ListWidget へ 20,000 アイテムを追加
599 (6) GUI アプリケーションで TreeWidget へ 5,000 ノードを追加
600 (7) ターミナルのコンソールアプリケーションで 10,000 メッセージを表示 
601
602 さらなる高速化を求めるならば C/C++ 拡張機能を使えます!
603
604 用例:
605
606 .. code-block:: ring
607
608         ? "Create list contains 100,000 items"
609         aList = 1:100000
610
611         ? "Do 1000 search operation - Find the last item (Worst Case!)"
612         c = clock() 
613
614         for t = 1 to 1000
615                 find(alist,100000)
616         next
617
618         ? "Time: " + ( clock() - c ) / clockspersecond() + " seconds"
619
620 実行結果:
621
622 .. code-block:: none
623
624         Create list contains 100,000 items
625         Do 1000 search operation - Find the last item (Worst Case!)
626         Time: 0.87 seconds
627
628 用例:
629
630 .. code-block:: ring
631
632         load "guilib.ring"
633
634         func main
635
636         new qApp {
637                 win = new qWidget() { 
638                         move(100,100) resize(500,500)
639                         setWindowTitle("Many Tree Items - Testing Performance")
640                         tree = new qTreeWidget(win) { 
641                                 blocksignals(True) setUpdatesEnabled(False)
642                                 root = new qTreeWidgetItem()
643                                 root.setText(0,"The Root Node")
644                                 t1 = clock()
645                                 for t = 1 to 5000
646                                         oItem = new qTreeWidgetItem()
647                                         oItem.settext(0,"Item " + t)
648                                         root.addchild(oItem)
649                                 next
650                                 cTime = (clock()-t1)/clockspersecond()
651                                 setHeaderLabel("Creating 5000 nodes in " + cTime + " seconds.")
652                                 addTopLevelItem(root)
653                                 expanditem(root)
654                                 blocksignals(False) setUpdatesEnabled(True)
655                         }
656                         oLayout = new qVBoxLayout() {
657                                 addWidget(tree)
658                         }
659                         setLayout(oLayout)
660                         show() 
661                 }
662                 exec()
663         }
664         
665
666 実行結果:
667
668 .. image:: manytreeitems.png
669         :alt: 大量のツリー項目