|
<< Click to Display Table of Contents >> Basic syntax rules |
![]() ![]()
|
This section tries to explain some of the syntax basics.
See the page with syntax diagrams if the basics of names, expressions, etc. is confusing.
Basic syntax
Most statements start with a statement name, for instance PRT (for printing). You can see the statements sorted into categories here, or the alphabetical list of statements here. Beware that user-defined procedures may look similar to statements. Assignments like SERIES, VAL, LIST, etc. may omit the statement name, for instance x = 100; or %x = 100;.
Many statements accept an option field right after the statement name, for instance prt <2015 2020>. The option field always uses angle brackets <>, and is often used to state the local time period used in the particular statement. But many other options may be set, for instance prt <p> for percentage printing, or prt <filter=avg>. In prt <filter=avg>, the option type is filter and option value is avg, whereas in prt <p>, the option type is p, and the option should be understood as short-hand for p = yes. Many of the options are of yes/no-type (boolean).
After the option field, some variables or expressions are typically stated, like for instance prt <2015 2020> x, y;. In this case, the timeseries x and y are printed. To delimit elements, you typically use a comma (,), but blanks may also be used as delimiter.
All statements end with a semicolon (;), and the statements may span multiple lines. (If you need a multi-line statement in the user interface, use [Ctrl+Enter] to add newlines, and then mark the whole block and press [Enter]). Note that you may change the way [Enter] vs. [Ctrl+Enter] works, see option interface edit style = ... , or under Edit --> Editor style in the Gekko menu.
You may sometimes add extra options at the end of the statement, for instance prt <2015 2020> x, y file = print.lst;. Such extra options use the equal sign (=), similar to options in the <>-option field.
Gekko operates with seven types of variables: scalars (value, date or string), collections (list, map, matrix), or series. When referring to a scalar, you must use the %-symbol, for instance %v. When referring to a collection, you must use the #-symbol, for instance #m, whereas timeseries do not use prefix symbols. Using such symbols is helpful when reading expressions like x + %y + #z[2], because x is known to be a timeseries, %y is known to be a scalar (probably a value, else the expression will fail), and #z is known to be a collection (from which the second item is selected, so in this case #z is probably a list). The prefix symbols must also be stated on the left-hand side of assigments like for instance %v = 100.
As anticipated above, you can use []-brackets to select items. For timeseries, []-brackets can be used for lags/leads, for instance gdp[-1] or gdp[+1], or for picking out an observation like gdp[2015] or gdp[2015q3]. For lists, []-brackets are used for selecting items in the list, for instance #m[2] or #m[1..%n], and for maps, brackets are used to select elements by name (for instance #m[d] or the equivalent #m['d'] or #m.d). Matrices use two dimensions, for instance #a[2..3, 1..%n]. You can use brackets on strings when selecting individual characters or ranges of characters, for instance %s[3] or %s[3..5].
Wildcards either use the ['...'] or {'...'} pattern, or are 'naked'. For instance, prt {'y*'}; will print all timeseries starting with y. Such wildcards can also be used with lists, for instance #m['y*'], selecting all elements starting with y. In some statements, the {'...'} pattern is not mandatory, for instance index y*; instead of the more tedious index {'y*'};. The reason why for instance {'a*b'} is used in prt {'a*b'}; is that otherwise the expression prt a*b; would be ambiguous (does it mean the mathematical product of two timeseries, or is it a wildcard matching variables starting with a and ending with b?). See more on the wildcard page.
The colon (:) is used to access open databanks, for instance prt bk7:pxa;, where bk7 is the databank, and pxa is the timeseries. As mentioned in the section on databank search, when writing prt pxa;, the first-position databank is implicitly understood if databank searching is inactive, and if databank searching is active (which is default), Gekko will first look for pxa in the first-position databank (or in the Local databank if this contains variables), and afterwards in the other open databanks, ending with the Global databank (the Ref is never searched like this). You may use prt bank2:pxa; to obtain the values from the bank2 databank. Alternatively, use the at symbol (@) to indicate the Ref (reference) databank, for instance: prt @pxa;.
You may use dot (.) to indicate lags, for instance prt pxa.1; instead of prt pxa[-1];. Dots can also be used to select items from a MAP, for instance #m.x picks out element x in the map (alternatively, #m[x] or #m['x'] can be used). Dots are also used for functions, for instance %s.length() for the length of a string %s.
Exclamation mark (!) is used to indicate frequency, for instance prt pxa!q, pxa!m; refers to the quarterly or monthly versions of the series pxa.
Strings should always be stated inside single quotes ('), for instance %s = 'Hello from Gekko.';. Double quotes (") are not used to define strings in Gekko, but may be put inside Gekko strings (the string 'The name "Peter" har 5 characters' is legal). If you need to insert a scalar or an expressions into a string, the most practical way is via {}-braces, for instance 'the {%s} car', where %s = 'blue'. This is more readable than the alternative: 'the ' + %s + ' car'. Note also that if %s is a string, there is the equivalence '{%s}' = %s.
{}-braces are also used for name-composition. For instance prt px{%s}; will be equivalent to prt pxa;, if %s = 'a'. When reading Gekko code containing {}-curlies, these curlies can be thought of as some sequence of characters, for instance abc. If in doubt regarding the use of {...}, for instance whether some string %s must be put inside {...} or not, try to first consider whether the statement/expression would use a string like 'abc' or name like abc? If you would use the former, you should correspondingly use %s, and if you would use the latter, you must correspondingly use {%s}. Note that there is the following equivalence: abc = {'abc'}, so in a sense, the {...}-curlies 'eat' the single quotes belonging to a string, and inside the {...}-curlies, you may put any expression, as long as it evaluates to a string. Another interpretation is that the {}-curlies reference to variables. If %s = 'abc', the expression {%s} creates a reference between from the variable %s to the variable abc. See also the syntax diagrams.
Functions use normal parentheses, for instance movavg(x, 3). You may define your own functions (see here). All functions, both in-built and user-defined, implement so-called UFCS, so movavg(x, 3) can alternatively be written as x.movavg(3), using a dot and putting the first argument on the left.
Power operators are either ** or ^, for instance prt a**b; or prt a^b;.
Logical operators use <, <=, ==, >=, >, <>; note in particular that the equivalence operator is == and not =, see also IF.
$-conditionals can be used in the same way as in the GAMS software package. So you can write for instance %x = 1 $ (%x < 0); which sets %x = 1 if %x < 0. This is equivalent to if(%x < 0); %x = 1; end;. The $-conditionals are often used in conjunction with lists, for instance y[#i] = 100 $ (#i in #i1); which sets the array-timeseries y[#i] to 100 for the elements of #i that are part of the subset #i1.
Variable names must start with %, #, a letter or an underscore, and are subsequently composed of letters, underscore or digits, for instance f16, _temp, %f16, %_temp, #f16, #_temp. Names may also contain {}-braces.
// and /* ... */ are used for out-commenting lines of code, or blocks of code.