source: trunk/third/ORBit/libIDL/parser.y @ 15271

Revision 15271, 47.6 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15270, which included commits to RCS files with non-trunk default branches.
Line 
1/***************************************************************************
2
3    parser.y (IDL yacc parser and tree generation)
4
5    Copyright (C) 1998, 1999 Andrew T. Veliath
6
7    This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Library General Public
9    License as published by the Free Software Foundation; either
10    version 2 of the License, or (at your option) any later version.
11
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Library General Public License for more details.
16
17    You should have received a copy of the GNU Library General Public
18    License along with this library; if not, write to the Free
19    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21    $Id: parser.y,v 1.1.1.1 2000-11-10 00:49:24 ghudson Exp $
22
23***************************************************************************/
24%{
25#include <assert.h>
26#include <stdarg.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <ctype.h>
30#include <string.h>
31#include <errno.h>
32#include "rename.h"
33#include "util.h"
34
35#define REF_IDENTS
36
37#define do_binop(rv,op,a,b)             do {            \
38        if (IDL_binop_chktypes (op, a, b))              \
39                YYABORT;                                \
40        if (!(__IDL_flags & IDLF_NO_EVAL_CONST)) {      \
41                rv = IDL_binop_eval (op, a, b);         \
42                IDL_tree_free (a);                      \
43                IDL_tree_free (b);                      \
44                if (!rv) YYABORT;                       \
45        } else {                                        \
46                rv = IDL_binop_new (op, a, b);          \
47        }                                               \
48} while (0)
49
50#define do_unaryop(rv,op,a)             do {            \
51        if (IDL_unaryop_chktypes (op, a))               \
52                YYABORT;                                \
53        if (!(__IDL_flags & IDLF_NO_EVAL_CONST)) {      \
54                rv = IDL_unaryop_eval (op, a);          \
55                IDL_tree_free (a);                      \
56                if (!rv) YYABORT;                       \
57        } else {                                        \
58                rv = IDL_unaryop_new (op, a);           \
59        }                                               \
60} while (0)
61
62#define assign_declspec(tree,declspec)  do {            \
63        IDL_NODE_DECLSPEC (tree) = declspec;            \
64        if (__IDL_inhibits > 0 ||                       \
65            (__IDL_flags & IDLF_INHIBIT_INCLUDES &&     \
66             __IDL_flagsi & IDLFP_IN_INCLUDES)) {       \
67                IDL_NODE_DECLSPEC (tree) |=             \
68                        IDLF_DECLSPEC_EXIST |           \
69                        IDLF_DECLSPEC_INHIBIT;          \
70        }                                               \
71} while (0)
72
73#define assign_props(tree,props)        do {            \
74        if (__IDL_flags & IDLF_PROPERTIES)              \
75                IDL_NODE_PROPERTIES (tree) = (props);   \
76        else                                            \
77                __IDL_free_properties (props);          \
78} while (0)
79
80extern int              yylex                           (void);
81static IDL_declspec_t   IDL_parse_declspec              (const char *strspec);
82static int              IDL_binop_chktypes              (enum IDL_binop op,
83                                                         IDL_tree a,
84                                                         IDL_tree b);
85static int              IDL_unaryop_chktypes            (enum IDL_unaryop op,
86                                                         IDL_tree a);
87static IDL_tree         IDL_binop_eval                  (enum IDL_binop op,
88                                                         IDL_tree a,
89                                                         IDL_tree b);
90static IDL_tree         IDL_unaryop_eval                (enum IDL_unaryop op,
91                                                         IDL_tree a);
92static IDL_tree         list_start                      (IDL_tree a,
93                                                         gboolean filter_null);
94static IDL_tree         list_chain                      (IDL_tree a,
95                                                         IDL_tree b,
96                                                         gboolean filter_null);
97static IDL_tree         zlist_chain                     (IDL_tree a,
98                                                         IDL_tree b,
99                                                         gboolean filter_null);
100static int              do_token_error                  (IDL_tree p,
101                                                         const char *message,
102                                                         gboolean prev);
103static void             illegal_context_type_error      (IDL_tree p,
104                                                         const char *what);
105static void             illegal_type_error              (IDL_tree p,
106                                                         const char *message);
107%}
108
109%union {
110        IDL_tree tree;
111        struct {
112                IDL_tree tree;
113                gpointer data;
114        } treedata;
115        GHashTable *hash_table;
116        char *str;
117        gboolean boolean;
118        IDL_declspec_t declspec;
119        IDL_longlong_t integer;
120        double floatp;
121        enum IDL_unaryop unaryop;
122        enum IDL_param_attr paramattr;
123}
124
125/* Terminals */
126%token                  TOK_ANY
127%token                  TOK_ATTRIBUTE
128%token                  TOK_BOOLEAN
129%token                  TOK_CASE
130%token                  TOK_CHAR
131%token                  TOK_CONST
132%token                  TOK_CONTEXT
133%token                  TOK_DEFAULT
134%token                  TOK_DOUBLE
135%token                  TOK_ENUM
136%token                  TOK_EXCEPTION
137%token                  TOK_FALSE
138%token                  TOK_FIXED
139%token                  TOK_FLOAT
140%token                  TOK_IN
141%token                  TOK_INOUT
142%token                  TOK_INTERFACE
143%token                  TOK_LONG
144%token                  TOK_MODULE
145%token                  TOK_NATIVE
146%token                  TOK_OBJECT
147%token                  TOK_OCTET
148%token                  TOK_ONEWAY
149%token                  TOK_OP_SCOPE
150%token                  TOK_OP_SHL
151%token                  TOK_OP_SHR
152%token                  TOK_OUT
153%token                  TOK_RAISES
154%token                  TOK_READONLY
155%token                  TOK_SEQUENCE
156%token                  TOK_SHORT
157%token                  TOK_STRING
158%token                  TOK_STRUCT
159%token                  TOK_SWITCH
160%token                  TOK_TRUE
161%token                  TOK_TYPECODE
162%token                  TOK_TYPEDEF
163%token                  TOK_UNION
164%token                  TOK_UNSIGNED
165%token                  TOK_VARARGS
166%token                  TOK_VOID
167%token                  TOK_WCHAR
168%token                  TOK_WSTRING
169%token <floatp>         TOK_FLOATP
170%token <integer>        TOK_INTEGER
171%token <str>            TOK_DECLSPEC TOK_PROP_KEY
172%token <str>            TOK_PROP_VALUE TOK_NATIVE_TYPE
173%token <str>            TOK_IDENT TOK_SQSTRING TOK_DQSTRING TOK_FIXEDP
174%token <tree>           TOK_CODEFRAG
175
176/* Non-Terminals */
177%type <tree>            add_expr
178%type <tree>            and_expr
179%type <tree>            any_type
180%type <tree>            array_declarator
181%type <tree>            attr_dcl
182%type <tree>            attr_dcl_def
183%type <tree>            base_type_spec
184%type <tree>            boolean_lit
185%type <tree>            boolean_type
186%type <tree>            case_label
187%type <tree>            case_label_list
188%type <tree>            case_stmt
189%type <tree>            case_stmt_list
190%type <tree>            char_lit
191%type <tree>            char_type
192%type <tree>            codefrag
193%type <tree>            complex_declarator
194%type <tree>            const_dcl
195%type <tree>            const_dcl_def
196%type <tree>            const_exp
197%type <tree>            const_type
198%type <tree>            constr_type_spec
199%type <tree>            context_expr
200%type <tree>            cur_ns_new_or_prev_ident
201%type <tree>            declarator
202%type <tree>            declarator_list
203%type <tree>            definition
204%type <tree>            definition_list
205%type <tree>            element_spec
206%type <tree>            enum_type
207%type <tree>            enumerator_list
208%type <tree>            except_dcl
209%type <tree>            except_dcl_def
210%type <tree>            export
211%type <tree>            export_list
212%type <tree>            fixed_array_size
213%type <tree>            fixed_array_size_list
214%type <tree>            fixed_pt_const_type
215%type <tree>            fixed_pt_lit
216%type <tree>            fixed_pt_type
217%type <tree>            floating_pt_lit
218%type <tree>            floating_pt_type
219%type <tree>            ident
220%type <tree>            illegal_ident
221%type <tree>            integer_lit
222%type <tree>            integer_type
223%type <tree>            interface
224%type <tree>            interface_body
225%type <tree>            interface_catch_ident
226%type <tree>            is_context_expr
227%type <tree>            is_raises_expr
228%type <tree>            literal
229%type <tree>            member
230%type <tree>            member_list
231%type <tree>            member_zlist
232%type <tree>            module
233%type <tree>            mult_expr
234%type <tree>            new_ident
235%type <tree>            new_or_prev_scope
236%type <tree>            new_scope
237%type <tree>            ns_global_ident
238%type <tree>            ns_new_ident
239%type <tree>            ns_prev_ident
240%type <tree>            ns_scoped_name
241%type <tree>            object_type
242%type <tree>            octet_type
243%type <tree>            op_dcl
244%type <tree>            op_dcl_def
245%type <tree>            op_param_type_spec
246%type <tree>            op_param_type_spec_illegal
247%type <tree>            op_type_spec
248%type <tree>            or_expr
249%type <tree>            param_dcl
250%type <tree>            param_dcl_list
251%type <tree>            param_type_spec
252%type <tree>            pop_scope
253%type <tree>            positive_int_const
254%type <tree>            primary_expr
255%type <tree>            raises_expr
256%type <tree>            scoped_name
257%type <tree>            scoped_name_list
258%type <tree>            sequence_type
259%type <tree>            shift_expr
260%type <tree>            simple_declarator
261%type <tree>            simple_declarator_list
262%type <tree>            simple_type_spec
263%type <tree>            specification
264%type <tree>            string_lit
265%type <tree>            string_lit_list
266%type <tree>            string_type
267%type <tree>            struct_type
268%type <tree>            switch_body
269%type <tree>            switch_type_spec
270%type <tree>            template_type_spec
271%type <tree>            type_dcl
272%type <tree>            type_dcl_def
273%type <tree>            type_declarator
274%type <tree>            type_spec
275%type <tree>            unary_expr
276%type <tree>            union_type
277%type <tree>            useless_semicolon
278%type <tree>            wide_char_type
279%type <tree>            wide_string_type
280%type <tree>            xor_expr
281%type <tree>            z_definition_list
282%type <tree>            z_inheritance
283%type <tree>            z_new_ident_catch
284%type <tree>            z_new_scope_catch
285%type <tree>            typecode_type
286
287%type <treedata>        parameter_dcls
288%type <declspec>        z_declspec module_declspec
289%type <hash_table>      z_props prop_hash
290%type <boolean>         is_readonly is_oneway
291%type <boolean>         is_varargs is_cvarargs
292%type <integer>         signed_int unsigned_int
293%type <paramattr>       param_attribute
294%type <str>             sqstring dqstring dqstring_cat
295%type <unaryop>         unary_op
296
297%%
298
299specification:          /* empty */                     { yyerror ("Empty file"); YYABORT; }
300|                       definition_list                 { __IDL_root = $1; }
301        ;
302
303z_definition_list:      /* empty */                     { $$ = NULL; }
304|                       definition_list
305        ;
306
307definition_list:        definition                      { $$ = list_start ($1, TRUE); }
308|                       definition_list definition      { $$ = list_chain ($1, $2, TRUE); }
309        ;
310
311check_semicolon:        ';'
312|                       /* empty */                     {
313        if (do_token_error ($<tree>0, "Missing semicolon after", TRUE))
314                YYABORT;
315}
316        ;
317
318useless_semicolon:      ';'                             {
319        yyerror ("Dangling semicolon has no effect");
320        $$ = NULL;
321}
322        ;
323
324check_comma:            ','
325|                       /* empty */                     {
326        if (do_token_error ($<tree>0, "Missing comma after", TRUE))
327                YYABORT;
328}
329        ;
330
331illegal_ident:          scoped_name                     {
332        if (IDL_NODE_UP ($1))
333                do_token_error (IDL_NODE_UP ($1), "Illegal context for", FALSE);
334        else
335                yyerror ("Illegal context for identifier");
336        YYABORT;
337}
338        ;
339
340definition:             type_dcl check_semicolon
341|                       const_dcl check_semicolon
342|                       except_dcl check_semicolon
343|                       interface check_semicolon
344|                       module check_semicolon
345|                       codefrag
346|                       illegal_ident
347|                       useless_semicolon
348        ;
349
350module_declspec:        z_declspec TOK_MODULE
351        ;
352
353module:                 module_declspec
354                        new_or_prev_scope               {
355        if (IDL_NODE_UP ($2) != NULL &&
356            IDL_NODE_TYPE (IDL_NODE_UP ($2)) != IDLN_MODULE) {
357                yyerror ("Module definition conflicts");
358                do_token_error (IDL_NODE_UP ($2), "with", FALSE);
359                YYABORT;
360        }
361}                       '{'
362                                z_definition_list
363                        '}' pop_scope                   {
364        IDL_tree module;
365
366        if ($5 == NULL) {
367                yyerrorv ("Empty module declaration `%s' is not legal IDL",
368                          IDL_IDENT ($2).str);
369                module = NULL;
370        }
371
372        if (__IDL_flags & IDLF_COMBINE_REOPENED_MODULES) {
373                if (IDL_NODE_UP ($2) == NULL)
374                        module = IDL_module_new ($2, $5);
375                else {
376                        module = IDL_NODE_UP ($2);
377                        IDL_MODULE (module).definition_list =
378                                IDL_list_concat (IDL_MODULE (module).definition_list, $5);
379                        module = NULL;
380                }
381        } else
382                module = IDL_module_new ($2, $5);
383
384        $$ = module;
385        if ($$) assign_declspec ($$, $1);
386}
387        ;
388
389interface_catch_ident:  new_or_prev_scope
390|                       TOK_OBJECT                      {
391        yyerror ("Interfaces cannot be named `Object'");
392        YYABORT;
393}
394|                       TOK_TYPECODE                    {
395        yyerror ("Interfaces cannot be named `TypeCode'");
396        YYABORT;
397}
398        ;
399
400interface:              z_declspec
401                        z_props
402                        TOK_INTERFACE
403                        interface_catch_ident           {
404        assert ($4 != NULL);
405        assert (IDL_NODE_TYPE ($4) == IDLN_IDENT);
406        assert (IDL_IDENT_TO_NS ($4) != NULL);
407        assert (IDL_NODE_TYPE (IDL_IDENT_TO_NS ($4)) == IDLN_GENTREE);
408
409        if (IDL_NODE_UP ($4) != NULL &&
410            IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_INTERFACE &&
411            IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_FORWARD_DCL) {
412                yyerrorl ("Interface definition conflicts",
413                          __IDL_prev_token_line - __IDL_cur_token_line);
414                do_token_error (IDL_NODE_UP ($4), "with", FALSE);
415                YYABORT;
416        } else if (IDL_NODE_UP ($4) != NULL &&
417                   IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_FORWARD_DCL) {
418                yyerrorv ("Cannot redeclare interface `%s'", IDL_IDENT ($4).str);
419                IDL_tree_error ($4, "Previous declaration of interface `%s'", IDL_IDENT ($4).str);
420                YYABORT;
421        } else if (IDL_NODE_UP ($4) != NULL &&
422                   IDL_NODE_TYPE (IDL_NODE_UP ($4)) == IDLN_FORWARD_DCL)
423                __IDL_assign_this_location ($4, __IDL_cur_filename, __IDL_cur_line);
424}
425                        pop_scope
426                        z_inheritance                   {
427        IDL_GENTREE (IDL_IDENT_TO_NS ($4))._import = $7;
428        IDL_ns_push_scope (__IDL_root_ns, IDL_IDENT_TO_NS ($4));
429        if (IDL_ns_check_for_ambiguous_inheritance ($4, $7))
430                __IDL_is_okay = FALSE;
431}                       '{'
432                                interface_body
433                        '}' pop_scope                   {
434        $$ = IDL_interface_new ($4, $7, $10);
435        assign_declspec ($$, $1);
436        assign_props (IDL_INTERFACE ($$).ident, $2);
437}
438|                       z_declspec
439                        z_props
440                        TOK_INTERFACE
441                        interface_catch_ident
442                        pop_scope                       {
443        if ($2) yywarningv (IDL_WARNING1,
444                            "Ignoring properties for forward declaration `%s'",
445                            IDL_IDENT ($4).str);
446        $$ = IDL_forward_dcl_new ($4);
447        assign_declspec ($$, $1);
448}
449        ;
450
451z_inheritance:          /* empty */                     { $$ = NULL; }
452|                       ':' scoped_name_list            {
453        GHashTable *table = g_hash_table_new (g_direct_hash, g_direct_equal);
454        gboolean die = FALSE;
455        IDL_tree p = $2;
456
457        assert (IDL_NODE_TYPE (p) == IDLN_LIST);
458        for (; p != NULL && !die; p = IDL_LIST (p).next) {
459                assert (IDL_LIST (p).data != NULL);
460                assert (IDL_NODE_TYPE (IDL_LIST (p).data) == IDLN_IDENT);
461
462                if (g_hash_table_lookup_extended (table, IDL_LIST (p).data, NULL, NULL)) {
463                        char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0);
464                        yyerrorv ("Cannot inherit from interface `%s' more than once", s);
465                        g_free (s);
466                        die = TRUE;
467                        break;
468                } else
469                        g_hash_table_insert (table, IDL_LIST (p).data, NULL);
470
471                if (IDL_NODE_TYPE (IDL_NODE_UP (IDL_LIST (p).data)) == IDLN_FORWARD_DCL) {
472                        char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0);
473                        yyerrorv ("Incomplete definition of interface `%s'", s);
474                        IDL_tree_error (IDL_LIST (p).data,
475                                        "Previous forward declaration of `%s'", s);
476                        g_free (s);
477                        die = TRUE;
478                }
479                else if (IDL_NODE_TYPE (IDL_NODE_UP (IDL_LIST (p).data)) != IDLN_INTERFACE) {
480                        char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0);
481                        yyerrorv ("`%s' is not an interface", s);
482                        IDL_tree_error (IDL_LIST (p).data,
483                                        "Previous declaration of `%s'", s);
484                        g_free (s);
485                        die = TRUE;
486                }
487        }
488
489        g_hash_table_destroy (table);
490
491        if (die)
492                YYABORT;
493
494        $$ = $2;
495}
496        ;
497
498scoped_name_list:       scoped_name                     { $$ = list_start ($1, TRUE); }
499|                       scoped_name_list
500                        check_comma scoped_name         { $$ = list_chain ($1, $3, TRUE); }
501        ;
502
503interface_body:         export_list
504        ;
505
506export_list:            /* empty */                     { $$ = NULL; }
507|                       export_list export              { $$ = zlist_chain ($1, $2, TRUE); }
508        ;
509
510export:                 type_dcl check_semicolon
511|                       except_dcl check_semicolon
512|                       op_dcl check_semicolon
513|                       attr_dcl check_semicolon
514|                       const_dcl check_semicolon
515|                       codefrag
516|                       useless_semicolon
517        ;
518
519type_dcl:               z_declspec type_dcl_def         {
520        $$ = $2;
521        assign_declspec ($$, $1);
522}
523        ;
524
525type_dcl_def:           z_props TOK_TYPEDEF
526                        type_declarator                 {
527        IDL_tree_node node;
528        IDL_tree p, dcl;
529
530        $$ = $3;
531        node.properties = $1;
532        for (p = IDL_TYPE_DCL ($3).dcls; p; p = IDL_LIST (p).next) {
533                dcl = IDL_LIST (p).data;
534                IDL_tree_properties_copy (&node, dcl);
535        }
536        __IDL_free_properties (node.properties);
537}
538|                       struct_type
539|                       union_type
540|                       enum_type
541|                       z_props TOK_NATIVE
542                        simple_declarator               {
543        $$ = IDL_native_new ($3);
544        assign_props (IDL_NATIVE ($$).ident, $1);
545}
546|                       z_props TOK_NATIVE simple_declarator
547                        '('                             {
548        /* Enable native type scanning */
549        if (__IDL_flags & IDLF_XPIDL)
550                __IDL_flagsi |= IDLFP_NATIVE;
551        else {
552                yyerror ("Native syntax not enabled");
553                YYABORT;
554        }
555}                       TOK_NATIVE_TYPE                 {
556        $$ = IDL_native_new ($3);
557        IDL_NATIVE ($$).user_type = $6;
558        assign_props (IDL_NATIVE ($$).ident, $1);
559}
560        ;
561
562type_declarator:        type_spec declarator_list       { $$ = IDL_type_dcl_new ($1, $2); }
563        ;
564
565type_spec:              simple_type_spec
566|                       constr_type_spec
567        ;
568
569simple_type_spec:       base_type_spec
570|                       template_type_spec
571|                       scoped_name
572        ;
573
574constr_type_spec:       struct_type
575|                       union_type
576|                       enum_type
577        ;
578
579z_new_ident_catch:      /* empty */                     {
580        yyerrorv ("Missing identifier in %s definition", $<str>0);
581        YYABORT;
582}
583|                       new_ident
584        ;
585
586z_new_scope_catch:      /* empty */                     {
587        yyerrorv ("Missing identifier in %s definition", $<str>0);
588        YYABORT;
589}
590|                       new_scope
591        ;
592
593struct_type:            z_props TOK_STRUCT
594                        { $<str>$ = "struct"; }
595                        z_new_scope_catch '{'           {
596        g_hash_table_insert (__IDL_structunion_ht, $4, $4);
597        $$ = IDL_type_struct_new ($4, NULL);
598}                               member_list
599                        '}' pop_scope                   {
600        g_hash_table_remove (__IDL_structunion_ht, $4);
601        $$ = $<tree>6;
602        __IDL_assign_up_node ($$, $7);
603        IDL_TYPE_STRUCT ($$).member_list = $7;
604        assign_props (IDL_TYPE_STRUCT ($$).ident, $1);
605}
606        ;
607
608union_type:             z_props TOK_UNION
609                        { $<str>$ = "union"; }
610                        z_new_scope_catch TOK_SWITCH '('
611                                switch_type_spec
612                        ')' '{'                         {
613        g_hash_table_insert (__IDL_structunion_ht, $4, $4);
614        $$ = IDL_type_union_new ($4, $7, NULL);
615}                               switch_body
616                        '}' pop_scope                   {
617        g_hash_table_remove (__IDL_structunion_ht, $4);
618        $$ = $<tree>10;
619        __IDL_assign_up_node ($$, $11);
620        IDL_TYPE_UNION ($$).switch_body = $11;
621        assign_props (IDL_TYPE_UNION ($$).ident, $1);
622}
623        ;
624
625switch_type_spec:       integer_type
626|                       char_type
627|                       boolean_type
628|                       enum_type
629|                       scoped_name
630        ;
631
632switch_body:            case_stmt_list
633        ;
634
635case_stmt_list:         case_stmt                       { $$ = list_start ($1, TRUE); }
636|                       case_stmt_list case_stmt        { $$ = list_chain ($1, $2, TRUE); }
637        ;
638
639case_stmt:              case_label_list
640                        element_spec check_semicolon    { $$ = IDL_case_stmt_new ($1, $2); }
641        ;
642
643element_spec:           type_spec declarator            {
644        char *s;
645
646        $$ = IDL_member_new ($1, list_start ($2, TRUE));
647        if (IDL_NODE_TYPE ($1) == IDLN_IDENT &&
648            g_hash_table_lookup (__IDL_structunion_ht, $1)) {
649                s = IDL_ns_ident_to_qstring ($2, "::", 0);
650                yyerrorv ("Member `%s'", s);
651                do_token_error (IDL_NODE_UP ($1), "recurses", TRUE);
652                g_free (s);
653        }
654}
655        ;
656
657case_label_list:        case_label                      { $$ = list_start ($1, FALSE); }
658|                       case_label_list case_label      { $$ = list_chain ($1, $2, FALSE); }
659        ;
660
661case_label:             TOK_CASE const_exp ':'          { $$ = $2; }
662|                       TOK_DEFAULT ':'                 { $$ = NULL; }
663        ;
664
665const_dcl:              z_declspec const_dcl_def        {
666        $$ = $2;
667        assign_declspec ($$, $1);
668}
669        ;
670
671const_dcl_def:          TOK_CONST const_type new_ident
672                        '=' const_exp                   {
673        $$ = IDL_const_dcl_new ($2, $3, $5);
674        /* Should probably do some type checking here... */
675}
676        ;
677
678except_dcl:             z_declspec except_dcl_def       {
679        $$ = $2;
680        assign_declspec ($$, $1);
681}
682        ;
683
684except_dcl_def:         TOK_EXCEPTION new_scope '{'
685                                member_zlist
686                        '}' pop_scope                   { $$ = IDL_except_dcl_new ($2, $4); }
687        ;
688
689member_zlist:           /* empty */                     { $$ = NULL; }
690|                       member_zlist member             { $$ = zlist_chain ($1, $2, TRUE); }
691        ;
692
693is_readonly:            /* empty */                     { $$ = FALSE; }
694|                       TOK_READONLY                    { $$ = TRUE; }
695        ;
696
697attr_dcl:               z_declspec attr_dcl_def         {
698        $$ = $2;
699        assign_declspec ($$, $1);
700}
701        ;
702
703attr_dcl_def:           z_props
704                        is_readonly
705                        TOK_ATTRIBUTE
706                        { $<str>$ = "attribute"; }
707                        param_type_spec
708                        simple_declarator_list          {
709        IDL_tree_node node;
710        IDL_tree p, dcl;
711
712        $$ = IDL_attr_dcl_new ($2, $5, $6);
713        node.properties = $1;
714        for (p = $6; p; p = IDL_LIST (p).next) {
715                dcl = IDL_LIST (p).data;
716                IDL_tree_properties_copy (&node, dcl);
717        }
718        __IDL_free_properties (node.properties);
719}
720        ;
721
722param_type_spec:        op_param_type_spec
723|                       TOK_VOID                        {
724        yyerrorv ("Illegal type `void' for %s", $<str>0);
725        $$ = NULL;
726}
727        ;
728
729op_param_type_spec_illegal:
730                        sequence_type
731|                       constr_type_spec
732        ;
733
734op_param_type_spec:     base_type_spec
735|                       string_type
736|                       wide_string_type
737|                       fixed_pt_type
738|                       scoped_name
739|                       op_param_type_spec_illegal      {
740        illegal_context_type_error ($1, $<str>0);
741        $$ = $1;
742}
743        ;
744
745is_oneway:              /* empty */                     { $$ = FALSE; }
746|                       TOK_ONEWAY                      { $$ = TRUE; }
747        ;
748
749op_dcl:         z_declspec op_dcl_def                   {
750        $$ = $2;
751        assign_declspec ($$, $1);
752}
753        ;
754
755op_dcl_def:             z_props
756                        is_oneway
757                        op_type_spec
758                        new_scope parameter_dcls pop_scope
759                        is_raises_expr
760                        is_context_expr                 {
761        $$ = IDL_op_dcl_new ($2, $3, $4, $5.tree, $7, $8);
762        IDL_OP_DCL ($$).f_varargs = GPOINTER_TO_INT ($5.data);
763        assign_props (IDL_OP_DCL ($$).ident, $1);
764}
765        ;
766
767op_type_spec:           { $<str>$ = "operation return value"; }
768                        op_param_type_spec              { $$ = $2; }
769|                       TOK_VOID                        { $$ = NULL; }
770        ;
771
772is_varargs:             /* empty */                     { $$ = FALSE; }
773|                       TOK_VARARGS                     { $$ = TRUE; }
774        ;
775
776is_cvarargs:            /* empty */                     { $$ = FALSE; }
777|                       ',' TOK_VARARGS                 { $$ = TRUE; }
778        ;
779
780parameter_dcls:         '('
781                        param_dcl_list
782                        is_cvarargs
783                        ')'                             {
784        $$.tree = $2;
785        $$.data = GINT_TO_POINTER ($3);
786}
787|                       '(' is_varargs ')'              {
788        $$.tree = NULL;
789        $$.data = GINT_TO_POINTER ($2);
790}
791        ;
792
793param_dcl_list:         param_dcl                       { $$ = list_start ($1, TRUE); }
794|                       param_dcl_list
795                        check_comma param_dcl           { $$ = list_chain ($1, $3, TRUE); }
796        ;
797
798param_dcl:              z_props
799                        param_attribute
800                        { $<str>$ = "parameter"; }
801                        param_type_spec
802                        simple_declarator               {
803        $$ = IDL_param_dcl_new ($2, $4, $5);
804        assign_props (IDL_PARAM_DCL ($$).simple_declarator, $1);
805}
806        ;
807
808param_attribute:        TOK_IN                          { $$ = IDL_PARAM_IN; }
809|                       TOK_OUT                         { $$ = IDL_PARAM_OUT; }
810|                       TOK_INOUT                       { $$ = IDL_PARAM_INOUT; }
811|                       param_type_spec                 {
812        yyerrorv ("Missing direction attribute (in, out, inout) before parameter");
813        IDL_tree_free ($1);
814}
815        ;
816
817is_raises_expr:         /* empty */                     { $$ = NULL; }
818|                       raises_expr
819        ;
820
821is_context_expr:        /* empty */                     { $$ = NULL; }
822|                       context_expr
823        ;
824
825raises_expr:            TOK_RAISES '('
826                                scoped_name_list
827                        ')'                             { $$ = $3; }
828        ;
829
830context_expr:           TOK_CONTEXT '('
831                                string_lit_list
832                        ')'                             { $$ = $3; }
833        ;
834
835const_type:             integer_type
836|                       char_type
837|                       wide_char_type
838|                       boolean_type
839|                       floating_pt_type
840|                       string_type
841|                       wide_string_type
842|                       fixed_pt_const_type
843|                       scoped_name
844        ;
845
846const_exp:              or_expr
847        ;
848
849or_expr:                xor_expr
850|                       or_expr '|' xor_expr            { do_binop ($$, IDL_BINOP_OR, $1, $3); }
851        ;
852
853xor_expr:               and_expr
854|                       xor_expr '^' and_expr           { do_binop ($$, IDL_BINOP_XOR, $1, $3); }
855        ;
856
857and_expr:               shift_expr
858|                       and_expr '&' shift_expr         { do_binop ($$, IDL_BINOP_AND, $1, $3); }
859        ;
860
861shift_expr:             add_expr
862|                       shift_expr TOK_OP_SHR add_expr  { do_binop ($$, IDL_BINOP_SHR, $1, $3); }
863|                       shift_expr TOK_OP_SHL add_expr  { do_binop ($$, IDL_BINOP_SHL, $1, $3); }
864        ;
865
866add_expr:               mult_expr
867|                       add_expr '+' mult_expr          { do_binop ($$, IDL_BINOP_ADD, $1, $3); }
868|                       add_expr '-' mult_expr          { do_binop ($$, IDL_BINOP_SUB, $1, $3); }
869        ;
870
871mult_expr:              unary_expr
872|                       mult_expr '*' unary_expr        { do_binop ($$, IDL_BINOP_MULT, $1, $3); }
873|                       mult_expr '/' unary_expr        { do_binop ($$, IDL_BINOP_DIV, $1, $3); }
874|                       mult_expr '%' unary_expr        { do_binop ($$, IDL_BINOP_MOD, $1, $3); }
875        ;
876
877unary_expr:             unary_op primary_expr           { do_unaryop ($$, $1, $2); }
878|                       primary_expr
879        ;
880
881unary_op:               '-'                             { $$ = IDL_UNARYOP_MINUS; }
882|                       '+'                             { $$ = IDL_UNARYOP_PLUS; }
883|                       '~'                             { $$ = IDL_UNARYOP_COMPLEMENT; }
884        ;
885
886primary_expr:           scoped_name                     {
887        IDL_tree p, literal;
888       
889        assert (IDL_NODE_TYPE ($1) == IDLN_IDENT);
890
891        p = IDL_NODE_UP ($1);
892       
893        if ((literal = IDL_resolve_const_exp ($1, IDLN_ANY))) {
894                ++IDL_NODE_REFS (literal);
895                $$ = literal;
896                IDL_tree_free ($1);
897        } else
898                $$ = $1;
899}
900|                       literal
901|                       '(' const_exp ')'               { $$ = $2; }
902        ;
903
904literal:                integer_lit
905|                       string_lit
906|                       char_lit
907|                       fixed_pt_lit
908|                       floating_pt_lit
909|                       boolean_lit
910        ;
911
912enum_type:              z_props TOK_ENUM
913                        { $<str>$ = "enum"; }
914                        z_new_ident_catch '{'
915                                enumerator_list
916                        '}'                             {
917        $$ = IDL_type_enum_new ($4, $6);
918        assign_props (IDL_TYPE_ENUM ($$).ident, $1);
919}
920        ;
921
922scoped_name:            ns_scoped_name                  {
923        assert ($1 != NULL);
924        assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE);
925        assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
926        $$ = IDL_GENTREE ($1).data;
927}
928        ;
929
930ns_scoped_name:         ns_prev_ident
931|                       TOK_OP_SCOPE ns_global_ident    { $$ = $2; }
932|                       ns_scoped_name TOK_OP_SCOPE
933                        ident                           {
934        IDL_tree p;
935
936        assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE);
937        assert (IDL_NODE_TYPE ($3) == IDLN_IDENT);
938
939#ifdef YYDEBUG
940        if (yydebug)
941                printf ("looking in %s\n", IDL_IDENT (IDL_GENTREE ($1).data).str);
942#endif
943
944        if ((p = IDL_ns_lookup_this_scope (__IDL_root_ns, $1, $3, NULL)) == NULL) {
945#ifdef YYDEBUG
946                if (yydebug)
947                        printf ("'%s'\n", IDL_IDENT ($3).str);
948#endif
949                yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($3).str);
950                IDL_tree_free ($3);
951                YYABORT;
952        }
953        IDL_tree_free ($3);
954#ifdef REF_IDENTS
955        ++IDL_NODE_REFS (IDL_GENTREE (p).data);
956#endif
957        $$ = p;
958}
959        ;
960
961enumerator_list:        new_ident                       { $$ = list_start ($1, TRUE); }
962|                       enumerator_list
963                        check_comma new_ident           { $$ = list_chain ($1, $3, TRUE); }
964        ;
965
966member_list:            member                          { $$ = list_start ($1, TRUE); }
967|                       member_list member              { $$ = list_chain ($1, $2, TRUE); }
968        ;
969
970member:                 type_spec declarator_list
971                        check_semicolon                 {
972        char *s;
973
974        $$ = IDL_member_new ($1, $2);
975        if (IDL_NODE_TYPE ($1) == IDLN_IDENT &&
976            g_hash_table_lookup (__IDL_structunion_ht, $1)) {
977                s = IDL_ns_ident_to_qstring (IDL_LIST ($2).data, "::", 0);
978                yyerrorv ("Member `%s'", s);
979                do_token_error (IDL_NODE_UP ($1), "recurses", TRUE);
980                g_free (s);
981        }
982}
983        ;
984
985base_type_spec:         floating_pt_type
986|                       integer_type
987|                       char_type
988|                       wide_char_type
989|                       boolean_type
990|                       octet_type
991|                       any_type
992|                       object_type
993|                       typecode_type
994        ;
995
996template_type_spec:     sequence_type
997|                       string_type
998|                       wide_string_type
999|                       fixed_pt_type
1000        ;
1001
1002sequence_type:          TOK_SEQUENCE '<'
1003                                simple_type_spec ',' positive_int_const
1004                        '>'                             { $$ = IDL_type_sequence_new ($3, $5); }
1005|                       TOK_SEQUENCE '<'
1006                                simple_type_spec
1007                        '>'                             { $$ = IDL_type_sequence_new ($3, NULL); }
1008        ;
1009
1010floating_pt_type:       TOK_FLOAT                       { $$ = IDL_type_float_new (IDL_FLOAT_TYPE_FLOAT); }
1011|                       TOK_DOUBLE                      { $$ = IDL_type_float_new (IDL_FLOAT_TYPE_DOUBLE); }
1012|                       TOK_LONG TOK_DOUBLE             { $$ = IDL_type_float_new (IDL_FLOAT_TYPE_LONGDOUBLE); }
1013        ;
1014
1015fixed_pt_type:          TOK_FIXED '<'
1016                                positive_int_const ',' integer_lit
1017                        '>'                             { $$ = IDL_type_fixed_new ($3, $5); }
1018        ;
1019
1020fixed_pt_const_type:    TOK_FIXED                       { $$ = IDL_type_fixed_new (NULL, NULL); }
1021        ;
1022
1023integer_type:           signed_int                      { $$ = IDL_type_integer_new (TRUE, $1); }
1024|                       unsigned_int                    { $$ = IDL_type_integer_new (FALSE, $1); }
1025        ;
1026
1027signed_int:             signed_short_int                { $$ = IDL_INTEGER_TYPE_SHORT; }
1028|                       signed_long_int                 { $$ = IDL_INTEGER_TYPE_LONG; }
1029|                       signed_longlong_int             { $$ = IDL_INTEGER_TYPE_LONGLONG; }
1030        ;
1031
1032signed_short_int:       TOK_SHORT
1033        ;
1034
1035signed_long_int:        TOK_LONG
1036        ;
1037
1038signed_longlong_int:    TOK_LONG TOK_LONG
1039        ;
1040
1041unsigned_int:           unsigned_short_int              { $$ = IDL_INTEGER_TYPE_SHORT; }
1042|                       unsigned_long_int               { $$ = IDL_INTEGER_TYPE_LONG; }
1043|                       unsigned_longlong_int           { $$ = IDL_INTEGER_TYPE_LONGLONG; }
1044        ;
1045
1046unsigned_short_int:     TOK_UNSIGNED TOK_SHORT
1047        ;
1048
1049unsigned_long_int:      TOK_UNSIGNED TOK_LONG
1050        ;
1051
1052unsigned_longlong_int:  TOK_UNSIGNED TOK_LONG TOK_LONG
1053        ;
1054
1055char_type:              TOK_CHAR                        { $$ = IDL_type_char_new (); }
1056        ;
1057
1058wide_char_type:         TOK_WCHAR                       { $$ = IDL_type_wide_char_new (); }
1059        ;
1060
1061boolean_type:           TOK_BOOLEAN                     { $$ = IDL_type_boolean_new (); }
1062        ;
1063
1064octet_type:             TOK_OCTET                       { $$ = IDL_type_octet_new (); }
1065        ;
1066
1067any_type:               TOK_ANY                         { $$ = IDL_type_any_new (); }
1068        ;
1069
1070object_type:            TOK_OBJECT                      { $$ = IDL_type_object_new (); }
1071        ;
1072
1073typecode_type:          TOK_TYPECODE                    { $$ = IDL_type_typecode_new (); }
1074        ;
1075
1076string_type:            TOK_STRING '<'
1077                                positive_int_const
1078                                '>'                     { $$ = IDL_type_string_new ($3); }
1079|                       TOK_STRING                      { $$ = IDL_type_string_new (NULL); }
1080        ;
1081
1082wide_string_type:       TOK_WSTRING '<'
1083                                positive_int_const
1084                        '>'                             { $$ = IDL_type_wide_string_new ($3); }
1085|                       TOK_WSTRING                     { $$ = IDL_type_wide_string_new (NULL); }
1086        ;
1087
1088declarator_list:        declarator                      { $$ = list_start ($1, TRUE); }
1089|                       declarator_list
1090                        check_comma declarator          { $$ = list_chain ($1, $3, TRUE); }
1091        ;
1092
1093declarator:             simple_declarator
1094|                       complex_declarator
1095        ;
1096
1097simple_declarator:      new_ident
1098        ;
1099
1100complex_declarator:     array_declarator
1101        ;
1102
1103simple_declarator_list: simple_declarator               { $$ = list_start ($1, TRUE); }
1104|                       simple_declarator_list
1105                        check_comma simple_declarator   { $$ = list_chain ($1, $3, TRUE); }
1106        ;
1107
1108array_declarator:       new_ident
1109                        fixed_array_size_list           {
1110        IDL_tree p;
1111        int i;
1112
1113        $$ = IDL_type_array_new ($1, $2);
1114        for (i = 1, p = $2; p; ++i, p = IDL_LIST (p).next)
1115                if (!IDL_LIST (p).data) {
1116                        char *s = IDL_ns_ident_to_qstring ($1, "::", 0);
1117                        yyerrorv ("Missing value in dimension %d of array `%s'", i, s);
1118                        g_free (s);
1119                }
1120}
1121        ;
1122
1123fixed_array_size_list:  fixed_array_size                { $$ = list_start ($1, FALSE); }
1124|                       fixed_array_size_list
1125                        fixed_array_size                { $$ = list_chain ($1, $2, FALSE); }
1126        ;
1127
1128fixed_array_size:       '[' positive_int_const ']'      { $$ = $2; }
1129|                       '[' ']'                         { $$ = NULL; }
1130        ;
1131
1132prop_hash:              TOK_PROP_KEY
1133                        TOK_PROP_VALUE                  {
1134        $$ = g_hash_table_new (IDL_strcase_hash, IDL_strcase_equal);
1135        g_hash_table_insert ($$, $1, $2);
1136}
1137|                       prop_hash ','
1138                        TOK_PROP_KEY
1139                        TOK_PROP_VALUE                  {
1140        $$ = $1;
1141        g_hash_table_insert ($$, $3, $4);
1142}
1143|                       TOK_PROP_KEY                    {
1144        $$ = g_hash_table_new (IDL_strcase_hash, IDL_strcase_equal);
1145        g_hash_table_insert ($$, $1, g_strdup (""));
1146}
1147|                       prop_hash ','
1148                        TOK_PROP_KEY                    {
1149        $$ = $1;
1150        g_hash_table_insert ($$, $3, g_strdup (""));
1151}
1152        ;
1153
1154ident:                  TOK_IDENT                       { $$ = IDL_ident_new ($1); }
1155        ;
1156
1157new_ident:              ns_new_ident                    {
1158        assert ($1 != NULL);
1159        assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE);
1160        assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
1161        $$ = IDL_GENTREE ($1).data;
1162}
1163        ;
1164
1165new_scope:              ns_new_ident                    {
1166        IDL_ns_push_scope (__IDL_root_ns, $1);
1167#ifdef YYDEBUG
1168        if (yydebug)
1169                printf ("entering new/prev scope of %s\n",
1170                       IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str);
1171#endif
1172        assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
1173        $$ = IDL_GENTREE ($1).data;
1174}
1175        ;
1176
1177new_or_prev_scope:      cur_ns_new_or_prev_ident        {
1178        IDL_ns_push_scope (__IDL_root_ns, $1);
1179        assert (IDL_NS (__IDL_root_ns).current != NULL);
1180        assert (IDL_NODE_TYPE (IDL_NS (__IDL_root_ns).current) == IDLN_GENTREE);
1181        assert (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data != NULL);
1182        assert (IDL_NODE_TYPE (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data) == IDLN_IDENT);
1183#ifdef YYDEBUG
1184        if (yydebug)
1185                printf ("entering new/prev scope of %s\n",
1186                       IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str);
1187#endif
1188        assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
1189        $$ = IDL_GENTREE ($1).data;
1190}
1191        ;
1192
1193pop_scope:              /* empty */                     {
1194#ifdef YYDEBUG
1195        if (yydebug)
1196                printf ("scope to parent of %s\n",
1197                       IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str);
1198#endif
1199        IDL_ns_pop_scope (__IDL_root_ns);
1200}
1201        ;
1202
1203ns_new_ident:           ident                           {
1204        IDL_tree p;
1205
1206        if ((p = IDL_ns_place_new (__IDL_root_ns, $1)) == NULL) {
1207                IDL_tree q;
1208                int i;
1209
1210                p = IDL_ns_lookup_cur_scope (__IDL_root_ns, $1, NULL);
1211
1212                for (i = 0, q = IDL_GENTREE (p).data;
1213                     q && (IDL_NODE_TYPE (q) == IDLN_IDENT ||
1214                           IDL_NODE_TYPE (q) == IDLN_LIST) && i < 4;
1215                     ++i)
1216                        if (IDL_NODE_UP (q))
1217                                q = IDL_NODE_UP (q);
1218
1219                if (q) {
1220                        IDL_tree_error ($1, "`%s' conflicts", IDL_IDENT ($1).str);
1221                        do_token_error (q, "with", FALSE);
1222                } else
1223                        yyerrorv ("`%s' duplicate identifier", IDL_IDENT ($1).str);
1224
1225                IDL_tree_free ($1);
1226                YYABORT;
1227        }
1228        assert (IDL_IDENT ($1)._ns_ref == p);
1229#ifdef REF_IDENTS
1230        ++IDL_NODE_REFS (IDL_GENTREE (p).data);
1231#endif
1232        if (__IDL_new_ident_comments != NULL) {
1233                assert (IDL_IDENT ($1).comments == NULL);
1234                IDL_IDENT ($1).comments = __IDL_new_ident_comments;
1235                __IDL_new_ident_comments = NULL;
1236        }
1237        $$ = p;
1238}
1239        ;
1240
1241ns_prev_ident:          ident                           {
1242        IDL_tree p;
1243
1244        if ((p = IDL_ns_resolve_ident (__IDL_root_ns, $1)) == NULL) {
1245                yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($1).str);
1246                IDL_tree_free ($1);
1247                YYABORT;
1248        }
1249        IDL_tree_free ($1);
1250        assert (IDL_GENTREE (p).data != NULL);
1251        assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p);
1252#ifdef REF_IDENTS
1253        ++IDL_NODE_REFS (IDL_GENTREE (p).data);
1254#endif
1255        $$ = p;
1256}
1257        ;
1258
1259cur_ns_new_or_prev_ident:
1260                        ident                           {
1261        IDL_tree p;
1262
1263        if ((p = IDL_ns_lookup_cur_scope (__IDL_root_ns, $1, NULL)) == NULL) {
1264                p = IDL_ns_place_new (__IDL_root_ns, $1);
1265                assert (p != NULL);
1266                assert (IDL_IDENT ($1)._ns_ref == p);
1267                if (__IDL_new_ident_comments != NULL) {
1268                        assert (IDL_IDENT ($1).comments == NULL);
1269                        IDL_IDENT ($1).comments = __IDL_new_ident_comments;
1270                        __IDL_new_ident_comments = NULL;
1271                }
1272        } else {
1273                IDL_tree_free ($1);
1274                assert (IDL_GENTREE (p).data != NULL);
1275                assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p);
1276        }
1277#ifdef REF_IDENTS
1278        ++IDL_NODE_REFS (IDL_GENTREE (p).data);
1279#endif
1280        $$ = p;
1281}
1282        ;
1283
1284ns_global_ident:        ident                           {
1285        IDL_tree p;
1286
1287        if ((p = IDL_ns_lookup_this_scope (
1288                __IDL_root_ns,IDL_NS (__IDL_root_ns).file, $1, NULL)) == NULL) {
1289                yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($1).str);
1290                IDL_tree_free ($1);
1291                YYABORT;
1292        }
1293        IDL_tree_free ($1);
1294        assert (IDL_GENTREE (p).data != NULL);
1295        assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p);
1296#ifdef REF_IDENTS
1297        ++IDL_NODE_REFS (IDL_GENTREE (p).data);
1298#endif
1299        $$ = p;
1300}
1301        ;
1302
1303string_lit_list:        string_lit                      { $$ = list_start ($1, TRUE); }
1304|                       string_lit_list
1305                        check_comma string_lit          { $$ = list_chain ($1, $3, TRUE); }
1306        ;
1307
1308positive_int_const:     const_exp                       {
1309        IDL_tree literal, ident = NULL;
1310        IDL_longlong_t value = 0;
1311
1312        if ((literal = IDL_resolve_const_exp ($1, IDLN_INTEGER))) {
1313                assert (IDL_NODE_TYPE (literal) == IDLN_INTEGER);
1314                ++IDL_NODE_REFS (literal);
1315                value = IDL_INTEGER (literal).value;
1316                IDL_tree_free ($1);
1317        }
1318
1319        if (literal && IDL_NODE_UP (literal) &&
1320            IDL_NODE_TYPE (IDL_NODE_UP (literal)) == IDLN_CONST_DCL)
1321                ident = IDL_CONST_DCL (IDL_NODE_UP (literal)).ident;
1322       
1323        if (literal == NULL) {
1324                if (!(__IDL_flags & IDLF_NO_EVAL_CONST))
1325                        yyerror ("Could not resolve constant expression");
1326                $$ = $1;
1327        } else if (value == 0) {
1328                yyerror ("Zero array size is illegal");
1329                if (ident)
1330                        IDL_tree_error (ident, "From constant declared here");
1331                $$ = NULL;
1332        } else if (value < 0) {
1333                yywarningv (IDL_WARNING1, "Cannot use negative value %"
1334                            IDL_LL "d, using %" IDL_LL "d",
1335                           value, -value);
1336                if (ident)
1337                        IDL_tree_warning (ident,
1338                                          IDL_WARNING1, "From constant declared here");
1339                $$ = IDL_integer_new (-value);
1340        }
1341        else
1342                $$ = IDL_integer_new (value);
1343}
1344        ;
1345
1346z_declspec:             /* empty */                     { $$ = 0; }
1347|                       TOK_DECLSPEC                    {
1348        $$ = IDL_parse_declspec ($1);
1349        g_free ($1);
1350}
1351        ;
1352
1353z_props:                /* empty */                     { $$ = NULL; }
1354|                       '['                             {
1355        /* Enable property scanning */
1356        if (__IDL_flags & IDLF_PROPERTIES)
1357                __IDL_flagsi |= IDLFP_PROPERTIES;
1358        else {
1359                yyerror ("Property syntax not enabled");
1360                YYABORT;
1361        }
1362}                       prop_hash
1363                        ']'                             { $$ = $3; }
1364        ;
1365
1366integer_lit:            TOK_INTEGER                     { $$ = IDL_integer_new ($1); }
1367        ;
1368
1369string_lit:             dqstring_cat                    { $$ = IDL_string_new ($1); }
1370        ;
1371
1372char_lit:               sqstring                        { $$ = IDL_char_new ($1); }
1373        ;
1374
1375fixed_pt_lit:           TOK_FIXEDP                      { $$ = IDL_fixed_new ($1); }
1376        ;
1377
1378floating_pt_lit:        TOK_FLOATP                      { $$ = IDL_float_new ($1); }
1379        ;
1380
1381boolean_lit:            TOK_TRUE                        { $$ = IDL_boolean_new (TRUE); }
1382|                       TOK_FALSE                       { $$ = IDL_boolean_new (FALSE); }
1383        ;
1384
1385codefrag:               z_declspec TOK_CODEFRAG         {
1386        $$ = $2;
1387        assign_declspec ($$, $1);
1388}
1389        ;
1390
1391dqstring_cat:           dqstring
1392|                       dqstring_cat dqstring           {
1393        char *catstr = g_malloc (strlen ($1) + strlen ($2) + 1);
1394        strcpy (catstr, $1); g_free ($1);
1395        strcat (catstr, $2); g_free ($2);
1396        $$ = catstr;
1397}
1398        ;
1399
1400dqstring:               TOK_DQSTRING                    {
1401        char *s = IDL_do_escapes ($1);
1402        g_free ($1);
1403        $$ = s;
1404}
1405        ;
1406
1407sqstring:               TOK_SQSTRING                    {
1408        char *s = IDL_do_escapes ($1);
1409        g_free ($1);
1410        $$ = s;
1411}
1412        ;
1413
1414%%
1415
1416void __IDL_parser_reset (void)
1417{
1418        yyclearin;
1419}
1420
1421static const char *IDL_ns_get_cur_prefix (IDL_ns ns)
1422{
1423        IDL_tree p;
1424
1425        p = IDL_NS (ns).current;
1426
1427        assert (p != NULL);
1428
1429        while (p && !IDL_GENTREE (p)._cur_prefix)
1430                p = IDL_NODE_UP (p);
1431
1432        return p ? IDL_GENTREE (p)._cur_prefix : NULL;
1433}
1434
1435gchar *IDL_ns_ident_make_repo_id (IDL_ns ns, IDL_tree p,
1436                                  const char *p_prefix, int *major, int *minor)
1437{
1438        GString *s = g_string_new (NULL);
1439        const char *prefix;
1440        char *q;
1441
1442        assert (p != NULL);
1443       
1444        if (IDL_NODE_TYPE (p) == IDLN_IDENT)
1445                p = IDL_IDENT_TO_NS (p);
1446
1447        assert (p != NULL);
1448
1449        prefix = p_prefix ? p_prefix : IDL_ns_get_cur_prefix (ns);
1450
1451        q = IDL_ns_ident_to_qstring (p, "/", 0);
1452        g_string_sprintf (s, "IDL:%s%s%s:%d.%d",
1453                          prefix ? prefix : "",
1454                          prefix && *prefix ? "/" : "",
1455                          q,
1456                          major ? *major : 1,
1457                          minor ? *minor : 0);
1458        g_free (q);
1459
1460        q = s->str;
1461        g_string_free (s, FALSE);
1462
1463        return q;
1464}
1465
1466static const char *get_name_token (const char *s, char **tok)
1467{
1468        const char *begin = s;
1469        int state = 0;
1470
1471        if (!s)
1472                return NULL;
1473
1474        while (isspace (*s)) ++s;
1475       
1476        while (1) switch (state) {
1477        case 0:         /* Unknown */
1478                if (*s == ':')
1479                        state = 1;
1480                else if (isalnum (*s) || *s == '_') {
1481                        begin = s;
1482                        state = 2;
1483                } else
1484                        return NULL;
1485                break;
1486        case 1:         /* Scope */
1487                if (strncmp (s, "::", 2) == 0) {
1488                        char *r = g_malloc (3);
1489                        strcpy (r, "::");
1490                        *tok = r;
1491                        return s + 2;
1492                } else  /* Invalid */
1493                        return NULL;
1494                break;
1495        case 2:
1496                if (isalnum (*s) || *s == '_')
1497                        ++s;
1498                else {
1499                        char *r = g_malloc (s - begin + 1);
1500                        strncpy (r, begin, s - begin + 1);
1501                        r[s - begin] = 0;
1502                        *tok = r;
1503                        return s;
1504                }
1505                break;
1506        }
1507}
1508
1509static IDL_tree IDL_ns_pragma_parse_name (IDL_ns ns, const char *s)
1510{
1511        IDL_tree p = IDL_NS (ns).current;
1512        int start = 1;
1513        char *tok;
1514
1515        while (p && *s && (s = get_name_token (s, &tok))) {
1516                if (tok == NULL)
1517                        return NULL;
1518                if (strcmp (tok, "::") == 0) {
1519                        if (start) {
1520                                /* Globally scoped */
1521                                p = IDL_NS (ns).file;
1522                        }
1523                        g_free (tok);
1524                } else {
1525                        IDL_tree ident = IDL_ident_new (tok);
1526                        p = IDL_ns_lookup_this_scope (__IDL_root_ns, p, ident, NULL);
1527                        IDL_tree_free (ident);
1528                }
1529                start = 0;
1530        }
1531       
1532        return p;
1533}
1534
1535void IDL_ns_ID (IDL_ns ns, const char *s)
1536{
1537        char name[1024], id[1024];
1538        IDL_tree p, ident;
1539        int n;
1540
1541        n = sscanf (s, "%1023s \"%1023s\"", name, id);
1542        if (n < 2 && __IDL_is_parsing) {
1543                yywarning (IDL_WARNING1, "Malformed pragma ID");
1544                return;
1545        }
1546        if (id[strlen (id) - 1] == '"')
1547                id[strlen (id) - 1] = 0;
1548
1549        p = IDL_ns_pragma_parse_name (__IDL_root_ns, name);
1550        if (!p && __IDL_is_parsing) {
1551                yywarningv (IDL_WARNING1, "Unknown identifier `%s' in pragma ID", name);
1552                return;
1553        }
1554
1555        /* We have resolved the identifier, so assign the repo id */
1556        assert (IDL_NODE_TYPE (p) == IDLN_GENTREE);
1557        assert (IDL_GENTREE (p).data != NULL);
1558        assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT);
1559        ident = IDL_GENTREE (p).data;
1560
1561        if (IDL_IDENT_REPO_ID (ident) != NULL)
1562                g_free (IDL_IDENT_REPO_ID (ident));
1563
1564        IDL_IDENT_REPO_ID (ident) = g_strdup (id);
1565}
1566
1567void IDL_ns_version (IDL_ns ns, const char *s)
1568{
1569        char name[1024];
1570        int n, major, minor;
1571        IDL_tree p, ident;
1572
1573        n = sscanf (s, "%1023s %u %u", name, &major, &minor);
1574        if (n < 3 && __IDL_is_parsing) {
1575                yywarning (IDL_WARNING1, "Malformed pragma version");
1576                return;
1577        }
1578
1579        p = IDL_ns_pragma_parse_name (__IDL_root_ns, name);
1580        if (!p && __IDL_is_parsing) {
1581                yywarningv (IDL_WARNING1, "Unknown identifier `%s' in pragma version", name);
1582                return;
1583        }
1584
1585        /* We have resolved the identifier, so assign the repo id */
1586        assert (IDL_NODE_TYPE (p) == IDLN_GENTREE);
1587        assert (IDL_GENTREE (p).data != NULL);
1588        assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT);
1589        ident = IDL_GENTREE (p).data;
1590
1591        if (IDL_IDENT_REPO_ID (ident) != NULL) {
1592                char *v = strrchr (IDL_IDENT_REPO_ID (ident), ':');
1593                if (v) {
1594                        GString *s;
1595
1596                        *v = 0;
1597                        s = g_string_new (NULL);
1598                        g_string_sprintf (s, "%s:%d.%d",
1599                                          IDL_IDENT_REPO_ID (ident), major, minor);
1600                        g_free (IDL_IDENT_REPO_ID (ident));
1601                        IDL_IDENT_REPO_ID (ident) = s->str;
1602                        g_string_free (s, FALSE);
1603                } else if (__IDL_is_parsing)
1604                        yywarningv (IDL_WARNING1, "Cannot find RepositoryID OMG IDL version in ID `%s'",
1605                                    IDL_IDENT_REPO_ID (ident));
1606        } else
1607                IDL_IDENT_REPO_ID (ident) =
1608                        IDL_ns_ident_make_repo_id (
1609                                __IDL_root_ns, p, NULL, &major, &minor);
1610}
1611
1612int IDL_inhibit_get (void)
1613{
1614        g_return_val_if_fail (__IDL_is_parsing, -1);
1615
1616        return __IDL_inhibits;
1617}
1618
1619void IDL_inhibit_push (void)
1620{
1621        g_return_if_fail (__IDL_is_parsing);
1622
1623        ++__IDL_inhibits;
1624}
1625
1626void IDL_inhibit_pop (void)
1627{
1628        g_return_if_fail (__IDL_is_parsing);
1629
1630        if (--__IDL_inhibits < 0)
1631                __IDL_inhibits = 0;
1632}
1633
1634static void IDL_inhibit (IDL_ns ns, const char *s)
1635{
1636        if (g_strcasecmp ("push", s) == 0)
1637                IDL_inhibit_push ();
1638        else if (g_strcasecmp ("pop", s) == 0)
1639                IDL_inhibit_pop ();
1640}
1641
1642void __IDL_do_pragma (const char *s)
1643{
1644        int n;
1645        char directive[256];
1646
1647        g_return_if_fail (__IDL_is_parsing);
1648        g_return_if_fail (s != NULL);
1649
1650        if (sscanf (s, "%255s%n", directive, &n) < 1)
1651                return;
1652        s += n;
1653        while (isspace (*s)) ++s;
1654
1655        if (strcmp (directive, "prefix") == 0)
1656                IDL_ns_prefix (__IDL_root_ns, s);
1657        else if (strcmp (directive, "ID") == 0)
1658                IDL_ns_ID (__IDL_root_ns, s);
1659        else if (strcmp (directive, "version") == 0)
1660                IDL_ns_version (__IDL_root_ns, s);
1661        else if (strcmp (directive, "inhibit") == 0)
1662                IDL_inhibit (__IDL_root_ns, s);
1663}
1664
1665static IDL_declspec_t IDL_parse_declspec (const char *strspec)
1666{
1667        IDL_declspec_t flags = IDLF_DECLSPEC_EXIST;
1668
1669        if (strspec == NULL)
1670                return flags;
1671
1672        if (strcmp (strspec, "inhibit") == 0)
1673                flags |= IDLF_DECLSPEC_INHIBIT;
1674        else if (__IDL_is_parsing)
1675                yywarningv (IDL_WARNING1, "Ignoring unknown declspec `%s'", strspec);
1676
1677        return flags;
1678}
1679
1680void IDL_file_set (const char *filename, int line)
1681{
1682        IDL_fileinfo *fi;
1683        char *orig;
1684
1685        g_return_if_fail (__IDL_is_parsing);
1686
1687        if (filename) {
1688                __IDL_cur_filename = g_strdup (filename);
1689
1690                if (
1691#ifdef HAVE_CPP_PIPE_STDIN
1692                        !strlen (__IDL_cur_filename)
1693#else
1694                        __IDL_tmp_filename &&
1695                        !strcmp (__IDL_cur_filename, __IDL_tmp_filename)
1696#endif
1697                        ) {
1698                        g_free (__IDL_cur_filename);
1699                        __IDL_cur_filename = g_strdup (__IDL_real_filename);
1700                        __IDL_flagsi &= ~IDLFP_IN_INCLUDES;
1701                } else
1702                        __IDL_flagsi |= IDLFP_IN_INCLUDES;
1703
1704                if (g_hash_table_lookup_extended (__IDL_filename_hash, __IDL_cur_filename,
1705                                                  (gpointer) &orig, (gpointer) &fi)) {
1706                        g_free (__IDL_cur_filename);
1707                        __IDL_cur_filename = orig;
1708                        __IDL_cur_fileinfo = fi;
1709                } else {
1710                        fi = g_new0 (IDL_fileinfo, 1);
1711                        __IDL_cur_fileinfo = fi;
1712                        g_hash_table_insert (__IDL_filename_hash, __IDL_cur_filename, fi);
1713                }
1714        }
1715
1716        if (__IDL_cur_line > 0)
1717                __IDL_cur_line = line;
1718}
1719
1720void IDL_file_get (const char **filename, int *line)
1721{
1722        g_return_if_fail (__IDL_is_parsing);
1723
1724        if (filename)
1725                *filename = __IDL_cur_filename;
1726
1727        if (line)
1728                *line = __IDL_cur_line;
1729}
1730
1731static int do_token_error (IDL_tree p, const char *message, gboolean prev)
1732{
1733        int dienow;
1734        char *what = NULL, *who = NULL;
1735
1736        assert (p != NULL);
1737
1738        dienow = IDL_tree_get_node_info (p, &what, &who);
1739
1740        assert (what != NULL);
1741       
1742        if (who && *who)
1743                IDL_tree_error (p, "%s %s `%s'", message, what, who);
1744        else
1745                IDL_tree_error (p, "%s %s", message, what);
1746       
1747        return dienow;
1748}
1749
1750static void illegal_context_type_error (IDL_tree p, const char *what)
1751{
1752        GString *s = g_string_new (NULL);
1753
1754        g_string_sprintf (s, "Illegal type `%%s' for %s", what);
1755        illegal_type_error (p, s->str);
1756        g_string_free (s, TRUE);
1757}
1758
1759static void illegal_type_error (IDL_tree p, const char *message)
1760{
1761        GString *s;
1762
1763        s = IDL_tree_to_IDL_string (p, NULL, IDLF_OUTPUT_NO_NEWLINES);
1764        yyerrorv (message, s->str);
1765        g_string_free (s, TRUE);
1766}
1767
1768static IDL_tree list_start (IDL_tree a, gboolean filter_null)
1769{
1770        IDL_tree p;
1771
1772        if (!a && filter_null)
1773                return NULL;
1774
1775        p = IDL_list_new (a);
1776
1777        return p;
1778}
1779
1780static IDL_tree list_chain (IDL_tree a, IDL_tree b, gboolean filter_null)
1781{
1782        IDL_tree p;
1783
1784        if (filter_null) {
1785                if (!b)
1786                        return a;
1787                if (!a)
1788                        return list_start (b, filter_null);
1789        }
1790
1791        p = IDL_list_new (b);
1792        a = IDL_list_concat (a, p);
1793
1794        return a;
1795}
1796
1797static IDL_tree zlist_chain (IDL_tree a, IDL_tree b, gboolean filter_null)
1798{
1799        if (a == NULL)
1800                return list_start (b, filter_null);
1801        else
1802                return list_chain (a, b, filter_null);
1803}
1804
1805static int IDL_binop_chktypes (enum IDL_binop op, IDL_tree a, IDL_tree b)
1806{
1807        if (IDL_NODE_TYPE (a) != IDLN_BINOP &&
1808            IDL_NODE_TYPE (b) != IDLN_BINOP &&
1809            IDL_NODE_TYPE (a) != IDLN_UNARYOP &&
1810            IDL_NODE_TYPE (b) != IDLN_UNARYOP &&
1811            IDL_NODE_TYPE (a) != IDL_NODE_TYPE (b)) {
1812                yyerror ("Invalid mix of types in constant expression");
1813                return -1;
1814        }
1815
1816        switch (op) {
1817        case IDL_BINOP_MULT:
1818        case IDL_BINOP_DIV:
1819        case IDL_BINOP_ADD:
1820        case IDL_BINOP_SUB:
1821                break;
1822
1823        case IDL_BINOP_MOD:
1824        case IDL_BINOP_SHR:
1825        case IDL_BINOP_SHL:
1826        case IDL_BINOP_AND:
1827        case IDL_BINOP_OR:
1828        case IDL_BINOP_XOR:
1829                if ((IDL_NODE_TYPE (a) != IDLN_INTEGER ||
1830                     IDL_NODE_TYPE (b) != IDLN_INTEGER) &&
1831                    !(IDL_NODE_TYPE (a) == IDLN_BINOP ||
1832                      IDL_NODE_TYPE (b) == IDLN_BINOP ||
1833                      IDL_NODE_TYPE (a) == IDLN_UNARYOP ||
1834                      IDL_NODE_TYPE (b) == IDLN_UNARYOP)) {
1835                        yyerror ("Invalid operation on non-integer value");
1836                        return -1;
1837                }
1838                break;
1839        }
1840
1841        return 0;
1842}
1843
1844static int IDL_unaryop_chktypes (enum IDL_unaryop op, IDL_tree a)
1845{
1846        switch (op) {
1847        case IDL_UNARYOP_PLUS:
1848        case IDL_UNARYOP_MINUS:
1849                break;
1850
1851        case IDL_UNARYOP_COMPLEMENT:
1852                if (IDL_NODE_TYPE (a) != IDLN_INTEGER &&
1853                    !(IDL_NODE_TYPE (a) == IDLN_BINOP ||
1854                      IDL_NODE_TYPE (a) == IDLN_UNARYOP)) {
1855                        yyerror ("Operand to complement must be integer");
1856                        return -1;
1857                }
1858                break;
1859        }
1860
1861        return 0;
1862}
1863
1864static IDL_tree IDL_binop_eval_integer (enum IDL_binop op, IDL_tree a, IDL_tree b)
1865{
1866        IDL_tree p = NULL;
1867
1868        assert (IDL_NODE_TYPE (a) == IDLN_INTEGER);
1869
1870        switch (op) {
1871        case IDL_BINOP_MULT:
1872                p = IDL_integer_new (IDL_INTEGER (a).value * IDL_INTEGER (b).value);
1873                break;
1874
1875        case IDL_BINOP_DIV:
1876                if (IDL_INTEGER (b).value == 0) {
1877                        yyerror ("Divide by zero in constant expression");
1878                        return NULL;
1879                }
1880                p = IDL_integer_new (IDL_INTEGER (a).value / IDL_INTEGER (b).value);
1881                break;
1882
1883        case IDL_BINOP_ADD:
1884                p = IDL_integer_new (IDL_INTEGER (a).value + IDL_INTEGER (b).value);
1885                break;
1886
1887        case IDL_BINOP_SUB:
1888                p = IDL_integer_new (IDL_INTEGER (a).value - IDL_INTEGER (b).value);
1889                break;
1890
1891        case IDL_BINOP_MOD:
1892                if (IDL_INTEGER (b).value == 0) {
1893                        yyerror ("Modulo by zero in constant expression");
1894                        return NULL;
1895                }
1896                p = IDL_integer_new (IDL_INTEGER (a).value % IDL_INTEGER (b).value);
1897                break;
1898
1899        case IDL_BINOP_SHR:
1900                p = IDL_integer_new (IDL_INTEGER (a).value >> IDL_INTEGER (b).value);
1901                break;
1902
1903        case IDL_BINOP_SHL:
1904                p = IDL_integer_new (IDL_INTEGER (a).value << IDL_INTEGER (b).value);
1905                break;
1906
1907        case IDL_BINOP_AND:
1908                p = IDL_integer_new (IDL_INTEGER (a).value & IDL_INTEGER (b).value);
1909                break;
1910
1911        case IDL_BINOP_OR:
1912                p = IDL_integer_new (IDL_INTEGER (a).value | IDL_INTEGER (b).value);
1913                break;
1914
1915        case IDL_BINOP_XOR:
1916                p = IDL_integer_new (IDL_INTEGER (a).value ^ IDL_INTEGER (b).value);
1917                break;
1918        }
1919
1920        return p;
1921}
1922
1923static IDL_tree IDL_binop_eval_float (enum IDL_binop op, IDL_tree a, IDL_tree b)
1924{
1925        IDL_tree p = NULL;
1926
1927        assert (IDL_NODE_TYPE (a) == IDLN_FLOAT);
1928
1929        switch (op) {
1930        case IDL_BINOP_MULT:
1931                p = IDL_float_new (IDL_FLOAT (a).value * IDL_FLOAT (b).value);
1932                break;
1933
1934        case IDL_BINOP_DIV:
1935                if (IDL_FLOAT (b).value == 0.0) {
1936                        yyerror ("Divide by zero in constant expression");
1937                        return NULL;
1938                }
1939                p = IDL_float_new (IDL_FLOAT (a).value / IDL_FLOAT (b).value);
1940                break;
1941
1942        case IDL_BINOP_ADD:
1943                p = IDL_float_new (IDL_FLOAT (a).value + IDL_FLOAT (b).value);
1944                break;
1945
1946        case IDL_BINOP_SUB:
1947                p = IDL_float_new (IDL_FLOAT (a).value - IDL_FLOAT (b).value);
1948                break;
1949
1950        default:
1951                break;
1952        }
1953
1954        return p;
1955}
1956
1957static IDL_tree IDL_binop_eval (enum IDL_binop op, IDL_tree a, IDL_tree b)
1958{
1959        assert (IDL_NODE_TYPE (a) == IDL_NODE_TYPE (b));
1960
1961        switch (IDL_NODE_TYPE (a)) {
1962        case IDLN_INTEGER: return IDL_binop_eval_integer (op, a, b);
1963        case IDLN_FLOAT: return IDL_binop_eval_float (op, a, b);
1964        default: return NULL;
1965        }
1966}
1967
1968static IDL_tree IDL_unaryop_eval_integer (enum IDL_unaryop op, IDL_tree a)
1969{
1970        IDL_tree p = NULL;
1971
1972        assert (IDL_NODE_TYPE (a) == IDLN_INTEGER);
1973
1974        switch (op) {
1975        case IDL_UNARYOP_PLUS:
1976                p = IDL_integer_new (IDL_INTEGER (a).value);
1977                break;
1978
1979        case IDL_UNARYOP_MINUS:
1980                p = IDL_integer_new (-IDL_INTEGER (a).value);
1981                break;
1982
1983        case IDL_UNARYOP_COMPLEMENT:
1984                p = IDL_integer_new (~IDL_INTEGER (a).value);
1985                break;
1986        }
1987       
1988        return p;
1989}
1990
1991static IDL_tree IDL_unaryop_eval_fixed (enum IDL_unaryop op, IDL_tree a)
1992{
1993        IDL_tree p = NULL;
1994
1995        assert (IDL_NODE_TYPE (a) == IDLN_FIXED);
1996
1997        switch (op) {
1998        case IDL_UNARYOP_PLUS:
1999                p = IDL_fixed_new (IDL_FIXED (a).value);
2000                break;
2001
2002        default:
2003                break;
2004        }
2005       
2006        return p;
2007}
2008
2009static IDL_tree IDL_unaryop_eval_float (enum IDL_unaryop op, IDL_tree a)
2010{
2011        IDL_tree p = NULL;
2012
2013        assert (IDL_NODE_TYPE (a) == IDLN_FLOAT);
2014
2015        switch (op) {
2016        case IDL_UNARYOP_PLUS:
2017                p = IDL_float_new (IDL_FLOAT (a).value);
2018                break;
2019
2020        case IDL_UNARYOP_MINUS:
2021                p = IDL_float_new (-IDL_FLOAT (a).value);
2022                break;
2023
2024        default:
2025                break;
2026        }
2027       
2028        return p;
2029}
2030
2031static IDL_tree IDL_unaryop_eval (enum IDL_unaryop op, IDL_tree a)
2032{
2033        switch (IDL_NODE_TYPE (a)) {
2034        case IDLN_INTEGER: return IDL_unaryop_eval_integer (op, a);
2035        case IDLN_FIXED: return IDL_unaryop_eval_fixed (op, a);
2036        case IDLN_FLOAT: return IDL_unaryop_eval_float (op, a);
2037        default: return NULL;
2038        }
2039}
2040
2041IDL_tree IDL_resolve_const_exp (IDL_tree p, IDL_tree_type type)
2042{
2043        gboolean resolved_value = FALSE, die = FALSE;
2044        gboolean wrong_type = FALSE;
2045
2046        while (!resolved_value && !die) {
2047                if (IDL_NODE_TYPE (p) == IDLN_IDENT) {
2048                        IDL_tree q = IDL_NODE_UP (p);
2049                       
2050                        assert (q != NULL);
2051                        if (IDL_NODE_UP (q) &&
2052                            IDL_NODE_TYPE (IDL_NODE_UP (q)) == IDLN_TYPE_ENUM) {
2053                                p = q;
2054                                die = TRUE;
2055                                break;
2056                        } else if (IDL_NODE_TYPE (q) != IDLN_CONST_DCL) {
2057                                p = q;
2058                                wrong_type = TRUE;
2059                                die = TRUE;
2060                        } else
2061                                p = IDL_CONST_DCL (q).const_exp;
2062                }
2063               
2064                if (p == NULL ||
2065                    IDL_NODE_TYPE (p) == IDLN_BINOP ||
2066                    IDL_NODE_TYPE (p) == IDLN_UNARYOP) {
2067                        die = TRUE;
2068                        continue;
2069                }
2070               
2071                resolved_value = IDL_NODE_IS_LITERAL (p);
2072        }
2073
2074        if (resolved_value &&
2075            type != IDLN_ANY &&
2076            IDL_NODE_TYPE (p) != type)
2077                wrong_type = TRUE;
2078       
2079        if (wrong_type) {
2080                yyerror ("Invalid type for constant");
2081                IDL_tree_error (p, "Previous resolved type declaration");
2082                return NULL;
2083        }
2084
2085        return resolved_value ? p : NULL;
2086}
2087
2088void IDL_queue_new_ident_comment (const char *str)
2089{
2090        g_return_if_fail (str != NULL);
2091
2092        __IDL_new_ident_comments = g_slist_append (__IDL_new_ident_comments, g_strdup (str));
2093}
2094
2095/*
2096 * Local variables:
2097 * mode: C
2098 * c-basic-offset: 8
2099 * tab-width: 8
2100 * indent-tabs-mode: t
2101 * End:
2102 */
Note: See TracBrowser for help on using the repository browser.