|
2 | 2 | * Compiler implementation of the |
3 | 3 | * $(LINK2 http://www.dlang.org, D programming language). |
4 | 4 | * |
| 5 | + * This module contains the `Id` struct with a list of predefined symbols the |
| 6 | + * compiler knows about. |
| 7 | + * |
5 | 8 | * Copyright: Copyright (c) 1999-2017 by Digital Mars, All Rights Reserved |
6 | 9 | * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) |
7 | 10 | * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) |
8 | | - * Source: $(DMDSRC _idgen.d) |
| 11 | + * Source: $(DMDSRC _id.d) |
9 | 12 | */ |
| 13 | +module ddmd.id; |
10 | 14 |
|
11 | | -// Program to generate string files in d data structures. |
12 | | -// Saves much tedious typing, and eliminates typo problems. |
13 | | -// Generates: |
14 | | -// id.h |
15 | | -// id.c |
16 | | - |
17 | | -import core.stdc.stdio; |
18 | | -import core.stdc.stdlib; |
| 15 | +import ddmd.identifier; |
| 16 | +import ddmd.tokens; |
19 | 17 |
|
20 | | -struct Msgtable |
| 18 | +/** |
| 19 | + * Represents a list of predefined symbols the compiler knows about. |
| 20 | + * |
| 21 | + * All static fields in this struct represents a specific predefined symbol. |
| 22 | + */ |
| 23 | +struct Id |
21 | 24 | { |
22 | | - const(char)* ident; // name to use in DMD source |
23 | | - const(char)* name; // name in D executable |
24 | | -}; |
| 25 | + static __gshared: |
| 26 | + |
| 27 | + mixin(msgtable.generate(&identifier)); |
| 28 | + |
| 29 | + /** |
| 30 | + * Populates the identifier pool with all predefined symbols. |
| 31 | + * |
| 32 | + * An identifier that corresponds to each static field in this struct will |
| 33 | + * be placed in the identifier pool. |
| 34 | + */ |
| 35 | + void initialize() |
| 36 | + { |
| 37 | + mixin(msgtable.generate(&initializer)); |
| 38 | + } |
| 39 | +} |
| 40 | + |
| 41 | +private: |
25 | 42 |
|
26 | | -Msgtable[] msgtable = |
| 43 | + |
| 44 | +/** |
| 45 | + * Each element in this array will generate one static field in the `Id` struct |
| 46 | + * and a call to `Identifier.idPool` to populate the identifier pool in the |
| 47 | + * `Id.initialize` method. |
| 48 | + */ |
| 49 | +immutable Msgtable[] msgtable = |
27 | 50 | [ |
28 | 51 | { "IUnknown" }, |
29 | 52 | { "Object" }, |
@@ -376,82 +399,60 @@ Msgtable[] msgtable = |
376 | 399 | ]; |
377 | 400 |
|
378 | 401 |
|
379 | | -int main() |
| 402 | +/* |
| 403 | + * Tuple of DMD source code identifier and symbol in the D executable. |
| 404 | + * |
| 405 | + * The first element of the tuple is the identifier to use in the DMD source |
| 406 | + * code and the second element, if present, is the name to use in the D |
| 407 | + * executable. If second element, `name`, is not present the identifier, |
| 408 | + * `ident`, will be used instead |
| 409 | + */ |
| 410 | +struct Msgtable |
380 | 411 | { |
| 412 | + // The identifier to use in the DMD source. |
| 413 | + string ident; |
| 414 | + |
| 415 | + // The name to use in the D executable |
| 416 | + private string name_; |
| 417 | + |
| 418 | + /* |
| 419 | + * Returns: the name to use in the D executable, `name_` if non-empty, |
| 420 | + * otherwise `ident` |
| 421 | + */ |
| 422 | + string name() |
381 | 423 | { |
382 | | - auto fp = fopen("ddmd/id.h","wb"); |
383 | | - if (!fp) |
384 | | - { |
385 | | - printf("can't open ddmd/id.h\n"); |
386 | | - exit(EXIT_FAILURE); |
387 | | - } |
388 | | - |
389 | | - fprintf(fp, "// File generated by idgen.d\n"); |
390 | | - fprintf(fp, "#ifndef DMD_ID_H\n"); |
391 | | - fprintf(fp, "#define DMD_ID_H 1\n"); |
392 | | - fprintf(fp, "class Identifier;\n"); |
393 | | - fprintf(fp, "struct Id\n"); |
394 | | - fprintf(fp, "{\n"); |
395 | | - |
396 | | - foreach(e; msgtable) |
397 | | - { |
398 | | - auto id = e.ident; |
399 | | - fprintf(fp," static Identifier *%s;\n", id); |
400 | | - } |
401 | | - |
402 | | - fprintf(fp, " static void initialize();\n"); |
403 | | - fprintf(fp, "};\n"); |
404 | | - fprintf(fp, "#endif\n"); |
405 | | - |
406 | | - fclose(fp); |
| 424 | + return name_.length == 0 ? ident : name_; |
407 | 425 | } |
| 426 | +} |
| 427 | + |
| 428 | +/* |
| 429 | + * Iterates the given Msgtable array, passes each element to the given lambda |
| 430 | + * and accumulates a string from each return value of calling the lambda. |
| 431 | + * Appends a newline character after each call to the lambda. |
| 432 | + */ |
| 433 | +string generate(immutable(Msgtable)[] msgtable, string function(Msgtable) dg) |
| 434 | +{ |
| 435 | + string code; |
408 | 436 |
|
| 437 | + foreach (i, m ; msgtable) |
409 | 438 | { |
410 | | - auto fp = fopen("ddmd/id.d","wb"); |
411 | | - if (!fp) |
412 | | - { |
413 | | - printf("can't open ddmd.id.d\n"); |
414 | | - exit(EXIT_FAILURE); |
415 | | - } |
416 | | - |
417 | | - fprintf(fp, "// File generated by idgen.d\n"); |
418 | | - fprintf(fp, "\n"); |
419 | | - fprintf(fp, "module ddmd.id;\n"); |
420 | | - fprintf(fp, "\n"); |
421 | | - fprintf(fp, "import ddmd.identifier, ddmd.tokens;\n"); |
422 | | - fprintf(fp, "\n"); |
423 | | - fprintf(fp, "struct Id\n"); |
424 | | - fprintf(fp, "{\n"); |
425 | | - |
426 | | - foreach(e; msgtable) |
427 | | - { |
428 | | - auto id = e.ident; |
429 | | - auto p = e.name; |
430 | | - |
431 | | - if (!p) |
432 | | - p = id; |
433 | | - fprintf(fp, " extern (C++) static __gshared Identifier %s;\n", id); |
434 | | - } |
435 | | - |
436 | | - fprintf(fp, "\n"); |
437 | | - fprintf(fp, " extern (C++) static void initialize()\n"); |
438 | | - fprintf(fp, " {\n"); |
439 | | - |
440 | | - foreach(e; msgtable) |
441 | | - { |
442 | | - auto id = e.ident; |
443 | | - auto p = e.name; |
444 | | - |
445 | | - if (!p) |
446 | | - p = id; |
447 | | - fprintf(fp," %s = Identifier.idPool(\"%s\");\n", id, p); |
448 | | - } |
449 | | - |
450 | | - fprintf(fp, " }\n"); |
451 | | - fprintf(fp, "}\n"); |
452 | | - |
453 | | - fclose(fp); |
| 439 | + if (i != 0) |
| 440 | + code ~= '\n'; |
| 441 | + |
| 442 | + code ~= dg(m); |
454 | 443 | } |
455 | 444 |
|
456 | | - return EXIT_SUCCESS; |
| 445 | + return code; |
| 446 | +} |
| 447 | + |
| 448 | +// Used to generate the code for each identifier. |
| 449 | +string identifier(Msgtable m) |
| 450 | +{ |
| 451 | + return "Identifier " ~ m.ident ~ ";"; |
| 452 | +} |
| 453 | + |
| 454 | +// Used to generate the code for each initializer. |
| 455 | +string initializer(Msgtable m) |
| 456 | +{ |
| 457 | + return m.ident ~ ` = Identifier.idPool("` ~ m.name ~ `");`; |
457 | 458 | } |
0 commit comments