├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── api
├── ems
│ └── sdl.d
└── native
│ └── sdl.d
├── build_asmjs
├── build_native
├── check
├── fetch_toolchain
├── ldc.patch
├── rt
├── mainloop.c
├── object.d
├── runtime.c
├── standard.d
└── test.d
└── src
├── game.d
├── main.d
└── vec.d
/.gitignore:
--------------------------------------------------------------------------------
1 | /config
2 | /bin
3 | *.swp
4 | .session.vim
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 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 Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | BIN?=bin
2 | EXT?=exe
3 |
4 | DFLAGS?="-Iapi/native"
5 | LINK?=clang
6 |
7 | all: \
8 | $(BIN)/game.$(EXT) \
9 | $(BIN)/tests.$(EXT) \
10 |
11 | $(BIN)/tests.$(EXT): \
12 | $(BIN)/rt/test.bc \
13 | $(BIN)/rt/runtime.bc \
14 | $(BIN)/rt/standard.bc \
15 | $(BIN)/rt/object.bc
16 |
17 | $(BIN)/game.$(EXT): \
18 | $(BIN)/src/main.bc \
19 | $(BIN)/src/game.bc \
20 | $(BIN)/src/vec.bc \
21 | $(BIN)/rt/runtime.bc \
22 | $(BIN)/rt/mainloop.bc \
23 | $(BIN)/rt/standard.bc \
24 | $(BIN)/rt/object.bc
25 |
26 | #------------------------------------------------------------------------------
27 | # Generic rules
28 | #------------------------------------------------------------------------------
29 |
30 | clean:
31 | rm -rf $(BIN)
32 |
33 | $(BIN)/%.bc: %.d
34 | @mkdir -p $(dir $@)
35 | ldc2 $(DFLAGS) -release -boundscheck=off -Isrc -Irt $< -c -output-bc -of$@
36 |
37 | $(BIN)/%.bc: %.c
38 | @mkdir -p $(dir $@)
39 | clang $(CFLAGS) $< -c -S -emit-llvm -o "$@.llvm"
40 | llvm-as "$@.llvm" -o="$@"
41 |
42 | $(BIN)/%.$(EXT):
43 | @mkdir -p $(dir $@)
44 | llvm-link $^ -o="$@.bc"
45 | $(LINK) $(CFLAGS) $(LDFLAGS) -w "$@.bc" -o "$@" -lSDL -lSDL_gfx
46 |
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # dscripten
2 | An example of D to asmjs using Emscripten
3 |
4 | Authors
5 | =======
6 |
7 | - Ace17 (Sebastien Alaiwan: sebastien.alaiwan@gmail.com)
8 |
9 | Purpose
10 | =======
11 |
12 | This is a demonstration on how D code can be compiled to Javascript using
13 | a combination of existing tools.
14 |
15 | Demo
16 | ====
17 |
18 | You can try an online demo here: http://code.alaiwan.org/dscripten/full.html
19 |
20 | Usage
21 | -----
22 |
23 | * Fetch and build the toolchains
24 |
25 | ```
26 | $ ./fetch_toolchain
27 | ```
28 |
29 | This will take some time, as it will build LLVM-fastcomp and a patched ldc2.
30 | The result will be in the /tmp/toolchains directory.
31 | Alternatively, it's possible to specify another installation prefix using
32 | the 'PREFIX' environment variable.
33 |
34 | It's also possible to specify another temporary directory using the 'tmpDir'
35 | environment variable. Using a tmpfs (in-RAM directory) is recommended, as it
36 | greatly speeds up the build.
37 |
38 | * Add some directories to your PATH
39 |
40 | First, add the JSBackend LLVM toolchain. This one provides ldc2, clang, llc.
41 | ```
42 | $ export PATH=/tmp/toolchains/llvm-js/bin:$PATH
43 | ```
44 |
45 | Then, add Emscripten itself, i.e the python 'emcc' tool family. This relies on the JSBackend LLVM toolchain.
46 | ```
47 | $ export PATH=/tmp/toolchains/emscripten:$PATH
48 | ```
49 |
50 | * Check your PATH:
51 |
52 | Here's what you should get:
53 |
54 | ```
55 | $ which -a llvm-config
56 | /tmp/toolchains/llvm-js/bin/llvm-config
57 | ```
58 |
59 | If you have more than one llvm-config appearing in this list, you're asking
60 | for trouble and the build might not work.
61 |
62 | * Now configure emscripten.
63 | This will create a '.emscripten' configuration file in your home,
64 | containing the path to LLVM 3.9svn (aka 'fastcomp', which implements the JSBackend).
65 | "emcc" will use this path to find its Javascript-enabled clang and llc.
66 |
67 | ```
68 | rm -f ~/.emscripten
69 | EMMAKEN_JUST_CONFIGURE=1 PATH=/tmp/toolchains/llvm-js/bin:$PATH /tmp/toolchains/emscripten/emcc
70 | ```
71 |
72 | * Run the build script (it just sets some variables before calling the makefile)
73 |
74 | ```
75 | $ ./build_asmjs
76 | ```
77 |
78 | (If it fails, try removing ~/.emscripten, or setting EM_CONFIG to anything else)
79 |
80 | * Enjoy the result:
81 |
82 | ```
83 | $ firefox bin/asmjs/game.html
84 | ```
85 |
86 | * You can also play the native version:
87 |
88 | ```
89 | $ ./build_native
90 | $ ./bin/native/game.exe
91 | ```
92 |
93 | License
94 | =======
95 |
96 | * The build scripts and demo game source files are licensed under the GNU Affero GPL.
97 | In short: you're free to run them for whatever purpose, but if you put them
98 | on a server and provide them as a service, you must ensure your users have
99 | access to the source code, under the same license.
100 |
101 | * Everything under the '/rt' directory is licensed under the permissive Boost
102 | software license.
103 | Indeed, some parts of 'rt' get integrated to the produced asm.js binaries,
104 | for which I don't want to impose any restriction.
105 |
106 |
--------------------------------------------------------------------------------
/build_asmjs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | export BIN="bin/asmjs"
6 | export EXT="html"
7 | export LINK="emcc"
8 | TARGET="asmjs-unknown-emscripten"
9 | export CFLAGS="--target=$TARGET -S "
10 | export DFLAGS="-Iapi/ems -mtriple=$TARGET "
11 | export LDFLAGS="-s WASM=0"
12 |
13 | make -j`nproc` "DFLAGS=$DFLAGS" "$@"
14 |
15 |
--------------------------------------------------------------------------------
/build_native:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 |
4 | export LINK="clang"
5 | export BIN="bin/native"
6 | export PKG_CONFIG_LIBDIR="$PWD/api/native"
7 |
8 | make -j`nproc` DFLAGS="-Iapi/native " CFLAGS="-g3 " LDFLAGS="-g " "$@"
9 |
10 |
--------------------------------------------------------------------------------
/check:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -euo pipefail
3 |
4 | echo "*********"
5 | echo "asmjs"
6 | ./build_asmjs >/dev/null
7 | nodejs ./bin/asmjs/tests.js
8 | echo ""
9 |
10 | echo "*********"
11 | echo "native"
12 | ./build_native >/dev/null
13 | ./bin/native/tests.exe
14 | echo ""
15 |
--------------------------------------------------------------------------------
/fetch_toolchain:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # This script downloads, builds and deploys a D-to-LLVM-to-ASMJS toolchain.
4 | # Usage:
5 | # $ ./fetch_toolchain
6 | # A painfully long time after, you've got a full toolchain in '/tmp/toolchains/'
7 |
8 | set -euo pipefail
9 |
10 | readonly PREFIX=${PREFIX:-/tmp/toolchains}
11 | readonly tmpDir=${tmpDir:-/tmp/dscripten-tmp}
12 |
13 | echo "Using prefix: $PREFIX"
14 | echo "Using tmpDir: $tmpDir"
15 |
16 | readonly PREFIX_JS=$PREFIX/llvm-js
17 | readonly PREFIX_EMS=$PREFIX/emscripten
18 | readonly scriptDir=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
19 |
20 | readonly MAKE=(make -j"$(nproc)")
21 |
22 | function main
23 | {
24 | mkdir -p "$tmpDir"
25 |
26 | ensureTool make
27 | ensureTool cmake
28 | ensureTool pkg-config
29 | ensureTool patch
30 | ensureTool git
31 | ensureTool dmd # ldc requires this
32 |
33 | buildEmscripten
34 | buildLdc
35 |
36 | configureEmcc
37 |
38 | PATH="$PREFIX_EMS:$PATH" \
39 | buildExtraLibs
40 |
41 | echo ""
42 | echo "================================================================"
43 | echo "Success. Your asmjs toolchain is now ready."
44 | }
45 |
46 | function ensureTool
47 | {
48 | local progName=$1
49 | echo -n "Checking for $progName ... "
50 | if ! which $progName 1>/dev/null 2>/dev/null; then
51 | echo "Can't find '$progName' in PATH. Aborting."
52 | return 1
53 | fi
54 | echo "OK"
55 | }
56 |
57 | function configureEmcc
58 | {
59 | # will create $HOME/.emscripten
60 | PATH=$PREFIX_JS/bin:$PATH \
61 | "$PREFIX_EMS"/emcc --version
62 | }
63 |
64 | function buildExtraLibs
65 | {
66 | # This causes the emscripten ports to be built
67 | echo "int main() { return 0; }" > $tmpDir/simple.cpp
68 | emcc $tmpDir/simple.cpp \
69 | -s USE_SDL=2\
70 | -s USE_OGG=1\
71 | -s USE_VORBIS=1\
72 | -s USE_SDL_IMAGE=2\
73 | -o $tmpDir/simple.html
74 |
75 | echo "All extra libs OK"
76 | }
77 |
78 | # Here, we build and install:
79 | # - ldc D2 compiler (requires LLVM >= 3.5)
80 | function buildLdc
81 | {
82 | if [ ! -d "$tmpDir"/ldc ] ; then
83 | echo "Cloning LDC ..."
84 | git clone -b master --single-branch --recursive https://github.com/ldc-developers/ldc.git "$tmpDir"/ldc
85 | gitCheckout "$tmpDir/ldc" '187d8198e63564c633f22f2ef4db2a31a8a600ce'
86 | runFrom "$tmpDir"/ldc git submodule init
87 | runFrom "$tmpDir"/ldc git submodule update
88 | patch --merge -d "$tmpDir"/ldc -p1 -i "$scriptDir"/ldc.patch
89 | fi
90 |
91 | mkdir -p "$tmpDir"/bin/ldc
92 | runFrom "$tmpDir"/bin/ldc cmake \
93 | -G "Unix Makefiles" \
94 | -D "CMAKE_INSTALL_PREFIX=$PREFIX_JS" \
95 | -D "LDC_DYNAMIC_COMPILE=OFF" \
96 | -D "LLVM_CONFIG=$PREFIX_JS/bin/llvm-config" \
97 | ../../ldc
98 | runFrom "$tmpDir"/bin/ldc "${MAKE[@]}" -k || true
99 | runFrom "$tmpDir"/bin/ldc make -j2 # retry with less parallelism (workaround potential memory limitations)
100 | runFrom "$tmpDir"/bin/ldc "${MAKE[@]}" install
101 | }
102 |
103 | # Here, we build and install:
104 | # - 'fastcomp' LLVM
105 | # - 'fastcomp' clang frontend (which requires 'fastcomp' LLVM)
106 | # - emscripten (python wrapper scripts + header files + pkg-config files)
107 | function buildEmscripten
108 | {
109 | # emcc and other python wrappers
110 | if [ ! -d "$PREFIX_EMS" ] ; then
111 | echo "Cloning emscripten ..."
112 | git clone -q --depth=1000 -b incoming --single-branch https://github.com/kripken/emscripten.git "$PREFIX_EMS"
113 | gitCheckout "$PREFIX_EMS" '1.38.26'
114 |
115 | # fake pkg-config files to keep happy the build systems of user projects, which don't know about emscripten
116 | cp "$PREFIX_EMS"/system/lib/pkgconfig/sdl.pc "$PREFIX_EMS"/system/lib/pkgconfig/SDL_image.pc
117 | cp "$PREFIX_EMS"/system/lib/pkgconfig/sdl.pc "$PREFIX_EMS"/system/lib/pkgconfig/SDL_gfx.pc
118 |
119 | generateGlPc > "$PREFIX_EMS"/system/lib/pkgconfig/gl.pc
120 | generateSdl2Pc > "$PREFIX_EMS"/system/lib/pkgconfig/sdl2.pc
121 | generateSdl2ImagePc > "$PREFIX_EMS"/system/lib/pkgconfig/SDL2_image.pc
122 | generateOggPc > "$PREFIX_EMS"/system/lib/pkgconfig/ogg.pc
123 | generateVorbisfilePc > "$PREFIX_EMS"/system/lib/pkgconfig/vorbisfile.pc
124 | fi
125 |
126 | # the asmjs backend
127 | if [ ! -d "$tmpDir"/emscripten-llvm ] ; then
128 | echo "Cloning emscripten-fastcomp ..."
129 | git clone -q --depth=100 -b incoming --single-branch https://github.com/kripken/emscripten-fastcomp.git "$tmpDir"/emscripten-llvm
130 | gitCheckout "$tmpDir"/emscripten-llvm '1.38.26'
131 | fi
132 |
133 | # forked clang front-end
134 | if [ ! -d "$tmpDir"/emscripten-llvm/tools/clang ] ; then
135 | echo "Cloning emscripten-fastcomp-clang ..."
136 | git clone -q --depth=100 -b incoming --single-branch https://github.com/kripken/emscripten-fastcomp-clang.git "$tmpDir"/emscripten-llvm/tools/clang
137 | gitCheckout "$tmpDir"/emscripten-llvm/tools/clang '1.38.26'
138 | fi
139 |
140 | mkdir -p "$tmpDir"/bin/emscripten-llvm
141 |
142 | runFrom "$tmpDir"/bin/emscripten-llvm cmake \
143 | -G "Unix Makefiles" \
144 | -D "CMAKE_INSTALL_PREFIX=$PREFIX_JS" \
145 | -D "CMAKE_BUILD_TYPE=Release" \
146 | -D "LLVM_BUILD_GLOBAL_ISEL=off" \
147 | -D "LLVM_TARGETS_TO_BUILD=host;JSBackend" \
148 | -D "LLVM_ENABLE_ASSERTIONS=off" \
149 | -D "LLVM_ENABLE_BACKTRACES=off" \
150 | -D "LLVM_ENABLE_WARNINGS=off" \
151 | -D "LLVM_INCLUDE_EXAMPLES=off" \
152 | -D "LLVM_INCLUDE_DOCS=off" \
153 | -D "CLANG_ENABLE_STATIC_ANALYZER=off" \
154 | -D "CLANG_ENABLE_ARCMT=off" \
155 | ../../emscripten-llvm
156 |
157 | runFrom "$tmpDir"/bin/emscripten-llvm "${MAKE[@]}" -k || true
158 | runFrom "$tmpDir"/bin/emscripten-llvm make -j2 # retry with less parallelism (workaround potential memory limitations)
159 | runFrom "$tmpDir"/bin/emscripten-llvm "${MAKE[@]}" install
160 | }
161 |
162 | function generateGlPc
163 | {
164 | echo "Name: gl"
165 | echo "Description: gl"
166 | echo "Version: 2.0.0"
167 | echo "Cflags: "
168 | echo "Libs: -lGL"
169 | }
170 |
171 | function generateSdl2Pc
172 | {
173 | echo "Name: sdl2"
174 | echo "Description: SDL2"
175 | echo "Version: 2.0.0"
176 | echo "Cflags: -s USE_SDL=2"
177 | echo "Libs: -s USE_SDL=2"
178 | }
179 |
180 | function generateOggPc
181 | {
182 | echo "Name: ogg"
183 | echo "Description: OGG"
184 | echo "Version: 2.0.0"
185 | echo "Cflags: -s USE_OGG=1"
186 | echo "Libs: -s USE_OGG=1"
187 | }
188 |
189 | function generateVorbisfilePc
190 | {
191 | echo "Name: vorbisfile"
192 | echo "Description: VorbisFile"
193 | echo "Version: 2.0.0"
194 | echo "Cflags: -s USE_VORBIS=1"
195 | echo "Libs: -s USE_VORBIS=1"
196 | }
197 |
198 | function generateSdl2ImagePc
199 | {
200 | echo "Name: SDL2_image"
201 | echo "Description: SDL2_image"
202 | echo "Version: 2.0.0"
203 | echo "Cflags: -s USE_SDL_IMAGE=2"
204 | echo "Libs: -s USE_SDL_IMAGE=2"
205 | }
206 |
207 | function gitCheckout
208 | {
209 | local dir=$1
210 | local commit=$2
211 |
212 | runFrom "$dir" git fetch --depth 100
213 | runFrom "$dir" git checkout -q "$commit"
214 | echo "[$dir] at $commit"
215 | }
216 |
217 | function runFrom
218 | {
219 | local readonly dir=$1
220 | shift
221 | (
222 | cd "$dir"
223 | "$@"
224 | )
225 | }
226 |
227 | main "$@"
228 |
229 |
--------------------------------------------------------------------------------
/ldc.patch:
--------------------------------------------------------------------------------
1 | diff --git a/CMakeLists.txt b/CMakeLists.txt
2 | index 1bf26399..fbf1b18d 100644
3 | --- a/CMakeLists.txt
4 | +++ b/CMakeLists.txt
5 | @@ -881,7 +881,7 @@ add_subdirectory(utils)
6 | #
7 | # Auxiliary tools.
8 | #
9 | -add_subdirectory(tools)
10 | +#add_subdirectory(tools)
11 |
12 | #
13 | # Test and runtime targets. Note that enable_testing() is order-sensitive!
14 | @@ -946,7 +946,7 @@ if(MSVC)
15 | install(DIRECTORY vcbuild/ DESTINATION ${CMAKE_INSTALL_PREFIX}/bin FILES_MATCHING PATTERN "*.bat")
16 | endif()
17 |
18 | -if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
19 | +if(${CMAKE_SYSTEM_NAME} MATCHES "Don't install completion: installation is flaky and we don't use this anyway")
20 | if(NOT DEFINED BASH_COMPLETION_COMPLETIONSDIR)
21 | find_package(bash-completion QUIET)
22 | if((NOT BASH_COMPLETION_FOUND) OR (NOT BASH_COMPLETION_PREFIX STREQUAL CMAKE_INSTALL_PREFIX))
23 | diff --git a/driver/main.cpp b/driver/main.cpp
24 | index 459ed019..63446a5b 100644
25 | --- a/driver/main.cpp
26 | +++ b/driver/main.cpp
27 | @@ -125,7 +125,7 @@ void printVersion(llvm::raw_ostream &OS) {
28 | OS.flush();
29 |
30 | llvm::TargetRegistry::printRegisteredTargetsForVersion(
31 | -#if LDC_LLVM_VER >= 600
32 | +#if LDC_LLVM_VER >= 600 || 1
33 | OS
34 | #endif
35 | );
36 | @@ -333,7 +333,7 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles,
37 | // finalize by expanding response files specified in config file
38 | expandResponseFiles(allocator, allArguments);
39 |
40 | -#if LDC_LLVM_VER >= 600
41 | +#if LDC_LLVM_VER >= 600 || 1
42 | cl::SetVersionPrinter(&printVersion);
43 | #else
44 | cl::SetVersionPrinter(&printVersionStdout);
45 | @@ -757,6 +757,8 @@ void registerPredefinedTargetVersions() {
46 | VersionCondition::addPredefinedGlobalIdent("NVPTX");
47 | VersionCondition::addPredefinedGlobalIdent("D_HardFloat");
48 | break;
49 | + case llvm::Triple::asmjs:
50 | + break;
51 | case llvm::Triple::nvptx64:
52 | VersionCondition::addPredefinedGlobalIdent("NVPTX64");
53 | VersionCondition::addPredefinedGlobalIdent("D_HardFloat");
54 | @@ -874,6 +876,8 @@ void registerPredefinedTargetVersions() {
55 | VersionCondition::addPredefinedGlobalIdent("NetBSD");
56 | VersionCondition::addPredefinedGlobalIdent("Posix");
57 | break;
58 | + case llvm::Triple::Emscripten:
59 | + break;
60 | case llvm::Triple::OpenBSD:
61 | VersionCondition::addPredefinedGlobalIdent("OpenBSD");
62 | VersionCondition::addPredefinedGlobalIdent("Posix");
63 |
--------------------------------------------------------------------------------
/rt/mainloop.c:
--------------------------------------------------------------------------------
1 | // Copyright: Sebastien Alaiwan 2018
2 |
3 | // Boost Software License - Version 1.0 - August 17th, 2003
4 | //
5 | // Permission is hereby granted, free of charge, to any person or organization
6 | // obtaining a copy of the software and accompanying documentation covered by
7 | // this license (the "Software") to use, reproduce, display, distribute,
8 | // execute, and transmit the Software, and to prepare derivative works of the
9 | // Software, and to permit third-parties to whom the Software is furnished to
10 | // do so, all subject to the following:
11 | //
12 | // The copyright notices in the Software and this entire statement, including
13 | // the above license grant, this restriction and the following disclaimer,
14 | // must be included in all copies of the Software, in whole or in part, and
15 | // all derivative works of the Software, unless such copies or derivative
16 | // works are solely in the form of machine-executable object code generated by
17 | // a source language processor.
18 | //
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | // DEALINGS IN THE SOFTWARE.
26 |
27 | void startup();
28 | void mainLoop();
29 |
30 | static int mustQuit;
31 |
32 | #ifdef __EMSCRIPTEN__
33 |
34 | void emscripten_set_main_loop(void (*function)(), int fps, int simulate_infinite_loop);
35 |
36 | int main()
37 | {
38 | startup();
39 | emscripten_set_main_loop(&mainLoop, 60, 1);
40 | return 0;
41 | }
42 |
43 | #else
44 |
45 | void SDL_Delay(int);
46 |
47 | int main()
48 | {
49 | startup();
50 |
51 | while(!mustQuit)
52 | {
53 | mainLoop();
54 | SDL_Delay(16);
55 | }
56 | return 0;
57 | }
58 |
59 | #endif
60 |
61 | void quit()
62 | {
63 | mustQuit = 1;
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/rt/object.d:
--------------------------------------------------------------------------------
1 | // Copyright: Digital Mars 2000 - 2011.
2 | // Copyright: Sebastien Alaiwan 2017
3 |
4 | // Boost Software License - Version 1.0 - August 17th, 2003
5 | //
6 | // Permission is hereby granted, free of charge, to any person or organization
7 | // obtaining a copy of the software and accompanying documentation covered by
8 | // this license (the "Software") to use, reproduce, display, distribute,
9 | // execute, and transmit the Software, and to prepare derivative works of the
10 | // Software, and to permit third-parties to whom the Software is furnished to
11 | // do so, all subject to the following:
12 | //
13 | // The copyright notices in the Software and this entire statement, including
14 | // the above license grant, this restriction and the following disclaimer,
15 | // must be included in all copies of the Software, in whole or in part, and
16 | // all derivative works of the Software, unless such copies or derivative
17 | // works are solely in the form of machine-executable object code generated by
18 | // a source language processor.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 | // DEALINGS IN THE SOFTWARE.
27 |
28 | // minimalistic D runtime
29 | // stripped-down version of the official one
30 | module object;
31 |
32 | pragma(LDC_no_moduleinfo);
33 |
34 | private
35 | {
36 | extern (C) void not_implemented(const char* file=__FILE__.ptr, int line=__LINE__) pure @nogc @safe nothrow;
37 | extern(C) int strlen(const char*) nothrow pure;
38 | extern(C) void* malloc(size_t) nothrow pure;
39 | extern(C) void memset(void*, long, size_t) nothrow pure;
40 | }
41 |
42 | version(D_LP64)
43 | {
44 | alias ulong size_t;
45 | alias long ptrdiff_t;
46 | }
47 | else
48 | {
49 | alias uint size_t;
50 | alias int ptrdiff_t;
51 | }
52 |
53 | alias immutable(char)[] string;
54 | alias immutable(wchar)[] wstring;
55 | alias immutable(dchar)[] dstring;
56 |
57 | class Object
58 | {
59 | string toString()
60 | {
61 | not_implemented();
62 | return "";
63 | }
64 |
65 | size_t toHash() @trusted nothrow
66 | {
67 | not_implemented();
68 | return 0;
69 | }
70 |
71 | int opCmp(Object o)
72 | {
73 | not_implemented();
74 | return 0;
75 | }
76 |
77 | bool opEquals(Object o)
78 | {
79 | not_implemented();
80 | return 0;
81 | }
82 |
83 | static Object factory(string classname)
84 | {
85 | not_implemented();
86 | return null;
87 | }
88 | }
89 |
90 | bool _xopEquals(in void*, in void*)
91 | {
92 | throw new Error("TypeInfo.equals is not implemented");
93 | }
94 |
95 | /**
96 | * Information about an interface.
97 | * When an object is accessed via an interface, an Interface* appears as the
98 | * first entry in its vtbl.
99 | */
100 | struct Interface
101 | {
102 | TypeInfo_Class classinfo; /// .classinfo for this interface (not for containing class)
103 | void*[] vtbl;
104 | size_t offset; /// offset to Interface 'this' from Object 'this'
105 | }
106 |
107 | /**
108 | * Array of pairs giving the offset and type information for each
109 | * member in an aggregate.
110 | */
111 | struct OffsetTypeInfo
112 | {
113 | size_t offset; /// Offset of member from start of object
114 | TypeInfo ti; /// TypeInfo for this member
115 | }
116 |
117 | /**
118 | * Runtime type information about a type.
119 | * Can be retrieved for any type using a
120 | * $(GLINK2 expression,TypeidExpression, TypeidExpression).
121 | */
122 | class TypeInfo
123 | {
124 | override string toString() const pure @safe nothrow
125 | {
126 | not_implemented();
127 | return "";
128 | }
129 |
130 | override size_t toHash() @trusted const
131 | {
132 | not_implemented();
133 | return 0;
134 | }
135 |
136 | override int opCmp(Object o)
137 | {
138 | not_implemented();
139 | return 0;
140 | }
141 |
142 | override bool opEquals(Object o)
143 | {
144 | not_implemented();
145 | return 0;
146 | }
147 |
148 | /// Returns a hash of the instance of a type.
149 | size_t getHash(in void* p) @trusted nothrow const
150 | {
151 | not_implemented();
152 | return 0;
153 | }
154 |
155 | /// Compares two instances for equality.
156 | bool equals(in void* p1, in void* p2) const { return p1 == p2; }
157 |
158 | /// Compares two instances for <, ==, or >.
159 | int compare(in void* p1, in void* p2) const { not_implemented(); return 0;}
160 |
161 | /// Returns size of the type.
162 | @property size_t tsize() nothrow pure const @safe @nogc { return 0; }
163 |
164 | /// Swaps two instances of the type.
165 | void swap(void* p1, void* p2) const
166 | {
167 | size_t n = tsize;
168 | for (size_t i = 0; i < n; i++)
169 | {
170 | byte t = (cast(byte *)p1)[i];
171 | (cast(byte*)p1)[i] = (cast(byte*)p2)[i];
172 | (cast(byte*)p2)[i] = t;
173 | }
174 | }
175 |
176 | /// Get TypeInfo for 'next' type, as defined by what kind of type this is,
177 | /// null if none.
178 | @property inout(TypeInfo) next() nothrow pure inout @nogc { return null; }
179 |
180 | /// Return default initializer. If the type should be initialized to all zeros,
181 | /// an array with a null ptr and a length equal to the type size will be returned.
182 | version(LDC)
183 | {
184 | // LDC uses TypeInfo's vtable for the typeof(null) type:
185 | // %"typeid(typeof(null))" = type { %object.TypeInfo.__vtbl*, i8* }
186 | // Therefore this class cannot be abstract, and all methods need implementations.
187 | // Tested by test14754() in runnable/inline.d, and a unittest below.
188 | const(void)[] initializer() nothrow pure const @safe @nogc { return null; }
189 | }
190 | else
191 | {
192 | abstract const(void)[] initializer() nothrow pure const @safe @nogc;
193 | }
194 |
195 | /// $(RED Scheduled for deprecation.) Please use `initializer` instead.
196 | alias init = initializer; // added in 2.070, to stay in 2.071
197 | version(none) deprecated alias init = initializer; // planned for 2.072
198 | version(none) @disable static const(void)[] init(); // planned for 2.073
199 | /* Planned for 2.074: Remove init, making way for the init type property,
200 | fixing issue 12233. */
201 |
202 | /// Get flags for type: 1 means GC should scan for pointers,
203 | /// 2 means arg of this type is passed in XMM register
204 | @property uint flags() nothrow pure const @safe @nogc { return 0; }
205 |
206 | /// Get type information on the contents of the type; null if not available
207 | const(OffsetTypeInfo)[] offTi() const { return null; }
208 | /// Run the destructor on the object and all its sub-objects
209 | void destroy(void* p) const {}
210 | /// Run the postblit on the object and all its sub-objects
211 | void postblit(void* p) const {}
212 |
213 |
214 | /// Return alignment of type
215 | @property size_t talign() nothrow pure const @safe @nogc { return tsize; }
216 |
217 | /** Return internal info on arguments fitting into 8byte.
218 | * See X86-64 ABI 3.2.3
219 | */
220 | version (X86_64) int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow
221 | {
222 | arg1 = this;
223 | return 0;
224 | }
225 |
226 | /** Return info used by the garbage collector to do precise collection.
227 | */
228 | @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return null; }
229 | }
230 |
231 | class TypeInfo_Typedef : TypeInfo
232 | {
233 | override string toString() const { return name; }
234 |
235 | override bool opEquals(Object o)
236 | {
237 | not_implemented();
238 | return 0;
239 | }
240 |
241 | override size_t getHash(in void* p) const { return base.getHash(p); }
242 | override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
243 | override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
244 | override @property size_t tsize() nothrow pure const { return base.tsize; }
245 | override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }
246 |
247 | override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
248 | override @property uint flags() nothrow pure const { return base.flags; }
249 |
250 | override const(void)[] initializer() const
251 | {
252 | return m_init.length ? m_init : base.initializer();
253 | }
254 |
255 | override @property size_t talign() nothrow pure const { return base.talign; }
256 |
257 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
258 | {
259 | return base.argTypes(arg1, arg2);
260 | }
261 |
262 | override @property immutable(void)* rtInfo() const { return base.rtInfo; }
263 |
264 | TypeInfo base;
265 | string name;
266 | void[] m_init;
267 | }
268 |
269 | class TypeInfo_Enum : TypeInfo_Typedef
270 | {
271 |
272 | }
273 |
274 | // Please make sure to keep this in sync with TypeInfo_P (src/rt/typeinfo/ti_ptr.d)
275 | class TypeInfo_Pointer : TypeInfo
276 | {
277 | override string toString() const
278 | {
279 | not_implemented();
280 | return "";
281 | }
282 |
283 | override bool opEquals(Object o)
284 | {
285 | not_implemented();
286 | return 0;
287 | }
288 |
289 | override size_t getHash(in void* p) @trusted const
290 | {
291 | not_implemented();
292 | return 0;
293 | }
294 |
295 | override bool equals(in void* p1, in void* p2) const
296 | {
297 | not_implemented();
298 | return 0;
299 | }
300 |
301 | override int compare(in void* p1, in void* p2) const
302 | {
303 | not_implemented();
304 | return 0;
305 | }
306 |
307 | override @property size_t tsize() nothrow pure const
308 | {
309 | not_implemented();
310 | return 0;
311 | }
312 |
313 | override const(void)[] initializer() const @trusted
314 | {
315 | not_implemented();
316 | return [];
317 | }
318 |
319 | override void swap(void* p1, void* p2) const
320 | {
321 | not_implemented();
322 | }
323 |
324 | override @property inout(TypeInfo) next() nothrow pure inout { return m_next; }
325 | override @property uint flags() nothrow pure const { return 1; }
326 |
327 | TypeInfo m_next;
328 | }
329 |
330 | class TypeInfo_Array : TypeInfo
331 | {
332 | override string toString() const
333 | {
334 | not_implemented();
335 | return "";
336 | }
337 |
338 | override bool opEquals(Object o)
339 | {
340 | not_implemented();
341 | return 0;
342 | }
343 |
344 | override bool equals(in void* p1, in void* p2) const
345 | {
346 | not_implemented();
347 | return 0;
348 | }
349 |
350 | override int compare(in void* p1, in void* p2) const
351 | {
352 | not_implemented();
353 | return 0;
354 | }
355 |
356 | override @property size_t tsize() nothrow pure const
357 | {
358 | return (void[]).sizeof;
359 | }
360 |
361 | override const(void)[] initializer() const @trusted
362 | {
363 | return (cast(void *)null)[0 .. (void[]).sizeof];
364 | }
365 |
366 | override void swap(void* p1, void* p2) const
367 | {
368 | not_implemented();
369 | }
370 |
371 | TypeInfo value;
372 |
373 | override @property inout(TypeInfo) next() nothrow pure inout
374 | {
375 | return value;
376 | }
377 |
378 | override @property uint flags() nothrow pure const { return 1; }
379 |
380 | override @property size_t talign() nothrow pure const
381 | {
382 | return (void[]).alignof;
383 | }
384 |
385 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
386 | {
387 | not_implemented();
388 | return 0;
389 | }
390 | }
391 |
392 | class TypeInfo_StaticArray : TypeInfo
393 | {
394 | override string toString() const
395 | {
396 | not_implemented();
397 | return "";
398 | }
399 |
400 | override bool opEquals(Object o)
401 | {
402 | not_implemented();
403 | return 0;
404 | }
405 |
406 | override bool equals(in void* p1, in void* p2) const
407 | {
408 | not_implemented();
409 | return 0;
410 | }
411 |
412 | override int compare(in void* p1, in void* p2) const
413 | {
414 | not_implemented();
415 | return 0;
416 | }
417 |
418 | override @property size_t tsize() nothrow pure const
419 | {
420 | return len * value.tsize;
421 | }
422 |
423 | override void swap(void* p1, void* p2) const
424 | {
425 | not_implemented();
426 | }
427 |
428 | override const(void)[] initializer() nothrow pure const
429 | {
430 | return value.initializer();
431 | }
432 |
433 | override @property inout(TypeInfo) next() nothrow pure inout { return value; }
434 | override @property uint flags() nothrow pure const { return value.flags; }
435 |
436 | override void destroy(void* p) const
437 | {
438 | auto sz = value.tsize;
439 | p += sz * len;
440 | foreach (i; 0 .. len)
441 | {
442 | p -= sz;
443 | value.destroy(p);
444 | }
445 | }
446 |
447 | override void postblit(void* p) const
448 | {
449 | auto sz = value.tsize;
450 | foreach (i; 0 .. len)
451 | {
452 | value.postblit(p);
453 | p += sz;
454 | }
455 | }
456 |
457 | TypeInfo value;
458 | size_t len;
459 |
460 | override @property size_t talign() nothrow pure const
461 | {
462 | return value.talign;
463 | }
464 |
465 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
466 | {
467 | not_implemented();
468 | return 0;
469 | }
470 | }
471 |
472 | class TypeInfo_AssociativeArray : TypeInfo
473 | {
474 | override string toString() const
475 | {
476 | not_implemented();
477 | return "";
478 | }
479 |
480 | override bool opEquals(Object o)
481 | {
482 | not_implemented();
483 | return 0;
484 | }
485 |
486 | // BUG: need to add the rest of the functions
487 |
488 | override @property size_t tsize() nothrow pure const
489 | {
490 | return (char[int]).sizeof;
491 | }
492 |
493 | override const(void)[] initializer() const @trusted
494 | {
495 | return (cast(void *)null)[0 .. (char[int]).sizeof];
496 | }
497 |
498 | override @property inout(TypeInfo) next() nothrow pure inout { return value; }
499 | override @property uint flags() nothrow pure const { return 1; }
500 |
501 | TypeInfo value;
502 | TypeInfo key;
503 |
504 | override @property size_t talign() nothrow pure const
505 | {
506 | return (char[int]).alignof;
507 | }
508 |
509 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
510 | {
511 | not_implemented();
512 | return 0;
513 | }
514 | }
515 |
516 | class TypeInfo_Vector : TypeInfo
517 | {
518 | override string toString() const
519 | {
520 | not_implemented();
521 | return "";
522 | }
523 |
524 | override bool opEquals(Object o)
525 | {
526 | not_implemented();
527 | return 0;
528 | }
529 |
530 | override size_t getHash(in void* p) const { return base.getHash(p); }
531 | override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
532 | override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
533 | override @property size_t tsize() nothrow pure const { return base.tsize; }
534 | override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }
535 |
536 | override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
537 | override @property uint flags() nothrow pure const { return base.flags; }
538 |
539 | override const(void)[] initializer() nothrow pure const
540 | {
541 | return base.initializer();
542 | }
543 |
544 | override @property size_t talign() nothrow pure const { return 16; }
545 |
546 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
547 | {
548 | return base.argTypes(arg1, arg2);
549 | }
550 |
551 | TypeInfo base;
552 | }
553 |
554 | class TypeInfo_Function : TypeInfo
555 | {
556 | override string toString() const
557 | {
558 | not_implemented(); return "";
559 | }
560 |
561 | override bool opEquals(Object o)
562 | {
563 | not_implemented(); return 0;
564 | }
565 |
566 | override @property size_t tsize() nothrow pure const
567 | {
568 | return 0; // no size for functions
569 | }
570 |
571 | override const(void)[] initializer() const @safe
572 | {
573 | return null;
574 | }
575 |
576 | TypeInfo next;
577 | string deco;
578 | }
579 |
580 | class TypeInfo_Delegate : TypeInfo
581 | {
582 | override string toString() const
583 | {
584 | not_implemented();
585 | return "";
586 | }
587 |
588 | override bool opEquals(Object o)
589 | {
590 | not_implemented();
591 | return 0;
592 | }
593 |
594 | override bool equals(in void* p1, in void* p2) const
595 | {
596 | not_implemented();
597 | return 0;
598 | }
599 |
600 | override int compare(in void* p1, in void* p2) const
601 | {
602 | not_implemented();
603 | return 0;
604 | }
605 |
606 | override @property size_t tsize() nothrow pure const
607 | {
608 | not_implemented();
609 | return 0;
610 | }
611 |
612 | override const(void)[] initializer() const @trusted
613 | {
614 | not_implemented();
615 | return [];
616 | }
617 |
618 | override @property uint flags() nothrow pure const { return 1; }
619 |
620 | TypeInfo next;
621 | string deco;
622 |
623 | override @property size_t talign() nothrow pure const
624 | {
625 | not_implemented();
626 | return 0;
627 | }
628 |
629 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
630 | {
631 | not_implemented();
632 | return 0;
633 | }
634 | }
635 |
636 | /**
637 | * Runtime type information about a class.
638 | * Can be retrieved from an object instance by using the
639 | * $(DDSUBLINK spec/property,classinfo, .classinfo) property.
640 | */
641 | class TypeInfo_Class : TypeInfo
642 | {
643 | override string toString() const
644 | {
645 | not_implemented();
646 | return "";
647 | }
648 |
649 | override bool opEquals(Object o)
650 | {
651 | not_implemented();
652 | return 0;
653 | }
654 |
655 | override size_t getHash(in void* p) @trusted const
656 | {
657 | not_implemented();
658 | return 0;
659 | }
660 |
661 | override bool equals(in void* p1, in void* p2) const
662 | {
663 | not_implemented();
664 | return 0;
665 | }
666 |
667 | override int compare(in void* p1, in void* p2) const
668 | {
669 | not_implemented();
670 | return 0;
671 | }
672 |
673 | override @property size_t tsize() nothrow pure const
674 | {
675 | not_implemented();
676 | return 0;
677 | }
678 |
679 | override const(void)[] initializer() nothrow pure const @safe
680 | {
681 | return m_init;
682 | }
683 |
684 | override @property uint flags() nothrow pure const { return 1; }
685 |
686 | override @property const(OffsetTypeInfo)[] offTi() nothrow pure const
687 | {
688 | return m_offTi;
689 | }
690 |
691 | @property auto info() @safe nothrow pure const { return this; }
692 | @property auto typeinfo() @safe nothrow pure const { return this; }
693 |
694 | byte[] m_init; /** class static initializer
695 | * (init.length gives size in bytes of class)
696 | */
697 | string name; /// class name
698 | void*[] vtbl; /// virtual function pointer table
699 | Interface[] interfaces; /// interfaces this class implements
700 | TypeInfo_Class base; /// base class
701 | void* destructor;
702 | void function(Object) classInvariant;
703 | enum ClassFlags : uint
704 | {
705 | isCOMclass = 0x1,
706 | noPointers = 0x2,
707 | hasOffTi = 0x4,
708 | hasCtor = 0x8,
709 | hasGetMembers = 0x10,
710 | hasTypeInfo = 0x20,
711 | isAbstract = 0x40,
712 | isCPPclass = 0x80,
713 | hasDtor = 0x100,
714 | }
715 | ClassFlags m_flags;
716 | void* deallocator;
717 | OffsetTypeInfo[] m_offTi;
718 | void function(Object) defaultConstructor; // default Constructor
719 |
720 | immutable(void)* m_RTInfo; // data for precise GC
721 | override @property immutable(void)* rtInfo() const { return m_RTInfo; }
722 |
723 | static const(TypeInfo_Class) find(in char[] classname)
724 | {
725 | not_implemented();
726 | return null;
727 | }
728 |
729 | Object create() const
730 | {
731 | not_implemented();
732 | return null;
733 | }
734 | }
735 |
736 | class TypeInfo_Interface : TypeInfo
737 | {
738 | override string toString() const { return info.name; }
739 |
740 | override bool opEquals(Object o)
741 | {
742 | not_implemented();
743 | return 0;
744 | }
745 |
746 | override size_t getHash(in void* p) @trusted const
747 | {
748 | not_implemented();
749 | return 0;
750 | }
751 |
752 | override bool equals(in void* p1, in void* p2) const
753 | {
754 | not_implemented();
755 | return 0;
756 | }
757 |
758 | override int compare(in void* p1, in void* p2) const
759 | {
760 | not_implemented();
761 | return 0;
762 | }
763 |
764 | override @property size_t tsize() nothrow pure const
765 | {
766 | return Object.sizeof;
767 | }
768 |
769 | override const(void)[] initializer() const @trusted
770 | {
771 | return (cast(void *)null)[0 .. Object.sizeof];
772 | }
773 |
774 | override @property uint flags() nothrow pure const
775 | {
776 | return 1;
777 | }
778 |
779 | TypeInfo_Class info;
780 | }
781 |
782 | class TypeInfo_Struct : TypeInfo
783 | {
784 | override string toString() const { return name; }
785 |
786 | override bool opEquals(Object o)
787 | {
788 | not_implemented();
789 | return 0;
790 | }
791 |
792 | override size_t getHash(in void* p) @safe pure nothrow const
793 | {
794 | not_implemented();
795 | return 0;
796 | }
797 |
798 | override bool equals(in void* p1, in void* p2) @trusted pure nothrow const
799 | {
800 | not_implemented();
801 | return 0;
802 | }
803 |
804 | override int compare(in void* p1, in void* p2) @trusted pure nothrow const
805 | {
806 | not_implemented();
807 | return 0;
808 | }
809 |
810 | override @property size_t tsize() nothrow pure const
811 | {
812 | return initializer().length;
813 | }
814 |
815 | override const(void)[] initializer() nothrow pure const @safe
816 | {
817 | return m_init;
818 | }
819 |
820 | override @property uint flags() nothrow pure const { return m_flags; }
821 |
822 | override @property size_t talign() nothrow pure const { return m_align; }
823 |
824 | final override void destroy(void* p) const
825 | {
826 | if (xdtor)
827 | {
828 | if (m_flags & StructFlags.isDynamicType)
829 | (*xdtorti)(p, this);
830 | else
831 | (*xdtor)(p);
832 | }
833 | }
834 |
835 | override void postblit(void* p) const
836 | {
837 | if (xpostblit)
838 | (*xpostblit)(p);
839 | }
840 |
841 | string name;
842 | void[] m_init; // initializer; m_init.ptr == null if 0 initialize
843 |
844 | @safe pure nothrow
845 | {
846 | size_t function(in void*) xtoHash;
847 | bool function(in void*, in void*) xopEquals;
848 | int function(in void*, in void*) xopCmp;
849 | string function(in void*) xtoString;
850 |
851 | enum StructFlags : uint
852 | {
853 | hasPointers = 0x1,
854 | isDynamicType = 0x2, // built at runtime, needs type info in xdtor
855 | }
856 | StructFlags m_flags;
857 | }
858 | union
859 | {
860 | void function(void*) xdtor;
861 | void function(void*, const TypeInfo_Struct ti) xdtorti;
862 | }
863 | void function(void*) xpostblit;
864 |
865 | uint m_align;
866 |
867 | override @property immutable(void)* rtInfo() const { return m_RTInfo; }
868 |
869 | version (X86_64)
870 | {
871 | override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
872 | {
873 | arg1 = m_arg1;
874 | arg2 = m_arg2;
875 | return 0;
876 | }
877 | TypeInfo m_arg1;
878 | TypeInfo m_arg2;
879 | }
880 | immutable(void)* m_RTInfo; // data for precise GC
881 | }
882 |
883 | /+
884 | class TypeInfo_Tuple : TypeInfo
885 | {
886 | TypeInfo[] elements;
887 |
888 | override string toString() const
889 | {
890 | not_implemented();
891 | return "";
892 | }
893 |
894 | override bool opEquals(Object o)
895 | {
896 | not_implemented(); return 0;
897 | }
898 |
899 | override size_t getHash(in void* p) const
900 | {
901 | not_implemented(); return 0;
902 | }
903 |
904 | override bool equals(in void* p1, in void* p2) const
905 | {
906 | not_implemented(); return 0;
907 | }
908 |
909 | override int compare(in void* p1, in void* p2) const
910 | {
911 | not_implemented(); return 0;
912 | }
913 |
914 | override @property size_t tsize() nothrow pure const
915 | {
916 | not_implemented(); return 0;
917 | }
918 |
919 | override const(void)[] initializer() const @trusted
920 | {
921 | not_implemented(); return [];
922 | }
923 |
924 | override void swap(void* p1, void* p2) const
925 | {
926 | not_implemented();
927 | }
928 |
929 | override void destroy(void* p) const
930 | {
931 | not_implemented();
932 | }
933 |
934 | override void postblit(void* p) const
935 | {
936 | not_implemented();
937 | }
938 |
939 | override @property size_t talign() nothrow pure const
940 | {
941 | not_implemented(); return 0;
942 | }
943 |
944 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
945 | {
946 | not_implemented(); return 0;
947 | }
948 | }
949 |
950 | +/
951 |
952 | // required by the compiler
953 | class TypeInfo_Const : TypeInfo
954 | {
955 | override string toString() const
956 | {
957 | not_implemented(); return "";
958 | }
959 |
960 | //override bool opEquals(Object o) { return base.opEquals(o); }
961 | override bool opEquals(Object o)
962 | {
963 | not_implemented(); return 0;
964 | }
965 |
966 | override size_t getHash(in void *p) const { return base.getHash(p); }
967 | override bool equals(in void *p1, in void *p2) const { return base.equals(p1, p2); }
968 | override int compare(in void *p1, in void *p2) const { return base.compare(p1, p2); }
969 | override @property size_t tsize() nothrow pure const { return base.tsize; }
970 | override void swap(void *p1, void *p2) const { return base.swap(p1, p2); }
971 |
972 | override @property inout(TypeInfo) next() nothrow pure inout { return base.next; }
973 | override @property uint flags() nothrow pure const { return base.flags; }
974 |
975 | override const(void)[] initializer() nothrow pure const
976 | {
977 | return base.initializer();
978 | }
979 |
980 | override @property size_t talign() nothrow pure const { return base.talign; }
981 |
982 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
983 | {
984 | return base.argTypes(arg1, arg2);
985 | }
986 |
987 | TypeInfo base;
988 | }
989 |
990 | /+
991 | class TypeInfo_Invariant : TypeInfo_Const
992 | {
993 | override string toString() const
994 | {
995 | return cast(string) ("immutable(" ~ base.toString() ~ ")");
996 | }
997 | }
998 |
999 | class TypeInfo_Shared : TypeInfo_Const
1000 | {
1001 | override string toString() const
1002 | {
1003 | return cast(string) ("shared(" ~ base.toString() ~ ")");
1004 | }
1005 | }
1006 |
1007 | class TypeInfo_Inout : TypeInfo_Const
1008 | {
1009 | override string toString() const
1010 | {
1011 | return cast(string) ("inout(" ~ base.toString() ~ ")");
1012 | }
1013 | }
1014 |
1015 |
1016 | +/
1017 | ///////////////////////////////////////////////////////////////////////////////
1018 | // ModuleInfo
1019 | ///////////////////////////////////////////////////////////////////////////////
1020 |
1021 |
1022 | enum
1023 | {
1024 | MIctorstart = 0x1, // we've started constructing it
1025 | MIctordone = 0x2, // finished construction
1026 | MIstandalone = 0x4, // module ctor does not depend on other module
1027 | // ctors being done first
1028 | MItlsctor = 8,
1029 | MItlsdtor = 0x10,
1030 | MIctor = 0x20,
1031 | MIdtor = 0x40,
1032 | MIxgetMembers = 0x80,
1033 | MIictor = 0x100,
1034 | MIunitTest = 0x200,
1035 | MIimportedModules = 0x400,
1036 | MIlocalClasses = 0x800,
1037 | MIname = 0x1000,
1038 | }
1039 |
1040 |
1041 | struct ModuleInfo
1042 | {
1043 | uint _flags;
1044 | uint _index; // index into _moduleinfo_array[]
1045 |
1046 | version (all)
1047 | {
1048 | deprecated("ModuleInfo cannot be copy-assigned because it is a variable-sized struct.")
1049 | void opAssign(in ModuleInfo m) { _flags = m._flags; _index = m._index; }
1050 | }
1051 | else
1052 | {
1053 | @disable this();
1054 | }
1055 |
1056 | const:
1057 | private void* addrOf(int flag) nothrow pure
1058 | {
1059 | void* p = cast(void*)&this + ModuleInfo.sizeof;
1060 |
1061 | if (flags & MItlsctor)
1062 | {
1063 | if (flag == MItlsctor) return p;
1064 | p += typeof(tlsctor).sizeof;
1065 | }
1066 | if (flags & MItlsdtor)
1067 | {
1068 | if (flag == MItlsdtor) return p;
1069 | p += typeof(tlsdtor).sizeof;
1070 | }
1071 | if (flags & MIctor)
1072 | {
1073 | if (flag == MIctor) return p;
1074 | p += typeof(ctor).sizeof;
1075 | }
1076 | if (flags & MIdtor)
1077 | {
1078 | if (flag == MIdtor) return p;
1079 | p += typeof(dtor).sizeof;
1080 | }
1081 | if (flags & MIxgetMembers)
1082 | {
1083 | if (flag == MIxgetMembers) return p;
1084 | p += typeof(xgetMembers).sizeof;
1085 | }
1086 | if (flags & MIictor)
1087 | {
1088 | if (flag == MIictor) return p;
1089 | p += typeof(ictor).sizeof;
1090 | }
1091 | if (flags & MIunitTest)
1092 | {
1093 | if (flag == MIunitTest) return p;
1094 | p += typeof(unitTest).sizeof;
1095 | }
1096 | if (flags & MIimportedModules)
1097 | {
1098 | if (flag == MIimportedModules) return p;
1099 | p += size_t.sizeof + *cast(size_t*)p * typeof(importedModules[0]).sizeof;
1100 | }
1101 | if (flags & MIlocalClasses)
1102 | {
1103 | if (flag == MIlocalClasses) return p;
1104 | p += size_t.sizeof + *cast(size_t*)p * typeof(localClasses[0]).sizeof;
1105 | }
1106 | if (true || flags & MIname) // always available for now
1107 | {
1108 | if (flag == MIname) return p;
1109 | p += strlen(cast(immutable char*)p);
1110 | }
1111 | not_implemented(); return null;
1112 | }
1113 |
1114 | @property uint index() nothrow pure { return _index; }
1115 |
1116 | @property uint flags() nothrow pure { return _flags; }
1117 |
1118 | @property void function() tlsctor() nothrow pure
1119 | {
1120 | return flags & MItlsctor ? *cast(typeof(return)*)addrOf(MItlsctor) : null;
1121 | }
1122 |
1123 | @property void function() tlsdtor() nothrow pure
1124 | {
1125 | return flags & MItlsdtor ? *cast(typeof(return)*)addrOf(MItlsdtor) : null;
1126 | }
1127 |
1128 | @property void* xgetMembers() nothrow pure
1129 | {
1130 | return flags & MIxgetMembers ? *cast(typeof(return)*)addrOf(MIxgetMembers) : null;
1131 | }
1132 |
1133 | @property void function() ctor() nothrow pure
1134 | {
1135 | return flags & MIctor ? *cast(typeof(return)*)addrOf(MIctor) : null;
1136 | }
1137 |
1138 | @property void function() dtor() nothrow pure
1139 | {
1140 | return flags & MIdtor ? *cast(typeof(return)*)addrOf(MIdtor) : null;
1141 | }
1142 |
1143 | @property void function() ictor() nothrow pure
1144 | {
1145 | return flags & MIictor ? *cast(typeof(return)*)addrOf(MIictor) : null;
1146 | }
1147 |
1148 | @property void function() unitTest() nothrow pure
1149 | {
1150 | return flags & MIunitTest ? *cast(typeof(return)*)addrOf(MIunitTest) : null;
1151 | }
1152 |
1153 | @property immutable(ModuleInfo*)[] importedModules() nothrow pure
1154 | {
1155 | if (flags & MIimportedModules)
1156 | {
1157 | auto p = cast(size_t*)addrOf(MIimportedModules);
1158 | return (cast(immutable(ModuleInfo*)*)(p + 1))[0 .. *p];
1159 | }
1160 | return null;
1161 | }
1162 |
1163 | @property TypeInfo_Class[] localClasses() nothrow pure
1164 | {
1165 | if (flags & MIlocalClasses)
1166 | {
1167 | auto p = cast(size_t*)addrOf(MIlocalClasses);
1168 | return (cast(TypeInfo_Class*)(p + 1))[0 .. *p];
1169 | }
1170 | return null;
1171 | }
1172 |
1173 | @property string name() nothrow pure
1174 | {
1175 | if (true || flags & MIname) // always available for now
1176 | {
1177 | auto p = cast(immutable char*)addrOf(MIname);
1178 | return p[0 .. strlen(p)];
1179 | }
1180 | // return null;
1181 | }
1182 |
1183 | static int opApply(scope int delegate(ModuleInfo*) dg)
1184 | {
1185 | /*
1186 | import core.internal.traits : externDFunc;
1187 | alias moduleinfos_apply = externDFunc!("rt.minfo.moduleinfos_apply",
1188 | int function(scope int delegate(immutable(ModuleInfo*))));
1189 | // Bugzilla 13084 - enforcing immutable ModuleInfo would break client code
1190 | return moduleinfos_apply(
1191 | (immutable(ModuleInfo*)m) => dg(cast(ModuleInfo*)m));
1192 | */
1193 | not_implemented();
1194 | return 0;
1195 | }
1196 | }
1197 |
1198 | ///////////////////////////////////////////////////////////////////////////////
1199 | // Throwable
1200 | ///////////////////////////////////////////////////////////////////////////////
1201 |
1202 | /**
1203 | * The base class of all thrown objects.
1204 | *
1205 | * All thrown objects must inherit from Throwable. Class $(D Exception), which
1206 | * derives from this class, represents the category of thrown objects that are
1207 | * safe to catch and handle. In principle, one should not catch Throwable
1208 | * objects that are not derived from $(D Exception), as they represent
1209 | * unrecoverable runtime errors. Certain runtime guarantees may fail to hold
1210 | * when these errors are thrown, making it unsafe to continue execution after
1211 | * catching them.
1212 | */
1213 | class Throwable : Object
1214 | {
1215 | interface TraceInfo
1216 | {
1217 | int opApply(scope int delegate(ref const(char[]))) const;
1218 | int opApply(scope int delegate(ref size_t, ref const(char[]))) const;
1219 | string toString() const;
1220 | }
1221 |
1222 | string msg; /// A message describing the error.
1223 |
1224 | /**
1225 | * The _file name and line number of the D source code corresponding with
1226 | * where the error was thrown from.
1227 | */
1228 | string file;
1229 | size_t line; /// ditto
1230 |
1231 | /**
1232 | * The stack trace of where the error happened. This is an opaque object
1233 | * that can either be converted to $(D string), or iterated over with $(D
1234 | * foreach) to extract the items in the stack trace (as strings).
1235 | */
1236 | TraceInfo info;
1237 |
1238 | /**
1239 | * A reference to the _next error in the list. This is used when a new
1240 | * $(D Throwable) is thrown from inside a $(D catch) block. The originally
1241 | * caught $(D Exception) will be chained to the new $(D Throwable) via this
1242 | * field.
1243 | */
1244 | Throwable next;
1245 |
1246 | @nogc @safe pure nothrow this(string msg, Throwable next = null)
1247 | {
1248 | this.msg = msg;
1249 | this.next = next;
1250 | //this.info = _d_traceContext();
1251 | }
1252 |
1253 | @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable next = null)
1254 | {
1255 | this(msg, next);
1256 | this.file = file;
1257 | this.line = line;
1258 | //this.info = _d_traceContext();
1259 | }
1260 |
1261 | /**
1262 | * Overrides $(D Object.toString) and returns the error message.
1263 | * Internally this forwards to the $(D toString) overload that
1264 | * takes a $(PARAM sink) delegate.
1265 | */
1266 | override string toString()
1267 | {
1268 | not_implemented();
1269 | return "";
1270 | }
1271 |
1272 | /**
1273 | * The Throwable hierarchy uses a toString overload that takes a
1274 | * $(PARAM sink) delegate to avoid GC allocations, which cannot be
1275 | * performed in certain error situations. Override this $(D
1276 | * toString) method to customize the error message.
1277 | */
1278 | void toString(scope void delegate(in char[]) sink) const
1279 | {
1280 | not_implemented();
1281 | }
1282 | }
1283 |
1284 | /+
1285 | /**
1286 | * The base class of all errors that are safe to catch and handle.
1287 | *
1288 | * In principle, only thrown objects derived from this class are safe to catch
1289 | * inside a $(D catch) block. Thrown objects not derived from Exception
1290 | * represent runtime errors that should not be caught, as certain runtime
1291 | * guarantees may not hold, making it unsafe to continue program execution.
1292 | */
1293 | class Exception : Throwable
1294 | {
1295 |
1296 | /**
1297 | * Creates a new instance of Exception. The next parameter is used
1298 | * internally and should always be $(D null) when passed by user code.
1299 | * This constructor does not automatically throw the newly-created
1300 | * Exception; the $(D throw) statement should be used for that purpose.
1301 | */
1302 | @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
1303 | {
1304 | super(msg, file, line, next);
1305 | }
1306 |
1307 | @nogc @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__)
1308 | {
1309 | super(msg, file, line, next);
1310 | }
1311 | }
1312 | +/
1313 |
1314 | /**
1315 | * The base class of all unrecoverable runtime errors.
1316 | *
1317 | * This represents the category of $(D Throwable) objects that are $(B not)
1318 | * safe to catch and handle. In principle, one should not catch Error
1319 | * objects, as they represent unrecoverable runtime errors.
1320 | * Certain runtime guarantees may fail to hold when these errors are
1321 | * thrown, making it unsafe to continue execution after catching them.
1322 | */
1323 | class Error : Throwable
1324 | {
1325 | /**
1326 | * Creates a new instance of Error. The next parameter is used
1327 | * internally and should always be $(D null) when passed by user code.
1328 | * This constructor does not automatically throw the newly-created
1329 | * Error; the $(D throw) statement should be used for that purpose.
1330 | */
1331 | @nogc @safe pure nothrow this(string msg, Throwable next = null)
1332 | {
1333 | super(msg, next);
1334 | bypassedException = null;
1335 | }
1336 |
1337 | @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable next = null)
1338 | {
1339 | super(msg, file, line, next);
1340 | bypassedException = null;
1341 | }
1342 |
1343 | /// The first $(D Exception) which was bypassed when this Error was thrown,
1344 | /// or $(D null) if no $(D Exception)s were pending.
1345 | Throwable bypassedException;
1346 | }
1347 |
1348 | void destroy(T)(T obj) if (is(T == class))
1349 | {
1350 | rt_finalize(cast(void*)obj);
1351 | }
1352 |
1353 | void destroy(T)(T obj) if (is(T == interface))
1354 | {
1355 | destroy(cast(Object)obj);
1356 | }
1357 |
1358 | void destroy(T)(ref T obj) if (is(T == struct))
1359 | {
1360 | _destructRecurse(obj);
1361 | auto buf = (cast(ubyte*) &obj)[0 .. T.sizeof];
1362 | auto init = cast(ubyte[])typeid(T).init();
1363 | if (init.ptr is null) // null ptr means initialize to 0s
1364 | buf[] = 0;
1365 | else
1366 | buf[] = init[];
1367 | }
1368 |
1369 | private void _destructRecurse(S)(ref S s)
1370 | if (is(S == struct))
1371 | {
1372 | static if (__traits(hasMember, S, "__xdtor") &&
1373 | // Bugzilla 14746: Check that it's the exact member of S.
1374 | __traits(isSame, S, __traits(parent, s.__xdtor)))
1375 | s.__xdtor();
1376 | }
1377 |
1378 | private void _destructRecurse(E, size_t n)(ref E[n] arr)
1379 | {
1380 | // import core.internal.traits : hasElaborateDestructor;
1381 | // static if (hasElaborateDestructor!E)
1382 | {
1383 | foreach_reverse (ref elem; arr)
1384 | _destructRecurse(elem);
1385 | }
1386 | }
1387 |
1388 | extern (C) Object _d_allocclass(const TypeInfo_Class ci) nothrow
1389 | {
1390 | auto p = cast(byte*)malloc(ci.initializer.length);
1391 | p[0 .. ci.initializer.length] = cast(byte[])ci.initializer[];
1392 | return cast(Object)p;
1393 | }
1394 |
1395 | extern (C) void* _d_newitemU(in TypeInfo ti)
1396 | {
1397 | return malloc(ti.tsize);
1398 | }
1399 |
1400 | extern (C) void* _d_newitemT(in TypeInfo ti)
1401 | {
1402 | auto p = _d_newitemU(ti);
1403 | memset(p, 0, ti.tsize);
1404 | return p;
1405 | }
1406 |
1407 | extern (C) void* _d_newitemiT(in TypeInfo ti)
1408 | {
1409 | auto p = _d_newitemU(ti);
1410 | auto init = ti.init;
1411 | assert(init.length <= ti.tsize);
1412 | p[0 .. init.length] = init[];
1413 | return p;
1414 | }
1415 |
1416 | // for array cast
1417 | extern (C)
1418 | size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
1419 | {
1420 | if (newelemsz == 1)
1421 | return len*elemsz;
1422 | if ((len*elemsz) % newelemsz)
1423 | not_implemented(); // bad array cast
1424 | return (len*elemsz)/newelemsz;
1425 | }
1426 |
1427 |
--------------------------------------------------------------------------------
/rt/runtime.c:
--------------------------------------------------------------------------------
1 | // Copyright: Sebastien Alaiwan 2018
2 |
3 | // Boost Software License - Version 1.0 - August 17th, 2003
4 | //
5 | // Permission is hereby granted, free of charge, to any person or organization
6 | // obtaining a copy of the software and accompanying documentation covered by
7 | // this license (the "Software") to use, reproduce, display, distribute,
8 | // execute, and transmit the Software, and to prepare derivative works of the
9 | // Software, and to permit third-parties to whom the Software is furnished to
10 | // do so, all subject to the following:
11 | //
12 | // The copyright notices in the Software and this entire statement, including
13 | // the above license grant, this restriction and the following disclaimer,
14 | // must be included in all copies of the Software, in whole or in part, and
15 | // all derivative works of the Software, unless such copies or derivative
16 | // works are solely in the form of machine-executable object code generated by
17 | // a source language processor.
18 | //
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | // DEALINGS IN THE SOFTWARE.
26 |
27 | #include
28 | #include
29 |
30 | ///////////////////////////////////////////////////////////////////////////////
31 |
32 | void not_implemented(const char* file, int line)
33 | {
34 | printf("Not implemented: %s(%d)\n", file, line);
35 | exit(123);
36 | }
37 |
38 | #define NOT_IMPLEMENTED not_implemented(__FILE__, __LINE__)
39 |
40 | ///////////////////////////////////////////////////////////////////////////////
41 | // make link work. will most probably crash if actually used during runtime.
42 | // can't get rid of those, seems to be refered-to by compiler-inserted code
43 | int _D10TypeInfo_v6__initZ;
44 | int _D10TypeInfo_m6__initZ;
45 | int _D11TypeInfo_Ai6__initZ;
46 | void _d_throw_exception() { NOT_IMPLEMENTED; }
47 |
48 | ///////////////////////////////////////////////////////////////////////////////
49 |
50 | size_t _d_arraycast_len(size_t elementCount, size_t srcElementSize, size_t dstElementSize)
51 | {
52 | return (elementCount * srcElementSize) / dstElementSize;
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/rt/standard.d:
--------------------------------------------------------------------------------
1 | // Copyright: Digital Mars 2000 - 2011.
2 | // Copyright: Sebastien Alaiwan 2017
3 |
4 | // Boost Software License - Version 1.0 - August 17th, 2003
5 | //
6 | // Permission is hereby granted, free of charge, to any person or organization
7 | // obtaining a copy of the software and accompanying documentation covered by
8 | // this license (the "Software") to use, reproduce, display, distribute,
9 | // execute, and transmit the Software, and to prepare derivative works of the
10 | // Software, and to permit third-parties to whom the Software is furnished to
11 | // do so, all subject to the following:
12 | //
13 | // The copyright notices in the Software and this entire statement, including
14 | // the above license grant, this restriction and the following disclaimer,
15 | // must be included in all copies of the Software, in whole or in part, and
16 | // all derivative works of the Software, unless such copies or derivative
17 | // works are solely in the form of machine-executable object code generated by
18 | // a source language processor.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
23 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
24 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 | // DEALINGS IN THE SOFTWARE.
27 |
28 | // minimalistic D standard library
29 | pragma(LDC_no_moduleinfo);
30 |
31 | extern(C) int printf(const(char)*, ...) nothrow;
32 | extern(C) void exit(int) nothrow;
33 | extern(C) void* malloc(size_t) nothrow;
34 | extern(C) void* calloc(int, size_t) nothrow;
35 | extern(C) void free(void*) nothrow;
36 | extern(C) void* memcpy(void*, const(void)*, size_t) pure nothrow;
37 |
38 | void deleteStruct(T)(T * r) nothrow
39 | {
40 | .destroy(*r);
41 | free(r);
42 | }
43 |
44 | void deleteObject(T)(T o) if(is(T == class))
45 | {
46 | static if(hasMember!(T, "__dtor"))
47 | {
48 | o.__dtor();
49 | }
50 | free(cast(void*)o);
51 | }
52 |
53 | struct vector (T)
54 | {
55 | this(int n)
56 | {
57 | for(int i = 0; i < n; ++i)
58 | push_back(T.init);
59 | }
60 |
61 | ~this()
62 | {
63 | clear();
64 | }
65 |
66 | void push_back()(auto ref T val)
67 | {
68 | ++len;
69 | buffer = cast(T*) realloc(buffer, len* T.sizeof);
70 | buffer[len - 1] = val;
71 | }
72 |
73 | void opIndexAssign()(auto ref T val, int idx)
74 | {
75 | buffer[idx] = val;
76 | }
77 |
78 | void clear()
79 | {
80 | foreach(element; this.opSlice())
81 | destroy(element);
82 |
83 | free(buffer);
84 | buffer = null;
85 | len = 0;
86 | }
87 |
88 | T[] opSlice()
89 | {
90 | return buffer[0 .. len];
91 | }
92 |
93 | int size() const
94 | {
95 | return len;
96 | }
97 |
98 | bool empty() const
99 | {
100 | return len == 0;
101 | }
102 |
103 | T* data()
104 | {
105 | return buffer;
106 | }
107 |
108 | private:
109 | T* buffer;
110 | int len;
111 | }
112 |
113 | T[] newArray(T)(int length)
114 | {
115 | void* block = calloc(T.sizeof, length);
116 | return cast(T[])block[0 .. T.sizeof * length];
117 | }
118 |
119 | void deleteArray(T)(in T[] arr)
120 | {
121 | free(cast(void*)arr.ptr);
122 | }
123 |
124 | ///////////////////////////////////////////////////////////////////////////////
125 | // meta
126 |
127 | template hasMember(T, string name)
128 | {
129 | static if (is(T == struct) || is(T == class) || is(T == union) || is(T == interface))
130 | {
131 | enum bool hasMember =
132 | staticIndexOf!(name, __traits(allMembers, T)) != -1 ||
133 | __traits(compiles, { mixin("alias Sym = Identity!(T."~name~");"); });
134 | }
135 | else
136 | {
137 | enum bool hasMember = false;
138 | }
139 | }
140 |
141 | template staticIndexOf(T, TList...)
142 | {
143 | enum staticIndexOf = genericIndexOf!(T, TList).index;
144 | }
145 |
146 | template staticIndexOf(alias T, TList...)
147 | {
148 | enum staticIndexOf = genericIndexOf!(T, TList).index;
149 | }
150 |
151 | template genericIndexOf(args...)
152 | if (args.length >= 1)
153 | {
154 | alias e = Alias!(args[0]);
155 | alias tuple = args[1 .. $];
156 |
157 | static if (tuple.length)
158 | {
159 | alias head = Alias!(tuple[0]);
160 | alias tail = tuple[1 .. $];
161 |
162 | static if (isSame!(e, head))
163 | {
164 | enum index = 0;
165 | }
166 | else
167 | {
168 | enum next = genericIndexOf!(e, tail).index;
169 | enum index = (next == -1) ? -1 : 1 + next;
170 | }
171 | }
172 | else
173 | {
174 | enum index = -1;
175 | }
176 | }
177 |
178 | template Alias(alias a)
179 | {
180 | static if (__traits(compiles, { alias x = a; }))
181 | alias Alias = a;
182 | else static if (__traits(compiles, { enum x = a; }))
183 | enum Alias = a;
184 | else
185 | static assert(0, "Cannot alias " ~ a.stringof);
186 | }
187 |
188 | template Alias(a...)
189 | {
190 | alias Alias = a;
191 | }
192 |
193 | template isSame(ab...)
194 | if (ab.length == 2)
195 | {
196 | static if (__traits(compiles, expectType!(ab[0]),
197 | expectType!(ab[1])))
198 | {
199 | enum isSame = is(ab[0] == ab[1]);
200 | }
201 | else static if (!__traits(compiles, expectType!(ab[0])) &&
202 | !__traits(compiles, expectType!(ab[1])) &&
203 | __traits(compiles, expectBool!(ab[0] == ab[1])))
204 | {
205 | static if (!__traits(compiles, &ab[0]) ||
206 | !__traits(compiles, &ab[1]))
207 | enum isSame = (ab[0] == ab[1]);
208 | else
209 | enum isSame = __traits(isSame, ab[0], ab[1]);
210 | }
211 | else
212 | {
213 | enum isSame = __traits(isSame, ab[0], ab[1]);
214 | }
215 | }
216 |
--------------------------------------------------------------------------------
/rt/test.d:
--------------------------------------------------------------------------------
1 | // Copyright: Sebastien Alaiwan 2018
2 |
3 | // Boost Software License - Version 1.0 - August 17th, 2003
4 | //
5 | // Permission is hereby granted, free of charge, to any person or organization
6 | // obtaining a copy of the software and accompanying documentation covered by
7 | // this license (the "Software") to use, reproduce, display, distribute,
8 | // execute, and transmit the Software, and to prepare derivative works of the
9 | // Software, and to permit third-parties to whom the Software is furnished to
10 | // do so, all subject to the following:
11 | //
12 | // The copyright notices in the Software and this entire statement, including
13 | // the above license grant, this restriction and the following disclaimer,
14 | // must be included in all copies of the Software, in whole or in part, and
15 | // all derivative works of the Software, unless such copies or derivative
16 | // works are solely in the form of machine-executable object code generated by
17 | // a source language processor.
18 | //
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | // DEALINGS IN THE SOFTWARE.
26 |
27 | // tests that the minimalistic D runtime/helpers actually works
28 | pragma(LDC_no_moduleinfo);
29 | import standard;
30 |
31 | extern(C)
32 | int main()
33 | {
34 | runTest!("struct: ctor/dtor", testStructCtorAndDtor);
35 |
36 | runTest!("class: empty", testEmptyClass);
37 | runTest!("class: ctor/dtor", testClassCtorAndDtor);
38 | runTest!("class: derived", testDerivedClass);
39 |
40 | runTest!("floating point: basic", testFloatingPoint);
41 | runTest!("arrays: copy", testArrayCopy);
42 | runTest!("arrays: dynamic", testArrayDynamic);
43 |
44 | runTest!("delegates", testDelegate);
45 |
46 | return 0;
47 | }
48 |
49 | ///////////////////////////////////////////////////////////////////////////////
50 |
51 | float g_f; // global nan-initialized float compile-test
52 |
53 | void testFloatingPoint()
54 | {
55 | check(g_f != g_f);
56 |
57 | float f;
58 | check(f != f);
59 | }
60 |
61 | void testEmptyClass()
62 | {
63 | static class E
64 | {
65 | }
66 |
67 | auto o = new E;
68 | check(o !is null);
69 | deleteObject(o);
70 | }
71 |
72 | void testClassCtorAndDtor()
73 | {
74 | static class C
75 | {
76 | static bool called;
77 | static bool constructed;
78 | static bool destroyed;
79 |
80 | this() nothrow
81 | {
82 | constructed = true;
83 | }
84 |
85 | ~this() nothrow
86 | {
87 | destroyed = true;
88 | }
89 |
90 | void f() nothrow
91 | {
92 | called = true;
93 | }
94 | }
95 |
96 | auto c = new C;
97 | check(C.constructed);
98 | c.f();
99 | check(C.called);
100 |
101 | deleteObject(c);
102 | check(C.destroyed);
103 | }
104 |
105 | void testDerivedClass()
106 | {
107 | static class Base
108 | {
109 | void f()
110 | {
111 | }
112 | }
113 |
114 | // construction/destruction
115 | static class D : Base
116 | {
117 | static bool derivedObjectConstructed;
118 | static bool called;
119 |
120 | this()
121 | {
122 | derivedObjectConstructed = true;
123 | }
124 |
125 | override void f()
126 | {
127 | called = true;
128 | }
129 | }
130 |
131 | // polymorphism
132 | {
133 | Base c = new D;
134 | check(D.derivedObjectConstructed);
135 |
136 | c.f();
137 | check(D.called);
138 |
139 | deleteObject(c);
140 | }
141 | }
142 |
143 | void testStructCtorAndDtor() nothrow
144 | {
145 | static struct MyStruct
146 | {
147 | int initialized = 7654;
148 | bool ctorCalled;
149 | int ctorArg;
150 | this(int arg_) nothrow
151 | {
152 | ctorCalled = true;
153 | ctorArg = arg_;
154 | }
155 |
156 | static bool dtorCalled;
157 |
158 | ~this() nothrow
159 | {
160 | dtorCalled = true;
161 | }
162 | }
163 |
164 | // statically allocated struct
165 | {
166 | {
167 | auto s = MyStruct(123);
168 | check(s.initialized == 7654);
169 | check(s.ctorCalled);
170 | check(s.ctorArg == 123);
171 | check(!s.dtorCalled);
172 | }
173 | check(MyStruct.dtorCalled);
174 | }
175 |
176 | // dynamically allocated struct
177 | MyStruct.dtorCalled = false;
178 | {
179 | auto s = new MyStruct(123);
180 | assertEquals(7654, s.initialized);
181 | check(s.ctorCalled);
182 | assertEquals(123, s.ctorArg);
183 | check(!s.dtorCalled);
184 |
185 | deleteStruct(s);
186 | }
187 | check(MyStruct.dtorCalled);
188 | }
189 |
190 | void testArrayCopy()
191 | {
192 | int[10] tab;
193 | tab[] = 4;
194 | assertEquals(4, tab[0]);
195 | assertEquals(4, tab[9]);
196 |
197 | int[10] tab2;
198 | tab2 = tab;
199 | assertEquals(4, tab2[0]);
200 | assertEquals(4, tab2[9]);
201 | }
202 |
203 | void testArrayDynamic()
204 | {
205 | int[] tab = newArray!int(256);
206 | assertEquals(256, cast(int)tab.length);
207 | assert(tab.ptr);
208 | assertEquals(0, tab[0]);
209 | tab[1] = 1234;
210 |
211 | deleteArray(tab);
212 | }
213 |
214 | void testDelegate()
215 | {
216 | static class C
217 | {
218 | int a;
219 | void f()
220 | {
221 | ++a;
222 | }
223 | }
224 |
225 | static void callMe(void delegate() func)
226 | {
227 | for(int i=0;i < 123;++i)
228 | func();
229 | }
230 |
231 | auto c = new C;
232 | callMe(&c.f);
233 | assertEquals(123, c.a);
234 | }
235 |
236 | ///////////////////////////////////////////////////////////////////////////////
237 | void runTest(string name, alias f)()
238 | {
239 | printf("Test: %s\n", name.ptr);
240 | f();
241 | }
242 |
243 | void assertEquals(int expected, int actual, string file=__FILE__, int line=__LINE__) nothrow
244 | {
245 | if(expected == actual)
246 | return;
247 |
248 | printf("At %s(%d): expected %d, got %d\n", file.ptr, line, expected, actual);
249 | exit(1);
250 | }
251 |
252 | void check(bool condition, string file=__FILE__, int line=__LINE__) nothrow
253 | {
254 | if(condition)
255 | return;
256 |
257 | printf("At %s(%d): assertion failure\n", file.ptr, line);
258 | exit(1);
259 | }
260 |
261 |
--------------------------------------------------------------------------------
/src/game.d:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2016 - Sebastien Alaiwan
2 | // This program is free software: you can redistribute it and/or modify
3 | // it under the terms of the GNU Affero General Public License as
4 | // published by the Free Software Foundation, either version 3 of the
5 | // License, or (at your option) any later version.
6 |
7 | pragma(LDC_no_moduleinfo);
8 |
9 | import vec;
10 | import standard;
11 |
12 | enum WIDTH = 512;
13 | enum HEIGHT = 512;
14 |
15 | struct Box
16 | {
17 | bool enable;
18 | Vec2 pos;
19 | Vec2 vel;
20 | }
21 |
22 | Box player;
23 | bool firing;
24 | bool dead;
25 |
26 | Box[128] boxes;
27 |
28 | enum SIZE = 10;
29 |
30 | struct Command
31 | {
32 | Vec2 dir;
33 | bool fire;
34 | }
35 |
36 | void init()
37 | {
38 | printf("-------------------------\n");
39 | printf("Avoid the red boxes!\n");
40 |
41 | dead = false;
42 | ticks = 0;
43 |
44 | boxes[] = Box();
45 | player.pos = Vec2(100, 100);
46 | player.vel = Vec2(1000, 0);
47 |
48 | for(int i = 0; i < 2; ++i)
49 | spawnRandomBox();
50 | }
51 |
52 | void update(Command cmd)
53 | {
54 | if(dead)
55 | return;
56 |
57 | player.vel += cmd.dir * SPEED;
58 | firing = cmd.fire;
59 |
60 | if(ticks % 100 == 0)
61 | {
62 | spawnRandomBox();
63 | shakeBoxes();
64 | }
65 |
66 | updateBox(&player);
67 |
68 | foreach(ref b; boxes)
69 | updateBox(&b);
70 |
71 | detectCollisions();
72 |
73 | ++ticks;
74 | }
75 |
76 | private:
77 |
78 | enum SPEED = 30;
79 | int ticks;
80 | int bestScore;
81 |
82 | void updateBox(Box* box)
83 | {
84 | if(box.pos.x < 0)
85 | box.vel.x = abs(box.vel.x);
86 |
87 | if(box.pos.x + SIZE > WIDTH)
88 | box.vel.x = -abs(box.vel.x);
89 |
90 | if(box.pos.y < 0)
91 | box.vel.y = abs(box.vel.y);
92 |
93 | if(box.pos.y + SIZE > HEIGHT)
94 | box.vel.y = -abs(box.vel.y);
95 |
96 | box.pos += box.vel / 10;
97 | box.vel *= 9;
98 | box.vel /= 10;
99 | }
100 |
101 | void detectCollisions()
102 | {
103 | foreach(ref b; boxes)
104 | {
105 | if(!b.enable)
106 | continue;
107 |
108 | if(overlaps(b, player))
109 | {
110 | gameOver();
111 | break;
112 | }
113 | }
114 | }
115 |
116 | void gameOver()
117 | {
118 | dead = true;
119 |
120 | bestScore = max(bestScore, ticks);
121 | printf("You died!\n");
122 | printf("Your score: %d (High score: %d)\n", ticks, bestScore);
123 | printf("Press 'R' to retry\n");
124 | }
125 |
126 | void shakeBoxes()
127 | {
128 | foreach(ref b; boxes)
129 | b.vel = Vec2(uniform(-5, 5) * 100, uniform(-5, 5) * 100);
130 | }
131 |
132 | void spawnRandomBox()
133 | {
134 | spawnBox(Vec2(uniform(0, WIDTH), uniform(0, HEIGHT)));
135 | }
136 |
137 | Box* spawnBox(Vec2 where)
138 | {
139 | auto box = allocBox();
140 | box.pos = where;
141 | return box;
142 | }
143 |
144 | Box* allocBox()
145 | {
146 | foreach(ref box; boxes)
147 | {
148 | if(!box.enable)
149 | {
150 | box.enable = true;
151 | return &box;
152 | }
153 | }
154 |
155 | return &boxes[0];
156 | }
157 |
158 | bool overlaps(ref Box a, ref Box b)
159 | {
160 | if(a.pos.x + SIZE < b.pos.x)
161 | return false;
162 |
163 | if(b.pos.x + SIZE < a.pos.x)
164 | return false;
165 |
166 | if(a.pos.y + SIZE < b.pos.y)
167 | return false;
168 |
169 | if(b.pos.y + SIZE < a.pos.y)
170 | return false;
171 |
172 | return true;
173 | }
174 |
175 | extern(C) int rand();
176 |
177 | int uniform(int min, int max)
178 | {
179 | return rand() % (max - min) + min;
180 | }
181 |
182 | auto max(T)(T a, T b)
183 | {
184 | return a > b ? a : b;
185 | }
186 |
187 |
--------------------------------------------------------------------------------
/src/main.d:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2016 - Sebastien Alaiwan
2 | // This program is free software: you can redistribute it and/or modify
3 | // it under the terms of the GNU Affero General Public License as
4 | // published by the Free Software Foundation, either version 3 of the
5 | // License, or (at your option) any later version.
6 |
7 | pragma(LDC_no_moduleinfo);
8 |
9 | import sdl;
10 | import vec;
11 | static import game;
12 |
13 | alias WIDTH = game.WIDTH;
14 | alias HEIGHT = game.HEIGHT;
15 |
16 | SDL_Surface* screen;
17 |
18 | extern(C) void quit();
19 |
20 | extern(C)
21 | void startup()
22 | {
23 | SDL_Init(SDL_INIT_VIDEO);
24 | screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, 0);
25 | SDL_WM_SetCaption("Dscripten demo game", null);
26 | game.init();
27 | }
28 |
29 | extern(C)
30 | void mainLoop()
31 | {
32 | auto cmd = processInput();
33 | game.update(cmd);
34 | drawScreen();
35 | }
36 |
37 | game.Command processInput()
38 | {
39 | SDL_PumpEvents();
40 |
41 | game.Command cmd;
42 |
43 | auto keyboard = SDL_GetKeyState(null);
44 |
45 | if(keyboard[SDLK_ESCAPE])
46 | quit();
47 |
48 | static bool debounce;
49 | if(keyboard[SDLK_F2] || keyboard[SDLK_r])
50 | {
51 | if(debounce)
52 | {
53 | game.init();
54 | debounce = false;
55 | }
56 | }
57 | else
58 | debounce = true;
59 |
60 | if(keyboard[SDLK_LEFT])
61 | cmd.dir.x += -1;
62 |
63 | if(keyboard[SDLK_RIGHT])
64 | cmd.dir.x += +1;
65 |
66 | if(keyboard[SDLK_UP])
67 | cmd.dir.y += -1;
68 |
69 | if(keyboard[SDLK_DOWN])
70 | cmd.dir.y += +1;
71 |
72 | if(keyboard[SDLK_SPACE])
73 | cmd.fire = true;
74 |
75 | return cmd;
76 | }
77 |
78 | void drawScreen()
79 | {
80 | boxColor(Vec2(0, 0), Vec2(WIDTH, HEIGHT), game.dead ? deadBackgroundColor : backgroundColor);
81 | int size = 10;
82 | uint color = game.firing ? 255 : 0;
83 |
84 | drawBox(game.player.pos, playerColor);
85 |
86 | foreach(ref box; game.boxes)
87 | {
88 | if(box.enable)
89 | drawBox(box.pos, enemyColor);
90 | }
91 |
92 | const border = 10;
93 | lineRGBA(screen, border, border, WIDTH - border, border, 255, 255, 255, 255);
94 | lineRGBA(screen, WIDTH - border, border, WIDTH - border, HEIGHT - border, 255, 255, 255, 255);
95 | lineRGBA(screen, WIDTH - border, HEIGHT - border, border, HEIGHT - border, 255, 255, 255, 255);
96 | lineRGBA(screen, border, HEIGHT - border, border, border, 255, 255, 255, 255);
97 |
98 | SDL_Flip(screen);
99 | }
100 |
101 | const backgroundColor = Color(128, 224, 255, 64);
102 | const deadBackgroundColor = Color(224, 128, 128, 255);
103 | const enemyColor = Color(255, 0, 0, 224);
104 | const playerColor = Color(255, 255, 0, 255);
105 |
106 | struct Color
107 | {
108 | int r, g, b, a;
109 | }
110 |
111 | void drawBox(Vec2 pos, Color color)
112 | {
113 | boxColor(pos, Vec2(game.SIZE, game.SIZE), color);
114 | }
115 |
116 | void boxColor(Vec2 pos, Vec2 size, Color color)
117 | {
118 | boxRGBA(screen, pos.x, pos.y, pos.x + size.x, pos.y + size.y, color.r, color.g, color.b, color.a);
119 | }
120 |
121 |
--------------------------------------------------------------------------------
/src/vec.d:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2016 - Sebastien Alaiwan
2 | // This program is free software: you can redistribute it and/or modify
3 | // it under the terms of the GNU Affero General Public License as
4 | // published by the Free Software Foundation, either version 3 of the
5 | // License, or (at your option) any later version.
6 |
7 | pragma(LDC_no_moduleinfo);
8 |
9 | struct Vec2
10 | {
11 | int x, y;
12 |
13 | void opAddAssign(Vec2 other)
14 | {
15 | x += other.x;
16 | y += other.y;
17 | }
18 |
19 | void opMulAssign(T)(T val)
20 | {
21 | x *= val;
22 | y *= val;
23 | }
24 |
25 | Vec2 opMul(T)(T val) const
26 | {
27 | Vec2 r = this;
28 | r.x *= val;
29 | r.y *= val;
30 | return r;
31 | }
32 |
33 | void opDivAssign(T)(T val)
34 | {
35 | x /= val;
36 | y /= val;
37 | }
38 |
39 | Vec2 opDiv(T)(T val) const
40 | {
41 | Vec2 r = this;
42 | r.x /= val;
43 | r.y /= val;
44 | return r;
45 | }
46 | }
47 |
48 | auto abs(T)(T val)
49 | {
50 | if(val < 0)
51 | return -val;
52 | else
53 | return val;
54 | }
55 |
56 |
--------------------------------------------------------------------------------