Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5/src/utilities/calculus/syntax.act – Rev 2

Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
%prefixes%
2
 
3
terminal = lex_ ;
4
 
5
 
6
%maps%
7
 
8
 
9
/*
10
    ENTRY POINT
11
 
12
    The main entry point for the calculus is mapped onto a function
13
    named read_calculus.
14
*/
15
 
16
unit -> read_calculus ;
17
extra-unit -> extra_calculus ;
18
 
19
 
20
/*
21
    TYPE MAPPINGS
22
 
23
    These maps give the relationship between the types used in the syntax
24
    and in the C implementation.
25
*/
26
 
27
CLASS-ID -> CLASS_ID_P ;
28
FLAG -> int ;
29
IDENTIFIER -> string ;
30
NUMBER -> number ;
31
TYPE -> TYPE_P ;
32
STRING -> string ;
33
 
34
ARGUMENT -> ARGUMENT_P ;
35
COMPONENT -> COMPONENT_P ;
36
ECONST -> ECONST_P ;
37
ENUM -> ENUM_P ;
38
FIELD -> FIELD_P ;
39
IDENTITY -> IDENTITY_P ;
40
MAP -> MAP_P ;
41
PRIMITIVE -> PRIMITIVE_P ;
42
STRUCTURE -> STRUCTURE_P ;
43
UNION -> UNION_P ;
44
 
45
ARGUMENT-LIST -> ARGUMENT_P_LIST ;
46
COMPONENT-LIST -> COMPONENT_P_LIST ;
47
ECONST-LIST -> ECONST_P_LIST ;
48
ENUM-LIST -> ENUM_P_LIST ;
49
FIELD-LIST -> FIELD_P_LIST ;
50
IDENTITY-LIST -> IDENTITY_P_LIST ;
51
MAP-LIST -> MAP_P_LIST ;
52
PRIMITIVE-LIST -> PRIMITIVE_P_LIST ;
53
STRUCTURE-LIST -> STRUCTURE_P_LIST ;
54
UNION-LIST -> UNION_P_LIST ;
55
 
56
 
57
%header% @{
58
/*
59
    		 Crown Copyright (c) 1997
60
 
61
    This TenDRA(r) Computer Program is subject to Copyright
62
    owned by the United Kingdom Secretary of State for Defence
63
    acting through the Defence Evaluation and Research Agency
64
    (DERA).  It is made available to Recipients with a
65
    royalty-free licence for its use, reproduction, transfer
66
    to other parties and amendment for any purpose not excluding
67
    product development provided that any such use et cetera
68
    shall be deemed to be acceptance of the following conditions:-
69
 
70
        (1) Its Recipients shall ensure that this Notice is
71
        reproduced upon any copies or amended versions of it;
72
 
73
        (2) Any amended version of it shall be clearly marked to
74
        show both the nature of and the organisation responsible
75
        for the relevant amendment or amendments;
76
 
77
        (3) Its onward transfer from a recipient to another
78
        party shall be deemed to be that party's acceptance of
79
        these conditions;
80
 
81
        (4) DERA gives no warranty or assurance as to its
82
        quality or suitability for any purpose and DERA accepts
83
        no liability whatsoever in relation to any use to which
84
        it may be put.
85
*/
86
 
87
 
88
#include "config.h"
89
#include "calculus.h"
90
#include "common.h"
91
#include "error.h"
92
#include "extra.h"
93
#include "lex.h"
94
#include "syntax.h"
95
#include "type_ops.h"
96
#include "xalloc.h"
97
 
98
 
99
/*
100
    PARSER TYPES
101
 
102
    These types give the implementations of the various types used
103
    in the syntax.
104
*/
105
 
106
typedef LIST ( ARGUMENT_P ) ARGUMENT_P_LIST ;
107
typedef LIST ( COMPONENT_P ) COMPONENT_P_LIST ;
108
typedef LIST ( ECONST_P ) ECONST_P_LIST ;
109
typedef LIST ( ENUM_P ) ENUM_P_LIST ;
110
typedef LIST ( FIELD_P ) FIELD_P_LIST ;
111
typedef LIST ( IDENTITY_P ) IDENTITY_P_LIST ;
112
typedef LIST ( MAP_P ) MAP_P_LIST ;
113
typedef LIST ( PRIMITIVE_P ) PRIMITIVE_P_LIST ;
114
typedef LIST ( STRUCTURE_P ) STRUCTURE_P_LIST ;
115
typedef LIST ( UNION_P ) UNION_P_LIST ;
116
 
117
 
118
/*
119
    COUNTER VARIABLES
120
 
121
    The variable enum_value is used to determine the value of enumerators.
122
    enum_max is used to record the maximum value of enum_value.  Both are
123
    reset to zero at the end of each enumeration type.  no_fields is used
124
    to count the number of field in each union.  It is reset to zero at
125
    the end of each union type.
126
*/
127
 
128
static number enum_value = 0 ;
129
static number enum_max = 0 ;
130
static int no_fields = 0 ;
131
static LIST ( ECONST_P ) enum_list = NULL_list ( ECONST_P ) ;
132
 
133
 
134
/*
135
    COMPILATION MODE
136
 
137
    We allow unreached code in the automatically generated sections.
138
*/
139
 
140
#if FS_TENDRA
141
#pragma TenDRA begin
142
#ifndef OLD_PRODUCER
143
#pragma TenDRA unreachable code allow
144
#endif
145
#endif
146
 
147
 
148
@}, @{
149
/*
150
    		 Crown Copyright (c) 1997
151
 
152
    This TenDRA(r) Computer Program is subject to Copyright
153
    owned by the United Kingdom Secretary of State for Defence
154
    acting through the Defence Evaluation and Research Agency
155
    (DERA).  It is made available to Recipients with a
156
    royalty-free licence for its use, reproduction, transfer
157
    to other parties and amendment for any purpose not excluding
158
    product development provided that any such use et cetera
159
    shall be deemed to be acceptance of the following conditions:-
160
 
161
        (1) Its Recipients shall ensure that this Notice is
162
        reproduced upon any copies or amended versions of it;
163
 
164
        (2) Any amended version of it shall be clearly marked to
165
        show both the nature of and the organisation responsible
166
        for the relevant amendment or amendments;
167
 
168
        (3) Its onward transfer from a recipient to another
169
        party shall be deemed to be that party's acceptance of
170
        these conditions;
171
 
172
        (4) DERA gives no warranty or assurance as to its
173
        quality or suitability for any purpose and DERA accepts
174
        no liability whatsoever in relation to any use to which
175
        it may be put.
176
*/
177
 
178
 
179
#ifndef SYNTAX_INCLUDED
180
#define SYNTAX_INCLUDED
181
 
182
@} ;
183
 
184
 
185
%terminals%
186
 
187
 
188
/*
189
    IDENTIFIER TERMINAL
190
 
191
    This action gives the terminal for identifiers.  The identifier text
192
    is built up in token_buff by the lexical routines.
193
*/
194
 
195
identifier : () -> ( i : IDENTIFIER ) = @{
196
    @i = xstrcpy ( token_buff ) ;
197
@} ;
198
 
199
 
200
/*
201
    NUMBER TERMINAL
202
 
203
    This action gives the terminal for numbers.  The number value is built
204
    up in token_value by the lexical routines.
205
*/
206
 
207
number : () -> ( n : NUMBER ) = @{
208
    @n = token_value ;
209
@} ;
210
 
211
 
212
/*
213
    STRING TERMINAL
214
 
215
    This action gives the terminal for strings.  The string text is built
216
    up in token_buff by the lexical routines.
217
*/
218
 
219
string : () -> ( s : STRING ) = @{
220
    @s = xstrcpy ( token_buff ) ;
221
@} ;
222
 
223
 
224
%actions%
225
 
226
 
227
/*
228
    FLAG VALUES
229
 
230
    These actions give the various flag values.
231
*/
232
 
233
<zero> : () -> ( f : FLAG ) =	@{ @f = 0 ; @} ;
234
<one> : () -> ( f : FLAG ) =	@{ @f = 1 ; @} ;
235
<two> : () -> ( f : FLAG ) =	@{ @f = 2 ; @} ;
236
<three> : () -> ( f : FLAG ) =	@{ @f = 3 ; @} ;
237
 
238
 
239
/*
240
    NULL STRING
241
 
242
    This action gives the null string.
243
*/
244
 
245
<null-string> : () -> ( s : STRING ) = @{
246
    @s = NULL ;
247
@} ;
248
 
249
 
250
/*
251
    SYNTAX ERROR
252
 
253
    This action is used to print a syntax error.
254
*/
255
 
256
<syntax-error> : () -> () = @{
257
    error ( ERROR_SERIOUS, "Syntax error" ) ;
258
@} ;
259
 
260
 
261
/*
262
    DEFAULT CLASS IDENTIFIER NAME
263
 
264
    The second name component of a class identifier is optional.  When
265
    it is not present this action is used to derive a default second name
266
    from the first name.
267
*/
268
 
269
<default-name> : ( n : IDENTIFIER ) -> ( i : IDENTIFIER ) = @{
270
    @i = @n ;
271
@} ;
272
 
273
 
274
/*
275
    CLASS IDENTIFIER
276
 
277
    This action creates a class identifier from its various components.
278
*/
279
 
280
<make-class-id> : ( n1 : IDENTIFIER, n2 : IDENTIFIER, f : FLAG )
281
		-> ( c : CLASS-ID ) = @{
282
    @c = MAKE_ptr ( SIZE_cid ) ;
283
    MAKE_cid ( @n1, @n2, @f, ( string ) crt_file_name, crt_line_no, @c ) ;
284
@} ;
285
 
286
 
287
/*
288
    NULL IDENTIFIER
289
 
290
    This action gives the null identifier.
291
*/
292
 
293
<null-identifier> : () -> ( i : IDENTIFIER ) = @{
294
    @i = NULL ;
295
@} ;
296
 
297
 
298
/*
299
    TYPE LOOK-UP
300
 
301
    This action looks up a named type.
302
*/
303
 
304
<find-type> : ( i : IDENTIFIER ) -> ( t : TYPE ) = @{
305
    @t = find_type ( algebra, @i ) ;
306
@} ;
307
 
308
 
309
/*
310
    POINTER TYPE
311
 
312
    This action creates the pointer type, PTR s.
313
*/
314
 
315
<ptr-type> : ( s : TYPE ) -> ( t : TYPE ) = @{
316
    @t = compound_type ( type_ptr_tag, @s, 0 ) ;
317
@} ;
318
 
319
 
320
/*
321
    LIST TYPE
322
 
323
    This action creates the list type, LIST s.
324
*/
325
 
326
<list-type> : ( s : TYPE ) -> ( t : TYPE ) = @{
327
    @t = compound_type ( type_list_tag, @s, 0 ) ;
328
@} ;
329
 
330
 
331
/*
332
    STACK TYPE
333
 
334
    This action creates the stack type, STACK s.
335
*/
336
 
337
<stack-type> : ( s : TYPE ) -> ( t : TYPE ) = @{
338
    @t = compound_type ( type_stack_tag, @s, 0 ) ;
339
@} ;
340
 
341
 
342
/*
343
    VECTOR TYPE
344
 
345
    This action creates the vector type, VEC s.
346
*/
347
 
348
<vec-type> : ( s : TYPE ) -> ( t : TYPE ) = @{
349
    @t = compound_type ( type_vec_tag, @s, 0 ) ;
350
@} ;
351
 
352
 
353
/*
354
    VECTOR-POINTER TYPE
355
 
356
    This action creates the vector-pointer type, VEC_PTR s.
357
*/
358
 
359
<vec-ptr-type> : ( s : TYPE ) -> ( t : TYPE ) = @{
360
    @t = compound_type ( type_vec_ptr_tag, @s, 0 ) ;
361
@} ;
362
 
363
 
364
/*
365
    QUOTED TYPE
366
 
367
    This action creates a type corresponding to the quoted C type, s.
368
*/
369
 
370
<quoted-type> : ( s : STRING ) -> ( t : TYPE ) = @{
371
    TYPE r ;
372
    @t = MAKE_ptr ( SIZE_type ) ;
373
    MAKE_type_quote ( 0, @s, r ) ;
374
    COPY_type ( @t, r ) ;
375
@} ;
376
 
377
 
378
/*
379
    TYPE ERROR
380
 
381
    This routine prints an error.
382
*/
383
 
384
<error-type> : () -> ( t : TYPE ) = @{
385
    error ( ERROR_SERIOUS, "Type expected" ) ;
386
    @t = find_type ( algebra, "ERROR!" ) ;
387
@} ;
388
 
389
 
390
/*
391
    ENUMERATOR EXPRESSSIONS
392
 
393
    These actions are used in the enumerator evaluation routines.
394
*/
395
 
396
<exp-crt> : () -> ( n : NUMBER ) = @{
397
    @n = enum_value - 1 ;
398
@} ;
399
 
400
<exp-id> : ( e : IDENTIFIER ) -> ( n : NUMBER ) = @{
401
    number n = 0 ;
402
    LIST ( ECONST_P ) p = enum_list ;
403
    while ( !IS_NULL_list ( p ) ) {
404
	ECONST_P q = DEREF_ptr ( HEAD_list ( p ) ) ;
405
	string s = DEREF_string ( ec_name ( q ) ) ;
406
	if ( streq ( s, @e ) ) {
407
	    n = DEREF_number ( ec_value ( q ) ) ;
408
	    break ;
409
	}
410
	p = TAIL_list ( p ) ;
411
    }
412
    if ( IS_NULL_list ( p ) ) {
413
	error ( ERROR_SERIOUS, "Unknown enumerator '%s'", @e ) ;
414
    }
415
    @n = n ;
416
@} ;
417
 
418
<exp-neg> : ( a : NUMBER ) -> ( n : NUMBER ) = @{
419
    @n = -@a ;
420
@} ;
421
 
422
<exp-compl> : ( a : NUMBER ) -> ( n : NUMBER ) = @{
423
    @n = ~@a ;
424
@} ;
425
 
426
<exp-mult> : ( a : NUMBER, b : NUMBER ) -> ( n : NUMBER ) = @{
427
    @n = @a * @b ;
428
@} ;
429
 
430
<exp-div> : ( a : NUMBER, b : NUMBER ) -> ( n : NUMBER ) = @{
431
    if ( @b == 0 ) {
432
	error ( ERROR_SERIOUS, "Division by zero" ) ;
433
	@n = 0 ;
434
    } else {
435
	@n = @a / @b ;
436
    }
437
@} ;
438
 
439
<exp-rem> : ( a : NUMBER, b : NUMBER ) -> ( n : NUMBER ) = @{
440
    if ( @b == 0 ) {
441
	error ( ERROR_SERIOUS, "Division by zero" ) ;
442
	@n = 0 ;
443
    } else {
444
	@n = @a % @b ;
445
    }
446
@} ;
447
 
448
<exp-plus> : ( a : NUMBER, b : NUMBER ) -> ( n : NUMBER ) = @{
449
    @n = @a + @b ;
450
@} ;
451
 
452
<exp-minus> : ( a : NUMBER, b : NUMBER ) -> ( n : NUMBER ) = @{
453
    @n = @a - @b ;
454
@} ;
455
 
456
<exp-lshift> : ( a : NUMBER, b : NUMBER ) -> ( n : NUMBER ) = @{
457
    @n = @a << @b ;
458
@} ;
459
 
460
<exp-rshift> : ( a : NUMBER, b : NUMBER ) -> ( n : NUMBER ) = @{
461
    @n = @a >> @b ;
462
@} ;
463
 
464
<exp-and> : ( a : NUMBER, b : NUMBER ) -> ( n : NUMBER ) = @{
465
    @n = @a & @b ;
466
@} ;
467
 
468
<exp-xor> : ( a : NUMBER, b : NUMBER ) -> ( n : NUMBER ) = @{
469
    @n = @a ^ @b ;
470
@} ;
471
 
472
<exp-or> : ( a : NUMBER, b : NUMBER ) -> ( n : NUMBER ) = @{
473
    @n = @a | @b ;
474
@} ;
475
 
476
 
477
/*
478
    EMPTY ENUMERATION CONSTANT LIST
479
 
480
    This action creates an empty list of enumeration constants.
481
*/
482
 
483
<null-econst> : () -> ( p : ECONST-LIST ) = @{
484
    @p = NULL_list ( ECONST_P ) ;
485
@} ;
486
 
487
 
488
/*
489
    CREATE ENUMERATION CONSTANT
490
 
491
    This action creates an enumeration constant from its various components.
492
*/
493
 
494
<make-econst> : ( s : IDENTIFIER ) -> ( p : ECONST ) = @{
495
    number v = enum_value++ ;
496
    if ( v > enum_max ) enum_max = v ;
497
    @p = MAKE_ptr ( SIZE_ec ) ;
498
    MAKE_ec ( @s, v, @p ) ;
499
    CONS_ptr ( @p, enum_list, enum_list ) ;
500
@} ;
501
 
502
 
503
/*
504
    ADD ENUMERATION CONSTANT TO LIST
505
 
506
    This action adds the enumeration constant q to the start of the
507
    enumeration constant list r.
508
*/
509
 
510
<join-econst> : ( q : ECONST, r : ECONST-LIST ) -> ( p : ECONST-LIST ) = @{
511
    CONS_ptr ( @q, @r, @p ) ;
512
@} ;
513
 
514
 
515
/*
516
    SET ENUMERATOR VALUE
517
 
518
    This actions sets the current enumerator value.
519
*/
520
 
521
<set-econst> : ( n : NUMBER ) -> () =	@{
522
    enum_value = @n ;
523
@} ;
524
 
525
 
526
/*
527
    EMPTY PRIMITIVE LIST
528
 
529
    This action creates an empty list of primitives.
530
*/
531
 
532
<null-primitive> : () -> ( p : PRIMITIVE-LIST ) = @{
533
    @p = NULL_list ( PRIMITIVE_P ) ;
534
@} ;
535
 
536
 
537
/*
538
    CREATE PRIMITIVE
539
 
540
    This action creates a primitive from its various components.
541
*/
542
 
543
<make-primitive> : ( c : CLASS-ID, s : STRING ) -> ( p : PRIMITIVE ) = @{
544
    TYPE r ;
545
    TYPE_P t ;
546
    @p = MAKE_ptr ( SIZE_prim ) ;
547
    MAKE_prim ( @c, @s, @p ) ;
548
    t = MAKE_ptr ( SIZE_type ) ;
549
    MAKE_type_primitive ( 0, @p, r ) ;
550
    COPY_type ( t, r ) ;
551
    IGNORE register_type ( t ) ;
552
@} ;
553
 
554
 
555
/*
556
    ADD PRIMITIVE TO LIST
557
 
558
    This action adds the primitive q to the start of the primitive list r.
559
*/
560
 
561
<join-primitive> : ( q : PRIMITIVE, r : PRIMITIVE-LIST )
562
		 -> ( p : PRIMITIVE-LIST ) = @{
563
    CONS_ptr ( @q, @r, @p ) ;
564
@} ;
565
 
566
 
567
/*
568
    EMPTY IDENTITY LIST
569
 
570
    This action creates an empty list of identities.
571
*/
572
 
573
<null-identity> : () -> ( p : IDENTITY-LIST ) = @{
574
    @p = NULL_list ( IDENTITY_P ) ;
575
@} ;
576
 
577
 
578
/*
579
    CREATE IDENTITY
580
 
581
    This action creates an identity from its various components.
582
*/
583
 
584
<make-identity> : ( c : CLASS-ID, t : TYPE ) -> ( p : IDENTITY ) = @{
585
    TYPE r ;
586
    TYPE_P t ;
587
    @p = MAKE_ptr ( SIZE_ident ) ;
588
    MAKE_ident ( @c, @t, @p ) ;
589
    t = MAKE_ptr ( SIZE_type ) ;
590
    MAKE_type_ident ( 0, @p, r ) ;
591
    COPY_type ( t, r ) ;
592
    IGNORE register_type ( t ) ;
593
@} ;
594
 
595
 
596
/*
597
    ADD IDENTITY TO LIST
598
 
599
    This action adds the identity q to the start of the identity list r.
600
*/
601
 
602
<join-identity> : ( q : IDENTITY, r : IDENTITY-LIST )
603
		-> ( p : IDENTITY-LIST ) = @{
604
    CONS_ptr ( @q, @r, @p ) ;
605
@} ;
606
 
607
 
608
/*
609
    EMPTY ENUMERATION LIST
610
 
611
    This action creates an empty list of enumerations.
612
*/
613
 
614
<null-enum> : () -> ( p : ENUM-LIST ) = @{
615
    @p = NULL_list ( ENUM_P ) ;
616
@} ;
617
 
618
 
619
/*
620
    LOOK UP ENUMERATION
621
 
622
    This action is used for the inheritance of enumeration types.  It
623
    returns the list of enumerators associated with a base identifier.
624
*/
625
 
626
<get-enum> : ( j : IDENTIFIER ) -> ( p : ECONST-LIST ) = @{
627
    string nm = @j ;
628
    TYPE r = DEREF_type ( find_type ( algebra, nm ) ) ;
629
    if ( IS_type_enumeration ( r ) ) {
630
	ENUM_P en = DEREF_ptr ( type_enumeration_en ( r ) ) ;
631
	@p = DEREF_list ( en_consts ( en ) ) ;
632
	enum_value = DEREF_number ( en_order ( en ) ) ;
633
	enum_max = enum_value ;
634
    } else {
635
	error ( ERROR_SERIOUS, "Can't inherit from %s", nm ) ;
636
	@p = NULL_list ( ECONST_P ) ;
637
    }
638
@} ;
639
 
640
 
641
/*
642
    CREATE ENUMERATION
643
 
644
    This action creates an enumeration from its various components.
645
*/
646
 
647
<make-enum> : ( c : CLASS-ID, l : FLAG, r : ECONST-LIST, s : ECONST-LIST )
648
	    -> ( p : ENUM ) = @{
649
    TYPE r ;
650
    TYPE_P t ;
651
    @s = ADD_list ( @r, @s, SIZE_ptr ( ECONST ) ) ;
652
    @p = MAKE_ptr ( SIZE_en ) ;
653
    MAKE_en ( @c, @s, enum_max + 1, @l, @p ) ;
654
    enum_value = 0 ;
655
    enum_max = 0 ;
656
    DESTROY_list ( enum_list, SIZE_ptr ( ECONST ) ) ;
657
    enum_list = NULL_list ( ECONST_P ) ;
658
    t = MAKE_ptr ( SIZE_type ) ;
659
    MAKE_type_enumeration ( 0, @p, r ) ;
660
    COPY_type ( t, r ) ;
661
    IGNORE register_type ( t ) ;
662
@} ;
663
 
664
 
665
/*
666
    ADD ENUMERATION TO LIST
667
 
668
    This action adds the enumeration q to the start of the enumeration
669
    list r.
670
*/
671
 
672
<join-enum> : ( q : ENUM, r : ENUM-LIST ) -> ( p : ENUM-LIST ) = @{
673
    CONS_ptr ( @q, @r, @p ) ;
674
@} ;
675
 
676
 
677
/*
678
    EMPTY COMPONENT LIST
679
 
680
    This action creates an empty list of components.
681
*/
682
 
683
<null-component> : () -> ( p : COMPONENT-LIST ) = @{
684
    @p = NULL_list ( COMPONENT_P ) ;
685
@} ;
686
 
687
 
688
/*
689
    CREATE COMPONENT
690
 
691
    This action creates a structure component from its various components.
692
*/
693
 
694
<make-component> : ( i : IDENTIFIER, t : TYPE, v : STRING )
695
		 -> ( p : COMPONENT ) = @{
696
    @p = MAKE_ptr ( SIZE_cmp ) ;
697
    MAKE_cmp ( @i, @t, @v, @p ) ;
698
@} ;
699
 
700
 
701
/*
702
    ADD COMPONENT TO LIST
703
 
704
    This action adds the component q to the start of the component list r.
705
*/
706
 
707
<join-component> : ( q : COMPONENT, r : COMPONENT-LIST )
708
		 -> ( p : COMPONENT-LIST ) = @{
709
    CONS_ptr ( @q, @r, @p ) ;
710
@} ;
711
 
712
 
713
/*
714
    LINK COMPONENT LISTS
715
 
716
    This actions combines two component lists into a single list.
717
*/
718
 
719
<link-component> : ( q : COMPONENT-LIST, r : COMPONENT-LIST )
720
		 -> ( p : COMPONENT-LIST ) = @{
721
    @p = APPEND_list ( @q, @r ) ;
722
@} ;
723
 
724
 
725
/*
726
    EMPTY STRUCTURE LIST
727
 
728
    This action creates an empty list of structures.
729
*/
730
 
731
<null-structure> : () -> ( p : STRUCTURE-LIST ) = @{
732
    @p = NULL_list ( STRUCTURE_P ) ;
733
@} ;
734
 
735
 
736
/*
737
    CREATE STRUCTURE
738
 
739
    This action creates a structure from its various components.
740
*/
741
 
742
<make-structure> : ( c : CLASS-ID, j : IDENTIFIER, s : COMPONENT-LIST )
743
		 -> ( p : STRUCTURE ) = @{
744
    TYPE r ;
745
    TYPE_P t ;
746
    string nm = @j ;
747
    STRUCTURE_P str = NULL_ptr ( STRUCTURE ) ;
748
    if ( nm ) {
749
	r = DEREF_type ( find_type ( algebra, nm ) ) ;
750
	if ( IS_type_structure ( r ) ) {
751
	    str = DEREF_ptr ( type_structure_struc ( r ) ) ;
752
	    @s = ADD_list ( DEREF_list ( str_defn ( str ) ), @s,
753
			    SIZE_ptr ( COMPONENT ) ) ;
754
	} else {
755
	    error ( ERROR_SERIOUS, "Can't inherit from %s", nm ) ;
756
	}
757
    }
758
    @p = MAKE_ptr ( SIZE_str ) ;
759
    MAKE_str ( @c, str, @s, 0, @p ) ;
760
    t = MAKE_ptr ( SIZE_type ) ;
761
    MAKE_type_structure ( 0, @p, r ) ;
762
    COPY_type ( t, r ) ;
763
    IGNORE register_type ( t ) ;
764
@} ;
765
 
766
 
767
/*
768
    ADD STRUCTURE TO LIST
769
 
770
    This action adds the structure q to the start of the structure list r.
771
*/
772
 
773
<join-structure> : ( q : STRUCTURE, r : STRUCTURE-LIST )
774
		 -> ( p : STRUCTURE-LIST ) = @{
775
    CONS_ptr ( @q, @r, @p ) ;
776
@} ;
777
 
778
 
779
/*
780
    EMPTY FIELD LIST
781
 
782
    This action creates an empty list of fields.
783
*/
784
 
785
<null-field> : () -> ( p : FIELD-LIST ) = @{
786
    @p = NULL_list ( FIELD_P ) ;
787
@} ;
788
 
789
 
790
/*
791
    CREATE FIELD
792
 
793
    This action creates a union field from its various components.
794
*/
795
 
796
<make-field> : ( i : IDENTIFIER, s : COMPONENT-LIST, f : FLAG )
797
	     -> ( p : FIELD ) = @{
798
    @p = MAKE_ptr ( SIZE_fld ) ;
799
    MAKE_fld ( @i, 0, @f, 0, NULL_ptr ( FIELD ),  @s, @p ) ;
800
    no_fields++ ;
801
@} ;
802
 
803
 
804
/*
805
    ADD FIELD TO LIST
806
 
807
    This action adds the field q to the start of the field list r.
808
*/
809
 
810
<join-field> : ( q : FIELD, r : FIELD-LIST ) -> ( p : FIELD-LIST ) = @{
811
    CONS_ptr ( @q, @r, @p ) ;
812
@} ;
813
 
814
 
815
/*
816
    LINK FIELD LISTS
817
 
818
    This actions combines two field lists into a single list.
819
*/
820
 
821
<link-field> : ( q : FIELD-LIST, r : FIELD-LIST ) -> ( p : FIELD-LIST ) = @{
822
    @p = APPEND_list ( @q, @r ) ;
823
@} ;
824
 
825
 
826
/*
827
    SET FIELD COMPONENTS
828
 
829
    This action sets the definition of each of the fields in f to c.
830
*/
831
 
832
<set-field-cmp> : ( f : FIELD-LIST, j : IDENTIFIER, c : COMPONENT-LIST )
833
		-> () = @{
834
    int n = 0 ;
835
    FIELD_P_LIST p = @f ;
836
    FIELD_P b = NULL_ptr ( FIELD ) ;
837
    if ( @j ) {
838
	b = MAKE_ptr ( SIZE_fld ) ;
839
	MAKE_fld ( @j, 0, 0, 0, NULL_ptr ( FIELD ),
840
		   NULL_list ( COMPONENT_P ), b ) ;
841
    }
842
    while ( !IS_NULL_list ( p ) ) {
843
	FIELD_P q = DEREF_ptr ( HEAD_list ( p ) ) ;
844
	COPY_ptr ( fld_base ( q ), b ) ;
845
	COPY_list ( fld_defn ( q ), @c ) ;
846
	p = TAIL_list ( p ) ;
847
	n++ ;
848
    }
849
    if ( n >= 2 ) {
850
	FIELD_P q = DEREF_ptr ( HEAD_list ( @f ) ) ;
851
	COPY_int ( fld_set ( q ), n ) ;
852
    }
853
@} ;
854
 
855
 
856
/*
857
    EMPTY ARGUMENT LIST
858
 
859
    This action creates an empty list of arguments.
860
*/
861
 
862
<null-argument> : () -> ( p : ARGUMENT-LIST ) = @{
863
    @p = NULL_list ( ARGUMENT_P ) ;
864
@} ;
865
 
866
 
867
/*
868
    CREATE ARGUMENT
869
 
870
    This action creates a union map argument from its various components.
871
*/
872
 
873
<make-argument> : ( i : IDENTIFIER, t : TYPE ) -> ( p : ARGUMENT ) = @{
874
    @p = MAKE_ptr ( SIZE_arg ) ;
875
    MAKE_arg ( @i, @t, @p ) ;
876
@} ;
877
 
878
 
879
/*
880
    ADD ARGUMENT TO LIST
881
 
882
    This action adds the argument q to the start of the argument list r.
883
*/
884
 
885
<join-argument> : ( q : ARGUMENT, r : ARGUMENT-LIST )
886
		-> ( p : ARGUMENT-LIST ) = @{
887
    CONS_ptr ( @q, @r, @p ) ;
888
@} ;
889
 
890
 
891
/*
892
    LINK ARGUMENT LISTS
893
 
894
    This actions combines two argument lists into a single list.
895
*/
896
 
897
<link-argument> : ( q : ARGUMENT-LIST, r : ARGUMENT-LIST )
898
		-> ( p : ARGUMENT-LIST ) = @{
899
    @p = APPEND_list ( @q, @r ) ;
900
@} ;
901
 
902
 
903
/*
904
    EMPTY MAP LIST
905
 
906
    This action creates an empty list of maps.
907
*/
908
 
909
<null-map> : () -> ( p : MAP-LIST ) = @{
910
    @p = NULL_list ( MAP_P ) ;
911
@} ;
912
 
913
 
914
/*
915
    CREATE MAP
916
 
917
    This action creates a union map from its various components.
918
*/
919
 
920
<make-map> : ( i : IDENTIFIER, t : TYPE, a : ARGUMENT-LIST, f : FLAG )
921
	   -> ( p : MAP ) = @{
922
    @p = MAKE_ptr ( SIZE_map ) ;
923
    MAKE_map ( @i, @f, @t, @a, @p ) ;
924
@} ;
925
 
926
 
927
/*
928
    ADD MAP TO LIST
929
 
930
    This action adds the map q to the start of the map list r.
931
*/
932
 
933
<join-map> : ( q : MAP, r : MAP-LIST ) -> ( p : MAP-LIST ) = @{
934
    CONS_ptr ( @q, @r, @p ) ;
935
@} ;
936
 
937
 
938
/*
939
    EMPTY UNION LIST
940
 
941
    This action creates an empty list of unions.
942
*/
943
 
944
<null-union> : () -> ( p : UNION-LIST ) = @{
945
    @p = NULL_list ( UNION_P ) ;
946
@} ;
947
 
948
 
949
/*
950
    CREATE UNION
951
 
952
    This action creates a union from its various components.
953
*/
954
 
955
<make-union> : ( c : CLASS-ID, j : IDENTIFIER, s : COMPONENT-LIST,
956
		 f : FIELD-LIST, m : MAP-LIST ) -> ( p : UNION ) = @{
957
    TYPE r ;
958
    TYPE_P t ;
959
    int tag = 0 ;
960
    string nm = @j ;
961
    FIELD_P_LIST p = @f ;
962
    UNION_P un = NULL_ptr ( UNION ) ;
963
 
964
    /* Deal with overall inheritance */
965
    if ( nm ) {
966
	r = DEREF_type ( find_type ( algebra, nm ) ) ;
967
	if ( IS_type_onion ( r ) ) {
968
	    un = DEREF_ptr ( type_onion_un ( r ) ) ;
969
	    @s = ADD_list ( DEREF_list ( un_s_defn ( un ) ), @s,
970
			    SIZE_ptr ( COMPONENT ) ) ;
971
	    @f = ADD_list ( DEREF_list ( un_u_defn ( un ) ), p,
972
			    SIZE_ptr ( FIELD ) ) ;
973
	    @m = ADD_list ( DEREF_list ( un_map ( un ) ), @m,
974
			    SIZE_ptr ( MAP ) ) ;
975
	    tag = DEREF_int ( un_no_fields ( un ) ) ;
976
	    no_fields += tag ;
977
	} else {
978
	    error ( ERROR_SERIOUS, "Can't inherit from %s", nm ) ;
979
	}
980
    }
981
 
982
    /* Deal with inheritance of fields and field tags */
983
    while ( !IS_NULL_list ( p ) ) {
984
	FIELD_P q = DEREF_ptr ( HEAD_list ( p ) ) ;
985
	FIELD_P b = DEREF_ptr ( fld_base ( q ) ) ;
986
	if ( !IS_NULL_ptr ( b ) ) {
987
	    int ok = 0 ;
988
	    FIELD_P_LIST pp = @f ;
989
	    string n = DEREF_string ( fld_name ( b ) ) ;
990
	    while ( !IS_NULL_list ( pp ) ) {
991
		FIELD_P qq = DEREF_ptr ( HEAD_list ( pp ) ) ;
992
		string nn = DEREF_string ( fld_name ( qq ) ) ;
993
		if ( streq ( n, nn ) ) {
994
		    COMPONENT_P_LIST cc = DEREF_list ( fld_defn ( qq ) ) ;
995
		    COMPONENT_P_LIST c = DEREF_list ( fld_defn ( q ) ) ;
996
		    c = ADD_list ( cc, c, SIZE_ptr ( COMPONENT ) ) ;
997
		    COPY_list ( fld_defn ( q ), c ) ;
998
		    COPY_ptr ( fld_base ( q ), qq ) ;
999
		    ok = 1 ;
1000
		    break ;
1001
		}
1002
		pp = TAIL_list ( pp ) ;
1003
	    }
1004
	    if ( !ok ) error ( ERROR_SERIOUS, "Can't find field %s", n ) ;
1005
	}
1006
	COPY_int ( fld_tag ( q ), tag++ ) ;
1007
	p = TAIL_list ( p ) ;
1008
    }
1009
 
1010
    /* Construct output */
1011
    @p = MAKE_ptr ( SIZE_un ) ;
1012
    MAKE_un ( @c, un, @s, @f, @m, no_fields, @p ) ;
1013
    no_fields = 0 ;
1014
    t = MAKE_ptr ( SIZE_type ) ;
1015
    MAKE_type_onion ( 0, @p, r ) ;
1016
    COPY_type ( t, r ) ;
1017
    IGNORE register_type ( t ) ;
1018
@} ;
1019
 
1020
 
1021
/*
1022
    ADD UNION TO LIST
1023
 
1024
    This action adds the union q to the start of the union list r.
1025
*/
1026
 
1027
<join-union> : ( q : UNION, r : UNION-LIST ) -> ( p : UNION-LIST ) = @{
1028
    CONS_ptr ( @q, @r, @p ) ;
1029
@} ;
1030
 
1031
 
1032
/*
1033
    CREATE AN EXTRA TYPE
1034
 
1035
    This action creates an extra type.  Actually this is done automatically
1036
    so no action is required.
1037
*/
1038
 
1039
<make-extra> : ( t : TYPE ) -> () = @{
1040
    UNUSED ( @t ) ;
1041
@} ;
1042
 
1043
 
1044
/*
1045
    IMPORT AN ENTIRE ALGEBRA
1046
 
1047
    This action imports an entire algebra.
1048
*/
1049
 
1050
<import-all> : ( a : IDENTIFIER ) -> () = @{
1051
    import_algebra ( @a ) ;
1052
@} ;
1053
 
1054
 
1055
/*
1056
    IMPORT AN ITEM FROM AN ALGEBRA
1057
 
1058
    This action imports a single type from an algebra.
1059
*/
1060
 
1061
<import-one> : ( a : IDENTIFIER, i : IDENTIFIER ) -> () = @{
1062
    import_type ( @a, @i ) ;
1063
@} ;
1064
 
1065
 
1066
/*
1067
    OVERALL NAME
1068
 
1069
    This action sets the overall algebra name to i.  It also prints a
1070
    warning if an old-style algebra is used.
1071
*/
1072
 
1073
<set-main> : ( i : IDENTIFIER ) -> () = @{
1074
    string nm = @i ;
1075
    if ( !new_format ) error ( ERROR_WARNING, "Old style algebra syntax" ) ;
1076
    if ( find_algebra ( nm ) ) {
1077
	error ( ERROR_SERIOUS, "Algebra %s already defined", nm ) ;
1078
    }
1079
    algebra->name = nm ;
1080
@} ;
1081
 
1082
 
1083
/*
1084
    VERSION NUMBER
1085
 
1086
    This action sets the overall algebra version number to a.b.
1087
*/
1088
 
1089
<set-version> : ( a : NUMBER, b : NUMBER ) -> () = @{
1090
    algebra->major_no = ( int ) @a ;
1091
    algebra->minor_no = ( int ) @b ;
1092
@} ;
1093
 
1094
 
1095
/*
1096
    RECORD PRIMITIVES
1097
 
1098
    This action adds a list of primitives to the list of all primitives.
1099
*/
1100
 
1101
<add-primitive> : ( p : PRIMITIVE-LIST ) -> () = @{
1102
    algebra->primitives = APPEND_list ( algebra->primitives, @p ) ;
1103
@} ;
1104
 
1105
 
1106
/*
1107
    RECORD IDENTITIES
1108
 
1109
    This action adds a list of identities to the list of all identities.
1110
*/
1111
 
1112
<add-identity> : ( p : IDENTITY-LIST ) -> () = @{
1113
    algebra->identities = APPEND_list ( algebra->identities, @p ) ;
1114
@} ;
1115
 
1116
 
1117
/*
1118
    RECORD ENUMERATIONS
1119
 
1120
    This action adds a list of enumerations to the list of all enumerations.
1121
*/
1122
 
1123
<add-enum> : ( p : ENUM-LIST ) -> () = @{
1124
    algebra->enumerations = APPEND_list ( algebra->enumerations, @p ) ;
1125
@} ;
1126
 
1127
 
1128
/*
1129
    RECORD STRUCTURES
1130
 
1131
    This action adds a list of structures to the list of all structures.
1132
*/
1133
 
1134
<add-structure> : ( p : STRUCTURE-LIST ) -> () = @{
1135
    algebra->structures = APPEND_list ( algebra->structures, @p ) ;
1136
@} ;
1137
 
1138
 
1139
/*
1140
    RECORD UNIONS
1141
 
1142
    This action adds a list of unions to the list of all unions.
1143
*/
1144
 
1145
<add-union> : ( p : UNION-LIST ) -> () = @{
1146
    algebra->unions = APPEND_list ( algebra->unions, @p ) ;
1147
@} ;
1148
 
1149
 
1150
/*
1151
    OLD INPUT FORMAT
1152
 
1153
    This action is used to indicate the old input format.
1154
*/
1155
 
1156
<set-old-unit> : () -> () = @{
1157
    new_format = 0 ;
1158
@} ;
1159
 
1160
 
1161
/*
1162
    NEW INPUT FORMAT
1163
 
1164
    This action is used to indicate the new input format.
1165
*/
1166
 
1167
<set-new-unit> : () -> () = @{
1168
    new_format = 1 ;
1169
@} ;
1170
 
1171
 
1172
%trailer% @{
1173
@}, @{
1174
#endif
1175
@} ;