fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / tools / dev / ncidef2pasm.pl
blob148fcd7c54d69c4eb4dca30fddca1651f03a6765
1 #! perl
3 # Copyright (C) 2003-2007, Parrot Foundation.
4 # $Id$
6 =head1 NAME
8 tools/dev/ncidef2asm.pl - Turn an NCI library definition file into PASM
10 =head1 SYNOPSIS
12 perl tools/dev/ncidef2asm.pl path/to/from_file [ path/to/to_file ]
14 =head1 DESCRIPTION
16 This program takes an NCI library definition file and turns it into PASM.
18 An NCI library definition file provides the information needed to
19 generate a parrot wrapper for the named library (or libraries). Its
20 format is simple, and looks like:
22 [package]
23 ncurses
25 [lib]
26 libform.so
28 [defs]
29 p new_field i i i i i i
31 [lib]
32 libncurses.so
34 [defs]
35 i is_term_resized i i
37 Note that the assembly file is generated in the order you specify, so
38 if there are library dependencies, make sure you have them in the
39 correct order.
41 =head2 package
43 Declares the package that all subsequent sub PMCs will be put
44 into. The name is a simple concatenation of the package name, double
45 colon, and the routine name, with no preceding punctuation.
47 =head2 lib
49 The name of the library to be loaded. Should be as qualified as
50 necessary for your platform--generally the full filename is required,
51 though the directory generally isn't.
53 You may load multiple libraries here, but only the last one loaded
54 will be exposed to subsequent defs.
56 =head2 defs
58 This section holds the definitions of functions. Each function is
59 assumed to be in the immediate preceding library. The definition of
60 the function is:
62 return_type name [param [param [param ...]]]
64 The param and return_type parameters use the NCI standard, which for
65 reference is:
67 =over 4
69 =item p
71 Parameter is a void pointer, taken from the PMC's data pointer. PMC is
72 assumed to be an unmanagedstruct or child class.
74 Taken from a P register
76 =item c
78 Parameter is a character.
80 Taken from an I register
82 =item s
84 Parameter is a short
86 Taken from an I register
88 =item i
90 Parameter is an int
92 Taken from an I register
94 =item l
96 Parameter is a long
98 Taken from an I register
100 =item f
102 Paramter is a float
104 Taken from an N register.
106 =item d
108 Parameter is a double.
110 Taken from an N register.
112 =item t
114 Paramter is a char *, presumably a C string
116 Taken from an S register
118 =item v
120 Void. Only valid as a return type, noting that the function returns no data.
122 =item I
124 Interpreter pointer. The current interpreter pointer is passed in
126 =item P
128 PMC.
130 =item 2
132 Pointer to short.
134 Taken from an I register.
136 =item 3
138 Pointer to int.
140 Taken from an I register
142 =item 4
144 Pointer to long
146 Taken from an I register
148 =back
150 =cut
152 use strict;
153 use warnings;
155 my ( $from_file, $to_file ) = @ARGV;
157 # If there is no destination file, strip off the extension of the
158 # source file and add a .pasm to it
159 if ( !defined $to_file ) {
160 $to_file = $from_file;
161 $to_file =~ s/\..*$//;
162 $to_file .= ".pasm";
165 open my $INPUT, '<', "$from_file" or die "Can't open up $from_file, error $!";
166 open my $OUTPUT, '>', "$to_file" or die "Can't open up $to_file, error $!";
168 # To start, save all the registers, just in case
169 print $OUTPUT "saveall\n";
171 my @libs;
172 my ( $cur_package, $line, $cur_section );
174 # Our dispatch table
175 my (%dispatch) = (
176 package => \&package_line,
177 lib => \&lib_line,
178 defs => \&def_line,
181 while ( $line = <$INPUT> ) {
183 # Throw away trailing newlines, comments, and whitespace. If the
184 # line's empty, then off to the next line
185 chomp $line;
186 $line =~ s/#.*//;
187 $line =~ s/\s*$//;
188 next unless $line;
190 # Is it a section line? If so, extract the section and set it.
191 if ( $line =~ /\[(\w+)\]/ ) {
192 $cur_section = $1;
193 next;
196 # Everything else goes to the handler
197 $dispatch{$cur_section}->($line);
201 # Put the registers back and end
202 print $OUTPUT "restoreall\n";
203 print $OUTPUT "end\n";
204 close $OUTPUT;
206 sub package_line {
207 my $line = shift;
209 # Trim leading and trailing spaces
210 $line =~ s/^\s*//;
211 $line =~ s/\s*$//;
213 # Set the global current package
214 $cur_package = $line;
218 sub lib_line {
219 my $line = shift;
220 print $OUTPUT "loadlib P1, '$line'\n";
223 sub def_line {
224 my $line = shift;
225 my ( $return_type, $name, @params ) = split ' ', $line;
226 unshift @params, $return_type;
227 my $signature = join( "", @params );
228 print $OUTPUT "dlfunc P2, P1, '$name', '$signature'\n";
229 print $OUTPUT "store_global '${cur_package}::${name}', P2\n";
232 # Local Variables:
233 # mode: cperl
234 # cperl-indent-level: 4
235 # fill-column: 100
236 # End:
237 # vim: expandtab shiftwidth=4: