From 115b38c4b004d337b7672ced9ea5efa09cc16d60 Mon Sep 17 00:00:00 2001 From: jnthn Date: Thu, 25 Apr 2013 14:58:02 +0200 Subject: [PATCH] Implement nqp::radix_I. --- src/vm/jvm/QAST/Compiler.nqp | 1 + .../runtime/org/perl6/nqp/runtime/Ops.java | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/vm/jvm/QAST/Compiler.nqp b/src/vm/jvm/QAST/Compiler.nqp index 55c82e503c..ea7c0e4a06 100644 --- a/src/vm/jvm/QAST/Compiler.nqp +++ b/src/vm/jvm/QAST/Compiler.nqp @@ -1580,6 +1580,7 @@ QAST::OperationsJAST.map_classlib_core_op('ln_n', $TYPE_MATH, 'log', [$RT_NUM], QAST::OperationsJAST.map_classlib_core_op('sqrt_n', $TYPE_MATH, 'sqrt', [$RT_NUM], $RT_NUM); QAST::OperationsJAST.map_classlib_core_op('exp_n', $TYPE_MATH, 'exp', [$RT_NUM], $RT_NUM); QAST::OperationsJAST.map_classlib_core_op('radix', $TYPE_OPS, 'radix', [$RT_INT, $RT_STR, $RT_INT, $RT_INT], $RT_OBJ, :tc); +QAST::OperationsJAST.map_classlib_core_op('radix_I', $TYPE_OPS, 'radix_I', [$RT_INT, $RT_STR, $RT_INT, $RT_INT, $RT_OBJ], $RT_OBJ, :tc); # trig opcodes QAST::OperationsJAST.map_classlib_core_op('sin_n', $TYPE_MATH, 'sin', [$RT_NUM], $RT_NUM); diff --git a/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java b/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java index 83624f54c1..f1a6076ddb 100644 --- a/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java +++ b/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java @@ -3395,6 +3395,59 @@ public static SixModelObject abs_I(SixModelObject a, SixModelObject type, Thread return makeBI(tc, type, getBI(tc, a).abs()); } + public static SixModelObject radix_I(long radix_l, String str, long zpos, long flags, SixModelObject type, ThreadContext tc) { + BigInteger zvalue = BigInteger.ZERO; + BigInteger zbase = BigInteger.ONE; + int chars = str.length(); + BigInteger value = zvalue; + BigInteger base = zbase; + long pos = -1; + char ch; + boolean neg = false; + BigInteger radix = BigInteger.valueOf(radix_l); + + if (radix_l > 36) { + throw ExceptionHandling.dieInternal(tc, "Cannot convert radix of " + radix_l + " (max 36)"); + } + + ch = (zpos < chars) ? str.charAt((int)zpos) : 0; + if ((flags & 0x02) != 0 && (ch == '+' || ch == '-')) { + neg = (ch == '-'); + zpos++; + ch = (zpos < chars) ? str.charAt((int)zpos) : 0; + } + while (zpos < chars) { + if (ch >= '0' && ch <= '9') ch = (char)(ch - '0'); + else if (ch >= 'a' && ch <= 'z') ch = (char)(ch - 'a' + 10); + else if (ch >= 'A' && ch <= 'Z') ch = (char)(ch - 'A' + 10); + else break; + if (ch >= radix_l) break; + zvalue = zvalue.multiply(radix).add(BigInteger.valueOf(ch)); + zbase = zbase.multiply(radix); + zpos++; pos = zpos; + if (ch != 0 || (flags & 0x04) == 0) { value=zvalue; base=zbase; } + if (zpos >= chars) break; + ch = str.charAt((int)zpos); + if (ch != '_') continue; + zpos++; + if (zpos >= chars) break; + ch = str.charAt((int)zpos); + } + + if (neg || (flags & 0x01) != 0) { value = value.negate(); } + + HLLConfig hllConfig = tc.curFrame.codeRef.staticInfo.compUnit.hllConfig; + SixModelObject result = hllConfig.slurpyArrayType.st.REPR.allocate(tc, + hllConfig.slurpyArrayType.st); + result.initialize(tc); + + result.push_boxed(tc, makeBI(tc, type, value)); + result.push_boxed(tc, makeBI(tc, type, base)); + result.push_boxed(tc, makeBI(tc, type, BigInteger.valueOf(pos))); + + return result; + } + public static SixModelObject bitor_I(SixModelObject a, SixModelObject b, SixModelObject type, ThreadContext tc) { return makeBI(tc, type, getBI(tc, a).or(getBI(tc, b))); }