Optscript, a programming language for extending optlib parsers¶
Table of contents
Preparation for learning¶
Optscript is an implementation of PostScript(tm) alike stack oriented general purpose programming language. Developers of optlib parsers can utilize the language for extending their parsers.
You may not be familiar with a stack oriented programming language. Though there are some differences, the syntax and core non-graphical operators of Optscript and PostScript are the same. You can get the basic knowledge for using Optscript from the materials for learning PostScript.
“PostScript Language Tutorial & Cookbook” published by Adobe Systems Inc. The book is known as “blue book”. This is the best place to start. PostScript is a language for controlling printers. So it has many graphical operators. Optscript is for tagging, and doesn’t have such graphical operators. So you can skip the sections about graphics (but you may want to read them because the book is written well).
Ghostscript (gs
or gsnd
) is an interpreter for the PostScript
language and PDF files. Unlike Optscript, it implements the full-set of
PostScript features including graphical operators. It is available
under either the GNU GPL Affero license. You can Ghostscript while
reading the blue book. Do web searching to know about Ghostscript.
optscript
is an command that source files are included in
Universal Ctags source tree. You can use it as the replacement of
gs
. However, I recommend you to have gs
at hand because
optscript
may have bugs. gs
is much mature than optscript
.
Having two interpreters helps you to know correct behavior.
Though gs
has much higher qualities than optscript
, eventually
you may have to build the optscript
command to learn Optscript
specific operators. You can built the command with “make
optscript
”.
red book
TBW
Syntax extension¶
?
is a prefix for representing a character literal.
For an example, ?x
represents 120. This is a short cut for (x) 0
get
.
Some characters has special notation using \
.
?\t
tab
?\n
newline
?\_
space
The optscript
command¶
You can run optscript with no argument:
$ ./optsript
OPT>
OPT>
is the prompt of the interpreter.
You can stop it with quit
operator:
$ ./optsript
OPT> quit
$
Let’s see some example sessions. To help you understand the session easily, Python sessions doing the same as Optscript are also written.
hello world
Optscript:
OPT> (hello, world) = hello, world
Python:
>>> print ('hello, world') hello, world
Adding
Optscript:
OPT> 2 3 add = 5
Python:
>>> print (2 + 3) 5
Variables
Optscript:
OPT> /x 2 def OPT> /y 3 def OPT> x y add = 5
Python:
>>> x = 2 >>> y = 3 >>> print (x + y) 5
Procedures
Optscript:
OPT> /add5_and_print { 5 add = } def OPT> 4 add5_and_print 9
Python:
>>> def add5_and_print(x): ... print(x + 5); >>> add5_and_print(4) 9
string manipulation
TBW
array manipulation
TBW
dict manipulation
TBW
control flow
TBW
operators for printing
TBW
reading script from file
TBW
Optscript in ctags¶
Operators¶
. -> -
. corkIndex:int
Push the cork index for the tag.
\n -> -
\n matchedString:string
n
is an integer (0…9) representing a group in a pattern. Push the matched string for the group.
_matchloc
TBW
:field
(See the output of --_list-operators
)
- Get the value for the specified field from a tag
- and put it.
field:
(See the output of --_list-operators
)
Set a value at the stack to the specified field of a tag.
_tag
TBW
_COMMIT
TBW
_traced
TBW
Recipes¶
Parameters¶
With --_paramdef-<LANG>=<param>,<description>
option, you can
define a parser-specific parameter to your optlib parser.
In the following example, we define a parser, Foo
with a
parser-specific parameter VAR
. If the parser sees “x” in the
current input stream, a code fragment attached to the pattern “/(x)/”
runs. The code fragment does (1) check whether a value for VAR
is
given, (2) emit a tag with the value given to parameter VAR
as
name and with xval
kind, and (3) remove the cork index from the
operand stack.
foo.ctags: .. code-block:
--langdef=Foo
--map-Foo=.foo
--kinddef-Foo=v,xval,externally defined values
--_paramdef-Foo=VAR,desc
--regex-Foo=/(x)//{{
/VAR _param { % if VAR is defined ....
/xval _tag _commit pop
} if
% if VAR is not defined, we do nothing.
}}
input.foo: .. code-block:
x
When running the parser, we can give a value (“hereiam” in the following example)
for the parameter VAR
from the command line:
$ ./ctags --options=args.ctags --param-Foo.VAR=hereiam -o - input.foo
hereiam input.foo /^x$/;" v
Difference between Optscript and PostScript¶
- Memory management
- Dynamically extendable data type
- string
- array