Mercurial > projects > mde
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mde/mergetag/old-code/typeSpec.d.old Sun Jan 06 17:38:51 2008 +0000 @@ -0,0 +1,103 @@ +/+ I wrote this and then realised it's not worth using, it being easier and faster to match type +strings without this. This module does enable spaces to be in appropriate places, but so what... + +module typeSpec; + +import mde.mergetag.exception; + +import Util = tango.text.Util; + +/** + * Struct to view a type specifier string. + */ +struct TypeView +{ + /// Type of stored type specifier (NULL, BASIC, ARRAY, ASSOCIATIVE_ARRAY). + enum SPEC_TYPE : ubyte { + NULL, BASIC, ARRAY, ASSOCIATIVE_ARRAY + } + + SPEC_TYPE spec_type; /// Current specifier type. + union { + char[] type_name; /// For BASIC types is the type name. + TypeView* type_array_value; /// For ARRAY and ASSOCIATIVE_ARRAY types, this is the value-type. + } + TypeView* type_array_key; /// For ASSOCIATIVE_ARRAY types, this is the key-type; + + /** Construct and return a TypeView from a source string. + * + * Such a string should have one of the following forms: + * TYPE_NAME: [_a-zA-Z][_a-zA-Z0-9]* (regexp) + * ARRAY: TYPE_NAME[] + * ASSOC_ARRAY: TYPE_NAME[TYPE_NAME] + * + * Throws MTBadTypeStringException on bad type specifier strings. + */ + static TypeSpec parse (char[] src) { + bool isNameChar (char c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c = '_'; + } + void throwErr () { + logger.warn ("Bad type string"); + throw new MTBadTypeStringException (); + } + + src = Util.trim(src); + if (!src.length) throwErr; + + TypeView ret; + if (src[$-1] == ']') { // ARRAY or ASSOCIATIVE_ARRAY type + if (src.length < 2) throwErr; + + if (src[$-2] == '[') { // ARRAY type + ret.spec_type = SPEC_TYPE.ARRAY; // this is an array of... + ret.type_array_value = parse (src[0..$-2]); // whatever this is + } + else { // ASSOCIATIVE_ARRAY type + // look backwards for matching '[' bracket: + uint i = src.length-2; + uint recursion_depth = 0; + while (true) { + char c = src[i]; + + if (c == ']') ++recursion_depth; + if (c == '[') { + if (recursion_depth) --recursion_depth; + else break; + } + if (i == 0) throwErr; // no matching bracket! + else --i; + } + + ret.spec_type = SPEC_TYPE.ASSOCIATIVE_ARRAY; + ret.type_array_value = parse (src[0..i]); + ret.type_array_key = parse (src[i+1..$-1]); + } + } + else { // BASIC type + char c = src[0]; + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c = '_')) + throwErr; + for (uint i=1; i < src.length; ++i) { + if (!isNameChar(src[i])) throwErr; + } + + ret.spec_type = SPEC_TYPE.BASIC; + ret.type_name = src; + } + return ret; + } +} + +unittest { + TypeView tv = TypeView.parse (` type1 [] [ Type2 [] ] [] `); + assert (tv.spec_type == SPEC_TYPE.ARRAY); + assert (tv.type_array_value.spec_type == SPEC_TYPE.ASSOCIATIVE_ARRAY); + assert (tv.type_array_value.type_array_value.spec_type == SPEC_TYPE.ARRAY); + assert (tv.type_array_value.type_array_value.type_array_value.spec_type == SPEC_TYPE.BASIC); + assert (tv.type_array_value.type_array_value.type_array_value.type_name == `type1`); + assert (tv.type_array_value.type_array_key.spec_type == SPEC_TYPE.ARRAY); + assert (tv.type_array_value.type_array_key.type_array_value.spec_type == SPEC_TYPE.BASIC); + assert (tv.type_array_value.type_array_key.type_array_value.type_name == `Type2`); +} ++/ \ No newline at end of file