├── .editorconfig
├── .gitattributes
├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── command_test.v
├── src
├── c2v.v
├── c2v_test.v
├── configuration.v
├── cpp.v
├── node.v
├── node_kind.v
└── struct.v
├── tests
├── 1.hello.c
├── 1.hello.out
├── 10.jni.h
├── 10.jni.out
├── 11.enum_default.c
├── 11.enum_default.out
├── 12.if_stmt.c
├── 12.if_stmt.out
├── 13.switch.c
├── 13.switch.out
├── 14.default.c
├── 14.default.out
├── 15.multi_var_decl.c
├── 15.multi_var_decl.out
├── 16.literals.c
├── 16.literals.out
├── 17.partial_struct.c
├── 17.partial_struct.out
├── 18.header_types.h
├── 18.header_types.out
├── 19.header_visibility_attribute.h
├── 19.header_visibility_attribute.out
├── 2.if.c
├── 2.if.out
├── 20.header_duplicate_type_declaration.h
├── 20.header_duplicate_type_declaration.out
├── 21.header_uninited_global_var.h
├── 21.header_uninited_global_var.out
├── 22.getline_linux.c
├── 22.getline_linux.out
├── 22.getline_macos.c
├── 22.getline_macos.out
├── 23.sizeof.c
├── 23.sizeof.out
├── 24.typedef_struct.h
├── 24.typedef_struct.out
├── 25.return_val_2.c
├── 25.return_val_2.out
├── 26.assign_zerof.c
├── 26.assign_zerof.out
├── 3.if_switch_enum.c
├── 3.if_switch_enum.out
├── 4.for.c
├── 4.for.out
├── 5.struct.c
├── 5.struct.out
├── 6.types.c
├── 6.types.out
├── 7.api_types.h
├── 7.api_types.out
├── 8.simple_func_header.h
├── 8.simple_func_header.out
├── 9.func_declaration.h
├── 9.func_declaration.out
├── IGNORE_header_duplicate_type_declaration_2.h
├── run_doom_tests.vsh
├── run_tests.vsh
└── test.c
│ ├── 1.hello.c
│ └── 1.hello.out
├── tests_todo
├── 5.if_paren_call.c
└── 5.if_paren_call.out
├── tools
├── build_doom_file.vsh
└── node_kind_gen
│ ├── gen_node_kind_code.v
│ └── types
└── v.mod
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | charset = utf-8
3 | end_of_line = lf
4 | insert_final_newline = true
5 | trim_trailing_whitespace = true
6 |
7 | [*.v]
8 | indent_style = tab
9 | indent_size = 4
10 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.v linguist-language=V text=auto eol=lf
2 | *.vv linguist-language=V text=auto eol=lf
3 | *.vsh linguist-language=V text=auto eol=lf
4 | **/v.mod linguist-language=V text=auto eol=lf
5 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | paths-ignore: ['**/*.md', '^\.*', 'LICENSE']
6 | pull_request:
7 | paths-ignore: ['**/*.md', '^\.*', 'LICENSE']
8 | schedule:
9 | - cron: '31 1,12 * * *'
10 |
11 | jobs:
12 | build:
13 | strategy:
14 | matrix:
15 | os: [ubuntu-latest, macos-latest]
16 | fail-fast: false
17 | runs-on: ${{ matrix.os }}
18 | steps:
19 | - name: Checkout V
20 | uses: actions/checkout@v4
21 | with:
22 | repository: vlang/v
23 | - name: Checkout C2V
24 | uses: actions/checkout@v4
25 | with:
26 | path: c2v
27 | - name: Install dependencies
28 | run: |
29 | if [ "${{ runner.os }}" == "Linux" ]; then
30 | sudo apt update -y -qq
31 | sudo apt install libsdl2-dev libsdl2-mixer-dev libsdl2-net-dev libpng-dev libsamplerate0-dev
32 | else
33 | brew install sdl2 sdl2_mixer sdl2_net libpng libsamplerate
34 | fi
35 | - name: Build V
36 | run: make && ./v symlink
37 | - name: Setup C2V
38 | run: |
39 | mv c2v ~/.vmodules/c2v
40 | v -g ~/.vmodules/c2v/ || true
41 | - name: Test C2V
42 | run: v -g test ~/.vmodules/c2v/
43 | - name: Build original Chocolate Doom
44 | run: |
45 | git clone --quiet --depth 1 https://github.com/vlang/doom ~/code/doom
46 | cd ~/code/doom/chocolate-doom
47 | cmake -DCMAKE_BUILD_TYPE=Debug .
48 | make chocolate-doom
49 | - name: Translate just p_enemy.v
50 | run: |
51 | cd ~/.vmodules/c2v/
52 | v -g run tools/build_doom_file.vsh doom/p_enemy
53 | - name: Translate the whole game in project/folder mode
54 | run: |
55 | touch ~/DOOM1.WAD
56 | if [ "${{ runner.os }}" == "Linux" ]; then
57 | WAD_FILE=~/DOOM1.WAD ~/code/doom/build_whole_project.sh
58 | else
59 | echo "TODO: ... building doom should be fixed on macos, after it regressed in eafdd3c"
60 | fi
61 |
62 | test-regressions:
63 | runs-on: ubuntu-latest
64 | timeout-minutes: 10
65 | env:
66 | VFLAGS: -cc tcc
67 | DISPLAY: :99
68 | LIBGL_ALWAYS_SOFTWARE: true
69 | VTMP: /tmp
70 | steps:
71 | - name: Checkout V
72 | uses: actions/checkout@v4
73 | with:
74 | repository: vlang/v
75 | - name: Checkout C2V
76 | uses: actions/checkout@v4
77 | with:
78 | path: c2v
79 | - name: Install dependencies
80 | run: |
81 | sudo apt update -y -qq
82 | sudo apt install libsdl2-dev libsdl2-mixer-dev libsdl2-net-dev libpng-dev libsamplerate0-dev
83 | # c2v / DOOM dependencies
84 | # vgret dependencies
85 | # imagemagick : convert, mogrify, import
86 | # xvfb : For starting X11 Virtual FrameBuffers
87 | # openimageio-tools : idiff
88 | # libgl1-mesa-dri : For headless rendering / software DRI driver (LIBGL_ALWAYS_SOFTWARE=true)
89 | # freeglut3-dev : Fixes graphic apps compilation with tcc
90 | sudo apt install imagemagick openimageio-tools freeglut3-dev libgl1-mesa-dri xvfb xsel xclip
91 | - name: Setup test tools
92 | run: |
93 | # Fetch the free ~4MB DOOM1.WAD from the link at https://doomwiki.org/wiki/DOOM1.WAD
94 | wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad -O ~/doom1.wad
95 | # Get imgur upload script
96 | wget https://raw.githubusercontent.com/tremby/imgur.sh/c98345d/imgur.sh
97 | chmod +x ./imgur.sh
98 | # Get regression images to test against
99 | git clone https://github.com/Larpon/doom-regression-images
100 | - name: Build V
101 | run: make && ./v symlink
102 | - name: Setup C2V
103 | run: |
104 | mv c2v ~/.vmodules/c2v
105 | v -g ~/.vmodules/c2v/ || true
106 | - name: Test C2V
107 | run: v -g test ~/.vmodules/c2v/
108 | - name: Build original Chocolate Doom
109 | run: |
110 | git clone --quiet --depth 1 https://github.com/vlang/doom ~/code/doom
111 | cd ~/code/doom/chocolate-doom
112 | cmake -DCMAKE_BUILD_TYPE=Debug .
113 | make chocolate-doom
114 | - name: Translate the whole game in project/folder mode
115 | run: WAD_FILE=~/doom1.wad ~/code/doom/build_whole_project.sh
116 | - name: Sample and compare
117 | id: compare
118 | continue-on-error: true
119 | run: |
120 | Xvfb $DISPLAY -screen 0 800x600x24 -fbdir /var/tmp/ &
121 | sleep 1; while [ ! -f /var/tmp/Xvfb_screen0 ]; do sleep 0.5; done # give xvfb time to start, even on slow CI runs
122 | sleep 1; v gret -r ~/code/doom -t ./doom-regression-images/vgret.doom.toml -v ./doom-sample_images ./doom-regression-images
123 | - name: Upload regression to imgur
124 | if: steps.compare.outcome != 'success'
125 | run: |
126 | ./imgur.sh /tmp/fail.png
127 | ./imgur.sh /tmp/diff.png
128 | exit 1
129 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | main
3 | c2v
4 | *.exe
5 | *.exe~
6 | *.so
7 | *.dylib
8 | *.dll
9 | vls.log
10 | tests/run_tests
11 | .idea/
12 | tests/**.json
13 |
14 | tests/test.c/1.hello.json
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: c2v
2 |
3 | c2v: *.v
4 | v -experimental -w .
5 |
6 | clean:
7 | rm -rf c2v
8 |
9 | .PHONY: all clean
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## C2V
2 |
3 | C => V source code translator.
4 |
5 | Demo Video: Translating DOOM from C to V, building and running it.
6 |
7 | https://www.youtube.com/watch?v=6oXrz3oRoEg
8 |
9 |
10 | ### Building
11 |
12 | ```bash
13 | v .
14 | ```
15 | ... or if you want to debug c2v behaviour:
16 | ```bash
17 | v -d trace_verbose .
18 | ```
19 |
20 | No dependencies other than a `clang` binary.
21 |
22 |
23 | ### Usage
24 |
25 | c2v accepts the following arguments:
26 | ```
27 | -keep_ast keep ast files
28 | -print_tree print the entire tree
29 | ```
30 |
31 | ```
32 | c2v file.c
33 | ```
34 |
35 | This will generate `file.v`.
36 |
37 | ```
38 | c2v project
39 | ```
40 |
41 | This will translate each C file in the `project` directory.
42 |
43 | ```
44 | project/ ==> project/
45 | a.c a.c
46 | foo.c a.v
47 | foo.c
48 | foo.v
49 | ```
50 |
51 | You may need to run translated code with `v -translated file.v` until early 2023.
52 |
53 | ### Wrapper generation
54 |
55 | C2V can also generate V wrappers on top of C libraries.
56 |
57 | ```
58 | c2v wrapper file.c
59 | ```
60 |
61 | ### Notes
62 |
63 | C2V is using Clang's AST to generate V. This allowed us to avoid writing a C parser.
64 |
65 | In order to avoid LLVM dependencies/C++ complexity, C2V parses AST generated by the `clang` binary.
66 |
67 |
68 | ### Configuration
69 | C2V supports reading from a project configuration file named `c2v.toml`, located in one of these places, in this order:
70 | 1) if C2V_CONFIG is set, it should contain the c2v.toml path.
71 | 2) the project folder (the last folder passed to c2v) + /c2v.toml
72 | 3) the project folder (the folder of the file that is last passed to c2v) + /c2v.toml
73 |
74 | That file has the following format:
75 | ```toml
76 | [project]
77 | uses_sdl = true
78 | output_dirname = "c2v_out.dir"
79 | additional_flags = "-I. -I.. -I../.."
80 |
81 | ["info.c"]
82 | additional_flags = "-I/some/folder/used/only/for/that/specific/file"
83 | ```
84 |
85 | In the above:
86 | `uses_sdl` is a boolean, that defaults to false.
87 | When it is true, c2v will append the result of `sdl2-config --cflags` to `additional_flags` .
88 | `output_dirname` is a string, that defaults to `c2v_output`. c2v will create that folder, if it does not exist, and it will put all the translated .v files there.
89 | `additional_flags` is a string, that will be passed verbatim to the clang parser for each .c file. It can be used to pass additional -I flags, that are specific to your project, so that clang can find all the headers needed by that project.
90 |
91 | Note: all these are global to the project.
92 |
93 | The c2v.toml configuration file also supports file specific overrides, for the `additional_flags` option, just put them in their own sections,
94 | titled as the file name.
95 |
--------------------------------------------------------------------------------
/command_test.v:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | fn testsuite_begin() {
4 | os.chdir(os.dir(@FILE))!
5 | }
6 |
7 | fn test_run_tests() {
8 | res := os.system('${os.quoted_path(@VEXE)} tests/run_tests.vsh')
9 | assert res == 0
10 | }
11 |
--------------------------------------------------------------------------------
/src/c2v_test.v:
--------------------------------------------------------------------------------
1 | module main
2 |
3 | fn check_ct(str_typ string, expected string) {
4 | t := convert_type(str_typ)
5 | assert t.name == expected
6 | if t.name != expected {
7 | println('!!!' + t.name)
8 | }
9 | }
10 |
11 | fn test_convert_type() {
12 | check_ct('FuncDef *[23]', '[23]&FuncDef')
13 | check_ct('void (*)(void *, void *)', 'fn (voidptr, voidptr)')
14 | check_ct('const char **', '&&u8')
15 | check_ct('byte [20]', '[20]u8')
16 | check_ct('byte *', '&u8')
17 | check_ct('byte *:byte *', '&u8')
18 | check_ct('short', 'i16')
19 | check_ct('signed char', 'i8')
20 | check_ct('int **', '&&int')
21 | check_ct('void **', '&voidptr')
22 | }
23 |
24 | fn test_trim_underscore() {
25 | assert trim_underscores('__name') == 'name'
26 | assert trim_underscores('_name') == 'name'
27 | }
28 |
--------------------------------------------------------------------------------
/src/configuration.v:
--------------------------------------------------------------------------------
1 | module main
2 |
3 | import os
4 | import toml
5 |
6 | fn (mut c2v C2V) handle_configuration(args []string) {
7 | last_path := args.last()
8 | if os.is_dir(last_path) {
9 | c2v.is_dir = true
10 | c2v.project_folder = os.real_path(last_path)
11 | } else {
12 | c2v.is_dir = false
13 | c2v.project_folder = os.dir(os.real_path(last_path))
14 | }
15 | // Configuration file priority:
16 | // 1) C2V_CONFIG, but only if it exits
17 | // 2) project_folder/c2v.toml, but only if it exists
18 | mut c2v_config_file := os.getenv('C2V_CONFIG')
19 | if c2v_config_file == '' || !os.exists(c2v_config_file) {
20 | c2v_config_file = ''
21 | folder_file := os.join_path(c2v.project_folder, 'c2v.toml')
22 | if os.exists(folder_file) {
23 | c2v_config_file = folder_file
24 | }
25 | }
26 | c2v.read_toml_configuration(c2v_config_file)
27 | c2v.set_config_overrides_for_project()
28 | }
29 |
30 | fn (mut c2v C2V) get_additional_flags(path string) string {
31 | return '${c2v.project_additional_flags} ${c2v.file_additional_flags} '
32 | }
33 |
34 | fn (mut c2v C2V) get_globals_path() string {
35 | return c2v.project_globals_path
36 | }
37 |
38 | fn (mut c2v C2V) read_toml_configuration(toml_file string) {
39 | if toml_file == '' {
40 | return
41 | }
42 | vprintln('> reading from toml configuration file: ${toml_file}')
43 | c2v.conf = toml.parse_file(toml_file) or { panic(err) }
44 | // dump(c2v.conf)
45 | }
46 |
47 | // called once per invocation
48 | fn (mut c2v C2V) set_config_overrides_for_project() {
49 | c2v.project_uses_sdl = c2v.conf.value('project.uses_sdl').default_to(false).bool()
50 | c2v.project_output_dirname = c2v.conf.value('project.output_dirname').default_to('c2v_output').string()
51 | c2v.project_additional_flags = c2v.conf.value('project.additional_flags').default_to('-I.').string()
52 | c2v.wrapper_module_name = c2v.conf.value('project.wrapper_module_name').default_to('').string()
53 | c2v.keep_ast = c2v.conf.value('keep_ast').default_to(false).bool()
54 | if c2v.project_uses_sdl {
55 | sdl_cflags := get_sdl_cflags()
56 | c2v.project_additional_flags += ' ' + sdl_cflags
57 | }
58 | c2v.project_globals_path = os.real_path(os.join_path(c2v.project_folder, c2v.project_output_dirname,
59 | '_globals.v'))
60 | }
61 |
62 | // called once per each .c file
63 | fn (mut c2v C2V) set_config_overrides_for_file(path string) {
64 | fname := os.file_name(path)
65 | c2v.file_additional_flags = c2v.conf.value("'${fname}'.additional_flags").default_to('').string()
66 | }
67 |
68 | fn get_sdl_cflags() string {
69 | res := os.execute('sdl2-config --cflags')
70 | if res.exit_code != 0 {
71 | eprintln('The project uses sdl, but `sdl2-config` was not found. Try installing a development package for SDL2')
72 | exit(1)
73 | }
74 | return res.output.trim_space()
75 | }
76 |
--------------------------------------------------------------------------------
/src/cpp.v:
--------------------------------------------------------------------------------
1 | module main
2 |
3 | fn (mut c C2V) cpp_top_level(_node &Node) bool {
4 | println('C++ top level')
5 | mut node := unsafe { _node }
6 | if node.kindof(.namespace_decl) {
7 | for child in node.inner {
8 | c.top_level(child)
9 | }
10 | } else if node.kindof(.cxx_constructor_decl) {
11 | c.constructor_decl(node)
12 | } else if node.kindof(.cxx_destructor_decl) {
13 | c.destructor_decl(node)
14 | } else if node.kindof(.original) {
15 | } else if node.kindof(.using_decl) {
16 | } else if node.kindof(.using_shadow_decl) {
17 | } else if node.kindof(.class_template_decl) {
18 | c.class_template_decl(node)
19 | } else if node.kindof(.class_template_specialization_decl) {
20 | } else if node.kindof(.cxx_record_decl) {
21 | } else if node.kindof(.linkage_spec_decl) {
22 | } else if node.kindof(.using_directive_decl) {
23 | } else if node.kindof(.class_template_partial_specialization_decl) {
24 | } else if node.kindof(.function_template_decl) {
25 | c.fn_template_decl(mut node)
26 | } else if node.kindof(.cxx_method_decl) {
27 | c.cxx_method_decl(node)
28 | } else {
29 | return false
30 | }
31 | return true
32 | }
33 |
34 | fn (mut c C2V) cpp_expr(_node &Node) bool {
35 | mut node := unsafe { _node }
36 | vprintln('C++ expr check')
37 | // println(node.vals)
38 | vprintln(node.ast_type.str())
39 | // std::vector a; OR
40 | // User u(34);
41 | if node.kindof(.cxx_construct_expr) {
42 | // println(node.vals)
43 | // c.genln(node.vals.str())
44 | c.genln('// cxx cons')
45 | typ := node.ast_type.qualified // get_val(-2)
46 | if typ.contains('') {
47 | c.gen('int')
48 | }
49 | } else if node.kindof(.cxx_member_call_expr) {
50 | // c.gen('[CXX MEMBER] ')
51 | mut member_expr := node.try_get_next_child_of_kind(.member_expr) or {
52 | println(err)
53 | bad_node
54 | }
55 |
56 | method_name := member_expr.name // get_val(-2)
57 | child := member_expr.try_get_next_child() or {
58 | println(err)
59 | bad_node
60 | }
61 | c.expr(child)
62 | mut add_par := false
63 | match method_name {
64 | '.push_back' {
65 | c.gen(' << ')
66 | }
67 | '.size' {
68 | c.gen('.len')
69 | }
70 | else {
71 | add_par = true
72 | method := method_name.replace('->', '.')
73 | c.gen('${method}(')
74 | }
75 | }
76 | mut mat_tmp_expr := node.try_get_next_child() or {
77 | println(err)
78 | bad_node
79 | }
80 | if mat_tmp_expr.kindof(.materialize_temporary_expr) {
81 | expr := mat_tmp_expr.try_get_next_child() or {
82 | println(err)
83 | bad_node
84 | }
85 | c.expr(expr)
86 | }
87 | if add_par {
88 | c.gen(')')
89 | }
90 | }
91 | // operator call (std::cout << etc)
92 | else if node.kindof(.cxx_operator_call_expr) {
93 | c.operator_call(node)
94 | }
95 | // std::string s = "HI";
96 | else if node.kindof(.expr_with_cleanups) {
97 | vprintln('expr with cle')
98 | typ := node.ast_type.qualified // get_val(-1)
99 | vprintln('TYP=${typ}')
100 | if typ.contains('basic_string<') {
101 | // All this for a simple std::string = "hello";
102 | mut construct_expr := node.try_get_next_child_of_kind(.cxx_construct_expr) or {
103 | println(err)
104 | bad_node
105 | }
106 |
107 | mut mat_tmp_expr := construct_expr.try_get_next_child_of_kind(.materialize_temporary_expr) or {
108 | println(err)
109 | bad_node
110 | }
111 |
112 | // cast_expr := mat_tmp_expr.get(ImplicitCastExpr)
113 | mut cast_expr := mat_tmp_expr.try_get_next_child() or {
114 | println(err)
115 | bad_node
116 | }
117 | if !cast_expr.kindof(.implicit_cast_expr) {
118 | return true
119 | }
120 | mut bind_tmp_expr := cast_expr.try_get_next_child_of_kind(.cxx_bind_temporary_expr) or {
121 | println(err)
122 | bad_node
123 | }
124 |
125 | mut cast_expr2 := bind_tmp_expr.try_get_next_child_of_kind(.implicit_cast_expr) or {
126 | println(err)
127 | bad_node
128 | }
129 |
130 | mut construct_expr2 := cast_expr2.try_get_next_child_of_kind(.cxx_construct_expr) or {
131 | println(err)
132 | bad_node
133 | }
134 |
135 | mut cast_expr3 := construct_expr2.try_get_next_child_of_kind(.implicit_cast_expr) or {
136 | println(err)
137 | bad_node
138 | }
139 |
140 | str_lit := cast_expr3.try_get_next_child_of_kind(.string_literal) or {
141 | println(err)
142 | bad_node
143 | }
144 |
145 | c.gen(str_lit.value as string) // get_val(-1))
146 | }
147 | } else if node.kindof(.unresolved_lookup_expr) {
148 | } else if node.kindof(.cxx_try_stmt) {
149 | } else if node.kindof(.cxx_throw_expr) {
150 | } else if node.kindof(.cxx_dynamic_cast_expr) {
151 | typ_ := convert_type(node.ast_type.qualified) // get_val(2))
152 | mut dtyp := typ_.name
153 | dtyp = dtyp.replace('* ', '&')
154 | c.gen('${dtyp}( ')
155 | child := node.try_get_next_child() or {
156 | println(err)
157 | bad_node
158 | }
159 | c.expr(child)
160 | c.gen(')')
161 | } else if node.kindof(.cxx_reinterpret_cast_expr) {
162 | } else if node.kindof(.cxx_unresolved_construct_expr) {
163 | } else if node.kindof(.cxx_dependent_scope_member_expr) {
164 | } else if node.kindof(.cxx_this_expr) {
165 | c.gen('this')
166 | } else if node.kindof(.cxx_bool_literal_expr) {
167 | val := node.value // get_val(-1)
168 | c.gen(val as string)
169 | } else if node.kindof(.cxx_null_ptr_literal_expr) {
170 | c.gen('nullptr')
171 | } else if node.kindof(.cxx_functional_cast_expr) {
172 | } else if node.kindof(.cxx_delete_expr) {
173 | }
174 | // static_cast(a)
175 | else if node.kindof(.cxx_static_cast_expr) {
176 | typ := node.ast_type.qualified // get_val(0)
177 | // v := node.vals.join(' ')
178 | c.gen('(${typ})(')
179 | expr := node.try_get_next_child() or {
180 | println(err)
181 | bad_node
182 | }
183 | c.expr(expr)
184 | c.gen(')')
185 | } else if node.kindof(.materialize_temporary_expr) {
186 | } else if node.kindof(.cxx_temporary_object_expr) {
187 | } else if node.kindof(.decl_stmt) {
188 | // TODO WTF
189 | } else if node.kindof(.cxx_new_expr) {
190 | } else {
191 | return false
192 | }
193 | return true
194 | }
195 |
196 | fn (mut c C2V) fn_template_decl(mut node Node) {
197 | // name := node.get_val(- 1)
198 | // build ""
199 | mut types := '<'
200 | nr_types := node.count_children_of_kind(.template_type_parm_decl)
201 | for i := 0; i < nr_types; i++ {
202 | t := node.try_get_next_child_of_kind(.template_type_parm_decl) or {
203 | println(err)
204 | bad_node
205 | }
206 |
207 | types += t.ast_type.qualified // get_val(-1)
208 | if i != nr_types - 1 {
209 | types += ', '
210 | }
211 | }
212 | types = types + '>'
213 | // First child fn decl is with
214 | // fn_node := node.get(.FunctionDecl)
215 | mut children := node.find_children(.function_decl)
216 | for mut fn_node in children {
217 | // fn_node2 := node.get(FunctionDecl)
218 | c.fn_decl(mut fn_node, '') // types)
219 | }
220 | }
221 |
222 | fn (mut c C2V) class_template_decl(node &Node) {
223 | // mut node := _node
224 | name := node.name // get_val(-1)
225 | c.genln('CLASS ${name}')
226 | }
227 |
228 | // CBattleAnimation::CBattleAnimation()
229 | fn (mut c C2V) constructor_decl(_node &Node) {
230 | mut node := unsafe { _node }
231 | // nt := get_name_type(node)
232 | name := node.name
233 | typ := convert_type(node.ast_type.qualified)
234 | str_args := c.fn_params(mut node)
235 | c.genln('fn new_${name}(${str_args}) ${typ.name} {')
236 | // User::User() : field1(val1), field2(val2)
237 | nr_ctor_inits := node.count_children_of_kind(.cxx_ctor_initializer)
238 | for i := 0; i < nr_ctor_inits; i++ {
239 | mut init := node.try_get_next_child_of_kind(.cxx_ctor_initializer) or {
240 | println(err)
241 | bad_node
242 | }
243 |
244 | expr := init.try_get_next_child() or {
245 | println(err)
246 | bad_node
247 | }
248 | c.expr(expr)
249 | c.genln('')
250 | }
251 | mut stmts := node.try_get_next_child_of_kind(.compound_stmt) or {
252 | println(err)
253 | bad_node
254 | }
255 |
256 | c.st_block_no_start(mut stmts)
257 | c.genln('')
258 | }
259 |
260 | // CBattleAnimation::~CBattleAnimation()
261 | fn (mut c C2V) destructor_decl(node &Node) {
262 | }
263 |
264 | fn (mut c C2V) cxx_method_decl(_node &Node) {
265 | mut node := unsafe { _node }
266 | name := node.name
267 | typ := convert_type(node.ast_type.qualified)
268 | str_args := c.fn_params(mut node)
269 | c.genln('fn (this typ) ${name}(${str_args}) ${typ.name} {')
270 | if node.has_child_of_kind(.overrides) {
271 | node.try_get_next_child_of_kind(.overrides) or {
272 | println(err)
273 | bad_node
274 | }
275 | }
276 | mut stmts := node.try_get_next_child_of_kind(.compound_stmt) or {
277 | println(err)
278 | bad_node
279 | }
280 |
281 | c.statements(mut stmts)
282 | }
283 |
284 | // std::cout << etc
285 | fn (mut c C2V) operator_call(_node &Node) {
286 | mut node := unsafe { _node }
287 | // cast_expr := node.get(ImplicitCastExpr)
288 | mut cast_expr := node.try_get_next_child() or {
289 | println(err)
290 | bad_node
291 | }
292 | if !cast_expr.kindof(.implicit_cast_expr) {
293 | c.genln('OP@@')
294 | return
295 | }
296 | decl_ref_expr := cast_expr.try_get_next_child_of_kind(.decl_ref_expr) or {
297 | println(err)
298 | bad_node
299 | }
300 |
301 | // vprintln('\n CXX OPERATOR DRE')
302 | // vprintln(decl_ref_expr.vals)
303 | typ := decl_ref_expr.ast_type.qualified // get_val(-1)
304 | op := decl_ref_expr.opcode // get_val(-2)
305 | mut add_par := false
306 | if op == 'operator<<' && typ.contains('basic_ostream') {
307 | c.gen('println(')
308 | add_par = true
309 | } else {
310 | // c.gen('op1 $op op2')
311 | }
312 | // vprintln('op="$op"')
313 | // decl_ref_expr2 := node.get(DeclRefExpr)
314 | // expr := decl_ref_expr2.get2()
315 | // expr := node.get2()
316 | expr := node.try_get_next_child() or {
317 | println(err)
318 | bad_node
319 | }
320 | // vprintln('<< EXPR $expr.typ')
321 | // vprintln(expr.vals)
322 | c.expr(expr)
323 | if add_par {
324 | c.gen(')')
325 | }
326 | }
327 |
328 | fn (mut c C2V) for_range(node &Node) {
329 | // mut node := unsafe { _node }
330 | // decl := node.get(DeclStmt)
331 | mut stmt := node.inner.last()
332 | // decls := node.find_children(DeclStmt)
333 | // decl:=decls.last()
334 | // var_name := j
335 | c.genln('for val in vals {')
336 | c.st_block_no_start(mut stmt)
337 | }
338 |
--------------------------------------------------------------------------------
/src/node.v:
--------------------------------------------------------------------------------
1 | // To generate example AST JSON, that Node structure maps,
2 | // use clang -w -Xclang -ast-dump=json -fsyntax-only -fno-diagnostics-color -c 1.hello.c > ast.json command, for example.
3 |
4 | module main
5 |
6 | type Value = string | int
7 |
8 | // vfmt off
9 | struct Node {
10 | id string
11 | kind_str string @[json: 'kind'] // e.g. "IntegerLiteral"
12 | previous_declaration string @[json: 'previousDecl']
13 | name string // e.g. "my_var_name"
14 | ast_type AstJsonType @[json: 'type']
15 | class_modifier string @[json: 'storageClass']
16 | tags string @[json: 'tagUsed']
17 | initialization_type string @[json: 'init'] // "c" => "cinit"
18 | value Value @[json: 'value'] // For CharacterLiterals, since `value` is a number there, not at string
19 | opcode string // e.g. "+" in BinaryOperator
20 | ast_argument_type AstJsonType @[json: 'argType']
21 | declaration_id string @[json: 'declId'] // for goto labels
22 | label_id string @[json: 'targetLabelDeclId'] // for goto statements
23 | is_postfix bool @[json: 'isPostfix']
24 | mut:
25 | //parent_node &Node [skip] = unsafe {nil }
26 | location NodeLocation @[json: 'loc']
27 | comment string @[skip] // comment string before this node
28 | unique_id int = -1 @[skip]
29 | range Range
30 | inner []Node
31 | array_filler []Node // for InitListExpr
32 | ref_declaration RefDeclarationNode @[json: 'referencedDecl'] //&Node
33 | kind NodeKind @[skip]
34 | current_child_id int @[skip]
35 | redeclarations_count int @[skip] // increased when some *other* Node had previous_decl == this Node.id
36 | owned_tag_decl OwnedTagDecl @[json: 'ownedTagDecl'] // for TagDecl nodes, to store the TagDecl node that is owned by this node
37 | }
38 | // vfmt on
39 |
40 | struct NodeLocation {
41 | mut:
42 | offset int
43 | file string @[json: 'file']
44 | line int
45 | source_file SourceFile @[json: 'includedFrom']
46 | spelling_file SourceFile @[json: 'spellingLoc']
47 | file_index int = -1
48 | }
49 |
50 | struct Range {
51 | mut:
52 | begin Begin
53 | end End
54 | }
55 |
56 | struct Begin {
57 | mut:
58 | offset int
59 | spelling_file SourceFile @[json: 'spellingLoc']
60 | expansion_file SourceFile @[json: 'expansionLoc']
61 | }
62 |
63 | struct End {
64 | mut:
65 | offset int
66 | spelling_file SourceFile @[json: 'spellingLoc']
67 | expansion_file SourceFile @[json: 'expansionLoc']
68 | }
69 |
70 | struct SourceFile {
71 | offset int @[json: 'offset']
72 | path string @[json: 'file']
73 | }
74 |
75 | struct AstJsonType {
76 | desugared_qualified string @[json: 'desugaredQualType']
77 | qualified string @[json: 'qualType']
78 | }
79 |
80 | struct RefDeclarationNode {
81 | kind_str string @[json: 'kind'] // e.g. "IntegerLiteral"
82 | name string
83 | mut:
84 | kind NodeKind @[skip]
85 | }
86 |
87 | struct OwnedTagDecl {
88 | id string
89 | kind_str string @[json: 'kind']
90 | name string
91 | }
92 |
93 | const bad_node = Node{
94 | kind: .bad
95 | }
96 |
97 | fn (value Value) to_str() string {
98 | if value is int {
99 | return value.str()
100 | } else {
101 | return value as string
102 | }
103 | }
104 |
105 | fn (node Node) kindof(expected_kind NodeKind) bool {
106 | return node.kind == expected_kind
107 | }
108 |
109 | fn (node Node) has_child_of_kind(expected_kind NodeKind) bool {
110 | for child in node.inner {
111 | if child.kindof(expected_kind) {
112 | return true
113 | }
114 | }
115 |
116 | return false
117 | }
118 |
119 | fn (node Node) count_children_of_kind(kind_filter NodeKind) int {
120 | mut count := 0
121 |
122 | for child in node.inner {
123 | if child.kindof(kind_filter) {
124 | count++
125 | }
126 | }
127 |
128 | return count
129 | }
130 |
131 | fn (node Node) find_children(wanted_kind NodeKind) []Node {
132 | mut suitable_children := []Node{}
133 |
134 | if node.inner.len == 0 {
135 | return suitable_children
136 | }
137 |
138 | for child in node.inner {
139 | if child.kindof(wanted_kind) {
140 | suitable_children << child
141 | }
142 | }
143 |
144 | return suitable_children
145 | }
146 |
147 | fn (mut node Node) try_get_next_child_of_kind(wanted_kind NodeKind) !Node {
148 | if node.current_child_id >= node.inner.len {
149 | return error('No more children')
150 | }
151 |
152 | mut current_child := node.inner[node.current_child_id]
153 |
154 | if current_child.kindof(wanted_kind) == false {
155 | error('try_get_next_child_of_kind(): WANTED ${wanted_kind.str()} BUT GOT ${current_child.kind.str()}')
156 | }
157 |
158 | node.current_child_id++
159 |
160 | return current_child
161 | }
162 |
163 | fn (mut node Node) try_get_next_child() !Node {
164 | if node.current_child_id >= node.inner.len {
165 | return error('No more children')
166 | }
167 |
168 | current_child := node.inner[node.current_child_id]
169 | node.current_child_id++
170 |
171 | return current_child
172 | }
173 |
174 | fn (mut node Node) initialize_node_and_children() {
175 | node.kind = convert_str_into_node_kind(node.kind_str)
176 |
177 | for mut child in node.inner {
178 | child.initialize_node_and_children()
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/src/node_kind.v:
--------------------------------------------------------------------------------
1 | // Since C2V uses Clang AST to "parse" C code and output of this parse step is a JSON file that describes code "nodes",
2 | // names of nodes from this JSON are converted into enum form to simplify working on a code level.
3 | //
4 | // This file contains 2 main things - constant str_to_node_kind_map and NodeKind enum declaration itself.
5 | // str_to_node_kind_map contains data pairs, so to add a new node that C2V should support,
6 | // simply define a new member of NodeKind enum (that is snake_case name of node) and add it to str_to_node_kind_map.
7 | //
8 | // You can also generate NodeKind enum and str_to_node_kind_map map code. See tools/node_kind_gen/gen_node_kind_code.v for details.
9 |
10 | module main
11 |
12 | // Take into account that members of this enum are sorted alphabetically A -> Z, but 'bad' value is on the top.
13 | // Use this style when defining a new record.
14 | enum NodeKind {
15 | bad // is used only inside a C2V to mark unknown or corrupted node.
16 | access_spec_decl
17 | acquire_capability_attr
18 | addr_label_expr
19 | aligned_attr
20 | alloc_size_attr
21 | always_inline_attr
22 | analyzer_no_return_attr
23 | array_filler
24 | array_subscript_expr
25 | asm_label_attr
26 | assert_exclusive_lock_attr
27 | atomic_expr
28 | availability_attr
29 | binary_operator
30 | block_command_comment
31 | block_expr
32 | break_stmt
33 | builtin_template_decl
34 | builtin_type
35 | call_expr
36 | capability_attr
37 | case_stmt
38 | character_literal
39 | class_decl
40 | class_template
41 | class_template_decl
42 | class_template_partial_specialization
43 | class_template_partial_specialization_decl
44 | class_template_specialization
45 | class_template_specialization_decl
46 | cold_attr
47 | compound_assign_operator
48 | compound_literal_expr
49 | compound_stmt
50 | conditional_operator
51 | constant_array_type
52 | constant_expr
53 | const_attr
54 | continue_stmt
55 | c_style_cast_expr
56 | cx_cursor_kind
57 | cxx
58 | cxx_access_specifier
59 | cxx_bind_temporary_expr
60 | cxx_bool_literal_expr
61 | cxx_catch_stmt
62 | cxx_const_cast_expr
63 | cxx_construct_expr
64 | cxx_constructor
65 | cxx_constructor_decl
66 | cxx_conversion
67 | cxx_conversion_decl
68 | cxx_ctor_initializer
69 | cxx_default_arg_expr
70 | cxx_default_init_expr
71 | cxx_delete_expr
72 | cxx_dependent_scope_member_expr
73 | cxx_destructor
74 | cxx_destructor_decl
75 | cxx_dynamic_cast_expr
76 | cxx_for_range_stmt
77 | cxx_functional_cast_expr
78 | cxx_member_call_expr
79 | cxx_method
80 | cxx_method_decl
81 | cxx_new_expr
82 | cxx_noexcept_expr
83 | cxx_null_ptr_literal_expr
84 | cxx_operator_call_expr
85 | cxx_pseudo_destructor_expr
86 | cxx_record
87 | cxx_record_decl
88 | cxx_reinterpret_cast_expr
89 | cxx_scalar_value_init_expr
90 | cxx_static_cast_expr
91 | cxx_temporary_object_expr
92 | cxx_this_expr
93 | cxx_throw_expr
94 | cxx_try_stmt
95 | cxx_typeid_expr
96 | cxx_unresolved_construct_expr
97 | decayed_type
98 | decl_ref_expr
99 | decl_stmt
100 | decltype_type
101 | default_stmt
102 | dependent_name_type
103 | dependent_scope_decl_ref_expr
104 | dependent_template_specialization_type
105 | deprecated_attr
106 | diagnose_if_attr
107 | disable_tail_calls_attr
108 | do_stmt
109 | elaborated_type
110 | enable_if_attr
111 | @enum
112 | enum_constant_decl
113 | enum_decl
114 | enum_type
115 | expr_with_cleanups
116 | field
117 | field_decl
118 | fixed_point_literal
119 | floating_literal
120 | format_arg_attr
121 | format_attr
122 | for_stmt
123 | friend_decl
124 | full_comment
125 | function
126 | function_decl
127 | function_no_proto_type
128 | function_proto_type
129 | function_template
130 | function_template_decl
131 | gcc_asm_stmt
132 | generic_selection_expr
133 | gnu_null_expr
134 | goto_stmt
135 | guarded_by_attr
136 | html_end_tag_comment
137 | html_start_tag_comment
138 | if_stmt
139 | imaginary_literal
140 | implicit_cast_expr
141 | implicit_value_init_expr
142 | incomplete_array_type
143 | indirect_field_decl
144 | indirect_goto_stmt
145 | init_list_expr
146 | injected_class_name_type
147 | inline_command_comment
148 | integer_literal
149 | invalid_code
150 | invalid_file
151 | label_ref
152 | label_stmt
153 | lambda_expr
154 | linkage_spec
155 | linkage_spec_decl
156 | l_value_reference_type
157 | materialize_temporary_expr
158 | max_field_alignment_attr
159 | member_expr
160 | member_pointer_type
161 | member_ref
162 | member_ref_expr
163 | module_import
164 | ms_asm_stmt
165 | namespace
166 | namespace_alias
167 | namespace_decl
168 | namespace_ref
169 | no_decl_found
170 | no_escape_attr
171 | no_inline_attr
172 | non_type_template_parameter
173 | non_type_template_parm_decl
174 | no_sanitize_attr
175 | no_throw_attr
176 | not_implemented
177 | null
178 | null_stmt
179 | obj_c_at_catch_stmt
180 | obj_c_at_finally_stmt
181 | obj_c_at_synchronized_stmt
182 | obj_c_at_throw_stmt
183 | obj_c_at_try_stmt
184 | obj_c_autorelease_pool_stmt
185 | obj_c_availability_check_expr
186 | obj_c_bool_literal_expr
187 | obj_c_bridged_cast_expr
188 | obj_c_category_decl
189 | obj_c_category_impl_decl
190 | obj_c_class_method_decl
191 | obj_c_class_ref
192 | obj_c_dynamic_decl
193 | obj_c_encode_expr
194 | obj_c_for_collection_stmt
195 | obj_c_implementation_decl
196 | obj_c_instance_method_decl
197 | obj_c_interface_decl
198 | obj_c_ivar_decl
199 | obj_c_message_expr
200 | obj_c_property_decl
201 | obj_c_protocol_decl
202 | obj_c_protocol_expr
203 | obj_c_protocol_ref
204 | obj_c_selector_expr
205 | obj_c_self_expr
206 | obj_c_string_literal
207 | obj_c_super_class_ref
208 | obj_c_synthesize_decl
209 | offset_of_expr
210 | omp_array_section_expr
211 | omp_atomic_directive
212 | omp_barrier_directive
213 | omp_cancel_directive
214 | omp_cancellation_point_directive
215 | omp_critical_directive
216 | omp_distribute_directive
217 | omp_distribute_parallel_for_directive
218 | omp_distribute_parallel_for_simd_directive
219 | omp_distribute_simd_directive
220 | omp_flush_directive
221 | omp_for_directive
222 | omp_for_simd_directive
223 | omp_master_directive
224 | omp_ordered_directive
225 | omp_parallel_directive
226 | omp_parallel_for_directive
227 | omp_parallel_for_simd_directive
228 | omp_parallel_sections_directive
229 | omp_section_directive
230 | omp_sections_directive
231 | omp_simd_directive
232 | omp_single_directive
233 | omp_target_data_directive
234 | omp_target_directive
235 | omp_target_enter_data_directive
236 | omp_target_exit_data_directive
237 | omp_target_parallel_directive
238 | omp_target_parallel_for_directive
239 | omp_target_parallel_for_simd_directive
240 | omp_target_simd_directive
241 | omp_target_teams_directive
242 | omp_target_teams_distribute_directive
243 | omp_target_teams_distribute_parallel_for_directive
244 | omp_target_teams_distribute_parallel_for_simd_directive
245 | omp_target_teams_distribute_simd_directive
246 | omp_target_update_directive
247 | omp_task_directive
248 | omp_taskgroup_directive
249 | omp_task_loop_directive
250 | omp_task_loop_simd_directive
251 | omp_taskwait_directive
252 | omp_taskyield_directive
253 | omp_teams_directive
254 | omp_teams_distribute_directive
255 | omp_teams_distribute_parallel_for_directive
256 | omp_teams_distribute_parallel_for_simd_directive
257 | omp_teams_distribute_simd_directive
258 | opaque_value_expr
259 | original
260 | overload_candidate
261 | overloaded_decl_ref
262 | override_attr
263 | overrides
264 | packed_attr
265 | pack_expansion_expr
266 | pack_expansion_type
267 | paragraph_comment
268 | paren_expr
269 | paren_list_expr
270 | paren_type
271 | parm_decl
272 | parm_var_decl
273 | pointer_type
274 | predefined_expr
275 | private
276 | protected
277 | public
278 | pure_attr
279 | qual_type
280 | record
281 | record_decl
282 | record_type
283 | release_capability_attr
284 | requires_capability_attr
285 | restrict_attr
286 | return_stmt
287 | returns_twice_attr
288 | ruct
289 | r_value_reference_type
290 | scoped_lockable_attr
291 | seh_except_stmt
292 | seh_finally_stmt
293 | seh_leave_stmt
294 | seh_try_stmt
295 | size_of_pack_expr
296 | static_assert
297 | static_assert_decl
298 | stmt_expr
299 | string_literal
300 | struct_decl
301 | subst_non_type_template_parm_expr
302 | subst_template_type_parm_type
303 | switch_stmt
304 | template_argument
305 | template_ref
306 | template_specialization_type
307 | template_template_parameter
308 | template_template_parm_decl
309 | template_type_parameter
310 | template_type_parm
311 | template_type_parm_decl
312 | template_type_parm_type
313 | text_comment
314 | translation_unit
315 | translation_unit_decl
316 | type_alias_decl
317 | type_alias_template_decl
318 | typedef
319 | typedef_decl
320 | typedef_type
321 | type_ref
322 | type_visibility_attr
323 | unary_expr
324 | unary_expr_or_type_trait_expr
325 | unary_operator
326 | unary_transform_type
327 | unexposed_attr
328 | unexposed_decl
329 | unexposed_expr
330 | unexposed_stmt
331 | unhandled
332 | union_decl
333 | unresolved_lookup_expr
334 | unresolved_member_expr
335 | unused_attr
336 | using_decl
337 | using_declaration
338 | using_directive
339 | using_directive_decl
340 | using_shadow_decl
341 | va_arg_expr
342 | var_decl
343 | variable_ref
344 | virtual
345 | visibility_attr
346 | warn_unused_result_attr
347 | while_stmt
348 | }
349 |
350 | // Take into account that records of this map are sorted alphabetically A -> Z, but 'bad' value is on the top.
351 | // Use this style when defining a new record.
352 | const str_to_node_kind_map = {
353 | 'BAD': NodeKind.bad // is used only inside a C2V to mark unknown or corrupted node.
354 | 'AccessSpecDecl': .access_spec_decl
355 | 'AcquireCapabilityAttr': .acquire_capability_attr
356 | 'AddrLabelExpr': .addr_label_expr
357 | 'AlignedAttr': .aligned_attr
358 | 'AllocSizeAttr': .alloc_size_attr
359 | 'AlwaysInlineAttr': .always_inline_attr
360 | 'AnalyzerNoReturnAttr': .analyzer_no_return_attr
361 | 'ArrayFiller': .array_filler
362 | 'ArraySubscriptExpr': .array_subscript_expr
363 | 'AsmLabelAttr': .asm_label_attr
364 | 'AssertExclusiveLockAttr': .assert_exclusive_lock_attr
365 | 'AtomicExpr': .atomic_expr
366 | 'AvailabilityAttr': .availability_attr
367 | 'BinaryOperator': .binary_operator
368 | 'BlockCommandComment': .block_command_comment
369 | 'BlockExpr': .block_expr
370 | 'BreakStmt': .break_stmt
371 | 'BuiltinTemplateDecl': .builtin_template_decl
372 | 'BuiltinType': .builtin_type
373 | 'CallExpr': .call_expr
374 | 'CapabilityAttr': .capability_attr
375 | 'CaseStmt': .case_stmt
376 | 'CharacterLiteral': .character_literal
377 | 'ClassDecl': .class_decl
378 | 'ClassTemplate': .class_template
379 | 'ClassTemplateDecl': .class_template_decl
380 | 'ClassTemplatePartialSpecialization': .class_template_partial_specialization
381 | 'ClassTemplatePartialSpecializationDecl': .class_template_partial_specialization_decl
382 | 'ClassTemplateSpecialization': .class_template_specialization
383 | 'ClassTemplateSpecializationDecl': .class_template_specialization_decl
384 | 'ColdAttr': .cold_attr
385 | 'CompoundAssignOperator': .compound_assign_operator
386 | 'CompoundLiteralExpr': .compound_literal_expr
387 | 'CompoundStmt': .compound_stmt
388 | 'ConditionalOperator': .conditional_operator
389 | 'ConstantArrayType': .constant_array_type
390 | 'ConstantExpr': .constant_expr
391 | 'ConstAttr': .const_attr
392 | 'ContinueStmt': .continue_stmt
393 | 'CStyleCastExpr': .c_style_cast_expr
394 | 'CXCursorKind': .cx_cursor_kind
395 | 'CXX': .cxx
396 | 'CXXAccessSpecifier': .cxx_access_specifier
397 | 'CXXBindTemporaryExpr': .cxx_bind_temporary_expr
398 | 'CXXBoolLiteralExpr': .cxx_bool_literal_expr
399 | 'CXXCatchStmt': .cxx_catch_stmt
400 | 'CXXConstCastExpr': .cxx_const_cast_expr
401 | 'CXXConstructExpr': .cxx_construct_expr
402 | 'CXXConstructor': .cxx_constructor
403 | 'CXXConstructorDecl': .cxx_constructor_decl
404 | 'CXXConversion': .cxx_conversion
405 | 'CXXConversionDecl': .cxx_conversion_decl
406 | 'CXXCtorInitializer': .cxx_ctor_initializer
407 | 'CXXDefaultArgExpr': .cxx_default_arg_expr
408 | 'CXXDefaultInitExpr': .cxx_default_init_expr
409 | 'CXXDeleteExpr': .cxx_delete_expr
410 | 'CXXDependentScopeMemberExpr': .cxx_dependent_scope_member_expr
411 | 'CXXDestructor': .cxx_destructor
412 | 'CXXDestructorDecl': .cxx_destructor_decl
413 | 'CXXDynamicCastExpr': .cxx_dynamic_cast_expr
414 | 'CXXForRangeStmt': .cxx_for_range_stmt
415 | 'CXXFunctionalCastExpr': .cxx_functional_cast_expr
416 | 'CXXMemberCallExpr': .cxx_member_call_expr
417 | 'CXXMethod': .cxx_method
418 | 'CXXMethodDecl': .cxx_method_decl
419 | 'CXXNewExpr': .cxx_new_expr
420 | 'CXXNoexceptExpr': .cxx_noexcept_expr
421 | 'CXXNullPtrLiteralExpr': .cxx_null_ptr_literal_expr
422 | 'CXXOperatorCallExpr': .cxx_operator_call_expr
423 | 'CXXPseudoDestructorExpr': .cxx_pseudo_destructor_expr
424 | 'CXXRecord': .cxx_record
425 | 'CXXRecordDecl': .cxx_record_decl
426 | 'CXXReinterpretCastExpr': .cxx_reinterpret_cast_expr
427 | 'CXXScalarValueInitExpr': .cxx_scalar_value_init_expr
428 | 'CXXStaticCastExpr': .cxx_static_cast_expr
429 | 'CXXTemporaryObjectExpr': .cxx_temporary_object_expr
430 | 'CXXThisExpr': .cxx_this_expr
431 | 'CXXThrowExpr': .cxx_throw_expr
432 | 'CXXTryStmt': .cxx_try_stmt
433 | 'CXXTypeidExpr': .cxx_typeid_expr
434 | 'CXXUnresolvedConstructExpr': .cxx_unresolved_construct_expr
435 | 'DecayedType': .decayed_type
436 | 'DeclRefExpr': .decl_ref_expr
437 | 'DeclStmt': .decl_stmt
438 | 'DecltypeType': .decltype_type
439 | 'DefaultStmt': .default_stmt
440 | 'DependentNameType': .dependent_name_type
441 | 'DependentScopeDeclRefExpr': .dependent_scope_decl_ref_expr
442 | 'DependentTemplateSpecializationType': .dependent_template_specialization_type
443 | 'DeprecatedAttr': .deprecated_attr
444 | 'DiagnoseIfAttr': .diagnose_if_attr
445 | 'DisableTailCallsAttr': .disable_tail_calls_attr
446 | 'DoStmt': .do_stmt
447 | 'ElaboratedType': .elaborated_type
448 | 'EnableIfAttr': .enable_if_attr
449 | 'Enum': .@enum
450 | 'EnumConstantDecl': .enum_constant_decl
451 | 'EnumDecl': .enum_decl
452 | 'EnumType': .enum_type
453 | 'ExprWithCleanups': .expr_with_cleanups
454 | 'Field': .field
455 | 'FieldDecl': .field_decl
456 | 'FixedPointLiteral': .fixed_point_literal
457 | 'FloatingLiteral': .floating_literal
458 | 'FormatArgAttr': .format_arg_attr
459 | 'FormatAttr': .format_attr
460 | 'ForStmt': .for_stmt
461 | 'FriendDecl': .friend_decl
462 | 'FullComment': .full_comment
463 | 'Function': .function
464 | 'FunctionDecl': .function_decl
465 | 'FunctionNoProtoType': .function_no_proto_type
466 | 'FunctionProtoType': .function_proto_type
467 | 'FunctionTemplate': .function_template
468 | 'FunctionTemplateDecl': .function_template_decl
469 | 'GCCAsmStmt': .gcc_asm_stmt
470 | 'GenericSelectionExpr': .generic_selection_expr
471 | 'GNUNullExpr': .gnu_null_expr
472 | 'GotoStmt': .goto_stmt
473 | 'GuardedByAttr': .guarded_by_attr
474 | 'HTMLEndTagComment': .html_end_tag_comment
475 | 'HTMLStartTagComment': .html_start_tag_comment
476 | 'IfStmt': .if_stmt
477 | 'ImaginaryLiteral': .imaginary_literal
478 | 'ImplicitCastExpr': .implicit_cast_expr
479 | 'ImplicitValueInitExpr': .implicit_value_init_expr
480 | 'IncompleteArrayType': .incomplete_array_type
481 | 'IndirectFieldDecl': .indirect_field_decl
482 | 'IndirectGotoStmt': .indirect_goto_stmt
483 | 'InitListExpr': .init_list_expr
484 | 'InjectedClassNameType': .injected_class_name_type
485 | 'InlineCommandComment': .inline_command_comment
486 | 'IntegerLiteral': .integer_literal
487 | 'InvalidCode': .invalid_code
488 | 'InvalidFile': .invalid_file
489 | 'LabelRef': .label_ref
490 | 'LabelStmt': .label_stmt
491 | 'LambdaExpr': .lambda_expr
492 | 'LinkageSpec': .linkage_spec
493 | 'LinkageSpecDecl': .linkage_spec_decl
494 | 'LValueReferenceType': .l_value_reference_type
495 | 'MaterializeTemporaryExpr': .materialize_temporary_expr
496 | 'MaxFieldAlignmentAttr': .max_field_alignment_attr
497 | 'MemberExpr': .member_expr
498 | 'MemberPointerType': .member_pointer_type
499 | 'MemberRef': .member_ref
500 | 'MemberRefExpr': .member_ref_expr
501 | 'ModuleImport': .module_import
502 | 'MSAsmStmt': .ms_asm_stmt
503 | 'Namespace': .namespace
504 | 'NamespaceAlias': .namespace_alias
505 | 'NamespaceDecl': .namespace_decl
506 | 'NamespaceRef': .namespace_ref
507 | 'NoDeclFound': .no_decl_found
508 | 'NoEscapeAttr': .no_escape_attr
509 | 'NoInlineAttr': .no_inline_attr
510 | 'NonTypeTemplateParameter': .non_type_template_parameter
511 | 'NonTypeTemplateParmDecl': .non_type_template_parm_decl
512 | 'NoSanitizeAttr': .no_sanitize_attr
513 | 'NoThrowAttr': .no_throw_attr
514 | 'NotImplemented': .not_implemented
515 | 'Null': .null
516 | 'NullStmt': .null_stmt
517 | 'ObjCAtCatchStmt': .obj_c_at_catch_stmt
518 | 'ObjCAtFinallyStmt': .obj_c_at_finally_stmt
519 | 'ObjCAtSynchronizedStmt': .obj_c_at_synchronized_stmt
520 | 'ObjCAtThrowStmt': .obj_c_at_throw_stmt
521 | 'ObjCAtTryStmt': .obj_c_at_try_stmt
522 | 'ObjCAutoreleasePoolStmt': .obj_c_autorelease_pool_stmt
523 | 'ObjCAvailabilityCheckExpr': .obj_c_availability_check_expr
524 | 'ObjCBoolLiteralExpr': .obj_c_bool_literal_expr
525 | 'ObjCBridgedCastExpr': .obj_c_bridged_cast_expr
526 | 'ObjCCategoryDecl': .obj_c_category_decl
527 | 'ObjCCategoryImplDecl': .obj_c_category_impl_decl
528 | 'ObjCClassMethodDecl': .obj_c_class_method_decl
529 | 'ObjCClassRef': .obj_c_class_ref
530 | 'ObjCDynamicDecl': .obj_c_dynamic_decl
531 | 'ObjCEncodeExpr': .obj_c_encode_expr
532 | 'ObjCForCollectionStmt': .obj_c_for_collection_stmt
533 | 'ObjCImplementationDecl': .obj_c_implementation_decl
534 | 'ObjCInstanceMethodDecl': .obj_c_instance_method_decl
535 | 'ObjCInterfaceDecl': .obj_c_interface_decl
536 | 'ObjCIvarDecl': .obj_c_ivar_decl
537 | 'ObjCMessageExpr': .obj_c_message_expr
538 | 'ObjCPropertyDecl': .obj_c_property_decl
539 | 'ObjCProtocolDecl': .obj_c_protocol_decl
540 | 'ObjCProtocolExpr': .obj_c_protocol_expr
541 | 'ObjCProtocolRef': .obj_c_protocol_ref
542 | 'ObjCSelectorExpr': .obj_c_selector_expr
543 | 'ObjCSelfExpr': .obj_c_self_expr
544 | 'ObjCStringLiteral': .obj_c_string_literal
545 | 'ObjCSuperClassRef': .obj_c_super_class_ref
546 | 'ObjCSynthesizeDecl': .obj_c_synthesize_decl
547 | 'OffsetOfExpr': .offset_of_expr
548 | 'OMPArraySectionExpr': .omp_array_section_expr
549 | 'OMPAtomicDirective': .omp_atomic_directive
550 | 'OMPBarrierDirective': .omp_barrier_directive
551 | 'OMPCancelDirective': .omp_cancel_directive
552 | 'OMPCancellationPointDirective': .omp_cancellation_point_directive
553 | 'OMPCriticalDirective': .omp_critical_directive
554 | 'OMPDistributeDirective': .omp_distribute_directive
555 | 'OMPDistributeParallelForDirective': .omp_distribute_parallel_for_directive
556 | 'OMPDistributeParallelForSimdDirective': .omp_distribute_parallel_for_simd_directive
557 | 'OMPDistributeSimdDirective': .omp_distribute_simd_directive
558 | 'OMPFlushDirective': .omp_flush_directive
559 | 'OMPForDirective': .omp_for_directive
560 | 'OMPForSimdDirective': .omp_for_simd_directive
561 | 'OMPMasterDirective': .omp_master_directive
562 | 'OMPOrderedDirective': .omp_ordered_directive
563 | 'OMPParallelDirective': .omp_parallel_directive
564 | 'OMPParallelForDirective': .omp_parallel_for_directive
565 | 'OMPParallelForSimdDirective': .omp_parallel_for_simd_directive
566 | 'OMPParallelSectionsDirective': .omp_parallel_sections_directive
567 | 'OMPSectionDirective': .omp_section_directive
568 | 'OMPSectionsDirective': .omp_sections_directive
569 | 'OMPSimdDirective': .omp_simd_directive
570 | 'OMPSingleDirective': .omp_single_directive
571 | 'OMPTargetDataDirective': .omp_target_data_directive
572 | 'OMPTargetDirective': .omp_target_directive
573 | 'OMPTargetEnterDataDirective': .omp_target_enter_data_directive
574 | 'OMPTargetExitDataDirective': .omp_target_exit_data_directive
575 | 'OMPTargetParallelDirective': .omp_target_parallel_directive
576 | 'OMPTargetParallelForDirective': .omp_target_parallel_for_directive
577 | 'OMPTargetParallelForSimdDirective': .omp_target_parallel_for_simd_directive
578 | 'OMPTargetSimdDirective': .omp_target_simd_directive
579 | 'OMPTargetTeamsDirective': .omp_target_teams_directive
580 | 'OMPTargetTeamsDistributeDirective': .omp_target_teams_distribute_directive
581 | 'OMPTargetTeamsDistributeParallelForDirective': .omp_target_teams_distribute_parallel_for_directive
582 | 'OMPTargetTeamsDistributeParallelForSimdDirective': .omp_target_teams_distribute_parallel_for_simd_directive
583 | 'OMPTargetTeamsDistributeSimdDirective': .omp_target_teams_distribute_simd_directive
584 | 'OMPTargetUpdateDirective': .omp_target_update_directive
585 | 'OMPTaskDirective': .omp_task_directive
586 | 'OMPTaskgroupDirective': .omp_taskgroup_directive
587 | 'OMPTaskLoopDirective': .omp_task_loop_directive
588 | 'OMPTaskLoopSimdDirective': .omp_task_loop_simd_directive
589 | 'OMPTaskwaitDirective': .omp_taskwait_directive
590 | 'OMPTaskyieldDirective': .omp_taskyield_directive
591 | 'OMPTeamsDirective': .omp_teams_directive
592 | 'OMPTeamsDistributeDirective': .omp_teams_distribute_directive
593 | 'OMPTeamsDistributeParallelForDirective': .omp_teams_distribute_parallel_for_directive
594 | 'OMPTeamsDistributeParallelForSimdDirective': .omp_teams_distribute_parallel_for_simd_directive
595 | 'OMPTeamsDistributeSimdDirective': .omp_teams_distribute_simd_directive
596 | 'OpaqueValueExpr': .opaque_value_expr
597 | 'original': .original
598 | 'OverloadCandidate': .overload_candidate
599 | 'OverloadedDeclRef': .overloaded_decl_ref
600 | 'OverrideAttr': .override_attr
601 | 'Overrides': .overrides
602 | 'PackedAttr': .packed_attr
603 | 'PackExpansionExpr': .pack_expansion_expr
604 | 'PackExpansionType': .pack_expansion_type
605 | 'ParagraphComment': .paragraph_comment
606 | 'ParenExpr': .paren_expr
607 | 'ParenListExpr': .paren_list_expr
608 | 'ParenType': .paren_type
609 | 'ParmDecl': .parm_decl
610 | 'ParmVarDecl': .parm_var_decl
611 | 'PointerType': .pointer_type
612 | 'PredefinedExpr': .predefined_expr
613 | 'private': .private
614 | 'protected': .protected
615 | 'public': .public
616 | 'PureAttr': .pure_attr
617 | 'QualType': .qual_type
618 | 'Record': .record
619 | 'RecordDecl': .record_decl
620 | 'RecordType': .record_type
621 | 'ReleaseCapabilityAttr': .release_capability_attr
622 | 'RequiresCapabilityAttr': .requires_capability_attr
623 | 'RestrictAttr': .restrict_attr
624 | 'ReturnStmt': .return_stmt
625 | 'ReturnsTwiceAttr': .returns_twice_attr
626 | 'ruct': .ruct
627 | 'RValueReferenceType': .r_value_reference_type
628 | 'ScopedLockableAttr': .scoped_lockable_attr
629 | 'SEHExceptStmt': .seh_except_stmt
630 | 'SEHFinallyStmt': .seh_finally_stmt
631 | 'SEHLeaveStmt': .seh_leave_stmt
632 | 'SEHTryStmt': .seh_try_stmt
633 | 'SizeOfPackExpr': .size_of_pack_expr
634 | 'StaticAssert': .static_assert
635 | 'StaticAssertDecl': .static_assert_decl
636 | 'StmtExpr': .stmt_expr
637 | 'StringLiteral': .string_literal
638 | 'StructDecl': .struct_decl
639 | 'SubstNonTypeTemplateParmExpr': .subst_non_type_template_parm_expr
640 | 'SubstTemplateTypeParmType': .subst_template_type_parm_type
641 | 'SwitchStmt': .switch_stmt
642 | 'TemplateArgument': .template_argument
643 | 'TemplateRef': .template_ref
644 | 'TemplateSpecializationType': .template_specialization_type
645 | 'TemplateTemplateParameter': .template_template_parameter
646 | 'TemplateTemplateParmDecl': .template_template_parm_decl
647 | 'TemplateTypeParameter': .template_type_parameter
648 | 'TemplateTypeParm': .template_type_parm
649 | 'TemplateTypeParmDecl': .template_type_parm_decl
650 | 'TemplateTypeParmType': .template_type_parm_type
651 | 'TextComment': .text_comment
652 | 'TranslationUnit': .translation_unit
653 | 'TranslationUnitDecl': .translation_unit_decl
654 | 'TypeAliasDecl': .type_alias_decl
655 | 'TypeAliasTemplateDecl': .type_alias_template_decl
656 | 'Typedef': .typedef
657 | 'TypedefDecl': .typedef_decl
658 | 'TypedefType': .typedef_type
659 | 'TypeRef': .type_ref
660 | 'TypeVisibilityAttr': .type_visibility_attr
661 | 'UnaryExpr': .unary_expr
662 | 'UnaryExprOrTypeTraitExpr': .unary_expr_or_type_trait_expr
663 | 'UnaryOperator': .unary_operator
664 | 'UnaryTransformType': .unary_transform_type
665 | 'UnexposedAttr': .unexposed_attr
666 | 'UnexposedDecl': .unexposed_decl
667 | 'UnexposedExpr': .unexposed_expr
668 | 'UnexposedStmt': .unexposed_stmt
669 | 'Unhandled': .unhandled
670 | 'UnionDecl': .union_decl
671 | 'UnresolvedLookupExpr': .unresolved_lookup_expr
672 | 'UnresolvedMemberExpr': .unresolved_member_expr
673 | 'UnusedAttr': .unused_attr
674 | 'UsingDecl': .using_decl
675 | 'UsingDeclaration': .using_declaration
676 | 'UsingDirective': .using_directive
677 | 'UsingDirectiveDecl': .using_directive_decl
678 | 'UsingShadowDecl': .using_shadow_decl
679 | 'VAArgExpr': .va_arg_expr
680 | 'VarDecl': .var_decl
681 | 'VariableRef': .variable_ref
682 | 'virtual': .virtual
683 | 'VisibilityAttr': .visibility_attr
684 | 'WarnUnusedResultAttr': .warn_unused_result_attr
685 | 'WhileStmt': .while_stmt
686 | }
687 |
688 | // Reverse process is done in a runtime, so this map always contains correct data.
689 | // We are using reversed str_to_node_kind_map to implement NodeKind.str() method.
690 | const node_kind_to_str_map = reverse_str_to_node_kind_map()
691 |
692 | // Use this method when you want to convert a node's name into NodeKind enum form.
693 | // ATTENTION: the 'value' parameter is case sensitive!
694 | //
695 | // Example:
696 | // convert_str_into_node_kind('AccessSpecDecl') -> NodeKind.access_spec_decl
697 | // convert_str_into_node_kind('access_spec_decl') -> NodeKind.bad
698 | // convert_str_into_node_kind('RANDOM123_NOT_EXISTS') -> NodeKind.bad
699 | pub fn convert_str_into_node_kind(value string) NodeKind {
700 | return str_to_node_kind_map[value] or { NodeKind.bad }
701 | }
702 |
703 | // ATTENTION: NodeKind string form - is the original name of a node, generated by Clang AST,
704 | // not a 'node_kind_enum_member_name'.
705 | //
706 | // Example:
707 | // NodeKind.access_spec_decl.str() -> 'AccessSpecDecl'
708 | pub fn (kind NodeKind) str() string {
709 | return node_kind_to_str_map[kind]
710 | }
711 |
712 | fn reverse_str_to_node_kind_map() map[NodeKind]string {
713 | mut reversed_map := map[NodeKind]string{}
714 |
715 | for key, value in str_to_node_kind_map {
716 | reversed_map[value] = key
717 | }
718 |
719 | return reversed_map
720 | }
721 |
--------------------------------------------------------------------------------
/src/struct.v:
--------------------------------------------------------------------------------
1 | module main
2 |
3 | import strings
4 |
5 | // |-RecordDecl 0x7fd7c302c560 line:3:8 struct User definition
6 | fn (mut c C2V) record_decl(node &Node) {
7 | vprintln('record_decl("${node.name}")')
8 | // Skip empty structs (extern or forward decls)
9 | if node.kindof(.record_decl) && node.inner.len == 0 {
10 | return
11 | }
12 | mut c_name := node.name
13 | // Dont generate struct header if it was already generated by typedef
14 | // Confusing, but typedefs in C AST are really messy.
15 | // ...
16 | // If the struct has no name, then it's `typedef struct { ... } name`
17 | // AST: 1) RecordDecl struct definition 2) TypedefDecl struct name
18 | if c.tree.inner.len > c.node_i + 1 {
19 | next_node := c.tree.inner[c.node_i + 1]
20 | if next_node.kind == .typedef_decl {
21 | if c.is_verbose {
22 | c.genln('// typedef struct')
23 | }
24 | c_name = next_node.name
25 | if c_name.contains('apthing_t') {
26 | vprintln(node.str())
27 | }
28 | }
29 | }
30 |
31 | if c_name in builtin_type_names {
32 | return
33 | }
34 | if c.is_verbose {
35 | c.genln('// struct decl name="${c_name}"')
36 | }
37 | if c_name in c.types {
38 | if node.previous_declaration == '' {
39 | return
40 | }
41 | }
42 | // Anonymous struct, most likely the next node is a vardecl with this anon struct type, so remember it
43 | if c_name == '' {
44 | c_name = 'AnonStruct_${node.location.line}'
45 | c.last_declared_type_name = c_name
46 | }
47 | if c_name !in ['struct', 'union'] {
48 | v_name := c.add_struct_name(mut c.types, c_name)
49 | // prevent duplicate generations:
50 | if v_name in c.generated_declarations {
51 | return
52 | }
53 | c.generated_declarations[v_name] = true
54 | if node.tags.contains('union') {
55 | c.genln('union ${v_name} { ')
56 | } else {
57 | c.genln('struct ${v_name} { ')
58 | }
59 | }
60 | mut new_struct := Struct{}
61 | // in V it's `field struct {...}`, but in C we get struct definition first, so save it and use it in the
62 | // next child
63 | mut anon_struct_definition := ''
64 | for field in node.inner {
65 | c.gen_comment(field)
66 | // Handle anon structs
67 | if field.kind == .record_decl {
68 | anon_struct_definition = c.anon_struct_field_type(field)
69 | continue
70 | }
71 | // There may be comments, skip them
72 | if field.kind != .field_decl {
73 | continue
74 | }
75 | field_type := convert_type(field.ast_type.qualified)
76 | field_name := filter_name(field.name, false).uncapitalize()
77 | mut field_type_name := field_type.name
78 |
79 | // Handle anon structs, the anonymous struct has just been defined above, use its definition
80 | if field_type_name.contains('unnamed at') {
81 | field_type_name = anon_struct_definition
82 | }
83 | if field_type_name.contains('anonymous at') {
84 | continue
85 | }
86 | /*
87 | if field_type.name.contains('union') {
88 | continue // TODO
89 | }
90 | */
91 | new_struct.fields << field_name
92 | if field_type.name.ends_with('_s') { // TODO doom _t _s hack, remove
93 | n := field_type.name[..field_type.name.len - 2] + '_t'
94 | c.genln('\t${field_name} ${n}')
95 | } else {
96 | c.genln('\t${field_name} ${field_type_name}')
97 | }
98 | }
99 | c.structs[c_name] = new_struct
100 | c.genln('}')
101 | }
102 |
103 | fn (mut c C2V) anon_struct_field_type(node &Node) string {
104 | mut sb := strings.new_builder(50)
105 | sb.write_string(' struct {')
106 | for field in node.inner {
107 | if field.kind != .field_decl {
108 | continue
109 | }
110 | field_type := convert_type(field.ast_type.qualified)
111 | field_name := filter_name(field.name, false)
112 | sb.write_string('\t${field_name} ${field_type.name}\n')
113 | }
114 | sb.write_string('}\n')
115 | return sb.str()
116 | }
117 |
118 | // Typedef node goes after struct enum, but we need to parse it first, so that "type name { " is
119 | // generated first
120 | fn (mut c C2V) typedef_decl(node &Node) {
121 | mut typ := node.ast_type.qualified
122 | // just a single line typedef: (alias)
123 | // typedef sha1_context_t sha1_context_s ;
124 | // typedef after enum decl, just generate "enum NAME {" header
125 | mut c_alias_name := node.name // get_val(-2)
126 | if c_alias_name.contains('et_context_t') {
127 | // TODO remove this
128 | return
129 | }
130 | if c_alias_name in builtin_type_names {
131 | return
132 | }
133 |
134 | if c_alias_name in c.types || c_alias_name in c.enums {
135 | // This means that this is a struct/enum typedef that has already been defined.
136 | return
137 | }
138 |
139 | v_alias_name := c.add_struct_name(mut c.types, c_alias_name)
140 |
141 | if typ.starts_with('struct ') && typ.ends_with(' *') {
142 | // Opaque pointer, for example: typedef struct TSTexture_t *TSTexture;
143 | c.genln('type ${v_alias_name} = voidptr')
144 | return
145 | }
146 |
147 | if !typ.contains(c_alias_name) {
148 | if typ.contains('(*)') {
149 | tt := convert_type(typ)
150 | typ = tt.name
151 | }
152 | // Struct types have junk before spaces
153 | else {
154 | c_alias_name = c_alias_name.all_after(' ')
155 | tt := convert_type(typ)
156 | typ = tt.name
157 | }
158 | if c_alias_name.starts_with('__') {
159 | // Skip internal stuff like __builtin_ms_va_list
160 | return
161 | }
162 | if typ in c.enums {
163 | return
164 | }
165 |
166 | mut cgen_alias := typ
167 | if cgen_alias.starts_with('_') {
168 | cgen_alias = trim_underscores(typ)
169 | }
170 | if typ !in ['int', 'i8', 'i16', 'i64', 'u8', 'u16', 'u32', 'u64', 'f32', 'f64', 'usize', 'isize', 'bool', 'void', 'voidptr']
171 | && !typ.starts_with('fn (') {
172 | // TODO handle this better
173 | cgen_alias = cgen_alias.capitalize()
174 | }
175 | c.genln('type ${c_alias_name.capitalize()} = ${cgen_alias}') // typedef alias (SINGLE LINE)')
176 | return
177 | }
178 | if typ.contains('enum ') {
179 | // enums were alredy handled in enum_decl
180 | return
181 | } else if typ.contains('struct ') {
182 | // structs were already handled in struct_decl
183 | return
184 | } else if typ.contains('union ') {
185 | // unions were alredy handled in struct_decl
186 | return
187 | }
188 | }
189 |
190 | // this calls typedef_decl() above
191 | fn (mut c C2V) parse_next_typedef() bool {
192 | // Hack: typedef with the actual enum name is next, parse it and generate "enum NAME {" first
193 | /*
194 | XTODO
195 | next_line := c.lines[c.line_i + 1]
196 | if next_line.contains('TypedefDecl') {
197 | c.line_i++
198 | c.parse_next_node()
199 | return true
200 | }
201 | */
202 | return false
203 | }
204 |
--------------------------------------------------------------------------------
/tests/1.hello.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main() {
4 | printf("hello world!");
5 | return 0;
6 | }
7 |
8 | typedef struct Foo {
9 | int bar;
10 | } Foo;
11 |
12 | void implicit_inits() {
13 | int num;
14 | Foo foo;
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/tests/1.hello.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn main() {
5 | C.printf(c'hello world!')
6 | return
7 | }
8 |
9 | struct Foo {
10 | bar int
11 | }
12 |
13 | fn implicit_inits() {
14 | num := 0
15 | foo := Foo{}
16 | }
17 |
--------------------------------------------------------------------------------
/tests/10.jni.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation. Oracle designates this
8 | * particular file as subject to the "Classpath" exception as provided
9 | * by Oracle in the LICENSE file that accompanied this code.
10 | *
11 | * This code is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 | * version 2 for more details (a copy is included in the LICENSE file that
15 | * accompanied this code).
16 | *
17 | * You should have received a copy of the GNU General Public License version
18 | * 2 along with this work; if not, write to the Free Software Foundation,
19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 | *
21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 | * or visit www.oracle.com if you need additional information or have any
23 | * questions.
24 | */
25 |
26 | #ifndef CLASSFILE_CONSTANTS_H
27 | #define CLASSFILE_CONSTANTS_H
28 |
29 | #ifdef __cplusplus
30 | extern "C" {
31 | #endif
32 |
33 | /* Classfile version number for this information */
34 | #define JVM_CLASSFILE_MAJOR_VERSION @@VERSION_CLASSFILE_MAJOR@@
35 | #define JVM_CLASSFILE_MINOR_VERSION @@VERSION_CLASSFILE_MINOR@@
36 |
37 | /* Flags */
38 |
39 | enum {
40 | JVM_ACC_PUBLIC = 0x0001,
41 | JVM_ACC_PRIVATE = 0x0002,
42 | JVM_ACC_PROTECTED = 0x0004,
43 | JVM_ACC_STATIC = 0x0008,
44 | JVM_ACC_FINAL = 0x0010,
45 | JVM_ACC_SYNCHRONIZED = 0x0020,
46 | JVM_ACC_SUPER = 0x0020,
47 | JVM_ACC_VOLATILE = 0x0040,
48 | JVM_ACC_BRIDGE = 0x0040,
49 | JVM_ACC_TRANSIENT = 0x0080,
50 | JVM_ACC_VARARGS = 0x0080,
51 | JVM_ACC_NATIVE = 0x0100,
52 | JVM_ACC_INTERFACE = 0x0200,
53 | JVM_ACC_ABSTRACT = 0x0400,
54 | JVM_ACC_STRICT = 0x0800,
55 | JVM_ACC_SYNTHETIC = 0x1000,
56 | JVM_ACC_ANNOTATION = 0x2000,
57 | JVM_ACC_ENUM = 0x4000,
58 | JVM_ACC_MODULE = 0x8000
59 | };
60 |
61 | #define JVM_ACC_PUBLIC_BIT 0
62 | #define JVM_ACC_PRIVATE_BIT 1
63 | #define JVM_ACC_PROTECTED_BIT 2
64 | #define JVM_ACC_STATIC_BIT 3
65 | #define JVM_ACC_FINAL_BIT 4
66 | #define JVM_ACC_SYNCHRONIZED_BIT 5
67 | #define JVM_ACC_SUPER_BIT 5
68 | #define JVM_ACC_VOLATILE_BIT 6
69 | #define JVM_ACC_BRIDGE_BIT 6
70 | #define JVM_ACC_TRANSIENT_BIT 7
71 | #define JVM_ACC_VARARGS_BIT 7
72 | #define JVM_ACC_NATIVE_BIT 8
73 | #define JVM_ACC_INTERFACE_BIT 9
74 | #define JVM_ACC_ABSTRACT_BIT 10
75 | #define JVM_ACC_STRICT_BIT 11
76 | #define JVM_ACC_SYNTHETIC_BIT 12
77 | #define JVM_ACC_ANNOTATION_BIT 13
78 | #define JVM_ACC_ENUM_BIT 14
79 |
80 | /* Used in newarray instruction. */
81 |
82 | enum {
83 | JVM_T_BOOLEAN = 4,
84 | JVM_T_CHAR = 5,
85 | JVM_T_FLOAT = 6,
86 | JVM_T_DOUBLE = 7,
87 | JVM_T_BYTE = 8,
88 | JVM_T_SHORT = 9,
89 | JVM_T_INT = 10,
90 | JVM_T_LONG = 11
91 | };
92 |
93 | /* Constant Pool Entries */
94 |
95 | enum {
96 | JVM_CONSTANT_Utf8 = 1,
97 | JVM_CONSTANT_Unicode = 2, /* unused */
98 | JVM_CONSTANT_Integer = 3,
99 | JVM_CONSTANT_Float = 4,
100 | JVM_CONSTANT_Long = 5,
101 | JVM_CONSTANT_Double = 6,
102 | JVM_CONSTANT_Class = 7,
103 | JVM_CONSTANT_String = 8,
104 | JVM_CONSTANT_Fieldref = 9,
105 | JVM_CONSTANT_Methodref = 10,
106 | JVM_CONSTANT_InterfaceMethodref = 11,
107 | JVM_CONSTANT_NameAndType = 12,
108 | JVM_CONSTANT_MethodHandle = 15, // JSR 292
109 | JVM_CONSTANT_MethodType = 16, // JSR 292
110 | JVM_CONSTANT_Dynamic = 17,
111 | JVM_CONSTANT_InvokeDynamic = 18,
112 | JVM_CONSTANT_Module = 19,
113 | JVM_CONSTANT_Package = 20,
114 | JVM_CONSTANT_ExternalMax = 20
115 | };
116 |
117 | /* JVM_CONSTANT_MethodHandle subtypes */
118 | enum {
119 | JVM_REF_getField = 1,
120 | JVM_REF_getStatic = 2,
121 | JVM_REF_putField = 3,
122 | JVM_REF_putStatic = 4,
123 | JVM_REF_invokeVirtual = 5,
124 | JVM_REF_invokeStatic = 6,
125 | JVM_REF_invokeSpecial = 7,
126 | JVM_REF_newInvokeSpecial = 8,
127 | JVM_REF_invokeInterface = 9
128 | };
129 |
130 | /* StackMapTable type item numbers */
131 |
132 | enum {
133 | JVM_ITEM_Top = 0,
134 | JVM_ITEM_Integer = 1,
135 | JVM_ITEM_Float = 2,
136 | JVM_ITEM_Double = 3,
137 | JVM_ITEM_Long = 4,
138 | JVM_ITEM_Null = 5,
139 | JVM_ITEM_UninitializedThis = 6,
140 | JVM_ITEM_Object = 7,
141 | JVM_ITEM_Uninitialized = 8
142 | };
143 |
144 | /* Type signatures */
145 |
146 | enum {
147 | JVM_SIGNATURE_SLASH = '/',
148 | JVM_SIGNATURE_DOT = '.',
149 | JVM_SIGNATURE_SPECIAL = '<',
150 | JVM_SIGNATURE_ENDSPECIAL = '>',
151 | JVM_SIGNATURE_ARRAY = '[',
152 | JVM_SIGNATURE_BYTE = 'B',
153 | JVM_SIGNATURE_CHAR = 'C',
154 | JVM_SIGNATURE_CLASS = 'L',
155 | JVM_SIGNATURE_ENDCLASS = ';',
156 | JVM_SIGNATURE_ENUM = 'E',
157 | JVM_SIGNATURE_FLOAT = 'F',
158 | JVM_SIGNATURE_DOUBLE = 'D',
159 | JVM_SIGNATURE_FUNC = '(',
160 | JVM_SIGNATURE_ENDFUNC = ')',
161 | JVM_SIGNATURE_INT = 'I',
162 | JVM_SIGNATURE_LONG = 'J',
163 | JVM_SIGNATURE_SHORT = 'S',
164 | JVM_SIGNATURE_VOID = 'V',
165 | JVM_SIGNATURE_BOOLEAN = 'Z'
166 | };
167 |
168 | /* Opcodes */
169 |
170 | enum {
171 | JVM_OPC_nop = 0,
172 | JVM_OPC_aconst_null = 1,
173 | JVM_OPC_iconst_m1 = 2,
174 | JVM_OPC_iconst_0 = 3,
175 | JVM_OPC_iconst_1 = 4,
176 | JVM_OPC_iconst_2 = 5,
177 | JVM_OPC_iconst_3 = 6,
178 | JVM_OPC_iconst_4 = 7,
179 | JVM_OPC_iconst_5 = 8,
180 | JVM_OPC_lconst_0 = 9,
181 | JVM_OPC_lconst_1 = 10,
182 | JVM_OPC_fconst_0 = 11,
183 | JVM_OPC_fconst_1 = 12,
184 | JVM_OPC_fconst_2 = 13,
185 | JVM_OPC_dconst_0 = 14,
186 | JVM_OPC_dconst_1 = 15,
187 | JVM_OPC_bipush = 16,
188 | JVM_OPC_sipush = 17,
189 | JVM_OPC_ldc = 18,
190 | JVM_OPC_ldc_w = 19,
191 | JVM_OPC_ldc2_w = 20,
192 | JVM_OPC_iload = 21,
193 | JVM_OPC_lload = 22,
194 | JVM_OPC_fload = 23,
195 | JVM_OPC_dload = 24,
196 | JVM_OPC_aload = 25,
197 | JVM_OPC_iload_0 = 26,
198 | JVM_OPC_iload_1 = 27,
199 | JVM_OPC_iload_2 = 28,
200 | JVM_OPC_iload_3 = 29,
201 | JVM_OPC_lload_0 = 30,
202 | JVM_OPC_lload_1 = 31,
203 | JVM_OPC_lload_2 = 32,
204 | JVM_OPC_lload_3 = 33,
205 | JVM_OPC_fload_0 = 34,
206 | JVM_OPC_fload_1 = 35,
207 | JVM_OPC_fload_2 = 36,
208 | JVM_OPC_fload_3 = 37,
209 | JVM_OPC_dload_0 = 38,
210 | JVM_OPC_dload_1 = 39,
211 | JVM_OPC_dload_2 = 40,
212 | JVM_OPC_dload_3 = 41,
213 | JVM_OPC_aload_0 = 42,
214 | JVM_OPC_aload_1 = 43,
215 | JVM_OPC_aload_2 = 44,
216 | JVM_OPC_aload_3 = 45,
217 | JVM_OPC_iaload = 46,
218 | JVM_OPC_laload = 47,
219 | JVM_OPC_faload = 48,
220 | JVM_OPC_daload = 49,
221 | JVM_OPC_aaload = 50,
222 | JVM_OPC_baload = 51,
223 | JVM_OPC_caload = 52,
224 | JVM_OPC_saload = 53,
225 | JVM_OPC_istore = 54,
226 | JVM_OPC_lstore = 55,
227 | JVM_OPC_fstore = 56,
228 | JVM_OPC_dstore = 57,
229 | JVM_OPC_astore = 58,
230 | JVM_OPC_istore_0 = 59,
231 | JVM_OPC_istore_1 = 60,
232 | JVM_OPC_istore_2 = 61,
233 | JVM_OPC_istore_3 = 62,
234 | JVM_OPC_lstore_0 = 63,
235 | JVM_OPC_lstore_1 = 64,
236 | JVM_OPC_lstore_2 = 65,
237 | JVM_OPC_lstore_3 = 66,
238 | JVM_OPC_fstore_0 = 67,
239 | JVM_OPC_fstore_1 = 68,
240 | JVM_OPC_fstore_2 = 69,
241 | JVM_OPC_fstore_3 = 70,
242 | JVM_OPC_dstore_0 = 71,
243 | JVM_OPC_dstore_1 = 72,
244 | JVM_OPC_dstore_2 = 73,
245 | JVM_OPC_dstore_3 = 74,
246 | JVM_OPC_astore_0 = 75,
247 | JVM_OPC_astore_1 = 76,
248 | JVM_OPC_astore_2 = 77,
249 | JVM_OPC_astore_3 = 78,
250 | JVM_OPC_iastore = 79,
251 | JVM_OPC_lastore = 80,
252 | JVM_OPC_fastore = 81,
253 | JVM_OPC_dastore = 82,
254 | JVM_OPC_aastore = 83,
255 | JVM_OPC_bastore = 84,
256 | JVM_OPC_castore = 85,
257 | JVM_OPC_sastore = 86,
258 | JVM_OPC_pop = 87,
259 | JVM_OPC_pop2 = 88,
260 | JVM_OPC_dup = 89,
261 | JVM_OPC_dup_x1 = 90,
262 | JVM_OPC_dup_x2 = 91,
263 | JVM_OPC_dup2 = 92,
264 | JVM_OPC_dup2_x1 = 93,
265 | JVM_OPC_dup2_x2 = 94,
266 | JVM_OPC_swap = 95,
267 | JVM_OPC_iadd = 96,
268 | JVM_OPC_ladd = 97,
269 | JVM_OPC_fadd = 98,
270 | JVM_OPC_dadd = 99,
271 | JVM_OPC_isub = 100,
272 | JVM_OPC_lsub = 101,
273 | JVM_OPC_fsub = 102,
274 | JVM_OPC_dsub = 103,
275 | JVM_OPC_imul = 104,
276 | JVM_OPC_lmul = 105,
277 | JVM_OPC_fmul = 106,
278 | JVM_OPC_dmul = 107,
279 | JVM_OPC_idiv = 108,
280 | JVM_OPC_ldiv = 109,
281 | JVM_OPC_fdiv = 110,
282 | JVM_OPC_ddiv = 111,
283 | JVM_OPC_irem = 112,
284 | JVM_OPC_lrem = 113,
285 | JVM_OPC_frem = 114,
286 | JVM_OPC_drem = 115,
287 | JVM_OPC_ineg = 116,
288 | JVM_OPC_lneg = 117,
289 | JVM_OPC_fneg = 118,
290 | JVM_OPC_dneg = 119,
291 | JVM_OPC_ishl = 120,
292 | JVM_OPC_lshl = 121,
293 | JVM_OPC_ishr = 122,
294 | JVM_OPC_lshr = 123,
295 | JVM_OPC_iushr = 124,
296 | JVM_OPC_lushr = 125,
297 | JVM_OPC_iand = 126,
298 | JVM_OPC_land = 127,
299 | JVM_OPC_ior = 128,
300 | JVM_OPC_lor = 129,
301 | JVM_OPC_ixor = 130,
302 | JVM_OPC_lxor = 131,
303 | JVM_OPC_iinc = 132,
304 | JVM_OPC_i2l = 133,
305 | JVM_OPC_i2f = 134,
306 | JVM_OPC_i2d = 135,
307 | JVM_OPC_l2i = 136,
308 | JVM_OPC_l2f = 137,
309 | JVM_OPC_l2d = 138,
310 | JVM_OPC_f2i = 139,
311 | JVM_OPC_f2l = 140,
312 | JVM_OPC_f2d = 141,
313 | JVM_OPC_d2i = 142,
314 | JVM_OPC_d2l = 143,
315 | JVM_OPC_d2f = 144,
316 | JVM_OPC_i2b = 145,
317 | JVM_OPC_i2c = 146,
318 | JVM_OPC_i2s = 147,
319 | JVM_OPC_lcmp = 148,
320 | JVM_OPC_fcmpl = 149,
321 | JVM_OPC_fcmpg = 150,
322 | JVM_OPC_dcmpl = 151,
323 | JVM_OPC_dcmpg = 152,
324 | JVM_OPC_ifeq = 153,
325 | JVM_OPC_ifne = 154,
326 | JVM_OPC_iflt = 155,
327 | JVM_OPC_ifge = 156,
328 | JVM_OPC_ifgt = 157,
329 | JVM_OPC_ifle = 158,
330 | JVM_OPC_if_icmpeq = 159,
331 | JVM_OPC_if_icmpne = 160,
332 | JVM_OPC_if_icmplt = 161,
333 | JVM_OPC_if_icmpge = 162,
334 | JVM_OPC_if_icmpgt = 163,
335 | JVM_OPC_if_icmple = 164,
336 | JVM_OPC_if_acmpeq = 165,
337 | JVM_OPC_if_acmpne = 166,
338 | JVM_OPC_goto = 167,
339 | JVM_OPC_jsr = 168,
340 | JVM_OPC_ret = 169,
341 | JVM_OPC_tableswitch = 170,
342 | JVM_OPC_lookupswitch = 171,
343 | JVM_OPC_ireturn = 172,
344 | JVM_OPC_lreturn = 173,
345 | JVM_OPC_freturn = 174,
346 | JVM_OPC_dreturn = 175,
347 | JVM_OPC_areturn = 176,
348 | JVM_OPC_return = 177,
349 | JVM_OPC_getstatic = 178,
350 | JVM_OPC_putstatic = 179,
351 | JVM_OPC_getfield = 180,
352 | JVM_OPC_putfield = 181,
353 | JVM_OPC_invokevirtual = 182,
354 | JVM_OPC_invokespecial = 183,
355 | JVM_OPC_invokestatic = 184,
356 | JVM_OPC_invokeinterface = 185,
357 | JVM_OPC_invokedynamic = 186,
358 | JVM_OPC_new = 187,
359 | JVM_OPC_newarray = 188,
360 | JVM_OPC_anewarray = 189,
361 | JVM_OPC_arraylength = 190,
362 | JVM_OPC_athrow = 191,
363 | JVM_OPC_checkcast = 192,
364 | JVM_OPC_instanceof = 193,
365 | JVM_OPC_monitorenter = 194,
366 | JVM_OPC_monitorexit = 195,
367 | JVM_OPC_wide = 196,
368 | JVM_OPC_multianewarray = 197,
369 | JVM_OPC_ifnull = 198,
370 | JVM_OPC_ifnonnull = 199,
371 | JVM_OPC_goto_w = 200,
372 | JVM_OPC_jsr_w = 201,
373 | JVM_OPC_MAX = 201
374 | };
375 |
376 | /* Opcode length initializer, use with something like:
377 | * unsigned char opcode_length[JVM_OPC_MAX+1] = JVM_OPCODE_LENGTH_INITIALIZER;
378 | */
379 | #define JVM_OPCODE_LENGTH_INITIALIZER { \
380 | 1, /* nop */ \
381 | 1, /* aconst_null */ \
382 | 1, /* iconst_m1 */ \
383 | 1, /* iconst_0 */ \
384 | 1, /* iconst_1 */ \
385 | 1, /* iconst_2 */ \
386 | 1, /* iconst_3 */ \
387 | 1, /* iconst_4 */ \
388 | 1, /* iconst_5 */ \
389 | 1, /* lconst_0 */ \
390 | 1, /* lconst_1 */ \
391 | 1, /* fconst_0 */ \
392 | 1, /* fconst_1 */ \
393 | 1, /* fconst_2 */ \
394 | 1, /* dconst_0 */ \
395 | 1, /* dconst_1 */ \
396 | 2, /* bipush */ \
397 | 3, /* sipush */ \
398 | 2, /* ldc */ \
399 | 3, /* ldc_w */ \
400 | 3, /* ldc2_w */ \
401 | 2, /* iload */ \
402 | 2, /* lload */ \
403 | 2, /* fload */ \
404 | 2, /* dload */ \
405 | 2, /* aload */ \
406 | 1, /* iload_0 */ \
407 | 1, /* iload_1 */ \
408 | 1, /* iload_2 */ \
409 | 1, /* iload_3 */ \
410 | 1, /* lload_0 */ \
411 | 1, /* lload_1 */ \
412 | 1, /* lload_2 */ \
413 | 1, /* lload_3 */ \
414 | 1, /* fload_0 */ \
415 | 1, /* fload_1 */ \
416 | 1, /* fload_2 */ \
417 | 1, /* fload_3 */ \
418 | 1, /* dload_0 */ \
419 | 1, /* dload_1 */ \
420 | 1, /* dload_2 */ \
421 | 1, /* dload_3 */ \
422 | 1, /* aload_0 */ \
423 | 1, /* aload_1 */ \
424 | 1, /* aload_2 */ \
425 | 1, /* aload_3 */ \
426 | 1, /* iaload */ \
427 | 1, /* laload */ \
428 | 1, /* faload */ \
429 | 1, /* daload */ \
430 | 1, /* aaload */ \
431 | 1, /* baload */ \
432 | 1, /* caload */ \
433 | 1, /* saload */ \
434 | 2, /* istore */ \
435 | 2, /* lstore */ \
436 | 2, /* fstore */ \
437 | 2, /* dstore */ \
438 | 2, /* astore */ \
439 | 1, /* istore_0 */ \
440 | 1, /* istore_1 */ \
441 | 1, /* istore_2 */ \
442 | 1, /* istore_3 */ \
443 | 1, /* lstore_0 */ \
444 | 1, /* lstore_1 */ \
445 | 1, /* lstore_2 */ \
446 | 1, /* lstore_3 */ \
447 | 1, /* fstore_0 */ \
448 | 1, /* fstore_1 */ \
449 | 1, /* fstore_2 */ \
450 | 1, /* fstore_3 */ \
451 | 1, /* dstore_0 */ \
452 | 1, /* dstore_1 */ \
453 | 1, /* dstore_2 */ \
454 | 1, /* dstore_3 */ \
455 | 1, /* astore_0 */ \
456 | 1, /* astore_1 */ \
457 | 1, /* astore_2 */ \
458 | 1, /* astore_3 */ \
459 | 1, /* iastore */ \
460 | 1, /* lastore */ \
461 | 1, /* fastore */ \
462 | 1, /* dastore */ \
463 | 1, /* aastore */ \
464 | 1, /* bastore */ \
465 | 1, /* castore */ \
466 | 1, /* sastore */ \
467 | 1, /* pop */ \
468 | 1, /* pop2 */ \
469 | 1, /* dup */ \
470 | 1, /* dup_x1 */ \
471 | 1, /* dup_x2 */ \
472 | 1, /* dup2 */ \
473 | 1, /* dup2_x1 */ \
474 | 1, /* dup2_x2 */ \
475 | 1, /* swap */ \
476 | 1, /* iadd */ \
477 | 1, /* ladd */ \
478 | 1, /* fadd */ \
479 | 1, /* dadd */ \
480 | 1, /* isub */ \
481 | 1, /* lsub */ \
482 | 1, /* fsub */ \
483 | 1, /* dsub */ \
484 | 1, /* imul */ \
485 | 1, /* lmul */ \
486 | 1, /* fmul */ \
487 | 1, /* dmul */ \
488 | 1, /* idiv */ \
489 | 1, /* ldiv */ \
490 | 1, /* fdiv */ \
491 | 1, /* ddiv */ \
492 | 1, /* irem */ \
493 | 1, /* lrem */ \
494 | 1, /* frem */ \
495 | 1, /* drem */ \
496 | 1, /* ineg */ \
497 | 1, /* lneg */ \
498 | 1, /* fneg */ \
499 | 1, /* dneg */ \
500 | 1, /* ishl */ \
501 | 1, /* lshl */ \
502 | 1, /* ishr */ \
503 | 1, /* lshr */ \
504 | 1, /* iushr */ \
505 | 1, /* lushr */ \
506 | 1, /* iand */ \
507 | 1, /* land */ \
508 | 1, /* ior */ \
509 | 1, /* lor */ \
510 | 1, /* ixor */ \
511 | 1, /* lxor */ \
512 | 3, /* iinc */ \
513 | 1, /* i2l */ \
514 | 1, /* i2f */ \
515 | 1, /* i2d */ \
516 | 1, /* l2i */ \
517 | 1, /* l2f */ \
518 | 1, /* l2d */ \
519 | 1, /* f2i */ \
520 | 1, /* f2l */ \
521 | 1, /* f2d */ \
522 | 1, /* d2i */ \
523 | 1, /* d2l */ \
524 | 1, /* d2f */ \
525 | 1, /* i2b */ \
526 | 1, /* i2c */ \
527 | 1, /* i2s */ \
528 | 1, /* lcmp */ \
529 | 1, /* fcmpl */ \
530 | 1, /* fcmpg */ \
531 | 1, /* dcmpl */ \
532 | 1, /* dcmpg */ \
533 | 3, /* ifeq */ \
534 | 3, /* ifne */ \
535 | 3, /* iflt */ \
536 | 3, /* ifge */ \
537 | 3, /* ifgt */ \
538 | 3, /* ifle */ \
539 | 3, /* if_icmpeq */ \
540 | 3, /* if_icmpne */ \
541 | 3, /* if_icmplt */ \
542 | 3, /* if_icmpge */ \
543 | 3, /* if_icmpgt */ \
544 | 3, /* if_icmple */ \
545 | 3, /* if_acmpeq */ \
546 | 3, /* if_acmpne */ \
547 | 3, /* goto */ \
548 | 3, /* jsr */ \
549 | 2, /* ret */ \
550 | 99, /* tableswitch */ \
551 | 99, /* lookupswitch */ \
552 | 1, /* ireturn */ \
553 | 1, /* lreturn */ \
554 | 1, /* freturn */ \
555 | 1, /* dreturn */ \
556 | 1, /* areturn */ \
557 | 1, /* return */ \
558 | 3, /* getstatic */ \
559 | 3, /* putstatic */ \
560 | 3, /* getfield */ \
561 | 3, /* putfield */ \
562 | 3, /* invokevirtual */ \
563 | 3, /* invokespecial */ \
564 | 3, /* invokestatic */ \
565 | 5, /* invokeinterface */ \
566 | 5, /* invokedynamic */ \
567 | 3, /* new */ \
568 | 2, /* newarray */ \
569 | 3, /* anewarray */ \
570 | 1, /* arraylength */ \
571 | 1, /* athrow */ \
572 | 3, /* checkcast */ \
573 | 3, /* instanceof */ \
574 | 1, /* monitorenter */ \
575 | 1, /* monitorexit */ \
576 | 0, /* wide */ \
577 | 4, /* multianewarray */ \
578 | 3, /* ifnull */ \
579 | 3, /* ifnonnull */ \
580 | 5, /* goto_w */ \
581 | 5 /* jsr_w */ \
582 | }
583 |
584 | #ifdef __cplusplus
585 | } /* extern "C" */
586 | #endif /* __cplusplus */
587 |
588 | #endif /* CLASSFILE_CONSTANTS */
--------------------------------------------------------------------------------
/tests/10.jni.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module tests
3 |
4 | //
5 | // *Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
6 | // *DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 | // * *This code is free software; you can redistribute it and/or modify it
8 | // *under the terms of the GNU General Public License version 2 only, as
9 | // *published by the Free Software Foundation. Oracle designates this
10 | // *particular file as subject to the "Classpath" exception as provided
11 | // *by Oracle in the LICENSE file that accompanied this code.
12 | // * *This code is distributed in the hope that it will be useful, but WITHOUT
13 | // *ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | // *FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | // *version 2 for more details (a copy is included in the LICENSE file that
16 | // *accompanied this code).
17 | // * *You should have received a copy of the GNU General Public License version
18 | // *2 along with this work; if not, write to the Free Software Foundation,
19 | // *Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 | // * *Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | // *or visit www.oracle.com if you need additional information or have any
22 | // *questions.
23 | //
24 | // Classfile version number for this information
25 | // Flags
26 |
27 | // empty enum
28 | const jvm_acc_public = 1
29 | const jvm_acc_private = 2
30 | const jvm_acc_protected = 4
31 | const jvm_acc_static = 8
32 | const jvm_acc_final = 16
33 | const jvm_acc_synchronized = 32
34 | const jvm_acc_super = 32
35 | const jvm_acc_volatile = 64
36 | const jvm_acc_bridge = 64
37 | const jvm_acc_transient = 128
38 | const jvm_acc_varargs = 128
39 | const jvm_acc_native = 256
40 | const jvm_acc_interface = 512
41 | const jvm_acc_abstract = 1024
42 | const jvm_acc_strict = 2048
43 | const jvm_acc_synthetic = 4096
44 | const jvm_acc_annotation = 8192
45 | const jvm_acc_enum = 16384
46 | const jvm_acc_module = 32768
47 |
48 | // Used in newarray instruction.
49 |
50 | // empty enum
51 | const jvm_t_boolean = 4
52 | const jvm_t_char = 5
53 | const jvm_t_float = 6
54 | const jvm_t_double = 7
55 | const jvm_t_byte = 8
56 | const jvm_t_short = 9
57 | const jvm_t_int = 10
58 | const jvm_t_long = 11
59 |
60 | // Constant Pool Entries
61 |
62 | // empty enum
63 | const jvm_constant_utf8 = 1
64 | const jvm_constant_unicode = 2
65 | // unused
66 | const jvm_constant_integer = 3
67 | const jvm_constant_float = 4
68 | const jvm_constant_long = 5
69 | const jvm_constant_double = 6
70 | const jvm_constant_class = 7
71 | const jvm_constant_string = 8
72 | const jvm_constant_fieldref = 9
73 | const jvm_constant_methodref = 10
74 | const jvm_constant_interface_methodref = 11
75 | const jvm_constant_name_and_type = 12
76 | const jvm_constant_method_handle = 15
77 | // JSR 292
78 | const jvm_constant_method_type = 16
79 | // JSR 292
80 | const jvm_constant_dynamic = 17
81 | const jvm_constant_invoke_dynamic = 18
82 | const jvm_constant_module = 19
83 | const jvm_constant_package = 20
84 | const jvm_constant_external_max = 20
85 |
86 | // JVM_CONSTANT_MethodHandle subtypes
87 |
88 | // empty enum
89 | const jvm_ref_get_field = 1
90 | const jvm_ref_get_static = 2
91 | const jvm_ref_put_field = 3
92 | const jvm_ref_put_static = 4
93 | const jvm_ref_invoke_virtual = 5
94 | const jvm_ref_invoke_static = 6
95 | const jvm_ref_invoke_special = 7
96 | const jvm_ref_new_invoke_special = 8
97 | const jvm_ref_invoke_interface = 9
98 |
99 | // StackMapTable type item numbers
100 |
101 | // empty enum
102 | const jvm_item_top = 0
103 | const jvm_item_integer = 1
104 | const jvm_item_float = 2
105 | const jvm_item_double = 3
106 | const jvm_item_long = 4
107 | const jvm_item_null = 5
108 | const jvm_item_uninitialized_this = 6
109 | const jvm_item_object = 7
110 | const jvm_item_uninitialized = 8
111 |
112 | // Type signatures
113 |
114 | // empty enum
115 | const jvm_signature_slash = `/`
116 | const jvm_signature_dot = `.`
117 | const jvm_signature_special = `<`
118 | const jvm_signature_endspecial = `>`
119 | const jvm_signature_array = `[`
120 | const jvm_signature_byte = `B`
121 | const jvm_signature_char = `C`
122 | const jvm_signature_class = `L`
123 | const jvm_signature_endclass = `;`
124 | const jvm_signature_enum = `E`
125 | const jvm_signature_float = `F`
126 | const jvm_signature_double = `D`
127 | const jvm_signature_func = `(`
128 | const jvm_signature_endfunc = `)`
129 | const jvm_signature_int = `I`
130 | const jvm_signature_long = `J`
131 | const jvm_signature_short = `S`
132 | const jvm_signature_void = `V`
133 | const jvm_signature_boolean = `Z`
134 |
135 | // Opcodes
136 |
137 | // empty enum
138 | const jvm_opc_nop = 0
139 | const jvm_opc_aconst_null = 1
140 | const jvm_opc_iconst_m1 = 2
141 | const jvm_opc_iconst_0 = 3
142 | const jvm_opc_iconst_1 = 4
143 | const jvm_opc_iconst_2 = 5
144 | const jvm_opc_iconst_3 = 6
145 | const jvm_opc_iconst_4 = 7
146 | const jvm_opc_iconst_5 = 8
147 | const jvm_opc_lconst_0 = 9
148 | const jvm_opc_lconst_1 = 10
149 | const jvm_opc_fconst_0 = 11
150 | const jvm_opc_fconst_1 = 12
151 | const jvm_opc_fconst_2 = 13
152 | const jvm_opc_dconst_0 = 14
153 | const jvm_opc_dconst_1 = 15
154 | const jvm_opc_bipush = 16
155 | const jvm_opc_sipush = 17
156 | const jvm_opc_ldc = 18
157 | const jvm_opc_ldc_w = 19
158 | const jvm_opc_ldc2_w = 20
159 | const jvm_opc_iload = 21
160 | const jvm_opc_lload = 22
161 | const jvm_opc_fload = 23
162 | const jvm_opc_dload = 24
163 | const jvm_opc_aload = 25
164 | const jvm_opc_iload_0 = 26
165 | const jvm_opc_iload_1 = 27
166 | const jvm_opc_iload_2 = 28
167 | const jvm_opc_iload_3 = 29
168 | const jvm_opc_lload_0 = 30
169 | const jvm_opc_lload_1 = 31
170 | const jvm_opc_lload_2 = 32
171 | const jvm_opc_lload_3 = 33
172 | const jvm_opc_fload_0 = 34
173 | const jvm_opc_fload_1 = 35
174 | const jvm_opc_fload_2 = 36
175 | const jvm_opc_fload_3 = 37
176 | const jvm_opc_dload_0 = 38
177 | const jvm_opc_dload_1 = 39
178 | const jvm_opc_dload_2 = 40
179 | const jvm_opc_dload_3 = 41
180 | const jvm_opc_aload_0 = 42
181 | const jvm_opc_aload_1 = 43
182 | const jvm_opc_aload_2 = 44
183 | const jvm_opc_aload_3 = 45
184 | const jvm_opc_iaload = 46
185 | const jvm_opc_laload = 47
186 | const jvm_opc_faload = 48
187 | const jvm_opc_daload = 49
188 | const jvm_opc_aaload = 50
189 | const jvm_opc_baload = 51
190 | const jvm_opc_caload = 52
191 | const jvm_opc_saload = 53
192 | const jvm_opc_istore = 54
193 | const jvm_opc_lstore = 55
194 | const jvm_opc_fstore = 56
195 | const jvm_opc_dstore = 57
196 | const jvm_opc_astore = 58
197 | const jvm_opc_istore_0 = 59
198 | const jvm_opc_istore_1 = 60
199 | const jvm_opc_istore_2 = 61
200 | const jvm_opc_istore_3 = 62
201 | const jvm_opc_lstore_0 = 63
202 | const jvm_opc_lstore_1 = 64
203 | const jvm_opc_lstore_2 = 65
204 | const jvm_opc_lstore_3 = 66
205 | const jvm_opc_fstore_0 = 67
206 | const jvm_opc_fstore_1 = 68
207 | const jvm_opc_fstore_2 = 69
208 | const jvm_opc_fstore_3 = 70
209 | const jvm_opc_dstore_0 = 71
210 | const jvm_opc_dstore_1 = 72
211 | const jvm_opc_dstore_2 = 73
212 | const jvm_opc_dstore_3 = 74
213 | const jvm_opc_astore_0 = 75
214 | const jvm_opc_astore_1 = 76
215 | const jvm_opc_astore_2 = 77
216 | const jvm_opc_astore_3 = 78
217 | const jvm_opc_iastore = 79
218 | const jvm_opc_lastore = 80
219 | const jvm_opc_fastore = 81
220 | const jvm_opc_dastore = 82
221 | const jvm_opc_aastore = 83
222 | const jvm_opc_bastore = 84
223 | const jvm_opc_castore = 85
224 | const jvm_opc_sastore = 86
225 | const jvm_opc_pop = 87
226 | const jvm_opc_pop2 = 88
227 | const jvm_opc_dup = 89
228 | const jvm_opc_dup_x1 = 90
229 | const jvm_opc_dup_x2 = 91
230 | const jvm_opc_dup2 = 92
231 | const jvm_opc_dup2_x1 = 93
232 | const jvm_opc_dup2_x2 = 94
233 | const jvm_opc_swap = 95
234 | const jvm_opc_iadd = 96
235 | const jvm_opc_ladd = 97
236 | const jvm_opc_fadd = 98
237 | const jvm_opc_dadd = 99
238 | const jvm_opc_isub = 100
239 | const jvm_opc_lsub = 101
240 | const jvm_opc_fsub = 102
241 | const jvm_opc_dsub = 103
242 | const jvm_opc_imul = 104
243 | const jvm_opc_lmul = 105
244 | const jvm_opc_fmul = 106
245 | const jvm_opc_dmul = 107
246 | const jvm_opc_idiv = 108
247 | const jvm_opc_ldiv = 109
248 | const jvm_opc_fdiv = 110
249 | const jvm_opc_ddiv = 111
250 | const jvm_opc_irem = 112
251 | const jvm_opc_lrem = 113
252 | const jvm_opc_frem = 114
253 | const jvm_opc_drem = 115
254 | const jvm_opc_ineg = 116
255 | const jvm_opc_lneg = 117
256 | const jvm_opc_fneg = 118
257 | const jvm_opc_dneg = 119
258 | const jvm_opc_ishl = 120
259 | const jvm_opc_lshl = 121
260 | const jvm_opc_ishr = 122
261 | const jvm_opc_lshr = 123
262 | const jvm_opc_iushr = 124
263 | const jvm_opc_lushr = 125
264 | const jvm_opc_iand = 126
265 | const jvm_opc_land = 127
266 | const jvm_opc_ior = 128
267 | const jvm_opc_lor = 129
268 | const jvm_opc_ixor = 130
269 | const jvm_opc_lxor = 131
270 | const jvm_opc_iinc = 132
271 | const jvm_opc_i2l = 133
272 | const jvm_opc_i2f = 134
273 | const jvm_opc_i2d = 135
274 | const jvm_opc_l2i = 136
275 | const jvm_opc_l2f = 137
276 | const jvm_opc_l2d = 138
277 | const jvm_opc_f2i = 139
278 | const jvm_opc_f2l = 140
279 | const jvm_opc_f2d = 141
280 | const jvm_opc_d2i = 142
281 | const jvm_opc_d2l = 143
282 | const jvm_opc_d2f = 144
283 | const jvm_opc_i2b = 145
284 | const jvm_opc_i2c = 146
285 | const jvm_opc_i2s = 147
286 | const jvm_opc_lcmp = 148
287 | const jvm_opc_fcmpl = 149
288 | const jvm_opc_fcmpg = 150
289 | const jvm_opc_dcmpl = 151
290 | const jvm_opc_dcmpg = 152
291 | const jvm_opc_ifeq = 153
292 | const jvm_opc_ifne = 154
293 | const jvm_opc_iflt = 155
294 | const jvm_opc_ifge = 156
295 | const jvm_opc_ifgt = 157
296 | const jvm_opc_ifle = 158
297 | const jvm_opc_if_icmpeq = 159
298 | const jvm_opc_if_icmpne = 160
299 | const jvm_opc_if_icmplt = 161
300 | const jvm_opc_if_icmpge = 162
301 | const jvm_opc_if_icmpgt = 163
302 | const jvm_opc_if_icmple = 164
303 | const jvm_opc_if_acmpeq = 165
304 | const jvm_opc_if_acmpne = 166
305 | const jvm_opc_goto = 167
306 | const jvm_opc_jsr = 168
307 | const jvm_opc_ret = 169
308 | const jvm_opc_tableswitch = 170
309 | const jvm_opc_lookupswitch = 171
310 | const jvm_opc_ireturn = 172
311 | const jvm_opc_lreturn = 173
312 | const jvm_opc_freturn = 174
313 | const jvm_opc_dreturn = 175
314 | const jvm_opc_areturn = 176
315 | const jvm_opc_return = 177
316 | const jvm_opc_getstatic = 178
317 | const jvm_opc_putstatic = 179
318 | const jvm_opc_getfield = 180
319 | const jvm_opc_putfield = 181
320 | const jvm_opc_invokevirtual = 182
321 | const jvm_opc_invokespecial = 183
322 | const jvm_opc_invokestatic = 184
323 | const jvm_opc_invokeinterface = 185
324 | const jvm_opc_invokedynamic = 186
325 | const jvm_opc_new = 187
326 | const jvm_opc_newarray = 188
327 | const jvm_opc_anewarray = 189
328 | const jvm_opc_arraylength = 190
329 | const jvm_opc_athrow = 191
330 | const jvm_opc_checkcast = 192
331 | const jvm_opc_instanceof = 193
332 | const jvm_opc_monitorenter = 194
333 | const jvm_opc_monitorexit = 195
334 | const jvm_opc_wide = 196
335 | const jvm_opc_multianewarray = 197
336 | const jvm_opc_ifnull = 198
337 | const jvm_opc_ifnonnull = 199
338 | const jvm_opc_goto_w = 200
339 | const jvm_opc_jsr_w = 201
340 | const jvm_opc_max = 201
341 |
342 | // Opcode length initializer, use with something like:
343 | // * unsigned char opcode_length[JVM_OPC_MAX+1] = JVM_OPCODE_LENGTH_INITIALIZER;
344 | //
345 | // nop
346 | // aconst_null
347 | // iconst_m1
348 | // iconst_0
349 | // iconst_1
350 | // iconst_2
351 | // iconst_3
352 | // iconst_4
353 | // iconst_5
354 | // lconst_0
355 | // lconst_1
356 | // fconst_0
357 | // fconst_1
358 | // fconst_2
359 | // dconst_0
360 | // dconst_1
361 | // bipush
362 | // sipush
363 | // ldc
364 | // ldc_w
365 | // ldc2_w
366 | // iload
367 | // lload
368 | // fload
369 | // dload
370 | // aload
371 | // iload_0
372 | // iload_1
373 | // iload_2
374 | // iload_3
375 | // lload_0
376 | // lload_1
377 | // lload_2
378 | // lload_3
379 | // fload_0
380 | // fload_1
381 | // fload_2
382 | // fload_3
383 | // dload_0
384 | // dload_1
385 | // dload_2
386 | // dload_3
387 | // aload_0
388 | // aload_1
389 | // aload_2
390 | // aload_3
391 | // iaload
392 | // laload
393 | // faload
394 | // daload
395 | // aaload
396 | // baload
397 | // caload
398 | // saload
399 | // istore
400 | // lstore
401 | // fstore
402 | // dstore
403 | // astore
404 | // istore_0
405 | // istore_1
406 | // istore_2
407 | // istore_3
408 | // lstore_0
409 | // lstore_1
410 | // lstore_2
411 | // lstore_3
412 | // fstore_0
413 | // fstore_1
414 | // fstore_2
415 | // fstore_3
416 | // dstore_0
417 | // dstore_1
418 | // dstore_2
419 | // dstore_3
420 | // astore_0
421 | // astore_1
422 | // astore_2
423 | // astore_3
424 | // iastore
425 | // lastore
426 | // fastore
427 | // dastore
428 | // aastore
429 | // bastore
430 | // castore
431 | // sastore
432 | // pop
433 | // pop2
434 | // dup
435 | // dup_x1
436 | // dup_x2
437 | // dup2
438 | // dup2_x1
439 | // dup2_x2
440 | // swap
441 | // iadd
442 | // ladd
443 | // fadd
444 | // dadd
445 | // isub
446 | // lsub
447 | // fsub
448 | // dsub
449 | // imul
450 | // lmul
451 | // fmul
452 | // dmul
453 | // idiv
454 | // ldiv
455 | // fdiv
456 | // ddiv
457 | // irem
458 | // lrem
459 | // frem
460 | // drem
461 | // ineg
462 | // lneg
463 | // fneg
464 | // dneg
465 | // ishl
466 | // lshl
467 | // ishr
468 | // lshr
469 | // iushr
470 | // lushr
471 | // iand
472 | // land
473 | // ior
474 | // lor
475 | // ixor
476 | // lxor
477 | // iinc
478 | // i2l
479 | // i2f
480 | // i2d
481 | // l2i
482 | // l2f
483 | // l2d
484 | // f2i
485 | // f2l
486 | // f2d
487 | // d2i
488 | // d2l
489 | // d2f
490 | // i2b
491 | // i2c
492 | // i2s
493 | // lcmp
494 | // fcmpl
495 | // fcmpg
496 | // dcmpl
497 | // dcmpg
498 | // ifeq
499 | // ifne
500 | // iflt
501 | // ifge
502 | // ifgt
503 | // ifle
504 | // if_icmpeq
505 | // if_icmpne
506 | // if_icmplt
507 | // if_icmpge
508 | // if_icmpgt
509 | // if_icmple
510 | // if_acmpeq
511 | // if_acmpne
512 | // goto
513 | // jsr
514 | // ret
515 | // tableswitch
516 | // lookupswitch
517 | // ireturn
518 | // lreturn
519 | // freturn
520 | // dreturn
521 | // areturn
522 | // return
523 | // getstatic
524 | // putstatic
525 | // getfield
526 | // putfield
527 | // invokevirtual
528 | // invokespecial
529 | // invokestatic
530 | // invokeinterface
531 | // invokedynamic
532 | // new
533 | // newarray
534 | // anewarray
535 | // arraylength
536 | // athrow
537 | // checkcast
538 | // instanceof
539 | // monitorenter
540 | // monitorexit
541 | // wide
542 | // multianewarray
543 | // ifnull
544 | // ifnonnull
545 | // goto_w
546 | // jsr_w
547 | // extern "C"
548 | // __cplusplus
549 | // CLASSFILE_CONSTANTS
--------------------------------------------------------------------------------
/tests/11.enum_default.c:
--------------------------------------------------------------------------------
1 | enum myEnum {
2 | A,
3 | B,
4 | C
5 | };
6 |
7 | typedef enum {
8 | D,
9 | E,
10 | F
11 | } myAnotherEnum;
12 |
13 | typedef enum myStrangeEnum {
14 | G,
15 | H,
16 | I
17 | } myStrangeEnum;
18 |
19 | enum { J = 1 };
20 |
21 | void enum_func(enum myEnum a) {
22 | }
23 |
24 | void enum_func_const(const enum myEnum a) {
25 | }
26 |
27 | int main() {
28 | enum myEnum myEnumVar = A;
29 | myAnotherEnum myEnumVar2 = D;
30 | myStrangeEnum myEnumVar3 = G;
31 | int myIntVar = J;
32 | enum_func(myEnumVar);
33 | enum_func_const(myEnumVar);
34 | return 0;
35 | }
36 |
--------------------------------------------------------------------------------
/tests/11.enum_default.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | enum MyEnum {
5 | a
6 | b
7 | c
8 | }
9 |
10 | enum MyAnotherEnum {
11 | d
12 | e
13 | f
14 | }
15 |
16 | enum MyStrangeEnum {
17 | g
18 | h
19 | i
20 | }
21 |
22 | // empty enum
23 | const j = 1
24 |
25 | fn enum_func(a MyEnum) {
26 | }
27 |
28 | fn enum_func_const(a MyEnum) {
29 | }
30 |
31 | fn main() {
32 | my_enum_var := MyEnum.a
33 | my_enum_var2 := MyAnotherEnum.d
34 | my_enum_var3 := MyStrangeEnum.g
35 | my_int_var := j
36 | enum_func(my_enum_var)
37 | enum_func_const(my_enum_var)
38 | return
39 | }
40 |
--------------------------------------------------------------------------------
/tests/12.if_stmt.c:
--------------------------------------------------------------------------------
1 | int static inline quot( int x, int y ) {
2 | if( x == 0 || y == 0 )
3 | return 0;
4 | if( x > y )
5 | return x%y ? 0 : x/y;
6 | else if (x == y)
7 | return x%y ? 0 : x/y;
8 | else
9 | return y%x ? 0 : y/x;
10 | }
11 | int main() {
12 | quot(2,2);
13 | }
--------------------------------------------------------------------------------
/tests/12.if_stmt.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn quot(x int, y int) int {
5 | if x == 0 || y == 0 {
6 | return 0
7 | }
8 | if x > y {
9 | return if x % y { 0 } else { x / y }
10 | } else if x == y {
11 | return if x % y { 0 } else { x / y }
12 | } else {
13 | return if y % x { 0 } else { y / x }
14 | }
15 | }
16 |
17 | fn main() {
18 | quot(2, 2)
19 | }
20 |
--------------------------------------------------------------------------------
/tests/13.switch.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | const int a = 0;
4 |
5 | void main()
6 | {
7 | switch(a)
8 | {
9 | default:
10 | printf("foo\n");
11 | break;
12 | case 0:
13 | printf("bar\n");
14 | break;
15 | }
16 |
17 |
18 | switch(a)
19 | {
20 | case 0:
21 | printf("bar\n");
22 | break;
23 | default:
24 | printf("foo\n");
25 | break;
26 | }
27 | }
--------------------------------------------------------------------------------
/tests/13.switch.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | @[export: 'a']
5 | const a = 0
6 |
7 | fn main() {
8 | match a {
9 | 0 { // case comp body kind=CallExpr is_enum=true
10 | C.printf(c'bar\n')
11 | }
12 | else {
13 | C.printf(c'foo\n')
14 | }
15 | }
16 | match a {
17 | 0 { // case comp body kind=CallExpr is_enum=true
18 | C.printf(c'bar\n')
19 | }
20 | else {
21 | C.printf(c'foo\n')
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/14.default.c:
--------------------------------------------------------------------------------
1 | const int a = 0;
2 |
3 | void f()
4 | {
5 | switch(a)
6 | {
7 | default:
8 | case 0:
9 | case 1:
10 | break;
11 | }
12 |
13 | switch(a)
14 | {
15 | default:
16 | case 0:
17 | break;
18 | }
19 |
20 | switch(a)
21 | {
22 | case 0:
23 | break;
24 | case 1:
25 | break;
26 | default:
27 | break;
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/tests/14.default.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | @[export: 'a']
5 | const a = 0
6 |
7 | fn f() {
8 | match a {
9 | 0, 1 {}
10 | else {}
11 | }
12 | match a {
13 | 0 { // case comp body kind=BreakStmt is_enum=true
14 | }
15 | else {}
16 | }
17 | match a {
18 | 0 { // case comp body kind=BreakStmt is_enum=true
19 | }
20 | 1 { // case comp body kind=BreakStmt is_enum=true
21 | }
22 | else {}
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/15.multi_var_decl.c:
--------------------------------------------------------------------------------
1 | int main() {
2 | int n, r, sum = 0, temp;
3 | }
--------------------------------------------------------------------------------
/tests/15.multi_var_decl.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn main() {
5 | n := 0
6 | r := 0
7 | sum := 0
8 | temp := 0
9 | }
10 |
--------------------------------------------------------------------------------
/tests/16.literals.c:
--------------------------------------------------------------------------------
1 | int main() {
2 | char c1 = '\\';
3 | char c2 = '`';
4 | char c3 = '.';
5 | }
--------------------------------------------------------------------------------
/tests/16.literals.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn main() {
5 | c1 := `\\`
6 | c2 := `\``
7 | c3 := `.`
8 | }
9 |
--------------------------------------------------------------------------------
/tests/17.partial_struct.c:
--------------------------------------------------------------------------------
1 | typedef struct TSTexture_t *TSTexture;
2 |
--------------------------------------------------------------------------------
/tests/17.partial_struct.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | type TSTexture = voidptr
5 |
--------------------------------------------------------------------------------
/tests/18.header_types.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | uint16_t ts_f32tof16(float f);
4 |
--------------------------------------------------------------------------------
/tests/18.header_types.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module tests
3 |
4 | fn C.ts_f32tof16(f f32) u16
5 |
6 | pub fn ts_f32tof16(f f32) u16 {
7 | return C.ts_f32tof16(f)
8 | }
9 |
--------------------------------------------------------------------------------
/tests/19.header_visibility_attribute.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #define TS_CAPI __attribute__ ((visibility("default")))
4 |
5 | TS_CAPI uint16_t ts_f32tof16(float f);
6 |
--------------------------------------------------------------------------------
/tests/19.header_visibility_attribute.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module tests
3 |
4 | fn C.ts_f32tof16(f f32) u16
5 |
6 | pub fn ts_f32tof16(f f32) u16 {
7 | return C.ts_f32tof16(f)
8 | }
9 |
--------------------------------------------------------------------------------
/tests/2.if.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main() {
4 | if (10 > 5) {
5 | printf("10 > 5");
6 | }
7 | else {
8 | printf("no");
9 | }
10 | int x = 10;
11 | int y = 20;
12 | if (y > x) {
13 | printf("y > x");
14 | }
15 | if (y + 1 > x); // TODO
16 | if (1) printf("one");
17 | else if (1 > 0 || x < y || (x > y && x < y + 1)) {
18 | printf("two");
19 | printf("three");
20 | }
21 | return 0;
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/tests/2.if.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn main() {
5 | if 10 > 5 {
6 | C.printf(c'10 > 5')
7 | } else {
8 | C.printf(c'no')
9 | }
10 | x := 10
11 | y := 20
12 | if y > x {
13 | C.printf(c'y > x')
14 | }
15 | if y + 1 > x {
16 | }
17 | // TODO
18 | if 1 {
19 | C.printf(c'one')
20 | } else if 1 > 0 || x < y || (x > y && x < y + 1) {
21 | C.printf(c'two')
22 | C.printf(c'three')
23 | }
24 | return
25 | }
26 |
--------------------------------------------------------------------------------
/tests/20.header_duplicate_type_declaration.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "IGNORE_header_duplicate_type_declaration_2.h"
4 |
5 | typedef int dup_typ;
6 |
--------------------------------------------------------------------------------
/tests/20.header_duplicate_type_declaration.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module tests
3 |
4 | type Dup_typ = int
5 |
--------------------------------------------------------------------------------
/tests/21.header_uninited_global_var.h:
--------------------------------------------------------------------------------
1 | #define TS_CAPI __attribute__ ((visibility("default")))
2 |
3 | TS_CAPI extern const char* tsMeshMaterialTypeBump;
4 |
--------------------------------------------------------------------------------
/tests/21.header_uninited_global_var.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module tests
3 |
--------------------------------------------------------------------------------
/tests/22.getline_linux.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main() {
5 | char *input = NULL;
6 | size_t len = 0;
7 | ssize_t read;
8 | printf("Enter text (Ctrl+D to quit):\n");
9 | read = getline(&input, &len, stdin);
10 |
11 | if (read != -1) {
12 | printf("Entered: %s", input);
13 | } else {
14 | printf("error reading input\n");
15 | }
16 |
17 | free(input);
18 | return 0;
19 | }
--------------------------------------------------------------------------------
/tests/22.getline_linux.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn main() {
5 | input := (unsafe { nil })
6 | len := 0
7 | read := isize(0)
8 | C.printf(c'Enter text (Ctrl+D to quit):\n')
9 | read = C.getline(&input, &len, C.stdin)
10 | if read != -1 {
11 | C.printf(c'Entered: %s', input)
12 | } else {
13 | C.printf(c'error reading input\n')
14 | }
15 | C.free(input)
16 | return
17 | }
18 |
--------------------------------------------------------------------------------
/tests/22.getline_macos.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main() {
5 | char *input = NULL;
6 | size_t len = 0;
7 | ssize_t read;
8 | printf("Enter text (Ctrl+D to quit):\n");
9 | read = getline(&input, &len, stdin);
10 |
11 | if (read != -1) {
12 | printf("Entered: %s", input);
13 | } else {
14 | printf("error reading input\n");
15 | }
16 |
17 | free(input);
18 | return 0;
19 | }
--------------------------------------------------------------------------------
/tests/22.getline_macos.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn main() {
5 | input := (unsafe { nil })
6 | len := 0
7 | read := isize(0)
8 | C.printf(c'Enter text (Ctrl+D to quit):\n')
9 | read = C.getline(&input, &len, C.__stdinp)
10 | if read != -1 {
11 | C.printf(c'Entered: %s', input)
12 | } else {
13 | C.printf(c'error reading input\n')
14 | }
15 | C.free(input)
16 | return
17 | }
18 |
--------------------------------------------------------------------------------
/tests/23.sizeof.c:
--------------------------------------------------------------------------------
1 | #include
2 | int main() {
3 | char hello[] = "Hello, unistd world!\n";
4 | write ( 1, hello, sizeof hello );
5 | return 0; }
--------------------------------------------------------------------------------
/tests/23.sizeof.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn main() {
5 | hello := c'Hello, unistd world!\n'
6 | C.write(1, hello, sizeof(hello))
7 | return
8 | }
9 |
--------------------------------------------------------------------------------
/tests/24.typedef_struct.h:
--------------------------------------------------------------------------------
1 | typedef struct
2 | {
3 | float x, y;
4 | } ImVec2;
5 |
6 | typedef struct ImVec3 ImVec3;
7 | struct ImVec3
8 | {
9 | float x, y, z;
10 | };
11 |
12 | struct ImVec4
13 | {
14 | float x, y, z, w;
15 | };
16 | typedef struct ImVec4 ImVec4;
17 |
18 | struct ImGuiTextRange
19 | {
20 | const char *b;
21 | const char *e;
22 | };
23 | typedef struct ImGuiTextRange ImGuiTextRange;
24 |
25 | typedef struct ImVector_ImGuiTextRange
26 | {
27 | int Size;
28 | int Capacity;
29 | ImGuiTextRange *Data;
30 | } ImVector_ImGuiTextRange;
31 |
32 | struct ImGuiTextFilter
33 | {
34 | char InputBuf[256];
35 | ImVector_ImGuiTextRange Filters;
36 | int CountGrep;
37 | };
38 | typedef struct ImGuiTextRange ImGuiTextRange;
39 |
40 | typedef unsigned short ImWchar16;
41 | typedef ImWchar16 ImWchar;
42 |
43 | typedef struct ImGuiContext ImGuiContext;
44 | struct ImGuiContext;
45 | struct ImGuiContext
46 | {
47 | int Initialized;
48 | };
--------------------------------------------------------------------------------
/tests/24.typedef_struct.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module tests
3 |
4 | struct ImVec2 {
5 | x f32
6 | y f32
7 | }
8 |
9 | struct ImVec3 {
10 | x f32
11 | y f32
12 | z f32
13 | }
14 |
15 | struct ImVec4 {
16 | x f32
17 | y f32
18 | z f32
19 | w f32
20 | }
21 |
22 | struct ImGuiTextRange {
23 | b &i8
24 | e &i8
25 | }
26 |
27 | struct ImVector_ImGuiTextRange {
28 | size int
29 | capacity int
30 | data &ImGuiTextRange
31 | }
32 |
33 | type ImWchar16 = u16
34 |
35 | struct ImGuiContext {
36 | initialized int
37 | }
38 |
--------------------------------------------------------------------------------
/tests/25.return_val_2.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | bool foo(int value)
4 | {
5 | return value == 2;
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/tests/25.return_val_2.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn foo(value int) bool {
5 | return value == 2
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/tests/26.assign_zerof.c:
--------------------------------------------------------------------------------
1 | int main() {
2 | double a = 0.0f;
3 | double b = 0;
4 | float c = 0;
5 | }
6 |
--------------------------------------------------------------------------------
/tests/26.assign_zerof.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn main() {
5 | a := 0.0
6 | b := f64(0)
7 | c := f32(0)
8 | }
9 |
--------------------------------------------------------------------------------
/tests/3.if_switch_enum.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | typedef enum {
4 | one, two
5 | } Number;
6 |
7 | Number return_number() {
8 | return one;
9 | }
10 |
11 | int main() {
12 | if (10 > 5) {
13 | printf("10 > 5");
14 | }
15 | else {
16 | printf("no");
17 | }
18 | int x = 10;
19 | int y = 20;
20 | if (y > x) {
21 | printf("y > x");
22 | }
23 | if (y + 1 > x); // TODO
24 | if (1) printf("one");
25 | else if (1 > 0 || x < y || (x > y && x < y + 1)) {
26 | printf("two");
27 | printf("three");
28 | }
29 | switch (x) {
30 | case 0: return 0;
31 | case 1: printf("one"); printf("ONE"); break;
32 | case 2: printf("two"); if (1 > 0) { printf("OK"); } break;
33 | }
34 | Number n = one;
35 | switch (n) {
36 | //case one: printf("one!"); int x = one + 1; break;
37 | //x := .one + 1
38 | case one: printf("one"); break;
39 | case two: printf("two"); break;
40 | }
41 | // handle enum <=> int in C: enum switch needs explicit casts to ints
42 | int m = 0;
43 | switch (m) {
44 | case one: printf("one"); break;
45 | case two: printf("two"); break;
46 | }
47 | return 0;
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/tests/3.if_switch_enum.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | enum Number {
5 | one
6 | two
7 | }
8 |
9 | fn return_number() Number {
10 | return Number.one
11 | }
12 |
13 | fn main() {
14 | if 10 > 5 {
15 | C.printf(c'10 > 5')
16 | } else {
17 | C.printf(c'no')
18 | }
19 | x := 10
20 | y := 20
21 | if y > x {
22 | C.printf(c'y > x')
23 | }
24 | if y + 1 > x {
25 | }
26 | // TODO
27 | if 1 {
28 | C.printf(c'one')
29 | } else if 1 > 0 || x < y || (x > y && x < y + 1) {
30 | C.printf(c'two')
31 | C.printf(c'three')
32 | }
33 | match x {
34 | 0 { // case comp body kind=ReturnStmt is_enum=false
35 | return
36 | }
37 | 1 { // case comp body kind=CallExpr is_enum=false
38 | C.printf(c'one')
39 | C.printf(c'ONE')
40 | }
41 | 2 { // case comp body kind=CallExpr is_enum=false
42 | C.printf(c'two')
43 | if 1 > 0 {
44 | C.printf(c'OK')
45 | }
46 | }
47 | else {}
48 | }
49 | n := Number.one
50 | match n {
51 | // case one: printf("one!"); int x = one + 1; break;
52 | // x := .one + 1
53 | .one { // case comp body kind=CallExpr is_enum=true
54 | C.printf(c'one')
55 | }
56 | .two { // case comp body kind=CallExpr is_enum=true
57 | C.printf(c'two')
58 | }
59 | else {}
60 | }
61 | // handle enum <=> int in C: enum switch needs explicit casts to ints
62 | m := 0
63 | match Number(m) {
64 | .one { // case comp body kind=CallExpr is_enum=true
65 | C.printf(c'one')
66 | }
67 | .two { // case comp body kind=CallExpr is_enum=true
68 | C.printf(c'two')
69 | }
70 | else {}
71 | }
72 | return
73 | }
--------------------------------------------------------------------------------
/tests/4.for.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void for_test() {
4 | for (int i = 0; i < 10; i++) {
5 | printf("i = %d\n", i);
6 | }
7 | for (int i = 0; i < 10; i++) printf("single line");
8 | //
9 | int x = 1;
10 | int sum = 0;
11 | while (x < 10) {
12 | x++;
13 | sum += x;
14 | }
15 | //
16 | while (1) {
17 | printf("inf loop");
18 | break;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/4.for.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn for_test() {
5 | for i := 0; i < 10; i++ {
6 | C.printf(c'i = %d\n', i)
7 | }
8 | for i := 0; i < 10; i++ {
9 | C.printf(c'single line')
10 | }
11 | //
12 | x := 1
13 | sum := 0
14 | for x < 10 {
15 | x++
16 | sum += x
17 | }
18 | //
19 | for 1 {
20 | C.printf(c'inf loop')
21 | break
22 | }
23 | }
--------------------------------------------------------------------------------
/tests/5.struct.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | const int PI= 314;
4 |
5 | struct User {
6 | char *name;
7 | int age;
8 | };
9 |
10 | // lots of structs are typedef'ed in C
11 | typedef struct {
12 | char *name;
13 | int age;
14 | float CapitalizedField; // fields in V must be lower case
15 | } TUser;
16 |
17 | // struct names have to be capitalized in V
18 | struct small {
19 | int foo;
20 | };
21 |
22 | struct small3 {
23 | int foo;
24 | };
25 |
26 | struct small2 {
27 | struct small struct_field; // make sure field types are capitalized
28 | struct small* struct_field_ptr;
29 | struct small3** struct_field_ptr2;
30 | };
31 |
32 | void small_fn(struct small param) { // make sure arg types are capitalized
33 |
34 | }
35 |
36 | typedef unsigned int angle_t;
37 |
38 | enum Color {
39 | red, green, blue,
40 | };
41 |
42 | void handle_user(struct User user) {
43 |
44 | }
45 |
46 | void handle_tuser(TUser user) {
47 |
48 | }
49 |
50 | void multi_assign() {
51 | int aa = 0;
52 | int bb = 10;
53 | int cc = 20;
54 | aa = bb = cc;
55 | }
56 |
57 | void x(int pi) {}
58 |
59 | #define arrlen(array) (sizeof(array) / sizeof(*array))
60 |
61 | static int *weapon_keys[] = { 0, 0, 0 };
62 | void sizeof_array() {
63 | int x = 10;
64 | int c = sizeof(x);
65 | int n = arrlen(weapon_keys);
66 | }
67 |
68 | int checkcoord[12][4] =
69 | {
70 | {3,0,2,1},
71 | {3,0,2,0},
72 | {3,1,2,0},
73 | {0,0,0,0},
74 | {2,0,2,1},
75 | {0,0,0,0},
76 | {3,1,3,0},
77 | {0,0,0,0},
78 | {2,0,3,1},
79 | {2,1,3,1},
80 | {2,1,3,0}
81 | };
82 |
83 | void i_error(char* s, ...) {
84 | puts(s);
85 | }
86 |
87 | static unsigned long long sixtyfour(void) {
88 | return 64;
89 | }
90 |
91 | typedef union {
92 | int a;
93 | char b;
94 | } MyUnion;
95 |
96 | struct AnonStructTest {
97 | int age;
98 | struct {
99 | int bar;
100 | char* baz;
101 | } foo;
102 | float last_field;
103 | };
104 |
105 | struct {
106 | int fff;
107 | char* sss;
108 | } global_state_using_anon_struct;
109 |
110 | int main() {
111 | struct User user;
112 | user.age = 20;
113 | user.name = "Bob";
114 | printf("age=%d", user.age);
115 | handle_user(user);
116 |
117 | unsigned long long sf = sixtyfour();
118 | printf("sixtyfour=%lld", sf);
119 | // TODO
120 | // struct User user2 = { .age = 30, .name = "Peter" };
121 | TUser user2;
122 | user2.age = 30;
123 | user2.name = "Peter";
124 | handle_tuser(user2);
125 | //
126 | struct small s; // make sure struct inits are capitalized
127 | struct small s2 = { .foo = 10 };
128 | x(PI); // make sure cap consts stay capitalized
129 | return 0;
130 | }
131 |
--------------------------------------------------------------------------------
/tests/5.struct.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | @[export: 'PI']
5 | const PI = 314
6 |
7 | struct User {
8 | name &i8
9 | age int
10 | }
11 |
12 | // lots of structs are typedef'ed in C
13 | struct TUser {
14 | name &i8
15 | age int
16 | capitalizedField f32
17 | // fields in V must be lower case
18 | }
19 |
20 | // struct names have to be capitalized in V
21 | struct Small {
22 | foo int
23 | }
24 |
25 | struct Small3 {
26 | foo int
27 | }
28 |
29 | struct Small2 {
30 | struct_field Small
31 | // make sure field types are capitalized
32 | struct_field_ptr &Small
33 | struct_field_ptr2 &&Small3
34 | }
35 |
36 | fn small_fn(param Small) {
37 | // make sure arg types are capitalized
38 | }
39 |
40 | type Angle_t = u32
41 |
42 | enum Color {
43 | red
44 | green
45 | blue
46 | }
47 |
48 | fn handle_user(user User) {
49 | }
50 |
51 | fn handle_tuser(user TUser) {
52 | }
53 |
54 | fn multi_assign() {
55 | aa := 0
56 | bb := 10
57 | cc := 20
58 | aa = cc
59 | bb = aa
60 | }
61 |
62 | fn x(pi int) {
63 | }
64 |
65 | @[export: 'weapon_keys']
66 | const weapon_keys = [0, 0, 0]!
67 |
68 | fn sizeof_array() {
69 | x := 10
70 | c := sizeof(x)
71 | n := (sizeof(weapon_keys) / sizeof(*weapon_keys))
72 | }
73 |
74 | @[export: 'checkcoord']
75 | const checkcoord = [[3, 0, 2, 1]!, [3, 0, 2, 0]!, [3, 1, 2, 0]!,
76 | [0, 0, 0, 0]!, [2, 0, 2, 1]!, [0, 0, 0, 0]!, [3, 1, 3, 0]!,
77 | [0, 0, 0, 0]!, [2, 0, 3, 1]!, [2, 1, 3, 1]!, [2, 1, 3, 0]!]!
78 |
79 | @[c2v_variadic]
80 | fn i_error(s ...&i8) {
81 | C.puts(s)
82 | }
83 |
84 | fn sixtyfour() i64 {
85 | return 64
86 | }
87 |
88 | union MyUnion {
89 | a int
90 | b i8
91 | }
92 |
93 | struct AnonStructTest {
94 | age int
95 | foo struct {
96 | bar int
97 | baz &i8
98 | }
99 |
100 | last_field f32
101 | }
102 |
103 | struct AnonStruct_105 {
104 | fff int
105 | sss &i8
106 | }
107 |
108 | @[weak]
109 | __global global_state_using_anon_struct AnonStruct_105
110 |
111 | fn main() {
112 | user := User{}
113 | user.age = 20
114 | user.name = c'Bob'
115 | C.printf(c'age=%d', user.age)
116 | handle_user(user)
117 | sf := sixtyfour()
118 | C.printf(c'sixtyfour=%lld', sf)
119 | // TODO
120 | // struct User user2 = { .age = 30, .name = "Peter" };
121 | user2 := TUser{}
122 | user2.age = 30
123 | user2.name = c'Peter'
124 | handle_tuser(user2)
125 | //
126 | s := Small{}
127 | // make sure struct inits are capitalized
128 | s2 := Small{
129 | foo: 10
130 | }
131 |
132 | x(PI)
133 | // make sure cap consts stay capitalized
134 | return
135 | }
136 |
--------------------------------------------------------------------------------
/tests/6.types.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | // standard types should be lower-cased
6 | typedef unsigned short v_u16;
7 | typedef float v_f32;
8 | typedef size_t v_usize;
9 | typedef void *v_voidptr;
10 | typedef bool v_bool;
11 |
12 | // disabled for macOS/Linux compatibility
13 | //#include
14 | //typedef ptrdiff_t v_isize;
15 |
16 | // not sure how this is supposed to work
17 | typedef intptr_t c_intptr_t;
18 |
19 | int main()
20 | {
21 | void *pointers[8];
22 |
23 | return 0;
24 | }
25 |
--------------------------------------------------------------------------------
/tests/6.types.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | // standard types should be lower-cased
5 | type V_u16 = u16
6 | type V_f32 = f32
7 | type V_usize = usize
8 | type V_voidptr = voidptr
9 | type V_bool = bool
10 |
11 | // disabled for macOS/Linux compatibility
12 | //#include
13 | // typedef ptrdiff_t v_isize;
14 | // not sure how this is supposed to work
15 | type C_intptr_t = C.intptr_t
16 |
17 | fn main() {
18 | pointers := [8]voidptr{}
19 | return
20 | }
--------------------------------------------------------------------------------
/tests/7.api_types.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | // Standard types and macros that are always available.
8 |
9 | // Types
10 |
11 | // Represents a 2D vector.
12 | typedef struct tm_vec2_t
13 | {
14 | float x, y;
15 | } tm_vec2_t;
16 |
17 | // Represents a 3D vector.
18 | typedef struct tm_vec3_t
19 | {
20 | float x, y, z;
21 | } tm_vec3_t;
22 |
23 | // Represents a 3D vector in double precision.
24 | typedef struct tm_vec3d_t
25 | {
26 | double x, y, z;
27 | } tm_vec3d_t;
28 |
29 | // Represents a 4D vector.
30 | typedef struct tm_vec4_t
31 | {
32 | float x, y, z, w;
33 | } tm_vec4_t;
34 |
35 | // Represents a 4x4 matrix.
36 | typedef struct tm_mat44_t
37 | {
38 | float xx, xy, xz, xw;
39 | float yx, yy, yz, yw;
40 | float zx, zy, zz, zw;
41 | float wx, wy, wz, ww;
42 | } tm_mat44_t;
43 |
44 | // Represents a transform in TRS form.
45 | typedef struct tm_transform_t
46 | {
47 | tm_vec3_t pos;
48 | tm_vec4_t rot;
49 | tm_vec3_t scl;
50 | } tm_transform_t;
51 |
52 | // Represents a rectangle.
53 | typedef struct tm_rect_t
54 | {
55 | float x, y, w, h;
56 | } tm_rect_t;
57 |
58 | // Used to represent a string slice with pointer and length.
59 | //
60 | // This lets you reason about parts of a string, which you are not able to do with standard
61 | // NULL-terminated strings.
62 | typedef struct tm_str_t
63 | {
64 | // Pointer to string bytes.
65 | const char *data;
66 |
67 | // Length of the string.
68 | uint32_t size;
69 |
70 | // If set to *true*, indicates that there is an allocated NULL-byte after the string data. I.e.
71 | // `data[size] == 0`. This means that `data` can be used immediately as a C string without
72 | // needing to copy it to a separate memory area.
73 | //
74 | // If *false*, there may or may not be a NULL-byte at the end of the string and accessing
75 | // `data[size]` may cause an access violation, so if you want to use it as a C-string you have
76 | // to copy it to a new memory area and append a NULL byte.
77 | //
78 | // Note that the NULL-byte is never included in the `size`.
79 | uint32_t null_terminated;
80 | } tm_str_t;
81 |
82 | // Creates a [[tm_str_t]] from a `char *` `s`.
83 | #define tm_str(s) (TM_LITERAL(tm_str_t){ (s), s ? (uint32_t)strlen(s) : 0, true })
84 |
85 | // Creates a [[tm_str_t]] from a static string `s`. As [[tm_str()]], but uses `sizeof()` instead of
86 | // `strlen()` to determine the length of the string. This means it avoids the `strlen()` overhead
87 | // and can be used to initialize static data, but it can only be used with static strings.
88 | #define TM_STR(s) (TM_LITERAL(tm_str_t){ ("" s ""), (uint32_t)(sizeof("" s "") - 1), true })
89 |
90 | // Creates a [[tm_str_t]] from a start pointer `s` and end pointer `e`.
91 | #define tm_str_range(s, e) (e > s ? TM_LITERAL(tm_str_t){ (s), (uint32_t)((e) - (s)), false } : TM_LITERAL(tm_str_t){ 0 })
92 |
93 | // Represents a time from the system clock.
94 | //
95 | // You can assume the clock to be monotonically increasing, i.e. a larger `opaque` value represents
96 | // a later time, but you shouldn't assume anything else about what the `opaque` value represents or
97 | // the resolution of the timer. Instead, use [[tm_os_time_api->delta()]] to convert elapsed time to
98 | // seconds.
99 | typedef struct tm_clock_o
100 | {
101 | uint64_t opaque;
102 | } tm_clock_o;
103 |
104 | // Represents a unique 128-bit identifier.
105 | typedef struct tm_uuid_t
106 | {
107 | uint64_t a;
108 | uint64_t b;
109 | } tm_uuid_t;
110 |
111 | // Represents an 8-bit per channel RGBA color in sRGB color space (Note: alpha is always linear.)
112 | typedef struct tm_color_srgb_t
113 | {
114 | uint8_t r, g, b, a;
115 | } tm_color_srgb_t;
116 |
117 | // Converts an `uint32_t` to an [[tm_color_srgb_t]] color.
118 | //
119 | // The nibbles in the `uint32_t` hex representation specify TRGB, where T is transparancy (0x00
120 | // means fully opaque and 0xff fully transparent, i.e. it is the invert of alpha). This lets you
121 | // leave the highest nibble out for an opaque color (the most common case), but specify it if
122 | // you want transparency.
123 | //
124 | // Hex | Color
125 | // ---------- | -------------------
126 | // 0x00 | Black
127 | // 0xff0000 | Red
128 | // 0xff000000 | Transparent black
129 | // 0x80ffff00 | 50 % transparent yellow
130 | #define TM_RGB(c) (TM_LITERAL(tm_color_srgb_t){ 0xff & (c >> 16), 0xff & (c >> 8), 0xff & (c >> 0), 0xff - (0xff & (c >> 24)) })
131 |
132 | // Type representing a type in The Truth.
133 | typedef struct tm_tt_type_t
134 | {
135 | uint64_t u64;
136 | } tm_tt_type_t;
137 |
138 | // ID representing an object in The Truth.
139 | typedef struct tm_tt_id_t
140 | {
141 | union
142 | {
143 | // Used for comparing objects or storing them in hash tables.
144 | uint64_t u64;
145 |
146 | struct
147 | {
148 | // Type of the object.
149 | uint64_t type : 10;
150 | // Generation of the object, used to distinguish objects created at the same index.
151 | uint64_t generation : 22;
152 | // Index of the object.
153 | uint64_t index : 32;
154 | };
155 | };
156 | } tm_tt_id_t;
157 |
158 | // Returns the type of `id`.
159 | static inline tm_tt_type_t tm_tt_type(tm_tt_id_t id)
160 | {
161 | tm_tt_type_t res = { id.type };
162 | return res;
163 | }
164 |
165 | // Type representing an undo scope in The Truth.
166 | typedef struct tm_tt_undo_scope_t
167 | {
168 | uint64_t u64;
169 | } tm_tt_undo_scope_t;
170 |
171 | // Used to represent API versions.
172 | //
173 | // Version numbers follow the SemVer 2.0.0 specification:
174 | //
175 | // * The major version is bumped for breaking API changes.
176 | // * The minor version is bumped when new functionality is added in a backwards-compatible manner.
177 | // * The patch version is bumped for backwards-compatible bug fixes.
178 | // * If the major version is 0, the API is considered unstable and under development. In this case,
179 | // nothing should be assumed about backwards compatibility.
180 | //
181 | // See: https://semver.org/spec/v2.0.0.html
182 | //
183 | // !!! WARNING: Be careful about backwards compatibility
184 | // The default action should be to bump the major version whenever you change something in the
185 | // API. If you are considering just bumping the minor or patch version, you must make 100 %
186 | // sure that your changes are backwards compatible, since otherwise you will break existing
187 | // plugins without any warning.
188 | typedef struct tm_version_t
189 | {
190 | // Bumped when breaking changes are made to the API. For example:
191 | //
192 | // * Adding functions in the middle of the API.
193 | // * Changing the number of parameters to a function or their types.
194 | // * Changing the return type of a function.
195 | // * Changing the fields of a struct.
196 | uint32_t major;
197 |
198 | // Bumped when new functionality is added to the API in a backwards-compatible manner.
199 | // Changes are backwards compatible if a caller using an old version of the header file can
200 | // still call into the new version of the ABI without errors. Examples of backwards-compatible
201 | // changes are:
202 | //
203 | // * Adding new functions to the end of the API.
204 | // * Repurposing unused bits in structs.
205 | //
206 | // If you want to change an API and only bump the minor version you should make sure to take
207 | // special care that your changes are really backwards compatible.
208 | uint32_t minor;
209 |
210 | // Bumped for backwards-compatible bug fixes.
211 | uint32_t patch;
212 | } tm_version_t;
213 |
214 | // Creates a [[tm_version_t]] literal.
215 | #define TM_VERSION(major, minor, patch) (TM_LITERAL(tm_version_t){ major, minor, patch })
216 |
217 | // The [[TM_VERSION()]] macro cannot be used to initialize constant objects in Visual Studio.
218 | // (It will give the error "initializer not constant".) This macro can be used as an alternative
219 | // for constant initializations.
220 | //
221 | // !!! TODO: TODO
222 | // Having two separate macros for this is not very elegant. See if we can find a better
223 | // solution.
224 | #define TM_VERSION_INITIALIZER(major, minor, patch) \
225 | { \
226 | major, minor, patch \
227 | }
228 |
229 | // Build configuration
230 | //
231 | // These macros are defined in the build file `premake5.lua`, but listed here for documentation
232 | // purposes.
233 |
234 | #if 0
235 |
236 | // Defined for Windows builds.
237 | #define TM_OS_WINDOWS
238 |
239 | // Defined for OS X builds.
240 | #define TM_OS_MACOSX
241 |
242 | // Defined for Linux builds.
243 | #define TM_OS_LINUX
244 |
245 | // Defined for POSIX builds (OS X or Linux).
246 | #define TM_OS_POSIX
247 |
248 | // If defined, the main job runs on a thread, not a fiber.
249 | #define TM_NO_MAIN_FIBER
250 |
251 | // Defined for debug builds.
252 | #define TM_CONFIGURATION_DEBUG
253 |
254 | // Defined for release builds.
255 | #define TM_CONFIGURATION_RELEASE
256 |
257 | #endif
258 |
259 | // String hashes
260 |
261 | #if defined(_MSC_VER) && !defined(__clang__)
262 |
263 | // `#define TM_USE_STRHASH_TYPE` controls whether we should use a custom type [[tm_strhash_t]] for
264 | // string hashes, or if they should just be `uint64_t`. Currently, it is set to `0` when compiling
265 | // using MSVC and `1` otherwise.
266 | //
267 | // We cannot use the [[tm_strhash_t]] type with the Visual Studio compiler, because it doesn't see
268 | // our [[TM_STATIC_HASH()]] macro as a constant, and thus will generate
269 | // [C2099](https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2099?view=msvc-160)
270 | // compiler error. errors whenever it is used to initialize a global variable. This is unfortunate,
271 | // because it means we can't get type safe string hashes in Visual Studio.
272 | //
273 | // Hopefully, this will be fixed in a future Visual Studio release and we can transition fully to
274 | // the [[tm_strhash_t]] type.
275 | #define TM_USE_STRHASH_TYPE 0
276 |
277 | #else
278 |
279 | // tm_docgen ignore
280 | #define TM_USE_STRHASH_TYPE 1
281 |
282 | #endif
283 |
284 | #if TM_USE_STRHASH_TYPE
285 |
286 | // Type-safe representation of a hashed string.
287 | //
288 | // !!! WARNING: WARNING
289 | // In Visual Studio, string hashes won't use this string type, instead
290 | // [[tm_strhash_t]] will be typedefed to `uint64_t`. The reason for this is that the
291 | // [[TM_STATIC_HASH()]] macro is not seen as a constant by the MSVC compiler and thus using it
292 | // to initialize global variables yields the
293 | // [C2099](https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2099?view=msvc-160)
294 | // compiler error.
295 | //
296 | // This means that the type safety of string hashes won't be checked when compiling with MSVC.
297 | // Make sure you build your code under clang too, with `tmbuild --clang` to check the type
298 | // safety of string hashes. Also, always use the macros [[TM_STRHASH()]] and
299 | // [[TM_STRHASH_U64()]] to convert between [[tm_strhash_t]] and `uint64_t`. This ensures that
300 | // the conversions work on all platforms.
301 | typedef struct tm_strhash_t
302 | {
303 | uint64_t u64;
304 | } tm_strhash_t;
305 |
306 | // Converts a `uint64_t` to a [[tm_strhash_t]].
307 | #define TM_STRHASH(x) (TM_LITERAL(tm_strhash_t){ x })
308 |
309 | // Extracts the `uint64_t` of a [[tm_strhash_t]] value `x`.
310 | #define TM_STRHASH_U64(x) ((x).u64)
311 |
312 | #else
313 |
314 | // tm_docgen ignore
315 | typedef uint64_t tm_strhash_t;
316 |
317 | // tm_docgen ignore
318 | #define TM_STRHASH(x) (x)
319 |
320 | // tm_docgen ignore
321 | #define TM_STRHASH_U64(x) (x)
322 |
323 | #endif
324 |
325 | // Returns true if the the two [[tm_strhash_t]] are equal.
326 | #define TM_STRHASH_EQUAL(a, b) (TM_STRHASH_U64(a) == TM_STRHASH_U64(b))
327 |
328 | // Used for static string hashes. The `hash.exe` utility checks the entire source code and makes
329 | // sure that wherever you use [[TM_STATIC_HASH()]], the numeric value `v` matches the actual hash of the
330 | // string `s` (if not, the code is updated).
331 | //
332 | // When you create a new static hash, don't enter the numeric value, just the string:
333 | // `TM_STATIC_HASH("bla")`.
334 | //
335 | // This ensures that the macro fails to compile until you run `hash.exe` to generate a numeric
336 | // value.
337 | //
338 | // [[TM_STATIC_HASH()]] returns a constant value of type [[tm_strhash_t]].
339 | //
340 | //
344 | #define TM_STATIC_HASH(s, v) TM_STRHASH(sizeof("" s "") > 0 ? v : v)
345 |
346 | // Macros
347 |
348 | #ifdef __cplusplus
349 |
350 | // tm_docgen ignore
351 | #define TM_LITERAL(T) T
352 |
353 | #else
354 |
355 | // Macro for creating a struct literal of type `T` that works both in C and C++. Use as:
356 | //
357 | // ~~~c
358 | // x = TM_LITERAL(tm_vec2_t) {x, y}
359 | // ~~~
360 | //
361 | // In C, this turns into `(tm_vec2_t){0, 0}` and in C++ to `tm_vec2_t{0, 0}`.
362 | //
363 | // Note that use of [[TM_LITERAL()]] is only needed in .h and .inl files that might be included from
364 | // both C and C++. In .c and .cpp file you should just use the native literal format instead of
365 | // relying on [[TM_LITERAL()]].
366 | #define TM_LITERAL(T) (T)
367 |
368 | #endif
369 |
370 | #if defined(_MSC_VER)
371 |
372 | // Marks a function to be exported to DLLs.
373 | #define TM_DLL_EXPORT __declspec(dllexport)
374 |
375 | #else
376 |
377 | // tm_docgen ignore
378 | #define TM_DLL_EXPORT __attribute__((visibility("default")))
379 |
380 | #endif
381 |
382 | #if defined(TM_OS_MACOSX)
383 | #ifndef __restrict
384 |
385 | // tm_docgen ignore
386 | //
387 | // This is not ideal -- preferably we would want to use `restrict` rather than `__restrict` as our
388 | // `restrict` keyword, since that is what the C standard specifies. However, VS does not support
389 | // this, and if we try `#define restrict __restrict` we run into trouble, because some of the
390 | // windows headers actually use `restrict` already.
391 | #define __restrict restrict
392 |
393 | #endif
394 | #endif
395 |
396 | #if defined(_MSC_VER) && !defined(__clang__)
397 |
398 | // Mark struct fields in header files as atomic.
399 | #define TM_ATOMIC
400 |
401 | #else
402 |
403 | // tm_docgen ignore
404 | #define TM_ATOMIC _Atomic
405 |
406 | #endif
407 |
408 | // tm_docgen off
409 |
410 | // Generate an error if this file was included in a C++ file, without wrapping the include in extern
411 | // "C". If you forget extern "C", the first declaration will get C++ linkage and you will then get a
412 | // conflict on the second declaration.
413 | #ifdef __cplusplus
414 | void use_extern_c_wrapper_to_include_the_machinery_headers_in_cpp_files(void);
415 | extern "C" void use_extern_c_wrapper_to_include_the_machinery_headers_in_cpp_files(void);
416 | #endif
417 |
418 | // tm_docgen on
419 |
420 | // Returns the `name` as a string.
421 | #define TM_STRINGIFY(name) #name
422 |
423 | // tm_docgen ignore
424 | #define TM_CONCAT_IMPL(a, b) a##b
425 |
426 | // Concatenates `a` and `b` , allowing you to expand macros before doing the concatenation. This is
427 | // useful when used with builtin macros like `__LINE__` or `__COUNTER__`. `x##__COUNTER__` doesn't
428 | // expand to `x1` since a macro is not expanded if preceded by `#` or `##`, but `TM_CONCAT(x,
429 | // __COUNTER__)` works.
430 | #define TM_CONCAT(a, b) TM_CONCAT_IMPL(a, b)
431 |
432 | // Generates a unique name for a macro variable, based on `name`.
433 | #define TM_MACRO_VAR(name) TM_CONCAT(name, __LINE__)
434 |
435 | // Declares a field that pads a struct with the specified number of bytes. To ensure that structs
436 | // are completely zero-initialized by designated initializers, we require all struct padding to be
437 | // explicitly declared using this macro. (We enable warnings that trigger if there is undeclared
438 | // padding in a struct.)
439 | //
440 | // Example:
441 | //
442 | // ~~~c
443 | // struct x {
444 | // uint32_t a;
445 | // // This padding is needed since `b` needs to be aligned to a 64-bit boundary.
446 | // TM_PAD(4);
447 | // uint64_t b;
448 | // };
449 | // ~~~
450 | //
451 | // Note that in situations where types have different sizes on different platforms you may need to
452 | // pad with different amounts:
453 | //
454 | // ~~~c
455 | // TM_PAD(8 - sizeof(x));
456 | // ~~~
457 | #define TM_PAD(n) char TM_MACRO_VAR(_padding_)[n]
458 |
459 | #if defined(TM_OS_WINDOWS)
460 |
461 | // Disable warnings about padding inserted into structs. Use this before including external headers
462 | // that do not explicitly declare padding. Restore the padding warning afterwards with
463 | // [[TM_RESTORE_PADDING_WARNINGS]].
464 | #define TM_DISABLE_PADDING_WARNINGS \
465 | __pragma(warning(push)) \
466 | __pragma(warning(disable : 4121 4820))
467 |
468 | // Restore padding warnings disabled by [[TM_DISABLE_PADDING_WARNINGS]].
469 | #define TM_RESTORE_PADDING_WARNINGS \
470 | __pragma(warning(pop))
471 |
472 | #elif defined(__clang__)
473 | // tm_docgen ignore
474 | #define TM_DISABLE_PADDING_WARNINGS \
475 | _Pragma("clang diagnostic push") \
476 | _Pragma("clang diagnostic ignored \"-Wpadded\"")
477 | // tm_docgen ignore
478 | #define TM_RESTORE_PADDING_WARNINGS \
479 | _Pragma("clang diagnostic pop")
480 | #elif defined(__GNUC__) || defined(__GNUG__)
481 | // tm_docgen ignore
482 | #define TM_DISABLE_PADDING_WARNINGS \
483 | _Pragma("GCC diagnostic push") \
484 | _Pragma("GCC diagnostic ignored \"-Wpadded\"")
485 | // tm_docgen ignore
486 | #define TM_RESTORE_PADDING_WARNINGS \
487 | _Pragma("GCC diagnostic pop")
488 | #endif
489 |
490 | #if !defined(__cplusplus)
491 |
492 | // Used to implement "inheritance" -- inserting the members of one struct into another, with a
493 | // construct like:
494 | //
495 | // ~~~c
496 | // struct tm_class_t {
497 | // TM_INHERITS(struct tm_super_t);
498 | // ...
499 | // }
500 | // ~~~
501 | //
502 | // In a compiler that supports anonymous structs, (`-Wno-microsoft-anon-tag`, `-fms-extensions`),
503 | // this will be expanded to just `struct tm_super_t;`, otherwise to `struct tm_super_t super;`.
504 | //
505 | // !!! note
506 | // A struct should never have more than one [[TM_INHERITS()]] and it should always be placed
507 | // at the top of the struct.
508 | #define TM_INHERITS(TYPE) TYPE
509 |
510 | #else
511 | // tm_docgen ignore
512 | #define TM_INHERITS(TYPE) TYPE super
513 | #endif
514 |
515 | #if defined(TM_OS_MACOSX) && defined(TM_CPU_ARM)
516 | // tm_docgen ignore
517 | #define TM_PAGE_SIZE 16384
518 | #else
519 | #define TM_PAGE_SIZE 4096
520 | #endif
--------------------------------------------------------------------------------
/tests/7.api_types.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module tests
3 |
4 | // Standard types and macros that are always available.
5 | // Types
6 | // Represents a 2D vector.
7 | struct Tm_vec2_t {
8 | x f32
9 | y f32
10 | }
11 |
12 | // Represents a 3D vector.
13 | struct Tm_vec3_t {
14 | x f32
15 | y f32
16 | z f32
17 | }
18 |
19 | // Represents a 3D vector in double precision.
20 | struct Tm_vec3d_t {
21 | x f64
22 | y f64
23 | z f64
24 | }
25 |
26 | // Represents a 4D vector.
27 | struct Tm_vec4_t {
28 | x f32
29 | y f32
30 | z f32
31 | w f32
32 | }
33 |
34 | // Represents a 4x4 matrix.
35 | struct Tm_mat44_t {
36 | xx f32
37 | xy f32
38 | xz f32
39 | xw f32
40 | yx f32
41 | yy f32
42 | yz f32
43 | yw f32
44 | zx f32
45 | zy f32
46 | zz f32
47 | zw f32
48 | wx f32
49 | wy f32
50 | wz f32
51 | ww f32
52 | }
53 |
54 | // Represents a transform in TRS form.
55 | struct Tm_transform_t {
56 | pos Tm_vec3_t
57 | rot Tm_vec4_t
58 | scl Tm_vec3_t
59 | }
60 |
61 | // Represents a rectangle.
62 | struct Tm_rect_t {
63 | x f32
64 | y f32
65 | w f32
66 | h f32
67 | }
68 |
69 | // Used to represent a string slice with pointer and length.
70 | //
71 | // This lets you reason about parts of a string, which you are not able to do with standard
72 | // NULL-terminated strings.
73 | struct Tm_str_t {
74 | // Pointer to string bytes.
75 | data &i8
76 | // Length of the string.
77 | size u32
78 | // If set to *true*, indicates that there is an allocated NULL-byte after the string data. I.e.
79 | // `data[size] == 0`. This means that `data` can be used immediately as a C string without
80 | // needing to copy it to a separate memory area.
81 | //
82 | // If *false*, there may or may not be a NULL-byte at the end of the string and accessing
83 | // `data[size]` may cause an access violation, so if you want to use it as a C-string you have
84 | // to copy it to a new memory area and append a NULL byte.
85 | //
86 | // Note that the NULL-byte is never included in the `size`.
87 | null_terminated u32
88 | }
89 |
90 | // Creates a [[tm_str_t]] from a `char *` `s`.
91 | // Creates a [[tm_str_t]] from a static string `s`. As [[tm_str()]], but uses `sizeof()` instead of
92 | // `strlen()` to determine the length of the string. This means it avoids the `strlen()` overhead
93 | // and can be used to initialize static data, but it can only be used with static strings.
94 | // Creates a [[tm_str_t]] from a start pointer `s` and end pointer `e`.
95 | // Represents a time from the system clock.
96 | //
97 | // You can assume the clock to be monotonically increasing, i.e. a larger `opaque` value represents
98 | // a later time, but you shouldn't assume anything else about what the `opaque` value represents or
99 | // the resolution of the timer. Instead, use [[tm_os_time_api->delta()]] to convert elapsed time to
100 | // seconds.
101 | struct Tm_clock_o {
102 | opaque u64
103 | }
104 |
105 | // Represents a unique 128-bit identifier.
106 | struct Tm_uuid_t {
107 | a u64
108 | b u64
109 | }
110 |
111 | // Represents an 8-bit per channel RGBA color in sRGB color space (Note: alpha is always linear.)
112 | struct Tm_color_srgb_t {
113 | r u8
114 | g u8
115 | b u8
116 | a u8
117 | }
118 |
119 | // Converts an `uint32_t` to an [[tm_color_srgb_t]] color.
120 | //
121 | // The nibbles in the `uint32_t` hex representation specify TRGB, where T is transparancy (0x00
122 | // means fully opaque and 0xff fully transparent, i.e. it is the invert of alpha). This lets you
123 | // leave the highest nibble out for an opaque color (the most common case), but specify it if
124 | // you want transparency.
125 | //
126 | // Hex | Color
127 | // ---------- | -------------------
128 | // 0x00 | Black
129 | // 0xff0000 | Red
130 | // 0xff000000 | Transparent black
131 | // 0x80ffff00 | 50 % transparent yellow
132 | // Type representing a type in The Truth.
133 | struct Tm_tt_type_t {
134 | u64 u64
135 | }
136 |
137 | // ID representing an object in The Truth.
138 | struct Tm_tt_id_t {
139 | }
140 |
141 | // Returns the type of `id`.
142 | // Type representing an undo scope in The Truth.
143 | struct Tm_tt_undo_scope_t {
144 | u64 u64
145 | }
146 |
147 | // Used to represent API versions.
148 | //
149 | // Version numbers follow the SemVer 2.0.0 specification:
150 | //
151 | // * The major version is bumped for breaking API changes.
152 | // * The minor version is bumped when new functionality is added in a backwards-compatible manner.
153 | // * The patch version is bumped for backwards-compatible bug fixes.
154 | // * If the major version is 0, the API is considered unstable and under development. In this case,
155 | // nothing should be assumed about backwards compatibility.
156 | //
157 | // See: https://semver.org/spec/v2.0.0.html
158 | //
159 | // !!! WARNING: Be careful about backwards compatibility
160 | // The default action should be to bump the major version whenever you change something in the
161 | // API. If you are considering just bumping the minor or patch version, you must make 100 %
162 | // sure that your changes are backwards compatible, since otherwise you will break existing
163 | // plugins without any warning.
164 | struct Tm_version_t {
165 | // Bumped when breaking changes are made to the API. For example:
166 | //
167 | // * Adding functions in the middle of the API.
168 | // * Changing the number of parameters to a function or their types.
169 | // * Changing the return type of a function.
170 | // * Changing the fields of a struct.
171 | major u32
172 | // Bumped when new functionality is added to the API in a backwards-compatible manner.
173 | // Changes are backwards compatible if a caller using an old version of the header file can
174 | // still call into the new version of the ABI without errors. Examples of backwards-compatible
175 | // changes are:
176 | //
177 | // * Adding new functions to the end of the API.
178 | // * Repurposing unused bits in structs.
179 | //
180 | // If you want to change an API and only bump the minor version you should make sure to take
181 | // special care that your changes are really backwards compatible.
182 | minor u32
183 | // Bumped for backwards-compatible bug fixes.
184 | patch u32
185 | }
186 |
187 | // Creates a [[tm_version_t]] literal.
188 | // The [[TM_VERSION()]] macro cannot be used to initialize constant objects in Visual Studio.
189 | // (It will give the error "initializer not constant".) This macro can be used as an alternative
190 | // for constant initializations.
191 | //
192 | // !!! TODO: TODO
193 | // Having two separate macros for this is not very elegant. See if we can find a better
194 | // solution.
195 | // Build configuration
196 | //
197 | // These macros are defined in the build file `premake5.lua`, but listed here for documentation
198 | // purposes.
199 | // Defined for Windows builds.
200 | // Defined for OS X builds.
201 | // Defined for Linux builds.
202 | // Defined for POSIX builds (OS X or Linux).
203 | // If defined, the main job runs on a thread, not a fiber.
204 | // Defined for debug builds.
205 | // Defined for release builds.
206 | // String hashes
207 | // `#define TM_USE_STRHASH_TYPE` controls whether we should use a custom type [[tm_strhash_t]] for
208 | // string hashes, or if they should just be `uint64_t`. Currently, it is set to `0` when compiling
209 | // using MSVC and `1` otherwise.
210 | //
211 | // We cannot use the [[tm_strhash_t]] type with the Visual Studio compiler, because it doesn't see
212 | // our [[TM_STATIC_HASH()]] macro as a constant, and thus will generate
213 | // [C2099](https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2099?view=msvc-160)
214 | // compiler error. errors whenever it is used to initialize a global variable. This is unfortunate,
215 | // because it means we can't get type safe string hashes in Visual Studio.
216 | //
217 | // Hopefully, this will be fixed in a future Visual Studio release and we can transition fully to
218 | // the [[tm_strhash_t]] type.
219 | // tm_docgen ignore
220 | // Type-safe representation of a hashed string.
221 | //
222 | // !!! WARNING: WARNING
223 | // In Visual Studio, string hashes won't use this string type, instead
224 | // [[tm_strhash_t]] will be typedefed to `uint64_t`. The reason for this is that the
225 | // [[TM_STATIC_HASH()]] macro is not seen as a constant by the MSVC compiler and thus using it
226 | // to initialize global variables yields the
227 | // [C2099](https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2099?view=msvc-160)
228 | // compiler error.
229 | //
230 | // This means that the type safety of string hashes won't be checked when compiling with MSVC.
231 | // Make sure you build your code under clang too, with `tmbuild --clang` to check the type
232 | // safety of string hashes. Also, always use the macros [[TM_STRHASH()]] and
233 | // [[TM_STRHASH_U64()]] to convert between [[tm_strhash_t]] and `uint64_t`. This ensures that
234 | // the conversions work on all platforms.
235 | struct Tm_strhash_t {
236 | u64 u64
237 | }
238 |
239 | // Converts a `uint64_t` to a [[tm_strhash_t]].
240 | // Extracts the `uint64_t` of a [[tm_strhash_t]] value `x`.
241 | // tm_docgen ignore
242 | // tm_docgen ignore
243 | // tm_docgen ignore
244 | // Returns true if the the two [[tm_strhash_t]] are equal.
245 | // Used for static string hashes. The `hash.exe` utility checks the entire source code and makes
246 | // sure that wherever you use [[TM_STATIC_HASH()]], the numeric value `v` matches the actual hash of the
247 | // string `s` (if not, the code is updated).
248 | //
249 | // When you create a new static hash, don't enter the numeric value, just the string:
250 | // `TM_STATIC_HASH("bla")`.
251 | //
252 | // This ensures that the macro fails to compile until you run `hash.exe` to generate a numeric
253 | // value.
254 | //
255 | // [[TM_STATIC_HASH()]] returns a constant value of type [[tm_strhash_t]].
256 | //
257 | //
261 | // Macros
262 | // tm_docgen ignore
263 | // Macro for creating a struct literal of type `T` that works both in C and C++. Use as:
264 | //
265 | // ~~~c
266 | // x = TM_LITERAL(tm_vec2_t) {x, y}
267 | // ~~~
268 | //
269 | // In C, this turns into `(tm_vec2_t){0, 0}` and in C++ to `tm_vec2_t{0, 0}`.
270 | //
271 | // Note that use of [[TM_LITERAL()]] is only needed in .h and .inl files that might be included from
272 | // both C and C++. In .c and .cpp file you should just use the native literal format instead of
273 | // relying on [[TM_LITERAL()]].
274 | // Marks a function to be exported to DLLs.
275 | // tm_docgen ignore
276 | // tm_docgen ignore
277 | //
278 | // This is not ideal -- preferably we would want to use `restrict` rather than `__restrict` as our
279 | // `restrict` keyword, since that is what the C standard specifies. However, VS does not support
280 | // this, and if we try `#define restrict __restrict` we run into trouble, because some of the
281 | // windows headers actually use `restrict` already.
282 | // Mark struct fields in header files as atomic.
283 | // tm_docgen ignore
284 | // tm_docgen off
285 | // Generate an error if this file was included in a C++ file, without wrapping the include in extern
286 | // "C". If you forget extern "C", the first declaration will get C++ linkage and you will then get a
287 | // conflict on the second declaration.
288 | // tm_docgen on
289 | // Returns the `name` as a string.
290 | // tm_docgen ignore
291 | // Concatenates `a` and `b` , allowing you to expand macros before doing the concatenation. This is
292 | // useful when used with builtin macros like `__LINE__` or `__COUNTER__`. `x##__COUNTER__` doesn't
293 | // expand to `x1` since a macro is not expanded if preceded by `#` or `##`, but `TM_CONCAT(x,
294 | // __COUNTER__)` works.
295 | // Generates a unique name for a macro variable, based on `name`.
296 | // Declares a field that pads a struct with the specified number of bytes. To ensure that structs
297 | // are completely zero-initialized by designated initializers, we require all struct padding to be
298 | // explicitly declared using this macro. (We enable warnings that trigger if there is undeclared
299 | // padding in a struct.)
300 | //
301 | // Example:
302 | //
303 | // ~~~c
304 | // struct x {
305 | // uint32_t a;
306 | // // This padding is needed since `b` needs to be aligned to a 64-bit boundary.
307 | // TM_PAD(4);
308 | // uint64_t b;
309 | // };
310 | // ~~~
311 | //
312 | // Note that in situations where types have different sizes on different platforms you may need to
313 | // pad with different amounts:
314 | //
315 | // ~~~c
316 | // TM_PAD(8 - sizeof(x));
317 | // ~~~
318 | // Disable warnings about padding inserted into structs. Use this before including external headers
319 | // that do not explicitly declare padding. Restore the padding warning afterwards with
320 | // [[TM_RESTORE_PADDING_WARNINGS]].
321 | // Restore padding warnings disabled by [[TM_DISABLE_PADDING_WARNINGS]].
322 | // tm_docgen ignore
323 | // tm_docgen ignore
324 | // tm_docgen ignore
325 | // tm_docgen ignore
326 | // Used to implement "inheritance" -- inserting the members of one struct into another, with a
327 | // construct like:
328 | //
329 | // ~~~c
330 | // struct tm_class_t {
331 | // TM_INHERITS(struct tm_super_t);
332 | // ...
333 | // }
334 | // ~~~
335 | //
336 | // In a compiler that supports anonymous structs, (`-Wno-microsoft-anon-tag`, `-fms-extensions`),
337 | // this will be expanded to just `struct tm_super_t;`, otherwise to `struct tm_super_t super;`.
338 | //
339 | // !!! note
340 | // A struct should never have more than one [[TM_INHERITS()]] and it should always be placed
341 | // at the top of the struct.
342 | // tm_docgen ignore
343 | // tm_docgen ignore
--------------------------------------------------------------------------------
/tests/8.simple_func_header.h:
--------------------------------------------------------------------------------
1 | void testFunc() {
2 |
3 | }
4 |
5 | void testFunc2(int remove) {
6 |
7 | }
8 |
9 | void testFunc3(int shared) {
10 |
11 | }
12 |
13 | void testFunc4(int select) {
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/tests/8.simple_func_header.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module tests
3 |
4 | fn C.testFunc()
5 |
6 | pub fn test_func() {
7 | C.testFunc()
8 | }
9 |
10 | fn C.testFunc2(remove int)
11 |
12 | pub fn test_func2(remove int) {
13 | C.testFunc2(remove)
14 | }
15 |
16 | fn C.testFunc3(shared_ int)
17 |
18 | pub fn test_func3(shared_ int) {
19 | C.testFunc3(shared_)
20 | }
21 |
22 | fn C.testFunc4(select_ int)
23 |
24 | pub fn test_func4(select_ int) {
25 | C.testFunc4(select_)
26 | }
27 |
--------------------------------------------------------------------------------
/tests/9.func_declaration.h:
--------------------------------------------------------------------------------
1 | void testFunc();
2 |
--------------------------------------------------------------------------------
/tests/9.func_declaration.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module tests
3 |
4 | fn C.testFunc()
5 |
6 | pub fn test_func() {
7 | C.testFunc()
8 | }
9 |
--------------------------------------------------------------------------------
/tests/IGNORE_header_duplicate_type_declaration_2.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | typedef int dup_typ;
4 |
--------------------------------------------------------------------------------
/tests/run_doom_tests.vsh:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022 Alexander Medvednikov. All rights reserved.
2 | // Use of this source code is governed by a GPL license that can
3 | // be found in the LICENSE file.
4 | import term
5 | import os
6 | import runtime
7 |
8 | struct App {
9 | mut:
10 | idx atomic int
11 | }
12 |
13 | const files = [
14 | 'g_game',
15 | 'd_main',
16 | 'm_menu',
17 | 'p_enemy'
18 | //'wi_stuff'
19 | 'p_saveg'
20 | //'st_stuff',
21 | 'p_spec',
22 | 'p_map',
23 | 'am_map',
24 | 'r_things',
25 | 'r_draw',
26 | 'p_mobj',
27 | 'r_segs',
28 | 'r_data',
29 | 'p_setup',
30 | 'p_pspr',
31 | 'p_maputl',
32 | 'p_inter',
33 | 's_sound',
34 | 'r_main',
35 | 'p_switch',
36 | 'hu_stuff',
37 | 'statdump',
38 | 'r_plane',
39 | 'r_bsp',
40 | 'p_sight',
41 | 'p_floor',
42 | 'deh_bexstr',
43 | 'st_lib'
44 | //'sounds',
45 | 'p_user',
46 | 'p_plats',
47 | 'p_lights',
48 | 'hu_lib',
49 | 'f_wipe',
50 | 'r_sky',
51 | 'p_tick',
52 | 'p_telept',
53 | 'm_random',
54 | 'dstrings',
55 | 'doomdef'
56 | //'deh_weapon.,
57 | //'deh_thing.c,
58 | //'deh_sound.c,
59 | //'deh_ptr.c / deh_frame.c,
60 | //'deh_doom.c,
61 | //'deh_cheat.c,
62 | //'deh_ammo.c,
63 | 'd_items',
64 | ]
65 |
66 | const exe = executable()
67 | const tests_dir = dir(exe)
68 | const c2v_dir = dir(tests_dir)
69 | const doom_dir = join_path(dir(c2v_dir), 'doom')
70 |
71 | const src_dir = join_path(doom_dir, 'src/doom')
72 |
73 | fn main() {
74 | println(src_dir)
75 |
76 | mut app := &App{
77 | idx: 0
78 | }
79 |
80 | for file in files {
81 | app.run(0)
82 | }
83 | /*
84 | nr_cpus := runtime.nr_cpus()
85 | mut threads := []thread{}
86 | for x in 0 .. nr_cpus {
87 | threads << go app.run(x)
88 | }
89 | threads.wait()
90 | */
91 | println(term.green('ALL GOOD'))
92 | }
93 |
94 | fn (mut app App) run(x int) {
95 | if app.idx >= files.len {
96 | return
97 | }
98 | file := files[app.idx]
99 | app.idx++
100 | // for file in files {
101 | println('\nTranslating ${file}... (thread ${x})')
102 | cmd := 'v run ${c2v_dir}/tools/build_doom_file.vsh doom/${file}'
103 | ret := os.system('${cmd} > /dev/null')
104 | if ret != 0 {
105 | println(term.red('FAILED'))
106 | os.system(cmd) // re-run it to print the error
107 | exit(1)
108 | }
109 | println(term.green('OK'))
110 | //}
111 | }
112 |
--------------------------------------------------------------------------------
/tests/run_tests.vsh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env -S v
2 |
3 | // Copyright (c) 2022 Alexander Medvednikov. All rights reserved.
4 | // Use of this source code is governed by a GPL license that can
5 | // be found in the LICENSE file.
6 | import term
7 | import os
8 |
9 | const c2v_dir = @VMODROOT
10 | const tests_dir = join_path(c2v_dir, 'tests')
11 | const exe_path = join_path(c2v_dir, $if windows {
12 | 'c2v.exe'
13 | } $else {
14 | 'c2v'
15 | })
16 |
17 | fn replace_file_extension(file_path string, old_extension string, new_extension string) string {
18 | // NOTE: It can't be just `file_path.replace(old_extenstion, new_extension)`, because it will replace all occurencies of old_extenstion string.
19 | // Path '/dir/dir/dir.c.c.c.c.c.c/kalle.c' will become '/dir/dir/dir.json.json.json.json.json.json/kalle.json'.
20 | return file_path.trim_string_right(old_extension) + new_extension
21 | }
22 |
23 | fn try_process_filter_argument() string {
24 | second_argument := os.args[1]
25 |
26 | if second_argument == '-h' {
27 | println('Usage: v run tests/run_tests.vsh ([testname])')
28 | exit(0)
29 | } else {
30 | return second_argument
31 | }
32 |
33 | return ''
34 | }
35 |
36 | fn build_c2v() {
37 | chdir(c2v_dir) or {
38 | eprintln('Cannot change directory to ' + c2v_dir)
39 | exit(1)
40 | }
41 |
42 | println('building c2v...')
43 | c2v_build_command_result := execute('v -o c2v -experimental -w .')
44 |
45 | if !exists(exe_path) || c2v_build_command_result.exit_code != 0 {
46 | eprintln('c2v compilation failed:')
47 | eprintln(c2v_build_command_result.output)
48 | eprintln('c2vdir="${c2v_dir}"')
49 |
50 | eprintln(ls(c2v_dir) or {
51 | eprintln('Cannot list c2v directory')
52 | exit(1)
53 | })
54 |
55 | exit(1)
56 | }
57 |
58 | println('done')
59 | }
60 |
61 | fn start_testing_process(filter string) {
62 | if run_tests('.c', '', filter) == false || run_tests('.h', 'wrapper', filter) == false {
63 | exit(1)
64 | }
65 |
66 | os.chdir(tests_dir) or {
67 | panic('Failed to switch folder to tests folder for testing translation for relative paths - ${err}')
68 | }
69 |
70 | if run_tests('.c', '', filter) == false || run_tests('.h', 'wrapper', filter) == false {
71 | exit(1)
72 | }
73 | }
74 |
75 | fn run_tests(test_file_extension string, c2v_opts string, filter string) bool {
76 | mut files := get_test_files(test_file_extension).filter(it.all_after_last('/').starts_with('IGNORE_') == false)
77 |
78 | files.sort()
79 |
80 | current_platform := os.user_os()
81 | next_file: for file in files {
82 | // skip all platform dependent .c/.out pairs, on non matching platforms:
83 | for platform in ['linux', 'macos', 'windows'] {
84 | if file.ends_with('_${platform}.c') && current_platform != platform {
85 | println(' >>>>> skipping `${file}` on ${current_platform} .')
86 | continue next_file
87 | }
88 | }
89 |
90 | print(file + '... ')
91 |
92 | if filter != '' {
93 | file.index(filter) or { continue }
94 | }
95 |
96 | if try_compile_test_file(file) == false {
97 | return false
98 | }
99 |
100 | c2v_cmd := '${exe_path} ${c2v_opts} ${file}'
101 | c2v_res := execute(c2v_cmd)
102 | if c2v_res.exit_code != 0 {
103 | eprintln(c2v_res.output)
104 | eprintln('command: ${c2v_cmd}')
105 | return false
106 | }
107 |
108 | generated_file := try_get_generated_file(file, test_file_extension) or {
109 | eprintln(term.red('FAIL'))
110 | return false
111 | }
112 |
113 | format_generated_file(generated_file)
114 |
115 | expected := get_expected_file_content(file, test_file_extension)
116 | result := get_result_file_content(generated_file, test_file_extension)
117 |
118 | if expected != result {
119 | print_test_fail_details(expected, result, c2v_cmd)
120 | return false
121 | } else {
122 | do_post_test_cleanup(generated_file)
123 | println(term.green('OK'))
124 | }
125 | }
126 |
127 | return true
128 | }
129 |
130 | fn get_test_files(extension string) []string {
131 | return walk_ext(tests_dir, extension)
132 | }
133 |
134 | fn try_compile_test_file(file string) bool {
135 | // Make sure the C test is a correct C program first
136 | o_path := join_path(temp_dir(), file_name(file)) + '.o'
137 | cmd := 'cc -c -w ${file} -o ${o_path}'
138 | res := execute(cmd)
139 |
140 | if res.exit_code != 0 {
141 | eprintln('failed to compile C test `${file}`')
142 | eprintln('command: ${cmd}')
143 | return false
144 | }
145 |
146 | return true
147 | }
148 |
149 | fn try_get_generated_file(file string, test_file_extension string) !string {
150 | generated_file := replace_file_extension(file, test_file_extension, '.v')
151 | println(generated_file)
152 |
153 | if !exists(generated_file) {
154 | return error('Expected generated file `${generated_file}` does not exist')
155 | }
156 |
157 | return generated_file
158 | }
159 |
160 | fn format_generated_file(file string) {
161 | system('v fmt -w ${file}')
162 | }
163 |
164 | fn get_expected_file_content(file string, test_file_extension string) string {
165 | file_content := read_file(replace_file_extension(file, test_file_extension, '.out')) or { '' }
166 | return file_content.trim_space()
167 | }
168 |
169 | fn get_result_file_content(file string, test_file_extension string) string {
170 | file_content := read_file(file) or { '' }
171 | return file_content.after('// vstart').trim_space()
172 | }
173 |
174 | fn print_test_fail_details(expected string, got string, cmd string) {
175 | eprintln(term.red('\nFAIL'))
176 | eprintln('expected:')
177 | eprintln(expected)
178 | eprintln('\n===got:')
179 | eprintln(got)
180 |
181 | eprintln('\n====diff=====')
182 | expected_file_form := join_path(temp_dir(), 'expected.txt')
183 | got_file_form := join_path(temp_dir(), 'got.txt')
184 |
185 | write_file(expected_file_form, expected) or { eprintln('Cannot write expected file') }
186 | write_file(got_file_form, got) or { eprintln('Cannot write got file') }
187 |
188 | diff := execute('diff -u ${expected_file_form} ${got_file_form}')
189 | eprintln(diff.output)
190 | eprintln('>>>>>>>>>>>>>>>>>> Failed cmd: ${cmd}')
191 | }
192 |
193 | fn do_post_test_cleanup(generated_file string) {
194 | os.rm(generated_file) or {}
195 | }
196 |
197 | mut filter := ''
198 |
199 | if os.args.len > 1 {
200 | filter = try_process_filter_argument()
201 | }
202 |
203 | build_c2v()
204 | start_testing_process(filter)
205 |
--------------------------------------------------------------------------------
/tests/test.c/1.hello.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main() {
4 | printf("hello world!");
5 | return 0;
6 | }
7 |
8 | typedef struct Foo {
9 | int bar;
10 | } Foo;
11 |
12 | void implicit_inits() {
13 | int num;
14 | Foo foo;
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/tests/test.c/1.hello.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn main() {
5 | C.printf(c'hello world!')
6 | return
7 | }
8 |
9 | struct Foo {
10 | bar int
11 | }
12 |
13 | fn implicit_inits() {
14 | num := 0
15 | foo := Foo{}
16 | }
17 |
--------------------------------------------------------------------------------
/tests_todo/5.if_paren_call.c:
--------------------------------------------------------------------------------
1 | main() {
2 | int a;
3 | if ((a = puts ("Hello World"))) {
4 | puts ("noes");
5 | }
6 | if ((a = puts ("Hello World")) != 0) {
7 | puts ("noes");
8 | }
9 | int cacatua;
10 | if ((cacatua = puts ("Hello World"))) {
11 | puts ("noes");
12 | }
13 | /*
14 | if ((1 > 0 && (3 < 20) && 1 < 10)) {
15 | puts ("noes");
16 | }
17 | */
18 | }
19 |
--------------------------------------------------------------------------------
/tests_todo/5.if_paren_call.out:
--------------------------------------------------------------------------------
1 | @[translated]
2 | module main
3 |
4 | fn main() {
5 | a := 0
6 | a = C.puts(c'Hello World')
7 | if a {
8 | C.puts(c'noes')
9 | }
10 | a = C.puts(c'Hello World')
11 | if a != 0 {
12 | C.puts(c'noes')
13 | }
14 | cacatua := 0
15 | cacatua = C.puts(c'Hello World')
16 | if cacatua {
17 | C.puts(c'noes')
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tools/build_doom_file.vsh:
--------------------------------------------------------------------------------
1 | import os
2 | import term
3 |
4 | const doom_src = home_dir() + '/code/doom/chocolate-doom/src/'
5 |
6 | const c2v_src = os.dir(os.dir(@FILE))
7 |
8 | const verbose = os.getenv('VVERBOSE') != ''
9 |
10 | const sdl_cflags = os.execute('sdl2-config --cflags').output.trim_space()
11 |
12 | fn cprintln(s string) {
13 | println(term.colorize(term.bold, term.colorize(term.green, s)))
14 | }
15 |
16 | fn run(s string) {
17 | println(' execute: ${term.colorize(term.green, s)}')
18 | ret := os.execute(s)
19 | if ret.exit_code != 0 {
20 | eprintln('Failed command: ${s}')
21 | eprintln(ret.output)
22 | eprintln('Exiting.')
23 | exit(1)
24 | }
25 | if verbose {
26 | println(ret.output)
27 | }
28 | }
29 |
30 | file := os.args[1]
31 |
32 | os.mkdir('/tmp/doom') or {}
33 |
34 | if !exists(join_path(doom_src, '${file}.c')) {
35 | eprintln(join_path(doom_src, '${file}.c') + ' does not exist')
36 | exit(1)
37 | }
38 |
39 | cur_dir := os.getwd()
40 | cprintln('Current folder: ${cur_dir} ; change to folder: ${doom_src}')
41 | chdir(doom_src)!
42 |
43 | if os.args.len < 2 {
44 | println('usage: v run build_doom_file.vsh doom/p_enemy')
45 | exit(1)
46 | }
47 |
48 | cprintln('Cleanup previous build artefacts')
49 | run('make clean')
50 |
51 | if os.args.contains('-g') {
52 | f := file.replace('doom/', 'doom.dir/')
53 | run('cc -g -I. -I.. -I../.. ${sdl_cflags} -w -ferror-limit=100 -c -I ${doom_src} -o ' +
54 | '${doom_src}/doom/CMakeFiles/${f}.c.o ${file}.c')
55 | run('make -j 6 chocolate-doom')
56 | println('-g done')
57 | exit(0)
58 | } else if os.args.contains('-prod') {
59 | f := file.replace('doom/', 'doom.dir/')
60 | run('cc -O2 -I. -I.. -I../.. ${sdl_cflags} -w -ferror-limit=100 -c -I ${doom_src} -o ' +
61 | '/var/tmp/${f}.c.o2.o ${file}.c')
62 | println('-o2 done')
63 | exit(0)
64 | }
65 |
66 | // ast_file := join_path(doom_src, '${file}.json')
67 | v_file := join_path(doom_src, '${file}.v')
68 |
69 | /*
70 | if !exists(ast_file) {
71 | println('${file}.json is missing, generating it...')
72 | // run('clang -v ${file}.c')
73 | run('clang -fparse-all-comments -I. -I.. -I../.. $sdl_cflags -w ' +
74 | '-Xclang -ast-dump=json -fno-diagnostics-color ' + '-c ${file}.c > ${file}.json')
75 | }
76 |
77 | if !exists(ast_file) {
78 | eprintln('failed to generate $ast_file')
79 | exit(1)
80 | }
81 | */
82 |
83 | println('> change folder to: ${c2v_src}')
84 | chdir(c2v_src)!
85 |
86 | cprintln('Converting C to V...')
87 | c_file := join_path(doom_src, '${file}.c')
88 | run('./c2v -keep_ast ${c_file}')
89 |
90 | if !exists(v_file) {
91 | eprintln('failed to generate v file ${v_file}')
92 | exit(1)
93 | }
94 |
95 | // cprintln('Formatting translated v file...')
96 | // run('v -w fmt -translated -w $v_file')
97 |
98 | cprintln('Building translated v file...')
99 | run('v -cc clang -d 4bytebool -showcc -w -cg -keepc -gc none -translated ' +
100 | '-cflags "-fPIE -w -ferror-limit=100 -I ${doom_src} ${sdl_cflags} -c" -o /tmp/${file}.o ${v_file}')
101 |
102 | chdir(os.dir(doom_src))!
103 | if file.starts_with('doom/') {
104 | f := file.replace('doom/', 'doom.dir/')
105 | source_file := '/tmp/${file}.o'
106 | target_file := '${doom_src}/doom/CMakeFiles/${f}.c.o'
107 | cprintln('Move by copying: ${source_file} => ${target_file}')
108 | os.mv_by_cp('/tmp/${file}.o', target_file)!
109 |
110 | cprintln('Remake chocolate-doom')
111 | run('make -j 6 chocolate-doom')
112 | }
113 |
114 | println('Done. You can run doom with: `src/chocolate-doom -width 640`')
115 |
--------------------------------------------------------------------------------
/tools/node_kind_gen/gen_node_kind_code.v:
--------------------------------------------------------------------------------
1 | // This code implements a small tool that can be used to generate a NodeKind and str_to_node_kind_map constructions,
2 | // used in the node_kind.v. Since there can be pretty big list of AST node types, making this by hand is not the most
3 | // optimal way to do it.
4 | //
5 | // To use this tool, simply put a list of node type names into the 'types' file, and place in next to this file.
6 | // Content in this file should look like this:
7 | // AccessSpecDecl
8 | // AcquireCapabilityAttr
9 | // AddrLabelExpr
10 | import os
11 | import artemkakun.textproc.src.case
12 |
13 | // Generates node kind related code, based on the 'types' file.
14 | //
15 | // Example:
16 | // Content of 'types' file:
17 | // AccessSpecDecl
18 | // AcquireCapabilityAttr
19 | // AddrLabelExpr
20 | //
21 | // Generated code:
22 | // enum NodeKind {
23 | // acces_spec_decl,
24 | // acquire_capability_attr,
25 | // addr_label_expr,
26 | // }
27 | //
28 | // const str_to_node_kind_map = {
29 | // 'AccessSpecDecl': .acces_spec_decl,
30 | // 'AcquireCapabilityAttr': .acquire_capability_attr,
31 | // 'AddrLabelExpr': .addr_label_expr,
32 | // }
33 | fn main() {
34 | types_file := 'types'
35 |
36 | lines := os.read_lines(types_file) or {
37 | println('{types_file} file not found')
38 | return
39 | }
40 |
41 | println('enum NodeKind {')
42 | println('bad')
43 |
44 | for line in lines {
45 | node_kind_name := line.trim_space()
46 | println(case.string_to_snake_case(node_kind_name))
47 | }
48 |
49 | println('}')
50 |
51 | print('\n')
52 |
53 | println('const str_to_node_kind_map = {')
54 | print_map_pair('BAD', 'NodeKind.bad')
55 |
56 | for line in lines {
57 | node_kind_name := line.trim_space()
58 | print_map_pair(node_kind_name, '.${case.string_to_snake_case(node_kind_name)}')
59 | }
60 |
61 | println('}')
62 | }
63 |
64 | fn print_map_pair(key string, value string) {
65 | println('\'${key}\': ${value}')
66 | }
67 |
--------------------------------------------------------------------------------
/tools/node_kind_gen/types:
--------------------------------------------------------------------------------
1 | AccessSpecDecl
2 | AcquireCapabilityAttr
3 | AddrLabelExpr
4 | AlignedAttr
5 | AllocSizeAttr
6 | AlwaysInlineAttr
7 | AnalyzerNoReturnAttr
8 | ArrayFiller
9 | ArraySubscriptExpr
10 | AsmLabelAttr
11 | AssertExclusiveLockAttr
12 | AtomicExpr
13 | AvailabilityAttr
14 | BinaryOperator
15 | BlockCommandComment
16 | BlockExpr
17 | BreakStmt
18 | BuiltinTemplateDecl
19 | BuiltinType
20 | CallExpr
21 | CapabilityAttr
22 | CaseStmt
23 | CharacterLiteral
24 | ClassDecl
25 | ClassTemplate
26 | ClassTemplateDecl
27 | ClassTemplatePartialSpecialization
28 | ClassTemplatePartialSpecializationDecl
29 | ClassTemplateSpecialization
30 | ClassTemplateSpecializationDecl
31 | ColdAttr
32 | CompoundAssignOperator
33 | CompoundLiteralExpr
34 | CompoundStmt
35 | ConditionalOperator
36 | ConstantArrayType
37 | ConstantExpr
38 | ConstAttr
39 | ContinueStmt
40 | CStyleCastExpr
41 | CXCursorKind
42 | CXX
43 | CXXAccessSpecifier
44 | CXXBindTemporaryExpr
45 | CXXBoolLiteralExpr
46 | CXXCatchStmt
47 | CXXConstCastExpr
48 | CXXConstructExpr
49 | CXXConstructor
50 | CXXConstructorDecl
51 | CXXConversion
52 | CXXConversionDecl
53 | CXXCtorInitializer
54 | CXXDefaultArgExpr
55 | CXXDefaultInitExpr
56 | CXXDeleteExpr
57 | CXXDependentScopeMemberExpr
58 | CXXDestructor
59 | CXXDestructorDecl
60 | CXXDynamicCastExpr
61 | CXXForRangeStmt
62 | CXXFunctionalCastExpr
63 | CXXMemberCallExpr
64 | CXXMethod
65 | CXXMethodDecl
66 | CXXNewExpr
67 | CXXNoexceptExpr
68 | CXXNullPtrLiteralExpr
69 | CXXOperatorCallExpr
70 | CXXPseudoDestructorExpr
71 | CXXRecord
72 | CXXRecordDecl
73 | CXXReinterpretCastExpr
74 | CXXScalarValueInitExpr
75 | CXXStaticCastExpr
76 | CXXTemporaryObjectExpr
77 | CXXThisExpr
78 | CXXThrowExpr
79 | CXXTryStmt
80 | CXXTypeidExpr
81 | CXXUnresolvedConstructExpr
82 | DecayedType
83 | DeclRefExpr
84 | DeclStmt
85 | DecltypeType
86 | DefaultStmt
87 | DependentNameType
88 | DependentScopeDeclRefExpr
89 | DependentTemplateSpecializationType
90 | DeprecatedAttr
91 | DiagnoseIfAttr
92 | DisableTailCallsAttr
93 | DoStmt
94 | ElaboratedType
95 | EnableIfAttr
96 | Enum
97 | EnumConstantDecl
98 | EnumDecl
99 | EnumType
100 | ExprWithCleanups
101 | Field
102 | FieldDecl
103 | FixedPointLiteral
104 | FloatingLiteral
105 | FormatArgAttr
106 | FormatAttr
107 | ForStmt
108 | FriendDecl
109 | FullComment
110 | Function
111 | FunctionDecl
112 | FunctionNoProtoType
113 | FunctionProtoType
114 | FunctionTemplate
115 | FunctionTemplateDecl
116 | GCCAsmStmt
117 | GenericSelectionExpr
118 | GNUNullExpr
119 | GotoStmt
120 | GuardedByAttr
121 | HTMLEndTagComment
122 | HTMLStartTagComment
123 | IfStmt
124 | ImaginaryLiteral
125 | ImplicitCastExpr
126 | ImplicitValueInitExpr
127 | IncompleteArrayType
128 | IndirectFieldDecl
129 | IndirectGotoStmt
130 | InitListExpr
131 | InjectedClassNameType
132 | InlineCommandComment
133 | IntegerLiteral
134 | InvalidCode
135 | InvalidFile
136 | LabelRef
137 | LabelStmt
138 | LambdaExpr
139 | LinkageSpec
140 | LinkageSpecDecl
141 | LValueReferenceType
142 | MaterializeTemporaryExpr
143 | MaxFieldAlignmentAttr
144 | MemberExpr
145 | MemberPointerType
146 | MemberRef
147 | MemberRefExpr
148 | ModuleImport
149 | MSAsmStmt
150 | Namespace
151 | NamespaceAlias
152 | NamespaceDecl
153 | NamespaceRef
154 | NoDeclFound
155 | NoEscapeAttr
156 | NoInlineAttr
157 | NonTypeTemplateParameter
158 | NonTypeTemplateParmDecl
159 | NoSanitizeAttr
160 | NoThrowAttr
161 | NotImplemented
162 | Null
163 | NullStmt
164 | ObjCAtCatchStmt
165 | ObjCAtFinallyStmt
166 | ObjCAtSynchronizedStmt
167 | ObjCAtThrowStmt
168 | ObjCAtTryStmt
169 | ObjCAutoreleasePoolStmt
170 | ObjCAvailabilityCheckExpr
171 | ObjCBoolLiteralExpr
172 | ObjCBridgedCastExpr
173 | ObjCCategoryDecl
174 | ObjCCategoryImplDecl
175 | ObjCClassMethodDecl
176 | ObjCClassRef
177 | ObjCDynamicDecl
178 | ObjCEncodeExpr
179 | ObjCForCollectionStmt
180 | ObjCImplementationDecl
181 | ObjCInstanceMethodDecl
182 | ObjCInterfaceDecl
183 | ObjCIvarDecl
184 | ObjCMessageExpr
185 | ObjCPropertyDecl
186 | ObjCProtocolDecl
187 | ObjCProtocolExpr
188 | ObjCProtocolRef
189 | ObjCSelectorExpr
190 | ObjCSelfExpr
191 | ObjCStringLiteral
192 | ObjCSuperClassRef
193 | ObjCSynthesizeDecl
194 | OffsetOfExpr
195 | OMPArraySectionExpr
196 | OMPAtomicDirective
197 | OMPBarrierDirective
198 | OMPCancelDirective
199 | OMPCancellationPointDirective
200 | OMPCriticalDirective
201 | OMPDistributeDirective
202 | OMPDistributeParallelForDirective
203 | OMPDistributeParallelForSimdDirective
204 | OMPDistributeSimdDirective
205 | OMPFlushDirective
206 | OMPForDirective
207 | OMPForSimdDirective
208 | OMPMasterDirective
209 | OMPOrderedDirective
210 | OMPParallelDirective
211 | OMPParallelForDirective
212 | OMPParallelForSimdDirective
213 | OMPParallelSectionsDirective
214 | OMPSectionDirective
215 | OMPSectionsDirective
216 | OMPSimdDirective
217 | OMPSingleDirective
218 | OMPTargetDataDirective
219 | OMPTargetDirective
220 | OMPTargetEnterDataDirective
221 | OMPTargetExitDataDirective
222 | OMPTargetParallelDirective
223 | OMPTargetParallelForDirective
224 | OMPTargetParallelForSimdDirective
225 | OMPTargetSimdDirective
226 | OMPTargetTeamsDirective
227 | OMPTargetTeamsDistributeDirective
228 | OMPTargetTeamsDistributeParallelForDirective
229 | OMPTargetTeamsDistributeParallelForSimdDirective
230 | OMPTargetTeamsDistributeSimdDirective
231 | OMPTargetUpdateDirective
232 | OMPTaskDirective
233 | OMPTaskgroupDirective
234 | OMPTaskLoopDirective
235 | OMPTaskLoopSimdDirective
236 | OMPTaskwaitDirective
237 | OMPTaskyieldDirective
238 | OMPTeamsDirective
239 | OMPTeamsDistributeDirective
240 | OMPTeamsDistributeParallelForDirective
241 | OMPTeamsDistributeParallelForSimdDirective
242 | OMPTeamsDistributeSimdDirective
243 | OpaqueValueExpr
244 | original
245 | OverloadCandidate
246 | OverloadedDeclRef
247 | OverrideAttr
248 | Overrides
249 | PackedAttr
250 | PackExpansionExpr
251 | PackExpansionType
252 | ParagraphComment
253 | ParenExpr
254 | ParenListExpr
255 | ParenType
256 | ParmDecl
257 | ParmVarDecl
258 | PointerType
259 | PredefinedExpr
260 | private
261 | protected
262 | public
263 | PureAttr
264 | QualType
265 | Record
266 | RecordDecl
267 | RecordType
268 | ReleaseCapabilityAttr
269 | RequiresCapabilityAttr
270 | RestrictAttr
271 | ReturnStmt
272 | ReturnsTwiceAttr
273 | ruct
274 | RValueReferenceType
275 | ScopedLockableAttr
276 | SEHExceptStmt
277 | SEHFinallyStmt
278 | SEHLeaveStmt
279 | SEHTryStmt
280 | SizeOfPackExpr
281 | StaticAssert
282 | StaticAssertDecl
283 | StmtExpr
284 | StringLiteral
285 | StructDecl
286 | SubstNonTypeTemplateParmExpr
287 | SubstTemplateTypeParmType
288 | SwitchStmt
289 | TemplateArgument
290 | TemplateRef
291 | TemplateSpecializationType
292 | TemplateTemplateParameter
293 | TemplateTemplateParmDecl
294 | TemplateTypeParameter
295 | TemplateTypeParm
296 | TemplateTypeParmDecl
297 | TemplateTypeParmType
298 | TextComment
299 | TranslationUnit
300 | TranslationUnitDecl
301 | TypeAliasDecl
302 | TypeAliasTemplateDecl
303 | Typedef
304 | TypedefDecl
305 | TypedefType
306 | TypeRef
307 | TypeVisibilityAttr
308 | UnaryExpr
309 | UnaryExprOrTypeTraitExpr
310 | UnaryOperator
311 | UnaryTransformType
312 | UnexposedAttr
313 | UnexposedDecl
314 | UnexposedExpr
315 | UnexposedStmt
316 | Unhandled
317 | UnionDecl
318 | UnresolvedLookupExpr
319 | UnresolvedMemberExpr
320 | UnusedAttr
321 | UsingDecl
322 | UsingDeclaration
323 | UsingDirective
324 | UsingDirectiveDecl
325 | UsingShadowDecl
326 | VAArgExpr
327 | VarDecl
328 | VariableRef
329 | virtual
330 | VisibilityAttr
331 | WarnUnusedResultAttr
332 | WhileStmt
333 |
--------------------------------------------------------------------------------
/v.mod:
--------------------------------------------------------------------------------
1 | Module {
2 | name: 'c2v'
3 | description: 'Tool for translation/wrapper generation from C to V'
4 | version: '0.4.1'
5 | license: 'GPLv3'
6 | dependencies: ['ArtemkaKun.textproc']
7 | }
8 |
--------------------------------------------------------------------------------