|
40 | 40 | */ |
41 | 41 | package com.oracle.graal.python.builtins.modules; |
42 | 42 |
|
| 43 | +import com.ibm.icu.lang.UCharacter; |
| 44 | + |
| 45 | +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; |
43 | 46 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; |
44 | 47 |
|
45 | 48 | import java.text.Normalizer; |
|
49 | 52 | import com.oracle.graal.python.builtins.CoreFunctions; |
50 | 53 | import com.oracle.graal.python.builtins.PythonBuiltinClassType; |
51 | 54 | import com.oracle.graal.python.builtins.PythonBuiltins; |
| 55 | +import com.oracle.graal.python.builtins.objects.PNone; |
52 | 56 | import com.oracle.graal.python.builtins.objects.object.PythonObject; |
53 | 57 | import com.oracle.graal.python.builtins.objects.str.PString; |
54 | 58 | import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; |
|
60 | 64 | import com.oracle.truffle.api.CompilerDirectives; |
61 | 65 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; |
62 | 66 | import com.oracle.truffle.api.dsl.Cached; |
| 67 | +import com.oracle.truffle.api.dsl.Fallback; |
63 | 68 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; |
64 | 69 | import com.oracle.truffle.api.dsl.NodeFactory; |
65 | 70 | import com.oracle.truffle.api.dsl.Specialization; |
@@ -245,4 +250,52 @@ public boolean normalize(String form, PString unistr, |
245 | 250 | } |
246 | 251 | } |
247 | 252 | } |
| 253 | + |
| 254 | + // unicodedata.name(char, defaultValue) |
| 255 | + @Builtin(name = "name", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) |
| 256 | + @GenerateNodeFactory |
| 257 | + public abstract static class NameNode extends PythonBuiltinNode { |
| 258 | + |
| 259 | + @TruffleBoundary |
| 260 | + protected Object getName(String chr, Object defaultValue) { |
| 261 | + if (chr.codePointCount(0, chr.length()) != 1) { |
| 262 | + throw raise(TypeError, ErrorMessages.ARG_MUST_BE_UNICODE, "name()", 1, chr); |
| 263 | + } |
| 264 | + int cp = Character.codePointAt(chr, 0); |
| 265 | + if ((0xe000 <= cp && cp <= 0xf8ff) || (0xF0000 <= cp && cp <= 0xFFFFD) || (0x100000 <= cp && cp <= 0x10FFFD)) { |
| 266 | + // do not populate names from private use areas |
| 267 | + throw raise(ValueError, ErrorMessages.NO_SUCH_NAME); |
| 268 | + } |
| 269 | + String result = UCharacter.getName(cp); |
| 270 | + if (result == null) { |
| 271 | + if (defaultValue == PNone.NO_VALUE) { |
| 272 | + throw raise(ValueError, ErrorMessages.NO_SUCH_NAME); |
| 273 | + } |
| 274 | + return defaultValue; |
| 275 | + } |
| 276 | + return result; |
| 277 | + } |
| 278 | + |
| 279 | + @Specialization |
| 280 | + public Object name(String chr, Object defaultValue) { |
| 281 | + return getName(chr, defaultValue); |
| 282 | + } |
| 283 | + |
| 284 | + @Specialization |
| 285 | + public Object name(PString pchr, Object defaultValue, |
| 286 | + @Cached CastToJavaStringNode castToJavaStringNode) { |
| 287 | + String chr; |
| 288 | + try { |
| 289 | + chr = castToJavaStringNode.execute(pchr); |
| 290 | + } catch (CannotCastException e) { |
| 291 | + throw CompilerDirectives.shouldNotReachHere(e); |
| 292 | + } |
| 293 | + return getName(chr, defaultValue); |
| 294 | + } |
| 295 | + |
| 296 | + @Fallback |
| 297 | + public Object name(Object chr, @SuppressWarnings("unused") Object defaultValue) { |
| 298 | + throw raise(TypeError, ErrorMessages.ARG_MUST_BE_UNICODE, "name()", 1, chr); |
| 299 | + } |
| 300 | + } |
248 | 301 | } |
0 commit comments