REBOL is designed by Carl Sassenrath, former primary developer of AmigaOS.
Table of contents |
2 Examples 3 Dialects 4 Grammar Rules |
The REBOL interpreter is available for a wide range of platforms (over 40).
It provides platform-independent graphics and sound access; and it comes with its own windowing toolkit and widget set. The REBOL community is interlinked through a "REBOL desktop", a graphical representation of REBOL-related files stored on the Internet, which is installed together with the REBOL interpreter. The REBOL desktop itself is a REBOL application.
REBOL is designed to handle a wide range of applications, but specifically aims to make distribution of objects and use of network connections simple. It has many specific data types, including a currency type and a URL type.
REBOL is context sensitive which provides support for dialecting. A classic example of REBOL's context sensitivity is seen with the word return. Under normal evaluation, return exits a function possibly passing back a result value. In the context of the Visual Interface Dialect (VID), an occurrence of the word return causes the layout engine to behave similar to carriage return, moving the "rendering pen" down to the beginning of the next line. REBOL programmers can create their own dialects possibly reusing any existing REBOL word with a different meaning in the context of the dialect.
view layout [text "Hello world!" button "Quit" [quit]]
send branko@collin.example read " class="external">http://www.rebol.com
Notable features
Examples
REBOL [
Title: "Hello World Window"
File: %hello.r
Date: 12-January-2002
Purpose: "Display the words in a window"
Category: [view VID 1]
]
And here is a simple internet application that uses two internet services, HTTP and SMTP:REBOL [
Title: "Web Page Emailer"
File: %sendwebpage.r
Date: 12-January-2002
Purpose: "Get an HTML document from the web and send it through e-mail"
Category: [web email net 1]
]
For many more examples, try the | REBOL Script Library
The source code of the REBOL interpreter is closed, and the interpreter must be licensed for distribution of commercial applications. REBOL is currently available online at: " class="external">http://www.rebol.com
REBOL provides a native function called parse which you can use to define domain specific languages, often referred to as dialects, by specifying grammar rules in a BNF-like format, much as you would for a parser building tool like YACC or Bison. Your rules are interpreted by REBOL at runtime; they are not used to generate code. You can include actions to be taken during the parsing process as well.
Using parse against a string allows you near-complete flexibility, but requires more effort, as it is a lower level approach. Block parsing makes it easier to create dialects, but there is a tradeoff. In block parsing mode, REBOL handles the lexical scanning for you and your rules are written at the level of REBOL values, not characters and delimiters. The up-side to this is that you can write your rules at a much higher level of abstraction; the downside is that your data must fit within the standard REBOL lexical form.
Another way to look at this is to say that a dialect is a sub-language of REBOL.
The rules you feed to the parse function are, themselves, written in a dialect of REBOL. When parsing strings, a subset of REBOL datatypes can be used in rules; in block parsing mode, all REBOL datatypes can be used along with some other features that make building sophisticated dialects easier.
Rather than try to cover all the details of writing dialects, I'll just provide a couple small examples:
This first example will parse a string, looking for some specific words, and copying parts of the data out which are variable, and that may be used elsewhere. In this example, all the parts copied from the string are, themselves, strings.
foreach string strings [
print string
; Our rules go in a block, enclosed by square brackets
parse string [
; Each string should start with one of these words. COPY will
; copy the text of interest so we can use it later.
copy how ["write" | "send"] (print ["How:" how])
; Now, copy everything up to the next space, which should
; then be followed by either "a" or "the". We use parenthesis
; to define actions to take when a rule succeeds.
copy who to " " ["a" | "the"] (print ["Who:" who])
; Finally, copy everything to the end of the string.
copy what to end (print ["What:" what])
]
print ""
]
Let's say you have a file analysis utility, and you want to provide an easy way for users to specify which files to operate on, what times to run it, where to post the results, and who to notify. A dialect could be used to provide a flexible text-based interface for this kind of task.
Here are two sets of commands users might send to the app. Note that the dialect allows for multiple items, alternate word orders, and optional words that a person might include for readability, but which shouldn't affect the program's operation.
; Words that have an apostrophe before them are literal words we want to match.
; Words that end with an exclamation are datatypes we want to match.
; SOME means "one or more". Like "+" in a regex.
; OPT means optionally, i.e. "zero or one".
; SET causes a word to refer to the value matched for later use; like setting
; a variable.
foreach block command-blocks [
print mold block
parse block [
some [
['analyze some [set file file! (print file)]]
| ['notify some [set who email! opt 'and (print who)]]
| ['at set when time! (print when)]
| ['post opt 'results 'to set target url! (print target)]
| 'again
| 'and
] to end
]
print ""
]
Dialects
Grammar Rules
String Parsing Example
strings: [
"write Graham a thank-you note"
"send Allen the new source code"
]
Block Parsing Example
command-blocks: [
[
analyze %test-1.txt %test-2.txt
post results to http://www.wikipedia.org/results.dat
notify rebol-xyz@wikipedia.org at 10:00 and again at 10:00pm
]
[
at 10:00 and at 10:00pm analyze %test-1.txt notify
rebol-xyz@wikipedia.org and reb-guy@wikipedia.org
post to ftp://wikipedia.org/results.dat
]
]
In the example above, the file, email, time, and url values are all native datatypes in REBOL, so the values extracted during the parse operation could be directly applied in REBOL expressions. For example, the who value could be used with the send function to send email notifications, and the url value with the write function to post the data.