#!/usr/bin/perl
+unlink "opcode.h";
open(OC, ">opcode.h") || die "Can't create opcode.h: $!\n";
select OC;
chop;
next unless $_;
next if /^#/;
- ($key, $name, $check, $flags, $args) = split(/\t+/, $_, 5);
+ ($key, $desc, $check, $flags, $args) = split(/\t+/, $_, 5);
+
+ warn qq[Description "$desc" duplicates $seen{$desc}\n] if $seen{$desc};
+ die qq[Opcode "$key" duplicates $seen{$key}\n] if $seen{$key};
+ $seen{$desc} = qq[description of opcode "$key"];
+ $seen{$key} = qq[opcode "$key"];
+
push(@ops, $key);
- $name{$key} = $name;
+ $desc{$key} = $desc;
$check{$key} = $check;
$ckname{$check}++;
$flags{$key} = $flags;
print "} opcode;\n";
print "\n#define MAXO ", scalar @ops, "\n\n";
-# Emit opnames.
+# Emit op names and descriptions.
print <<END;
#ifndef DOINIT
END
for (@ops) {
- print qq(\t"$name{$_}",\n);
+ print qq(\t"$_",\n);
+}
+
+print <<END;
+};
+#endif
+
+END
+
+print <<END;
+#ifndef DOINIT
+EXT char *op_desc[];
+#else
+EXT char *op_desc[] = {
+END
+
+for (@ops) {
+ print qq(\t"$desc{$_}",\n);
}
print <<END;
print <<END;
#ifndef DOINIT
-EXT OP * (*check[])();
+EXT OP * (*check[]) _((OP *op));
#else
-EXT OP * (*check[])() = {
+EXT OP * (*check[]) _((OP *op)) = {
END
for (@ops) {
gvsv scalar variable ck_null ds
gv glob value ck_null ds
+gelem glob elem ck_null d S S
padsv private variable ck_null ds
padav private array ck_null d
padhv private hash ck_null d
# References and stuff.
rv2gv ref-to-glob cast ck_rvconst ds
-sv2len scalar value length ck_null ist
rv2sv scalar deref ck_rvconst ds
av2arylen array length ck_null is
rv2cv subroutine deref ck_rvconst d
-anoncode anonymous subroutine ck_null 0
+anoncode anonymous subroutine ck_anoncode 0
+prototype subroutine prototype ck_null s S
refgen reference constructor ck_spair m L
srefgen scalar ref constructor ck_null fs S
ref reference-type operator ck_fun stu S?
schomp scalar safe chop ck_null stu S?
defined defined operator ck_rfun isu S?
undef undef operator ck_lfun s S?
-study study ck_fun stu S?
+study study ck_fun su S?
pos match position ck_lfun stu S?
preinc preincrement ck_lfun dIs S
concat concatenation ck_concat fst S S
stringify string ck_fun fst S
-left_shift left bitshift ck_null ifst S S
-right_shift right bitshift ck_null ifst S S
+left_shift left bitshift ck_bitop fst S S
+right_shift right bitshift ck_bitop fst S S
lt numeric lt ck_null Iifs S S
i_lt integer lt ck_null ifs S S
ncmp spaceship operator ck_null Iifst S S
i_ncmp integer spaceship ck_null ifst S S
-slt string lt ck_null ifs S S
-sgt string gt ck_null ifs S S
-sle string le ck_null ifs S S
-sge string ge ck_null ifs S S
+slt string lt ck_scmp ifs S S
+sgt string gt ck_scmp ifs S S
+sle string le ck_scmp ifs S S
+sge string ge ck_scmp ifs S S
seq string eq ck_null ifs S S
sne string ne ck_null ifs S S
-scmp string comparison ck_null ifst S S
+scmp string comparison ck_scmp ifst S S
-bit_and bitwise and ck_null fst S S
-bit_xor bitwise xor ck_null fst S S
-bit_or bitwise or ck_null fst S S
+bit_and bitwise and ck_bitop fst S S
+bit_xor bitwise xor ck_bitop fst S S
+bit_or bitwise or ck_bitop fst S S
negate negate ck_null Ifst S
i_negate integer negate ck_null ifst S
not not ck_null ifs S
-complement 1's complement ck_null fst S
+complement 1's complement ck_bitop fst S
# High falutin' math.
index index ck_index ist S S S?
rindex rindex ck_index ist S S S?
-sprintf sprintf ck_fun mst S L
-formline formline ck_formline ms S L
+sprintf sprintf ck_fun_locale mst S L
+formline formline ck_fun ms S L
ord ord ck_fun ifstu S?
chr chr ck_fun fstu S?
crypt crypt ck_fun fst S S
-ucfirst upper case first ck_fun fst S
-lcfirst lower case first ck_fun fst S
-uc upper case ck_fun fst S
-lc lower case ck_fun fst S
-quotemeta quote metachars ck_fun fst S
+ucfirst upper case first ck_fun_locale fstu S?
+lcfirst lower case first ck_fun_locale fstu S?
+uc upper case ck_fun_locale fstu S?
+lc lower case ck_fun_locale fstu S?
+quotemeta quote metachars ck_fun fstu S?
# Arrays.
each each ck_fun t H
values values ck_fun t H
keys keys ck_fun t H
-delete delete ck_delete s S
-exists exists operator ck_delete is S
+delete delete ck_delete 0 S
+exists exists operator ck_exists is S
rv2hv associative array deref ck_rvconst dt
helem associative array elem ck_null s H S
hslice associative array slice ck_null m H L
and logical and ck_null 0
or logical or ck_null 0
xor logical xor ck_null fs S S
-cond_expr conditional expression ck_null 0
+cond_expr conditional expression ck_null d
andassign logical and assignment ck_null s
orassign logical or assignment ck_null s
tie tie ck_fun idms R S L
untie untie ck_fun is R
+tied tied ck_fun s R
dbmopen dbmopen ck_fun is H S S
dbmclose dbmclose ck_fun is H
prtf printf ck_listiob ims F? L
print print ck_listiob ims F? L
+sysopen sysopen ck_fun s F S S S?
sysread sysread ck_fun imst F R S S?
syswrite syswrite ck_fun imst F S S S?
eof eof ck_eof is F?
tell tell ck_fun st F?
seek seek ck_fun s F S S
+# truncate really behaves as if it had both "S S" and "F S"
truncate truncate ck_trunc is S S
fcntl fcntl ck_fun st F S S