--** Test definitions for OccamDoc.
-- This file should exercise all of OccamDoc's features.
-- @maintainer Adam Sampson <ats@offog.org>

--* Test with comment marker
VAL []BYTE T1 IS "--":

VAL INT T2 IS 42: --* Test at EOL

--* Test with multiple lines.
-- Line line line.
-- Line line line.
VAL INT T3 IS 42:

--* Test with tags.
-- Line line line.
-- @maintainer Joe Example
--   <joe@example.com>
-- @deprecated
VAL INT T4 IS 42:

--* Test PROC.
PROC t5 (VAL INT arg1, arg2, BYTE arg3)
  SKIP
:

--* Test PROC with nested stuff inside it.
PROC t6 ()
   --* Test inner PROC -- since this isn't visible it probably ought to be
   -- explicitly @private.
  PROC t6.inner ()
    SKIP
  :
  t6.inner ()
:

--* Test RECORD.
DATA TYPE T7
  RECORD
    INT no.comment:
    --* Normal comment.
    INT normal.comment:
    INT eol.comment: --* EOL comment
    -- This is not OccamDoc, it's just a regular occam comment.
:

--* Test OccamDoc with regular comment too.
-- This is OccamDoc.

-- This is not OccamDoc.
-- This is not OccamDoc.
PROC t8 ()
  SKIP
:

--* Draw a straight line between two points using pixels.
-- This uses [@link http://example.com/bresenham/ Bresenham's
-- algorithm] with some adjustments for anti-aliased output.
-- To enable anti-aliasing, pass [@code TRUE] as the [@code antialias]
-- argument.
--
-- Note that this code is [@em very] inefficient on vector displays;
-- it is better to use [@ref draw.vector.line].
PROC draw.pixel.line ()
  INT x:
  --* Test abbreviation.
  INT y IS x:
  SKIP
:

--* Output a string (with optional padding) to a channel.
-- @param string The string to output.
-- @param width The width, in characters, to pad the output to; if the
--   string is shorter than this, spaces will be added at the end so
--   that width characters are written. Use 0 for no padding.
-- @param out The channel to output to.
PROC out.string (VAL []BYTE string, VAL INT width, CHAN BYTE out!)
  SKIP
:

--* Calculate the length of a UTF-8 string in runes.
-- Runes are Unicode characters, which may be encoded using multiple
-- bytes.
-- @param string The string.
-- @return The number of runes in the string.
INT FUNCTION utf.length (VAL []BYTE string)
  INT x:
  VALOF
    x := (SIZE string)
    RESULT x
:

--* Graphics to be rendered.
-- @item x X coordinate.
-- @item y Y coordinate.
-- @item pixels Pixel data in packed 24-bit format.
PROTOCOL GRAPHICS IS INT; INT; MOBILE []BYTE:

--* Commands to the rendering engine.
PROTOCOL COMMANDS
  CASE
    --* Start rendering.
    -- @item seed Initial seed for the RNG.
    start; INT
    --* Stop rendering.
    stop
:

--* A chunk of image data.
DATA TYPE CHUNK
  MOBILE RECORD
    INT x:               --* X coordinate.
    INT y:               --* Y coordinate.
    MOBILE []INT pixels: --* Pixel data in packed 24-bit format.
:

--* Width of display.
VAL INT WIDTH IS 640:

--* Square brackets in comment.
-- [This is not a tag.]
-- [This [isn't [one] either.].].
-- [@code This is, but it's got some in it: [[]]]
VAL INT T9 IS 42:

--* Private; this should not show up in the output.
-- @private
VAL INT T10 IS 42:

--* Deprecated, since, etc.
-- @deprecated
-- @since KRoC 3.141
VAL INT T11 IS 42:

--* Test formatted code block.
--
-- [@code
-- SEQ i = 0 FOR T12
--   IF
--     (i \ 2) = 0
--       create.universe (i)
--     TRUE
--       destroy.universe (i)]
--
-- After formatted code.
VAL INT T12 IS 42:

--* Test multiple paragraphs in param.
-- @param foo This is the
--   first paragraph.
--
--   This is the second paragraph.
--
--   This is the third. They should all be run together in the output.
-- @param bar This is just one line.
PROC t13 (VAL INT foo, bar)
  SKIP
:

--* Test cross-references.
-- Have a look at [@ref T1].
VAL INT T14 IS 42:

--*{ TG Test group.
-- This is used as a nasty workaround for not having proper ENUMs.
VAL INT TG.NORTH IS 1: --* North
VAL INT TG.SOUTH IS 1: --* South
VAL INT TG.WEST IS 1: --* West
VAL INT TG.EAST IS 1: --* East
--*}

--* Continuation lines.
-- Oh dear -- yes, most of these can be found in the course library...
-- Note the fold header with what looks like a continuation but isn't.

--{{{  PROC t15 (VAL INT x,
PROC t15 (VAL INT x,
          y,
          z, INT a)
  SEQ
    a := (x +
     (y +
     z))
    BOOL b:
    b := TRUE AND
     FALSE
    a := a +
     a
    a :=
     a
    INITIAL INT b IS 42:
    a,
     b :=
     b,
     a
:
--}}}

--* One-liner function.
-- @param x Argument
-- @return Return value
INT FUNCTION t16 (VAL INT x) IS x + 1:

--* More complicated one-liner function.
-- @param char Character
-- @param bottom Bottom
-- @param top Top
-- @return Whether it's in range
BOOL FUNCTION is.in.range (VAL BYTE char, bottom, top) IS
 ((char >= bottom) AND (char <= top)) :

--* Multi-return-value function.
-- @param x Input value
-- @return The input value as-is
-- @return The input value as a byte
-- @return The input value as a boolean
INT, BYTE, BOOL FUNCTION t17 (VAL INT x) IS x, BYTE x, BOOL x:

--* Flat mobile type.
DATA TYPE PACKET IS MOBILE []BYTE:

--* Structured mobile type.
DATA TYPE S.PACKET
  MOBILE RECORD
    [512]BYTE data:       --* data in the packet
    INT32 chk32:          --* 32-bit checksum
    INT64 chk64:          --* 64-bit checksum
:

--* Mobile channel type.
CHAN TYPE CT.IO
  MOBILE RECORD
    CHAN INT request?:    --* requests made on this channel
    CHAN INT response!:   --* responses given here
:

--* Process type.
-- This is the integrator-style process type, just input and output.
-- @param in Input to the process
-- @param out Output from the process
PROC TYPE PT IS (CHAN INT in?, out!):

--* Lists of items.
-- Permitted colours are:
--
-- [@item] red
-- [@item] green
-- [@item] aquamarine
-- [@item] puce; this is [@em only] visible on displays with firmware Version 3
--   or later
-- [@item] black
--
-- Remember to take colour-blindness into account when choosing colour schemes.
--
-- @param command The command to execute
PROC t18 (VAL []BYTE command)
  SKIP
:

--* Inline function.
INT INLINE FUNCTION inline.func (VAL INT x) IS x:

--* Inline PROC.
INLINE PROC inline.proc (VAL INT x)
  SKIP
:

--* Recursive PROC, short form.
REC PROC rec.proc (VAL INT x)
  SKIP
:

--* Recursive PROC, long form.
RECURSIVE PROC recursive.proc (VAL INT x)
  SKIP
:

--* Recursive CHAN TYPE, short form.
REC CHAN TYPE REC.CT
  MOBILE RECORD
    CHAN INT c?:
:

--* Recursive CHAN TYPE, long form.
RECURSIVE CHAN TYPE RECURSIVE.CT
  MOBILE RECORD
    CHAN INT c?:
:

--* Continuation lines in IS functions, 1.
BYTE INLINE FUNCTION not.nested.1 (VAL REAL64 x) IS
--BYTE ROUND (x * MAX64):                     -- linear
  BYTE ROUND ((x * (2.0 - x)) * MAX64):       -- quadratic
--* Continuation lines in IS functions, 2.
BYTE INLINE FUNCTION not.nested.2 (VAL REAL64 x) IS

  BYTE ROUND ((x * (2.0 - x)) * MAX64):       -- quadratic
--* Continuation lines in IS functions, 3.
BYTE INLINE FUNCTION not.nested.3 (VAL REAL64 x) IS
  BYTE ROUND ((x * (2.0 - x)) * MAX64):       -- quadratic

--* Bizarre spacing.
-- This is contrary to the style guide -- but it's legal!
INT     ,     INT      INLINE      FUNCTION   spaced    (VAL  INT     x)     IS
                                x:
--* Comments in tables.
VAL []INT TABLE IS [0,	-- comment
                    1,
                    2]:

--* User-defined operator.
--
--  @param X Operand
--  @param Y "shift" count
--  @return X scaled by 2^Y

REAL32 FUNCTION ">>" (VAL REAL32 X, VAL INT Y) IS  SCALEB (X,  Y):

--* Multiline UDO.
INT FUNCTION "+" (VAL INT x, y) IS
  x + y:

--* UDOs with the same operator but different types, 1.
INT FUNCTION "-" (VAL INT x, y) IS x - y:

--* UDOs with the same operator but different types, 2.
REAL32 FUNCTION "-" (VAL REAL32 x, y) IS x - y:

--* Stars in strings, 1.
PROC stars.1 ()
  foo ("**")
:

--* Stars in strings, 2.
PROC stars.2 ()
  foo ("**")
:

--* Stars in strings, 3.
INT32 FUNCTION "**" (VAL INT32 x, y) IS x * y:

--* Stars in strings, 4.
INT64 FUNCTION "**" (VAL INT64 x, y) IS x * y:

--* Multiple variables in a record.
DATA TYPE POINT
  RECORD
    REAL64 X, Y: --* Coordinates
:

--* Retyped constant
VAL REAL80 Zero.REAL80 RETYPES [0, 0, 0]:

--* Things that look like OccamDoc comments in strings.
VAL []BYTE COMMENT.STRING IS "-----*n":
