This section describes experimental features of the interpreter in PCC2. They may still change their behaviour or be removed completely. They are not generally intended for the casual user.

This section does not apply to PCC 1.x.

In this section, "subroutine" refers to a subroutine defined with Sub, or to a function defined with Function.

Subroutine and Object References

Normally, a subroutine or structure type is global: executing a Sub/Function/Struct statement makes the subroutine or type available to all other scripts in the system. Subroutines and types are defined in the same context as global variables (Dim Shared).

Because these things are normal objects, they can be assigned as usual:

 Sub Foo (x)
   Print x
 EndSub
 Dim Bar := Foo

This defines a subroutine Foo. A variable Bar is defined and set to Foo, making it an alternative way to refer to this subroutine. To call the subroutine, you could therefore use

 Foo "this"
 Bar "or this"

The same goes for arrays, objects, types, context references, etc.

 Dim a := Ship
 Dim b := a(1)
 Dim c := b->Name   % same as c := Ship(1).Name

This feature isn't widely advertised because it can easily lead to problems if used wrong:

  • not all references can be saved in the scriptX.cc file when PCC2 closes and reloads. If such a reference appears in a process's variable when that process is about to be saved, the process will be terminated.
  • it's possible to build cyclic references which PCC2's memory manager cannot resolve, so your script will leak memory if you do not resolve cycles.
  • it's plenty of rope to hang yourself. For example, after "Ship := Planet", the reference "Ship(12)" will actually give you planet #12, and ships will no longer be accessible.

Note that this only applies to regular subroutines and builtin commands. It does not apply to elementary commands. It is not possible to make a variable with an alternative name for, say, If, and it is not possible to make If mean anything else than the default meaning.

Local Subroutines

It is possible to define subroutines in local (subroutine scope) or static (script scope) context.

To enable the feature, use Option LocalSubs(1). Then, define subroutines using Local Sub.... For example,

 Option LocalSubs(1)
 Sub PrintSquare(n)
   Local Function MakeRow(n)
     Return String(n, "X")
   EndFunction
   Local i
   For i:=1 To n Do Print MakeRow(n)
 EndSub

In this example, the MakeRow function is only defined during the execution of the PrintSquare function. It is not available to any other function.

Be careful that some code will be executed outside the current function. For example,

 Sub Initialize
   Local Sub Callback    % wrong!
     Print "something"
   EndSub
   On Load Do Callback   % wrong!
 EndSub

will not work. When the On Load hook runs, Initialize will have finished executing, and Callback is no longer defined.

Local Types

Like subroutines, you can also define types locally.

To enable the feature, use Option LocalTypes(1). Then, define types using Local Struct....

For example:

 Option LocalTypes(1)
 Function MakePair(x,y)
   Local Struct Pair
     X, Y
   EndStruct
   Dim a As Pair
   a->X := x
   a->Y := y
   Return a
 EndFunction

Types are Functions

The documented way to define an instance of a type is Dim...As.

 Struct Coord
   X, Y
 EndStruct
 Dim pos As Coord

Defining such a structure actually just defines a constructor function named the same as the type. Thus, you can also create instances of a type by using a function call:

 Dim pos2 := Coord()
 pos := Coord()

The advantage of this notation is that you can use it everywhere, not just in Dim statements.