自然言語ライブラリの用法¶
命令グループのある言語を手軽に定義するために、自然言語ライブラリの用法を学びます。
自然言語ライブラリの使用前に naturallib.ring ライブラリを読み込みます。
load "naturallib.ring"
ライブラリの読み込み後、このメソッドで自然言語を使用できます。
- SetLanguageName(cLanguageName)
- setCommandsPath(cFolder)
- SetPackageName(cPackageName)
- UseCommand(cCommandName)
- SetOperators(cOperators)
- RunFile(cFileName)
- RunString(cString)
自然言語ライブラリ - デモプログラム¶
例えば、テキストファイル program.txt に自然言語コードを記述します。
ファイル: program.txt
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.
実行結果:
Hello, Sir!
The Numbers!
1
2
3
4
5
I will count Again!
5
4
3
2
1
自然言語コードを実行するには start.ring が必要です。
start.ring には言語と命令を定義します。
ファイル: start.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
DefineNaturalCommand.SyntaxIsKeyword([
:Package = "MyLanguage.Natural",
:Keyword = :hello,
:Function = func {
See "Hello, Sir!" + nl + nl
}
])
ファイル: count.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)
}
])
命令の定義¶
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
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
DefineNaturalCommand.SyntaxIsKeywordExpression([
:Package = "MyLanguage.Natural",
:Keyword = :print,
:Function = func {
See Expr(1)
}
])
用法:
load "mylanguage.ring"
MyLanguage.RunString('
print "Hello, World!"
')
実行結果:
Hello, World!
用例②
ファイル: iwantwindow.ring
DefineNaturalCommand.SyntaxIsCommand([
:Package = "MyLanguage.Natural",
:Command = "i want window",
:Function = func {
See "Command: I want window" + nl
}
])
用法:
load "mylanguage.ring"
MyLanguage.RunString('
i want window
')
実行結果:
Command: I want window
用例③
ファイル: windowtitleis.ring
DefineNaturalCommand.SyntaxIsCommandString([
:Package = "MyLanguage.Natural",
:Command = "window title is",
:Function = func {
See "Command: Window title is " + Expr(1) + nl
}
])
用法:
load "mylanguage.ring"
MyLanguage.RunString('
I want window and the window title is "Hello World"
')
実行結果:
Command: I want window
Command: Window title is Hello World
自然言語ライブラリ - 演算子¶
この用例は演算子ではなく Count 命令を使用しています。
load "mylanguage.ring"
MyLanguage.RunString("
Hello
Count 1 5
Count 5 1
")
さらに詳しく記述できます。
load "mylanguage.ring"
MyLanguage.RunString("
Hello, Please Count from 1 to 5 then count from 5 to 1
")
また、命令は “(” や ”)” などの演算子で囲むことができます。
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!
")
}
クラスによる命令の定義¶
本章は詳細な実装と関係があります。
新しい命令を定義するとき、各命令は自然言語ライブラリにより、クラスとして定義されます。
DefineNaturalCommand オブジェクト、またはこの用例のように、新しいクラスを定義することにより提供される単純明快なインタフェースでコマンドを定義する選択肢があります。
DefineNaturalCommand (最も簡単な方法) は実行時にクラスを定義します。
ファイル: hello.ring
Package MyLanguage.Natural
class Hello
func AddAttributes_Hello
AddAttribute(self,:hello)
func GetHello
See "Hello, Sir!" + nl + nl
ファイル: count.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)