1#!/usr/bin/perl -w
2#
3# Regenerate (overwriting only if changed):
4#
5#    keywords.h keywords.c
6#
7# from information stored in the DATA section of this file.
8#
9# Accepts the standard regen_lib -q and -v args.
10
11use strict;
12use Devel::Tokenizer::C 0.05;
13
14require './regen/regen_lib.pl';
15
16my $h = open_new('keywords.h', '>',
17                 { by => 'regen/keywords.pl', from => 'its data',
18                   file => 'keywords.h', style => '*',
19                   copyright => [1994 .. 1997, 1999 .. 2002, 2005 .. 2007]});
20my $c = open_new('keywords.c', '>',
21                 { by => 'regen/keywords.pl', from => 'its data', style => '*'});
22
23my %by_strength;
24
25my $keynum = 0;
26while (<DATA>) {
27    chop;
28    next unless $_;
29    next if /^#/;
30    my ($strength, $keyword) = /^([- +])([A-Z_a-z2]+)/;
31    die "Bad line '$_'" unless defined $strength;
32    print $h tab(5, "#define KEY_$keyword"), $keynum++, "\n";
33    push @{$by_strength{$strength}}, $keyword;
34}
35
36# If this hash changes, make sure the equivalent hash in
37# lib/B/Deparse.pm (%feature_keywords) is also updated.
38my %feature_kw = (
39    state     => 'state',
40    say       => 'say',
41    given     => 'switch',
42    when      => 'switch',
43    default   => 'switch',
44    # continue is already a keyword
45    break     => 'switch',
46    evalbytes => 'evalbytes',
47    __SUB__   => '__SUB__',
48    fc        => 'fc',
49    isa       => 'isa',
50    try       => 'try',
51    catch     => 'try',
52    finally   => 'try',
53    defer     => 'defer',
54    class     => 'class',
55    field     => 'class',
56    method    => 'class',
57    ADJUST    => 'class',
58    __CLASS__ => 'class',
59);
60
61my %pos = map { ($_ => 1) } @{$by_strength{'+'}};
62
63my $t = Devel::Tokenizer::C->new(TokenFunc     => \&perl_keyword,
64                                 TokenString   => 'name',
65                                 StringLength  => 'len',
66                                 MergeSwitches => 1,
67                                );
68
69$t->add_tokens(@{$by_strength{'+'}}, @{$by_strength{'-'}}, 'elseif');
70
71my $switch = $t->generate(Indent => '  ');
72
73print $c <<"END";
74#include "EXTERN.h"
75#define PERL_IN_KEYWORDS_C
76#include "perl.h"
77#include "keywords.h"
78#include "feature.h"
79
80I32
81Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords)
82{
83  PERL_ARGS_ASSERT_KEYWORD;
84
85$switch
86unknown:
87  return 0;
88}
89END
90
91sub perl_keyword
92{
93  my $k = shift;
94  my $sign = $pos{$k} ? '' : '-';
95
96  if ($k eq 'elseif') {
97    return <<END;
98Perl_ck_warner_d(aTHX_ packWARN(WARN_SYNTAX), "elseif should be elsif");
99END
100  }
101  elsif (my $feature = $feature_kw{$k}) {
102    $feature =~ s/([\\"])/\\$1/g;
103    return <<END;
104return (all_keywords || FEATURE_\U$feature\E_IS_ENABLED ? ${sign}KEY_$k : 0);
105END
106  }
107  return <<END;
108return ${sign}KEY_$k;
109END
110}
111
112read_only_bottom_close_and_rename($_, [$0]) foreach $c, $h;
113
114
115# coresub_op in op.c expects __FILE__, __LINE__ and __PACKAGE__ to be the
116# first three.
117
118__END__
119
120 NULL
121-__FILE__
122-__LINE__
123-__PACKAGE__
124-__CLASS__
125+__DATA__
126+__END__
127-__SUB__
128+ADJUST
129+AUTOLOAD
130+BEGIN
131+UNITCHECK
132+DESTROY
133+END
134+INIT
135+CHECK
136-abs
137-accept
138-alarm
139-and
140-atan2
141-bind
142-binmode
143-bless
144-break
145-caller
146+catch
147-chdir
148-chmod
149-chomp
150-chop
151-chown
152-chr
153-chroot
154-class
155-close
156-closedir
157-cmp
158-connect
159-continue
160-cos
161-crypt
162-dbmclose
163-dbmopen
164+default
165+defer
166+defined
167+delete
168-die
169+do
170-dump
171-each
172+else
173+elsif
174-endgrent
175-endhostent
176-endnetent
177-endprotoent
178-endpwent
179-endservent
180-eof
181-eq
182+eval
183-evalbytes
184-exec
185+exists
186-exit
187-exp
188-fc
189-fcntl
190-field
191-fileno
192+finally
193-flock
194+for
195+foreach
196-fork
197+format
198-formline
199-ge
200-getc
201-getgrent
202-getgrgid
203-getgrnam
204-gethostbyaddr
205-gethostbyname
206-gethostent
207-getlogin
208-getnetbyaddr
209-getnetbyname
210-getnetent
211-getpeername
212-getpgrp
213-getppid
214-getpriority
215-getprotobyname
216-getprotobynumber
217-getprotoent
218-getpwent
219-getpwnam
220-getpwuid
221-getservbyname
222-getservbyport
223-getservent
224-getsockname
225-getsockopt
226+given
227+glob
228-gmtime
229+goto
230+grep
231-gt
232-hex
233+if
234-index
235-int
236-ioctl
237-isa
238-join
239-keys
240-kill
241+last
242-lc
243-lcfirst
244-le
245-length
246-link
247-listen
248+local
249-localtime
250-lock
251-log
252-lstat
253-lt
254+m
255+map
256-method
257-mkdir
258-msgctl
259-msgget
260-msgrcv
261-msgsnd
262+my
263-ne
264+next
265+no
266-not
267-oct
268-open
269-opendir
270-or
271-ord
272+our
273-pack
274+package
275-pipe
276-pop
277+pos
278+print
279+printf
280+prototype
281-push
282+q
283+qq
284+qr
285-quotemeta
286+qw
287+qx
288-rand
289-read
290-readdir
291-readline
292-readlink
293-readpipe
294-recv
295+redo
296-ref
297-rename
298+require
299-reset
300+return
301-reverse
302-rewinddir
303-rindex
304-rmdir
305+s
306+say
307+scalar
308-seek
309-seekdir
310-select
311-semctl
312-semget
313-semop
314-send
315-setgrent
316-sethostent
317-setnetent
318-setpgrp
319-setpriority
320-setprotoent
321-setpwent
322-setservent
323-setsockopt
324-shift
325-shmctl
326-shmget
327-shmread
328-shmwrite
329-shutdown
330-sin
331-sleep
332-socket
333-socketpair
334+sort
335-splice
336+split
337-sprintf
338-sqrt
339-srand
340-stat
341+state
342+study
343+sub
344-substr
345-symlink
346-syscall
347-sysopen
348-sysread
349-sysseek
350-system
351-syswrite
352-tell
353-telldir
354-tie
355-tied
356-time
357-times
358+tr
359+try
360-truncate
361-uc
362-ucfirst
363-umask
364+undef
365+unless
366-unlink
367-unpack
368-unshift
369-untie
370+until
371+use
372-utime
373-values
374-vec
375-wait
376-waitpid
377-wantarray
378-warn
379+when
380+while
381-write
382-x
383-xor
384+y
385