home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / language / grs / Text_Man / UserMan < prev   
Encoding:
Text File  |  1993-02-27  |  100.9 KB  |  3,347 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12. The GRS programming language
  13. and environment.
  14.  
  15. Reference Manual.
  16.  
  17. Steven Inkster.
  18. Guy Verbist.
  19.  
  20. Department Of Computer Science.
  21. Heriot Watt University.
  22.  
  23. Archimedes Public Domain Release 1.05
  24. September 1991
  25.  
  26.  
  27.  
  28.  
  29. Acknowledgement.
  30.  
  31. The authors would like to thank Dr. N. W. Paton for his invaluable aid and
  32. advice throughout the design and implementation of this language.
  33.  
  34.  
  35.  
  36.  
  37. Contents
  38.  
  39. 1.0  Basics.                                     1
  40. 1.1  Format of input.                            1
  41. 1.2  Comments.                                   1
  42. 1.3  Statements.                                 1
  43. 1.4  Variables.                                  1
  44. 1.4.1  Types.                                    2
  45. 1.4.2  Declarations.                             2
  46. 1.4.3  Implicit declarations.                    3
  47. 1.5  Constants.                                  4
  48. 1.5.1 Integers.                                  4
  49. 1.5.2  Strings.                                  4
  50. 1.5.3.  Expressions.                             4
  51. 1.6.  Operators.                                 5
  52. 1.7  Assignment.                                 7
  53. 1.8  Loops.                                      7
  54. 1.9  Blocks.                                     7
  55. 1.10  Iterators.                                 8
  56. 1.11  Functions.                                 8
  57. 1.11.1  Declaration.                             9
  58. 1.11.2  Return.                                 10
  59. 1.11.3  Calling.                                10
  60. 1.12  The assume statement.                     10
  61. 1.13  System defined functions.                 11
  62. 2.0  Expressions and meta - level programming.  15
  63. 2.1 Null expressions.                           15
  64. 2.1.2  Using null expressions as slots,
  65.             or reusing outside an assume.       19
  66. 2.1.3  Assigning expressions.                   20
  67. 2.2  Typed expressions.                         20
  68. 3.0  The Object Store.                          22
  69. 3.1  Introduction                               22
  70. 3.2  What is an object?                         22
  71. 3.3  How to create an object                    23
  72. 3.4  The object hierarchy                       23
  73. 3.6  More on methods and slots                  25
  74. 3.7  Objects as variables                       26
  75. 3.8 Objects as slots                            26
  76. 3.9  Summary                                    26
  77. 3.10  Advanced use of objects                   27
  78. 3.10.1  isa and super                           27
  79. 3.10.2  Creating new class objects              29
  80. 3.10.3  Referring to objects by their
  81.         literal name                            29
  82. 3.11  Methods to manipulate objects             30
  83. 3.11.1  Other pre-defined methods               31
  84. 3.12  Directly manipulating the object store    32
  85. 4.0  The GRS programming environment            35
  86. 4.1  Getting started                            35
  87. 4.2  Running programs                           35
  88. 4.3  A short example                            36
  89. 4.4  Organising GRS programs                    36
  90. 4.5  Debugging options                          38
  91. 4.6  Resources required by GRS                  38
  92. 4.7  Recovering from errors                     39
  93. 4.8  Common sources of error                    39
  94. 5.0  References.                                40
  95. A)  Some example GRS code                       41
  96. Desk calculator.                                41
  97. Database.                                       41
  98. Some short programs to demonstrate
  99.              some of the features of GRS        45
  100. Sharing objects and using objects as
  101.              parameters and slots               45
  102. Local "methods" / replacing methods             48
  103. A simple front-end to GRS                       49
  104. A tank game                                     50
  105. B)  Compiler / Analyser Error Messages.         56
  106. B1)  Syntax errors.                             56
  107. B2)  Semantic errors.                           59
  108. C)  Interpreter / Object Store Error Messages.  65
  109. C1)  Internal fatal errors                      65
  110. C 1.1)  Stack errors                            65
  111. C 1.2)  Errors around system defined functions  66
  112. C 1.3)  Miscellaneous errors                    67
  113. C 1.4)  Object store errors                     69
  114. C 1.5)  Memory failures                         69
  115. C 1.6)  User errors                             70
  116. C 1.7)  User warnings                           71
  117. D)  BNF grammar for GRS.                        72
  118. E)  Known Infelcities Of Version 1.05.          77
  119.  
  120.  
  121.  
  122.  
  123. 1.0  Basics.
  124.  
  125. GRS is a strongly typed object - oriented language.  Strong typing is
  126. unusual in most object - oriented langauges, however this stricture
  127. encourages a more disciplined and modular approach.  As opposed to most
  128. object - oriented languages, GRS supports an array of meta - level
  129. programming constructs, allowing the programmer to change the behaviour of
  130. objects dynamically.  The implementation of GRS incorporates an interactive
  131. environment allowing the state of the system to be monitored.
  132.  
  133. This section deals with the normal facilities of GRS which match those of
  134. other high level languages closely.  Section two explains the meta - level
  135. facilities in more detail.  Section three deals with the use of the object
  136. store, and finally section four serves as a guide to interacting with the
  137. environment.
  138.  
  139. This manual assumes a knowledge of a high level language such as C or Pascal.
  140.  
  141. 1.1  Format of input.
  142.  
  143. GRS is a free form language.  That is, no restrictions are placed on the
  144. typographical appearance of source text.  It may be indented, and statements
  145. may span over as many or as few lines as the programmer deems necessary.
  146.  
  147. Any character in a source file which is outside the range of those used in
  148. GRS constructs is ignored.
  149.  
  150. 1.2  Comments.
  151.  
  152. Anything within (* and *) is a comment and is ignored completely.
  153.  
  154. 1.3  Statements.
  155.  
  156. GRS is a statement based language.  A statement is terminated by a semicolon.
  157.  
  158. 1.4  Variables.
  159.  
  160. Variables have a type and an identifier.
  161.  
  162. 1.4.1  Types.
  163.  
  164. Inbuilt types are:
  165.  
  166. integer
  167. string
  168. null
  169.  
  170. and these are augmented by the ability to create a listof any type, and an
  171. expression returning any type.  To create a list of a type, the keyword
  172. listof is placed before the type e.g.
  173.  
  174. listof integer
  175.  
  176. To create an expression, the keyword expression is placed after the type. 
  177. To avoid ambiguity when combining listof and expression the type being
  178. "expressioned" is placed in round brackets e.g.
  179.  
  180. (integer) expression  is an expression which returns an integer
  181. listof (string) expression  is a list of expressions which return strings
  182. (listof string) expression  is an expression which returns a list of strings
  183.  
  184. listofs and expressions can be nested to any level.
  185.  
  186. 1.4.2  Declarations.
  187.  
  188. Variables are declared with a name and a type.
  189. A valid variable name begins with an alphabetic character, upper or lower
  190. case, which is followed by zero or more characters from a-z, A-Z, 0-9 and
  191. '_'.
  192.  
  193. A variable declaration begins with a type and then a list of identifiers
  194. separated by commas.  Valid variable declarations include:
  195.  
  196. integer one;
  197. integer two, three;
  198.  
  199. listof string ls;
  200. (null) expression ne;
  201.  
  202. If a declaration for a variable is present in the source file, a variable
  203. with that name will be declared once and only once, no matter where the
  204. declaration occurs e.g.
  205.  
  206. The following are legal and execute as expected:
  207.  
  208. let integer i := 0;
  209.  
  210. if i=1 then
  211.    string s;         (* will ALWAYS be declared *)
  212.    write("Hello\n");
  213. endif;
  214.  
  215. s:= "Hello again\n";
  216. write(s);
  217.  
  218.  
  219. let integer j := 6;
  220. loop
  221.    integer i;       (* again will always be declared *)
  222.    i:=4;            (* but only once                 *)
  223.    exiton(j>10);
  224.    j := j+i;
  225. endloop;
  226.  
  227. 1.4.3  Implicit declarations.
  228.  
  229. The loop control variable of an iterator is implicitly declared within the
  230. scope of the iteration, with the type of an element of the list it is
  231. iterating across. (see later)
  232.  
  233. The let statement declares and assigns to a variable in one statement e.g.
  234.  
  235. let integer i := 10;
  236.  
  237. Note that when a let statement occurs within a loop the variable will be
  238. declared only once, but the assignment in the statement will be executed as
  239. many times as the loop runs.
  240.  
  241. A function declaration implicitly declares the function name in the level of
  242. scope of the declaration, and the function arguments within the level of
  243. scope inside the function.
  244.  
  245. 1.5  Constants.
  246.  
  247. Valid constants (literals) are string constants, integer constants,
  248. expression constants, and list constants.
  249.  
  250. 1.5.1 Integers.
  251.  
  252. An integer constant is one or more digits e.g.
  253.  
  254. 0
  255. 1234532
  256. 96
  257.  
  258. Note that -96 is not a constant it is the integer constant 96 preceded by
  259. the unary minus operator.
  260.  
  261. The minimum value for an integer is -2147483648 and the maximum 2147483647.
  262.  
  263. 1.5.2  Strings.
  264.  
  265. A string constant is zero or more ascii characters between inverted commas
  266. "".  Within a string constant the backslash character '\' has a special
  267. significance.  A single backslash on its own is not permitted, but several
  268. combinations of the backslash and other characters are allowed.
  269.  
  270. \\ means a single backslash within a string
  271. \" means an inverted comma within a string
  272. \n is interpreted by the write() function as a new line
  273. \t is interpreted by the write() function as a horizontal tab
  274.  
  275. When the string is stored the surrounding inverted commas are removed and
  276. backslashes which precede other backslashes or inverted commas are also
  277. removed.  This is important when using the compile() function with string
  278. constants. (see later)  The maximum length for a string read from the
  279. keyboard is 1023 characters, but a constant string in a program has
  280. unlimited length.
  281.  
  282. 1.5.3.  Expressions.
  283.  
  284. An expression constant is any expression enclosed in curly brackets (braces)
  285. {}.  A typed expression has the type of the expression within the brackets. 
  286. A null expression is one or more program statements within braces, since an
  287. expression has type null e.g.
  288.  
  289. integer i;
  290. let (integer) expression ie := {1+4};
  291. let (null) expression ne := {write("Hello");};
  292.  
  293. It should be noted that null expressions have their own local level of scope
  294. so a variable declaration within a null expression is local to that
  295. expression, but can be brought into the current level of scope by a call to
  296. exec() or summon().
  297.  
  298. Expressions are discussed more fully in section two.
  299.  
  300. 1.6.  Operators.
  301.  
  302. GRS supports the following operators with operand types, result types and meanings:
  303.  
  304. <graphic - "operators">
  305.  
  306.  
  307. 1.7  Assignment.
  308.  
  309. Assignment is much like assignment in any other high level language.  An
  310. identifier followed  by the ':=' symbol followed by an expression.  The
  311. expression must be of exactly the same type as the variable; i.e. no
  312. coercion is possible.  As noted above the let statement performs a
  313. declaration and an assignment in one statement.  It is not legal to assign
  314. to a function name, even though the name may appear as a normal identifier.
  315.  
  316. 1.8  Loops.
  317.  
  318. Only one kind of loop construct is available at the basic level of GRS (but
  319. see 'Iterators' section 1.10) as opposed to the normal array of for, while,
  320. and repeat constructs in other languages.  The construct is governed by one
  321. and only one integer expression, and the loop terminates when this
  322. expression becomes true (non zero).
  323.  
  324. It takes the form:
  325.  
  326. loop
  327.  
  328.    <zero or more statements>
  329.    exiton(<expr>);
  330.    <zero or more statements>
  331.  
  332. endloop;
  333.  
  334. There must be one and only one exiton() statement in a loop.
  335.  
  336. 1.9  Blocks.
  337.  
  338. A block is a statement containing zero or more statements enclosed in
  339. braces.  A block is a single statement so it is useful when more than one
  340. statement is needing to be governed by an if statement, an iterator or an
  341. assume, so the statement governed can be a block containing many statements. 
  342. Unlike the C language, variables declared within a block are not local to
  343. the block.
  344.  
  345. 1.10  Iterators.
  346.  
  347. An iterator is a type of loop construct which iterates across a list,
  348. performing actions for each element in the list.  An iterator takes the
  349. form:
  350.  
  351. foreach <varname> in <expression yielding a list> do
  352.    <statement>
  353.  
  354. An iterator has its own level of scope (see later) and the governing
  355. variable is declared within this scope with the type of an element of the
  356. list expression.  The iterator gives <varname> the value of the head of
  357. <list expression>, executes <statement>, makes <list expression> equal to
  358. the tail of <list expression> and executes <statement> etc etc.  It stops
  359. when <list expression> yields the empty list.
  360.  
  361. e.g.
  362.  
  363. let integer j := 0;
  364. foreach i in [1,2,3,4] do
  365. {
  366.    j := j + i;
  367.    write(j,"\n");
  368. };
  369.  
  370. Iterators are of most use when interacting with the self description
  371. facilities of the object store.
  372.  
  373. 1.11  Functions.
  374.  
  375. Functions have a type and an identifier, like normal variables.  If a
  376. function is not intended to return anything then it can be declared as a
  377. null function.  Functions can have any number of parameters, which are
  378. value, not variable parameters.  Values for the function are returned via
  379. the return mechanism.  Local variables and functions are possible, as is
  380. recursion.  It is even possible to declare a local function with the same
  381. name as the parent function and still be able to recurse to the parent
  382. function, as will be explained later.
  383.  
  384. 1.11.1  Declaration.
  385.  
  386. A function declaration has the form
  387.  
  388. <type> function <ident> ( <paramlist>)
  389. {
  390.    <statements>
  391. };
  392.  
  393. The <paramlist> is a set of normal variable declarations separated by
  394. semi-colons, the last declaration is not followed by a semi-colon.
  395.  
  396. For instance
  397.  
  398. listof string function fred(integer i; integer j,k)
  399. {
  400. .......
  401. };
  402.  
  403. null function do_nothing()
  404. {
  405. };
  406.  
  407. The name of the function is declared in the level of scope of the
  408. declaration, and the parameters are declared local to the function i.e. the
  409. level of scope is raised at the opening bracket of the parameter list. 
  410. Anything declared within the function is local to that function.  As usual,
  411. a reference to identifier refers to the most local identifier with that
  412. name, so the following is possible:
  413.  
  414. null function fred(integer i)
  415. {
  416.    if i = 1 then fred(4);  (*recursive*)
  417.    integer function fred(string s)
  418.    {
  419.       write(s);
  420.    };
  421.    fred("Hello");  (*refers to local function*)
  422. };
  423.  
  424. Functions may have objects as parameters, or return objects (see section 3).
  425.  
  426. 1.11.2  Return.
  427.  
  428. The value returned by a function comes from a return statement which takes
  429. the form
  430.  
  431. return <expression>;
  432.  
  433. where expression has the same type as the declaration of the function. 
  434. There may be any number of return statements in a function e.g.
  435.  
  436. integer function bigger_than_ten(integer param)
  437. {
  438.    if param > 10 then 
  439.       return true;
  440.    else
  441.       return false;
  442.    endif;
  443. };
  444.  
  445.  
  446. 1.11.3  Calling.
  447.  
  448. Function calls are as in any other high level language, the name of the
  449. function followed by a list of parameters separated by commas.  The
  450. parameters must match exactly the number and types of those given in the
  451. declaration e.g.
  452.  
  453. integer function add(integer i,j)
  454. {
  455.    return i+j;   (* brackets are not essential *)
  456. };
  457.  
  458. let integer k := add(1,1);
  459.  
  460. 1.12  The assume statement.
  461.  
  462. To allow the use of expressions that are evaluated late, it is possible to
  463. assume the existence of variables and functions at runtime which do not
  464. exist at compile time.
  465.  
  466. The assume statement takes the form:
  467.  
  468. assume <variable declaration> in
  469.    <statement>;
  470.  
  471. or
  472.  
  473. assume <type> function <ident> (<paramlist>) in
  474.    <statement>;
  475.  
  476. e.g.
  477.  
  478. assume integer i; string s in
  479. {
  480.    let (integer) expression ne1 := {i+4};
  481.    let (string) expression ne2 := {"Hello "+s};
  482. };
  483.  
  484. let integer i := 4;
  485. let string s := "world";
  486.  
  487. write(eval(ne2),eval(ne1));
  488.  
  489. It is only valid to assume functions within a method declaration (see
  490. later), to enable methods to "see" each other and for mutual recursion.
  491.  
  492. The effect of referring to an assumed variable which does not exist at
  493. runtime is undefined.
  494.  
  495. 1.13  System defined functions.
  496.  
  497. The basic system - defined functions are as follows:
  498.  
  499. null write(e1,e2,....) 
  500.  
  501. Takes any number of integer or string or lists of integers or strings
  502. expressions (not in the GRS sense of an expression) as parameters.  Writes
  503. their literal value to the console device.
  504.  
  505. null read(v1,v2,....) 
  506.  
  507. Takes any number of integer or string variables as parameters and reads
  508. their value from the console device.
  509.  
  510. element head(list) 
  511.  
  512. Takes any kind of list as parameter and returns the head of the list.
  513.  
  514. list tail(list)
  515.  
  516. Takes any kind of list as a parameter and returns the tail of the list.
  517.  
  518. (null) expression compile(string)
  519.  
  520. The callable compiler which compiles the string to a null expression.  It
  521. should be noted that, as with other null expressions, the contents of what
  522. is returned by compile() has its own level of scope, so any variable
  523. declarations within the string given as a parameter can only be accessed
  524. from within that string.
  525.  
  526. null consult(string)
  527.  
  528. Compiles and executes a file with the name string.
  529.  
  530. type eval(typed expression)
  531.  
  532. Evaluates a typed expression (with late binding of the value and scope of
  533. variables) and returns the value.
  534.  
  535. null exec((null) expression)
  536.  
  537. Executes a null expression (including variable declarations) in the level of
  538. scope of the call to exec(). Variables in the expression are redeclared in
  539. the current level of scope i.e. the expression is semantically re-analysed. 
  540. A call exec(ne) is equivalent to summon(ne); run(ne).
  541.  
  542. null summon((null) expression)
  543.  
  544. Semantically analyses a null expression and redeclares the variables in the
  545. expression in the current level of scope, but does not run the expression.
  546.  
  547. null run((null) expression)
  548.  
  549. Executes a null expression which must have been previously analysed by
  550. either exec() or summon().  
  551.  
  552. integer len(string)
  553.  
  554. Returns the number of characters in a string.
  555.  
  556. string mid(string; integer a; integer b)
  557.  
  558. Returns the string starting at the a'th character with length b, of the
  559. string given as parameter.
  560.  
  561. null beep()
  562.  
  563. Writes an ascii bel character to the console.
  564.  
  565. integer rnd(integer)
  566.  
  567. Returns a random integer between 1 and the value provided.
  568.  
  569. null tab(integer x; integer y)
  570.  
  571. Moves the screen cursor to the position x,y.
  572.  
  573. null cls()
  574.  
  575. Clears the console screen.
  576.  
  577. string itos(integer)
  578.  
  579. converts an integer to a string.
  580.  
  581. integer stoi(string)
  582.  
  583. converts a string to an integer.
  584.  
  585. true and false are system defined variables which are initially set to 1 and
  586. 0 respectively, but the user may assign to them if he / she feels so
  587. inclined.
  588.  
  589. There are also several system defined messages which may be sent to objects. 
  590.  These are explained in section 3.
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598. 2.0  Expressions and meta - level programming.
  599.  
  600. Expressions will be unfamiliar to most new users so this section attempts to
  601. shed some light on their meaning and use.  It will concern itself with
  602.  
  603.         * compile()
  604.         * exec()
  605.         * summon()
  606.         * run()
  607.         * eval()
  608.         * typed expressions
  609.         * null expressions
  610.         * the assume statement
  611.  
  612. 2.1 Null expressions.
  613.  
  614. A null expression is a piece of code which can be passed around a program as
  615. a normal variable, and can be used as a slot for classes.  Their primary use
  616. is for the creation of new classes, so that methods can be passed to the
  617. new() method, but they can be used in many other ways to make code far more
  618. efficient and intuitive than in normal imperative languages.  For instance
  619. depending on a variable, different null expressions can be passed to a
  620. function so it will take different actions.  However for this added
  621. convenience, a price is paid in the form of added complexity when
  622. considering such things as scope.
  623.  
  624. A null expression can be created in two different ways, through the
  625. compile() function or by declaration as a constant in a program. compile()
  626. takes a string and compiles it to a null expression, constant null
  627. expressions are simply pieces of program code enclosed in curly brackets. 
  628. However there are subtle differences between these methods, compile() simply
  629. compiles the expression but does not analyse the semantics of the
  630. expression, whereas constant expressions in a program are automatically
  631. analysed and could be run immediately.  Null expressions have their own
  632. level of scope so variables declared within them are not visible outside the
  633. expression.
  634.  
  635. e.g.
  636.  
  637. let (null) expression ne := 
  638.    compile("let string s := \"Hello\n\"; write(s);"); (correct)
  639.  
  640. (note the use of the \" symbol to prevent the inverted commas from being
  641. removed by the first pass of the compiler)
  642.  
  643. or
  644.  
  645. let (null) expression ne := 
  646.       {let string s := "Hello\n"; write(s);};        (correct)
  647.  
  648. To execute a null expression either exec() or run() can be called.  The
  649. difference between these two calls is that exec() runs the semantic analyser
  650. over the expression and declares any variables in the expression in the
  651. current level of scope, whereas run() only executes the code.  To analyse an
  652. expression and redeclare the variables without executing it, a call should
  653. be made to summon().  exec(ne) is equivalent to summon(ne); run(ne);.
  654.  
  655. e.g.
  656.  
  657. exec({let string s := "Hello\n"; write(s);});  (correct)
  658.  
  659. run({let string s := "Hello\n"; write(s);});   (correct)
  660.  
  661. exec(compile("let string s:= \"Hello\n\"; write(s);")); (correct)
  662.  
  663. are all correct, whereas
  664.  
  665. let string s := "Goodbye\n";
  666. exec({let string s := "Hello\n"; write(s);});    (wrong)
  667.  
  668. is incorrect because it would redeclare string s in the level of scope to
  669. the call to exec() where an identifier with that name already exists.  The
  670. call to exec() should be replaced with a call to run().
  671.  
  672. Also
  673.  
  674. run(compile("let string s := \"Hello\n\"; write(s);")); (wrong)
  675.  
  676. is incorrect because it is not meaningful to run expressions which have not
  677. been analysed.
  678.  
  679. However
  680.  
  681. let string s := "Goodbye\n";
  682. exec({write(s);});              (correct)
  683.  
  684. would be correct because there is no variable declaration for s in the
  685. expression.  Note the semicolon after the write(s).  If there were no
  686. semicolon then the expression would be an expression that returns a null
  687. because write() returns a null, but it would not be a null expression in the
  688. GRS sense, for which it must be a complete statement.
  689.  
  690. Also
  691.  
  692. assume string s in
  693.    let (null) expression ne := {write(s);};
  694. let (null) expression vardecl := compile("string s;");
  695. exec(vardecl);
  696. assume string s in
  697.    exec({s := "Hello\n";});
  698. exec(ne); (* or run(ne *)                       (correct)
  699.  
  700. would be correct because variables in expressions are looked up dynamically
  701. at run time.
  702.  
  703. The reader may notice extensive use of the assume statement when constant
  704. null expressions are being created.  It is used to tell the compiler that a
  705. variable referred to may not exist in the context of the input file at
  706. compile time, but will exist in the context of the expression at run time. 
  707. It is only valid to assume a variable in an expression.  All variable
  708. references outside expressions are bound at compile time.
  709.  
  710. For instance
  711.  
  712. assume integer i in
  713.    let (null) expression ne := {write(i);};   (correct)
  714. integer i;
  715. i := 6;
  716. exec(ne);
  717.  
  718. is meaningful, whereas
  719.  
  720. assume integer i in
  721.    let (null) expression ne := {write(i);};   (wrong)
  722. exec(ne);
  723.  
  724. is not.
  725.  
  726. One final point of note is that the semantic analyser uses a great deal of
  727. memory every time it is called, and the analysis process is relatively time
  728. consuming.  Hence if is at all possible, it is advisable to call the
  729. analyser only once and then to use run().  If there are no variable
  730. declarations in a constant expression then it need not be called at all
  731. because the analyser was run at compile time e.g.
  732.  
  733. let (null) expression ne := {write("Hello\n");};    (correct)
  734. run(ne);
  735. run(ne);
  736. run(ne);
  737.  
  738. or
  739.  
  740. let (null) expression ne := {write("Hello\n");};    (correct)
  741. exec(ne);    (*still OK but wasting time and memory *)
  742. exec(ne);
  743. exec(ne);
  744.  
  745. Now use a variable in the expression ......
  746.  
  747. let (null) expression ne := {let string s := "Hello\n"; 
  748.                             write(s);};    
  749. run(ne);
  750. assume string s in
  751.    exec({write(s);});   (*s not in scope*)      (wrong)
  752. run(ne);
  753. run(ne);
  754.  
  755. but it must be brought into scope if you are going to use it outside the
  756. expression.
  757.  
  758. let (null) expression ne := {let string s := "Hello\n"; 
  759.                             write(s);};    
  760. exec(ne);
  761. assume string s in
  762.    exec({write(s);});   (*s is now in scope*)           (correct)
  763. run(ne);
  764. run(ne);
  765.  
  766. Also, expressions from the callable compiler must be be analysed first:
  767.  
  768. let (null) expression ne := 
  769.       compile("write(\"Hello\n\");");
  770. summon(ne);  (* no variables but need to analyse *)
  771. run(ne);                                                (correct)
  772. run(ne);
  773. run(ne);
  774.  
  775. or
  776.  
  777. let (null) expression ne :=
  778.       compile("write(\"Hello\n\");");
  779. exec(ne);  (*no variables but need to analyse, then run*)
  780. run(ne);   (* or exec *)                                            (correct)
  781. run(ne);   (* or exec *)
  782.  
  783. 2.1.2  Using null expressions as slots, or reusing outside an assume.
  784.  
  785. Consider the declaration
  786.  
  787. assume integer i in
  788. {
  789.    (null) expression ne;
  790.    ne := {write(i);};
  791. };
  792.  
  793.  
  794. To exec(ne) or run(ne) where i is in scope is perfectly meaningful.  However
  795. if ne is passed to a method on a class and then exec'ed, with the intention
  796. of it finding i as a slot, this will not work.  This is because within
  797. methods, slots are looked up dynamically at run time, so according to the
  798. semantic analyser the variable i will not exist.  Note that if the
  799. expression did not come from compile() then it could be run() straight away
  800. inside the method with no problems.  If the expression must be analysed
  801. within a method then technique is to put the assume inside the null
  802. expression so it is still present when the semantic analyser runs over the
  803. expression i.e.
  804.  
  805. (null) expression ne;
  806. ne := {assume integer i in write(i);};
  807.  
  808. 2.1.3  Assigning expressions.
  809.  
  810. If one null expression variable is assigned to another then both refer to
  811. the same variable, i.e. the expression is not copied, thus when the
  812. expression is referred to via one identifier, this reference will be
  813. reflected in the state of what the other identifier refers to.  This is the
  814. same as the way in which objects can be assigned and referred to.
  815.  
  816. 2.2  Typed expressions.
  817.  
  818. A typed expression is a collection of meaningful symbols (i.e. in scope or
  819. assumed) which can normally be evaluated by the interpreter, but whose value
  820. is determined at run time depending on the position in the code of the
  821. evaluation.  Identifiers are looked up dynamically starting at the call to
  822. eval() and using the nearest (by scope) match.
  823.  
  824. It is not meaningful to try to compile typed expressions as null expressions
  825. can be compiled, this would be equivalent of attempting to compile e.g.
  826.  
  827. 3+4
  828.  
  829. using a Pascal compiler.
  830.  
  831. A typed expression takes its type automatically from its contents i.e. what
  832. is between the curly brackets e.g.
  833.  
  834. {"hello"}               (*(string) expression*)
  835. string s;
  836. {s}                     (*(string) expression*)
  837. {s+"hello"}             (*(string) expression*)
  838. {123}                   (*(integer) expression*)
  839. integer i;
  840. {i/145}                 (*(integer) expression*)
  841. {[1,2,3]}               (*(listof integer) expression*)
  842. [{1},{2},{3}]           (*listof (integer) expression*)
  843.  
  844. When a typed expression is passed to eval() the expression is evaluated and
  845. returned.  As stated before the values of identifiers are those of the
  846. identifiers with that name which are nearest by scope.  The type eval()
  847. returns is determined by its argument, and is bound at compile time. e.g.
  848.  
  849. let (integer) expression ie := {4};             (correct)
  850. write(3+eval(ie));
  851.  
  852. For assignment types must be correct as per usual
  853.  
  854. let (integer) expression ie := {"Hello"};               (wrong)
  855.  
  856. Finding by scope ...
  857.  
  858. assume string s in
  859.    let (string) expression se := {s};
  860. let string s := "Hello";
  861. string function rubbish()
  862. {
  863.    let string s := "Goodbye";
  864.    return eval(se);
  865. };
  866.  
  867. write(eval(se));                (*Hello*)
  868. write(rubbish());               (*Goodbye*)
  869.  
  870.  
  871.  
  872.  
  873.  
  874. 3.0  The Object Store.
  875.  
  876. 3.1  Introduction
  877.  
  878. So far this manual has dealt with the basic elements of the GRS programming
  879. language such as assignment, loops, iterators and so on, and has looked in
  880. detail at the complexities of the expression type.  With these techniques it
  881. is possible to write many impressive programs (see the examples given in the
  882. previous chapters and in section 5).  This chapter explains how these
  883. features can be used to create objects.  Firstly, the term object is
  884. explained, and through example code, it is shown how to create, access and
  885. manipulate objects in GRS.  For further reading see "Object-oriented
  886. Software Construction" by Betrand Meyer.
  887.  
  888. 3.2  What is an object?
  889.  
  890. Most programming languages provide a means for creating data structures,
  891. that is, units of information consisting of several different attributes
  892. with unique names.  For example, in the programming language C, a person may
  893. be described as
  894.  
  895.  struct person  {
  896.    char *name;
  897.    int age;
  898.    };
  899.  
  900. Here the person is given attributes name (a string), and age (an integer). 
  901. The programmer is then free to create as many examples of type person as
  902. they wish, each of which will have a different (but not necessarily unique)
  903. name and age.
  904.  
  905. Within the same program, functions may be written which manipulate examples
  906. of the type person.  For example, to calculate the year of birth for a given
  907. person, a function may be written (in C) something like: 
  908.  
  909. int year_of_birth (struct person p, int this_year )
  910.  {
  911.    return(this_year-p.age);
  912. }
  913.  
  914. This simply takes the age of the given person, and subtracts it from the
  915. current year. It seems logical that year_of_birth and a person's age should
  916. belong together in some way.  This is where objects come in.
  917.  
  918. An object is simply a collection of attributes (commonly known as slots) and
  919. functions (known as methods).  The object can only communicate to the rest
  920. of the world via its methods (which is why executing a method is known as
  921. sending a message) and its slots are invisible to the rest of the world. 
  922. Only the object can access its own slots, and can only be commanded by its
  923. methods.  This gives an object very dynamic characteristics.
  924.  
  925. 3.3  How to create an object
  926.  
  927. Now that we know what an object is, how does GRS allow objects to be
  928. created?  This is achieved by sending a message to another object!  When
  929. starting up GRS (see chapter 4) there are two objects already installed. 
  930. The first is known as meta_class, the other is known as class. Before
  931. continuing, the hierarchy which exists between objects is explained.
  932.  
  933. 3.4  The object hierarchy
  934.  
  935. The example C code above explained how a structure describing a person is
  936. built.  So, we may have a person whose name is Fred and age is 42.  Fred is
  937. simply an instance of a person, which means that Fred can do all of the
  938. things a person can do.  Similarly, a structure describing a tank may be
  939. built, with its position, and which side it is fighting for, meaning the
  940. King Tiger would be an instance of a tank, and could do everything which a
  941. tank could do.  So, if we asked Fred to move forward, he would step forward. 
  942. If we asked the King Tiger to move forward, there would be a grinding of
  943. gears, and it would move forward.  If we asked Fred to sit down, he would do
  944. so, but the King Tiger would be a little lost!  Similarly, asking the King
  945. Tiger to fire a shell a few miles would cause it no problems, Fred would
  946. however be struggling!
  947.  
  948. The point here is that instances of a person have the characteristics of
  949. people, and all instances of a tank have the characteristics of a tank.  
  950. "Peopleness" and "tankness" may seem similar (for example both can sensibly
  951. respond to the message "go forward"), but they can be as different or as
  952. similar as whoever created them would wish.
  953.  
  954. In GRS, phenomena such as person and tank are known as classes.  A class
  955. describes exactly the properties and behaviour of each of its instances
  956. (such as Fred or the King Tiger), and provides a means for creating new
  957. instances.
  958.  
  959. Within GRS, every object is treated equally, therefore each has a class. 
  960. For cases such as person or tank, their class is the object called class. 
  961. The class of the object class is meta_class, the class of which is itself,
  962. ie meta_class.  This is made a little clearer in figure O1.
  963.  
  964. To create an instance of a class, the message "new" is sent to the
  965. appropriate object.  For example, to create a new example of the class
  966. class, the code is instanceof class person; person := class.new( ....some
  967. parameters... );
  968.  
  969. The parameters are explained in detail later.
  970.  
  971. Notice the form of sending a message—the object to receive the message
  972. precedes the dot, the message to pass follows the dot.  The message follows
  973. the usual rules for calling a GRS function.
  974.  
  975. In the case of sending the message "new" to the class class, the parameters
  976. are
  977.  
  978. *       a string, which is the name of the object to be created (which is
  979.         not the same as the identifier, although it is usually clearer to
  980.         use the same name)
  981.  
  982. *       a list of null expressions, each element of which must be a single
  983.         function declaration.  A warning is produced if this is not the case.
  984.  
  985. *       a list of null expressions, each element of which must be a set of
  986.         one or more variable declarations.  A warning is given if this is
  987.         not the case.
  988.  
  989. The full code to create the class person is therefore
  990.  
  991. instanceof class person;
  992. person := class.new(
  993.              "person",          (* name of new object *)
  994.              [                  (* list of methods *)
  995.                 {
  996.                    null function set( string pname; integer page )
  997.                    {
  998.                       assume integer age; string name in
  999.                       {   age := page;  name := pname;  };
  1000.                    };
  1001.                 },
  1002.                 {
  1003.                    null function show()
  1004.                    {
  1005.                       assume integer age; string name in
  1006.                          write(name," is ",age," years old\n");
  1007.                    };
  1008.                 }
  1009.              ],
  1010.              [                  (* list of slots *)
  1011.                 {
  1012.                    integer age;
  1013.                    string name;
  1014.                 }
  1015.              ]
  1016.              );
  1017.  
  1018. There are a few points to note
  1019.  
  1020. *       the use of the assume command to avoid a compile time error, as the
  1021.         slots are only added at run-time, and until then their existence
  1022.         will not be accepted.  The types of assumed variables are not
  1023.         checked at run-time, meaning that a wrongly specified type or a
  1024.         non-existent variable which was assumed will produce strange
  1025.         behaviour, most likely crashing the program.
  1026.  
  1027. *       the methods and slots follow the usual syntactic form of a list of
  1028.         GRS null expressions
  1029.  
  1030. *       the slots could equally have been represented using the list
  1031.         [ {integer age;}, {string name;} ]
  1032.         The order of the slots is not important.
  1033.  
  1034. Then, to create instances of the class person, the message "new" must be
  1035. sent to the object person, ie
  1036.  
  1037. instanceof person fred;
  1038. fred := fred.new("fred");
  1039.  
  1040. When creating instances of new classes, the only parameter is the name of
  1041. the new object.
  1042.  
  1043. Now that we have an instance of person, we can manipulate the object.  For
  1044. example,
  1045.  
  1046. fred.set("Fred",42);
  1047. fred.show();
  1048.  
  1049. would produce Fred is 42 years old.  Creating more people is easy, say
  1050.  
  1051. instanceof person guy;
  1052. guy := person.new("guy");
  1053.  
  1054. Using this new object follows the same pattern, ie
  1055.  
  1056. guy.set("Guy",24);
  1057. guy.show();
  1058.  
  1059. would produce Guy is 24 years old.
  1060.  
  1061. Notice that there is a shorter way of creating an instance of a new class,
  1062. using the create keyword.  For example, the object guy could equally have
  1063. been produced using
  1064.  
  1065. create person guy;
  1066.  
  1067. or
  1068.  
  1069. #person guy;
  1070.  
  1071. which is equivalent to the code shown above.  The # form is quicker but less
  1072. clear, and is intended only for interactive use.
  1073.  
  1074. 3.6  More on methods and slots
  1075.  
  1076. Once a class is defined, passing messages causes the methods to be executed. 
  1077. For the most part, the code behaves exactly as any other piece of GRS code,
  1078. and all of the normal rules of scope apply, but with two exceptions.
  1079.  
  1080. When executing a method, all identifiers are checked dynamically, that is,
  1081. every time a variable is encountered, the object store and attribute tables
  1082. are searched to produce a value.  Thus, when responding to a message, the
  1083. interpreter first checks to see if there is a slot with the same name. 
  1084. Slots are always searched first within a method, and care must be taken to
  1085. avoid naming local variables which share the same name as slots.  Similarly,
  1086. any function calls cause the interpreter to firstly search through the
  1087. methods, and only if none of these match, then the normal rules of scope
  1088. apply.
  1089.  
  1090. Note that when creating a new class, the methods do not yet exist.  So, if
  1091. methods refer to other methods in the class, their existence must be assumed
  1092. for now.
  1093.  
  1094. 3.7  Objects as variables
  1095.  
  1096. Objects can be assigned to one another, and used as parameters.  So, to make
  1097. two identifiers indicate the same object, use
  1098.  
  1099. instanceof someclass o1,o2;
  1100. o1 := someclass.new("o1");
  1101. o2 := o1;
  1102.  
  1103. Notice that this does not make a copy of o1, it simply means that both of
  1104. the identifiers refer to the same object.  This is particularly important
  1105. when objects are used as slots.
  1106.  
  1107. 3.8 Objects as slots
  1108.  
  1109. Often an attribute of a class is another object.  For example, a student
  1110. will be studying a course, which itself could be a class.  There are two
  1111. methods of implementing this in GRS:
  1112.  
  1113. *       declare a slot as instanceof classid slotname.  This means that the
  1114.         slot can be used in a very general way, assigned to new objects,
  1115.         used as a parameter, and so on.  It does however mean that the
  1116.         object will have to be initialised in one of the class's methods.
  1117.  
  1118. *       declare a slot as create classid slotname.  In this case the object
  1119.         is created, without the need to send the message "new" to the class.
  1120.  
  1121.  
  1122. 3.9  Summary
  1123.  
  1124. To create a new class
  1125.  
  1126. instanceof class newclass;
  1127. newclass := class.new(
  1128.                "newclassname",
  1129.                [ listof methods ],
  1130.                [ listof slots ]
  1131.                );
  1132.  
  1133. The methods must be single function declarations in the form of a null
  1134. expression, the slots can be any number of variable declarations, again in
  1135. the form of a null expression.  A warning is given if any of the elements
  1136. are not of the correct form.  All references to slots and other methods must
  1137. be assumed.
  1138.  
  1139. To create instances of the new class use
  1140.  
  1141. instanceof newclass instance;
  1142. instance := newclass.new("instancename");
  1143.  
  1144. or
  1145.  
  1146. create newclass instance2;
  1147.  
  1148. which is equivalent to
  1149.  
  1150. instanceof newclass instance2;
  1151. instance2 := newclass.new("instance2");
  1152.  
  1153. Now instance and instance2 can respond to the messages defined within
  1154. newclass, that is they share the properties defined by newclass.
  1155.  
  1156. 3.10  Advanced use of objects
  1157.  
  1158. It is possible for the user to create hierarchies, and to manipulate more
  1159. directly the object store.  Details of how this is achieved are given below.
  1160.  
  1161. 3.10.1  isa and super
  1162.  
  1163. Often in real life certain groups are subsets of a larger group.  For
  1164. example, humans and dolphins are both mammals, and as such, they share the
  1165. properties of all mammals, whilst retaining quite unique properties.  Thus,
  1166. both dolphins and humans would share the property of having skin, but only
  1167. dolphins have fins, and only humans have hands.  Similarly, people have
  1168. certain attributes, and students, whilst having all of the attributes
  1169. associated with people, also have characteristics such as college, course
  1170. name, and year of study.
  1171.  
  1172. In GRS it is possible to represent this relationship quite easily.  Assuming
  1173. that the class person has been set up, student can also be defined thus
  1174.  
  1175. instanceof class student;
  1176. student := class.new(
  1177.               "student",
  1178.               [
  1179.                  {
  1180.                     null function set( string pname; integer page;
  1181.                                        string pcrse; integer pyear )
  1182.                     {
  1183.                        assume instanceof person super in
  1184.                           super.set(pname,page);
  1185.                        assume string course; integer year in
  1186.                        {  course := pcrse; year := pyear;  };
  1187.                     };
  1188.                  },
  1189.                  {
  1190.                     null function show()
  1191.                     {
  1192.                        write("\nStudent details :\n");
  1193.                        assume instanceof person super in
  1194.                           super.show();
  1195.                        assume string course; integer year in
  1196.                           write("Course : ",course,
  1197.                                 " year : ",year,"\n");
  1198.                     };
  1199.                  }
  1200.               ],
  1201.               [
  1202.                  {
  1203.                     string course;
  1204.                     integer year;
  1205.                  }
  1206.               ]
  1207.               );
  1208.  
  1209. Notice how super is used only within assume blocks in order to prevent a
  1210. compile time error.  Whenever the interpreter finds a message is to be sent
  1211. to the object super, the message is sent to the appropriate superclass.  For
  1212. example,
  1213.  
  1214. create student guy;
  1215. guy.set("Guy",24,"Comp Sci",4);
  1216.  
  1217. Here an instance of student is being created, and a message passed to
  1218. initialise its slots.  As it stands though, the superclass has not been
  1219. defined.  Thus, before executing guy.set, the statement
  1220.  
  1221. student isa person;
  1222.  
  1223. must be executed.  If this was not done, an error isa of <student> does not
  1224. exist would result.
  1225.  
  1226. The isa operator defines the type of object which super will be for the
  1227. given class.  It also means that every instance of student is paired with an
  1228. instance of person, although this extra object is invisible to the user and
  1229. can only be accessed through the use of the object super.  This is explained
  1230. in figure O2.
  1231.  
  1232. It is only possible for a class to have one superclass, but there is no
  1233. limit to the number of levels of superclasses.  For example, person could be
  1234. a mammal, ie person isa mammal, and mammal could be a living being, ie
  1235.  
  1236. mammal isa living_being.  
  1237.  
  1238. Equally, there is no limit to the number of times a class can be used as a
  1239. superclass, so we could have 
  1240.  
  1241. dolphin isa mammal.
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254. 3.10.2  Creating new class objects
  1255.  
  1256. So far this chapter has concentrated on creating new classes, that is,
  1257. instances of the object class.  Just as class defines how each of its
  1258. instances behave, meta_class defines how class behaves.  There is no reason
  1259. why more instances of meta_class cannot be created, allowing user-defined
  1260. class types to be created.  Examples of this, with regard to the ADAM
  1261. database system, can be found in [Paton 90].  Details of how to manipulate
  1262. the object store directly are given in section 3.12.
  1263.  
  1264. 3.10.3  Referring to objects by their literal name
  1265.  
  1266. Previously, every time a new object has been created, its name has been the
  1267. same as the object identifier.  This need not be the case however, as the
  1268. following example shows.
  1269.  
  1270. instanceof person fred;
  1271. fred := fred.new("another fred");
  1272. instanceof person p;
  1273. p := person.new("fred");
  1274. p := person.new("jim");
  1275. "jim".set("Jim",29);
  1276. "fred".set("Fred",55);       (* these last two refer to *)
  1277. fred.set("Fred",42);         (* different objects       *)
  1278.  
  1279. The object name may be used, rather than an object identifier, whenever a
  1280. message is to be sent.  It is much quicker to use the identifier, but if the
  1281. name is to be used, remember that the match is case-sensitive and all
  1282. characters are significant.  The advantage of using the literal name is that
  1283. it is insensitive to scope and thus makes the object accessible from any
  1284. level.  However the "object name" form cannot be used if the object is part
  1285. of an assignment or being passed as a parameter, only when a message is to
  1286. be sent.
  1287.  
  1288. 3.11  Methods to manipulate objects
  1289.  
  1290. It is possible to delete slots, methods and objects, to add new methods and
  1291. slots, and to replace methods within an object.
  1292.  
  1293. To delete an object, use
  1294.  
  1295. sys_delete_object( objectid, flag );
  1296.  
  1297. The objectid must be a valid object identifier, and flag is an integer
  1298. indicating whether or not confirmation is required before the deletion takes
  1299. place.  When set to true, the list of objects, methods and slots which would
  1300. be deleted as a result is displayed, and the user then types y or n.
  1301.  
  1302. When deleting an object, the object store also deletes
  1303.  
  1304. *       every instance of the object if the object is a class
  1305. *       every subclass of the object (ie those joined by isa links)
  1306. *       every method in the object, and every method which refers to these methods, and so on
  1307. *       every slot in the object
  1308.  
  1309. The consequcnces of deleting an object are further reaching than this.  All
  1310. identifiers which refer to the deleted object will no longer be valid, and
  1311. any code containing such references (for example inside expressions) is no
  1312. longer valid.  Such code must be recompiled before it can be used again.
  1313.  
  1314. To delete the slot slotname from the class classid, use
  1315. classid.delete_slot("slotname",flag);
  1316.  
  1317. flag is an integer, either true or false, and indicates whether or not
  1318. warning is required before deletion takes place.  This is because deleting a
  1319. slot also deletes all of the methods which refer to that slot, and the
  1320. methods which refer to those methods, and so on.  If true is used, the user
  1321. then types y or n to delete or ignore the slot and methods listed.  If the
  1322. slot does not exist, a warning is given such as  Delete warning-slot
  1323. 'slotname' does not exist in object 'objectname'.
  1324.  
  1325. Deletion of a method is similar, ie
  1326.  
  1327. classid.delete_method("methodname",flag);
  1328.  
  1329. Again, the flag being true allows inspection of the methods which will be
  1330. deleted and a choice to be made.  If the method does not exist, a warning is
  1331. given.
  1332.  
  1333. To add a slot to an object, use
  1334.  
  1335. classid.add_slot( ne );
  1336.  
  1337. where ne is a (null) expression consisting of one or more variable
  1338. declarations.  Similarly, to add a method, use
  1339.  
  1340. classid.add_method( ne );
  1341.  
  1342. where ne is a (null) expression consisting of a single function declaration. 
  1343. If in either case the null expression is not in the correct format an error
  1344. is produced.
  1345.  
  1346. 3.11.1  Other pre-defined methods
  1347.  
  1348. When starting GRS, meta_class and class both have a set of methods.  As well
  1349. as those described above, these are
  1350.  
  1351. get_instances
  1352.  
  1353. This returns a listof instances of the object to which the message was
  1354. passed.  Thus, meta_class.get_instances() returns instances of meta_class,
  1355. and person.get_instances() returns instances of person.  The most common use
  1356. of this method is within foreach loops.
  1357.  
  1358. get_slots
  1359.  
  1360. This returns a list of strings, which are the names of the slots attached to
  1361. the object to which the message was passed.
  1362.  
  1363. describe_object
  1364.  
  1365. Provided mainly for debugging purposes, this prints details of the object to
  1366. which the message was passed.
  1367.  
  1368.  
  1369. 3.12  Directly manipulating the object store
  1370.  
  1371. Several system-defined functions are used by class and meta_class, and may
  1372. be used with care within other methods.  However, there is seldom any need
  1373. to use these, unless the user wishes to set up another instance of
  1374. meta_class.
  1375.  
  1376. The current object is mentioned throughout.  By default, this is meta_class,
  1377. but changes whenever a message is passed to the object receiving the
  1378. message.  For example, with person.new("fred") when the method new is being
  1379. executed, the current object is person.
  1380.  
  1381. null function sys_create_object( name,methods,slots );
  1382. name    the name of the object to create
  1383. methods a list of single function declarations, in the form of null expressions
  1384. slots   a list of one or more variable declarations, in the form of null expressions
  1385. Although this is a null function, it returns an instance of the current
  1386. object.  To return the value properly, this function must be placed within a
  1387. method called new, as the methods (but not functions) called new have their
  1388. types altered to indicate that they return an instance of the current
  1389. object.
  1390.  
  1391. null function sys_create_class_object( name );
  1392. name    a string which is the name of the object to be created
  1393. Similar to sys_create_object, this returns an instance of the current
  1394. object, and thus should only be used within a method, which again must have
  1395. the name new.  The method new in class is simply null function
  1396. new( stringname ) {
  1397.    sys_create_class_object( name );
  1398. };
  1399. This returns an instance of the object class.
  1400.  
  1401. null function sys_add_method( ne )
  1402. ne      a null expression containing a single function declaration
  1403. The method described is added to the methods of the current object.  The
  1404. definition of add_method attached to meta_class and class is
  1405. null function add_method( (null) expression ne )
  1406. {
  1407.    sys_add_method(ne);
  1408. };
  1409.  
  1410. null function sys_add_slot( ne )
  1411. ne      a null expression containing one or more variable declarations
  1412. The slot(s) described are added to the current object.  The definition of
  1413. the method add_slot is
  1414. null function add_slot( (null) expression ne )
  1415. {
  1416.    sys_add_slot( ne );
  1417. };
  1418.  
  1419. null function sys_describe_object()
  1420. This displays full information about the current object.  The definition of
  1421. the method describe_object is
  1422. null function describe_object()
  1423. {
  1424.    sys_describe_object();
  1425. };
  1426.  
  1427. null function sys_get_instances()
  1428. This function returns a list of all instances of the current object.  It
  1429. should be used within a method named get_instances, the type of which is
  1430. changed to return a list of instances of the current object.  For example,
  1431. the definition of the method get_instances is
  1432. null function get_instances()
  1433. {
  1434.    sys_get_instances();
  1435. };
  1436. and the type is changed so that get_instances returns the desired object type.
  1437. The most common use of this function is with the foreach statement.
  1438.  
  1439. null function sys_delete_slot( name,flag )
  1440. name    the name of the slot to be deleted
  1441. flag    an integer indicating whether or not confirmation is required
  1442. This function removes the slot with the given name from the current object,
  1443. and all methods which refer to that slot.  It is possible to remove all
  1444. slots with the method null function delete_all(integer warning)
  1445. {
  1446.    foreach s in sys_get_slots() do
  1447.       sys_delete_slot(s,warning);
  1448. };
  1449.  
  1450. null function sys_delete_method( name,flag )
  1451. name    the name of the function to be deleted
  1452. flag    an integer indicating whether or not confirmation is required
  1453. This function removes the method named from the current object, and all
  1454. methods which refer to this method.
  1455.  
  1456. null function sys_replace_method( name,ne )
  1457. name    the name of the method to be replaced
  1458. ne      a null expression containing a single function declaration, which
  1459. will directly replace the named method
  1460. This function simply replaces the method named with that provided within the
  1461. null expression.  The names of the new method must match the old name, and
  1462. the types must be the same.
  1463.  
  1464. listof string function sys_get_slots()
  1465. This function returns a list of the names of all the slots of the current
  1466. object.  Thus, person.get_slots() would return ["name","age"].  Note that
  1467. this is one of the few "sys" functions to return a value with a fixed type.
  1468.  
  1469.  
  1470.  
  1471.  
  1472.  
  1473. 4.0  The GRS programming environment
  1474.  
  1475. In order to start tinkering with GRS, the GRS environment needs to be
  1476. understood.  If the reader has started reading this manual here, they need
  1477. only read the sections Getting Started and Running Programs.  Once the
  1478. basics have been mastered, the rest of the chapter should be read.
  1479.  
  1480. 4.1  Getting started
  1481.  
  1482. To start a GRS session, the command is
  1483.  
  1484. grs [filename] [options]
  1485.  
  1486. The filename is optional, and the options are mainly for debugging purposes. 
  1487. If a filename is provided, the file is read and executed as if it were being
  1488. read by the consult command (explained below).  An error in this file
  1489. returns causes GRS to quit, otherwise from now on all GRS errors will return
  1490. to the GRS prompt.
  1491.  
  1492. The possible options are described later.
  1493.  
  1494. 4.2  Running programs
  1495.  
  1496. Unlike some other interpreters which execute a command at a time, GRS deals
  1497. with files.  This distinction is important, and must not be forgotten,
  1498. especially where the assume statement is being used a lot, and in particular
  1499. when building up an object store.
  1500.  
  1501. There are two ways of executing files in GRS:
  1502.  
  1503. *       use an editor such as the !Edit application on the Archimedes to
  1504.         create a text file. This file can then be compiled and run using the
  1505.         consult command or by specifying the filename when starting GRS.
  1506.  
  1507. *       typing the program at the GRS prompt, and then pressing the
  1508.         end-of-file key.  It is important not to forget this end-of-file, as
  1509.         no action can take place until the end-of-file has been found.  On
  1510.         the Acorn Archimedes, this is a simultaneous press of the Ctrl key
  1511.         and the D key, commonly written as Ctrl-D.  There are many
  1512.         disadvantages to this method, not least having to re-type many lines
  1513.         of code if a mistake is made.  However it is useful for examining
  1514.         the state of certain variables or objects, and is essential when
  1515.         there is more than one GRS application resident in memory at once.
  1516.  
  1517. For the remainder of this chapter, the term file is taken to mean either a
  1518. physical file, executed by using the consult command or commands typed at
  1519. the command line, followed by an end-of-file.
  1520.  
  1521. 4.3  A short example
  1522.  
  1523. In this example, it is assumed that the following file has been created and
  1524. saved as examp.
  1525.  
  1526. integer function fact( integer n )
  1527. {
  1528.    if n <= 0 then
  1529.       return(1);
  1530.    else
  1531.       return( n*fact(n-1) );
  1532.    endif;
  1533. };
  1534.  
  1535. write("fact (5) = ",fact(5),"\n");
  1536.  
  1537. foreach a in [2,4,6,8] do
  1538.    write("fact (",a,") = ",fact(a),"\n");
  1539.  
  1540. The following sequence describes how to load and run this program, and then
  1541. make use of the function it creates.  Note that the end-of-file key-press is
  1542. represented as [EOF].
  1543.  
  1544. *grs
  1545.  
  1546. No file name given - input from keyboard.
  1547.  
  1548. GRS->consult("g.examp");    [EOF]
  1549.  
  1550. Consulting file g.examp ...
  1551. fact (5) = 120
  1552. fact (2) = 2
  1553. fact (4) = 24
  1554. fact (6) = 720
  1555. fact (8) = 40320
  1556.  
  1557. GRS->let integer z := 9;
  1558. write(z,"\n");
  1559. z := z+fact(z);
  1560. write(z,"\n");             [EOF]
  1561. 9
  1562. 362889
  1563.  
  1564. GRS->
  1565.  
  1566. To quit from GRS, use Escape on the Archimedes, or Ctrl-C on the Unix machines.
  1567.  
  1568. 4.4  Organising GRS programs
  1569.  
  1570. Because of their dynamic nature, GRS programs of any reasonable complexity
  1571. can rarely be written in a single file.  There is a limit to the number of
  1572. assume statements which can be used whilst retaining readability in the
  1573. code, and messages cannot be sent to instances until the class has been
  1574. created at run time.  So, before writing an application in GRS, thought must
  1575. be given to organising the files.  Several points should be kept in mind:
  1576.  
  1577. *       in object creation, the first file should set up the classes and
  1578.         their methods and any global functions to be used in the
  1579.         application.  It is a good idea to test this file, and then make
  1580.         this the default starting state by using the name of the file in the
  1581.         command line when starting up GRS.
  1582.  
  1583. *       once the initial classes and functions are in place, any
  1584.         relationships should be placed in subsequent files.  For example,
  1585.         setting up student isa person requires that person is created in an
  1586.         earlier file, so the object super can be used without error; then
  1587.         student has to be set up and finally the isa operator applied.
  1588.  
  1589. *       finally, the instances can be declared and created and the
  1590.         operations can begin.  Here it is good practice to use as few global
  1591.         variables as possible, and to keep the function names as specific as
  1592.         possible, to allow several applications to be resident in memory at
  1593.         the same time.  For example, the overly zealous use of integer i
  1594.         will produce many frustrating Duplicate identifier in same scope
  1595.         errors.  A possible way to overcome this is to place the final
  1596.         processes inside a large function (or even an object!), so that all
  1597.         "globals" are in fact local, but there are often circumstances where
  1598.         this is not possible.
  1599.  
  1600. Once the files have been produced, a master file can be created, which would
  1601. look something like
  1602.  
  1603. consult("file1"); consult("file2"); (* and so on *)
  1604.  
  1605. The naming of files should be consistent too.  For example, a database
  1606. application may have four files, and the master file.  These could be named:
  1607.  
  1608. *       on an Archimedes, create a directory called "database" and have files
  1609.                 file1
  1610.                 file2
  1611.                 file3
  1612.                 file4
  1613.                 master
  1614.         Or these could be given more meaningful names, such as classes and functions.
  1615.  
  1616. Here, the master file would be (for the Archimedes)
  1617.  
  1618. consult("database.file1");
  1619. consult("database.file2");
  1620. consult("database.file3");
  1621. consult("database.file4");
  1622.  
  1623. and the whole process would be started with either
  1624.  
  1625. grs database.master
  1626.  
  1627. from the operating system command line, or
  1628.  
  1629. consult("database.master");   (* plus end-of-file *)
  1630.  
  1631. from inside GRS.
  1632.  
  1633. GRS does not insist on any particular format of file name, so above all try
  1634. to group related files and keep the names fairly meaningful.
  1635.  
  1636. 4.5  Debugging options
  1637.  
  1638. There are several options available to help debug a program, although these
  1639. should be used only as a last resort.
  1640.  
  1641. -p      This displays the parse tree for every file read in by GRS. Unless
  1642.         the file is small the output from this option soon becomes confusing.
  1643.  
  1644. -s      This displays the symbol table of every file read in by GRS.
  1645.  
  1646. The following options all follow -S on the command line, but can be
  1647. combined, eg -Ssat and Â­Ssa -St are equivalent.
  1648.  
  1649. a       This displays some information about the operators such as + and ::.
  1650.  
  1651. d       This displays information about the dependencies of slots and
  1652.         methods and the processes of deletion.
  1653.  
  1654. f       This displays information surrounding function and method calls.
  1655.  
  1656. l       This echoes the file being read in by GRS.
  1657.  
  1658. o       This displays information about the object store communicating with
  1659.         the interpreter.
  1660.  
  1661. s       This displays the communication between the parameter stack and the
  1662.         interpreter.
  1663.  
  1664. t       This displays information about each node of the parse tree as it is
  1665.         interpreted and evaluated.
  1666.  
  1667. It must be stressed again that tracing in the GRS sources will provide much
  1668. more specific and helpful information than these options, although they do
  1669. provide an insight into how the GRS system operates.
  1670.  
  1671. 4.6  Resources required by GRS
  1672.  
  1673. When GRS is started, it executes a file bootclass which creates the object
  1674. class, and add some methods to meta_class.  In addition, dummy declarations
  1675. of many of the system defined functions (for example beep and itos) appear
  1676. in this file.  The user can alter this as required, but should bear in mind
  1677. the consequences.
  1678.  
  1679. bootclass is expected to be in a directory called "g", so it must be present
  1680. in the current path as g.bootclass.
  1681.  
  1682. GRS also requires the shared C library 3.50 or higher, and the floating
  1683. point emulator module.  The user is advised to set up an obey file to set
  1684. the current directory and load the requisite modules.
  1685.  
  1686. 4.7  Recovering from errors
  1687.  
  1688. GRS tries as far as possible to return the system to its initial state after
  1689. an error has occurred.  However, the error may have happened during a
  1690. critical operation such as the summon command, so there may be some
  1691. structures which contain incomplete information.  Compile time errors mean
  1692. that no attempt will be made to execute the code which caused the error.
  1693.  
  1694. 4.8  Common sources of error
  1695.  
  1696. The most common causes of error are:
  1697.  
  1698. *       no return in a function which should return a value.  This is
  1699.         usually accompanied by the GRS system error "Tried to pop from stack
  1700.         size zero."
  1701.  
  1702. *       variables declared within an assume statement not existing at run
  1703.         time, or the type being different from that within the assume
  1704.         statement.  Check for typing errors in variable names.  This is
  1705.         harder to confirm, as the program usually simply crashes or just
  1706.         behaves in an unexpected manner.
  1707.  
  1708. *       trying to reference incomplete objects.  This can occur when sending
  1709.         a message to a method which inculded an assume statement–see above. 
  1710.         Perhaps the program does not send the message "new" to fully set up
  1711.         a new object, or a warning from add_method or add_slot has been missed.
  1712.  
  1713.  
  1714.  
  1715.  
  1716. 5.0  References.
  1717.  
  1718. Paton, N.W. Diaz, O.  'Metaclasses in Object - Oriented Databases.'
  1719.         Object - Oriented Databases:  Analysis, Design and Construction,
  1720.         Proc IFIP TC 2 Working Conference On Database Semantics,
  1721.         R. A. Meersman and W. Kent (eds) North - Holland, 1990.
  1722.  
  1723. Stroustrup, B.  'An Overview of C++'.  Sigplan Notices v21 #10. October 1986.
  1724.  
  1725. Meyer, B. 'Object-oriented Software Construction'.  Prentice-Hall, 1986.
  1726.  
  1727. Inkster, S. P. A.  'A Virtual Machine And Object Store For An Object - Oriented Programming
  1728.         Language.'  Submitted as a final year dissertation for the Department Of Computer
  1729.         Science, Heriot - Watt University.  1991.
  1730.  
  1731. Verbist, G.  'A Compiler For An Object - Oriented Language.'
  1732.         Submitted as a final year dissertation for the Department Of Computer
  1733.         Science, Heriot - Watt University.  1991.
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740. Appendix.
  1741.  
  1742. A)  Some example GRS code
  1743.  
  1744. Desk calculator.
  1745.  
  1746. The following is a desk calculator which reads a typed expression from the
  1747. keyboard, and then compiles and evaluates the expression, thus remaining
  1748. independent of the type of the expression.
  1749.  
  1750. (* string / integer expression evaluator *)
  1751. (* supports integers, strings, lists of.
  1752.   + - / * :: or and not head tail mid len
  1753. *)
  1754. (* Guy Verbist 1991 *)
  1755.  
  1756. let string s := "";
  1757. string s_to_eval;
  1758. loop
  1759.    write("?-> ");
  1760.    read(s);
  1761.    exiton( (s="quit") or (s="end") or (s="exit") or 
  1762.            (s = "q") or (s="x"));
  1763.    s_to_eval := "write(\"Answer is : \",eval({" + 
  1764.                      s + "}),\"\n\");";
  1765.    exec(compile(s_to_eval));
  1766. endloop;
  1767.  
  1768. Database.
  1769.  
  1770. This is a database which reads its fields and the types of fields from the
  1771. keyboard.  It creates an instance of class called data and then compiles and
  1772. executes a message to class creating this new class, with the requisite
  1773. slots and set methods.  It then uses an add_method message to add show
  1774. methods.  The database is then queried and modified via a menu.
  1775.  
  1776. (* generic database written in GRS *)
  1777. (* shows off most of the capabilities of the language *)
  1778. (* Guy Verbist April 1991 *)
  1779.  
  1780.  
  1781. write("Enter the attributes of object:\n");
  1782. write("Enter 'end' to end.\n");
  1783.  
  1784. let listof string attribs := [];
  1785. let listof string attribtypes := [];
  1786.  
  1787. let string attrib := "";
  1788. let string attribtype := "";
  1789.  
  1790. loop
  1791.    write("Enter attribute name:\n");
  1792.    read(attrib);
  1793.    exiton(attrib = "end");
  1794.    write("Enter attribute type:\n");
  1795.    read(attribtype);
  1796.    attribs := attrib::attribs;
  1797.    attribtypes := attribtype::attribtypes;
  1798. endloop;
  1799.  
  1800. let listof string attribs_copy := attribs;
  1801. let listof string attribtypes_copy := attribtypes;
  1802.  
  1803. let listof string main_attribs := attribs;
  1804. let listof string main_types := attribtypes;
  1805.  
  1806. (* now create the class *)
  1807.  
  1808. instanceof class data;
  1809.                                         
  1810. let string tempstring :=
  1811. "data := class.new(\"data\",[{null function hello()" +
  1812.         "{write(\"Hello\n\");};} " ;
  1813.  
  1814. (*add in methods*)
  1815.  
  1816. let string methodstring := "";
  1817.  
  1818. loop
  1819.    exiton(attribs_copy = []);
  1820.    methodstring := methodstring + 
  1821.                    ",{null function set_" + 
  1822.                    head(attribs_copy)+
  1823.                    "("+head(attribtypes_copy) + 
  1824.                    " param){" +
  1825.                    "assume " + 
  1826.                    head(attribtypes_copy) + 
  1827.                    " "+head(attribs_copy) + " in " +
  1828.                    head(attribs_copy)+":= param;};}" ;
  1829.  
  1830.    attribs_copy := tail(attribs_copy);
  1831.    attribtypes_copy := tail(attribtypes_copy);
  1832. endloop;
  1833.  
  1834.  
  1835. methodstring := methodstring + "],[{";
  1836.  
  1837. (*add in slots*)
  1838.  
  1839. let string slotstring := "";
  1840.  
  1841. loop
  1842.    exiton (attribs = []);
  1843.    slotstring := slotstring + 
  1844.                  head(attribtypes) + " " + head(attribs)+ ";";
  1845.    attribtypes := tail(attribtypes);
  1846.    attribs := tail(attribs);
  1847. endloop;
  1848.  
  1849. slotstring := slotstring+"}]);";
  1850.  
  1851. exec(compile(tempstring+methodstring+slotstring));
  1852.                           
  1853. (*now add show method for each attribute*)
  1854.  
  1855. attribs_copy := main_attribs;
  1856. attribtypes_copy := main_types;
  1857.  
  1858. loop
  1859.    exiton(attribs_copy = []);
  1860.    methodstring := "null function show_" + head(attribs_copy)
  1861.                    + "(){assume " + head(attribtypes_copy) + " "
  1862.                    + head(attribs_copy) + " in write(\""
  1863.                    + head(attribs_copy)
  1864.                    + " is \"," + head(attribs_copy)
  1865.                    + ",\"\n\");};" ;
  1866.  
  1867.    let (null) expression new_method := compile(methodstring);
  1868.    exec(compile("data.add_method(new_method);"));
  1869.    attribs_copy := tail(attribs_copy);
  1870.    attribtypes_copy := tail(attribtypes_copy);
  1871. endloop;
  1872.  
  1873. write("Type 'db();' to access the database.\n");
  1874.  
  1875.  
  1876. null function db()
  1877. {
  1878.    integer function menu(listof string menu)
  1879.    {
  1880.       let integer options := 0;
  1881.  
  1882.       write("\n");
  1883.       loop
  1884.          exiton(menu = []);
  1885.          options := options +1;
  1886.          write(options,") ",head(menu),"\n");
  1887.          menu := tail(menu);
  1888.       endloop;
  1889.       write("\n");
  1890.  
  1891.       integer selection;
  1892.  
  1893.       loop
  1894.          write("Select an option between 1 and ",options," :");
  1895.          read(selection);
  1896.          exiton( (selection > 0) and (selection <= options));
  1897.       endloop;
  1898.       write("\n");
  1899.       return selection;
  1900.    };
  1901.  
  1902.    integer choice;
  1903.    string entry_name, attrib_name, attrib_val;
  1904.  
  1905.    loop
  1906.       choice := menu(["add an entry", "delete an entry", 
  1907.                       "modify entry",
  1908.                       "show an entry", "show all entries", 
  1909.                       "show all attributes", "quit"]);
  1910.       exiton(choice=7);
  1911.  
  1912.       if (choice=1) then
  1913.          write("Please enter name of entry : ");
  1914.          read(entry_name);
  1915.          exec(compile("#data "+entry_name+";"));
  1916.       endif;
  1917.  
  1918.       (* these are declared locally to the db() function so *)
  1919.       (* cannot be accessed from the command line, and will *)
  1920.       (*not conflict with anything else *)
  1921.  
  1922.       if (choice=2) then
  1923.          write("Please enter name of entry : ");
  1924.          read(entry_name);
  1925.          exec(compile("sys_delete_object("+entry_name+",true);"));
  1926.       endif;
  1927.  
  1928.       if (choice=3) then
  1929.          (*modify*)
  1930.          write("Please enter name of entry : ");
  1931.          read(entry_name);
  1932.          write("Please enter name of attribute to change : ");
  1933.          read(attrib_name);
  1934.          write("and the new value for that attribute : ");
  1935.          read(attrib_val);
  1936.          exec(compile(entry_name+".set_"+attrib_name +
  1937.                      "("+attrib_val+");"));
  1938.       endif;
  1939.       if (choice=4) then
  1940.          (*show*)
  1941.          write("Please enter name of entry : ");
  1942.          read(entry_name);
  1943.          attribs_copy := main_attribs;
  1944.          string meth_str;
  1945.          exec(compile("loop exiton(attribs_copy = []);"
  1946.                       + "meth_str := \".show_\"
  1947.                       + head(attribs_copy)+\"();\";"
  1948.                       + "exec(compile(entry_name + meth_str));"
  1949.                       + "attribs_copy := tail(attribs_copy);"
  1950.                       + "endloop;" ));
  1951.       endif;
  1952.       if (choice=5) then
  1953.          (*show*)
  1954.          exec(compile("foreach inst in data.get_instances() do {"
  1955.                       + "attribs_copy := main_attribs;"
  1956.                       + "loop exiton(attribs_copy = []);"
  1957.                       + "meth_str := \"show_\"
  1958.                       + head(attribs_copy)+\"();\";"
  1959.                       + "exec(compile(\"inst.\"+ meth_str));"
  1960.                       + "attribs_copy := tail(attribs_copy);"
  1961.                       + "endloop;};" ));
  1962.       endif;
  1963.  
  1964.       if (choice=6) then
  1965.          listof string slts;
  1966.          let integer sltcount := 0;
  1967.          foreach slt in data.get_slots() do
  1968.          {
  1969.             sltcount := sltcount +1;
  1970.             write("Attribute ",sltcount," is ",slt,".\n"); 
  1971.          };         
  1972.       endif;
  1973.  
  1974.    endloop;
  1975. };
  1976.  
  1977.  
  1978. Some short programs to demonstrate some of the features of GRS
  1979.  
  1980. Sharing objects and using objects as parameters and slots
  1981.  
  1982. In this example, there are three files.  The first creates the class person, the next creates the class book1, and finally some examples are set up and used.
  1983.  
  1984. (* --------------------------------------------------------------*)
  1985. (* file 1 - creates the class person *)
  1986. (* Steven Inkster, April 1991 *)
  1987.  
  1988. instanceof class person;
  1989.  
  1990. person := class.new(
  1991.              "person",
  1992.              [
  1993.                 {
  1994.                    null function set( integer b,d; string n )
  1995.                    {
  1996.                       assume string name; integer born,died in
  1997.                       {
  1998.                          name := n;
  1999.                          born := b;
  2000.                          died := d;
  2001.                       };
  2002.                    };
  2003.                 },
  2004.                 {
  2005.                    null function show()
  2006.                    {
  2007.                       assume string name; integer born,died in
  2008.                       {
  2009.                          write("\n",name," was born in ",born);
  2010.                          if died >= born then
  2011.                             write(" and died in ",died);
  2012.                          endif;
  2013.                          write("\n\n");
  2014.                       };
  2015.                    };
  2016.                 },
  2017.                 {
  2018.                    null function died( integer year )
  2019.                    {
  2020.                       assume integer died in
  2021.                          died := year;
  2022.                    };
  2023.                 }
  2024.              ],
  2025.              [
  2026.                 {
  2027.                    string name;
  2028.                    integer born, died;
  2029.                 }
  2030.              ]
  2031.              );
  2032.  
  2033.  
  2034.  
  2035.  
  2036. (* -------------------------------------------------------------*)
  2037. (* file 2 - creates the class book1 *)
  2038.  
  2039. instanceof class book1;
  2040.  
  2041. book1 := class.new(
  2042.             "book1",
  2043.             [
  2044.                {
  2045.                   null function set( string s; integer i;
  2046.                            listof integer l; instanceof person p )
  2047.                   {
  2048.                      assume string title;
  2049.                             listof integer publication_dates;
  2050.                             integer number_of_pages;
  2051.                             instanceof person author in
  2052.                      {
  2053.                         title := s;
  2054.                         publication_dates := l;
  2055.                         number_of_pages := i;
  2056.                         author := p;
  2057.                      };
  2058.                   };
  2059.                },
  2060.                {
  2061.                   null function show()
  2062.                   {
  2063.                      assume string title;
  2064.                             listof integer publication_dates;
  2065.                             integer number_of_pages;
  2066.                             instanceof person author in
  2067.                      {
  2068.                         write("\nBook : ",title,"\n");
  2069.                         write("published in : ");
  2070.                         foreach i in publication_dates do
  2071.                            write(i," ");
  2072.                         write("\nno of pages : ",
  2073.                            number_of_pages,"\n\n");
  2074.                         write("Author :\n");
  2075.                         author.show();
  2076.                      };
  2077.                   };
  2078.                },
  2079.                {
  2080.                   null function republished( integer date )
  2081.                   {
  2082.                      assume listof integer publication_dates in
  2083.                         publication_dates :=
  2084.                            publication_dates + [date];
  2085.                   };
  2086.                }
  2087.             ],
  2088.             [
  2089.                {
  2090.                   string title;
  2091.                   listof integer publication_dates;
  2092.                   integer number_of_pages;
  2093.                   instanceof person author;
  2094.                }
  2095.             ]
  2096.             );
  2097.  
  2098.  
  2099.  
  2100.  
  2101. (* --------------------------------------------------------------*)
  2102. (* file 3 - uses the classes to demonstrate the sharing of *)
  2103. (* objects and using objects as parameters                 *)
  2104.  
  2105. (* first set up the author *)
  2106.  
  2107. instanceof person a1;
  2108.  
  2109. a1 := person.new("Lawrence");
  2110. a1.set(1921,-1,"D. H. Lawrence");
  2111.  
  2112. (* now set up the books *)
  2113.  
  2114. instanceof book1 b1,b2;
  2115.  
  2116. b1 := book1.new( "Lady Chatterly" );
  2117.  
  2118. b1.set("Lady Chatterly",566,[1963],a1);
  2119. b2 := book1.new( "Woman In Love" );
  2120. b2.set("Woman In Love",343,[1968],a1);
  2121.  
  2122. (* now show them.  Notice the author is the same OBJECT thus *)
  2123. (* when the author is declared dead, all references to the *)
  2124. (* author reflect this *)
  2125.  
  2126. b1.show();
  2127. b2.show();
  2128.  
  2129. a1.died(1977);
  2130. b1.republished(1974);
  2131.  
  2132. b1.show();
  2133. b2.show();
  2134.  
  2135. Local "methods" / replacing methods
  2136.  
  2137. This pair of programs demonstrate how null expressions can be used to give
  2138. individual behaviour patterns to instances of a class, and then using the
  2139. method replace_method to return to the normal, uniform, manner of behaviour. 
  2140.  
  2141.  
  2142. (* ------------------------------------------------------------- *)
  2143. (* Steven Inkster April 1991 *)
  2144. (* program to demonstrate local "methods" and replacing methods *)
  2145.  
  2146. (* file 1 - sets up the class *)
  2147.  
  2148. instanceof class test;
  2149.  
  2150. test := class.new(
  2151.            "test",
  2152.            [
  2153.               {
  2154.                  null function go()
  2155.                  {
  2156.                     assume (null) expression ne in
  2157.                        run(ne);
  2158.                  };
  2159.               },
  2160.               {
  2161.                  null function set( (null) expression p )
  2162.                  {
  2163.                     assume (null) expression ne in
  2164.                        ne := p;
  2165.                  };
  2166.               }
  2167.            ],
  2168.            [
  2169.               {
  2170.                  (null) expression ne;
  2171.               }
  2172.            ]
  2173.            );
  2174.  
  2175.  
  2176.  
  2177.  
  2178.  
  2179. (* --------------------------------------------------------------- *)
  2180. (* file 2 - this actually uses the class just set up *)
  2181.  
  2182. instanceof test t1,t2;
  2183.  
  2184. t1 := test.new("t1");
  2185. t2 := test.new("t2");
  2186.  
  2187. t1.set( {write("I am t1\n");} );
  2188. t2.set(
  2189.    {
  2190.       write("I am t2\n");
  2191.       test.replace_method(
  2192.           "go",
  2193.           {
  2194.              null function go()
  2195.              {
  2196.                 write("I am an instance of test\n");
  2197.              };
  2198.           }
  2199.           );
  2200.        test.delete_slot("ne",false);    (* so we fully tidy up *)
  2201.       (* this deletion should NOT delete "go" as the new go    *)
  2202.       (* does not refer to the slot ne at all                  *)
  2203.    }
  2204.    );
  2205.  
  2206. t1.go();
  2207. t2.go();
  2208. t1.go();
  2209. t2.go();
  2210.  
  2211. Running these programs would produce :
  2212.  
  2213.         I am t1
  2214.         I am t2
  2215.         I am an instance of test
  2216.         I am an instance of test
  2217.  
  2218.  
  2219. A simple front-end to GRS
  2220.  
  2221. This program allows single commands to be passed to the GRS interpreter
  2222. without need for the end-of-file character, effectively replacing
  2223. end-of-file with the Return key.
  2224.  
  2225. (* a simple GRS front end                    *)
  2226. (* Steven Inkster November 1990 / April 1991 *)
  2227.  
  2228. null function fe()
  2229. {
  2230. string s;
  2231.  
  2232.    loop
  2233.       write("> ");
  2234.       read(s);
  2235.       exiton(s="quit");
  2236.       exec(compile(s));
  2237.    endloop;
  2238. };
  2239.  
  2240. fe();     (* so it auto-starts *)
  2241.  
  2242. A tank game
  2243.  
  2244. These programs demonstrate how get_instances and sys_delete_object can be
  2245. used in combination to produce very short, compact code.  There are three
  2246. files.  The first sets up the possible tactics to be employed by the tanks
  2247. and the class tank; the second adds the method move to the class tank and
  2248. sets up the teams; the third loops, exiting when one side has won the
  2249. battle.
  2250.  
  2251.  
  2252. (* ------------------------------------------------------------ *)
  2253. (* a tank game *)
  2254. (* Steven Inkster March 1991 *)
  2255. (* file 1 - sets up the possible tactics and the class tank *)
  2256.  
  2257. instanceof class tank;
  2258.  
  2259.  
  2260.    let (null) expression default :=
  2261.       {
  2262.          assume integer x,y in
  2263.          {  
  2264.          x := x + rnd(3) - 2;
  2265.          y := y + rnd(3) - 2;
  2266.          if x<0 then x:=0; endif;
  2267.          if x>25 then x:=25; endif;
  2268.          if y<0 then y:=0; endif;
  2269.          if y>19 then y:=19; endif;
  2270.          };
  2271.       };
  2272.  
  2273.    let (null) expression retreat :=
  2274.       {
  2275.          assume string side; integer x in
  2276.          {
  2277.          if side="German" and x>0 then
  2278.             x := x-1;
  2279.          else
  2280.             if side="American" and x<25 then
  2281.                x := x+1;
  2282.             endif;
  2283.          endif;
  2284.          };
  2285.       };
  2286.  
  2287.    let (null) expression advance :=
  2288.       {
  2289.          assume string side; integer x in
  2290.          {
  2291.          if side="American" and x>0 then
  2292.             x := x-1;
  2293.          else
  2294.             if side="German" and x<25 then
  2295.                x := x+1;
  2296.             endif;
  2297.          endif;
  2298.          };
  2299.       };
  2300.  
  2301.    let (null) expression panic :=
  2302.       {
  2303.          assume integer x,y in
  2304.          {
  2305.             x := x;
  2306.             y := y;
  2307.          };
  2308.       };
  2309.  
  2310. assume string side; integer x,y,skill; (null) expression tactic in
  2311. {
  2312.    tank := class.new(
  2313.               "tank",
  2314.               [
  2315.                  {
  2316.                     null function set( string pside; integer px;
  2317.                                        integer py; integer pskill )
  2318.                     {
  2319.                        side := pside;
  2320.                        x := px;
  2321.                        y := py;
  2322.                        skill := pskill;
  2323.                        tactic := default;
  2324.                     };
  2325.                  },
  2326.                  {
  2327.                     null function set_tactic(
  2328.                             (null) expression ptactic )
  2329.                     {
  2330.                        tactic := ptactic;
  2331.                     };
  2332.                  },
  2333.                  {
  2334.                     integer function get_pos( string myside )
  2335.                     {
  2336.                        if myside = side then
  2337.                           return(-1);
  2338.                        else
  2339.                           return(x+y*256);
  2340.                        endif;
  2341.                     };
  2342.                  },
  2343.                  {
  2344.                     null function blowup()
  2345.                        {
  2346.                           beep();
  2347.                           foreach s in ["X","x","X","x","X","x"] do
  2348.                           {
  2349.                              tab(x,y);
  2350.                              write(s);
  2351.                           };
  2352.                        };
  2353.                  },
  2354.                  {
  2355.                     null function display()
  2356.                     {
  2357.                        tab(x,y);
  2358.                        write(mid(side,1,1));
  2359.                     };
  2360.                  }
  2361.               ],
  2362.               [
  2363.                  {
  2364.                     string side;
  2365.                     integer x,y,skill;
  2366.                     (null) expression tactic;
  2367.                  }
  2368.               ]
  2369.               );
  2370. };
  2371.  
  2372.  
  2373. (* ---------------------------------------------------------------- *)
  2374. (* file 2 - add the method "move" and set up the teams *)
  2375.  
  2376. integer function abs( integer i )
  2377. {
  2378. if i<0 then
  2379.    return(-i);
  2380. else
  2381.    return(i);
  2382. endif;
  2383. };
  2384.  
  2385.  
  2386. assume string side; integer x,y,skill; (null) expression tactic in
  2387. {
  2388.    let (null) expression movefunc :=
  2389.      {
  2390.         null function move()
  2391.         {
  2392.            integer shot;
  2393.            integer epos;
  2394.            integer ex,ey;
  2395.  
  2396.            foreach i in tank.get_instances() do
  2397.            {
  2398.               shot := false;
  2399.               epos := i.get_pos(side);
  2400.               ey := epos/256;
  2401.               ex := epos - (ey*256);
  2402.               if epos<>-1 and abs(y-ey)<4 and
  2403.                  abs(x-ex)<4 and rnd(3)<>1 then
  2404.                  shot := true;
  2405.                  foreach s in [".","|",".","|",".","|",
  2406.                                ".","|",".","|",".","|",
  2407.                                ".","|",".","|",".","|",
  2408.                                ".","|",".","|",".","|",
  2409.                                ".","|",".","|",".","|"] do
  2410.                  {
  2411.                     tab(x,y);
  2412.                     write(s);
  2413.                  };
  2414.                  if rnd(100)<skill then
  2415.                     i.blowup();
  2416.                     sys_delete_object(i,false);
  2417.                  endif;
  2418.               endif;
  2419.               if not shot then
  2420.                  run(tactic);
  2421.                  if rnd(10)=1 then
  2422.                     integer nt;
  2423.                     nt := rnd(10);
  2424.                     if nt=1 or nt=2 then
  2425.                        i.set_tactic(retreat);
  2426.                     else
  2427.                        if nt=3 or nt=4 or nt=5 then
  2428.                           i.set_tactic(advance);
  2429.                        else
  2430.                           if nt=6 then
  2431.                              i.set_tactic(panic);
  2432.                           else
  2433.                              if nt>6 then
  2434.                                 i.set_tactic(default);
  2435.                              endif;
  2436.                           endif;
  2437.                        endif;
  2438.                     endif;
  2439.                  endif;
  2440.               endif;
  2441.            };
  2442.         };
  2443.      };
  2444. };
  2445.  
  2446.  
  2447. tank.add_method( movefunc );
  2448.  
  2449. #tank gt1;
  2450. #tank at1;
  2451. #tank gt2;
  2452. #tank at2;
  2453. #tank gt3;
  2454. #tank gt4;
  2455. #tank at3;
  2456. #tank gt5;
  2457.  
  2458.  
  2459. gt1.set("German",10,3,30);
  2460. gt2.set("German",10,6,30);
  2461. gt3.set("German",10,9,30);
  2462. gt4.set("German",10,12,30);
  2463. gt5.set("German",10,15,30);
  2464.  
  2465. at1.set("American",15,5,60);
  2466. at2.set("American",15,15,60);
  2467. at3.set("American",25,10,90);
  2468.  
  2469.  
  2470.  
  2471.  
  2472.  
  2473.  
  2474.  
  2475.  
  2476. (* ----------------------------------------------------------- *)
  2477. (* file 3 - the main loop *)
  2478.  
  2479. integer function somebody_has_won()
  2480. {
  2481. integer germans, americans;
  2482.  
  2483.    germans := 0;
  2484.    americans := 0;
  2485.  
  2486.    foreach i in tank.get_instances() do
  2487.    {
  2488.       if i.get_pos("German")=-1 then
  2489.          germans := germans + 1;
  2490.       else
  2491.          americans := americans + 1;
  2492.       endif;
  2493.    };
  2494.  
  2495.    if americans=0 then
  2496.       write("\n\nThe Germans have won!\n\n");
  2497.       return(true);
  2498.    else
  2499.       if germans=0 then
  2500.          write("\n\nThe Americans have won!\n\n");
  2501.          return(true);
  2502.       else
  2503.          return(false);
  2504.       endif;
  2505.    endif;
  2506. };
  2507.  
  2508. null function go()
  2509. {
  2510.    cls();
  2511.  
  2512.    foreach i in tank.get_instances() do
  2513.    {
  2514.       i.display();
  2515.    };
  2516.  
  2517.    loop
  2518.       foreach i in tank.get_instances() do
  2519.       {
  2520.          i.move();
  2521.       };
  2522.  
  2523.       cls();
  2524.  
  2525.       foreach i in tank.get_instances() do
  2526.       {
  2527.          i.display();
  2528.       };
  2529.  
  2530.       exiton( somebody_has_won() );
  2531.  
  2532.    endloop;
  2533. };
  2534.  
  2535. go();
  2536.  
  2537.  
  2538.  
  2539.  
  2540.  
  2541.  
  2542.  
  2543. b)  Compiler / Analyser Error Messages.
  2544.  
  2545. Where possible a line number is printed for the error and that line of the
  2546. source file is printed.
  2547.  
  2548. * = An identifier or the like will appear here
  2549. ! = Internal error, should never appear.
  2550.  
  2551. b1)  Syntax errors.
  2552.  
  2553. These are generated by the syntax analyser.
  2554.  
  2555. GRS parser: unrecognised statement (ignored)
  2556.  
  2557. A whole statement was syntactically incorrect and was ignored.
  2558.  
  2559. GRS parser: missing 'function' in function declaration (inserted)
  2560.  
  2561. A function declaration was missing the keyword 'function'.  This error is
  2562. fully recoverable.
  2563.  
  2564. GRS parser: missing closing ')' in function 
  2565.             argument list (inserted)
  2566.  
  2567. A function argument list was missing a closing parenthesis.  This error is
  2568. fully recoverable.
  2569.  
  2570. GRS parser: error in function decl arg list (args ignored)
  2571.  
  2572. An error occurred in the argument list of a function declaration.  The
  2573. arguments were ignored.
  2574.  
  2575. GRS parser: error in identifier of iterator (iterator ignored)
  2576.  
  2577. The identifier used in an iterator caused a parse error.  The entire
  2578. iterator was ignored.
  2579.  
  2580. GRS parser: error in assumed function arg list (args ignored)
  2581.  
  2582. The arguments of an assumed function were incorrect and so ignored.
  2583.  
  2584. GRS parser: error in declaration list of assume (assume ignored)
  2585.  
  2586. A list of assumed variables caused a parse error, the whole assume statement
  2587. was ignored.
  2588.  
  2589. GRS parser: error in constant expression (ignored)
  2590.  
  2591. A constant typed or null expression declaration caused a parse error.  The
  2592. expression was ignored.
  2593.  
  2594. GRS parser: error in constant list (ignored)
  2595.  
  2596. A constant list caused a parse error.  The list was ignored.
  2597.  
  2598. GRS parser: missing closing ')' around <type> expression (inserted)
  2599.  
  2600. A type declaration of an expression needs brackets around the type, of which
  2601. the closing on was missing but inserted.  This error is fully recoverable.
  2602.  
  2603. GRS parser: missing closing ')' in exiton() (inserted)
  2604.  
  2605. The closing bracket of an exiton(<expression>) was missing.  This error is
  2606. fully recoverable.
  2607.  
  2608. GRS parser: error in block (ignored)
  2609.  
  2610. A parse error occurred in a block statement.  The entire block was ignored.
  2611.  
  2612. GRS parser: error in function parameters (parameters ignored)
  2613.  
  2614. A parse error occurred in a set of function call parameters.  The parameters
  2615. were ignored.
  2616.  
  2617. GRS parser: error in bracketed expression (ignored)
  2618.  
  2619. A parse error occurred in a bracketed expression.  The expression was
  2620. ignored.
  2621.  
  2622. GRS parser: parse error at symbol * line *
  2623.  
  2624. A general syntax error has occurred in the current input file.
  2625.  
  2626. GRS parser: Unexpected end of file within a comment.
  2627.  
  2628. The compiler encountered an end of file within a comment.  This probably
  2629. means that the programmer has forgotten to close a comment.
  2630.  
  2631. GRS parser: warning - possible nested comments at line *
  2632.  
  2633. The compiler has encountered a (* sequence within a comment.  This is
  2634. possibly valid, but probably means that comments have been nested, probably
  2635. during "commenting out" of sizeable blocks of code.  In this case the code
  2636. will be scanned from the first closing comment delimiter and this will
  2637. probably result in bizarre syntactic and semantic errors.
  2638.  
  2639.  
  2640.  
  2641. b2)  Semantic errors.
  2642.  
  2643. These errors are flagged by the semantic analyser:
  2644.  
  2645. GRS parser: cannot bring a non-null expression into scope
  2646.  
  2647. The user is attempting to run summon() or exec() on something which is not a
  2648. null expression.  This is commonly caused by a semicolon missing from the
  2649. end of statement, thus making it an expression which yields a null, not a
  2650. null expression in the GRS sense.
  2651.  
  2652. !  GRS parser: not a null expression.
  2653.  
  2654. A parameter given to a new() method as a slot declaration was not a null
  2655. expression.
  2656.  
  2657. GRS parser: not a variable declaration for slots.
  2658.  
  2659. A null expression given to a new() method as a slot declaration was not a
  2660. variable declaration.  It will be ignored but this may well cause code
  2661. referring to this slot to crash at run time.  A common cause of this error
  2662. is an assume statement surrounding a variable declaration.
  2663.  
  2664. GRS parser: Warning, multiple statements in single method declaration.
  2665.  
  2666. A parameter given to a new() method as a method declaration contained
  2667. multiple statements.  Everything after the first statement is ignored.
  2668.  
  2669. GRS parser: duplicate identifier in same scope *
  2670.  
  2671. An identifier has been declared with the same name as one already present in
  2672. this level of scope.
  2673.  
  2674. GRS parser: attempt to create instanceof non-class object *
  2675.  
  2676. The user has attempted to create an instanceof something which is not a
  2677. class.
  2678.  
  2679. GRS parser: too few params in function call.
  2680.  
  2681. Too few parameters were given in a function call compared with the number of
  2682. parameters in the declaration.
  2683.  
  2684. GRS parser: type mismatch in fcall (should be a typed expression).
  2685.  
  2686. A call to eval() was attempted with a parameter which is not a typed
  2687. expression.
  2688.  
  2689. GRS parser: type mismatch in fcall (should be a list).
  2690.  
  2691. A call to head() or tail() was attempted with a parameter which was not a
  2692. list.
  2693.  
  2694. GRS parser: type mismatch in fcall.
  2695.  
  2696. A parameter in a function call had a different type to parameter in
  2697. declaration.
  2698.  
  2699. GRS parser: attempt to write null expression.
  2700.  
  2701. It is not meaningful to attempt to write() an expression which yields a
  2702. null.
  2703.  
  2704. GRS parser: attempt to read non variable.
  2705.  
  2706. It is not meaningful to attempt to read() a constant expression or an
  2707. object.
  2708.  
  2709. GRS parser: mismatch in fcall args.
  2710.  
  2711. A bad mismatch in argument numbers occurred in a function call. Either the
  2712. call has multiple arguments and the declaration has none or the call has
  2713. none whereas the declaration expects one or more.
  2714.  
  2715. GRS parser: too many args in fcall.
  2716.  
  2717. There were too many arguments given for a function call.
  2718.  
  2719. !  GRS parser: attribs are null.
  2720.  
  2721. Bad internal error.
  2722.  
  2723. GRS parser: Differring types in constant list.
  2724.  
  2725. Expressions of different types have been placed in a constant list.  The
  2726. expressions must all be of the same type so the list is listof that type.
  2727.  
  2728. GRS parser: unknown identifier * (class name?).
  2729.  
  2730. An attempt has probably been made to assume an instanceof a class which does
  2731. not exist.
  2732.  
  2733. GRS parser: expression to iterate across does not yield a list.
  2734.  
  2735. A foreach iterator must iterate across a list of some type.
  2736.  
  2737. GRS parser: attempt to access non - existent object by name *
  2738.  
  2739. The user has attempted to send a message to an object by a name which does
  2740. not exist. e.g. "name".method() where "name" does not exist.
  2741.  
  2742. GRS parser: attempt to access non - existent method *
  2743.  
  2744. The user is sending a message to an object trying to use a method which that
  2745. object does not have.
  2746.  
  2747. GRS parser: unknown identifier *
  2748.  
  2749. An attempt to access an identifier which does not exist.
  2750.  
  2751. GRS parser: cannot return - not in a function.
  2752.  
  2753. A return statement has been encountered outside a function.
  2754.  
  2755. GRS parser: must return an expression from a non-null function.
  2756.  
  2757. A non-null function must return something, it cannot just return;.
  2758.  
  2759. GRS parser: returned expression must be same type as function.
  2760.  
  2761. The type of the expression returned from a function must match the type
  2762. declared for the function.
  2763.  
  2764. GRS parser: rhs of cons is not a list.
  2765.  
  2766. The right hand side of a cons "::" operation must a list.
  2767.  
  2768. GRS parser: type mismatch in cons.
  2769.  
  2770. The left hand side of a cons "::" operation must have the same type as an
  2771. element of the list on the right hand side.
  2772.  
  2773. GRS parser: type mismatch.
  2774.  
  2775. One or more of the operands for an operator do not match the permitted
  2776. combinations of types for that operator.
  2777.  
  2778. GRS parser: type mismatch in assignment.
  2779.  
  2780. The right hand side of an assignment must have the same type as the variable
  2781. on the left hand side.
  2782.  
  2783. GRS parser: cannot assign to a function
  2784.  
  2785. It is not meaningful to assign to an identifier which represents a function.
  2786.  
  2787. GRS parser: controlling expression does not yield an integer.
  2788.  
  2789. The controlling expression of an if or loop statements must yield an
  2790. integer; true or false.
  2791.  
  2792. GRS parser: non -existent class name in isa *
  2793.  
  2794. One or more of the identifiers in an isa statement is not a class name.
  2795.  
  2796. GRS parser: sys_delete_object takes (object,integer) parameters.
  2797.  
  2798. The first parameter of sys_delete_object must be an object of some class and
  2799. the second must be an integer, true or false.
  2800.  
  2801. !  GRS parser: parameter which should be an object has no attributes.
  2802.  
  2803. A bad error has occurred in checking the parameters of sys_delete_object.
  2804.  
  2805. !  GRS parser: first parameter is not an object.
  2806.  
  2807. A bad error has occurred in checking the parameters of sys_delete_object.
  2808.  
  2809. !  GRS parser: parameter which should be an integer has no attributes.
  2810.  
  2811. A bad error has occurred in checking the parameters of sys_delete_object.
  2812.  
  2813. !  GRS parser: second parameter does not yield an integer.
  2814.  
  2815. A bad error has occurred in checking the parameters of sys_delete_object.
  2816.  
  2817. b3)  Memory Errors.
  2818.  
  2819. If one of these errors occurs then GRS has run out of memory, or something
  2820. more sinister is occurring within the target hardware.  The solution is
  2821. system dependent.
  2822.  
  2823. GRS parser: no room for new scope child.
  2824. GRS parser: no room for new attribute.
  2825. GRS parser: no room for heap attribute.
  2826. GRS parser: no room for expression stack.
  2827. GRS parser: out of memory for copying tree.
  2828. GRS parser: no memory for symbol table.
  2829.  
  2830.  
  2831.  
  2832.  
  2833. c)  Interpreter / Object Store Error Messages.
  2834.  
  2835.  
  2836. c1)  Internal fatal errors
  2837. All of these errors are preceded by the message
  2838.  
  2839. GRS fatal system error
  2840.  
  2841. and followed by information as to where within the GRS system the error was
  2842. produced, for example
  2843.  
  2844. Source is 'c.eval' at line 309
  2845.  
  2846. c 1.1)  Stack errors
  2847.  
  2848. Stack errors occur when the internal stack has become full, or an attempt
  2849. has been made to pop a value from an empty stack.  The former will happen
  2850. only in very complex expressions or with long lists, the latter will happen
  2851. if a non-null function is called, but the function has not executed a return
  2852. statement.  This will produce the error Tried to pop from stack size zero
  2853. followed by the specific error.
  2854.  
  2855. Stack error in list cons
  2856.  
  2857. The interpreter was unable to stack the result of the :: operator.
  2858.  
  2859. Failed to push result of string +
  2860.  
  2861. The interpreter was unable to stack the result of the + operator.
  2862.  
  2863. Failed to push result of unary minus
  2864.  
  2865. The interpreter was unable to stack the result of the unary minus operator.
  2866.  
  2867. Failed to push the result of logical NOT
  2868.  
  2869. The interpreter was unable to stack the result of the NOT operator.
  2870.  
  2871. EXPRCONST could not stack the address
  2872.  
  2873. The interpreter was unable to stack the value of an expression.
  2874.  
  2875. Stack error in XXX NODE
  2876.  
  2877. This indicates that an operator was unable to pop its operands.  The most
  2878. likely cause is that a function appears as one of the operands and has
  2879. failed to return a value.  The XXX can be  PLUS, MINUS, MULT, DIVIDE, CONS,
  2880. OR, AND, EQUALS, NOT EQUALS, LESS THAN OR EQUAL TO, LESS THAN, GREATER THAN
  2881. OR EQUAL TO, GREATER THAN, NOT, UMINUS.
  2882.  
  2883. Error in popping stack to build a list
  2884.  
  2885. Building a list involves making constant use of the stack.  This error
  2886. should never occur.
  2887.  
  2888. Could not pop the LVAL at assign node
  2889.  
  2890. The stack was empty when the address to which to assign the value was
  2891. required.
  2892.  
  2893. Could not pop the RVAL at assign node
  2894.  
  2895. The stack was empty when the value of the expression to assign to the
  2896. identifier was required.
  2897.  
  2898. IF node not able to find logical value
  2899.  
  2900. The stack was empty when the value of the condition in an if statement was
  2901. required.
  2902.  
  2903. Stack error at LOOP node
  2904.  
  2905. The stack was empty after the evaluation of the condition within the exiton
  2906. command.
  2907.  
  2908. c 1.2)  Errors around system defined functions
  2909.  
  2910. The errors which may be produced are all to do with collecting the
  2911. parameters from the stack, and then stacking the result.  The former should
  2912. always be correct because of the semantic checking [Verbist 91], the only
  2913. time an error will occur is when the internal stack is full. All of the
  2914. errors are of the form
  2915.  
  2916. FUNCTION NAME did not have N parameter(s)
  2917.  
  2918. and
  2919.  
  2920. Could not stack the result of FUNCTION NAME
  2921.  
  2922. c 1.3)  Miscellaneous errors
  2923.  
  2924. These errors are caused for a variety of reasons.
  2925.  
  2926. Failed to compare element in lists_identical
  2927.  
  2928. The list equality operator has found an element with unknown type in the
  2929. list.
  2930.  
  2931. Failed to unstack parameter in call_function
  2932.  
  2933. The parameter stack had emptied before all of the parameters had been
  2934. assigned a value.  This will happen if a parameter is a function call which
  2935. has not returned a value.
  2936.  
  2937. Failed to assign parameter in call_function
  2938.  
  2939. The value on the stack being assigned to the parameter was of unknown type.
  2940.  
  2941. Expression type tree error
  2942.  
  2943. The type tree of a variable is of an unknown form, despite the root node
  2944. suggesting that the type is some sort of expression.
  2945.  
  2946. Tried to read <identifier>
  2947. Cannot take the value of a NULL variable
  2948.  
  2949. The interpreter had to try and read the value of an identifier whose type
  2950. was null.
  2951.  
  2952. Failed to evaluate identifier
  2953.  
  2954. The identifier was of an unrecognised type.
  2955.  
  2956. call_node is null for exec/eval
  2957.  
  2958. The interpreter has not recorded the node from which the call to exec or
  2959. eval was made.  This information is required so that variables can be dealt
  2960. with in the correct scope.  This error should never appear.
  2961.  
  2962.  
  2963.  
  2964. Add given unknown types
  2965.  
  2966. The + operator has been asked to add a type which it does not recognise.
  2967.  
  2968. Found a node not capable of being an LVAL
  2969.  
  2970. The identifiers on the left side of an assignment or in the parameter list
  2971. of a call to the read function are of an unknown type.
  2972.  
  2973. Failed to assign list element in foreach
  2974.  
  2975. The list element was of an unknown type.
  2976.  
  2977. Assign node - Failed to assign the node
  2978.  
  2979. The value on the stack was of an unknown type.
  2980.  
  2981. Failed to unstack parameter when saving locals
  2982.  
  2983. A parameter within a function could not be given its value as the stack was
  2984. empty.
  2985.  
  2986. Failed to assign parameter in save_locals (unknown type)
  2987.  
  2988. An unrecognised type has appeared on the stack and therefore the parameter
  2989. cannot be assigned a value.
  2990.  
  2991. Could not print the variable type
  2992.  
  2993. or
  2994.  
  2995. Failed to print parameter
  2996.  
  2997. or
  2998.  
  2999. Could not print variable parameter
  3000.  
  3001. or
  3002.  
  3003. Failed to print constant parameter
  3004.  
  3005. These are when trying to print an identifier (either via debugging
  3006. diagnostics or directly using write) but an unexpected type has been found.
  3007.  
  3008. c 1.4)  Object store errors
  3009.  
  3010. These errors should never occur, as the situations should only arise if
  3011. there are inconsistencies within the object store.
  3012.  
  3013. <O1> was supposed to be an instance of <O2>
  3014. Unexpected instance of an object
  3015. This occurs when the class of the object O1 is O2, but the list of instances of O2 is empty.
  3016.  
  3017. Failed to find <O1> in instances of <O2>
  3018. Failed to find an instance of an object
  3019.  
  3020. This error occurs when deleting object O1, and it cannot be found in the
  3021. list of instances of its class, the object O2.
  3022.  
  3023. <O1> was supposed to be an instance of <O2>
  3024.  
  3025. Unexpected subclass of an object
  3026.  
  3027. and
  3028.  
  3029. Failed to find <O1> in subclasses of <O2>
  3030. Failed to find a subclass of an object
  3031.  
  3032. These errors are the same as the previous two, except they deal with the isa
  3033. relationship rather than the usual object-class relationship.
  3034.  
  3035. c 1.5)  Memory failures
  3036.  
  3037. The GRS system often has to claim more memory.  If it is unable to claim any
  3038. more memory, the error
  3039.  
  3040. Fatal error : GRS system out of memory
  3041.  
  3042. is produced.
  3043.  
  3044. c 1.6)  User errors
  3045.  
  3046. These errors are all preceded by
  3047.  
  3048. GRS run time error :
  3049.  
  3050. which is then followed by the messages described below.
  3051.  
  3052. Error occurred in file described in command line
  3053. If the file which was given to execute when starting GRS is not correct this
  3054. error is produced and the system then exits and returns to the operating
  3055. system.
  3056.  
  3057. Assumed variable non-existent at run time
  3058. A variable which had appeared within an assume statement has not been
  3059. provided.  This error is unlikely to appear, as the result of referring to a
  3060. non-existent variable is undefined.
  3061.  
  3062. Attempt to evaluate head([])
  3063. Attempting to evaluate head of the empty list is illegal and causes a run
  3064. time error.
  3065.  
  3066. Parameter to add_method was not a method
  3067. The null expression passed to add_method was not a single function
  3068. declaration.
  3069.  
  3070. Parameter to add_slot was not a slot
  3071. The null expression passed to add_slot was not a set of one or more variable
  3072. declarations.
  3073.  
  3074. Parameter to sys_replace_method was not a method
  3075. The null expression passed to sys_add_method was not a single function
  3076. declaration.
  3077.  
  3078. GRS parser could not consult 'filename'
  3079. File could not be opened
  3080. The parameter passed to consult was not a valid filename.
  3081.  
  3082. Tried to find method <M> in class <C>
  3083. Failed to find/execute the method
  3084. An attempt has been made to reference, most likely to execute, a method
  3085. which has been deleted since compilation.
  3086.  
  3087. Replace method - method <M> is not attached to object <O>
  3088. An attempt has been made to replace a non-existent method.  This error may
  3089. be followed by nor its superclass <S> if the object has a superclass.
  3090.  
  3091. Name error - tried to replace <N1> with <N2>
  3092. The method offered as a replacement has a different name to the original
  3093. method.
  3094.  
  3095. Type of new method <M> is not the same as the previous method
  3096. The name of the method offered as a replacement matches, but the type it
  3097. returns is not the same.
  3098.  
  3099. isa of <O> does not exist
  3100. A reference to the object super has been made within a class whose
  3101. superclass does not exist.
  3102.  
  3103.  
  3104. c 1.7)  User warnings
  3105.  
  3106. A warning given at run time has the form
  3107. GRS run time warning :
  3108. followed by the appropriate message.
  3109.  
  3110. Division by zero
  3111. If the user attempts a division by zero, this warning is produced, and the
  3112. result is L where the division is L/R.
  3113.  
  3114. null expression has not been analysed
  3115. The user has attempted to run a null expression which has been produced by
  3116. compile but not analysed by either exec or summon.
  3117.  
  3118. expression provided is not a legal slot
  3119. and
  3120. expression provided is not a legal method
  3121. The list of slots or methods passed with the message new are not legal. 
  3122. However it is only a warning as the rest of the list will be processed
  3123. correctly.
  3124.  
  3125.  
  3126.  
  3127.  
  3128.  
  3129.  
  3130. d)  BNF grammar for GRS.
  3131.  
  3132. String literals are enclosed in single (') quotation marks.
  3133. Non terminals are enclosed in angle brackets (<,>).
  3134.  
  3135. { ... } indicates 0 or more.
  3136.  
  3137. <statements> ::=
  3138.         {<statement> ';'}
  3139.  
  3140. <statement> ::=
  3141.           <funcdecl>
  3142.         | <loop>
  3143.         | <vardecl>
  3144.         | <assignment>
  3145.         | <ifstmt>
  3146.         | <letstmt>
  3147.         | <message>
  3148.         | <assumest>
  3149.         | <block>
  3150.         | <iterator>
  3151.         | <fcall>
  3152.         | <return>
  3153.         | <isa>
  3154.  
  3155. <funcdecl> ::=
  3156.         <type> 'function' <identifier> 
  3157.             '(' <arglist> ')' <block>
  3158.  
  3159. <iterator> ::=
  3160.         'foreach' <identifier> 'in' 
  3161.             <expr> 'do' <statement>
  3162.  
  3163. <assumest> ::=
  3164.           'assume' <declist> 'in' <statement>
  3165.         | 'assume' <type> 'function' <identifier> 
  3166.               '(' <arglist> ')' 'in' <statement>
  3167.  
  3168. <isa>   ::=
  3169.         identifier 'isa' identifier
  3170.  
  3171. <arglist> ::=
  3172.         {<declist>}
  3173.  
  3174. <declist> ::=
  3175.           <declist> ';' <vardecl>
  3176.         | <vardecl>
  3177.  
  3178. <vardecl> ::=
  3179.         <type> <identlist>
  3180.  
  3181. <paramlist> ::=
  3182.         {<expr>} {',' <expr>}
  3183.  
  3184.  
  3185. <identlist> ::=
  3186.         <identifier> {',' <identifier>}
  3187.  
  3188. <identifier> ::=
  3189.         <letter> {id2}
  3190.  
  3191. <id2> ::=
  3192.           <letter>
  3193.         | <digit>
  3194.  
  3195. <letter> ::=
  3196.           'a'
  3197.         | 'b'
  3198.         | 'c'
  3199.         .
  3200.         .
  3201.         .
  3202.         | 'z'
  3203.         | 'A'
  3204.         | 'B'
  3205.         .
  3206.         .
  3207.         .
  3208.         | 'Z'
  3209.  
  3210. <digit> ::=
  3211.           '0'
  3212.         | '1'
  3213.         | '2'
  3214.         .
  3215.         .
  3216.         .
  3217.         | '9'
  3218.  
  3219. <constant> ::=
  3220.           <integer>
  3221.         | <string>
  3222.         | '[' <constlist> ']'
  3223.         | '{' <expr> '}'
  3224.         | '{' <statements> '}'
  3225.  
  3226. <integer> ::= 
  3227.         <digit> {<digit>}
  3228.  
  3229. <string> ::=
  3230.         '"' {<string2>} '"'
  3231.  
  3232. <string2> ::=
  3233.           <character>
  3234.         | '\"'
  3235.  
  3236. <constlist> ::=
  3237.         <expr> {,<expr>}
  3238.  
  3239. <type> ::=
  3240.           <type1>
  3241.         | '(' <type> ')' 'expression'
  3242.  
  3243. <type1> ::=
  3244.           'integer'
  3245.         | 'string'
  3246.         | 'null'
  3247.         | 'listof' <type>
  3248.         | 'instanceof' <identifier>
  3249.         | '#' <identifier>
  3250.         | 'create' <identifier>
  3251.  
  3252. <letstmt> ::=
  3253.         'let' <type> <assignment>
  3254.  
  3255. <loop> ::=
  3256.         'loop' <statements> 'exiton' '(' <expr> ')' 
  3257.               ';' <statements> 'endloop'
  3258.  
  3259. <block> ::=
  3260.         '{' <statements> '}'
  3261.  
  3262. <assignment> ::=
  3263.         <identifier> ':=' <expr>
  3264.  
  3265. <fcall> ::=
  3266.         <identifier> '(' <paramlist> ')'
  3267.  
  3268. <return> ::=
  3269.           'return' <expr>
  3270.         | 'return'
  3271.  
  3272. <ifstmt> ::=
  3273.         'if' <expr> 'then' <statements> <restif>
  3274.  
  3275. <restif> ::=
  3276.            'endif'
  3277.         |  'else' <statements> 'endif'
  3278.  
  3279. <expr> ::=
  3280.           <expr> 'or' <e1>
  3281.         | <e1>
  3282.  
  3283. <e1> ::=
  3284.           <e1> 'and' <e2>
  3285.         | <e2>
  3286.  
  3287. <e2> ::=
  3288.           <e2> '=' <e3>
  3289.         | <e2> '<>' <e3>
  3290.         | <e2> '>' <e3>
  3291.         | <e2> '<' <e3>
  3292.         | <e2> '>=' <e3>
  3293.         | <e2> '<=' <e3>
  3294.         | <e3>
  3295.  
  3296. <e3> ::=
  3297.           <e3> '+' <e4>
  3298.         | <e3> '-' <e4>
  3299.         | <e4>
  3300.  
  3301. <e4> ::=
  3302.           <e4> '*' <e5>
  3303.         | <e4> '/' <e5>
  3304.         | <e4> '::' <e5>
  3305.         | <e5>
  3306.  
  3307. <e5> ::=
  3308.           'not' <e5>
  3309.         | '-' <e5>
  3310.         | <e6>
  3311.  
  3312. <e6> ::=
  3313.           <fcall>
  3314.         | '(' <expr> ')'
  3315.         | <val>
  3316.         | <message>
  3317.  
  3318. <val> ::=
  3319.           <identifier>
  3320.         | <constant>
  3321.  
  3322.  
  3323. <message> ::=
  3324.           <identifier> '.' <fcall>
  3325.         | <string> '.' <fcall>
  3326.  
  3327.  
  3328.  
  3329.  
  3330. e)  Known Infelcities Of Version 1.05.
  3331.  
  3332. a)      References to assumed variables which do not exist at run time cause
  3333.         the interpreter to crash.  No method was found to signal the fact
  3334.         that a reference was assumed and may not exist any more.
  3335.  
  3336. b)      A declaration of instanceof person fred; does not create a new
  3337.         object. This object must be filled out by 
  3338.             fred := person.new("fred");
  3339.         or the whole affair can be replaced by #person fred;
  3340.  
  3341. If an instance is referenced before it has been "filled out" then the object
  3342. store will crash e.g.
  3343.  
  3344. instanceof person fred;
  3345. fred.set(12);
  3346.  
  3347.