.. index:: 
	single: 自然言語ライブラリの用法; はじめに

========================
自然言語ライブラリの用法
========================

命令グループのある言語を手軽に定義するために、自然言語ライブラリの用法を学びます。

自然言語ライブラリの使用前に naturallib.ring ライブラリを読み込みます。

.. code-block:: ring

	load "naturallib.ring"

ライブラリの読み込み後、このメソッドで自然言語を使えます。

* SetLanguageName(cLanguageName)
* setCommandsPath(cFolder)
* SetPackageName(cPackageName)
* UseCommand(cCommandName)
* SetOperators(cOperators)
* RunFile(cFileName)
* RunString(cString)

.. index:: 
	pair: 自然言語ライブラリの用法; 自然言語ライブラリ - デモプログラム

自然言語ライブラリ - デモプログラム
===================================

例えば、テキストファイル program.txt に自然言語コードを記述します。

ファイル: program.txt

.. code-block:: none

	Welcome to the Ring programming language!
	What you are reading now is not comments, I swear!

	After many years of programming I decided to think different about
	programming and solve the problems in a better way. 

	We are writing commands or code and the Ring language is reading
	it to understand us! Sure, What you are seeing now is
	just ***part of the code - Not the Complete Program***
	You have to write little things before and after this 
	part to be able to run it!

	It is the natural part of our code where we can write in English, 
	Arabic or any Natural Language Then we will tell the computer 
	through the Ring language what must happens! in a way that we can scale 
	for large frameworks and programs.

	Just imagine what will happens to the world of programming once
	we create many powerful frameworks using the Ring language that
	uses this way (Natural Programming).

	For example When we say Hello to the Machine, It can reply! and when we
	say count from 1 to 5 it will understand us, Also if 
	we said count from 5 to 1 it will
	understand us too! You can see the Output window!

	This Goal is not new, but the Ring language comes
	with an innovative solution to this problem. 	

実行結果:

.. code-block:: none

	Hello, Sir!


	The Numbers!

	1

	2

	3

	4

	5

	I will count Again!

	5

	4

	3

	2

	1


自然言語コードを実行するには start.ring が必要です。

start.ring には言語と命令を定義します。

ファイル: start.ring

.. code-block:: ring

	load "stdlib.ring"
	load "naturallib.ring"

	New NaturalLanguage {
		SetLanguageName(:MyLanguage)
		SetCommandsPath(CurrentDir()+"/../command")
		SetPackageName("MyLanguage.Natural")
		UseCommand(:Hello)
		UseCommand(:Count)
		RunFile("program.txt")
	}


これで MyLanguage 言語名は定義済みになり、言語命令用のフォルダが指定されます。

各命令は MyLanguage.Natural パッケージにあるクラスとして定義されています。

Hello と Count の二つの命令を定義しています。

CurrentDir()+”/../command” フォルダで命令を定義するために二つのファイルが必要です。

ファイル: hello.ring

.. code-block:: ring

	DefineNaturalCommand.SyntaxIsKeyword([
		:Package = "MyLanguage.Natural",
		:Keyword = :hello, 
		:Function = func {
			See  "Hello, Sir!" + nl + nl
		}
	])

ファイル: count.ring

.. code-block:: ring

	DefineNaturalCommand.SyntaxIsKeywordNumberNumber([
		:Package = "MyLanguage.Natural",
		:Keyword = :count, 
		:Function = func {
			if not isattribute(self,:count_times) {
				AddAttribute(self,:count_times)
				Count_Times = 0
			}
			if Expr(1) > Expr(2) { 
				nStep = -1 
			else 
				nStep = 1
			}
			if Count_Times = 0 { 
				see nl+"The Numbers!" + nl 
				Count_Times++
			else 
				see nl + "I will count Again!" +nl 
			}
			for x = Expr(1) to Expr(2) step nStep {
				see nl+x+nl 
			}
			CommandReturn(fabs(Expr(1)-Expr(2))+1)				
		}
	])


.. index:: 
	pair: 自然言語ライブラリの用法; 命令の定義

命令の定義
==========

DefineNaturalCommand オブジェクトで新しい命令を定義します。

このオブジェクトでは、下記のメソッドが使えます。

* SyntaxIsKeyword(aPara)
* SyntaxIsKeywordNumber(aPara)
* SyntaxIsKeywordNumberNumber(aPara)
* SyntaxIsKeywordNumbers(aPara,nCount)
* SyntaxIsKeywordString(aPara)
* SyntaxIsKeywordStringString(aPara)
* SyntaxIsKeywordStrings(aPara,nCount)
* SyntaxIsKeywordExpression(aPara)
* SyntaxIsKeywordExpressionExpression(aPara)
* SyntaxIsKeywordExpressions(aPara,nCount)
* SyntaxIsCommand(aPara)
* SyntaxIsCommandNumber(aPara)
* SyntaxIsCommandNumberNumber(aPara)
* SyntaxIsCommandNumbers(aPara,nCount)
* SyntaxIsCommandString(aPara)
* SyntaxIsCommandStringString(aPara)
* SyntaxIsCommandStrings(aPara,nCount)
* SyntaxIsCommandExpression(aPara)
* SyntaxIsCommandExpressionExpression(aPara)
* SyntaxIsCommandExpressions(aPara,nCount)

ファイル: mylanguage.ring

.. code-block:: ring

	load "stdlib.ring"
	load "naturallib.ring"

	MyLanguage = New NaturalLanguage {
		SetLanguageName(:MyLanguage)
		SetCommandsPath(CurrentDir()+"/../command")
		SetPackageName("MyLanguage.Natural")
		UseCommand(:Hello)
		UseCommand(:Count)
		UseCommand(:Print)
		UseCommand(:IWantWindow)
		UseCommand(:WindowTitleIs)
		UseCommand(:IWantButton)
	}


用例①

この用例では、 Print 命令を定義します。

SyntaxIsKeywordExpression() メソッドを使用します。

メソッドにはリスト (ハッシュとして) を渡します。
実行するパッケージ名、キーワード、および関数を決定します。

この関数の内側で使用する Expr(nExprNumber) 関数はユーザがキーワードの後に記述する式の値を取得します。

ファイル: print.ring

.. code-block:: ring

	DefineNaturalCommand.SyntaxIsKeywordExpression([
		:Package = "MyLanguage.Natural",
		:Keyword = :print, 
		:Function = func {
			See  Expr(1)  
		}
	])

用法:

.. code-block:: ring

	load "mylanguage.ring"

	MyLanguage.RunString('
 		print "Hello, World!"
	')

実行結果:

.. code-block:: none

	Hello, World!

用例②

ファイル: iwantwindow.ring

.. code-block:: ring

	DefineNaturalCommand.SyntaxIsCommand([
		:Package = "MyLanguage.Natural",
		:Command = "i want window", 
		:Function = func {
			See  "Command: I want window" + nl
		}
	])

用法:

.. code-block:: ring

	load "mylanguage.ring"

	MyLanguage.RunString('
 		i want window
	')

実行結果:

.. code-block:: none

	Command: I want window

用例③

ファイル: windowtitleis.ring

.. code-block:: ring

	DefineNaturalCommand.SyntaxIsCommandString([
		:Package = "MyLanguage.Natural",
		:Command = "window title is", 
		:Function = func {
			See  "Command: Window title is " + Expr(1) + nl
		}	
	])

用法:

.. code-block:: ring

	load "mylanguage.ring"

	MyLanguage.RunString('
 		I want window and the window title is "Hello World"
	')

実行結果:

.. code-block:: none

	Command: I want window
	Command: Window title is Hello World


.. index:: 
	pair: 自然言語ライブラリの用法; 演算子

自然言語ライブラリ - 演算子
===========================

この用例は演算子ではなく Count 命令を使用しています。

.. code-block:: ring

	load "mylanguage.ring"

	MyLanguage.RunString("
		Hello	
		Count 1 5
		Count 5 1
	")

詳述すると、

.. code-block:: ring

	load "mylanguage.ring"

	MyLanguage.RunString("
		Hello, Please 	Count from 1 to 5 then count from 5 to 1
	")

また、命令は “(” や ”)” などの演算子で囲むことができます。

.. code-block:: ring

	load "mylanguage.ring"

	MyLanguage {
		SetOperators("()")
		RunString("
			Here we will play and will try something
			that looks like Lisp Syntax
			(count  (count 1 5)  (count 20 15))
			Just for fun!
		")
	}


.. index:: 
	pair: 自然言語ライブラリの用法; クラスによる命令の定義

クラスによる命令の定義
======================

本章は詳細な実装と関係があります。

新しい命令を定義するとき、各命令は自然言語ライブラリにより、クラスとして定義されます。

DefineNaturalCommand オブジェクト、またはこの用例のように、新しいクラスの定義することで使える単純明快なインタフェースでコマンドを定義する選択肢があります。

DefineNaturalCommand (最も簡単な方法) は実行時にクラスを定義します。

ファイル: hello.ring

.. code-block:: ring

	Package MyLanguage.Natural

	class Hello

		func AddAttributes_Hello	
			AddAttribute(self,:hello)

		func GetHello   
			See  "Hello, Sir!" + nl + nl


ファイル: count.ring

.. code-block:: ring

	Package MyLanguage.Natural

	class Count
           
		func Getcount
			StartCommand()
			CommandData()[:name] = :Count
			CommandData()[:nExpr] = 0
			CommandData()[:aExpr] = []

		func BraceExprEval_Count nValue
			if isCommand() and CommandData()[:name] = :Count {
				if isNumber(nValue) {
					CommandData()[:nExpr]++     
					CommandData()[:aExpr] + nValue
					if CommandData()[:nExpr] = 2 {
						Count_Execute()
					}
				}
			}

		func AddAttributes_Count	
			AddAttribute(self,:count)
	
		func Count_Execute
			if not isattribute(self,:count_times) {
				AddAttribute(self,:count_times)
				Count_Times = 0
			}
			if Expr(1) > Expr(2) { 
				nStep = -1 
			else 
				nStep = 1
			}
			if Count_Times = 0 { 
				see nl+"The Numbers!" + nl 
				Count_Times++
			else 
				see nl + "I will count Again!" +nl 
			}
			for x = Expr(1) to Expr(2) step nStep {
				see nl+x+nl 
			}
			CommandReturn(fabs(Expr(1)-Expr(2))+1)				
