picma
  Contents
  
  
  
   picma [options] [file...]
  
   Options include:
   
    - -h
    
- Print help text and exit
    
- -d types
    
- Generate debug output of various types:
     
      | l | Assembler listing |  | p | Passes |  | t | Code tree |  | a | Code allocation |  | f | Code freespace map |  | s | Struct freespace map |  | b | Stack backtrace |  
 
- -f type
    
- Select output format, type is either 'hex', 'ptf', or 'hp'.
    
- -m type
    
- Write a HTML memory map to stdout, of the given type. Type should be 'C', 'R', 'D', or 'P'.
    
- -o file
    
- Output code to the given file instead of stdout.
    
- -r
    
- On UNIX, swap '.' and '/' in included names. Ignored on RISC OS.
    
- -t
    
- Enable throwback (ignored on UNIX)
    
- -u
    
- Same as -r, except this is active on RISC OS and ignored on UNIX.
    
- -v
    
- Turns on an increasing number of -d options.
    
- -I path
    
- Defines or replaces the default search path when looking for
        included files. On RISC OS, the default is 'picma:', on UNIX it is the contents of 'PICMA_PATH'.
   
   Whitespace in the input is generally optional, and can be any mix of CR, LF, SPC, and TAB.
   Anything between /* and */, and anything from // until the end
   of the line is ignored. /*...*/ comments can also be nested.
  
Entities
  
   - program
   
- A complete program consists of 1 or more files. The filenames can come from the command
       line, where the files will be concatenated and treated as one big file. Other files can be
       included with #include. The syntax of #include depends on the build environment:
 
        - RISC OS
- Directories are separated with '.', and the path is a ','-separated list of prefixes.
        - #include "[path.]wildmask"
 This searches in the directory holding the current file, or in
            a subdirectory if the optional path is given.
            All the files that match the given wildmask are included
            as they are found.
- #include <[path.]wildmask>
 This searches the include path (see -I above), adding the
            optional path given, and finds the first directory that
            contains one or more files matching the wildmask. All
            the matching files in this directory are then included.
- UNIX
- Directories are separated with '/', and the path is a ':'-separated list of directories.
        - #include "[path/]wildmask"
 This searches in the directory holding the current file, or in
            a subdirectory if the optional path is given.
            All the files that match the given wildmask are included
            as they are found.
- #include <[path/]wildmask>
 This searches the include path (see -I above), adding the
            optional path given, and finds the first directory that
            contains one or more files matching the wildmask. All
            the matching files in this directory are then included.
- Windows
- This is apparently a relatively new OS used by an unknown number of people. No build is
            planned for that OS until it matures.
       
 
       In all cases the files are inserted in place of the include command.
 Another relevant command is #include_only_once. If this is encountered in a file that
       has already been included, the parsing stops as if the file ended at that point.
 
       All this produces one long sequence of statements.
 These statements are implicitly inside an unseen block, which is in turn attached to a
       global code statement. This is important because that global code statement
       has the base = P0 option set, which means that any instructions present in the top
       level will be stored from P0.
 
 
- block
   
- A block is 0 or more statements enclosed in { }. Every block has its own local
       name scope, and variables are looked up by working outwards from the current block.
       Each block also has local begin and end labels, pointing to the first word and
       the one after the last, respectively. These are constants, and cannot be changed.
   
- statement
   
- There are several types of statements:
       
        - expr ;
        
- This simply evaluates the given expr. Since the result is thrown away, this is
            most useful for expressions that end up changing variables.
            There is a special case of this statement:
 varref ( [ expr ] [ , [ expr ] ... ] ] ) ;
 This would normally call the named function and throw the result away. Instead it invokes
            the named macro with the given argument list. If there are more args than the macro takes,
            the rest are ignored. If there are less, the missing macro parametres will
            exist, but be unassigned.
 
- #prefix name1 = name2 ;
        
- This defines a prefix in the current block called name1 with the value
            name2. See below for more information on prefixes.
        
- block
        
- This creates a block containing the enclosed statements.
        
- instr [ expr [ , expr ... ] ] ;
        
- This stores the given instruction at the current word.
            
            A valid instruction is one from the following list, or their uppercase versions:
 addlw, addwf, andlw, andwf, bcf, bsf, btfsc, btfss, call, clrf, clrw,
            clrwdt, comf, decf, decfsz, goto, incf, incfsz, iorlw, iorwf, movf, movlw, movwf, nop,
            retfie, retlw, return, rlf, rrf, sleep, sublw, subwf, swapf, xorlw, xorwf.
 Or any of the aliases:
 addwl, andwl, iorwl, movwl, retwl, subwl, xorwl.
 
- name:
        
- This defines a label (an area in the program memory) called name.
        
- area expr , [ newvar [ := expr ] ]
            [ ,    [ newvar [ := expr ] ] ... ] ;
        
- This defines a number of vars, based on the area given. If any of the the newvars
            are given values, the relevant areas are initialised too.
 The first var defined will have the area value given. The next will have the same width,
            but placed just after the previous var, and so on. You can also omit both the newvar
            and the value, which will just skip the area that you've come to.
 
- alloc varref , { members } ;
        
- This creates a local copy of the named area, if it doesn't exist already, and allocates a
            number of subset areas within it. The members have the same syntax and meaning as
            structure members. In this case they are created as constants, in
            the scope of the alloc statement.
 When the names go out of scope, so does the local copy of varref, and the areas
            allocated are in effect freed for reuse by subsequent alloc statements.
            Once you have alloc'ed from an area, it (locally) shrinks by the amount
            used, and any other references to that area within that scope will use the new, smaller,
            area. If this is done in the top level (or varref starts with '?'), it will already
            exist, so there will be no local copy, it will never go out of scope, and you never get
            the allocated space back.
- chip string ;
        
- This statement predefines all the chip\* variables to standard values for the
            given chip. There can be more than one, but they must all use the same chip name.
 The following chip names are recognised:
 12F629, 12F675, 16F84, 16F627, 16F628, 16F872, 16F873, 16F874, 16F876, 16F877.
- code varref options block
        
- This defines a code block with the options given.
            It creates a constant word area as varref which points to the start of the code
            block, and has the same width.
 Note that creating a code block (rather than just a block), also declares that the
            code is relocatable, and it may be placed anywhere (unless there is a link
            statement for it).
 
            The possible code options are listed below. The options are given as name/value pairs
            enclosed in ( ). The list can be empty, and the brackets may then be omitted.
             
             - base = expr
             
- Force the start of the code block to be at the address specified (which must be
                 a program area).
             
- nowrap [ = expr ]
             
- Prevent the code block from crossing a block boundary, with the block size given
                 (or 256 if none is specified). If this option is not present, the chip still has a
                 default block size that will apply to the code block.
             
- optional
             
- This declares the code block optional. If it ends up unused, it will not be included
                 in the output. There are certain rules that must be followed to use this feature
                 safely:
                 
                  - A block is considered "in use" if its name-label is used in a call,
                      goto, link, or uses statement. This includes inside
                      the block itself, so you should use "begin" instead, if you want to refer to the start.
                  
- Any other jump to the block, e.g. using a calculated address, will not be spotted.
                      Hence, if you have optional code blocks that might be called in this way, you
                      should add appropriate uses statements to make sure they are not
                      removed.
                  
- When a block is removed, it generates a warning. Use option\warning\cr
                      to turn it off.
                  
- Don't make the reset code optional (or any other code on a hardware vector).
                      Chances are it is not called (by you), and hence will be removed. Bad thing.
                  
- Note that the statements inside a removed block will still be executed, it just won't
                      generate any code or labels. If these have global effects, they will still happen.
                 
 
 
            You can have several code blocks of the same name in the same scope. There will only be one
            label, and it points to the last block defined. This requires that all the other blocks are
            optional, otherwise it results in an error about reassigning that label. The last
            block (which is the only one not removed) may also be optional, but that is not required.
             
            For each code block, a local variable called "!name" is created, containing the fully expanded
            name of the code block (i.e. without prefixes). This is an internal variable, and it can only
            be accessed via the @ operator, as in @"!name".
         
- def newvar [ = expr ] [ , newvar
            [ = expr ] ... ] ;
        
- This defines one or more variables, with optional initial values. When creating constants,
            giving intitial values is mandatory.
        
- do block while expr ;
        
- This will execute the block, and keep doing that until the expr is 0.
        
- enum [ varref [ = expr ] ] [ , [ varref
            [ = expr ] ] ... ] ;
        
- This is another way of creating areas, where each of the varrefs can define its own
            area. The first area will have the value 0 if none is specified. The next will increase
            like in the area object, as long as no specific value is given. If both name
            and value is omitted, the value is increased like normal, but not assigned to anything.
            All variables created will be constants.
        
- error expr [ , expr ... ] ;
        
- This makes the assembler output the given exprs as an error, and stop.
        
- every expr , ( [ expr ] [ , [ expr ] ...
            ] ] ) ;
        
- This expands all macros that match the given wildcarded expr (which must produce a
            string), passing the arguments to each of them. The matches are expanded in alphabetical order.
            If no macros match the expr, nothing happens (it is not an error).
        
- for ( expr ; expr ; expr ) block
        
- This will evaluate the first expr, and while the second expr is non-0, it
            will execute the given block and then evaluate the third expr after each
            execution.
        
- foreach ( varref = expr ) block
        
- This will expand the given block once for each variable that matches the wildcarded
            string expression. The matches are processed in alphabetical order. For each expansion,
            varref is set to the name of the matched variable. The value can be extracted using
            @varref.
 Make sure you only match variables that are defined at the point of the foreach
            statement. If more matching names are created later, the next pass may create more code,
            and you will get an error about that.
- func name ( [ varref [ , varref ] ... ]
            ) block
        
- This defines a function of the given name, taking the listed parameters.
            The code in block is executed when the function is evaluated. There are certain
            statements you can't use in the block, namely all the ones that can generate data to go
            in the output. This includes all PIC instructions, label definitions, macro calls,
            area, init, and alloc.
 There is an exception to this
            rule: Inside functions return expr ; is allowed, but instead
            of generating a return instruction, it makes the function return with the given expr
            as result.
- if expr block
 if expr block else block
- This evaluates the expr as a scalar, and if non-0, executes the first block 
            given. Otherwise the second block is executed if it is present.
        
- init expr := expr [ , expr :=
            expr ... ] ;
        
- This initialises the given areas.
        
- link expr ;
        
- expr is evaluated, and the result must be a string. This will ensure that the named
            codeblock is assembled at the current position. There are rules:
            
             - The name must match an existing code block label (i.e. no forward references).
             
- There can be 0 or 1 link statements for each code block.
             
- Linked blocks are always optional, and will be removed if the enclosing block is
                 removed.
             
- The base and nowrap options can also be used for the linked block.
                 The enclosing block will not be moved because of these, they will just generate errors
                 if they end up wrong.
            
 
- macro name ( [ varref [ , varref ] ... ]
            ) block
        
- This defines a macro of the given name, taking the listed parameters.
            The code in block is expanded when the macro is invoked. The macro name can be used
            according to the same rules that apply to variables, except you can use forward references
            to macros.
        
- print expr [ , expr ... ] ;
        
- This will print (to stdout) all the exprs given, evaluating each one. It finishes by
            printing a newline.
        
- return expr ;
        
- This is valid inside functions only. The function returns with the given value.
        
- switch expr { cases }
        
- The expr is evaluated, and compared with the cases until a match is
            found. That block is then executed.
            There are two types of cases:
             
             - case expr block
             
- The block is executed if the expr matches the one in the enclosing
                 switch.
             
- default block
             
- The block is executed if none of the other cases matched.
            
 There can be 0 or more case blocks, and 0 or 1 default block.
- uses expr ;
        
- This statement takes a string, which must be a code block name. The named
            code block is then considered "in use", and won't be removed if it is optional.
        
- warning expr [ , expr ... ] ;
        
- This makes the assembler output the given exprs as a warning.
        
- while expr block
        
- This will evaluate the expr, and while it is non-0, execute the block.
       
 
- newvar
   
- This is a variable that will be created. It is an varref, optionally prefixed by
       const (which creates a constant variable).
   
- varref
   
- This is an entity that can be written to, i.e. a variable reference. It can be either
       a name or @( expr ). The latter will evaluate the expression,
       and use the result as the name (which must become a string).
       Writing @(" name ") is the same as writing name.
   
- name
   
- An identifier used for variables, macro names, etc. It is a string of 1 char from the set [A-Za-z_¬\],
       followed by 0 or more from [0-9A-Za-z_¬\]. names are case sensitive.
 There are certain reserved words and constructs that cannot be used for a name.
       Here is a list of reserved names:
        - Preset variables, e.g. true, false, chip\name, etc.
        
- Keywords, e.g. area, enum, init, etc.
        
- Instructions, e.g. addlw, addwf, andlw, etc. (and their uppercase versions)
        
- Aliases, e.g. addwl, andwl, etc.
        
- Literal areas
       
 The easiest way to avoid reserved names is to use mixed case, e.g. 'Output'. If short enumerated
       names are desired, use lowercase like d0, d1, d2, etc. to avoid making an area instead.Global namesBy prepending '?' to a name, you can refer to the global version of that variable. This works
       everywhere a name is acceptable, but it doesn't make sense in all cases. You can for example
       create a global var in a loop, but if it runs more than once, you get an error trying to create it
       the second time. The solution is of course to create it outside the loop, and only assign it inside.
       
       A block can have any number of prefixes defined, using the #prefix statement. You can then
       use names like foo#bar, where 'foo' is the name of a prefix. The value of this prefix will
       then be used instead of 'foo#' when looking up the variable. This works for variables, macro names,
       function names, and code block names. The prefix name must be a plain name, and can't contain
       '?' or '#'. The value can contain a prefix itself, but not '?'.
       When searching for the named prefix, the source structure is used  (rather than the
       execution structure used for everything else). This means that the parent of a macro definition is the
       block where it is defined, and not the block where it is invoked.
        Example:
 #prefix foo = baz;
def foo#bar = 5; // this creates a variable called "bazbar"
 Note: When using '?' in combination with prefixes, the prefix has higher precedence. This means
       that ?foo#bar will search for the 'foo' prefix in the current block (and then the parent,
       etc.), but the resulting name is then looked up globally.
    
- expr
   
- An expression, containing 1 or more names, literals, or exprs in
       combination with operators. Valid expressions, highest precedence first:
       
        | Precedence | expr | Effect/Result | 
|---|
 | 17 | ( expr ) | expr |  | 16 | expr -> expr | Structure operator, see structures |  | 15 | expr [ expr ] | Indexed subset of area, indexed character from string, or indexed sub-structure. See also
             structures. |  | 15 | name++ | Return name, then increase it |  | 15 | name-- | Return name, then decrease it |  | 15 | varref ( [ expr ] [ , [ expr ] ... ] ] ) | Return value after calling the named function with the given arguments |  | 15 | bytes( expr ) | Size of an area, a string, or a structure, rounded up to a whole number of bytes. For a scalar
             it is (scalar + 7) / 8. |  | 15 | bits( expr ) | Exact size of an area, a string, or a structure, in bits. Returns a scalar unchanged. |  | 15 | asc( expr ) | ASCII value of the first character of the string expr. Returns 0 if given a null string. |  | 15 | chr( expr ) | A string containing the character that has an ASCII value of expr. Returns a null string
             if expr is 0. |  | 15 | now() | The current date and time as a string. |  | 15 | def( expr ) | True if @(expr) exists |  | 15 | type( expr ) | Returns the type of @(expr) as a string: 
              | "scalar" | for scalars |  | "string" | for strings |  | "area C" | for configuration areas |  | "area R" | for register areas |  | "area D" | for data areas |  | "area P" | for program areas |  | "struct" | for structures |  | "" | for existing, but unassigned vars |  |  | 15 | left( expr1, expr2
                    ) | The first expr2 chars of the string expr1 |  | 15 | right( expr1, expr2
                    ) | The last expr2 chars of the string expr1 |  | 15 | mid( expr1, expr2
                    ) | The last part of the string expr1, starting at position
             expr2 (0 is the first position) |  | 15 | mid( expr1, expr2,
                    expr3 ) | expr3 chars of the string expr1, starting at position
             expr2 |  | 15 | str( expr ) | expr as a string (same as print would output) |  | 15 | firstleft( expr1, expr2
                    ) | Takes two string expressions. Returns the left part of expr1, up to but
             excluding the first occurence of expr2 (searching from left). |  | 15 | firstright( expr1, expr2
                    ) | Takes two string expressions. Returns the right part of expr1, down to but
             excluding the first occurence of expr2 (searching from right). |  | 15 | lastleft( expr1, expr2
                    ) | Takes two string expressions. Returns the left part of expr1, up to but
             excluding the last occurence of expr2 (searching from left). |  | 15 | lastright( expr1, expr2
                    ) | Takes two string expressions. Returns the right part of expr1, down to but
             excluding the last occurence of expr2 (searching from right). |  | 14 | expr . expr | Convert area to bit area, with given bit offset |  | 14 | expr ` expr | Change width of area |  | 13 | ++name | Increase name, then return it |  | 13 | --name | Decrease name, then return it |  | 13 | ../expr | expr evaluated in the parent scope |  | 13 | @expr | Reference to a variable, whose name is given in the string expression. |  | 13 | $expr | Scalar value. The base offset of areas and structures, and the numerical value of strings. |  | 13 | &expr | Bit offset of area or structure |  | 13 | *expr | Mask of area or structure |  | 13 | ~expr | Binary NOT |  | 13 | !expr | Logical NOT |  | 13 | -expr | Negation |  | 12 | expr * expr | Multiplication |  | 12 | expr / expr | Division |  | 12 | expr % expr | Modulus |  | 11 | expr + expr | Addition, and string concatenation |  | 11 | expr - expr | Subtraction |  | 10 | expr >> expr | Binary shift right |  | 10 | expr << expr | Binary shift left |  | 9 | expr >= expr | Logical greater than or equal |  | 9 | expr <= expr | Logical less than or equal |  | 9 | expr > expr | Logical greater than |  | 9 | expr < expr | Logical less than |  | 8 | expr != expr | Logical difference |  | 8 | expr == expr | Logical equality |  | 7 | expr & expr | Binary AND |  | 6 | expr ^ expr | Binary EOR |  | 5 | expr | expr | Binary OR |  | 4 | expr && expr | Logical AND |  | 3 | expr ^^ expr | Logical EOR |  | 2 | expr || expr | Logical OR |  | 1 | name = expr | Assigns value of expr to name, and returns that value |  | 1 | name += expr | Adds (or concatenates) expr with name, and stores and returns the result |  | 1 | name -= expr | Subtracts expr from name, and stores and returns the result |  | 1 | name *= expr | Multiplies name by expr, and stores and returns the result |  | 1 | name /= expr | Divides name by expr, and stores and returns the result |  | 1 | name %= expr | Calculates name modulus expr, and stores and returns the result |  | 1 | name |= expr | Ors expr with name, and stores and returns the result |  | 1 | name &= expr | Ands expr with name, and stores and returns the result |  | 1 | name ^= expr | Eors expr with name, and stores and returns the result |  | 1 | name <<= expr | Shifts name left by expr bits, and stores and returns the result |  | 1 | name >>= expr | Shifts name right by expr bits, and stores and returns the result |  
 
  A literal can have one of 4 different types:
  
  
  A scalar is a one-dimensional integer. Literal scalars can be written in various ways:
  
   - Prefixed with 0b, it is in binary.
   
- Prefixed with 0x, it is in hexadecimal.
   
- Prefixed with 0, it is in octal.
   
- Any other number is in decimal.
   
- A character constant enclosed in single quotes. This is either a single character,
       or an escape sequence from the list below:
       
        | Char | Written as | Char | Written as | 
|---|
 | BEL | \a | FF | \f |  | CR | \r | BS | \b |  | VT | \v | TAB | \t |  | LF | \n | \ | \\ |  | ? | \? | ' | \' |  | " | \" |  |  |  
 It is also possible to use \ooo and \xhh to denote the
       corresponding char in octal or hexadecimal.
An area is a 2-dimensional extent. One dimension is the type of memory,
  which can be configuration memory (C), registers (R), EEPROM data (D), or
  program memory (P). The second dimension is the offset within this
  memory. Finally, it also has a size. Literal areas are written like
  this:
  areatype scalar
  where areatype is either 'C', 'R', 'D', or 'P', defining the type of memory, and the
  scalar is the offset in words. The size of a literal area is always 1 word.
  Example: D10: 1 word at offset 10 in the EEPROM data memory.
  
The . and ` operators can be used to change the properties of an area.
  area . expr changes the area from word to bit, giving it a bit-offset
  equal to the scalar value of expr. The size of the area changes to 1 bit.
  area ` expr changes the size of the area to the scalar value of expr.
  The size is measured in either bits or words depending on the type of area given.
  
Examples:
  D10.0: 1 bit at (word-)offset 10 in the EEPROM data memory.
  D10.0`4: 4 bits at (word-)offset 10 in the EEPROM data memory.
  D10`4: 4 bytes at (word-)offset 10 in the EEPROM data memory.
  
  A string is a sequence of max. 511 chars enclosed in double quotes. Character constants can also
  be used within strings (with the same behaviour as in scalars). These are C
  strings, so they can not contain \0 (NUL).
  Example: "foo\n": The word 'foo' followed by an LF.
  
  A structure is a collection of data areas called members. Structures can be in two states,
  prototypes and instances. The prototypes have everything except a base address, and can be used in
  calculations where only the size is used. When a base address is attached (using ->),
  the value becomes an instance of the prototype, and can be used where actual addresses are needed.
  All structures are treated as normal values, and can be stored in variables, used within expressions,
  etc.
  A literal structure prototype is written like this:
  struct { member [, member ]... }
  
Each member has a unique name within a structure, and can take 3 forms:
  
   - name = bit [ .expr ] [`expr ]
 A bit area with an optional fixed offset (in bits) and the given width in bits (default 1).
- name = byte [ .expr ] [`expr ]
 A byte area with an optional fixed offset (in bytes) and the given width in bytes (default 1).
- name = expr [ .expr ] [`expr ]
 This bases the member on the given expr, which must evaluate to a structure. This can
       optionally be placed on a fixed offset (in bits). Giving a width of n means that the
       referenced structure will be repeated n times.
Note that the syntax allows name to start with '?', and/or be a @(...)
  reference. This is because the same syntax is used in alloc. If you use anything except
  a plain name in a structure, it will be allowed (the space will be allocated), but you will not be
  able to reference the member with ->.Example:
def x = struct {
  foo = bit`6,		// 6 bit wide bitfield
  bar = byte,		// one single byte
  baz = bit.14`2,	// two bits at offset 14 (byte 1, bit 6 and 7)
  quux = struct {	// inline sub-structure
    flop = bit.0	// one bit fixed at offset 0
  }.20`3		// makes 3 copies of the sub-structure (total of 3
			// bits) and places it at offset 20
};
  The structure operator -> has 3 different modes of operation, depending on the
  type of the first argument given:
  
   - area -> struct
 This creates an instance of the given structure, with the given area as base address. The
   area must be greater than or equal to the size of the structure. A warning is generated if the given
   struct is an instance instead of a prototype (but it is still allowed to happen). If the
   struct requires byte-alignment, it is an error to base it on a bit area with a bit offset
   other than 0. See below for details on alignment rules.
- struct prototype -> member
 This returns the size of the given member in bits. You can use bytes() on this to get
   the whole number of bytes.
- struct instance -> member
 This returns a value representing the given member. If the member is a plain bit or byte field, a
   normal area is returned. Otherwise an instance of the given sub-structure is returned, which can
   then be selected from with a further -> if desired.
The [ operator has special behaviour for structures. Normally it uses the "natural size"
  of the base area to index a given item. When used on a structure, it uses the size of the structure
  as the "natural size". This means that in the example above, the 3 copies of the sub-structure
  can be referenced as x->quux[0], x->quux[1], and x->quux[2].
  
Note that there is no difference between x->quux[0] and x->quux.
  This is because there are no arrays in this language (it just looks like it). So there are not really
  3 structures there, just one that takes 3 times the space.
  
  There are special rules for alignment of structures and their members. These rules only apply if there
  are byte members involved, which must be byte-aligned to be useful. If you want byte-size
  fields without the alignment, use bit members of size 8.
  Any byte members in the structure will get byte-aligned offsets. This alignment is contagious, and
  the structure itself will also have to be byte-aligned to ensure that the members are. If this structure
  is then used as part of another structure, it infects that as well, and it will also require byte
  alignment. In certain cases the byte-alignment also spreads to the size of the structure, for example if
  there are more than one in a sequence. Padding bits may be inserted between them so each copy is
  byte-aligned. These bits are 'lost', i.e. it is currently impossible for the member allocation code to
  place small bitfield members within these padding spaces. This may be added in the future, so don't
  assume that the padding bits are free for other uses.
  
  
  There are a few predefined global constants: w=0, f=1, false=0,
  true=1.
  
Options
  Also, there are many preset options that can be changed. All of these have the form
  option\type[\name].
  
   - Type "warning"
   
- All of these can be turned on or off. The value 0 switches the warning off. Any other scalar
       switches the warning on. They all default to 1 unless changed.
       
        | variable | Warning | 
|---|
 | option\warning\op | Overwriting program memory at offset ... |  | option\warning\ss | Using string value as scalar |  | option\warning\as | Using area base as scalar |  | option\warning\bw | Using bit area as word area |  | option\warning\pw | Using partial area as whole word |  | option\warning\mb | Using multi-bit area as one bit |  | option\warning\rb | Replacing bit offset |  | option\warning\wb | Wrapping bit offset |  | option\warning\wa | Wrapping area offset |  | option\warning\wd | Wrapping destination specifier |  | option\warning\wn | Wrapping bit number |  | option\warning\ge | Jump to expression, ... |  | option\warning\cr | Code '...' not in use, removed |  | option\warning\movf | Default destination is f, ... |  | option\warning\bitwrap | Bitfield x`y crosses byte boundary, ... |  | option\warning\rebase | Rebasing struct |  | option\warning\fw | Having a local 'f/w' is... |  | option\warning\oldalloc | This code uses the old alloc syntax |  
 Example: option\warning\bw = false;
- Type "print"
   
- There is only one of these. It turns off the print statement if set to false.
       It actually turns it off, i.e. the arguments will not be evaluated, so any side effects
       from these will stop happening.
 Example: option\print = false;
- Type "list"
   
- These control the assembler listing (enabled by -v). They are all on by default.
 
        | variable | Effect | 
|---|
 | option\list | If set to false, it disables the assembler listing. |  | option\list\file | Enables printing of the filename. |  | option\list\line | Enables printing of the line number. |  
 Example: option\list = false;
- Type "ptf"
   
- These allow you to set the headers when the output format is ptf. Normally they will not
       exist, so the headers are omitted. When created (using def) the relevant header
       lines will be included. They must be created in the global scope to have any effect.
       
        | variable | Effect | 
|---|
 | option\ptf\name | Creates a header line called name. |  
 Example: def ?option\ptf\Date = now();
  Note that there is a big difference between
  option\foo = ... and
  def option\foo = ...
  In the former case, you are changing the existing value, which would usually be the global
  setting. In the latter case, you create a new local option, and the selected value only applies
  within the current block. This is exactly like all other variables.
  
Chip characteristics
  Another set of variables define the limits of the target chip. The complete set is:
  
   | variable | Contents | 
|---|
| chip\name | This is just a string giving the name of the chip. It is mainly used to ensure that
       you don't accidentally include libraries written for different incompatible chips. | 
| chip\size\config | This is the size of the configuration area, in words. | 
| chip\size\data | This is the size of the EEPROM data area, in bytes. | 
| chip\size\program | This is the size of the program area, in words. | 
  All of these are set to default values if you use the chip command. This will also
  create them as constants. Otherwise they behave exactly like normal variables.
  If you need to target a chip that is not in the list, you can set the limits yourself.
  For example:
  
def chip\name = "24F951";
def chip\size\config = 16;
def chip\size\data = 8192;
def chip\size\program = 4194304;
  
  It is not strictly necessary to set a name, it is only used for headings, etc. But it does make
  it a lot easier when you come back to the code later.
  The various variables need to be defined before they are needed. The compiler will only check
  this immediately before it needs the value, so if you get strange errors about chip\size\*,
  it is probably because it hasn't been defined in time.
  
  
   A variable can be in one of 3 major states. In macro and function code, it can be necessary to
   determine the state of an argument. def() and type() is used for this:
   
    | State | def() | type() | 
|---|
| Does not exist | false | Gives an error | 
| Exists, unassigned | true | "" | 
| Exists, assigned | true | String giving type | 
   When calling a macro or function with some arguments missing, the affected
   parameter variables exist, but are unassigned.
  
  
   Some operators work on more than scalars, and behave in various weird ways when applied to areas.
   This is described below, see also structures for other strange effects.
  
   - $area
   
- Returns the scalar value of the area or structure, which is the word offset.
   
- *area
   
- The mask of the area, which is a scalar containing a bit mask with 1's covering the area.
       This only works for bit areas.
   
- &area
   
- Bit offset of the area. This only works for bit areas.
   
- area+scalar
 scalar+area
- Returns another area, covering the same width as the original, but offset from it by
       width*scalar bits. For example,
       
        - D0.1`2 + 1 = D0.3`2
        
- D0.1`2 + 2 = D0.5`2
        
- D0.1`2 + 3 = D0.7`2 (not very useful, since you can't currently have
            bit areas covering more than 1 word).
       
 For word areas, this always works, and offsets by width*scalar words instead.
- area-area
   
- Works for areas of the same type, and the same kind (word or bit). In each case, a new area
       is returned, covering the space between the base offsets of the two areas. The widths are
       ignored, and the result is always the absolute value. For example:
       
        - D0.1 - D0.6 = D0.1`5
        
- D4 - D5 = D4`1
       
 If the result is a bit area covering more than one word, an error is returned.
- area < area
 area > area
 area <= area
 area >= area
 area != area
 area == area
 
- Allowed for areas of the same type. The result is a comparison of the base offsets if they
       are different, otherwise the widths. Word and bit areas can be compared, and will return
       results depending on the actual width. E.g. a word area of width 1 will be equal to a bit
       area covering the whole word (8 or 14 bits depending on type). This is necessary to return
       consistent results, so (a >= b) returns true if (a == b) and (a < b) is always the
       opposite of (a >= b) etc. etc.
   
- area[scalar]
   
- This is also an operator, it returns an indexed subset of the area, measured in the "natural
       size" (1 word or 1 bit).
   
   Initialising an area (with area or init) will register the values as the
   initial content of that area. This can be done with the config and data areas, and will cause
   the data to be included in the output file at the appropriate addresses.
  
   You can initialise an area to a string. With a word area, the characters
   are simply stored at increasing word offsets.
   If it is a bit area, every character will be stored at increasing area locations (increasing as
   if adding 1 to the area after every char).
   Example: area D3.0`4, foo = "12345";
   This will store 0x21 at offset 3, 0x43 at offset 4, and 0x5 in the low nibble of offset 5. This
   is because '1' (0x31) truncated to the width of the area (4 bits) is 0x01, so D3.0`4 becomes 0x01.
   The next area is D3.0`4 + 1 = D3.4`4, which becomes 0x02, giving 0x21 in the whole byte. And so on.
  
  Here are a few things that are nice to know when you're writing in this language.
  
Tip #1: This is not C
  The C-like syntax can easily make you slip into "C-mode" mentally.
  This should be avoided, since it is really quite different. For example, a perfectly normal
  thing like this:
n = 0;
while (n < 5) {
  print n++;
}
  ...will completely fail to do what you'd expect and instead become an infinite loop.
  The reason for this is important to know, since it affects a lot of constructs in this
  language.
  
Since this is an assembler, it makes several passes over the code to deal with forward
  references. Some statements are run on every pass (e.g. while), but others, like
  print and PIC instructions, are only executed on the last pass. This is necessary
  so they can use references to variables that don't yet exist, but will be created in a later
  pass.
  
But it also means that side effects should be avoided in these commands, since they will
  only happen at the last pass. That is why the above becomes an infinite loop - the
  n++ is not evaluated in the first pass, so the loop never ends.
  
The statements that execute on every pass are:
  alloc, area (except init data), code, def, enum, expr;, every,
  for, foreach, if, init (except init data), link, switch, while, & return
  (from function).
  All of these are safe to use side effects in. For the same reason, they can't use variables
  that are forward-referenced.
  The rest are usually only executed once, on the last pass. Of course, it's slightly more
  complicated than this - in certain circumstances they are executed on every pass too.
  If the interpreter is currently evaluating a function call (in any code pass), commands like
  print, error, & warning will be executed, macro invocations and every
  will be ignored, while PIC instructions will generate errors.
  This means that the above code could be changed to:
n = 0;
while (n < 5) {
  -echo(n++);
}
func echo(x)
{
  print x;
  return 0;
}
  ...and it stops being an infinite loop.
  There are several things to note here:
  
   - print is now run on every pass, so the list of numbers comes out about 10 times.
   
- The - in front of the function call is a way to avoid it being interpreted as a
       macro invocation.
   
- Functions must return a value.
  
The above is still useless, so here's the "correct" way of writing it:
n = 0;
while (n < 5) {
  print n;
  n++;
}
  Now n++ has become an expr; statement, so it is evaluated every
  time, and the loop terminates properly. print is only executed on the last pass, so
  you get only one list of numbers out.