The PenDraw™ Manual  .   PREV  .   Chapter-TOC  .   Manual-TOC  .   NEXT  .   PenDraw-Home



4  .  PENDRAW LANGUAGE FOR PROGRAMMING
4.1  LANGUAGE STRUCTURE



4.1.1  FORM OF LANGUAGE

PenDraw is instructional. It is an imperative language. You tell PenDraw what to do. It obeys. It is procedural, in classical terms. It is not object-oriented, because there would be zero gain. It is simple, and designed to be quick to learn.

As a programming language, PenDraw is deliberately like BASIC, except with square brackets [ ] for arrays, instead of round parentheses ( ). Like BASIC its SELECT CASE instruction executes only one instruction, and does not 'drop through' stupidly (beware of that if you use JavaScript).

Unlike BASIC, PenDraw is strongly typed. The great majority of errors are caught at compile time. Given that it is intended for such uses as web service, this is important. One of the very highest goals of PenDraw is that it is predictable and reliable. Strong typing is an important element in achieving that goal. (If you are not sure what strong typing means, don't worry). There is very little automatic changing of types. One fault of BASIC (that we have avoided) is that it is deliberately tolerant of programmer sloppiness. Some BASIC compilers allow 'variants' into which you can assign any type. PenDraw is not like that. PenDraw has no variants, and a type is a type is a type. (There is some 'coercion' of numbers into coordinates, but the context defines the coercion. We have limited its use to what makes sense, and not tried to extend it).

PenDraw does not offer error trapping or handling. There is no reason you should need it. It is better to write programs that work properly in the first place.

Names in PenDraw are not case-sensitive: thread is the same as Thread is the same as ThReAd to PenDraw.

4.1.2  ALBUM

One Album equates to one PenDraw program equates to PenDraw Drawing. When you run a PenDraw program, you execute the instructions in an Album. There can only be one Pic Drawing in an Album, though you can produce multiple drawings from one execution of an Album. Each Album is self contained, but it can refer to (use) things from other Albums (which can refer to things from yet other Albums). An Album is to PenDraw what a module is to other languages. That is why you declare some things Public and some Private.

There are two types of Album. Those that produce a drawing, and those that used as libraries to other Albums. It is legal to use an Album, that produces a Drawing, as a library to another Album that produces a Drawing.

Every Album is like a library of pictures. You can use Pics from other Albums (See SCOPE, below, however). There are two steps to it. Firstly, you add a USE ALBUM instruction to the Album you are working in. Secondly you call the Pic as normal with a DRAW { ... } picname() instruction. What if you have a name clash &emdash; two Pics each in its own Album, but with the same name? Easy. Put the Album name in front of the Pic name, with a stop between them like this DRAW { ... } albumname.picname() and PenDraw will call the right one. If you do not put in the albumname, PenDraw will use the one in the current album.

4.1.3  ALBUM FORMAT

Compact Example:-


Album name
  Use Album DimensionLines
  Use Album HotelFurniture
Main
  Open AlbumName()+".svgz" For Output As 1
  StyleSheet    = "abc.css"
  Scripts File  = "abc.js"
  SvgZ Output   = 1
  User Viewport = "100%","100%"
  Drawing Paper = 297,210
  Svg Events    = { OnLoad "Initialize"}
  Drawing Title = "PenDraw Manual Chapter 2 Figure: PenDraw's basic axis system"
  Draw {} Drawing()
  Close 1
End Main
Private Pic Drawing()
End Pic
End Album
  

Long Example: with explanations:-


Album name 'The file must have exactly the same name, but end with .pdrs
           'eg Album trybox goes in file trybox.pdrs

           'Optional: Name other Albums referred to.  An Album called
           'SYS is automatically included.  Don't use SYS as an Album name.
           'Here are two examples...
  Use Album DimensionLines
  Use Album HotelFurniture

Main
           'OPTIONAL: You can put ordinary instructions first, 
           '   eg to loop through multiple datasets

           '   Example Const declarations for Album-wide scope, eg
  Const MajorLength=1500
  Const MajorType  ="CUSTOMER"
  Const CutLength [] = [250,300,500,750]
  
           '   Example Public constants for use in other Albums, eg
  Public MinorLength=1000
  Public MinorType  ="SALESMAN"
  Public RoughLength [] = [275,325,525,775]
           
           'ALWAYS DO THIS ONE
           '   It's part of the general instructions but you always need it
           '   Open a file for output (AlbumName is a function
           '   that returns the name of the Album that is being drawn)
  Open AlbumName()+".svgz" For Output As 1

           'THE MANDATORY EIGHT
           '   FIRST comes a Stylesheet instruction
  StyleSheet    = "abc.css"

           '   SECOND, client-side JavaScript filename goes here
           '   default type is text/ecmascript, or you can specify a type
  Scripts File  = "abc.js"

           '   THIRD you tell PenDraw where to put the SVG output
  SvgZ Output   = 1
           '   FOURTH say how much of the browser or paper you wish to use
  User Viewport = "100%","100%"
           '   FIFTH define the dimensions that you are going to work in
           '   297,210 are good for drawing on A4 paper in millimetres
  Drawing Paper = 297,210
           '   SIXTH you specify the SVG-level events that 
           '   you want your scripts to react to.  These take place
           '   at the outermost SVG document level.
  Svg Events    = { OnLoad "Initialize"}
           '   SEVENTH you give a meaningful title
  Drawing Title = "PenDraw Manual Chapter 2 Figure: PenDraw's basic axis system"
           '   EIGHTH do the drawing! This is the only 
           '   Draw instruction allowed in Main
  Draw {} Drawing()


           'OPTIONAL: you can put ordinary instructions here, 
           '   if (say) your drawing is going to loop through 
           '   multiple datasets you might have a Loop 
           '   instruction here, for example

           '   One instruction we SHOULD have closes the file that 
           '   the svg output is now in (PenDraw closes it anyway,
           '   but it is good practice to close it formally).
  Close 1

           'FINALLY, End Main stops the Main program.
End Main


           'In this part, between End Main and Pic Drawing you 
           'can declare Pics, Subs and Functions.
           'Each one MUST be declared before 
           'being called



Private Pic Drawing()
           'Pic Drawing is what Main calls and it must come last
End Pic

End Album
  


4.1.4  USE ALBUM

These instructions are optional.

In the Use Album instruction, you are telling PenDraw that 'This' Album uses some or all of another Album ('That' Album). You are telling PenDraw to suspend compiling This Album, and to compile That Album (the named Album in the Use Album instruction), then return to compiling This Album.

'That' Album may have Use Album instructions of its own. No problem. But circular references are not allowed: Album A using Album B which uses Album C which Uses Album A will cause a compile error.

4.1.4.1  Album Sys

There is an Album called Sys. It is built in to PenDraw. It is always the first Album to be compiled. It has lots of useful constants, colours, functions, and Pics, that you need. They are documented in chapters 5 and 6 of this manual.

4.1.4.2  Album Compile Order

What order does PenDraw compile Albums? Well, the order in which it is told to Use them: if you compile Album A, which uses B and C, and B uses D and E: PenDraw compiles Sys then D then E then B then C then A.

Album AAlbum SysAlbum BAlbum CAlbum DAlbum E
AlbumA
Use Album B
Use Album C


End Album
Album Sys




End Album
Album B
Use Album D
Use Album E


End Album
Album C
Use Album D



End Album
Album D




End Album
Album E




End Album
614523
This one is
compiled last
because it
implicitly or
explicitly
Uses all of them.
This one is
compiled first.
Always.
This one is
compiled after
D and E because
it Uses them.
This one is
compiled after B
and all Albums
that B Uses
because it is
the next one
Used in A
after B
This one is
compiled first
after Sys
because it
is the first
one Used in B
and B is
the first
one Used in A
This one is
compiled after
D because it
is the next
after D to be
Used in B


4.1.4.3  Name Search Order

When PenDraw compiles your code, and it comes across a variable or constant simple identifier - one with no dot in it (ie like size, not like abc.size) it looks for something with that name in these places, in this order:-

  1. in the current routine
  2. in Main in the current Album
  3. in the Main section of Album Sys

When PenDraw compiles your code, and it comes across a variable or constant compound identifier - one with a dot in it (ie like abc.size) it looks for something with that name:-

When PenDraw compiles your code, and it comes across a Pic/Function/Sub simple name it looks for it in these places in this order:-

  1. in the current Album
  2. in Album Sys

When PenDraw compiles your code, and it comes across a Pic/Function/Sub compound name it looks for it in this place only:-

NoteYou can always use the compound name form, if you want to be unambiguous. If you want to refer to the colour Green in Sys, you can call it Green or Sys.Green. You can force PenDraw only to look in Main of the current Album by using the compound form: even inside Album abc, using the name abc.boxlength will force PenDraw to get boxlength from Main in Album abc.

4.1.5  MILLIMETRES

PenDraw works in millimetres. Drawing in PenDraw is like drawing on paper. You can scale your real-world things, so you do not have to stay in millimetres. But you start in millimetres.

4.1.6  cDISTANCE: DISTANCES AND NUMBERS

This is not a feature you need much, but it is there when you need it.

There is one language feature that you need to know about, to make use of this capability. There is an extra type cDistance. It is used for parameter passing, and you can only declare parameters As cDistance. You can not declare variables As cDistance. That is important.

As you will have observed, numbers can sometimes mean coordinates, and sometimes they can mean just numbers. Consider


          'Here are numbers used as numbers
  For k = 12 To 32
          
          'Here are the same two numbers used as coordinates
  P = (12,32)
  

The point is: PenDraw 'knows' when a number is a number and when it is a coordinate. The reason is: the context defines it. The language instruction, and its composition give it away. In the first line above, we want to know how many times to execute the loop: that is a matter of numeric value (number). In the second, the numbers are unmistakably coordinates. This brings us to the nub of the issue: there is one context where PenDraw can not tell which is which just from the context, and where you have to 'flag' the difference to PenDraw: it is when the number is a parameter.

PenDraw is responsible for keeping geometrical values the same when they are passed into Pics (and possibly modifying their numeric values in order to do so), but it keeps numeric values of simple types the same (Integers and Doubles). Thus there is no problem with cPoint, because it is a geometric type. But Integer and Double parameters could either be numeric (numbers) or geometric (distances). That is the ambiguity. Defining the type of the parameter (as cDistance or Integer or Double) removes the ambiguity.

Consider these two Pics. Ledge has a geometric parameter. Wedge has a numeric parameter. PenDraw will act accordingly.


Private Pic Ledge(Length As cDistance)  'cDistance is always
                                        'a Double, behind the 
                                        'scenes, by the way

Private Pic Wedge(Length As Double)
  

If you are wondering why we did not have cDistances as variables, and go for even stronger typing? The answer is PenDraw programmer convenience. It would get in the way, surprisingly, much more than it would help.

4.1.7  MAIN ... END MAIN

Main (this section) is optional. If the Album does not have its own drawing, but is a 'library' Album for other Albums to use, it does not need Main (nor Pic Drawing, either).

Main is executed before anything else. In fact all Main sections in all Albums are executed in sequence, before any other instructions. If you want to know the sequence, just follow the Use Album instructions; bear in mind that at each Use Album instruction, compilation pauses to compile the used Album (and if it uses another album compilation it pauses to compile that other album, and so on). That gives you the order of execution of Main sections.

The 'Mandatory Eight' instructions are only executed in the Primary Album (the first one). They are not executed in 'Use Album' albums, but all other instructions in Main are always executed.

In case you are wondering, yes you can Use Album an Album that has a Main and a Drawing.

All constants and variables declared in Main can be accessed from anywhere in their own Album, but outside Main they all work as Constants. PenDraw has no Global variable - and that is A Good Thing: global variables just open the door to side-effects. You can declare Public constants in Main and they are accessible from any other Album (though because Albums are compiled in a particular order, an Album compiled earlier, before a later one, will not be able to access anything declared in the later one).

You can even Draw another Album's Pic Drawing, but it will not necessarily come out as a drawing-within-a-drawing, because there is only one drawing frame-of-reference (the outermost), not one for each drawing. So for example, if you draw one drawing at 45 degrees within another, Default Turn will prevent rotation with respect to the outermost drawing's axes, not to the inner drawing axes. We used to have full drawings-within-drawings capability, because it was part of the theory of PenDraw, but no-one used it in over 7 years (most people couldn't even understand it). So we simplified PenDraw, which speeded it up a little, and got rid of it.

4.1.8  PIC DRAWING

This is optional: if there is no Main you do not need this.

Pic Drawing can not have parameters.

You can put attributes between the braces in the Draw {} Drawing () instruction. It is ok to do so, but do it with care if you do it at all. You will probably never need it. You can not put geometric attributes there, only non-geometric attributes. Putting attributes there changes the drawing defaults: you can change the default line width, or line colour, or fill colour, etcetera.

4.1.9  END ALBUM

This instruction must be there. It must be the last instruction in the Album. If the compiler finds (a) non-space character(s) after End Album other than spaces and carriage-returns and linefeeds, it treats it(them) as an error.


PREV  .   Chapter-TOC  .   Manual-TOC  .   NEXT  .   PenDraw-Home



Level Triple-A conformance icon, 
          W3C-WAI Web Content Accessibility Guidelines 1.0