Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
                 Crown Copyright (c) 1997
    
    This TenDRA(r) Computer Program is subject to Copyright
    owned by the United Kingdom Secretary of State for Defence
    acting through the Defence Evaluation and Research Agency
    (DERA).  It is made available to Recipients with a
    royalty-free licence for its use, reproduction, transfer
    to other parties and amendment for any purpose not excluding
    product development provided that any such use et cetera
    shall be deemed to be acceptance of the following conditions:-
    
        (1) Its Recipients shall ensure that this Notice is
        reproduced upon any copies or amended versions of it;
    
        (2) Any amended version of it shall be clearly marked to
        show both the nature of and the organisation responsible
        for the relevant amendment or amendments;
    
        (3) Its onward transfer from a recipient to another
        party shall be deemed to be that party's acceptance of
        these conditions;
    
        (4) DERA gives no warranty or assurance as to its
        quality or suitability for any purpose and DERA accepts
        no liability whatsoever in relation to any use to which
        it may be put.
*/


@use all
@special external
@special sortname
@special token
@special tokdec
@special tokdef
@special tagdec
@special tagdef
@special al_tagdef
@special diag_tagdef
@special token_defn
@special exp case
@special exp labelled
@special exp make_proc
@special exp sequence
@special nat make_nat
@special signed_nat make_signed_nat
@special string make_string
@special version make_version
/* AUTOMATICALLY GENERATED BY %ZX VERSION %ZV FROM TDF %VA.%VB */

#include "config.h"
#include "types.h"
#include "basic.h"
#include "binding.h"
#include "file.h"
#include "sort.h"
#include "tdf.h"
#include "tree.h"
#include "unit.h"
#include "utility.h"
@loop sort
@if sort.basic


/* DECODE A %ST */

long de_%SN
    PROTO_Z ()
{
@if sort.extends
    long n = fetch_extn ( %SB%1u ) ;
@else
    long n = fetch ( %SB%0u ) ;
@endif
@if sort.special
    if ( n < %u || n > %SM ) {
        out ( "<error>" ) ;
        input_error ( "Illegal %ST value, %%ld", n ) ;
        n = -1 ;
    }
@else
    switch ( n ) {
@loop sort.cons
        case %CE : {
@if cons.simple
@if cons.params
            format ( VERT_BRACKETS, "%CN", "%CX" ) ;
@else
            out ( "%CN" ) ;
@endif
@else
@if cons.cond
            format ( VERT_BRACKETS, "%CN", "%CX" ) ;
@else
@if cons.token
@if sort.name.foreign
            sortname sn = find_sortname ( '%SX' ) ;
            IGNORE de_token_aux ( sn, "%SN" ) ;
@else
            IGNORE de_token_aux ( sort_%20SN, "%SN" ) ;
@endif
@else
@if cons.edge
            long t = tdf_int () ;
@if sort.link
            out_object ( t, ( object * ) null, var_%SN ) ;
@else
            de_%CN ( t ) ;
@endif
@else
            /* Decode string "%CX" */
            de_%CN ( "%CN" ) ;
@endif
@endif
@endif
@endif
            break ;
        }
@end
        default : {
            out ( "<error>" ) ;
            input_error ( "Illegal %ST value, %%ld", n ) ;
            n = -1 ;
            break ;
        }
    }
@endif
    return ( n ) ;
}
@endif
@end


/*
    SKIP TEXT ENCLOSED IN [...]

    On input, s, points to the character '['.  The routine returns a
    pointer to the character following the corresponding ']'.
*/

static char *skip_sub
    PROTO_N ( ( s ) )
    PROTO_T ( char *s )
{
    char c = *( s++ ) ;
    if ( c == '[' ) {
        int n = 0 ;
        while ( c = *( s++ ), c != 0 ) {
            if ( c == '[' ) n++ ;
            if ( c == ']' ) {
                if ( n == 0 ) return ( s ) ;
                n-- ;
            }
        }
    }
    input_error ( "Illegal decoding string" ) ;
    return ( "" ) ;
}


/*
    DECODE A STRING OF DECODE CHARACTERS

    This routine takes a string of characters, reads it one character
    at a time, and, according to what it is, calls a particular TDF
    decoding routine (the character is vaguely mnemonic).  For example,
    decode ( "Sn*[x]" ) means, decode a SHAPE and a NAT, then read a
    TDF integer and decode that number of EXPs.
*/

void decode
    PROTO_N ( ( str ) )
    PROTO_T ( char *str )
{
    char c ;
    while ( c = *( str++ ), c != 0 ) {
        switch ( c ) {
            case '[' :
            case '{' :
            case '}' :
            case '&' : {
                /* Ignore these cases */
                break ;
            }
            case ']' : {
                /* Marks the end of a group */
                return ;
            }
            case 'i' : {
                /* Decode an integer */
                long n = tdf_int () ;
                out_int ( n ) ;
                break ;
            }
            case '$' : {
                /* Decode a string */
                de_tdfstring_format () ;
                break ;
            }
            case 'T' : {
                /* Decode a token */
                IGNORE de_token_aux ( sort_unknown, "token" ) ;
                break ;
            }
            case 'F' : {
                /* Decode an unknown foreign sort */
                input_error ( "Unknown foreign sort" ) ;
                break ;
            }
            case '*' : {
                /* The following text is repeated n times */
                long i, n ;
                check_list () ;
                n = tdf_int () ;
                if ( n == 0 ) {
                    out ( "empty" ) ;
                } else {
                    for ( i = 0 ; i < n ; i++ ) decode ( str + 1 ) ;
                }
                str = skip_sub ( str ) ;
                break ;
            }
            case '+' : {
                /* The following text is repeated n + 1 times */
                long i, n ;
                check_list () ;
                n = tdf_int () ;
                for ( i = 0 ; i <= n ; i++ ) decode ( str + 1 ) ;
                str = skip_sub ( str ) ;
                break ;
            }
            case '?' : {
                /* The following text is optional */
                if ( tdf_bool () ) {
                    decode ( str + 1 ) ;
                } else {
                    out ( "-" ) ;
                }
                str = skip_sub ( str ) ;
                break ;
            }
            case '@' : {
                /* The following text is a bitstream */
                long p = tdf_int () ;
                p += posn ( here ) ;
                decode ( str + 1 ) ;
                if ( p != posn ( here ) ) {
                    input_error ( "Bitstream length wrong" ) ;
                }
                str = skip_sub ( str ) ;
                break ;
            }
            case '|' : {
                /* Align input stream */
                byte_align () ;
                break ;
            }
@loop sort
@if sort.basic
@if !sort.special
            case '%SX' : IGNORE de_%SN () ; break ;
@endif
@endif
@end
            default : {
                input_error ( "Illegal decode letter, %%c", c ) ;
                break ;
            }
        }
    }
    return ;
}


/*
    FIND THE NAME AND DECODE LETTER ASSOCIATED WITH A SORT

    This routine returns a sortid structure corresponding to the sort
    number n.
*/

sortid find_sort
    PROTO_N ( ( n ) )
    PROTO_T ( sortname n )
{
    sortid s ;
    switch ( n ) {
@loop sort
@if sort.name.simple
@if !sort.special
        case sort_%20SN : {
            s.name = "%ST" ;
            s.decode = '%SX' ;
            break ;
        }
@endif
@endif
@end
        case sort_token : {
            s.name = "TOKEN" ;
            s.decode = 'T' ;
            break ;
        }
        case sort_foreign : {
            s.name = "FOREIGN" ;
            s.decode = 'F' ;
            break ;
        }
        default: {
            int m = n - extra_sorts ;
            if ( m >= 0 && m < no_foreign_sorts ) {
                s.name = foreign_sorts [m].name ;
                s.decode = foreign_sorts [m].decode ;
            } else {
                input_error ( "Illegal sort value, %%d", n ) ;
                s.name = "<error in SORT>" ;
                s.decode = 'F' ;
            }
            break ;
        }
    }
    s.res = n ;
    s.args = null ;
    return ( s ) ;
}


/*

    CONVERT A DECODE LETTER TO A SORT VALUE

    This routine given a decode letter c returns the corresponding sort
    number.
*/

sortname find_sortname
    PROTO_N ( ( c ) )
    PROTO_T ( int c )
{
    long i ;
    switch ( c ) {
@loop sort
@if sort.name.simple
@if !sort.special
        case '%SX' : return ( sort_%20SN ) ;
@endif
@endif
@end
        case 'T' : return ( sort_token ) ;
        case 'F' : return ( sort_foreign ) ;
    }
    for ( i = 0 ; i < no_foreign_sorts ; i++ ) {
        if ( c == foreign_sorts [i].decode ) {
            return ( ( sortname ) ( extra_sorts + i ) ) ;
        }
    }
    return ( sort_unknown ) ;
}


/*
    INITIALISE FOREIGN SORT NAMES

    This routine initialises the array of foreign sort names.
*/

void init_foreign_sorts
    PROTO_Z ()
{
@loop sort
@if sort.name.foreign
    add_foreign_sort ( "%ST", "%SCN", '%SX' ) ;
@endif
@end
    return ;
}


/*
    LINKAGE VARIABLE NUMBERS

    Usually "tag" and "token" etc. appear in the var_types array.  These
    variables indicate where (negative values mean not at all).
*/
%1u
@loop sort
@if sort.link
long var_%SN = -%u ;
@endif
@end


/*
    FIND A LINKAGE VARIABLE CODE

    This routine sets the nth element of the var_types array to the
    linkage variable indicated by the variable name s.
*/

char find_variable
    PROTO_N ( ( s, n ) )
    PROTO_T ( string s X long n )
{
@loop sort
@if sort.link
    if ( streq ( s, "%SL" ) ) {
        var_%SN = n ;
        return ( '%SX' ) ;
    }
@endif
@end
    return ( 'F' ) ;
}


/*
    FIND A EQUATION DECODING FUNCTION

    This routine returns the unit decoding function used to deal with
    units with equation name s.  It also assigns a unit description to
    pt and a usage flag to po.
*/

equation_func find_equation
    PROTO_N ( ( s, pt, po ) )
    PROTO_T ( string s X string *pt X int *po )
{
@loop sort
@if sort.unit
    if ( streq ( s, "%SU" ) ) {
        *pt = MSG_%SN ;
        *po = OPT_%SN ;
        return ( de_%SN ) ;
    }
@endif
@end
    if ( streq ( s, "tld" ) ) {
        *pt = MSG_tld_unit ;
        *po = OPT_tld_unit ;
        return ( de_tld_unit ) ;
    }
    if ( streq ( s, "tld2" ) ) {
        *pt = MSG_tld2_unit ;
        *po = OPT_tld2_unit ;
        return ( de_tld2_unit ) ;
    }
    return ( NULL ) ;
}