# Using the Natural Library¶

In this chapter we will learn how to use the Natural Library to quickly define a language that contains a group of commands.

To start using the library, We need to call naturallib.ring

load "naturallib.ring"


After loading the library, We can use the NaturalLanguage class that contains the next methods :-

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

## Natural Library - Demo Program¶

We will write the natural code in a Text file, for example program.txt

File: 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.


Output:

Hello, Sire!

The Numbers!

1

2

3

4

5

I will count Again!

5

4

3

2

1


To execute the natural code, We have start.ring

In start.ring we define the language and the commands.

File: start.ring

load "stdlib.ring"

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


We defined a language called MyLanguage, We have folder for the language commands.

Each command will define a class that belong to the MyLanguage.Natural package.

We will define two commands, Hello and Count.

So we must have two files for defining the commands in the CurrentDir()+”/../command” folder

File: hello.ring

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


File: count.ring

DefineNaturalCommand.SyntaxIsKeywordNumberNumber([
:Package = "MyLanguage.Natural",
:Keyword = :count,
:Function = func {
if not isattribute(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)
}
])


## Defining Commands¶

To define new command we can use the DefineNaturalCommand object

This object provides the next methods :-

• 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)

File: mylanguage.ring

load "stdlib.ring"

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


Example (1)

In the next example we will define the Print command.

We will use the SyntaxIsKeywordExpression() Method.

We pass list (as Hash) to the method. We determine the package name, the keyword and the function that will be executed.

Inside this function we uses the Expr(nExprNumber) function to get the expression value that the user will write after the keyword.

File: print.ring

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


Usage:

load "mylanguage.ring"

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


Output:

Hello, World!


Example (2)

File: iwantwindow.ring

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


Usage:

load "mylanguage.ring"

MyLanguage.RunString('
i want window
')


Output:

Command: I want window


Example (3)

File: windowtitleis.ring

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


Usage:

load "mylanguage.ring"

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


Output:

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


## Natural Library - Operators¶

In the next example we uses the Count command without using operators

load "mylanguage.ring"

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


We can add more description

load "mylanguage.ring"

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


Also we can use operators like “(” and ”)” around the instruction

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!
")
}


## Defining commands using classes¶

This section is related to the implementation details.

When we define new command, Each command is defined by the Natural Library as a class.

We have the choice to define commands using the simple interface provided by the DefineNaturalCommand object or by defining new class as in the next examples.

If we used DefineNaturalCommand (More Simple), The class will be defined during the runtime.

File: hello.ring

Package MyLanguage.Natural

class Hello

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


File: 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 Count_Execute
if not isattribute(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)