work on macro functions
[pspp] / src / language / lexer / macro.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2021 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifndef MACRO_H
18 #define MACRO_H 1
19
20 #include <stdbool.h>
21 #include <stddef.h>
22
23 #include "libpspp/hmap.h"
24 #include "libpspp/str.h"
25 #include "language/lexer/token.h"
26
27 struct macro_expander;
28
29 struct macro_token
30   {
31     struct token token;
32     struct substring representation;
33   };
34
35 void macro_token_copy (struct macro_token *, const struct macro_token *);
36 void macro_token_uninit (struct macro_token *);
37
38 struct macro_tokens
39   {
40     struct macro_token *mts;
41     size_t n;
42     size_t allocated;
43   };
44
45 void macro_tokens_copy (struct macro_tokens *, const struct macro_tokens *);
46 void macro_tokens_uninit (struct macro_tokens *);
47 struct macro_token *macro_tokens_add_uninit (struct macro_tokens *);
48 void macro_tokens_add (struct macro_tokens *, const struct macro_token *);
49
50 void macro_tokens_print (const struct macro_tokens *, FILE *);
51
52 struct macro_param
53   {
54     bool positional;            /* Is this a positional parameter? */
55     char *name;                 /* "!1" or "!name". */
56     struct macro_tokens def;    /* Default expansion. */
57     bool expand_arg;            /* Macro-expand the argument? */
58
59     enum
60       {
61         ARG_N_TOKENS,
62         ARG_CHAREND,
63         ARG_ENCLOSE,
64         ARG_CMDEND
65       }
66     arg_type;
67     union
68       {
69         int n_tokens;
70         struct token charend;
71         struct token enclose[2];
72       };
73   };
74
75 struct macro
76   {
77     struct hmap_node hmap_node; /* Indexed by 'name'. */
78     char *name;
79
80     struct macro_param *params;
81     size_t n_params;
82
83     struct macro_tokens body;
84   };
85
86 void macro_destroy (struct macro *);
87
88 struct macro_set
89   {
90     struct hmap macros;
91   };
92
93 struct macro_set *macro_set_create (void);
94 void macro_set_destroy (struct macro_set *);
95 const struct macro *macro_set_find (const struct macro_set *,
96                                     const char *);
97 void macro_set_add (struct macro_set *, struct macro *);
98
99 static inline bool
100 macro_set_is_empty (const struct macro_set *set)
101 {
102   return hmap_is_empty (&set->macros);
103 }
104 \f
105 /* Macro expansion. */
106
107 int macro_expander_create (const struct macro_set *,
108                            const struct token *,
109                            struct macro_expander **);
110 void macro_expander_destroy (struct macro_expander *);
111
112 int macro_expander_add (struct macro_expander *, const struct macro_token *);
113
114 void macro_expander_get_expansion (struct macro_expander *, struct macro_tokens *);
115
116 #endif /* macro.h */