diff options
author | Matthias Andreas Benkard <matthias@benkard.de> | 2008-06-17 19:52:46 +0200 |
---|---|---|
committer | Matthias Andreas Benkard <matthias@benkard.de> | 2008-06-17 19:52:46 +0200 |
commit | 2491e0485e6851a3a3f3a5e1f5c399780e04fae5 (patch) | |
tree | 52594a6878f5536ad61672bdeb6459ec6c409af0 | |
parent | fae6a10cd7a1c0a12c00d869b5b7c94299a722ef (diff) |
MLKReadtable: Implement constituent trait support.
-rw-r--r-- | MLKReadtable.h | 1 | ||||
-rw-r--r-- | MLKReadtable.m | 64 |
2 files changed, 65 insertions, 0 deletions
diff --git a/MLKReadtable.h b/MLKReadtable.h index b430dd1..ef88c17 100644 --- a/MLKReadtable.h +++ b/MLKReadtable.h @@ -37,6 +37,7 @@ enum MLKReadtableCase { NSMutableDictionary *_syntaxTable; NSMutableDictionary *_readerMacros; + NSMutableDictionary *_traits; //MLKFuncallable *_caseConverter; enum MLKReadtableCase _case; } diff --git a/MLKReadtable.m b/MLKReadtable.m index 585d930..08539d9 100644 --- a/MLKReadtable.m +++ b/MLKReadtable.m @@ -31,6 +31,23 @@ #define MULTI_ESCAPE 5 +enum MLKCharacterTrait +{ + ALPHABETIC = 0, + INVALID, + PACKAGE_MARKER, + ALPHA_DIGIT, + EXPONENT_MARKER, + NUMBER_MARKER, + RATIO_MARKER, + DECIMAL_POINT, + MINUS_SIGN, + PLUS_SIGN, + SIGN, + DOT +}; + + @implementation MLKReadtable -(MLKReadtable *) initSuper { @@ -130,4 +147,51 @@ } return 0; } + + +#define DEFINE_TRAIT_PREDICATE(SELECTOR, TRAIT) \ +-(BOOL) SELECTOR (unichar)ch \ +{ \ + return ([[_traits objectForKey:[NSNumber numberWithLong:ch]] \ + isEqual:[NSNumber numberWithShort:TRAIT]]); \ +} + +DEFINE_TRAIT_PREDICATE(isInvalid:, INVALID) +DEFINE_TRAIT_PREDICATE(isAlphabetic:, ALPHABETIC) +DEFINE_TRAIT_PREDICATE(isPackageMarker:, PACKAGE_MARKER) +DEFINE_TRAIT_PREDICATE(isAlphaDigit:, ALPHA_DIGIT) +DEFINE_TRAIT_PREDICATE(isExponentMarker:, EXPONENT_MARKER) +DEFINE_TRAIT_PREDICATE(isNumberMarker:, NUMBER_MARKER) +DEFINE_TRAIT_PREDICATE(isRatioMarker:, RATIO_MARKER) +DEFINE_TRAIT_PREDICATE(isDecimalPoint:, DECIMAL_POINT) +DEFINE_TRAIT_PREDICATE(isMinusSign:, MINUS_SIGN) +DEFINE_TRAIT_PREDICATE(isPlusSign:, PLUS_SIGN) +DEFINE_TRAIT_PREDICATE(isSign:, SIGN) +DEFINE_TRAIT_PREDICATE(isDot:, DOT) + +-(BOOL) isDecimalDigit:(unichar)ch +{ + return [self isDigit:ch inBase:10]; +} + +-(BOOL) isDigit:(unichar)ch inBase:(int)base +{ + if (base < 11) + return (ch < '0' + base); + else + return (ch <= '9' + || ('A' <= ch && ch < 'A' + base - 10) + || ('a' <= ch && ch < 'a' + base - 10)); +} + +-(int) digitWeight:(unichar)ch +{ + if ('0' <= ch && ch <= '9') + return (ch - '0'); + else if ('A' <= ch && ch <= 'Z') + return (ch - 'A' + 10); + else + return (ch - 'a' + 10); +} + @end |