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 +/