Mercurial > projects > mde
comparison mde/mergetag/old-code/typeSpec.d.old @ 4:9a990644948c
Many changes: upgraded to tango 0.99.4, reorganised mde/input, large changes to mde/mergetag and mde/init, separated off test/MTTest.d and more.
committer: Diggory Hardy <diggory.hardy@gmail.com>
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Sun, 06 Jan 2008 17:38:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:485c98ecbd91 | 4:9a990644948c |
---|---|
1 /+ I wrote this and then realised it's not worth using, it being easier and faster to match type | |
2 strings without this. This module does enable spaces to be in appropriate places, but so what... | |
3 | |
4 module typeSpec; | |
5 | |
6 import mde.mergetag.exception; | |
7 | |
8 import Util = tango.text.Util; | |
9 | |
10 /** | |
11 * Struct to view a type specifier string. | |
12 */ | |
13 struct TypeView | |
14 { | |
15 /// Type of stored type specifier (NULL, BASIC, ARRAY, ASSOCIATIVE_ARRAY). | |
16 enum SPEC_TYPE : ubyte { | |
17 NULL, BASIC, ARRAY, ASSOCIATIVE_ARRAY | |
18 } | |
19 | |
20 SPEC_TYPE spec_type; /// Current specifier type. | |
21 union { | |
22 char[] type_name; /// For BASIC types is the type name. | |
23 TypeView* type_array_value; /// For ARRAY and ASSOCIATIVE_ARRAY types, this is the value-type. | |
24 } | |
25 TypeView* type_array_key; /// For ASSOCIATIVE_ARRAY types, this is the key-type; | |
26 | |
27 /** Construct and return a TypeView from a source string. | |
28 * | |
29 * Such a string should have one of the following forms: | |
30 * TYPE_NAME: [_a-zA-Z][_a-zA-Z0-9]* (regexp) | |
31 * ARRAY: TYPE_NAME[] | |
32 * ASSOC_ARRAY: TYPE_NAME[TYPE_NAME] | |
33 * | |
34 * Throws MTBadTypeStringException on bad type specifier strings. | |
35 */ | |
36 static TypeSpec parse (char[] src) { | |
37 bool isNameChar (char c) { | |
38 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c = '_'; | |
39 } | |
40 void throwErr () { | |
41 logger.warn ("Bad type string"); | |
42 throw new MTBadTypeStringException (); | |
43 } | |
44 | |
45 src = Util.trim(src); | |
46 if (!src.length) throwErr; | |
47 | |
48 TypeView ret; | |
49 if (src[$-1] == ']') { // ARRAY or ASSOCIATIVE_ARRAY type | |
50 if (src.length < 2) throwErr; | |
51 | |
52 if (src[$-2] == '[') { // ARRAY type | |
53 ret.spec_type = SPEC_TYPE.ARRAY; // this is an array of... | |
54 ret.type_array_value = parse (src[0..$-2]); // whatever this is | |
55 } | |
56 else { // ASSOCIATIVE_ARRAY type | |
57 // look backwards for matching '[' bracket: | |
58 uint i = src.length-2; | |
59 uint recursion_depth = 0; | |
60 while (true) { | |
61 char c = src[i]; | |
62 | |
63 if (c == ']') ++recursion_depth; | |
64 if (c == '[') { | |
65 if (recursion_depth) --recursion_depth; | |
66 else break; | |
67 } | |
68 if (i == 0) throwErr; // no matching bracket! | |
69 else --i; | |
70 } | |
71 | |
72 ret.spec_type = SPEC_TYPE.ASSOCIATIVE_ARRAY; | |
73 ret.type_array_value = parse (src[0..i]); | |
74 ret.type_array_key = parse (src[i+1..$-1]); | |
75 } | |
76 } | |
77 else { // BASIC type | |
78 char c = src[0]; | |
79 if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c = '_')) | |
80 throwErr; | |
81 for (uint i=1; i < src.length; ++i) { | |
82 if (!isNameChar(src[i])) throwErr; | |
83 } | |
84 | |
85 ret.spec_type = SPEC_TYPE.BASIC; | |
86 ret.type_name = src; | |
87 } | |
88 return ret; | |
89 } | |
90 } | |
91 | |
92 unittest { | |
93 TypeView tv = TypeView.parse (` type1 [] [ Type2 [] ] [] `); | |
94 assert (tv.spec_type == SPEC_TYPE.ARRAY); | |
95 assert (tv.type_array_value.spec_type == SPEC_TYPE.ASSOCIATIVE_ARRAY); | |
96 assert (tv.type_array_value.type_array_value.spec_type == SPEC_TYPE.ARRAY); | |
97 assert (tv.type_array_value.type_array_value.type_array_value.spec_type == SPEC_TYPE.BASIC); | |
98 assert (tv.type_array_value.type_array_value.type_array_value.type_name == `type1`); | |
99 assert (tv.type_array_value.type_array_key.spec_type == SPEC_TYPE.ARRAY); | |
100 assert (tv.type_array_value.type_array_key.type_array_value.spec_type == SPEC_TYPE.BASIC); | |
101 assert (tv.type_array_value.type_array_key.type_array_value.type_name == `Type2`); | |
102 } | |
103 +/ |