xref: /openbsd-src/gnu/usr.bin/binutils/gdb/p-lang.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Pascal language support routines for GDB, the GNU debugger.
2b725ae77Skettenis    Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
3b725ae77Skettenis 
4b725ae77Skettenis    This file is part of GDB.
5b725ae77Skettenis 
6b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
7b725ae77Skettenis    it under the terms of the GNU General Public License as published by
8b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
9b725ae77Skettenis    (at your option) any later version.
10b725ae77Skettenis 
11b725ae77Skettenis    This program is distributed in the hope that it will be useful,
12b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
13b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14b725ae77Skettenis    GNU General Public License for more details.
15b725ae77Skettenis 
16b725ae77Skettenis    You should have received a copy of the GNU General Public License
17b725ae77Skettenis    along with this program; if not, write to the Free Software
18b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19b725ae77Skettenis 
20b725ae77Skettenis /* This file is derived from c-lang.c */
21b725ae77Skettenis 
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "gdb_string.h"
24b725ae77Skettenis #include "symtab.h"
25b725ae77Skettenis #include "gdbtypes.h"
26b725ae77Skettenis #include "expression.h"
27b725ae77Skettenis #include "parser-defs.h"
28b725ae77Skettenis #include "language.h"
29b725ae77Skettenis #include "p-lang.h"
30b725ae77Skettenis #include "valprint.h"
31b725ae77Skettenis #include "value.h"
32b725ae77Skettenis #include <ctype.h>
33b725ae77Skettenis 
34b725ae77Skettenis extern void _initialize_pascal_language (void);
35b725ae77Skettenis 
36b725ae77Skettenis 
37b725ae77Skettenis /* Determines if type TYPE is a pascal string type.
38b725ae77Skettenis    Returns 1 if the type is a known pascal type
39b725ae77Skettenis    This function is used by p-valprint.c code to allow better string display.
40b725ae77Skettenis    If it is a pascal string type, then it also sets info needed
41b725ae77Skettenis    to get the length and the data of the string
42b725ae77Skettenis    length_pos, length_size and string_pos are given in bytes.
43b725ae77Skettenis    char_size gives the element size in bytes.
44b725ae77Skettenis    FIXME: if the position or the size of these fields
45b725ae77Skettenis    are not multiple of TARGET_CHAR_BIT then the results are wrong
46b725ae77Skettenis    but this does not happen for Free Pascal nor for GPC.  */
47b725ae77Skettenis int
is_pascal_string_type(struct type * type,int * length_pos,int * length_size,int * string_pos,int * char_size,char ** arrayname)48b725ae77Skettenis is_pascal_string_type (struct type *type,int *length_pos,
49b725ae77Skettenis                        int *length_size, int *string_pos, int *char_size,
50b725ae77Skettenis 		       char **arrayname)
51b725ae77Skettenis {
52b725ae77Skettenis   if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
53b725ae77Skettenis     {
54b725ae77Skettenis       /* Old Borland type pascal strings from Free Pascal Compiler.  */
55b725ae77Skettenis       /* Two fields: length and st.  */
56b725ae77Skettenis       if (TYPE_NFIELDS (type) == 2
57b725ae77Skettenis           && strcmp (TYPE_FIELDS (type)[0].name, "length") == 0
58b725ae77Skettenis           && strcmp (TYPE_FIELDS (type)[1].name, "st") == 0)
59b725ae77Skettenis         {
60b725ae77Skettenis           if (length_pos)
61b725ae77Skettenis 	    *length_pos = TYPE_FIELD_BITPOS (type, 0) / TARGET_CHAR_BIT;
62b725ae77Skettenis           if (length_size)
63b725ae77Skettenis 	    *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0));
64b725ae77Skettenis           if (string_pos)
65b725ae77Skettenis 	    *string_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT;
66b725ae77Skettenis           if (char_size)
67b725ae77Skettenis 	    *char_size = 1;
68b725ae77Skettenis  	  if (arrayname)
69b725ae77Skettenis 	    *arrayname = TYPE_FIELDS (type)[1].name;
70b725ae77Skettenis          return 2;
71b725ae77Skettenis         };
72b725ae77Skettenis       /* GNU pascal strings.  */
73b725ae77Skettenis       /* Three fields: Capacity, length and schema$ or _p_schema.  */
74b725ae77Skettenis       if (TYPE_NFIELDS (type) == 3
75b725ae77Skettenis           && strcmp (TYPE_FIELDS (type)[0].name, "Capacity") == 0
76b725ae77Skettenis           && strcmp (TYPE_FIELDS (type)[1].name, "length") == 0)
77b725ae77Skettenis         {
78b725ae77Skettenis           if (length_pos)
79b725ae77Skettenis 	    *length_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT;
80b725ae77Skettenis           if (length_size)
81b725ae77Skettenis 	    *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 1));
82b725ae77Skettenis           if (string_pos)
83b725ae77Skettenis 	    *string_pos = TYPE_FIELD_BITPOS (type, 2) / TARGET_CHAR_BIT;
84b725ae77Skettenis           /* FIXME: how can I detect wide chars in GPC ?? */
85b725ae77Skettenis           if (char_size)
86b725ae77Skettenis 	    *char_size = 1;
87b725ae77Skettenis  	  if (arrayname)
88b725ae77Skettenis 	    *arrayname = TYPE_FIELDS (type)[2].name;
89b725ae77Skettenis          return 3;
90b725ae77Skettenis         };
91b725ae77Skettenis     }
92b725ae77Skettenis   return 0;
93b725ae77Skettenis }
94b725ae77Skettenis 
95b725ae77Skettenis static void pascal_one_char (int, struct ui_file *, int *);
96b725ae77Skettenis 
97b725ae77Skettenis /* Print the character C on STREAM as part of the contents of a literal
98b725ae77Skettenis    string.
99b725ae77Skettenis    In_quotes is reset to 0 if a char is written with #4 notation */
100b725ae77Skettenis 
101b725ae77Skettenis static void
pascal_one_char(int c,struct ui_file * stream,int * in_quotes)102b725ae77Skettenis pascal_one_char (int c, struct ui_file *stream, int *in_quotes)
103b725ae77Skettenis {
104b725ae77Skettenis 
105b725ae77Skettenis   c &= 0xFF;			/* Avoid sign bit follies */
106b725ae77Skettenis 
107b725ae77Skettenis   if ((c == '\'') || (PRINT_LITERAL_FORM (c)))
108b725ae77Skettenis     {
109b725ae77Skettenis       if (!(*in_quotes))
110b725ae77Skettenis 	fputs_filtered ("'", stream);
111b725ae77Skettenis       *in_quotes = 1;
112b725ae77Skettenis       if (c == '\'')
113b725ae77Skettenis 	{
114b725ae77Skettenis 	  fputs_filtered ("''", stream);
115b725ae77Skettenis 	}
116b725ae77Skettenis       else
117b725ae77Skettenis 	fprintf_filtered (stream, "%c", c);
118b725ae77Skettenis     }
119b725ae77Skettenis   else
120b725ae77Skettenis     {
121b725ae77Skettenis       if (*in_quotes)
122b725ae77Skettenis 	fputs_filtered ("'", stream);
123b725ae77Skettenis       *in_quotes = 0;
124b725ae77Skettenis       fprintf_filtered (stream, "#%d", (unsigned int) c);
125b725ae77Skettenis     }
126b725ae77Skettenis }
127b725ae77Skettenis 
128b725ae77Skettenis static void pascal_emit_char (int c, struct ui_file *stream, int quoter);
129b725ae77Skettenis 
130b725ae77Skettenis /* Print the character C on STREAM as part of the contents of a literal
131b725ae77Skettenis    string whose delimiter is QUOTER.  Note that that format for printing
132b725ae77Skettenis    characters and strings is language specific. */
133b725ae77Skettenis 
134b725ae77Skettenis static void
pascal_emit_char(int c,struct ui_file * stream,int quoter)135b725ae77Skettenis pascal_emit_char (int c, struct ui_file *stream, int quoter)
136b725ae77Skettenis {
137b725ae77Skettenis   int in_quotes = 0;
138b725ae77Skettenis   pascal_one_char (c, stream, &in_quotes);
139b725ae77Skettenis   if (in_quotes)
140b725ae77Skettenis     fputs_filtered ("'", stream);
141b725ae77Skettenis }
142b725ae77Skettenis 
143b725ae77Skettenis void
pascal_printchar(int c,struct ui_file * stream)144b725ae77Skettenis pascal_printchar (int c, struct ui_file *stream)
145b725ae77Skettenis {
146b725ae77Skettenis   int in_quotes = 0;
147b725ae77Skettenis   pascal_one_char (c, stream, &in_quotes);
148b725ae77Skettenis   if (in_quotes)
149b725ae77Skettenis     fputs_filtered ("'", stream);
150b725ae77Skettenis }
151b725ae77Skettenis 
152b725ae77Skettenis /* Print the character string STRING, printing at most LENGTH characters.
153b725ae77Skettenis    Printing stops early if the number hits print_max; repeat counts
154b725ae77Skettenis    are printed as appropriate.  Print ellipses at the end if we
155b725ae77Skettenis    had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.  */
156b725ae77Skettenis 
157b725ae77Skettenis void
pascal_printstr(struct ui_file * stream,char * string,unsigned int length,int width,int force_ellipses)158b725ae77Skettenis pascal_printstr (struct ui_file *stream, char *string, unsigned int length,
159b725ae77Skettenis 		 int width, int force_ellipses)
160b725ae77Skettenis {
161b725ae77Skettenis   unsigned int i;
162b725ae77Skettenis   unsigned int things_printed = 0;
163b725ae77Skettenis   int in_quotes = 0;
164b725ae77Skettenis   int need_comma = 0;
165b725ae77Skettenis 
166b725ae77Skettenis   /* If the string was not truncated due to `set print elements', and
167b725ae77Skettenis      the last byte of it is a null, we don't print that, in traditional C
168b725ae77Skettenis      style.  */
169b725ae77Skettenis   if ((!force_ellipses) && length > 0 && string[length - 1] == '\0')
170b725ae77Skettenis     length--;
171b725ae77Skettenis 
172b725ae77Skettenis   if (length == 0)
173b725ae77Skettenis     {
174b725ae77Skettenis       fputs_filtered ("''", stream);
175b725ae77Skettenis       return;
176b725ae77Skettenis     }
177b725ae77Skettenis 
178b725ae77Skettenis   for (i = 0; i < length && things_printed < print_max; ++i)
179b725ae77Skettenis     {
180b725ae77Skettenis       /* Position of the character we are examining
181b725ae77Skettenis          to see whether it is repeated.  */
182b725ae77Skettenis       unsigned int rep1;
183b725ae77Skettenis       /* Number of repetitions we have detected so far.  */
184b725ae77Skettenis       unsigned int reps;
185b725ae77Skettenis 
186b725ae77Skettenis       QUIT;
187b725ae77Skettenis 
188b725ae77Skettenis       if (need_comma)
189b725ae77Skettenis 	{
190b725ae77Skettenis 	  fputs_filtered (", ", stream);
191b725ae77Skettenis 	  need_comma = 0;
192b725ae77Skettenis 	}
193b725ae77Skettenis 
194b725ae77Skettenis       rep1 = i + 1;
195b725ae77Skettenis       reps = 1;
196b725ae77Skettenis       while (rep1 < length && string[rep1] == string[i])
197b725ae77Skettenis 	{
198b725ae77Skettenis 	  ++rep1;
199b725ae77Skettenis 	  ++reps;
200b725ae77Skettenis 	}
201b725ae77Skettenis 
202b725ae77Skettenis       if (reps > repeat_count_threshold)
203b725ae77Skettenis 	{
204b725ae77Skettenis 	  if (in_quotes)
205b725ae77Skettenis 	    {
206b725ae77Skettenis 	      if (inspect_it)
207b725ae77Skettenis 		fputs_filtered ("\\', ", stream);
208b725ae77Skettenis 	      else
209b725ae77Skettenis 		fputs_filtered ("', ", stream);
210b725ae77Skettenis 	      in_quotes = 0;
211b725ae77Skettenis 	    }
212b725ae77Skettenis 	  pascal_printchar (string[i], stream);
213b725ae77Skettenis 	  fprintf_filtered (stream, " <repeats %u times>", reps);
214b725ae77Skettenis 	  i = rep1 - 1;
215b725ae77Skettenis 	  things_printed += repeat_count_threshold;
216b725ae77Skettenis 	  need_comma = 1;
217b725ae77Skettenis 	}
218b725ae77Skettenis       else
219b725ae77Skettenis 	{
220b725ae77Skettenis 	  int c = string[i];
221b725ae77Skettenis 	  if ((!in_quotes) && (PRINT_LITERAL_FORM (c)))
222b725ae77Skettenis 	    {
223b725ae77Skettenis 	      if (inspect_it)
224b725ae77Skettenis 		fputs_filtered ("\\'", stream);
225b725ae77Skettenis 	      else
226b725ae77Skettenis 		fputs_filtered ("'", stream);
227b725ae77Skettenis 	      in_quotes = 1;
228b725ae77Skettenis 	    }
229b725ae77Skettenis 	  pascal_one_char (c, stream, &in_quotes);
230b725ae77Skettenis 	  ++things_printed;
231b725ae77Skettenis 	}
232b725ae77Skettenis     }
233b725ae77Skettenis 
234b725ae77Skettenis   /* Terminate the quotes if necessary.  */
235b725ae77Skettenis   if (in_quotes)
236b725ae77Skettenis     {
237b725ae77Skettenis       if (inspect_it)
238b725ae77Skettenis 	fputs_filtered ("\\'", stream);
239b725ae77Skettenis       else
240b725ae77Skettenis 	fputs_filtered ("'", stream);
241b725ae77Skettenis     }
242b725ae77Skettenis 
243b725ae77Skettenis   if (force_ellipses || i < length)
244b725ae77Skettenis     fputs_filtered ("...", stream);
245b725ae77Skettenis }
246b725ae77Skettenis 
247b725ae77Skettenis /* Create a fundamental Pascal type using default reasonable for the current
248b725ae77Skettenis    target machine.
249b725ae77Skettenis 
250b725ae77Skettenis    Some object/debugging file formats (DWARF version 1, COFF, etc) do not
251b725ae77Skettenis    define fundamental types such as "int" or "double".  Others (stabs or
252b725ae77Skettenis    DWARF version 2, etc) do define fundamental types.  For the formats which
253b725ae77Skettenis    don't provide fundamental types, gdb can create such types using this
254b725ae77Skettenis    function.
255b725ae77Skettenis 
256b725ae77Skettenis    FIXME:  Some compilers distinguish explicitly signed integral types
257b725ae77Skettenis    (signed short, signed int, signed long) from "regular" integral types
258b725ae77Skettenis    (short, int, long) in the debugging information.  There is some dis-
259b725ae77Skettenis    agreement as to how useful this feature is.  In particular, gcc does
260b725ae77Skettenis    not support this.  Also, only some debugging formats allow the
261b725ae77Skettenis    distinction to be passed on to a debugger.  For now, we always just
262b725ae77Skettenis    use "short", "int", or "long" as the type name, for both the implicit
263b725ae77Skettenis    and explicitly signed types.  This also makes life easier for the
264b725ae77Skettenis    gdb test suite since we don't have to account for the differences
265b725ae77Skettenis    in output depending upon what the compiler and debugging format
266b725ae77Skettenis    support.  We will probably have to re-examine the issue when gdb
267b725ae77Skettenis    starts taking it's fundamental type information directly from the
268b725ae77Skettenis    debugging information supplied by the compiler.  fnf@cygnus.com */
269b725ae77Skettenis 
270b725ae77Skettenis /* Note there might be some discussion about the choosen correspondance
271b725ae77Skettenis    because it mainly reflects Free Pascal Compiler setup for now PM */
272b725ae77Skettenis 
273b725ae77Skettenis 
274b725ae77Skettenis struct type *
pascal_create_fundamental_type(struct objfile * objfile,int typeid)275b725ae77Skettenis pascal_create_fundamental_type (struct objfile *objfile, int typeid)
276b725ae77Skettenis {
277b725ae77Skettenis   struct type *type = NULL;
278b725ae77Skettenis 
279b725ae77Skettenis   switch (typeid)
280b725ae77Skettenis     {
281b725ae77Skettenis     default:
282b725ae77Skettenis       /* FIXME:  For now, if we are asked to produce a type not in this
283b725ae77Skettenis          language, create the equivalent of a C integer type with the
284b725ae77Skettenis          name "<?type?>".  When all the dust settles from the type
285b725ae77Skettenis          reconstruction work, this should probably become an error. */
286b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
287b725ae77Skettenis 			TARGET_INT_BIT / TARGET_CHAR_BIT,
288b725ae77Skettenis 			0, "<?type?>", objfile);
289b725ae77Skettenis       warning ("internal error: no Pascal fundamental type %d", typeid);
290b725ae77Skettenis       break;
291b725ae77Skettenis     case FT_VOID:
292b725ae77Skettenis       type = init_type (TYPE_CODE_VOID,
293b725ae77Skettenis 			TARGET_CHAR_BIT / TARGET_CHAR_BIT,
294b725ae77Skettenis 			0, "void", objfile);
295b725ae77Skettenis       break;
296b725ae77Skettenis     case FT_CHAR:
297b725ae77Skettenis       type = init_type (TYPE_CODE_CHAR,
298b725ae77Skettenis 			TARGET_CHAR_BIT / TARGET_CHAR_BIT,
299b725ae77Skettenis 			0, "char", objfile);
300b725ae77Skettenis       break;
301b725ae77Skettenis     case FT_SIGNED_CHAR:
302b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
303b725ae77Skettenis 			TARGET_CHAR_BIT / TARGET_CHAR_BIT,
304b725ae77Skettenis 			0, "shortint", objfile);
305b725ae77Skettenis       break;
306b725ae77Skettenis     case FT_UNSIGNED_CHAR:
307b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
308b725ae77Skettenis 			TARGET_CHAR_BIT / TARGET_CHAR_BIT,
309b725ae77Skettenis 			TYPE_FLAG_UNSIGNED, "byte", objfile);
310b725ae77Skettenis       break;
311b725ae77Skettenis     case FT_SHORT:
312b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
313b725ae77Skettenis 			TARGET_SHORT_BIT / TARGET_CHAR_BIT,
314b725ae77Skettenis 			0, "integer", objfile);
315b725ae77Skettenis       break;
316b725ae77Skettenis     case FT_SIGNED_SHORT:
317b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
318b725ae77Skettenis 			TARGET_SHORT_BIT / TARGET_CHAR_BIT,
319b725ae77Skettenis 			0, "integer", objfile);		/* FIXME-fnf */
320b725ae77Skettenis       break;
321b725ae77Skettenis     case FT_UNSIGNED_SHORT:
322b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
323b725ae77Skettenis 			TARGET_SHORT_BIT / TARGET_CHAR_BIT,
324b725ae77Skettenis 			TYPE_FLAG_UNSIGNED, "word", objfile);
325b725ae77Skettenis       break;
326b725ae77Skettenis     case FT_INTEGER:
327b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
328b725ae77Skettenis 			TARGET_INT_BIT / TARGET_CHAR_BIT,
329b725ae77Skettenis 			0, "longint", objfile);
330b725ae77Skettenis       break;
331b725ae77Skettenis     case FT_SIGNED_INTEGER:
332b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
333b725ae77Skettenis 			TARGET_INT_BIT / TARGET_CHAR_BIT,
334b725ae77Skettenis 			0, "longint", objfile);		/* FIXME -fnf */
335b725ae77Skettenis       break;
336b725ae77Skettenis     case FT_UNSIGNED_INTEGER:
337b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
338b725ae77Skettenis 			TARGET_INT_BIT / TARGET_CHAR_BIT,
339b725ae77Skettenis 			TYPE_FLAG_UNSIGNED, "cardinal", objfile);
340b725ae77Skettenis       break;
341b725ae77Skettenis     case FT_LONG:
342b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
343b725ae77Skettenis 			TARGET_LONG_BIT / TARGET_CHAR_BIT,
344b725ae77Skettenis 			0, "long", objfile);
345b725ae77Skettenis       break;
346b725ae77Skettenis     case FT_SIGNED_LONG:
347b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
348b725ae77Skettenis 			TARGET_LONG_BIT / TARGET_CHAR_BIT,
349b725ae77Skettenis 			0, "long", objfile);	/* FIXME -fnf */
350b725ae77Skettenis       break;
351b725ae77Skettenis     case FT_UNSIGNED_LONG:
352b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
353b725ae77Skettenis 			TARGET_LONG_BIT / TARGET_CHAR_BIT,
354b725ae77Skettenis 			TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
355b725ae77Skettenis       break;
356b725ae77Skettenis     case FT_LONG_LONG:
357b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
358b725ae77Skettenis 			TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
359b725ae77Skettenis 			0, "long long", objfile);
360b725ae77Skettenis       break;
361b725ae77Skettenis     case FT_SIGNED_LONG_LONG:
362b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
363b725ae77Skettenis 			TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
364b725ae77Skettenis 			0, "signed long long", objfile);
365b725ae77Skettenis       break;
366b725ae77Skettenis     case FT_UNSIGNED_LONG_LONG:
367b725ae77Skettenis       type = init_type (TYPE_CODE_INT,
368b725ae77Skettenis 			TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
369b725ae77Skettenis 			TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
370b725ae77Skettenis       break;
371b725ae77Skettenis     case FT_FLOAT:
372b725ae77Skettenis       type = init_type (TYPE_CODE_FLT,
373b725ae77Skettenis 			TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
374b725ae77Skettenis 			0, "float", objfile);
375b725ae77Skettenis       break;
376b725ae77Skettenis     case FT_DBL_PREC_FLOAT:
377b725ae77Skettenis       type = init_type (TYPE_CODE_FLT,
378b725ae77Skettenis 			TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
379b725ae77Skettenis 			0, "double", objfile);
380b725ae77Skettenis       break;
381b725ae77Skettenis     case FT_EXT_PREC_FLOAT:
382b725ae77Skettenis       type = init_type (TYPE_CODE_FLT,
383b725ae77Skettenis 			TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
384b725ae77Skettenis 			0, "extended", objfile);
385b725ae77Skettenis       break;
386b725ae77Skettenis     }
387b725ae77Skettenis   return (type);
388b725ae77Skettenis }
389b725ae77Skettenis 
390b725ae77Skettenis 
391b725ae77Skettenis /* Table mapping opcodes into strings for printing operators
392b725ae77Skettenis    and precedences of the operators.  */
393b725ae77Skettenis 
394b725ae77Skettenis const struct op_print pascal_op_print_tab[] =
395b725ae77Skettenis {
396b725ae77Skettenis   {",", BINOP_COMMA, PREC_COMMA, 0},
397b725ae77Skettenis   {":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
398b725ae77Skettenis   {"or", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
399b725ae77Skettenis   {"xor", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
400b725ae77Skettenis   {"and", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
401b725ae77Skettenis   {"=", BINOP_EQUAL, PREC_EQUAL, 0},
402b725ae77Skettenis   {"<>", BINOP_NOTEQUAL, PREC_EQUAL, 0},
403b725ae77Skettenis   {"<=", BINOP_LEQ, PREC_ORDER, 0},
404b725ae77Skettenis   {">=", BINOP_GEQ, PREC_ORDER, 0},
405b725ae77Skettenis   {">", BINOP_GTR, PREC_ORDER, 0},
406b725ae77Skettenis   {"<", BINOP_LESS, PREC_ORDER, 0},
407b725ae77Skettenis   {"shr", BINOP_RSH, PREC_SHIFT, 0},
408b725ae77Skettenis   {"shl", BINOP_LSH, PREC_SHIFT, 0},
409b725ae77Skettenis   {"+", BINOP_ADD, PREC_ADD, 0},
410b725ae77Skettenis   {"-", BINOP_SUB, PREC_ADD, 0},
411b725ae77Skettenis   {"*", BINOP_MUL, PREC_MUL, 0},
412b725ae77Skettenis   {"/", BINOP_DIV, PREC_MUL, 0},
413b725ae77Skettenis   {"div", BINOP_INTDIV, PREC_MUL, 0},
414b725ae77Skettenis   {"mod", BINOP_REM, PREC_MUL, 0},
415b725ae77Skettenis   {"@", BINOP_REPEAT, PREC_REPEAT, 0},
416b725ae77Skettenis   {"-", UNOP_NEG, PREC_PREFIX, 0},
417b725ae77Skettenis   {"not", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
418b725ae77Skettenis   {"^", UNOP_IND, PREC_SUFFIX, 1},
419b725ae77Skettenis   {"@", UNOP_ADDR, PREC_PREFIX, 0},
420b725ae77Skettenis   {"sizeof", UNOP_SIZEOF, PREC_PREFIX, 0},
421b725ae77Skettenis   {NULL, 0, 0, 0}
422b725ae77Skettenis };
423b725ae77Skettenis 
424b725ae77Skettenis struct type **const (pascal_builtin_types[]) =
425b725ae77Skettenis {
426b725ae77Skettenis   &builtin_type_int,
427b725ae77Skettenis     &builtin_type_long,
428b725ae77Skettenis     &builtin_type_short,
429b725ae77Skettenis     &builtin_type_char,
430b725ae77Skettenis     &builtin_type_float,
431b725ae77Skettenis     &builtin_type_double,
432b725ae77Skettenis     &builtin_type_void,
433b725ae77Skettenis     &builtin_type_long_long,
434b725ae77Skettenis     &builtin_type_signed_char,
435b725ae77Skettenis     &builtin_type_unsigned_char,
436b725ae77Skettenis     &builtin_type_unsigned_short,
437b725ae77Skettenis     &builtin_type_unsigned_int,
438b725ae77Skettenis     &builtin_type_unsigned_long,
439b725ae77Skettenis     &builtin_type_unsigned_long_long,
440b725ae77Skettenis     &builtin_type_long_double,
441b725ae77Skettenis     &builtin_type_complex,
442b725ae77Skettenis     &builtin_type_double_complex,
443b725ae77Skettenis     0
444b725ae77Skettenis };
445b725ae77Skettenis 
446b725ae77Skettenis const struct language_defn pascal_language_defn =
447b725ae77Skettenis {
448b725ae77Skettenis   "pascal",			/* Language name */
449b725ae77Skettenis   language_pascal,
450b725ae77Skettenis   pascal_builtin_types,
451b725ae77Skettenis   range_check_on,
452b725ae77Skettenis   type_check_on,
453b725ae77Skettenis   case_sensitive_on,
454*11efff7fSkettenis   array_row_major,
455b725ae77Skettenis   &exp_descriptor_standard,
456b725ae77Skettenis   pascal_parse,
457b725ae77Skettenis   pascal_error,
458*11efff7fSkettenis   null_post_parser,
459b725ae77Skettenis   pascal_printchar,		/* Print a character constant */
460b725ae77Skettenis   pascal_printstr,		/* Function to print string constant */
461b725ae77Skettenis   pascal_emit_char,		/* Print a single char */
462b725ae77Skettenis   pascal_create_fundamental_type,	/* Create fundamental type in this language */
463b725ae77Skettenis   pascal_print_type,		/* Print a type using appropriate syntax */
464b725ae77Skettenis   pascal_val_print,		/* Print a value using appropriate syntax */
465b725ae77Skettenis   pascal_value_print,		/* Print a top-level value */
466b725ae77Skettenis   NULL,				/* Language specific skip_trampoline */
467b725ae77Skettenis   value_of_this,		/* value_of_this */
468b725ae77Skettenis   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
469b725ae77Skettenis   basic_lookup_transparent_type,/* lookup_transparent_type */
470b725ae77Skettenis   NULL,				/* Language specific symbol demangler */
471*11efff7fSkettenis   NULL,				/* Language specific class_name_from_physname */
472b725ae77Skettenis   pascal_op_print_tab,		/* expression operators for printing */
473b725ae77Skettenis   1,				/* c-style arrays */
474b725ae77Skettenis   0,				/* String lower bound */
475b725ae77Skettenis   &builtin_type_char,		/* Type of string elements */
476b725ae77Skettenis   default_word_break_characters,
477*11efff7fSkettenis   NULL, /* FIXME: la_language_arch_info.  */
478b725ae77Skettenis   LANG_MAGIC
479b725ae77Skettenis };
480b725ae77Skettenis 
481b725ae77Skettenis void
_initialize_pascal_language(void)482b725ae77Skettenis _initialize_pascal_language (void)
483b725ae77Skettenis {
484b725ae77Skettenis   add_language (&pascal_language_defn);
485b725ae77Skettenis }
486