A global variable is created on the first time it is referenced. Scalar variables are created with the value (and type) NIL.
Variables are normally referenced by their name. A variable name must
start with underscore or letter and can consist underscores, letters and
digits
A variable is a piece of data memory, named by the variable name.
A global variable is a variable that is accessible from every function within a script and will always access the same memory region with the same name. A global variable exists from the time the script is loaded until it is unloaded.
A local variable is function-local: it exists only for a specific call of a function; different functions or different calls of the same function will see a different memory location using the same local variable name. More on local variables in chapter 4. This chapter will deal with global variables only.
Each variable is either a scalar or an array. A scalar variable holds a single value, an array holds multiple values. This chapter describes scalars only - more on arrays in chapter 5.
Each variable stores a data and a data type. Data type is one of:
type name | description | example |
---|---|---|
NUM | rational number | 4, -6, 3.14, 0 |
STR | text string | |
FUNC | function ref | main |
NIL | special empty value | |
ARRAY | arrays | see chapter 5 |
Data type is determined automatically, runtime: when the value of the variable is changed, the data type is adjusted as required.
The NIL type is a special type used for indicating "no value". It
is written as
Variables are changed using operators. The simplest operator is the
assignment operator (written as
This will copy 5 into global variable called foo and sets the type
of the variable to NUM. The variable is global because there is no sign
that suggests it is not.
Reading the variable is done by simply using its name. For example:
at the end of main the value of foo is 8. The second statement
reads the original value (5) and adds (3) to it then assigns the result
(8) to the variable, overwriting any previous value (and type, but in this
example the type did not change).
A vairable is a cell so it can be printed using fawk_print_cell() or
fawk_print(), depending on the details required:
Note: for the + operator, each operand is converted to number before
the operation. For example:
will print 8, not "53": the + operator means "convert both sides to
number and sum them".
The difference between v++ and ++v is the same as in C: whether the value
of the expression is decided before or after the increment. Take the
following code: v=5;fawk_print(v++); this will print 5,
but the value of v is 6 after v++. Code v=5;fawk_print(++v);
will print 6 and the value of v is 6 at the end. The difference is
"first take the value, then increment" or "first increment then take the value".
Note: boolean operators will look at the numeric value of
the operand. Value zero is interpreted as false, any other
value is interpreted as true.
Using the operators listed above will build expressions. An expression
is evaluated in place and will yield a result which is a type and a value.
The result can be used as an operand in another expression, as a function
call parameter, as a function return value or can be discarded:
In fact fawk_print() is a function that we call. A function always has
a return value, so a function call is an expression too. So far all our
calls to fawk_print() were "void expressions" because we discarded
the return value of fawk_print().
Note: "void expressions" is the way an expression is turned into
a statement, which is required because a function body is a sequence of
statements
When there is a logical AND or OR in an expression, the left side is evaluated
first. If the left side determines the result already, the right side is not
evaluated at all. For example in
Similar way, if the left side of an AND operator is false, the result is
false and the right side is not evaluated.
This obviously doesn't make a difference if the right side is something
like (a > 4), but does make a difference if the right side has side effect
(any effect that change global states, e.g. global variables, or calls
to C functions, even indirectly).
In a trenary operator only two expressions are evaluated: the condition
and either the true or the false side. This is not merely an optimization
on CPU, it affects side effects as well:
This example prints 21, because a is greater than 5 and b++ is evaluated,
while b-- is not. This is called short circuit evaluation: what is not
needed is not evaluated, so its side effects are not applied either.
All three operands are expressions and the syntax is:
First condition is evaluated. If it is non-zero, then when_true
is evaluated and the result of the expression is the result of when_true.
If condition is zero then when_false is evaluated and the
result of the expression is the result of when_false.
2.4. Assignment
2.5. Operators
Arithmetic operators
syntax description example
a + b sum of a and b foo+3
a - b subtract b from a foo-3
a * b multiply a with b 10*foo
a / b divide a with b foo/3
a % b integer remiainder of a/b foo%3
a mod b integer remiainder of a/b foo mod 3
-a negate a -5
-foo
(a) change precedence (4+2)*8
v++ shorthand: v = v+1
v-- shorthand: v = v-1
++v shorthand: v = v+1
--v shorthand: v = v-1
v += a shorthand: v = v+a
v -= a shorthand: v = v-a
v *= a shorthand: v = v+a
v %= a shorthand: v = v-a
boolean operators
!a logical negate a v = !a
a && b true if a and b are true
a || b true if a or b is true
boolean operators
not a logical negate a v = !a
a and b true if a and b are true
a or b true if a or b is true
Relational operators
syntax description example
a == b true if a equals to b if (a == 5) ...
a = b true if a equals to b if (a = 5) ...
a != b true if a is not equal to b if (a != 5) ...
a > b true if a is greater than b if (a > 5) ...
a < b true if a is less than b if (a < 5) ...
a >= b a is greater than or equal to b if (a > 5) ...
a <= b a is less than or equal to b if (a < 5) ...
Misc operators
v = a copy the value of a to v foo=5
foo=bar
a @ b concatenate string a and b "foo" @ "bar" is "foobar"
a ? b :c trenary a > 10 ? b-- : b++
v[] explicit array (chapter 5) my_func(FOO[])
v[b] array indexing (chapter 5) FOO[3]
v.b array indexing (chapter 5) FOO.bar
&v used in C function call: pass by reference (chapter 5) delete(&FOO)
2.6. expressions
2.7. Short circuit evaluation (lazy evaluation)
function main(ARGV)
{
a = 10;
b = 20;
a > 5 ? b++ : b--;
fawk_print(b);
}
2.8. the trenary expression
condition ? when_true : when_false