Optscript, a programming language for extending optlib parsers

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

Data types

MATCHLOC

TBW

index:int

TBW

TAG

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