|
REFAL-PHP GUIDE |
|
|
Leonid Belous |
|
|
Copyright © 2002 Leonid Belous |
|
|
14-12-2002 |
|
|
|
|
|
Contents |
|
|
|
|
|
- 1. Introduction to Refal-PHP
- 1.1. What is
Refal?
- 1.2. What is PHP?
- 1.3. What
is Refal-PHP?
|
|
|
- 2. Interface with PHP as
Refal-extention
- 2.1. PHP using in
Refal programs
2.2. Data exchange between Refal and PHP environments
- 2.3. On paradigms of operational and functional programming languages
- 2.4. Interface with Data Base
- 2.5. Mathematical functions evaluation
|
|
|
- 3. Refal-PHP as embedded scripting
language
- 3.1. The most
simple example "Hello World!"
- 3.2. How
does it function?
- 3.3. General
structure of Refal-PHP program
- 3.4. Variables and
function calls scope
|
|
|
- 4. Downloading, installation and
getting starting of Refal-PHP
- 4.1. Alternative
working configurations Refal - (PHP, PHP+MySQL, PHP+MySQL+Apache)
- 4.2. Windows
9x/ME/NT/2000/XP platform
- 4.3. UNIX platform
- 4.4. Working with Refal-PHP System
- 4.5. Recommendations on program debugging
- 4.6. Some "small items"
- 4.7. Additional information for system
programmers
-
|
|
|
- APPENDIX A
- A.1. Demo examples
- A.2. Refal-PHP
function libraries
- A.3. The
License
-
|
|
|
|
|
|
1. Introduction
to Refal-PHP |
|
|
|
|
|
1.1. What is Refal? |
|
|
|
|
|
Refal (REcursive Funstion Agorithmic
Language) is a functional programming language, oriented on symbolic
information processing. It was created in 60-s of XX century by V.F.Turchin (in former the
USSR) as "metalanguage" to describe other languages semantics. But the language
also proved to be an useful working instrument for programmers, who solved the applied
problems in various spheres of human activity. Refal history is closely connected
with dramatic events in life of his author, famous physicist, V.F.Turchin. You can
get to know in detail about Refal and about its author from site
"Refal/Supercompilation Community" www.refal.net
(mirror www.refal.org).
After some time of calm, Refal begins to
attract attention again as convenient and elegant programming language, free from
excessive details, with simple and natural mechanism of pattern matching. Here and
further, if contrary won't be fixed, Refal-5 System will be considered as definitive
realization of Refal language.
There are two examples of Refal programs.
Example 1.1-1 "Hello world!"
$ENTRY Go { = <Print "Hello world!\n">;
} |
It prints as a result the traditional
phrase "Hello world!" succeeding with line transfer.
Next example is more interesting and show a specific character of Refal.
Let's consider such simple problem. We want to define a function, which determines whether
a given string of characters is or is not a palindrome. A palindrome is a string which reads the same from left to right and from
right to left.
Example 1.1-2 Palindrome
$ENTRY Go { = <Pal 'revolver'>; } Pal {
= True;
s.1 = True;
s.1 e.2 s.1 = <Pal e.2>;
e.1 = False;
} |
Program analysis of input string 'revolver' results in printing of value
"False".
Refal is good first of all because it gives the opportunity to write a program, which
is very close to mathematical formulation of problem, instead of inventing (with
scrupulous care, indeed!) a detail algorithm to solve one. This example illustrates such
opportunity. As you can see, the program reflects following mathematical precise
definition of palindrome concept:
- An empty string is a palindrome.
- A string of one symbol is a palindrome.
- If a string starts and ends with the same symbol, then it is a palindrome if and only if
the string which remains after the removal of the first and the last letters is a
palindrome.
- If none of the above are applicable, the string is not a palindrome.
Here s.1, e.2 are used to denote patterns for single symbol and any expression
correspondingly. Special interpretator "Refal machine" really executes stated
checks and substitutions from 1. till 4. in step by step manner, selecting the first
applicable rule exactly in the same order, as it is indicated in program, moreover the
third rule brings to recursive call (function "Pal" calls itself).
And one more capacity of Refal is worthy to be mentioned. It is very suitable
for processing of tree-structured data, namely of algebraic expressions, XML and
SGML format structures, etc.
Here you can study Refal-5 System in
more detail. |
|
|
|
|
|
|
|
|
1.2. What is PHP? |
|
|
|
|
|
PHP language, which appeared not so long ago (1994), has
unusual “recursive” acronym (Php: Hypertext Preprocessor). It represents scripting
language builted into HTML , and in this capacity it have become as something of standard
de facto in creating of dynamically changed web-pages. It is Open Source, BSD like language.
Language syntax absorb Ñ, Java and Perl characteristics, but it has its own special
constructions also.
The attractive characteristics of language are its simplicity and ease in study,
cross-platformed implementation, interface with practically all popular DBS.
Less known fact is that PHP can be applied independently, out of web-technologies, as
usual universal programming language with the excellent library of interface functions.
There are two e xamples of PHP programs.
Example 1.2-1
"Hello world!"
<?php echo "Hello world!\n";
?> |
This text, to be put into file, named world.php for example, is interpreted by
web-server, as a task for web page generating.
Such generating really takes place, when
visitor of site, containing this page, set its URL (or get to it by reference). Then
“Hello world!” text appears in web-browser window, as if an usual HTML page have been
examinated. If we view its source code by browser, then, indeed, we won't see the
mentioned above PHP text, but just the result with HTML tags, obtained after generating.
Output “Hello world!” as a result of vide supra PHP program you can see also while
working in â ðåæèìå êîìàíäíîé ñòðîêè without any server and browser,
if command
> php -q world.php
is executed under condition, that PHP is set to
work in such regime. This remarkable capacity simplify debugging very much. No
compilation, no ñáîðêè, ….
PHP works in interpreter regime, and begins to apply successfully in the capacity of
script interpreter in UNIX platforms side by side with sh, bash, perl. Key –q suppress
the output of unwanted HTML information, which isn't essential in this case.
Example 1.2-2 Integration with HTML
<html>
<head> <title> Example </title> </head>
<body>
<?php
echo "Hello world!\n";
?>
</body>
</html>
|
Example demonstrates how PHP text is built in HTML pages.
For this sake the couple of tags <?php …?> framing the text in this language
is used.
Moreover, server should have means to indicate PHP code presence at page. The agreement
is usually taken that pages with absence of PHP code have htm or html
expansion in file name in contradistinction to those ones, which include PHP code and have
php extention.
These means allow to facilitate PHP interpretation for large sites by avoiding of
unnecessary analysis for pages without PHP code.
In above-cited example the server part will output purely (without any changes) all
HTML code, adding in title of page header “Example”, but also put in the result of
interpreted PHP code (which is the same as in former example). I.e. PHP interpreter
appears like transparent filter for HTML code.
You can study PHP in detail on official site www.php.net
Don't be scared that the list of PHP functions seemes
endless to you J . Hardly
you can need in most of them. But it's highly probable that there are some useful
functions just for your sphere of activity. The basic part of list, concerned strictly
with language, is rather compact.
And it's important fact, that collective and easy of access depositories of varied
applications wtritten in PHP are filling up very rapidly. Some attempts have been made
also to standardize this process. For example, the library of PHP classes can be
recommended. As for this capacity, it seems that soon PHP won't give up to Perl with its
reach depository CPAN. |
|
|
|
|
|
|
|
|
1.3. What is
Refal-PHP? |
|
|
|
|
|
Refal-PHP represents interface of Refal System with PHP ,
which allow to create cross-platform applications both on the
server side and on the client side, combining advantages of functional programming
language Refal with universal PHP language capacities. Created applications can be
modified easily for standalone regime, which doesn't require web server and browser
or, on the contrary, to intend them for working as server application.
We propose two interface alternatives, which are discussed in detail below.
First of them is an Refal extension by means of special function
<Php e.php> ,
where e.php argument is a PHP program. With the help of this function some additional
library functions have been created to operate with database and the function of
arithmetic expression evaluating over real numbers. These functions can be considered as
examples of additional capacities embedding into Refal language, while user may have no
suspicion about another language existence, excepting case when he needs in obvious exit
into PHP.
Second, more universal alternative, turns Refal into enjoying equal rights with PHP
(with regard to HTML) embedded scripting language, which have its own couple of tags
<?ref ... ?>
|
|
|
|
|
|
|
|
|
|
|
|
2. Interface
with PHP as Refal-extention |
|
|
|
|
|
This way in fact doesn't require additional
efforts from Refal users for studying new operational environment. It can be considered
that usual Refal-5 System is used (last 25.09.2000 version) with addition of new
functions. Principally, if the direct exit into PHP isn't required, then study of this
new language isn't obligatory. For instance, using of functions operating with DBS and
function of arithmetic expression evaluating over real
numbers doesn't require PHP
study. It is enough to make the acquaintance with new function specifications. The fact is
hidden from user that interface with PHP is involved.
Properly speaking, the same assertion can be referred to C and to Refal itself with
regard to creating of special functions and library modula with the help of this
languages. But in this care it is the question of language with very reach library of
interfaces, which provides rapid and effective creating of such modula, using the Open
Source technology advantage.
We'll demonsrate this approach in examples below and now let us consider the function,
which open, as a matter of fact, the PHP world for Refal. |
|
|
|
|
|
|
|
|
2.1. PHP
using in Refal programs |
|
|
|
|
|
Special function <Php e.php> calls PHP
interpreter from Refal, and transfer the argument to it which is Refal-expression
e.php represented by PHP text. The result of PHP program execution stay as a
string in view field of Refal-machine. Ïðèìåð 2.1-1
"Hello world!"
$ENTRY Go { = <Print <Php 'echo "Hello
world!\n";' >>;
} |
In this example the inner function “Php” first is executed, which calls PHP
iterpreter, sending the text <?php echo "Hello world!\n";> to
it.
Tags <?php …?> are automatically added.
After this PHP program execution the output string of symbols “Hello world!”, is
caught by “Php”-function and is feft just as its result in view field of
Refal-machine.
The next in turn call of Refal function “Print” results in output of this string
copy to standard output device, but leaves it in the view field. There is another function
“Prout” in Refal, which wipes out the string at time of output. It would be more
natural to use such function in given example, but we wrote more understandable
“Print” for clearness sake. |
|
|
|
|
|
|
|
|
2.2.
Data exchange between Refal and PHP environments |
|
|
|
|
|
In case of using function <Php
e.php> it's necessary to take into consideration the local variables scope of the
program e.php, which is limited only by given call of Refal function <Php...>.
Any new call of this function doesn't suppose safe keeping of PHP variables from any other
calls, including repeated ones. In case of such programming style the special functions
both in Refal and in PHP are provided to solve this problem. The idea is in organizing of
special common change buffer for necessary data transfer. In principle it's quite
analogous to box mechanism in Refal. Merely access to these boxes is possible not only
from Refal environment but from PHP one also.
There are those 4 functions ( PHP variable names begin from symbol $):
For Refal:
- <Write_var '$var=value'>
write into exchange buffer value value
for PHP variable $var .
<Read_var '$var'>
read value of PHP variable $var from
exchange buffer.
For PHP:
- write_var($var, $value)
-
- write into exchange buffer value $value
under the name $var.
-
- read_var($var)
-
- read value of varible $var from exchange buffer.
Example 2.2-1 Two PHP
calls
$ENTRY Go { = <Php '$var = 1;'>
<Prout "Second call for PHP ">
<Prout '$var= ' <Php '$var = $var + 1; echo $var;' >>;
} |
As a result instead of expected value 2 following text
- Second call for PHP $var = 1
-
- will be printed because the assignment of unity by first “Php” call will be
forgotten by second “Php” call. This unity will be added to unassigned (null) initial
value of variable $var.
We can improve such situation, using proposed exchange functions.
Example 2.2-2 Buffer change
$ENTRY Go { = <Php '$var = 1; write_var("\\$var",
$var );' >
<Print 'Second call for PHP' >
<Print '$var= '
<Php '$var=read_var("\\$var"); $var = $var + 1;
echo $var;' >
>
- }
|
Now the follwing text
Second call for PHP $var = 2
will be printed. Reverse slash (escape symbol) provides self transfer into PHP,
this is necessary when variable name is transferred as a parameter instead of
variable value.
In given implementation PHP call is rather expemsive operation. That's why the number
of transitions between Refal and PHP should be minimized. As foregoing example, if it
would be nothing between two “Php” calls then we could combine two calls in one and
the problem would disappear. |
|
|
|
|
|
|
|
|
2.3. On
paradigms of operational and functional programming languages |
|
|
|
|
|
It's easy to note that proposed way of data change between
fragments of Refal and PHP programs is rather inconvenient. But fortunately there won't be
greater necessity in it.
- The point is that execution process of program operators in such imperative language as
PHP is strictly determined by handling language contructions. But in functional
language Refal executive order of evaluations is defined while intepretation of
expressions being processed, and it can be complicated enough, especially by presence of
recursive functions.
-
- If for imperative languge recursion is rather exclusion than rule, then for Refal,
on the contrary, recursive definitions give the possibility to write very clear and
compact function descriptions.
-
- For this reason it's difficult to provide data agreement via global variables for
program fragments in these languages. If we'll want to use the PHP variable value in Refal
(and vice versa) in unsuitable moment, we run risks to get wrong variable value, either
unassigned one, or another taken from wrong level of recursive call.
-
- Therefore common recommendation is to avoid Refal and PHP data binding via buffer
functions with all defects inherent in global variable apparatus. That's just good, in
principle, that variable values in PHP program fragments are located inside Refal calls of
“Php” function.
|
|
|
|
|
|
|
|
|
2.4. Interface with
Data Base |
|
|
|
|
|
- PHP has the thought-out, convenient interface with databases, that is one of the most
advantageous quality of the language.
-
- The most popular and simple is MySQL DBMS. Fortunately, the simplicity of MySQL
doesn't at all mean the limitedness of its potentialities. This system is well scaleable,
and is not failing effectiveness while working with databases of large-scale enterprises.
-
- Interface is quite simple for that persons who know PHP and MySQL. Although the set of
functions described in previous section is enough for turning to databases from Refal, but
the set of undermentioned functions have been proposed for that users, who hasn't a great
wish to investigate thoroughly the details of PHP+MySQL interface, which give the total
universality, but require a large term for studying.
-
- Database is considered as electronic depository of data, which is organized in such way,
that provides convenient and quick search, re-stocking and modification (if necessary) of
these data. The electronic library of a book serves as a typical example of database.
-
- The so called relational databases and standardized query language (SQL) are known as DB
standard de facto. MySQL system just operates with these categories.
-
- More percise definition of "database" concept (DB) in this model can be
considered as follows: database is the aggregate of interrelated tables, and each of
them is determined by its own set of fields (columns). A table consists of rows (records)
which represent, properly speaking, the data themselves. In simple cases let's suppose
that DB consist of just one table.
-
- For example, such table represents DB:
-
- Data
|
- Weather
|
- 14.05.2002
|
- good
|
- 15.05.2002
|
- bad
|
Relational BD design provides a basic stage as tables constructing
(choice of field sets), appointing of interrelationship between tables, assignment
of key fields oriented on the set of search requests. All
this isn't a trivial pursuit, indeed, and we won't go deep into details.
- The proposed below set of special functions (in addition to Refal library) allows to
create table with given structure, to locate data in table for storage, and to select
these data. Naturally, the set of these operations can be extended to hide the details of
interface with PHP and MySQL, but at some moment user have to deside already, what
language level is preferable for him, and to apply his knowledge taking into account all
available opportunities.
-
- The interesting fact can be discovered, that Refal-PHP provides operating with DB
separately from web technologies, i.e. doesn't require web server or browser. It is
sufficiently to install the Refal+PHP+MySQL configuration for such operating (this case
will be considered in part 4 "Downloading,
installation and getting starting of Refal-PHP").
-
- Now we'll discuss Refal language functions for operating with DBMS MySQL and
example of their use. Let's suppose, that already we have the fixed database name at our
disposal (let it be "refal") and while Refal-PHP installation
the DB was initialised. As the Internet provider node, the DB name usually is given to new
user as a resource. As a rule user have no power to execute such operation himself. But
the DB owner have access usually to his own DB administration means on the level of
popular web-program phpMyAdmin, and any manipulation with DB is in its powers. Use of
phpMyAdmin implies that web server is available.
-
- The interface functions for connection with DBMS are cited below. They can be considered
as examples of such PHP+MySQL possibilities embedding into Refal, which doesn't
requier the compulsory acquaintance of Refal users with PHP and MySQL.
-
- <Db_open>
Opens the connection with DB.
<Db_close>
Close the connection with DB.
<Db_create_table (e.table)
e.structure>
Creates the table with e.table name and with the fields structure, defined by
e.structure. If the table exists in DB already, then the operation result is equivalent to
empty. The table fields (columns) structure e.structure represents a symbol string (enclosed
in single quotation marks!), which consists of pair, separated by commas (without
blanks after coma), and looks like
'<field> <blank> <type>, ….' .
For example, the following Refal function
<Db_create_table ('table1')
'm integer,a text' >
will create in DB ("refal")
the table named "table1", which consist of two fields
(columns), integer and text correspondingly, with names
"m" and "a".
There about 30 types of fields in MySQL, and detailed acquaintance with them is out of
our interests. It's enough for our examples to take two tradicional types: - text
– for string fields, and – integer – for defining of integers. If
more details are needed, refer to MySQL manual.
- <Db_select_table e.table>
-
- Select table e.table for processing. All next operations will be
execuited over this selected (current) table. Operation is necessary only if several
tables are processed simultaneously. Previous function <Db_create_table..>
automatically ends its execution with this select function, making current the table just
created.
-
- <Db_write e.record>
-
- Adds the record e.record to table.
<Db_read_field
e.field>
Reads into view field all records from table, selecting
only given column e.field.
<Db_read_all>
Reads into view field all records from table (completely,
with all fields).
- Let's for example write a Refal program, which asks for
string text in dialogue, store this string with its input date into DB, and prints all
records, located in DB at present. Here the table with two fields (data, record) is
considered as DB.
Example 2.4-1 Working with DB -
simplest case
$ENTRY Go { = <Db_create_table ('table1') 'data
text,record text'>
<Prout "Enter record">
<Db_write ‘"’
<Time> ‘","’ <Card> ‘"’>
<Db_print_all>
} |
- First function creates the table with name "table1" and two columns – data
and record, then this table is fixed as current, and the invitation to
user input is printed.
-
- Next function <Db_write...> at first is waiting for execution of
two inner calls - <Time> function returns into view field
the symbol string, which represents the current moment, and <Card>
function is waiting for string input, about what the user have been just informed.
-
- After "enter" press, the record formed from two fields, separated by comma, is
added to DB. In other words, the new string is added to table "table1".
Finally, the last program function reads
all records from DB and print them.
Next runnings of this program will add next
strings with new time values, in this cases the first function (table creation) isn't
mandatory. It will be treated as empty.
While writing of modified programs (bearing in
mind that the table have been created, and it isn't necessary to re-creat it)
instead of this function it's necessary to insert the call of table selecting function
<Select_table 'table1'>.
- Now let's complicate a little the pevious example. There is
the program, which requests the string text in dialogue mode, writes this string with
input date into DB, and prints the whole terminal input. Under DB there is meant the table
with two fields: data, record.
Example 2.4-2
Working with DB (Table with two fields)
$ENTRY Go { = <Db_create_table ('table2') 'data text,record
text'>
<Print "Enter record">
<Db_write '"' <Time>
'","' <Card> '"'>
<Db_print_field 'record'>
} |
- The first function creats the table named “table2” with two columns
(fields) – data and record, then this
table is fixed as
- current. Notice, that this is another table already.
-
- The second function prints invitation to input record.
-
- The next function <Db_write...> at first is waiting for two inner
calls - <Time> function returns in view field the symbol
string, which represent current moment, and <Card> function is
waiting string input, about what the user have been informed.
-
- After “enter” pressing the record wich was formed from two fields, separated by
comma, is added to DB. In other words current string is added to "table2"
table.
Finally, the last program line puts out all values from "record" field. Program, as it's written, is intended to operate in command line mode. For
operating via WWW it's necessary to program the information input. Refal function <Card>
power isn't sufficient for this obviously. While attept of running of this example on
general scheme, like as the previous example, with Apache server usage (see 4.4. Working with Refal-PHP System ), the refgo
process will hang up in data input waiting state.
|
|
|
|
|
|
|
|
|
2.5.
Mathematical functions evaluation |
|
|
|
|
|
As it known, the last version Refal-5 has no operations
with real numbers. Refal function proposed below
<Evalf e.expression>
eliminates this defect, permitting to use traditional arithmetic expressions with
mathematical functions in Refal programs. The set of more than 40 functions,
together with frequently used constants, is included into PHP system and operates with
computer representation of real numbers. The cross-platformed float and integer
arithmetics corresponds currently to the “C”
types long and respectively double. Maximal number value
about 1.8e308 with 14 digits precision (IEEE 64 bit format) is used typically.
- Any arithmetic expression in PHP syntax is acceptable as
e.expression. Resulting number is left in Refal machine view field in symbol string form.
Detailed description of functions see in PHP manual (LII. Mathematical Functions).
Ïðèìåð 2.5-1
Computer arithmetic
$ENTRY Go { = <Print
<Evalf 'sin(0.235)+cos(1/3)' >>
} |
|
|
|
|
|
|
The result is printed as:
1.1777999318272 |
|
|
|
|
|
|
|
|
3. Refal-PHP as
embedded scripting language |
|
|
|
|
|
|
|
|
This more universal variant of use of Refal language in
bunch with PHP presupposes the acquaintance with HTML and PHP. The idea is that code
fragments in Refal, which are singled out by couple of tags <?ref ...
?> , can be used on HTML pages construction in common with PHP code. |
|
|
|
|
|
|
|
|
3.1.
The most simple example "Hello World!"
Let's consider the most simple traditional example.
Example 3.1-1 "Hello
world!" - file hello.rphp
<?ref <Print "Hello world!\n">;
?> |
If the command
> refalphp hello.rphp
is executed in command regime, then "Hello World!" will be printed (as
expected) with succeeding line transfer. |
|
|
|
|
|
|
|
|
3.2. How does it function ?
Pages, which contain Refal-PHP code, are marked with rphp
extention in file name. The special compiler (refalphp) processes such
pages and creates the equivalent program and generates simultaneously the page of the same
name in pure PHP (hello.php), which doesn't contain Refal code fragments
already.
In its turn the Refal program of the same name is constructed from Refal code fragments
(hello.ref), which is compiled by Refal compiler and changes into
interpretable modulus of the same name again (hello.rsl), which is ready
to be executed by Refal interpreter refgo.
At corresponding places of PHP page there are dynamic calls (via refgo)
of this modulus with appropriate list of parameteres. The hello.php page
initiates its execution.
We have pointed out here (maybe excessively going into detail) just the specification
aspect, depending on the implementation, because this takes off immediately many questions
about what is possible and what isn't possiple (or isn't suitable) te be written in
Refal-PHP as in embedded scripting language. On the other hand, we shall consider minutely
the structure of dynamically generated programs in anothert part, which contains recommendations on debugging.
If it is the question of site and its pages, then, as a rule, it makes sense to execute
the preliminary processing of pages, which contain codes, by compiler refalphp,
for to have to do with generated php pages and interpretable Refal
module. Although, there are no hindrance for dynamical use of refalphp
modules in principle. |
|
|
|
|
|
|
|
|
3.3. General structure of
Refal-PHP program
Let define the Refal interspersing as all that is bounded by
Refal tags.
In general the refal code interspersing can assume as:
It may be the single call, for example,
<?ref <Time>
?>
or sequence of calls, for example,
<?ref <Func1
e.1> <Func2 e.2> ...<FuncN e.n> ?>
- Refal function definitions + function calls
For example,
<?ref
Func1 { .... } Func2 {
.... } ..... FuncN { ..... }
<Func1 e.1> ....<Card>... <Time>....
<XFunk e.x>
?>
Semicolon isn't put at the end of call (or several calls).
Within couple of tags <?ref and ?> the
Refal syntax operates with one implied extention, which is related to entry point $ENTRY
Go, necessary for usual Refal program. And it isn't necessary to indicate this
point in Refal-PHP. Corresponding initial point will be added automatically.
This is realized not only for convenience sake, but for another reason also.
All Refal interspersing finally are chanded into common Refal program. Function
descriptons, irrespective of any interspersing, including them, are gathed in the
beginning, and the rest function calls are mounted as function description also, but
having the special name sequel F_rphp_N. And automatically added $ENTRY
Go point leads to special function, which provides calls of F_rphp_N
functions for any given number N. Just these functions are called
dynamically from main PHP page, when PHP program runs.
In fact, the Refal program, which comes as a result of compiler refalphp
running, represents the modulus with N entry points.
Let's consider some examples.
Example 3.3-1 Refal function calls.
<?php echo "This is PHP\n"; ?> This is HTML
<?ref <Print "This is Refal"> ?>
<?php echo "This is PHP again"; ?> |
The result is printing of sequence of texts
This is PHP
This is HTML
This is Refal
This is PHP again
In above cited example the printing of phrase "This is Refal" is provided by
Refal interspersing of the single call of <Print ...>
function.
Example 3.3-2 Refal function's definition combined with calls.
<?ref
Func1 {
e.1 = <Print "Func1: " e.1>;
}
<Func1 "This is Refal">
?> <?php echo "This is PHP\n"; ?>
<?ref <Func1 "This is Refal again"> ?> |
The result will be
Func1: This is Refal
This is PHP
Func1: This is Refal again
|
|
|
|
|
|
|
|
|
3.4. Variables
and function calls scope
As it was mentioned before, from the logical point of view all Refal interspersings are
parts of the same Refal program. For this sake the scope of function names and global
variables (boxes) is spreaded over all Refal interspersings.
As the data change between Refal interspersings and PHP-fragments via PHP variables, in
present implementation it is realizable only with the help of functions providing data
change between refal and PHP program environments, which have been described in Part
2.2. Though there are plans to realize the data change via PHP variables which doesn't
require these service functions.
Example 3.4-1 Access to PHP variables
<?php $var = 'string_value';
write_var ('\$var', $var);
?>
<?ref
<Print '$var = ' <Read_var '$var'>>
?> |
The rusult is output
$var = string_value
|
|
|
|
|
|
|
|
|
4. Downloading,
installation and getting starting of Refal-PHP |
|
|
|
|
|
4.1. Alternative
working configurations Refal - (PHP, PHP+MySQL, PHP+MySQL+Apache) |
|
|
|
|
|
Depending on object which is pursued it's
possible to select different structure configuration for to work with Refal-PHP,
from minimal (Refal + PHP) up to complete one (Refal + PHP + MySQL + Apache). Refal + PHP and Refal + PHP + MySQL
versions don't require installation of Apache server and using of browser.
The minimal version require about 3 Ìbt, and the
complete one about 10 Mbt of hard disk space. These figures are rough, they change
depending on new versions of referred systems.
Installation procedure of Refal-PHP system imply that necessary components for selected
configuration (PHP, MySQL, Apache) either have been installed, or must be installed
independently. All these systems are free and have their own Open Source Licenses. Refal-5
is included in the distribution, but it may be recieved and installed separately.
Coirresponding site addresses are given below.
PHP - http://www.php.net ,
with Russified manual http://www.php.net/manual/ru/
MySQL - http://www.mysql.com , and
site http://www.mysql.ru/ (in Russian)
Apache - http://www.apache.org ,
with the Russian Apache support http://apache.lexa.ru/
Refal-5 - http://botik.ru/pub/local/scp/refal5/refal5.html
, and also http://www.refal.net/doctrain.html
|
|
|
|
|
|
|
|
|
4.2. Windows 9x/ME/NT/2000/XP
platform |
|
|
|
|
|
- After installation of necessary components ( PHP as minimum), download the distribution
of last version of Refal-PHP here and unzip it in any
directory.
- Enter the directory rphp-<date>-<version>-win32
(for instance, it may be rphp-021128-0.1.0-win32) and run install
instruction, it results to the directory <rphp_home> (default c:\refalphp).
- Copy this directory together with installed PHP System (keeping the same name php)
into <rphp_home>.
At this point the installation of minimal vession (Refal+PHP) is over. For
expanded version installation it's necessary to copy in addition (depending on your
choice) already installed Apache and/or MySQL into the same directory <rphp_home>,
and then to run insruction <rphp_home>\tuning.bat.
If operating with DB and Apache server is intended, then phpMyAdmin
should be persistently recommended to install as well, using the directory
<rphp_home>\www\ for it. Installation procedure for phpMyAdmin is reduced to
simple copying of unzipped distribution content (for example, content of
phpMyAdmin-2.3.3-rc1 directory) into <rphp_home>\www\phpMyAdmin. No
additional tuning is needed. PhpMyAdmin call from browser must be done by URL: http:\\localhost\phpMyAdmin (Apache server have to
be started). The program has a friendly interface (up to automatic recognition of Cyrillic
alphabet). You can see and select DB "refal" among those
ones wich will be proposed for your choice.
|
|
|
|
|
|
|
|
|
|
|
|
4.3. UNIX platform |
|
|
|
|
|
Most of popular Linux distributions contains already PHP, MySQL and Apache support.
Therefore Refal-PHP installation procedure,on the whole, is reduced to Refal-5
installation for corresponding UNIX version. Download the last Refal-5 System distribution
with sources here, unzip it
and follow instruction on UNIX System installation. The special distribution on
Refal-PHP installatiion for UNIX is preparing now, but there's no special need in it,
principally. The source texts, which are included in distribution for Windows platform,
are the same practically. The main change to be done in some places, is substitutions of
slash instead of each back slash in whole directory paths.
In other respects you may follow recommendations of section 4.7. Additional information fpr system
programmers on Refal-PHP System embedding in already installed Refal+PHP+MySQL+Apache
configuration and ñhoose <rphp_home> location at the most suitable place for you.
|
|
|
|
|
|
4.4. Working with
Refal-PHP System |
|
|
|
|
|
The most simple is to begin work with Refal-PHP system, running the demo examples
which are given in present guide. They are disposed in directory <rphp_home>\www\demo
. On default <rphp_home> = c:\refalphp is the system home
directory. If complete version (Refal+PHP+MySQL+Apache) have been installed, then
it's necessary to run Apache server ( data base server MySQL will be run automatically
with it). Useful advice: create icons "Start" for command
<rphp_home>\start.bat and "Stop"
- for <rphp_home>\stop.bat at the Windows desktop. After
running Apache by "Start" command (while this action the background process will
arise for Apache application), it'necessaty to call http://localhost
page by any brouser . As a result present guide will appear again, but all examples in it
will be "alive", it means, that example's execution will be possible in
real time mode after pressing "submit" button close by example.
Such guide version (with interactive execution of examples) is included in the
distribution. After end of work with Refal-PHP it's necessary to execute "Stop"
command to stop Apache and MySQL servers.
While work in command line mode <rphp_home>\www\demo must be the
working directory , otherwise take the special care about PATH
variable as usual.
Example structure in case of Interface with PHP as
Refal extention
All exaples are arranged in the same way. Let's consider one of them in detail.
Example 2.5-1 Computer
arithmetic.
For example execution in command line mode minimal configuration (Refal+PHP) is
suffucient, and in case of complete configuration it isn't necessary to run Apache server
.
Three files are associated with this example:
- example251.ref
- example251.rsl
- example251.php
First (basic) file is the source text in Refal-5
$EXTRN Evalf;
$ENTRY Go { =
<Print <Evalf 'sin(0.235)+cos(1/3)'>>
}
Using of PHP is reflected here only in special Refal function <Evalf
...>, described formely in this guide. In examples which are given in text we
took some liberties, omitting $EXTRN descriptions for to make guide text more compact,
because with the aid of another libraries' organizing in Refale-5 and Refal-PHP these
descriptions can be avoided.
The second file can be obtained as a result of Refal-5 compiler's work. For that
it'necessary to execute command
> refc example251
All examples, included in distribution, have passed the compilation phase already, and
as result of it files rsl extension have appeared, in so
called intermediate assembly language, ready for effective interpretation by command refgo.
All you need to do now - to execute command
> refgo example251+..\lib\rphplib
Additional text with plus sign is reference to run time library during Refal programs
execution.
The result will be printed as: 1.1777999318272 .
The third file is necessary only when client-server web technology is used. What is
necessary for it that is Apache server should be run. This scheme does'nt differ
principally from that one, which is used in real Internet. Moreover, if your
computer is connected with real Internet and is visible in it, it's necessary to take
preventive measures to defend youself from hackers' attacks. These things have a principal
nature and does'nt belong tp our examinations. We shall consider, that our computer
is local, maybe is included in local (Intranet) network, which is protected against such
dangers :).
The third file of example251.php is looking like:
<?php echo `refgo example251+..\\lib\\rphplib`; ?>
It can be easily noticed that it's the same command, which has to be executed in
command line mode, just framed by some environment, which allow browser to refer this text
as HTML page, parsed by PHP interpreter. In this case our page contains nothing but PHP
text. Single left quotation mark has the special meaning in creation of PHP lines, namely
it is an instruction to execute immediately the code in quotation marks. The back slash is
dobled because it has the special meaning (to escape the next symbol). The echo command
redirects output to standard one. And finally browser will show a page, which have been
dynamically generated.
It's easy to notice, that after executing in command line mode the following
instruction
php -q example251.php
we can see the same result, which is obtained by scheme Apache --> browser -->
screen.
Indeed, this very valuable quality of PHP interpreter must be used for preliminary
debugging of pages with PHP code in the time of sites developing, especially in case when
your hosting is remote.
Example structure in case of Refal-PHP as embedded
scripting language
In this case source files have rphp extention.
Let's consider Example 3.3-2 Refal
function's definition combined with calls
File example332.rphp has form:
<?ref
Func1 {
e.1 = <Print "Func1: " e.1>;
}
<Func1 "This is Refal<br>">
?>
<?php echo "This is PHP\n"; ?>
<?ref <Func1 "This is Refal again"> ?>
After processing of this file by special command, which calls refalphp compiler,
this page is transformed in triple of files having structure, described in former section.
Namely, following files are generated:
File example332.ref
* Refal run time module for page example332.rphp
$ENTRY Go { = <Mu <Implode <Arg 1>> <Arg 2>> }
Func1 { e.1 = <Print "Func1: " e.1>; }
F_rphp_1 { =
<Func1 "This is Refal<br>">;
}
F_rphp_2 { =
<Func1 "This is Refal again"> ;
}
file example332.rsl
(result of compilation) and
file example332.php
// PHP run time module for page example332.rphp
<?php include("..\\lib\\rphplib.php"); ?>
<?php
$out = `refgo example332+..\\lib\\rphplib F_rphp_1`;
echo "$out";
?>
<?php echo "This is PHP\n"; ?>
<?php
$out = `refgo example332+..\\lib\\rphplib F_rphp_2`;
echo "$out";
?>
There are two ways of using refalphp compiler
- one is static, when module with rphp extentiom is processed preliminary
by command rphp_c, and other is dynamical, when compiler is called by
command rphp_cgo. In second case the command may come from PHP pages, it
executes the same operations as rphp_c, but after that leads to immediate
execution of module with php extension (for given example it is example333.php).
It's possible also to execute all foregoing commands in command line mode.
Examples with rphp extension of this guide have
been processed by command rphp_c. Sourse texts of resulting Refal modules
are not needed in principle, but are reserved for a training sake.
|
|
|
|
|
|
|
|
|
4.5. Recommendations on program debugging |
|
|
|
|
|
|
|
|
Refal-5 System has an embedded debugger. PHP system hasn't such one, but there are
some elaborations, which facilitate debugging to some degree, (see, for example, http://apd.communityconnect.com/ ). We are
far from such mission as to give general recommendations how you should (or shouldn't)
debuge Refal-5 or PHP programs. But there is the outline of Refal-PHP System specific
character and knowledge of it makes possible to simplify dubgging essencially without
using special debug means.
- There is a working directory <rphp_home>\www\demo\ws_rphp_tmp
in this system. Variable values are kept in this directory as a resulting files of
buffer exchange (see 2.2. Data Exchange between Refal and PHP environments). These
file have the same names as the variables corresponding to them.
- Immediately after execution of Refal function <Php e.1> two
files php.in and php.out are formed
in <rphp_home>\www\demo\ directory. The first file contains
PHP fragment text, and the second one is the result of its execution.
- While rphplib.php creation the debugging mode is provided. In the
second line of rphplib.php file is (default) operator define("debug",
0) , switching off debugging output. If 0 is changed to1, then debugging output
is enabled.
It is sufficient to stop temporary the investigated program at desirable point, for
example, to insert <Card> function into Refal-5 program,
which result is waiting of input from terminal. After that it's possible to look for
(without input execution) the content of referred files, and a new session have to be open
for this purpose.
Let's examine the example 2.4-2 - (Working with DB (Table with two fields)). Program was
invented for to work in command line mode and it was tuned up for terminal input, which is
provided just by refal function <Card>.
Running this program by command
> refgo example242+..\lib\rphplib
we can obtain the warning on screen, which
precedes the inviting program line ("Enter record")
PHP Warning: mysql_connect()
[http://www.php.net/function.mysql-connect]: Can't
connect to MySQL server on 'localhost' (10061) in C:\refalphp\www\lib\rphplib.php on line
55
and means, that MySQL hadn't started. None the less, after that the program prints the
invitation "Enter record",
and passes to the input data waiting. There is no sence in doing anything else, because we
can to foresee the next error messages which will accompany all further attepts to include
in DB our input data.
Then we must stop our program by CTRL-C
combination, and correct our mistake. We run Apache and MySQL servers again by "Start"
icon and repeat the command refgo example242+..\lib\rphplib.
When invitation "Enter record"is
received, let's leave temporary the input waiting window and open another session, in
which we can view the content of referred files by any text viewer. If the debugging mode
in rphplib.php is swiched on we can watch following things at this
moment.
There are no any new files in working directory ws_rphp_tmp
(maybe some old ones have been left after previous work),
The php.in file content is as follows:
<?php include ('..\lib\rphplib.php');
db_open(); db_create_table(table2,"data text,record text"); ?>
And the php.out file content is:
Function: db_open
HostName=/localhost/
UserName=/test/
Password=//
-------------------
Function: db_create_table
table=/table2/
structure=/data text,record text/
-------------------
This output gives rather informative confirmation that two operations were rightly
executed - connection to MySQL server and creation of table2
table.
Now let's return to the input data waiting window,
and input for instance "qu-qu". The executed program will
put in DB the string with two fields and put out on the screen all DB records, selecting
the second field record only, from table2
table. In given case we'll get only a single string at the screen
qu-qu
because only one string have been formed in DB. When program is finished we can
watch again the contents of working directory ws_rphp_tmp and of
files php.in and php.out.
File php.in is as follows:
<?php include ('..\lib\rphplib.php');
db_read_field (table2,record, "\$all_base"); ?>
File php.out:
Function: db_read_field
table=/table2/
field=/record/
all_base=/$all_base/
-------------------
In this case two files $all_base and $record
have appeared in ws_rphp_tmp directory.
File $all_base: qu-qu
File $record: "Wed Dec 04 19:36:54
2002","22222"
If we'll repeat running of the program by refgo example242+..\lib\rphplib
command, then new strings will be put in DB, and the program will put out the more longer
column of record field content.
We hope that such enough (or maybe excessively) detailed description will make the
debugging process in Refal-PHP more convenient for you. |
|
|
|
|
|
|
|
|
|
|
|
4.6. Some "small
items" |
|
|
|
|
|
As is well known there are no small items in programming. But for exposition
clearness sake we would like to avoid many technical minuteness in basic text of this
guide. However they have to be marked especially for they have not to be lost in any case.
We have chosen two moments for the present. Perhaps, in fututre this section will be
supplemented by new remarks.
- About quotation marks in Refal-5. In last version of Refal-5
System (with new syntax) single quotation marks and double ones are not equivalent.
Namely, double quotation marks have, if we could say, "freezing" effect. All
that is between double quotation marks after Refal compiling is trancformed in atomic
symbol. For that reason, if you noticed, in (2.4) section, describing
the DB interface functions, the fact was accentuated that string with fields' structure
description have to be enclosed in single quotation marks. Otherwise further
character-by-character processing of this string while buffer exchanges between Refal and
PHP Systems would be impossible. You can enclose in double quotation marks only that text,
which won't be put in further processing, and only in cases, where you could not have
managed with one couple of quotation marks.
- About HTML format printing and terminal output. The examples
given in present guide persue an object to combine (for the simplicity sake) two modes of
working - the command line mode (in DOS session) and work via WWW mode (in series
Apache -> browser -> screen). Therefore, as to information output, we didn't manage
to obtain the same output format in these cases. In that guide places, where the
information output is demonstrated, some difference may be occured. Namely, instead of
column output while example executing in command line mode, all may be put out as one
continuous string while examination by WWW technology. And
on the contrary, some examples, which are executed in a command line mode, will put out
HTML syntax in addition to output data. First of all it concerns to the symbol of a new
line. Symbol "\n" is enough for transition to a new
line only for terminal output, and for browser case it is necessary to use <br>.
The specific of HTML format output must be taken into accont in your
programs.
|
|
|
|
|
|
|
|
|
4.7. Additional
Information for system programmers |
|
|
|
|
|
The present section is an auxiliary one, it isn't necessary if you had not problems
with installation and running of Refal-PHP. Otherwise information given here can help you
to solve the occured problems if you'll ask for consultnig some persons who are
experienced in PHP, MySQL, Apache installation and operating. Unfortunately, it's
difficult (and perhaps it isn't expedient) to write quite automatic procedure for to
install an expanded version of Refal-PHP System, for the simple reason that there is a
great variety of versions and configurations for Apache and MySQL.
Installation procedure for Refal-PHP System is rather simple. The idea of it is to copy
previously istalled PHP, MySQL, Apache Systems and properly the Refal-PHP itself (install.bat
script) into <rphp_home> directory. Then the configuration httpd.conf
file for Apache has to be corrected and "refal" DB
for MySQL (tuning.bat script) has to be opened.
It must be done for to not disturbe the functioning of PHP+MySQL+Apache Systems, which
maybe have been installed before. Indeed, if you are properly experienced, you can avoid
such copying and embed Refal-PHP as addition into the configuration which you have in your
disposal. In this case you may correct htppd.conf, if it's necessary, and
creat "refal" DB in MySQL by phpMyAdmin, for instance.
Finally, it's necessary to correct the file <rphp_home>\www\demo\php.bat,
which depend on php.exe location. It's supposed that Apache have been
installed with the capacity of PHP call in CGI mode. Otherwise (PHP module alone),
Refal-PHP won't be able to work. After that you may run the Apache server and
operate in accordance with section 4.4. Working with Refal-PHP System .
At last several words have to be said about how far effective is the Refal-PHP
implementation. System's present version, of course, can provoke reprimands concerning
with possible non-effective functioning, which is especially noticeable for Windows-95
platforms because of non-effective implementation of php.exe interperter
call (via Refal function <System...>). But it wasn't the priority
author's mission to increase the effective functioning degree. The main puspose was an
improving of language interface while embedding of Refal into HTML. Moreover, the reserved
means of increasing the effective functioning degree is well-known - thas is to write a
corresponding module for Apache server, like as existing now PHP module
implementation, more effective than PHP for CGI.
|
|
|
|
|
|
5. Appendix A |
|
|
|
|
|
A.1. Demo examples |
|
|
|
|
|
Example 1.1-1 "Hello
world!"
$ENTRY Go { = <Print "Hello world!\n">;
} |
As a result the program prints the
traditional phrase "Hello world!" with succeeding line transfer.
Example 1.1-2 Palindrom
$ENTRY Go { = <Print <Pal 'revolver'>>; } Pal {
= True;
s.1 = True;
s.1 e.2 s.1 = <Pal e.2>;
e.1 = False;
} |
As a result of analysis of input string 'revolver' the program prints value False.
Example
1.2-1 "Hello world!"
<?php echo “Hello world!\n";
?> |
The printing “Hello world!” as a result of foregoing PHP program running you could
see also while work in command string rigeme if such command have been executed
> php -q world.php
Usually this code is processed on the server side, and browser (client) demonstrates
phrase "Hello world!" at its own window.
Example 1.2-2 Integration with HTML
<html>
<head> <title> Example </title> </head>
<body>
<?php
echo "Hello world!\n";
?>
</body>
</html>
|
Example demonstrates how PHP text is built in HTML pages.
A couple of tags <?php and ?> framing the PHP text
is used for this purpose.
Example 2.1-1 "Hello
world!"
$ENTRY Go { = <Print <Php 'echo "Hello
world!\n";' >>;
} |
The most simple example of application of interface Refal function <Php...>.
Refal program will print the result of PHP program.
Example 2.2-1 Two calls PHP
$ENTRY Go { = <Php '$var = 1;'>
<Prout "Second call for PHP ">
<Prout '$var= ' <Php '$var = $var + 1; echo $var;' >>;
} |
As a result, instead of expected value 2, two strings
- Second call for PHP
- $var = 1
-
- will be printed, because the fact of assignment of unity in time of the first call
“Php” function will be forgotten on the second call “Php”. Unity will be added to
unassigned (null) initial value of variable $var.
Situation can be improved by using of suggested change functions.
Example 2.2-2 Buffer change
$ENTRY Go { = <Php '$var = 1; write_var("\\$var",
$var );'>
<Print "Second call for PHP ">
<Print "$var= "
<Php '$var=read_var("\\$var"); $var = $var + 1;
echo $var;'>
>;
- }
|
Now the result will look like printing
Second call for PHP
$var = 2
Example 2.4-1 Working with Database
$ENTRY Go { = <Db_create_table ('table1') 'data text,record
text'>
<Print "Enter record">
<Db_write ‘"’ <Time> ‘","’ <Card>
‘"’>
<Db_print_all>>
} |
-
- The first function creates the table with name "table1"
having two columns (fields) – data and record, then
this table is fixed as current one. The second function prints the offer to input record.
-
- The next function <Db_write...> at first waits for execution of
two inner calls - ôóíêöèÿ <Time> function returns into view
field the symbol string, which represents the current moment, and <Card>
function waits the string input, about what the user have been informed.
-
- After click of "enter" the record, formed by two fields, separated with
comma, is added to database. In other words the next row is added to table "table1".
At last the final operator of program gets and prints all records from database.
Example 2.5-1 Computer arithmetic
$ENTRY Go { = <Print <Evalf 'sin(0.235)+cos(1/3)' >>
} |
The result is printing of:
1.1777999318272
|
|
|
|
|
|
A.2. Refal-PHP function
libraries |
|
|
|
|
|
Below there is the list of
functions, which have been considered minutely in this guide, in form of two
libraries, for Refal and PHP systems correspondingly.
RPHPLIB.REF Library
<Write_var
'$var=value'>
write into exchange buffer value value
for PHP variable $var .
<Read_var
'$var'>
read value of PHP
variable $var from exchange buffer.
<Db_create_table (e.table) e.structure>
Creates the table with e.table name and with the fields
structure, defined by e.structure.
- <Db_select_table e.table>
-
- Select table e.table for processing.
-
- <Db_write e.record>
-
- Adds the record e.record to table.
<Db_read_field
e.field>
Reads into view field all records from table, selecting
only given column e.field.
<Db_read_all>
Reads into view field all records from table (completely,
with all fields).
<Db_print_field
e.field>
Prints all rows from the table, selecting only given field
e.field.
<Db_print_all>
Prints all rows from the table (completely, with all
fields).
<Evalf
e.expression>
Evaluate e.expression as any arithmetic
expression in PHP syntax.
RPHPLIB.PHP Library
- This library contains more functions as compared with number of ones analysed in guide
examples. These "additional" service functions are used in Refal library rphplib.ref
via <Php ...> function for building of afore-mentioned
"high-level" Refal functions. The knowledge of them isn't necessary as a rule.
-
- write_var ($var, $value)
-
- Write into exchange buffer value $value
under the name $var.
-
- read_var ($var)
-
- Read value of varible $var
from exchange
buffer.
-
- db_open ()
-
- Opens the connection with DB.
-
- db_close ()
-
- Close the connection with DB.
-
- db_create_table ($table, $structure)
-
- Creates the table $table with the field
structure $structure.
-
- db_write ($table, $fields, $values)
-
- Writes values $values into fields $fields
of the table $table.
-
- db_read_field ($table, $field, $all_base)
-
- Reads all rows from the table $table,
assigning only given field $field values to $all_base
variable.
-
- db_read_all ($table, $all_base)
-
- Reads all rows from $table into $all_base
variable.
|
|
|
|
|
|
|
|
|
A.3. The License |
|
|
|
|
|
Copyright © 2002 Leonid Belous
All rights reserved.Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
- Neither the name of the Refal-PHP nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|