Basics
Frag uses a very simple and uniform basic syntax, which is extensible in many ways.
If you have programming experiences, you can learn enough to write interesting Frag
programs within a few hours.
This section provides a quick overview of the main syntactic features of Frag.
Frag's syntax is inspired by the language Tcl. This section uses adapted examples
from the Web page Tcl Language to illustrate
the similarities for those familiar with Tcl.
Note that the object concepts etc. that follow in subsequent sections are
substantially different to Tcl's concepts.
Frag programs are made up of invocations separated by newlines or semicolons.
Invocations all have the same basic form illustrated by the following example:
obj methodName arg1 arg2
This invocation sends the message methodName to the object obj, and methodName receives
the arguments arg1 and arg2. All elements of invocations are separated using whitespaces.
There's one important special form of invocations: commands. Commands
(see Section Commands) are object's
which - in principle - process all invocations using the same method, so the methodName
can be omitted. A typical command example is:
math sqrt 1
This command performs a calculation of a mathematical function. As a result 1.0
is printed.
You can try out this example and all the others in this page by typing
them into the interactive Frag shell, or by executing a program file that contains
this invocation.
Each Frag invocations consists of one or more words separated by whitespaces.
In this example there are three words: math, sqrt, and 1.
A Frag invocation always returns a result.
If an invocation has no meaningful result then it returns an
empty string as its result.
If you want to write something to the console output, puts can be used.
puts prints a line msg to a channel. The default channel is out, the standard output.
Alternatively err, the standard error channel, can be chosen. Per default,
puts prints a line break after printing msg. This can be turned off using the
-noNewLine option.
It has the following syntax:
puts ?-noNewLine? ?channel? msg
Usually, you use puts with only one argument, such as in the example of
printing a b c to the standard output channel followed by a line break:
puts "a b c"
Consider the example of
printing a b c to the standard error channel followed by no line break. Here we
need to use the -noNewLine option and the err channel:
puts -noNewLine err "a b c"
You can also read from the console using gets.
gets reads a string line, ending by carriage return, from the standard
input. The syntax is simply:
gets
The variable x gets the input from the standard input, and then this input
is read from the variable (for more explanation on variables see below)
and written to the standard output using the puts command.
set x [gets]
puts "You wrote: $x"
Frag allows you to store values in variables and use the values later on.
The set command is used to write variables.
For example, the following invocation modifies the variable x to hold the
value 4:
set x 4
The command returns the new value of the variable.
You can read the value of a variable by invoking get:
get x
You don't need to declare variables: a variable is created automatically
the first time it is used. Frag variables don't have (visible) types:
any variable can hold any value. Internally the variables are converted to
a suitable type, such as integer in the example above.
To use the value of a variable in a command, you can use variable
substitution as in the following example:
math sqrt $x
When a $ appears in an invocation, Frag treats the characters following it
as a variable name, and substitutes the value of the variable
in place of the name. In this example, the actual argument received by the
math sqrt command will be 4 (assuming that variable x was set as in the
previous example). You can use variable substitution in any word of any
command, or even multiple times within a word:
set cmd math
set x 16
$cmd sqrt $x
This code executes the command math sqrt 16.
A variable name ends with the next whitespace or reserved character (like $).
You can include such characters in a variable name by using quotes and braces, as in the following example:
set "my whitespace var" 1
puts ${my whitespace var}
You can also use the result of one invocation in an argument to another invocation.
This is called code substitution:
set b [math sqrt 4]
When an opening square bracket appears in an invocation, Frag treats everything
between it and the matching closing square bracket as a nested invocation. Frag
evaluates the nested invocation and substitutes its result into the
enclosing invocation in place of the bracketed text.
In the example above the second argument of the set invocation will be 2.0,
and hence the variable b will be set to that value.
If a backslash ('\') appears within a word then backslash substitution occurs.
In all cases but those described below the backslash is dropped and the
following character is treated as an ordinary character and included in the word.
This allows characters such as double quotes, close brackets, dollar signs, and
backslashes to be included in words without triggering special processing.
The following lists some backslash sequences that are handled specially, along
with the value that replaces each sequence.
\r - Carriage-return
\n - New line
\t - Tab
\u - Unicode sequence (4 hex digits), e.g. \u0042 for B.
Double-quotes allow you to specify words that contain spaces.
For example, consider the following code:
set x 24
set y 18
set z "$x + $y is ($x + $y)"
After these three invocations are evaluated the variable z will have the
value "24 + 18 is 42". Everything between the quotes is passed to the set
command as a single word. Note that (a) command and variable substitutions
are performed on the text between the quotes, and (b) the quotes themselves
are not passed to the command. If the quotes were not present, the set
command would have received 6 arguments, which would have caused an error.
Curly braces provide another way of grouping information into words.
They are different from quotes in that no substitutions are performed on the
text between the curly braces:
set z {sqrt of $x is [math sqrt $x]}
This command sets variable z to the value:
sqrt of $x is [math sqrt $x]
Backslashes are also used to construct overly long lines - spanning across multiple lines.
If a backslash is found as the very last character of
a line - just before the newline character, the newline character is ignored and the line continued.
In the following example "d e f" is appended to the previous line:
list build a b c \
d e f
Please note that it is not necessary to backslash lines in blocks (i.e., in square braces and curly braces).
They automatically
span multiple lines. For instance, the following is legal code:
set x [list build
a b c
d e f]
set y {
a b
c d
}
In Frag, expressions can either be given in control structures or as arguments to commands.
Frag's expression syntax is similar to the C/Java expression syntax. For instance,
in the following code, a boolean expression is evaluated in an if-statement:
if {$r > 5} {
set x 0
}
Round braces can be used to evaluate an expression through expression substitution. That is,
the expression is evaluated on the fly, and the result of the expression is returned. For instance,
the following code evaluates the same expression as above, and writes
the boolean result true or false into the variable y:
set y ($r > 5)
Expression can be used to perform all kinds of other calculations, not only boolean
operations. For instance, we can perform a multiplication:
set y (5 * 3)
For a detailed description of the expression syntax and operators, see Section Expressions and Mathematical Functions.
Unparsed regions are a special syntax in Frag. They are used for easily building up code,
which is written in other languages, or Frag code which should not be parsed directly, but consumed
later. Unparsed regions use the rather seldom used characters:
`...`
as a delimiter. Everything
in an unparsed region is handed to the user program without parsing.
The following code creates the head of an HTML document using unparsed regions
and invocations/variable access with $ inside:
set head [string build `
<head>
<title>`[$doc get title]`</title>
<meta NAME="description" CONTENT="`[$doc get description]`">
`$cssText`
</head>`]
The following code creates a number of similar Frag methods in a foreach loop using
unparsed regions to delimit the generated code template:
Object create TextCommands -classes TextCommands
foreach {methodName mmClass} {
section Section
bf Bf
subSection SubSection
subSubSection SubSubSection
paragraph Paragraph
em Em
bf Bf
tt Tt
bulletList List
item ListItem
} {
set code [string build `TextCommands method `$methodName` {text} {
set o [`$mmClass` create]
$o element [DocDSL mapText [textParser parse $text]]
return $o
}`]
eval $code
}