From 8ec6da500c83b78035433f6bfb46a886a311063d Mon Sep 17 00:00:00 2001 From: "Flavio S. Glock" Date: Tue, 19 Jan 2016 15:23:44 +0100 Subject: [PATCH] Perlito5 - java - regex character class fixup - avoid double escape --- perlito5.pl | 8 ++++---- src5/lib/Perlito5/Java/Runtime.pm | 9 ++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/perlito5.pl b/perlito5.pl index 027dedab9..96ab0ed12 100644 --- a/perlito5.pl +++ b/perlito5.pl @@ -2,7 +2,7 @@ use v5.10; use feature 'say'; -# Do not edit this file - Generated by Perlito5 9.016 +# Do not edit this file - Generated by Perlito5 9.017 { package main; @@ -17371,7 +17371,7 @@ $a cmp $b } keys(%java_classes))) . 'class PlControlException extends RuntimeException {' . chr(10) . '}' . chr(10) . 'class PlNextException extends PlControlException {' . chr(10) . ' public int label_id;' . chr(10) . chr(10) . ' public PlNextException(int i) {' . chr(10) . ' this.label_id = i;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlLastException extends PlControlException {' . chr(10) . ' public int label_id;' . chr(10) . chr(10) . ' public PlLastException(int i) {' . chr(10) . ' this.label_id = i;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlRedoException extends PlControlException {' . chr(10) . ' public int label_id;' . chr(10) . chr(10) . ' public PlRedoException(int i) {' . chr(10) . ' this.label_id = i;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlReturnException extends PlControlException {' . chr(10) . ' public PlObject ret;' . chr(10) . chr(10) . ' public PlReturnException(PlObject ret) {' . chr(10) . ' this.ret = ret;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlDieException extends PlControlException {' . chr(10) . ' public PlObject ret;' . chr(10) . chr(10) . ' public PlDieException(PlObject ret) {' . chr(10) . ' this.ret = ret;' . chr(10) . ' }' . chr(10) . ' public String getMessage() {' . chr(10) . ' return this.ret.toString();' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlCx {' . chr(10) . ' public static final int VOID = 0;' . chr(10) . ' public static final int SCALAR = 1;' . chr(10) . ' public static final int LIST = 2;' . chr(10) . ' public static final PlUndef UNDEF = new PlUndef();' . chr(10) . ' public static final PlBool TRUE = new PlBool(true);' . chr(10) . ' public static final PlBool FALSE = new PlBool(false);' . chr(10) . ' public static final PlString STDOUT = new PlString("STDOUT");' . chr(10) . ' public static final PlString STDERR = new PlString("STDERR");' . chr(10) . ' public static final PlString STDIN = new PlString("STDIN");' . chr(10) . ' public static final PlString DIED = new PlString("Died");' . chr(10) . ' public static final PlString EMPTY = new PlString("");' . chr(10) . ' public static final String ARGV = "main::List_ARGV";' . chr(10) . ' public static final String ENV = "main::Hash_ENV";' . chr(10) . ' public static final PlNextException NEXT = new PlNextException(0);' . chr(10) . ' public static final PlLastException LAST = new PlLastException(0);' . chr(10) . chr(10) . ' ' . join(chr(10) . ' ', map { 'public static final PlInt ' . ($_ < 0 ? 'MIN' : 'INT') . abs($_) . ' = new PlInt(' . $_ . ');' - } (-2 .. 2)) . chr(10) . ' ' . join(chr(10) . ' ', @{$args{'java_constants'} // []}) . chr(10) . '}' . chr(10) . 'class PlCORE {' . chr(10) . ' public static final PlObject print(int want, PlObject filehandle, PlArray List__) {' . chr(10) . ' // TODO - write to filehandle' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' System.out.print(List__.aget(i).toString());' . chr(10) . ' }' . chr(10) . ' return PlCx.INT1;' . chr(10) . ' }' . chr(10) . ' public static final PlObject say(int want, PlObject filehandle, PlArray List__) {' . chr(10) . ' // TODO - write to filehandle' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' System.out.print(List__.aget(i).toString());' . chr(10) . ' }' . chr(10) . ' System.out.println("");' . chr(10) . ' return PlCx.INT1;' . chr(10) . ' }' . chr(10) . ' public static final PlObject say(String s) {' . chr(10) . ' // say() shortcut' . chr(10) . ' return PlCORE.say(PlCx.VOID, PlCx.STDOUT, new PlArray(new PlString(s)));' . chr(10) . ' }' . chr(10) . ' public static final PlObject exit(int want, PlArray List__) {' . chr(10) . ' int arg = List__.aget(0).to_int();' . chr(10) . ' System.exit(arg);' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' public static final PlObject warn(int want, PlArray List__) {' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' System.err.print(List__.aget(i).toString());' . chr(10) . ' }' . chr(10) . ' System.err.println("");' . chr(10) . ' return PlCx.INT1;' . chr(10) . ' }' . chr(10) . ' public static final PlObject die(int want, PlArray List__) {' . chr(10) . ' PlObject arg = List__.aget(0);' . chr(10) . ' if (arg.is_undef() || (arg.is_string() && arg.toString() == "")) {' . chr(10) . ' throw new PlDieException(PlCx.DIED);' . chr(10) . ' }' . chr(10) . ' if (List__.to_int() == 1) {' . chr(10) . ' throw new PlDieException(arg);' . chr(10) . ' }' . chr(10) . ' StringBuilder sb = new StringBuilder();' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' String item = List__.aget(i).toString();' . chr(10) . ' sb.append(item);' . chr(10) . ' }' . chr(10) . ' throw new PlDieException(new PlString(sb.toString()));' . chr(10) . ' }' . chr(10) . ' public static final PlObject die(String s) {' . chr(10) . ' // die() shortcut' . chr(10) . ' return PlCORE.die(PlCx.VOID, new PlArray(new PlString(s)));' . chr(10) . ' }' . chr(10) . ' public static final PlString ref(int want, PlArray List__) {' . chr(10) . ' return List__.aget(0).ref();' . chr(10) . ' }' . chr(10) . ' public static final PlObject values(int want, PlObject List__) {' . chr(10) . ' return want == PlCx.LIST ? List__.values() : List__.values().scalar();' . chr(10) . ' }' . chr(10) . ' public static final PlObject keys(int want, PlObject List__) {' . chr(10) . ' return want == PlCx.LIST ? List__.keys() : List__.keys().scalar();' . chr(10) . ' }' . chr(10) . ' public static final PlObject each(int want, PlObject List__) {' . chr(10) . ' return want == PlCx.LIST ? List__.each() : List__.each().aget(0);' . chr(10) . ' }' . chr(10) . ' public static final PlObject scalar(int want, PlArray List__) {' . chr(10) . ' if (List__.to_int() == 0) {' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' return List__.aget(-1).scalar();' . chr(10) . ' }' . chr(10) . ' public static final PlObject join(int want, PlArray List__) {' . chr(10) . ' String s = List__.shift().toString();' . chr(10) . ' StringBuilder sb = new StringBuilder();' . chr(10) . ' boolean first = true;' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' String item = List__.aget(i).toString();' . chr(10) . ' if (first)' . chr(10) . ' first = false;' . chr(10) . ' else' . chr(10) . ' sb.append(s);' . chr(10) . ' sb.append(item);' . chr(10) . ' }' . chr(10) . ' return new PlString(sb.toString());' . chr(10) . ' }' . chr(10) . ' public static final PlObject reverse(int want, PlArray List__) {' . chr(10) . ' if (want == PlCx.LIST) {' . chr(10) . ' PlArray ret = new PlArray(List__);' . chr(10) . ' Collections.reverse(ret.a);' . chr(10) . ' return ret;' . chr(10) . ' }' . chr(10) . ' StringBuilder sb = new StringBuilder();' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' sb.append( List__.aget(i).toString() );' . chr(10) . ' }' . chr(10) . ' return new PlString(sb.reverse().toString());' . chr(10) . ' }' . chr(10) . ' public static final PlObject time(int want, PlArray List__) {' . chr(10) . ' return new PlDouble( System.currentTimeMillis() * 0.001 );' . chr(10) . ' }' . chr(10) . ' public static final PlObject sleep(int want, PlArray List__) {' . chr(10) . ' long s = (new Double(List__.shift().to_double() * 1000)).longValue();' . chr(10) . ' try {' . chr(10) . ' TimeUnit.MILLISECONDS.sleep(s);' . chr(10) . ' } catch (InterruptedException e) {' . chr(10) . ' //Handle exception' . chr(10) . ' }' . chr(10) . ' return new PlDouble(s / 1000.0);' . chr(10) . ' }' . chr(10) . ' public static final PlObject system(int want, PlArray List__) {' . chr(10) . ' // TODO - see perldoc -f system' . chr(10) . ' try {' . chr(10) . ' String[] args = new String[List__.to_int()];' . chr(10) . ' int i = 0;' . chr(10) . ' for (PlObject s : List__.a) {' . chr(10) . ' args[i++] = s.toString();' . chr(10) . ' }' . chr(10) . ' String s = null;' . chr(10) . ' Process p = Runtime.getRuntime().exec(args);' . chr(10) . ' // BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));' . chr(10) . ' // BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));' . chr(10) . ' // System.out.println("STDOUT' . chr(92) . 'n");' . chr(10) . ' // while ((s = stdInput.readLine()) != null) {' . chr(10) . ' // System.out.println(" " + s);' . chr(10) . ' // }' . chr(10) . ' // System.out.println("STDERR' . chr(92) . 'n");' . chr(10) . ' // while ((s = stdError.readLine()) != null) {' . chr(10) . ' // System.out.println(" " + s);' . chr(10) . ' // }' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' catch (IOException e) {' . chr(10) . ' // System.out.println("IOexception: ");' . chr(10) . ' // e.printStackTrace();' . chr(10) . ' return PlCx.MIN1;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject qx(int want, PlArray List__) {' . chr(10) . ' // TODO - see perldoc -f qx' . chr(10) . ' try {' . chr(10) . ' String[] args = new String[List__.to_int()];' . chr(10) . ' int i = 0;' . chr(10) . ' for (PlObject s : List__.a) {' . chr(10) . ' args[i++] = s.toString();' . chr(10) . ' }' . chr(10) . ' PlArray res = new PlArray();' . chr(10) . ' String s = null;' . chr(10) . ' Process p = Runtime.getRuntime().exec(args);' . chr(10) . ' BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));' . chr(10) . ' System.out.println("STDOUT' . chr(92) . 'n");' . chr(10) . ' while ((s = stdInput.readLine()) != null) {' . chr(10) . ' // System.out.println(" " + s);' . chr(10) . ' res.push(s + "' . chr(92) . 'n");' . chr(10) . ' }' . chr(10) . ' // BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));' . chr(10) . ' // System.out.println("STDERR' . chr(92) . 'n");' . chr(10) . ' // while ((s = stdError.readLine()) != null) {' . chr(10) . ' // System.out.println(" " + s);' . chr(10) . ' // }' . chr(10) . ' if (want == PlCx.LIST) {' . chr(10) . ' return res;' . chr(10) . ' }' . chr(10) . ' res.unshift(PlCx.EMPTY);' . chr(10) . ' return join(want, res);' . chr(10) . ' }' . chr(10) . ' catch (IOException e) {' . chr(10) . ' // System.out.println("IOexception: ");' . chr(10) . ' // e.printStackTrace();' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PerlCompare implements Comparator {' . chr(10) . ' public PlClosure sorter;' . chr(10) . ' public PlLvalue v_a;' . chr(10) . ' public PlLvalue v_b;' . chr(10) . ' public PerlCompare (PlClosure sorter, PlLvalue a, PlLvalue b) {' . chr(10) . ' this.sorter = sorter;' . chr(10) . ' this.v_a = a;' . chr(10) . ' this.v_b = b;' . chr(10) . ' }' . chr(10) . ' public int compare (PlObject a, PlObject b) {' . chr(10) . ' v_a.set(a);' . chr(10) . ' v_b.set(b);' . chr(10) . ' return this.sorter.apply( PlCx.SCALAR, new PlArray() ).to_int();' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PerlOp {' . chr(10) . ' // PerlOp implements operators: && || ' . chr(10) . ' // and auxiliary functions' . chr(10) . ' //' . chr(10) . ' // note: ' . chr(39) . '+' . chr(39) . ' add() and ' . chr(39) . '-' . chr(39) . ' sub() are PlObject methods, not implemented here.' . chr(10) . ' //' . chr(10) . ' // TODO - see Perlito5/Javascript2/Runtime.pm for more operator implementations' . chr(10) . ' // TODO - ' . chr(39) . 'boolean_stack' . chr(39) . ' should be reset when an exception happens' . chr(10) . chr(10) . ' private static ArrayList boolean_stack = new ArrayList();' . chr(10) . ' private static PlArray local_stack = new PlArray();' . chr(10) . ' private static Random random = new Random();' . chr(10) . chr(10) . ' // objects' . chr(10) . ' // coderef methods can be called on ANY invocant' . chr(10) . ' // $m = sub {...};' . chr(10) . ' // $a->$m' . chr(10) . ' public static final PlObject call( PlObject invocant, PlObject method, PlArray args, int context ) {' . chr(10) . ' if ( method.is_coderef() ) {' . chr(10) . ' args.unshift(invocant);' . chr(10) . ' return method.apply(context, args);' . chr(10) . ' }' . chr(10) . ' else if ( method.is_lvalue() ) {' . chr(10) . ' return call( invocant, method.get(), args, context );' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return call( invocant, method.toString(), args, context );' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject call( String invocant, PlObject method, PlArray args, int context ) {' . chr(10) . ' if ( method.is_coderef() ) {' . chr(10) . ' args.unshift( new PlString(invocant) );' . chr(10) . ' return method.apply(context, args);' . chr(10) . ' }' . chr(10) . ' else if ( method.is_lvalue() ) {' . chr(10) . ' return call( invocant, method.get(), args, context );' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return call( invocant, method.toString(), args, context );' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' // Intermediate calls, which have to be dispatched properly' . chr(10) . ' public static final PlObject call( PlObject invocant, String method, PlArray args, int context ) {' . chr(10) . ' if ( invocant.is_undef() ) {' . chr(10) . ' PlCORE.die( "Can' . chr(39) . 't call method ' . chr(92) . '"" + method' . chr(10) . ' + "' . chr(92) . '" on an undefined value" );' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . chr(10) . ' if ( invocant.is_lvalue() ) {' . chr(10) . ' invocant = invocant.get();' . chr(10) . ' }' . chr(10) . chr(10) . ' PlClass pClass = invocant.blessed();' . chr(10) . chr(10) . ' if ( pClass == null ) {' . chr(10) . ' PlCORE.die( "Can' . chr(39) . 't call method ' . chr(92) . '"" + method' . chr(10) . ' + "' . chr(92) . '" on unblessed reference" );' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return call( pClass.className().toString(), method, args, context );' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject call( String invocant, String method, PlArray args, int context ) {' . chr(10) . ' if ( invocant.equals("") ) {' . chr(10) . ' PlCORE.die( "Can' . chr(39) . 't call method ' . chr(92) . '"" + method' . chr(10) . ' + "' . chr(92) . '" on an undefined value" );' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . chr(10) . ' PlObject methodCode = PlV.get(invocant + "::" + method);' . chr(10) . chr(10) . ' if (methodCode.is_undef()) {' . chr(10) . ' PlCORE.die( "Can' . chr(39) . 't locate object method ' . chr(92) . '"" + method' . chr(10) . ' + "' . chr(92) . '" via package ' . chr(92) . '"" + invocant' . chr(10) . ' + "' . chr(92) . '" (perhaps you forgot to load ' . chr(92) . '"" + invocant + "' . chr(92) . '"?" );' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . chr(10) . ' args.unshift( new PlString(invocant) );' . chr(10) . ' return methodCode.apply(context, args);' . chr(10) . ' }' . chr(10) . chr(10) . ' // local()' . chr(10) . ' public static final PlObject push_local(PlHash container, String index) {' . chr(10) . ' local_stack.a.add(container);' . chr(10) . ' local_stack.a.add(new PlString(index));' . chr(10) . ' PlLvalue empty = new PlLvalue();' . chr(10) . ' local_stack.a.add(container.hget_lvalue(index));' . chr(10) . ' container.h.put(index, empty);' . chr(10) . ' return empty;' . chr(10) . ' }' . chr(10) . ' public static final PlObject push_local(PlArray container, int index) {' . chr(10) . ' local_stack.a.add(container);' . chr(10) . ' local_stack.a.add(new PlInt(index));' . chr(10) . ' PlLvalue empty = new PlLvalue();' . chr(10) . ' local_stack.a.add(container.aget_lvalue(index));' . chr(10) . ' container.aset(index, empty);' . chr(10) . ' return empty;' . chr(10) . ' }' . chr(10) . ' public static final int local_length() {' . chr(10) . ' return local_stack.to_int();' . chr(10) . ' }' . chr(10) . ' public static final PlObject cleanup_local(int pos, PlObject ret) {' . chr(10) . ' while (local_stack.to_int() > pos) {' . chr(10) . ' PlLvalue lvalue = (PlLvalue)local_stack.pop();' . chr(10) . ' PlObject index = local_stack.pop();' . chr(10) . ' PlObject container = local_stack.pop();' . chr(10) . ' if (container.is_array()) {' . chr(10) . ' ((PlArray)container).a.set(index.to_int(), lvalue);' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' ((PlHash)container).h.put(index.toString(), lvalue);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return ret;' . chr(10) . ' }' . chr(10) . chr(10) . ' // context()' . chr(10) . ' // - handles run-time scalar/list/void context in expression results' . chr(10) . ' public static final PlObject context(int want, PlObject arg) {' . chr(10) . ' if (want == PlCx.LIST) {' . chr(10) . ' return arg;' . chr(10) . ' }' . chr(10) . ' return arg.scalar();' . chr(10) . ' }' . chr(10) . ' public static final PlObject context(int want) {' . chr(10) . ' if (want == PlCx.LIST) {' . chr(10) . ' return new PlArray();' . chr(10) . ' }' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' public static final PlObject context(int want, PlObject... args) {' . chr(10) . ' if (want == PlCx.LIST) {' . chr(10) . ' return new PlArray(args);' . chr(10) . ' }' . chr(10) . ' return args[args.length-1].scalar();' . chr(10) . ' }' . chr(10) . chr(10) . ' // statement()' . chr(10) . ' // - workaround for "Error: not a statement"' . chr(10) . ' // - this is the compile-time version of context(null, arg)' . chr(10) . ' public static final void statement(PlObject arg) { }' . chr(10) . ' public static final void statement() { }' . chr(10) . chr(10) . ' // control-flow exceptions' . chr(10) . ' public static final PlObject next() {' . chr(10) . ' throw PlCx.NEXT;' . chr(10) . ' }' . chr(10) . ' public static final PlObject next(int label_id) {' . chr(10) . ' throw new PlNextException(label_id);' . chr(10) . ' }' . chr(10) . ' public static final PlObject last() {' . chr(10) . ' throw PlCx.LAST;' . chr(10) . ' }' . chr(10) . ' public static final PlObject last(int label_id) {' . chr(10) . ' throw new PlLastException(label_id);' . chr(10) . ' }' . chr(10) . ' public static final PlObject redo(int label_id) {' . chr(10) . ' throw new PlRedoException(label_id);' . chr(10) . ' }' . chr(10) . ' public static final PlObject ret(PlObject ret) {' . chr(10) . ' throw new PlReturnException(ret);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject caller(int ctx, PlObject s) {' . chr(10) . ' int item = s.to_int();' . chr(10) . ' PlCORE.die("caller() not implemented");' . chr(10) . ' return null;' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject srand() {' . chr(10) . ' random = new Random();' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' public static final PlObject srand(int s) {' . chr(10) . ' random = new Random(s);' . chr(10) . ' return new PlInt(s);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject rand(double s) {' . chr(10) . ' if (s == 0.0) {' . chr(10) . ' s = 1.0;' . chr(10) . ' }' . chr(10) . ' return new PlDouble(s * random.nextDouble());' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final long[] range(PlObject _start, PlObject _end, int ctx, String var, int ignore) {' . chr(10) . ' if (ctx == PlCx.LIST) {' . chr(10) . ' long start = _start.to_long(),' . chr(10) . ' end = _end.to_long();' . chr(10) . ' int size = Math.max(0, (int)(end - start + 1));' . chr(10) . ' long[] ret = new long[size];' . chr(10) . ' for (int i = 0; i < size; ++i) {' . chr(10) . ' ret[i] = start + i;' . chr(10) . ' }' . chr(10) . ' return ret;' . chr(10) . ' }' . chr(10) . ' PlCORE.die("Range not implemented for context " + ctx);' . chr(10) . ' return null;' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject smartmatch_scalar(PlObject arg0, PlObject arg1) {' . chr(10) . ' if (arg1.is_undef()) {' . chr(10) . ' return arg0.is_undef() ? PlCx.TRUE : PlCx.FALSE;' . chr(10) . ' }' . chr(10) . ' if (arg1.is_string()) {' . chr(10) . ' return arg0.str_eq(arg1);' . chr(10) . ' }' . chr(10) . ' if (arg1.is_num() || arg1.is_int()) {' . chr(10) . ' return arg0.num_eq(arg1);' . chr(10) . ' }' . chr(10) . ' return PlCORE.die(PlCx.VOID, new PlArray(new PlString("Not implemented: smartmatch operator with argument type ' . chr(39) . '"), PlCORE.ref(PlCx.SCALAR, new PlArray(arg1)), new PlString("' . chr(39) . '")));' . chr(10) . ' }' . chr(10) . chr(10) . ' // and1(x) ? y : and3()' . chr(10) . ' public static final boolean and1(PlObject arg1) {' . chr(10) . ' if (arg1.to_bool()) {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' boolean_stack.add(0, arg1);' . chr(10) . ' return false;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject and3() {' . chr(10) . ' return boolean_stack.remove(0);' . chr(10) . ' }' . chr(10) . chr(10) . ' // or1(x) ? or2() : y' . chr(10) . ' public static final boolean or1(PlObject arg1) {' . chr(10) . ' if (arg1.to_bool()) {' . chr(10) . ' boolean_stack.add(0, arg1);' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return false;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject or2() {' . chr(10) . ' return boolean_stack.remove(0);' . chr(10) . ' }' . chr(10) . chr(10) . ' // defined_or1(x) ? defined_or2() : y' . chr(10) . ' public static final boolean defined_or1(PlObject arg1) {' . chr(10) . ' if (!arg1.is_undef()) {' . chr(10) . ' boolean_stack.add(0, arg1);' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return false;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject defined_or2() {' . chr(10) . ' return boolean_stack.remove(0);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlInt ord(PlString s) {' . chr(10) . ' String item = s.toString();' . chr(10) . ' return new PlInt(item.length() > 0 ? Character.codePointAt(item, 0) : 0);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlString string_replicate(PlObject s, PlObject c) {' . chr(10) . ' int count = c.to_int();' . chr(10) . ' if ( count < 1 ) {' . chr(10) . ' return new PlString("");' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' String raw_s = s.toString();' . chr(10) . ' StringBuilder sb = new StringBuilder();' . chr(10) . ' for (int i = 0; i < count; i++) {' . chr(10) . ' sb.append(raw_s);' . chr(10) . ' }' . chr(10) . ' return new PlString(sb.toString());' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject list_replicate(PlArray o, PlObject c, int wantarray) {' . chr(10) . ' int count = c.to_int();' . chr(10) . ' PlArray a = new PlArray();' . chr(10) . ' if (count > 0) {' . chr(10) . ' for (int i = 0; i < count; i++) {' . chr(10) . ' a.push( o );' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return (wantarray == PlCx.LIST ) ? a : a.length_of_array();' . chr(10) . ' }' . chr(10) . ' public static final PlObject grep(PlClosure c, PlArray a, int wantarray) {' . chr(10) . ' PlArray ret = new PlArray();' . chr(10) . ' int size = a.to_int();' . chr(10) . ' PlLvalue v__ref = (PlLvalue)PlV.get("main::v__");' . chr(10) . ' PlObject v__val = v__ref.get();' . chr(10) . ' for (int i = 0; i < size; i++) {' . chr(10) . ' boolean result;' . chr(10) . ' PlObject temp = a.aget(i);' . chr(10) . ' v__ref.set(temp);' . chr(10) . ' result = c.apply(PlCx.SCALAR, new PlArray()).to_bool();' . chr(10) . ' if (result) {' . chr(10) . ' ret.push(temp);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' v__ref.set(v__val);' . chr(10) . ' return (wantarray == PlCx.LIST ) ? ret : ret.length_of_array();' . chr(10) . ' }' . chr(10) . ' public static final PlObject map(PlClosure c, PlArray a, int wantarray) {' . chr(10) . ' PlArray ret = new PlArray();' . chr(10) . ' int size = a.to_int();' . chr(10) . ' PlLvalue v__ref = (PlLvalue)PlV.get("main::v__");' . chr(10) . ' PlObject v__val = v__ref.get();' . chr(10) . ' for (int i = 0; i < size; i++) {' . chr(10) . ' v__ref.set(a.aget(i));' . chr(10) . ' ret.push(c.apply(PlCx.LIST, new PlArray()));' . chr(10) . ' }' . chr(10) . ' v__ref.set(v__val);' . chr(10) . ' return (wantarray == PlCx.LIST ) ? ret : ret.length_of_array();' . chr(10) . ' }' . chr(10) . ' public static final PlObject sort(PlClosure c, PlArray a, int wantarray, String pckg) {' . chr(10) . ' PlArray ret = new PlArray(a);' . chr(10) . ' int size = a.to_int();' . chr(10) . ' PlLvalue v_a_ref = (PlLvalue)PlV.get(pckg + "::v_a");' . chr(10) . ' PlLvalue v_b_ref = (PlLvalue)PlV.get(pckg + "::v_b");' . chr(10) . ' PerlCompare comp = new PerlCompare(c, v_a_ref, v_b_ref);' . chr(10) . ' PlObject v_a_val = v_a_ref.get();' . chr(10) . ' PlObject v_b_val = v_b_ref.get();' . chr(10) . ' Collections.sort(ret.a, comp);' . chr(10) . ' v_a_ref.set(v_a_val);' . chr(10) . ' v_b_ref.set(v_b_val);' . chr(10) . ' return (wantarray == PlCx.LIST ) ? ret : ret.length_of_array();' . chr(10) . ' }' . chr(10) . chr(10) . ' private static String double_escape(String s) {' . chr(10) . ' // add double escapes: ' . chr(92) . chr(92) . 'w instead of ' . chr(92) . 'w' . chr(10) . ' return s.replace("' . chr(92) . chr(92) . '", "' . chr(92) . chr(92) . chr(92) . chr(92) . '");' . chr(10) . ' }' . chr(10) . chr(10) . ' private static int _character_class_escape(int offset, String s, StringBuilder sb, int length) {' . chr(10) . ' // [ ... ]' . chr(10) . ' int offset3 = offset;' . chr(10) . ' for ( ; offset3 < length; ) {' . chr(10) . ' final int c3 = s.codePointAt(offset3);' . chr(10) . ' switch (c3) {' . chr(10) . ' case ' . chr(39) . ']' . chr(39) . ':' . chr(10) . ' sb.append(Character.toChars(c3));' . chr(10) . ' return offset3;' . chr(10) . ' case ' . chr(39) . ' ' . chr(39) . ':' . chr(10) . ' sb.append("' . chr(92) . chr(92) . ' "); // make this space a "token", even inside /x' . chr(10) . ' break;' . chr(10) . ' default:' . chr(10) . ' sb.append(Character.toChars(c3));' . chr(10) . ' break;' . chr(10) . ' }' . chr(10) . ' offset3++;' . chr(10) . ' }' . chr(10) . ' return offset3;' . chr(10) . ' }' . chr(10) . chr(10) . ' public static String character_class_escape(String s) {' . chr(10) . ' // escape spaces in character classes' . chr(10) . ' final int length = s.length();' . chr(10) . ' StringBuilder sb = new StringBuilder();' . chr(10) . ' for (int offset = 0; offset < length; ) {' . chr(10) . ' final int c = s.codePointAt(offset);' . chr(10) . ' switch (c) {' . chr(10) . ' case ' . chr(39) . chr(92) . chr(92) . chr(39) . ': // escape - ' . chr(92) . '[' . chr(10) . ' sb.append(Character.toChars(c));' . chr(10) . ' if (offset < length) {' . chr(10) . ' offset++;' . chr(10) . ' int c2 = s.codePointAt(offset);' . chr(10) . ' sb.append(Character.toChars(c2));' . chr(10) . ' }' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . '[' . chr(39) . ': // character class' . chr(10) . ' sb.append(Character.toChars(c));' . chr(10) . ' offset++;' . chr(10) . ' offset = _character_class_escape(offset, s, sb, length);' . chr(10) . ' break;' . chr(10) . ' default: // normal char' . chr(10) . ' sb.append(Character.toChars(c));' . chr(10) . ' break;' . chr(10) . ' }' . chr(10) . ' offset++;' . chr(10) . ' }' . chr(10) . ' return sb.toString();' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject match(PlObject s, PlRegex pat, int want) {' . chr(10) . ' if (want != PlCx.LIST) {' . chr(10) . ' return pat.p.matcher(s.toString()).find() ? PlCx.TRUE : PlCx.FALSE;' . chr(10) . ' }' . chr(10) . ' PlArray ret = new PlArray();' . chr(10) . ' Matcher matcher = pat.p.matcher(s.toString());' . chr(10) . ' while (matcher.find()) {' . chr(10) . ' for (int i = 1; i <= matcher.groupCount(); i++) {' . chr(10) . ' ret.push(matcher.group(i));' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return ret;' . chr(10) . ' }' . chr(10) . ' public static final PlObject match(PlObject s, PlLvalue pat, int want) {' . chr(10) . ' return match(s, pat.get(), want);' . chr(10) . ' }' . chr(10) . ' public static final PlObject match(PlObject s, PlObject pat, int want) {' . chr(10) . ' // TODO - cache the compiled pattern' . chr(10) . ' return match(s, new PlRegex(pat, 0), want);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject replace(PlLvalue s, PlRegex pat, PlObject rep, int want) {' . chr(10) . ' if (want != PlCx.LIST) {' . chr(10) . ' return s.set(new PlString(pat.p.matcher(s.toString()).replaceAll(double_escape(rep.toString()))));' . chr(10) . ' }' . chr(10) . ' PlCORE.die("not implemented string replace in list context");' . chr(10) . ' return s;' . chr(10) . ' }' . chr(10) . ' public static final PlObject replace(PlObject s, PlObject pat, PlObject rep, int want) {' . chr(10) . ' // TODO - cache the compiled pattern' . chr(10) . ' return replace(s, new PlRegex(pat, 0), rep, want);' . chr(10) . ' }' . chr(10) . chr(10) . '}' . chr(10) . 'class PlV {' . chr(10) . ' // PlV implements namespaces and global variables' . chr(10) . ' //' . chr(10) . ' // TODO - import CORE subroutines in new namespaces, if needed' . chr(10) . ' // TODO - cache lookups in lexical variables (see PlClosure implementation)' . chr(10) . chr(10) . ' public static final PlHash var = new PlHash();' . chr(10) . chr(10) . ' public static final PlLvalue get(String name) {' . chr(10) . ' return (PlLvalue)var.hget_lvalue(name);' . chr(10) . ' }' . chr(10) . ' public static final PlLvalue get_local(String name) {' . chr(10) . ' return (PlLvalue)var.hget_lvalue_local(name);' . chr(10) . ' }' . chr(10) . ' public static final PlObject set(String name, PlObject v) {' . chr(10) . ' return var.hset(name, v);' . chr(10) . ' }' . chr(10) . ' public static final PlObject set_local(String name, PlObject v) {' . chr(10) . ' return var.hget_lvalue_local(name).set(v);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlHash hash_get(String name) {' . chr(10) . ' return (PlHash)var.hget_hashref(name).get();' . chr(10) . ' }' . chr(10) . ' public static final PlHash hash_get_local(String name) {' . chr(10) . ' return (PlHash)var.hget_lvalue_local(name).get_hashref().get();' . chr(10) . ' }' . chr(10) . ' public static final PlObject hash_set(String name, PlObject v) {' . chr(10) . ' return var.hget_hashref(name).hash_deref_set(v);' . chr(10) . ' }' . chr(10) . ' public static final PlObject hash_set_local(String name, PlObject v) {' . chr(10) . ' return var.hget_lvalue_local(name).get_hashref().hash_deref_set(v);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlArray array_get(String name) {' . chr(10) . ' return (PlArray)var.hget_arrayref(name).get();' . chr(10) . ' }' . chr(10) . ' public static final PlArray array_get_local(String name) {' . chr(10) . ' return (PlArray)var.hget_lvalue_local(name).get_arrayref().get();' . chr(10) . ' }' . chr(10) . ' public static final PlObject array_set(String name, PlObject v) {' . chr(10) . ' return var.hget_arrayref(name).array_deref_set(v);' . chr(10) . ' }' . chr(10) . ' public static final PlObject array_set_local(String name, PlObject v) {' . chr(10) . ' return var.hget_lvalue_local(name).get_arrayref().array_deref_set(v);' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlEnv {' . chr(10) . ' public static final void init(String[] args) {' . chr(10) . ' PlV.array_set(PlCx.ARGV, new PlArray(args)); // args is String[]' . chr(10) . ' PlV.hash_set(PlCx.ENV, new PlArray(System.getenv())); // env is Map' . chr(10) . ' PlV.set("main::v_" + (char)34, new PlString(" ")); // $" = " "' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlObject {' . chr(10) . ' public static final PlString REF = new PlString("");' . chr(10) . chr(10) . ' public PlObject() {' . chr(10) . ' }' . chr(10) . join('', (map { + } (-2 .. 2)) . chr(10) . ' ' . join(chr(10) . ' ', @{$args{'java_constants'} // []}) . chr(10) . '}' . chr(10) . 'class PlCORE {' . chr(10) . ' public static final PlObject print(int want, PlObject filehandle, PlArray List__) {' . chr(10) . ' // TODO - write to filehandle' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' System.out.print(List__.aget(i).toString());' . chr(10) . ' }' . chr(10) . ' return PlCx.INT1;' . chr(10) . ' }' . chr(10) . ' public static final PlObject say(int want, PlObject filehandle, PlArray List__) {' . chr(10) . ' // TODO - write to filehandle' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' System.out.print(List__.aget(i).toString());' . chr(10) . ' }' . chr(10) . ' System.out.println("");' . chr(10) . ' return PlCx.INT1;' . chr(10) . ' }' . chr(10) . ' public static final PlObject say(String s) {' . chr(10) . ' // say() shortcut' . chr(10) . ' return PlCORE.say(PlCx.VOID, PlCx.STDOUT, new PlArray(new PlString(s)));' . chr(10) . ' }' . chr(10) . ' public static final PlObject exit(int want, PlArray List__) {' . chr(10) . ' int arg = List__.aget(0).to_int();' . chr(10) . ' System.exit(arg);' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' public static final PlObject warn(int want, PlArray List__) {' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' System.err.print(List__.aget(i).toString());' . chr(10) . ' }' . chr(10) . ' System.err.println("");' . chr(10) . ' return PlCx.INT1;' . chr(10) . ' }' . chr(10) . ' public static final PlObject die(int want, PlArray List__) {' . chr(10) . ' PlObject arg = List__.aget(0);' . chr(10) . ' if (arg.is_undef() || (arg.is_string() && arg.toString() == "")) {' . chr(10) . ' throw new PlDieException(PlCx.DIED);' . chr(10) . ' }' . chr(10) . ' if (List__.to_int() == 1) {' . chr(10) . ' throw new PlDieException(arg);' . chr(10) . ' }' . chr(10) . ' StringBuilder sb = new StringBuilder();' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' String item = List__.aget(i).toString();' . chr(10) . ' sb.append(item);' . chr(10) . ' }' . chr(10) . ' throw new PlDieException(new PlString(sb.toString()));' . chr(10) . ' }' . chr(10) . ' public static final PlObject die(String s) {' . chr(10) . ' // die() shortcut' . chr(10) . ' return PlCORE.die(PlCx.VOID, new PlArray(new PlString(s)));' . chr(10) . ' }' . chr(10) . ' public static final PlString ref(int want, PlArray List__) {' . chr(10) . ' return List__.aget(0).ref();' . chr(10) . ' }' . chr(10) . ' public static final PlObject values(int want, PlObject List__) {' . chr(10) . ' return want == PlCx.LIST ? List__.values() : List__.values().scalar();' . chr(10) . ' }' . chr(10) . ' public static final PlObject keys(int want, PlObject List__) {' . chr(10) . ' return want == PlCx.LIST ? List__.keys() : List__.keys().scalar();' . chr(10) . ' }' . chr(10) . ' public static final PlObject each(int want, PlObject List__) {' . chr(10) . ' return want == PlCx.LIST ? List__.each() : List__.each().aget(0);' . chr(10) . ' }' . chr(10) . ' public static final PlObject scalar(int want, PlArray List__) {' . chr(10) . ' if (List__.to_int() == 0) {' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' return List__.aget(-1).scalar();' . chr(10) . ' }' . chr(10) . ' public static final PlObject join(int want, PlArray List__) {' . chr(10) . ' String s = List__.shift().toString();' . chr(10) . ' StringBuilder sb = new StringBuilder();' . chr(10) . ' boolean first = true;' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' String item = List__.aget(i).toString();' . chr(10) . ' if (first)' . chr(10) . ' first = false;' . chr(10) . ' else' . chr(10) . ' sb.append(s);' . chr(10) . ' sb.append(item);' . chr(10) . ' }' . chr(10) . ' return new PlString(sb.toString());' . chr(10) . ' }' . chr(10) . ' public static final PlObject reverse(int want, PlArray List__) {' . chr(10) . ' if (want == PlCx.LIST) {' . chr(10) . ' PlArray ret = new PlArray(List__);' . chr(10) . ' Collections.reverse(ret.a);' . chr(10) . ' return ret;' . chr(10) . ' }' . chr(10) . ' StringBuilder sb = new StringBuilder();' . chr(10) . ' for (int i = 0; i < List__.to_int(); i++) {' . chr(10) . ' sb.append( List__.aget(i).toString() );' . chr(10) . ' }' . chr(10) . ' return new PlString(sb.reverse().toString());' . chr(10) . ' }' . chr(10) . ' public static final PlObject time(int want, PlArray List__) {' . chr(10) . ' return new PlDouble( System.currentTimeMillis() * 0.001 );' . chr(10) . ' }' . chr(10) . ' public static final PlObject sleep(int want, PlArray List__) {' . chr(10) . ' long s = (new Double(List__.shift().to_double() * 1000)).longValue();' . chr(10) . ' try {' . chr(10) . ' TimeUnit.MILLISECONDS.sleep(s);' . chr(10) . ' } catch (InterruptedException e) {' . chr(10) . ' //Handle exception' . chr(10) . ' }' . chr(10) . ' return new PlDouble(s / 1000.0);' . chr(10) . ' }' . chr(10) . ' public static final PlObject system(int want, PlArray List__) {' . chr(10) . ' // TODO - see perldoc -f system' . chr(10) . ' try {' . chr(10) . ' String[] args = new String[List__.to_int()];' . chr(10) . ' int i = 0;' . chr(10) . ' for (PlObject s : List__.a) {' . chr(10) . ' args[i++] = s.toString();' . chr(10) . ' }' . chr(10) . ' String s = null;' . chr(10) . ' Process p = Runtime.getRuntime().exec(args);' . chr(10) . ' // BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));' . chr(10) . ' // BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));' . chr(10) . ' // System.out.println("STDOUT' . chr(92) . 'n");' . chr(10) . ' // while ((s = stdInput.readLine()) != null) {' . chr(10) . ' // System.out.println(" " + s);' . chr(10) . ' // }' . chr(10) . ' // System.out.println("STDERR' . chr(92) . 'n");' . chr(10) . ' // while ((s = stdError.readLine()) != null) {' . chr(10) . ' // System.out.println(" " + s);' . chr(10) . ' // }' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' catch (IOException e) {' . chr(10) . ' // System.out.println("IOexception: ");' . chr(10) . ' // e.printStackTrace();' . chr(10) . ' return PlCx.MIN1;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject qx(int want, PlArray List__) {' . chr(10) . ' // TODO - see perldoc -f qx' . chr(10) . ' try {' . chr(10) . ' String[] args = new String[List__.to_int()];' . chr(10) . ' int i = 0;' . chr(10) . ' for (PlObject s : List__.a) {' . chr(10) . ' args[i++] = s.toString();' . chr(10) . ' }' . chr(10) . ' PlArray res = new PlArray();' . chr(10) . ' String s = null;' . chr(10) . ' Process p = Runtime.getRuntime().exec(args);' . chr(10) . ' BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));' . chr(10) . ' System.out.println("STDOUT' . chr(92) . 'n");' . chr(10) . ' while ((s = stdInput.readLine()) != null) {' . chr(10) . ' // System.out.println(" " + s);' . chr(10) . ' res.push(s + "' . chr(92) . 'n");' . chr(10) . ' }' . chr(10) . ' // BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));' . chr(10) . ' // System.out.println("STDERR' . chr(92) . 'n");' . chr(10) . ' // while ((s = stdError.readLine()) != null) {' . chr(10) . ' // System.out.println(" " + s);' . chr(10) . ' // }' . chr(10) . ' if (want == PlCx.LIST) {' . chr(10) . ' return res;' . chr(10) . ' }' . chr(10) . ' res.unshift(PlCx.EMPTY);' . chr(10) . ' return join(want, res);' . chr(10) . ' }' . chr(10) . ' catch (IOException e) {' . chr(10) . ' // System.out.println("IOexception: ");' . chr(10) . ' // e.printStackTrace();' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PerlCompare implements Comparator {' . chr(10) . ' public PlClosure sorter;' . chr(10) . ' public PlLvalue v_a;' . chr(10) . ' public PlLvalue v_b;' . chr(10) . ' public PerlCompare (PlClosure sorter, PlLvalue a, PlLvalue b) {' . chr(10) . ' this.sorter = sorter;' . chr(10) . ' this.v_a = a;' . chr(10) . ' this.v_b = b;' . chr(10) . ' }' . chr(10) . ' public int compare (PlObject a, PlObject b) {' . chr(10) . ' v_a.set(a);' . chr(10) . ' v_b.set(b);' . chr(10) . ' return this.sorter.apply( PlCx.SCALAR, new PlArray() ).to_int();' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PerlOp {' . chr(10) . ' // PerlOp implements operators: && ||' . chr(10) . ' // and auxiliary functions' . chr(10) . ' //' . chr(10) . ' // note: ' . chr(39) . '+' . chr(39) . ' add() and ' . chr(39) . '-' . chr(39) . ' sub() are PlObject methods, not implemented here.' . chr(10) . ' //' . chr(10) . ' // TODO - see Perlito5/Javascript2/Runtime.pm for more operator implementations' . chr(10) . ' // TODO - ' . chr(39) . 'boolean_stack' . chr(39) . ' should be reset when an exception happens' . chr(10) . chr(10) . ' private static ArrayList boolean_stack = new ArrayList();' . chr(10) . ' private static PlArray local_stack = new PlArray();' . chr(10) . ' private static Random random = new Random();' . chr(10) . chr(10) . ' // objects' . chr(10) . ' // coderef methods can be called on ANY invocant' . chr(10) . ' // $m = sub {...};' . chr(10) . ' // $a->$m' . chr(10) . ' public static final PlObject call( PlObject invocant, PlObject method, PlArray args, int context ) {' . chr(10) . ' if ( method.is_coderef() ) {' . chr(10) . ' args.unshift(invocant);' . chr(10) . ' return method.apply(context, args);' . chr(10) . ' }' . chr(10) . ' else if ( method.is_lvalue() ) {' . chr(10) . ' return call( invocant, method.get(), args, context );' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return call( invocant, method.toString(), args, context );' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject call( String invocant, PlObject method, PlArray args, int context ) {' . chr(10) . ' if ( method.is_coderef() ) {' . chr(10) . ' args.unshift( new PlString(invocant) );' . chr(10) . ' return method.apply(context, args);' . chr(10) . ' }' . chr(10) . ' else if ( method.is_lvalue() ) {' . chr(10) . ' return call( invocant, method.get(), args, context );' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return call( invocant, method.toString(), args, context );' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' // Intermediate calls, which have to be dispatched properly' . chr(10) . ' public static final PlObject call( PlObject invocant, String method, PlArray args, int context ) {' . chr(10) . ' if ( invocant.is_undef() ) {' . chr(10) . ' PlCORE.die( "Can' . chr(39) . 't call method ' . chr(92) . '"" + method' . chr(10) . ' + "' . chr(92) . '" on an undefined value" );' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . chr(10) . ' if ( invocant.is_lvalue() ) {' . chr(10) . ' invocant = invocant.get();' . chr(10) . ' }' . chr(10) . chr(10) . ' PlClass pClass = invocant.blessed();' . chr(10) . chr(10) . ' if ( pClass == null ) {' . chr(10) . ' PlCORE.die( "Can' . chr(39) . 't call method ' . chr(92) . '"" + method' . chr(10) . ' + "' . chr(92) . '" on unblessed reference" );' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return call( pClass.className().toString(), method, args, context );' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject call( String invocant, String method, PlArray args, int context ) {' . chr(10) . ' if ( invocant.equals("") ) {' . chr(10) . ' PlCORE.die( "Can' . chr(39) . 't call method ' . chr(92) . '"" + method' . chr(10) . ' + "' . chr(92) . '" on an undefined value" );' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . chr(10) . ' PlObject methodCode = PlV.get(invocant + "::" + method);' . chr(10) . chr(10) . ' if (methodCode.is_undef()) {' . chr(10) . ' PlCORE.die( "Can' . chr(39) . 't locate object method ' . chr(92) . '"" + method' . chr(10) . ' + "' . chr(92) . '" via package ' . chr(92) . '"" + invocant' . chr(10) . ' + "' . chr(92) . '" (perhaps you forgot to load ' . chr(92) . '"" + invocant + "' . chr(92) . '"?" );' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . chr(10) . ' args.unshift( new PlString(invocant) );' . chr(10) . ' return methodCode.apply(context, args);' . chr(10) . ' }' . chr(10) . chr(10) . ' // local()' . chr(10) . ' public static final PlObject push_local(PlHash container, String index) {' . chr(10) . ' local_stack.a.add(container);' . chr(10) . ' local_stack.a.add(new PlString(index));' . chr(10) . ' PlLvalue empty = new PlLvalue();' . chr(10) . ' local_stack.a.add(container.hget_lvalue(index));' . chr(10) . ' container.h.put(index, empty);' . chr(10) . ' return empty;' . chr(10) . ' }' . chr(10) . ' public static final PlObject push_local(PlArray container, int index) {' . chr(10) . ' local_stack.a.add(container);' . chr(10) . ' local_stack.a.add(new PlInt(index));' . chr(10) . ' PlLvalue empty = new PlLvalue();' . chr(10) . ' local_stack.a.add(container.aget_lvalue(index));' . chr(10) . ' container.aset(index, empty);' . chr(10) . ' return empty;' . chr(10) . ' }' . chr(10) . ' public static final int local_length() {' . chr(10) . ' return local_stack.to_int();' . chr(10) . ' }' . chr(10) . ' public static final PlObject cleanup_local(int pos, PlObject ret) {' . chr(10) . ' while (local_stack.to_int() > pos) {' . chr(10) . ' PlLvalue lvalue = (PlLvalue)local_stack.pop();' . chr(10) . ' PlObject index = local_stack.pop();' . chr(10) . ' PlObject container = local_stack.pop();' . chr(10) . ' if (container.is_array()) {' . chr(10) . ' ((PlArray)container).a.set(index.to_int(), lvalue);' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' ((PlHash)container).h.put(index.toString(), lvalue);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return ret;' . chr(10) . ' }' . chr(10) . chr(10) . ' // context()' . chr(10) . ' // - handles run-time scalar/list/void context in expression results' . chr(10) . ' public static final PlObject context(int want, PlObject arg) {' . chr(10) . ' if (want == PlCx.LIST) {' . chr(10) . ' return arg;' . chr(10) . ' }' . chr(10) . ' return arg.scalar();' . chr(10) . ' }' . chr(10) . ' public static final PlObject context(int want) {' . chr(10) . ' if (want == PlCx.LIST) {' . chr(10) . ' return new PlArray();' . chr(10) . ' }' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' public static final PlObject context(int want, PlObject... args) {' . chr(10) . ' if (want == PlCx.LIST) {' . chr(10) . ' return new PlArray(args);' . chr(10) . ' }' . chr(10) . ' return args[args.length-1].scalar();' . chr(10) . ' }' . chr(10) . chr(10) . ' // statement()' . chr(10) . ' // - workaround for "Error: not a statement"' . chr(10) . ' // - this is the compile-time version of context(null, arg)' . chr(10) . ' public static final void statement(PlObject arg) { }' . chr(10) . ' public static final void statement() { }' . chr(10) . chr(10) . ' // control-flow exceptions' . chr(10) . ' public static final PlObject next() {' . chr(10) . ' throw PlCx.NEXT;' . chr(10) . ' }' . chr(10) . ' public static final PlObject next(int label_id) {' . chr(10) . ' throw new PlNextException(label_id);' . chr(10) . ' }' . chr(10) . ' public static final PlObject last() {' . chr(10) . ' throw PlCx.LAST;' . chr(10) . ' }' . chr(10) . ' public static final PlObject last(int label_id) {' . chr(10) . ' throw new PlLastException(label_id);' . chr(10) . ' }' . chr(10) . ' public static final PlObject redo(int label_id) {' . chr(10) . ' throw new PlRedoException(label_id);' . chr(10) . ' }' . chr(10) . ' public static final PlObject ret(PlObject ret) {' . chr(10) . ' throw new PlReturnException(ret);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject caller(int ctx, PlObject s) {' . chr(10) . ' int item = s.to_int();' . chr(10) . ' PlCORE.die("caller() not implemented");' . chr(10) . ' return null;' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject srand() {' . chr(10) . ' random = new Random();' . chr(10) . ' return PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' public static final PlObject srand(int s) {' . chr(10) . ' random = new Random(s);' . chr(10) . ' return new PlInt(s);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject rand(double s) {' . chr(10) . ' if (s == 0.0) {' . chr(10) . ' s = 1.0;' . chr(10) . ' }' . chr(10) . ' return new PlDouble(s * random.nextDouble());' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final long[] range(PlObject _start, PlObject _end, int ctx, String var, int ignore) {' . chr(10) . ' if (ctx == PlCx.LIST) {' . chr(10) . ' long start = _start.to_long(),' . chr(10) . ' end = _end.to_long();' . chr(10) . ' int size = Math.max(0, (int)(end - start + 1));' . chr(10) . ' long[] ret = new long[size];' . chr(10) . ' for (int i = 0; i < size; ++i) {' . chr(10) . ' ret[i] = start + i;' . chr(10) . ' }' . chr(10) . ' return ret;' . chr(10) . ' }' . chr(10) . ' PlCORE.die("Range not implemented for context " + ctx);' . chr(10) . ' return null;' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject smartmatch_scalar(PlObject arg0, PlObject arg1) {' . chr(10) . ' if (arg1.is_undef()) {' . chr(10) . ' return arg0.is_undef() ? PlCx.TRUE : PlCx.FALSE;' . chr(10) . ' }' . chr(10) . ' if (arg1.is_string()) {' . chr(10) . ' return arg0.str_eq(arg1);' . chr(10) . ' }' . chr(10) . ' if (arg1.is_num() || arg1.is_int()) {' . chr(10) . ' return arg0.num_eq(arg1);' . chr(10) . ' }' . chr(10) . ' return PlCORE.die(PlCx.VOID, new PlArray(new PlString("Not implemented: smartmatch operator with argument type ' . chr(39) . '"), PlCORE.ref(PlCx.SCALAR, new PlArray(arg1)), new PlString("' . chr(39) . '")));' . chr(10) . ' }' . chr(10) . chr(10) . ' // and1(x) ? y : and3()' . chr(10) . ' public static final boolean and1(PlObject arg1) {' . chr(10) . ' if (arg1.to_bool()) {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' boolean_stack.add(0, arg1);' . chr(10) . ' return false;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject and3() {' . chr(10) . ' return boolean_stack.remove(0);' . chr(10) . ' }' . chr(10) . chr(10) . ' // or1(x) ? or2() : y' . chr(10) . ' public static final boolean or1(PlObject arg1) {' . chr(10) . ' if (arg1.to_bool()) {' . chr(10) . ' boolean_stack.add(0, arg1);' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return false;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject or2() {' . chr(10) . ' return boolean_stack.remove(0);' . chr(10) . ' }' . chr(10) . chr(10) . ' // defined_or1(x) ? defined_or2() : y' . chr(10) . ' public static final boolean defined_or1(PlObject arg1) {' . chr(10) . ' if (!arg1.is_undef()) {' . chr(10) . ' boolean_stack.add(0, arg1);' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return false;' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject defined_or2() {' . chr(10) . ' return boolean_stack.remove(0);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlInt ord(PlString s) {' . chr(10) . ' String item = s.toString();' . chr(10) . ' return new PlInt(item.length() > 0 ? Character.codePointAt(item, 0) : 0);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlString string_replicate(PlObject s, PlObject c) {' . chr(10) . ' int count = c.to_int();' . chr(10) . ' if ( count < 1 ) {' . chr(10) . ' return new PlString("");' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' String raw_s = s.toString();' . chr(10) . ' StringBuilder sb = new StringBuilder();' . chr(10) . ' for (int i = 0; i < count; i++) {' . chr(10) . ' sb.append(raw_s);' . chr(10) . ' }' . chr(10) . ' return new PlString(sb.toString());' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' public static final PlObject list_replicate(PlArray o, PlObject c, int wantarray) {' . chr(10) . ' int count = c.to_int();' . chr(10) . ' PlArray a = new PlArray();' . chr(10) . ' if (count > 0) {' . chr(10) . ' for (int i = 0; i < count; i++) {' . chr(10) . ' a.push( o );' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return (wantarray == PlCx.LIST ) ? a : a.length_of_array();' . chr(10) . ' }' . chr(10) . ' public static final PlObject grep(PlClosure c, PlArray a, int wantarray) {' . chr(10) . ' PlArray ret = new PlArray();' . chr(10) . ' int size = a.to_int();' . chr(10) . ' PlLvalue v__ref = (PlLvalue)PlV.get("main::v__");' . chr(10) . ' PlObject v__val = v__ref.get();' . chr(10) . ' for (int i = 0; i < size; i++) {' . chr(10) . ' boolean result;' . chr(10) . ' PlObject temp = a.aget(i);' . chr(10) . ' v__ref.set(temp);' . chr(10) . ' result = c.apply(PlCx.SCALAR, new PlArray()).to_bool();' . chr(10) . ' if (result) {' . chr(10) . ' ret.push(temp);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' v__ref.set(v__val);' . chr(10) . ' return (wantarray == PlCx.LIST ) ? ret : ret.length_of_array();' . chr(10) . ' }' . chr(10) . ' public static final PlObject map(PlClosure c, PlArray a, int wantarray) {' . chr(10) . ' PlArray ret = new PlArray();' . chr(10) . ' int size = a.to_int();' . chr(10) . ' PlLvalue v__ref = (PlLvalue)PlV.get("main::v__");' . chr(10) . ' PlObject v__val = v__ref.get();' . chr(10) . ' for (int i = 0; i < size; i++) {' . chr(10) . ' v__ref.set(a.aget(i));' . chr(10) . ' ret.push(c.apply(PlCx.LIST, new PlArray()));' . chr(10) . ' }' . chr(10) . ' v__ref.set(v__val);' . chr(10) . ' return (wantarray == PlCx.LIST ) ? ret : ret.length_of_array();' . chr(10) . ' }' . chr(10) . ' public static final PlObject sort(PlClosure c, PlArray a, int wantarray, String pckg) {' . chr(10) . ' PlArray ret = new PlArray(a);' . chr(10) . ' int size = a.to_int();' . chr(10) . ' PlLvalue v_a_ref = (PlLvalue)PlV.get(pckg + "::v_a");' . chr(10) . ' PlLvalue v_b_ref = (PlLvalue)PlV.get(pckg + "::v_b");' . chr(10) . ' PerlCompare comp = new PerlCompare(c, v_a_ref, v_b_ref);' . chr(10) . ' PlObject v_a_val = v_a_ref.get();' . chr(10) . ' PlObject v_b_val = v_b_ref.get();' . chr(10) . ' Collections.sort(ret.a, comp);' . chr(10) . ' v_a_ref.set(v_a_val);' . chr(10) . ' v_b_ref.set(v_b_val);' . chr(10) . ' return (wantarray == PlCx.LIST ) ? ret : ret.length_of_array();' . chr(10) . ' }' . chr(10) . chr(10) . ' private static String double_escape(String s) {' . chr(10) . ' // add double escapes: ' . chr(92) . chr(92) . 'w instead of ' . chr(92) . 'w' . chr(10) . ' return s.replace("' . chr(92) . chr(92) . '", "' . chr(92) . chr(92) . chr(92) . chr(92) . '");' . chr(10) . ' }' . chr(10) . chr(10) . ' private static int _character_class_escape(int offset, String s, StringBuilder sb, int length) {' . chr(10) . ' // [ ... ]' . chr(10) . ' int offset3 = offset;' . chr(10) . ' for ( ; offset3 < length; ) {' . chr(10) . ' final int c3 = s.codePointAt(offset3);' . chr(10) . ' switch (c3) {' . chr(10) . ' case ' . chr(39) . ']' . chr(39) . ':' . chr(10) . ' sb.append(Character.toChars(c3));' . chr(10) . ' return offset3;' . chr(10) . ' case ' . chr(39) . ' ' . chr(39) . ':' . chr(10) . ' sb.append("' . chr(92) . chr(92) . ' "); // make this space a "token", even inside /x' . chr(10) . ' break;' . chr(10) . ' default:' . chr(10) . ' sb.append(Character.toChars(c3));' . chr(10) . ' break;' . chr(10) . ' }' . chr(10) . ' offset3++;' . chr(10) . ' }' . chr(10) . ' return offset3;' . chr(10) . ' }' . chr(10) . chr(10) . ' public static String character_class_escape(String s) {' . chr(10) . ' // escape spaces in character classes' . chr(10) . ' final int length = s.length();' . chr(10) . ' StringBuilder sb = new StringBuilder();' . chr(10) . ' for (int offset = 0; offset < length; ) {' . chr(10) . ' final int c = s.codePointAt(offset);' . chr(10) . ' switch (c) {' . chr(10) . ' case ' . chr(39) . chr(92) . chr(92) . chr(39) . ': // escape - ' . chr(92) . '[' . chr(10) . ' sb.append(Character.toChars(c));' . chr(10) . ' if (offset < length) {' . chr(10) . ' offset++;' . chr(10) . ' int c2 = s.codePointAt(offset);' . chr(10) . ' sb.append(Character.toChars(c2));' . chr(10) . ' }' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . '[' . chr(39) . ': // character class' . chr(10) . ' sb.append(Character.toChars(c));' . chr(10) . ' offset++;' . chr(10) . ' offset = _character_class_escape(offset, s, sb, length);' . chr(10) . ' break;' . chr(10) . ' default: // normal char' . chr(10) . ' sb.append(Character.toChars(c));' . chr(10) . ' break;' . chr(10) . ' }' . chr(10) . ' offset++;' . chr(10) . ' }' . chr(10) . ' return sb.toString();' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject match(PlObject s, PlRegex pat, int want) {' . chr(10) . ' if (want != PlCx.LIST) {' . chr(10) . ' return pat.p.matcher(s.toString()).find() ? PlCx.TRUE : PlCx.FALSE;' . chr(10) . ' }' . chr(10) . ' PlArray ret = new PlArray();' . chr(10) . ' Matcher matcher = pat.p.matcher(s.toString());' . chr(10) . ' while (matcher.find()) {' . chr(10) . ' for (int i = 1; i <= matcher.groupCount(); i++) {' . chr(10) . ' ret.push(matcher.group(i));' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return ret;' . chr(10) . ' }' . chr(10) . ' public static final PlObject match(PlObject s, PlLvalue pat, int want) {' . chr(10) . ' return match(s, pat.get(), want);' . chr(10) . ' }' . chr(10) . ' public static final PlObject match(PlObject s, PlObject pat, int want) {' . chr(10) . ' // TODO - cache the compiled pattern' . chr(10) . ' return match(s, new PlRegex(pat, 0), want);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlObject replace(PlLvalue s, PlRegex pat, PlObject rep, int want) {' . chr(10) . ' if (want != PlCx.LIST) {' . chr(10) . ' return s.set(new PlString(pat.p.matcher(s.toString()).replaceAll(double_escape(rep.toString()))));' . chr(10) . ' }' . chr(10) . ' PlCORE.die("not implemented string replace in list context");' . chr(10) . ' return s;' . chr(10) . ' }' . chr(10) . ' public static final PlObject replace(PlObject s, PlObject pat, PlObject rep, int want) {' . chr(10) . ' // TODO - cache the compiled pattern' . chr(10) . ' return replace(s, new PlRegex(pat, 0), rep, want);' . chr(10) . ' }' . chr(10) . chr(10) . '}' . chr(10) . 'class PlV {' . chr(10) . ' // PlV implements namespaces and global variables' . chr(10) . ' //' . chr(10) . ' // TODO - import CORE subroutines in new namespaces, if needed' . chr(10) . ' // TODO - cache lookups in lexical variables (see PlClosure implementation)' . chr(10) . chr(10) . ' public static final PlHash var = new PlHash();' . chr(10) . chr(10) . ' public static final PlLvalue get(String name) {' . chr(10) . ' return (PlLvalue)var.hget_lvalue(name);' . chr(10) . ' }' . chr(10) . ' public static final PlLvalue get_local(String name) {' . chr(10) . ' return (PlLvalue)var.hget_lvalue_local(name);' . chr(10) . ' }' . chr(10) . ' public static final PlObject set(String name, PlObject v) {' . chr(10) . ' return var.hset(name, v);' . chr(10) . ' }' . chr(10) . ' public static final PlObject set_local(String name, PlObject v) {' . chr(10) . ' return var.hget_lvalue_local(name).set(v);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlHash hash_get(String name) {' . chr(10) . ' return (PlHash)var.hget_hashref(name).get();' . chr(10) . ' }' . chr(10) . ' public static final PlHash hash_get_local(String name) {' . chr(10) . ' return (PlHash)var.hget_lvalue_local(name).get_hashref().get();' . chr(10) . ' }' . chr(10) . ' public static final PlObject hash_set(String name, PlObject v) {' . chr(10) . ' return var.hget_hashref(name).hash_deref_set(v);' . chr(10) . ' }' . chr(10) . ' public static final PlObject hash_set_local(String name, PlObject v) {' . chr(10) . ' return var.hget_lvalue_local(name).get_hashref().hash_deref_set(v);' . chr(10) . ' }' . chr(10) . chr(10) . ' public static final PlArray array_get(String name) {' . chr(10) . ' return (PlArray)var.hget_arrayref(name).get();' . chr(10) . ' }' . chr(10) . ' public static final PlArray array_get_local(String name) {' . chr(10) . ' return (PlArray)var.hget_lvalue_local(name).get_arrayref().get();' . chr(10) . ' }' . chr(10) . ' public static final PlObject array_set(String name, PlObject v) {' . chr(10) . ' return var.hget_arrayref(name).array_deref_set(v);' . chr(10) . ' }' . chr(10) . ' public static final PlObject array_set_local(String name, PlObject v) {' . chr(10) . ' return var.hget_lvalue_local(name).get_arrayref().array_deref_set(v);' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlEnv {' . chr(10) . ' public static final void init(String[] args) {' . chr(10) . ' PlV.array_set(PlCx.ARGV, new PlArray(args)); // args is String[]' . chr(10) . ' PlV.hash_set(PlCx.ENV, new PlArray(System.getenv())); // env is Map' . chr(10) . ' PlV.set("main::v_" + (char)34, new PlString(" ")); // $" = " "' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlObject {' . chr(10) . ' public static final PlString REF = new PlString("");' . chr(10) . chr(10) . ' public PlObject() {' . chr(10) . ' }' . chr(10) . join('', (map { my $class = $java_classes{$_}; my $java_class_name = $class->{'java_type'}; my $perl_to_java = $class->{'perl_to_java'}; @@ -17392,7 +17392,7 @@ ' public PlObject ' . $perl . '(PlObject b) {' . chr(10) . ' return new ' . $returns . '(this.toString().compareTo(b.toString()) ' . $native . ');' . chr(10) . ' }' . chr(10) } sort { $a cmp $b - } keys(%string_binop))) . '}' . chr(10) . 'class PlReference extends PlObject {' . chr(10) . ' public static final PlString REF = new PlString("REF");' . chr(10) . chr(9) . 'public PlClass bless;' . chr(10) . chr(10) . ' public boolean is_ref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public PlReference bless(PlString className) {' . chr(10) . ' this.bless = new PlClass(className);' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlClass blessed() {' . chr(10) . chr(9) . chr(9) . 'return this.bless;' . chr(10) . ' }' . chr(10) . chr(10) . chr(9) . 'public PlString ref() {' . chr(10) . chr(9) . chr(9) . 'if ( this.bless == null ) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return REF;' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . chr(9) . 'else {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return this.bless.className();' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . chr(10) . ' public String toString() {' . chr(10) . ' return this.ref().toString() + "(0x" + Integer.toHexString(this.hashCode()) + ")";' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlRegex extends PlReference {' . chr(10) . ' public Pattern p;' . chr(10) . ' // public Matcher m;' . chr(10) . ' public static final PlString REF = new PlString("Regexp");' . chr(10) . chr(10) . ' public PlRegex(String p, int flags) {' . chr(10) . ' this.p = Pattern.compile(PerlOp.character_class_escape(p), flags);' . chr(10) . ' }' . chr(10) . ' public PlRegex(PlObject p, int flags) {' . chr(10) . ' this.p = Pattern.compile(PerlOp.character_class_escape(p.toString()), flags);' . chr(10) . ' }' . chr(10) . ' public String toString() {' . chr(10) . ' // TODO - show flags' . chr(10) . ' return this.p.toString();' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlClosure extends PlReference implements Runnable {' . chr(10) . ' public PlObject[] env; // new PlObject[]{ v1, v2, v3 }' . chr(10) . ' public PlObject prototype; // ' . chr(39) . '$$$' . chr(39) . chr(10) . ' public static final PlString REF = new PlString("CODE");' . chr(10) . chr(10) . ' public PlClosure(PlObject prototype, PlObject[] env) {' . chr(10) . ' this.prototype = prototype;' . chr(10) . ' this.env = env;' . chr(10) . ' }' . chr(10) . ' // Note: apply() is inherited from PlObject' . chr(10) . ' public PlObject apply(int want, PlArray List__) {' . chr(10) . ' PlCORE.die("it looks like you have a closure without a block");' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public void run() {' . chr(10) . ' // run as a thread' . chr(10) . ' this.apply(PlCx.VOID, new PlArray());' . chr(10) . ' }' . chr(10) . chr(9) . 'public PlString ref() {' . chr(10) . chr(9) . chr(9) . 'if ( this.bless == null ) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return REF;' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . chr(9) . 'else {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return this.bless.className();' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . ' public boolean is_coderef() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlLvalueRef extends PlReference {' . chr(10) . ' private PlObject o;' . chr(10) . ' public static final PlString REF = new PlString("SCALAR");' . chr(10) . chr(10) . chr(9) . 'public PlString ref() {' . chr(10) . chr(9) . chr(9) . 'if ( this.bless == null ) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return REF;' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . chr(9) . 'else {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return this.bless.className();' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . ' public String toString() {' . chr(10) . ' int id = System.identityHashCode(this.o);' . chr(10) . ' return this.ref().toString() + "(0x" + Integer.toHexString(id) + ")";' . chr(10) . ' }' . chr(10) . ' public PlLvalueRef(PlLvalue o) {' . chr(10) . ' this.o = o;' . chr(10) . ' }' . chr(10) . ' public PlLvalueRef(PlObject o) {' . chr(10) . ' this.o = o;' . chr(10) . ' }' . chr(10) . ' public PlObject scalar_deref_set(PlObject v) {' . chr(10) . ' return this.o.set(v);' . chr(10) . ' }' . chr(10) . ' public boolean is_scalarref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public PlObject get() {' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlArrayRef extends PlArray {' . chr(10) . ' public static final PlString REF = new PlString("ARRAY");' . chr(10) . chr(9) . 'public PlClass bless;' . chr(10) . chr(10) . ' public String toString() {' . chr(10) . ' int id = System.identityHashCode(this.a);' . chr(10) . ' return this.ref().toString() + "(0x" + Integer.toHexString(id) + ")";' . chr(10) . ' }' . chr(10) . ' public PlArrayRef() {' . chr(10) . ' this.each_iterator = 0;' . chr(10) . ' this.a = new ArrayList();' . chr(10) . ' }' . chr(10) . ' public PlArrayRef(PlArray o) {' . chr(10) . ' this.a = o.a;' . chr(10) . ' this.each_iterator = o.each_iterator;' . chr(10) . ' }' . chr(10) . ' public PlObject set(PlArray o) {' . chr(10) . ' this.a = o.a;' . chr(10) . ' this.each_iterator = o.each_iterator;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject get() {' . chr(10) . ' PlArray o = new PlArray();' . chr(10) . ' o.a = this.a;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject array_deref() {' . chr(10) . ' PlArray o = new PlArray();' . chr(10) . ' o.a = this.a;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject array_deref_set(PlObject v) {' . chr(10) . ' super.set(v);' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' public boolean is_array() {' . chr(10) . ' return false;' . chr(10) . ' }' . chr(10) . ' public boolean is_ref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public boolean is_arrayref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public PlObject scalar() {' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlArrayRef bless(PlString className) {' . chr(10) . ' this.bless = new PlClass(className);' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlClass blessed() {' . chr(10) . chr(9) . chr(9) . 'return this.bless;' . chr(10) . ' }' . chr(10) . chr(9) . 'public PlString ref() {' . chr(10) . chr(9) . chr(9) . 'if ( this.bless == null ) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return REF;' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . chr(9) . 'else {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return this.bless.className();' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . '}' . chr(10) . 'class PlHashRef extends PlHash {' . chr(10) . ' public static final PlString REF = new PlString("HASH");' . chr(10) . chr(9) . 'public PlClass bless;' . chr(10) . chr(10) . ' public String toString() {' . chr(10) . ' int id = System.identityHashCode(this.h);' . chr(10) . ' return this.ref().toString() + "(0x" + Integer.toHexString(id) + ")";' . chr(10) . ' }' . chr(10) . ' public PlHashRef() {' . chr(10) . ' this.h = new HashMap();' . chr(10) . ' this.each_iterator = null;' . chr(10) . ' }' . chr(10) . ' public PlHashRef(PlHash o) {' . chr(10) . ' this.h = o.h;' . chr(10) . ' this.each_iterator = o.each_iterator;' . chr(10) . ' }' . chr(10) . ' public PlObject set(PlHash o) {' . chr(10) . ' this.h = o.h;' . chr(10) . ' this.each_iterator = o.each_iterator;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject get() {' . chr(10) . ' PlHash o = new PlHash();' . chr(10) . ' o.h = this.h;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject hash_deref() {' . chr(10) . ' PlHash o = new PlHash();' . chr(10) . ' o.h = this.h;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject hash_deref_set(PlObject v) {' . chr(10) . ' super.set(v);' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' public boolean is_hash() {' . chr(10) . ' return false;' . chr(10) . ' }' . chr(10) . ' public boolean is_ref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public boolean is_hashref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public PlObject scalar() {' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlHashRef bless(PlString className) {' . chr(10) . ' this.bless = new PlClass(className);' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlClass blessed() {' . chr(10) . chr(9) . chr(9) . 'return this.bless;' . chr(10) . ' }' . chr(10) . ' public PlString ref() {' . chr(10) . chr(9) . chr(9) . 'if ( this.bless == null ) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return REF;' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . chr(9) . 'else {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return this.bless.className();' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . '}' . chr(10) . 'class PlClass {' . chr(10) . chr(9) . 'public static PlHash classes = new PlHash();' . chr(10) . chr(9) . 'public PlString className;' . chr(10) . chr(10) . chr(9) . 'public PlClass (PlString blessing) {' . chr(10) . chr(9) . chr(9) . 'this.className = blessing;' . chr(10) . chr(9) . chr(9) . 'if (classes.exists(className) == null) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'classes.hset(className, className);' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . chr(9) . 'public PlString className() {' . chr(10) . chr(9) . chr(9) . 'return this.className;' . chr(10) . chr(9) . '}' . chr(10) . ' public boolean is_undef() {' . chr(10) . ' return this.className == null;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlLvalue extends PlObject {' . chr(10) . ' private PlObject o;' . chr(10) . chr(10) . ' // Note: several versions of PlLvalue()' . chr(10) . ' public PlLvalue() {' . chr(10) . ' this.o = PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' public PlLvalue(PlObject o) {' . chr(10) . ' this.o = o;' . chr(10) . ' }' . chr(10) . ' public PlLvalue(PlLvalue o) {' . chr(10) . ' this.o = o.get();' . chr(10) . ' }' . chr(10) . ' public PlLvalue(PlArray o) {' . chr(10) . ' // $a = @x' . chr(10) . ' this.o = o.scalar();' . chr(10) . ' }' . chr(10) . ' public PlLvalue(PlHash o) {' . chr(10) . ' // $a = %x' . chr(10) . ' this.o = o.scalar();' . chr(10) . ' }' . chr(10) . ' public PlObject get() {' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' public PlObject get_scalarref() {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' PlLvalueRef ar = new PlLvalueRef(new PlLvalue());' . chr(10) . ' this.o = ar;' . chr(10) . ' return ar;' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_scalarref()) {' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' // Modification of a read-only value attempted' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' public PlObject get_arrayref() {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' PlArrayRef ar = new PlArrayRef();' . chr(10) . ' this.o = ar;' . chr(10) . ' return ar;' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_arrayref()) {' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not an ARRAY reference");' . chr(10) . ' }' . chr(10) . ' public PlObject get_hashref() {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' PlHashRef hr = new PlHashRef();' . chr(10) . ' this.o = hr;' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_hashref()) {' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not a HASH reference");' . chr(10) . ' }' . chr(10) . ' public PlObject aget(PlObject i) {' . chr(10) . ' return this.o.aget(i);' . chr(10) . ' }' . chr(10) . ' public PlObject aget(int i) {' . chr(10) . ' return this.o.aget(i);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject aget_scalarref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlArrayRef();' . chr(10) . ' }' . chr(10) . ' return this.o.aget_scalarref(i);' . chr(10) . ' }' . chr(10) . ' public PlObject aget_arrayref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlArrayRef();' . chr(10) . ' }' . chr(10) . ' return this.o.aget_arrayref(i);' . chr(10) . ' }' . chr(10) . ' public PlObject aget_hashref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlArrayRef();' . chr(10) . ' }' . chr(10) . ' return this.o.aget_hashref(i);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject aset(int i, PlObject v) {' . chr(10) . ' return this.o.aset(i, v);' . chr(10) . ' }' . chr(10) . ' public PlObject aset(PlObject i, PlObject v) {' . chr(10) . ' return this.o.aset(i, v);' . chr(10) . ' }' . chr(10) . ' public PlObject hget(PlObject i) {' . chr(10) . ' return this.o.hget(i);' . chr(10) . ' }' . chr(10) . ' public PlObject hget(String i) {' . chr(10) . ' return this.o.hget(i);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject hget_scalarref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlHashRef();' . chr(10) . ' }' . chr(10) . ' return this.o.hget_scalarref(i);' . chr(10) . ' }' . chr(10) . ' public PlObject hget_arrayref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlHashRef();' . chr(10) . ' }' . chr(10) . ' return this.o.hget_arrayref(i);' . chr(10) . ' }' . chr(10) . ' public PlObject hget_hashref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlHashRef();' . chr(10) . ' }' . chr(10) . ' return this.o.hget_hashref(i);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject hset(PlObject s, PlObject v) {' . chr(10) . ' return this.o.hset(s, v);' . chr(10) . ' }' . chr(10) . ' public PlObject hset(String s, PlObject v) {' . chr(10) . ' return this.o.hset(s, v);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject scalar_deref() {' . chr(10) . ' return this.get_scalarref().get();' . chr(10) . ' }' . chr(10) . ' public PlObject scalar_deref_set(PlObject v) {' . chr(10) . ' return this.get_scalarref().scalar_deref_set(v);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject array_deref() {' . chr(10) . ' // @$x doesn' . chr(39) . 't autovivify' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' return new PlArray();' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_arrayref()) {' . chr(10) . ' return this.o.get();' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not an ARRAY reference");' . chr(10) . ' }' . chr(10) . ' public PlObject array_deref_set(PlObject v) {' . chr(10) . ' // @$x = ...' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlArrayRef();' . chr(10) . ' return this.o.array_deref_set(v);' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_arrayref()) {' . chr(10) . ' return this.o.array_deref_set(v);' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not an ARRAY reference");' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject hash_deref() {' . chr(10) . ' // %$x doesn' . chr(39) . 't autovivify' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' return new PlHash();' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_hashref()) {' . chr(10) . ' return this.o.get();' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not a HASH reference");' . chr(10) . ' }' . chr(10) . ' public PlObject hash_deref_set(PlObject v) {' . chr(10) . ' // %$x = ...' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlHashRef();' . chr(10) . ' return this.o.hash_deref_set(v);' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_hashref()) {' . chr(10) . ' return this.o.hash_deref_set(v);' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not a HASH reference");' . chr(10) . ' }' . chr(10) . ' public PlObject apply(int want, PlArray List__) {' . chr(10) . ' return this.o.apply(want, List__);' . chr(10) . ' }' . chr(10) . chr(10) . ' // Note: several versions of set()' . chr(10) . ' public PlObject set(PlObject o) {' . chr(10) . ' if (o == null) {' . chr(10) . ' o = PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' this.o = o;' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlObject set(PlLvalue o) {' . chr(10) . ' this.o = o.get();' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlObject set(PlArray o) {' . chr(10) . ' // $a = @x' . chr(10) . ' this.o = o.scalar();' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlObject set(PlHash o) {' . chr(10) . ' // $a = %x' . chr(10) . ' this.o = o.scalar();' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . (join('', map { + } keys(%string_binop))) . '}' . chr(10) . 'class PlReference extends PlObject {' . chr(10) . ' public static final PlString REF = new PlString("REF");' . chr(10) . chr(9) . 'public PlClass bless;' . chr(10) . chr(10) . ' public boolean is_ref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public PlReference bless(PlString className) {' . chr(10) . ' this.bless = new PlClass(className);' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlClass blessed() {' . chr(10) . chr(9) . chr(9) . 'return this.bless;' . chr(10) . ' }' . chr(10) . chr(10) . chr(9) . 'public PlString ref() {' . chr(10) . chr(9) . chr(9) . 'if ( this.bless == null ) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return REF;' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . chr(9) . 'else {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return this.bless.className();' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . chr(10) . ' public String toString() {' . chr(10) . ' return this.ref().toString() + "(0x" + Integer.toHexString(this.hashCode()) + ")";' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlRegex extends PlReference {' . chr(10) . ' public Pattern p;' . chr(10) . ' public String original_string;' . chr(10) . ' // public Matcher m;' . chr(10) . ' public static final PlString REF = new PlString("Regexp");' . chr(10) . chr(10) . ' public PlRegex(String p, int flags) {' . chr(10) . ' this.original_string = p;' . chr(10) . ' this.p = Pattern.compile(PerlOp.character_class_escape(this.original_string), flags);' . chr(10) . ' }' . chr(10) . ' public PlRegex(PlObject p, int flags) {' . chr(10) . ' this.original_string = p.toString();' . chr(10) . ' this.p = Pattern.compile(PerlOp.character_class_escape(this.original_string), flags);' . chr(10) . ' }' . chr(10) . ' public String toString() {' . chr(10) . ' // TODO - show flags' . chr(10) . ' return this.original_string;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlClosure extends PlReference implements Runnable {' . chr(10) . ' public PlObject[] env; // new PlObject[]{ v1, v2, v3 }' . chr(10) . ' public PlObject prototype; // ' . chr(39) . '$$$' . chr(39) . chr(10) . ' public static final PlString REF = new PlString("CODE");' . chr(10) . chr(10) . ' public PlClosure(PlObject prototype, PlObject[] env) {' . chr(10) . ' this.prototype = prototype;' . chr(10) . ' this.env = env;' . chr(10) . ' }' . chr(10) . ' // Note: apply() is inherited from PlObject' . chr(10) . ' public PlObject apply(int want, PlArray List__) {' . chr(10) . ' PlCORE.die("it looks like you have a closure without a block");' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public void run() {' . chr(10) . ' // run as a thread' . chr(10) . ' this.apply(PlCx.VOID, new PlArray());' . chr(10) . ' }' . chr(10) . chr(9) . 'public PlString ref() {' . chr(10) . chr(9) . chr(9) . 'if ( this.bless == null ) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return REF;' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . chr(9) . 'else {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return this.bless.className();' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . ' public boolean is_coderef() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlLvalueRef extends PlReference {' . chr(10) . ' private PlObject o;' . chr(10) . ' public static final PlString REF = new PlString("SCALAR");' . chr(10) . chr(10) . chr(9) . 'public PlString ref() {' . chr(10) . chr(9) . chr(9) . 'if ( this.bless == null ) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return REF;' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . chr(9) . 'else {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return this.bless.className();' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . ' public String toString() {' . chr(10) . ' int id = System.identityHashCode(this.o);' . chr(10) . ' return this.ref().toString() + "(0x" + Integer.toHexString(id) + ")";' . chr(10) . ' }' . chr(10) . ' public PlLvalueRef(PlLvalue o) {' . chr(10) . ' this.o = o;' . chr(10) . ' }' . chr(10) . ' public PlLvalueRef(PlObject o) {' . chr(10) . ' this.o = o;' . chr(10) . ' }' . chr(10) . ' public PlObject scalar_deref_set(PlObject v) {' . chr(10) . ' return this.o.set(v);' . chr(10) . ' }' . chr(10) . ' public boolean is_scalarref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public PlObject get() {' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlArrayRef extends PlArray {' . chr(10) . ' public static final PlString REF = new PlString("ARRAY");' . chr(10) . chr(9) . 'public PlClass bless;' . chr(10) . chr(10) . ' public String toString() {' . chr(10) . ' int id = System.identityHashCode(this.a);' . chr(10) . ' return this.ref().toString() + "(0x" + Integer.toHexString(id) + ")";' . chr(10) . ' }' . chr(10) . ' public PlArrayRef() {' . chr(10) . ' this.each_iterator = 0;' . chr(10) . ' this.a = new ArrayList();' . chr(10) . ' }' . chr(10) . ' public PlArrayRef(PlArray o) {' . chr(10) . ' this.a = o.a;' . chr(10) . ' this.each_iterator = o.each_iterator;' . chr(10) . ' }' . chr(10) . ' public PlObject set(PlArray o) {' . chr(10) . ' this.a = o.a;' . chr(10) . ' this.each_iterator = o.each_iterator;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject get() {' . chr(10) . ' PlArray o = new PlArray();' . chr(10) . ' o.a = this.a;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject array_deref() {' . chr(10) . ' PlArray o = new PlArray();' . chr(10) . ' o.a = this.a;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject array_deref_set(PlObject v) {' . chr(10) . ' super.set(v);' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' public boolean is_array() {' . chr(10) . ' return false;' . chr(10) . ' }' . chr(10) . ' public boolean is_ref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public boolean is_arrayref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public PlObject scalar() {' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlArrayRef bless(PlString className) {' . chr(10) . ' this.bless = new PlClass(className);' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlClass blessed() {' . chr(10) . chr(9) . chr(9) . 'return this.bless;' . chr(10) . ' }' . chr(10) . chr(9) . 'public PlString ref() {' . chr(10) . chr(9) . chr(9) . 'if ( this.bless == null ) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return REF;' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . chr(9) . 'else {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return this.bless.className();' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . '}' . chr(10) . 'class PlHashRef extends PlHash {' . chr(10) . ' public static final PlString REF = new PlString("HASH");' . chr(10) . chr(9) . 'public PlClass bless;' . chr(10) . chr(10) . ' public String toString() {' . chr(10) . ' int id = System.identityHashCode(this.h);' . chr(10) . ' return this.ref().toString() + "(0x" + Integer.toHexString(id) + ")";' . chr(10) . ' }' . chr(10) . ' public PlHashRef() {' . chr(10) . ' this.h = new HashMap();' . chr(10) . ' this.each_iterator = null;' . chr(10) . ' }' . chr(10) . ' public PlHashRef(PlHash o) {' . chr(10) . ' this.h = o.h;' . chr(10) . ' this.each_iterator = o.each_iterator;' . chr(10) . ' }' . chr(10) . ' public PlObject set(PlHash o) {' . chr(10) . ' this.h = o.h;' . chr(10) . ' this.each_iterator = o.each_iterator;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject get() {' . chr(10) . ' PlHash o = new PlHash();' . chr(10) . ' o.h = this.h;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject hash_deref() {' . chr(10) . ' PlHash o = new PlHash();' . chr(10) . ' o.h = this.h;' . chr(10) . ' return o;' . chr(10) . ' }' . chr(10) . ' public PlObject hash_deref_set(PlObject v) {' . chr(10) . ' super.set(v);' . chr(10) . ' return v;' . chr(10) . ' }' . chr(10) . ' public boolean is_hash() {' . chr(10) . ' return false;' . chr(10) . ' }' . chr(10) . ' public boolean is_ref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public boolean is_hashref() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public PlObject scalar() {' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlHashRef bless(PlString className) {' . chr(10) . ' this.bless = new PlClass(className);' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlClass blessed() {' . chr(10) . chr(9) . chr(9) . 'return this.bless;' . chr(10) . ' }' . chr(10) . ' public PlString ref() {' . chr(10) . chr(9) . chr(9) . 'if ( this.bless == null ) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return REF;' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . chr(9) . 'else {' . chr(10) . chr(9) . chr(9) . chr(9) . 'return this.bless.className();' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . '}' . chr(10) . 'class PlClass {' . chr(10) . chr(9) . 'public static PlHash classes = new PlHash();' . chr(10) . chr(9) . 'public PlString className;' . chr(10) . chr(10) . chr(9) . 'public PlClass (PlString blessing) {' . chr(10) . chr(9) . chr(9) . 'this.className = blessing;' . chr(10) . chr(9) . chr(9) . 'if (classes.exists(className) == null) {' . chr(10) . chr(9) . chr(9) . chr(9) . 'classes.hset(className, className);' . chr(10) . chr(9) . chr(9) . '}' . chr(10) . chr(9) . '}' . chr(10) . chr(9) . 'public PlString className() {' . chr(10) . chr(9) . chr(9) . 'return this.className;' . chr(10) . chr(9) . '}' . chr(10) . ' public boolean is_undef() {' . chr(10) . ' return this.className == null;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlLvalue extends PlObject {' . chr(10) . ' private PlObject o;' . chr(10) . chr(10) . ' // Note: several versions of PlLvalue()' . chr(10) . ' public PlLvalue() {' . chr(10) . ' this.o = PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' public PlLvalue(PlObject o) {' . chr(10) . ' this.o = o;' . chr(10) . ' }' . chr(10) . ' public PlLvalue(PlLvalue o) {' . chr(10) . ' this.o = o.get();' . chr(10) . ' }' . chr(10) . ' public PlLvalue(PlArray o) {' . chr(10) . ' // $a = @x' . chr(10) . ' this.o = o.scalar();' . chr(10) . ' }' . chr(10) . ' public PlLvalue(PlHash o) {' . chr(10) . ' // $a = %x' . chr(10) . ' this.o = o.scalar();' . chr(10) . ' }' . chr(10) . ' public PlObject get() {' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' public PlObject get_scalarref() {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' PlLvalueRef ar = new PlLvalueRef(new PlLvalue());' . chr(10) . ' this.o = ar;' . chr(10) . ' return ar;' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_scalarref()) {' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' // Modification of a read-only value attempted' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' public PlObject get_arrayref() {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' PlArrayRef ar = new PlArrayRef();' . chr(10) . ' this.o = ar;' . chr(10) . ' return ar;' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_arrayref()) {' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not an ARRAY reference");' . chr(10) . ' }' . chr(10) . ' public PlObject get_hashref() {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' PlHashRef hr = new PlHashRef();' . chr(10) . ' this.o = hr;' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_hashref()) {' . chr(10) . ' return this.o;' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not a HASH reference");' . chr(10) . ' }' . chr(10) . ' public PlObject aget(PlObject i) {' . chr(10) . ' return this.o.aget(i);' . chr(10) . ' }' . chr(10) . ' public PlObject aget(int i) {' . chr(10) . ' return this.o.aget(i);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject aget_scalarref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlArrayRef();' . chr(10) . ' }' . chr(10) . ' return this.o.aget_scalarref(i);' . chr(10) . ' }' . chr(10) . ' public PlObject aget_arrayref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlArrayRef();' . chr(10) . ' }' . chr(10) . ' return this.o.aget_arrayref(i);' . chr(10) . ' }' . chr(10) . ' public PlObject aget_hashref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlArrayRef();' . chr(10) . ' }' . chr(10) . ' return this.o.aget_hashref(i);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject aset(int i, PlObject v) {' . chr(10) . ' return this.o.aset(i, v);' . chr(10) . ' }' . chr(10) . ' public PlObject aset(PlObject i, PlObject v) {' . chr(10) . ' return this.o.aset(i, v);' . chr(10) . ' }' . chr(10) . ' public PlObject hget(PlObject i) {' . chr(10) . ' return this.o.hget(i);' . chr(10) . ' }' . chr(10) . ' public PlObject hget(String i) {' . chr(10) . ' return this.o.hget(i);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject hget_scalarref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlHashRef();' . chr(10) . ' }' . chr(10) . ' return this.o.hget_scalarref(i);' . chr(10) . ' }' . chr(10) . ' public PlObject hget_arrayref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlHashRef();' . chr(10) . ' }' . chr(10) . ' return this.o.hget_arrayref(i);' . chr(10) . ' }' . chr(10) . ' public PlObject hget_hashref(PlObject i) {' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlHashRef();' . chr(10) . ' }' . chr(10) . ' return this.o.hget_hashref(i);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject hset(PlObject s, PlObject v) {' . chr(10) . ' return this.o.hset(s, v);' . chr(10) . ' }' . chr(10) . ' public PlObject hset(String s, PlObject v) {' . chr(10) . ' return this.o.hset(s, v);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject scalar_deref() {' . chr(10) . ' return this.get_scalarref().get();' . chr(10) . ' }' . chr(10) . ' public PlObject scalar_deref_set(PlObject v) {' . chr(10) . ' return this.get_scalarref().scalar_deref_set(v);' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject array_deref() {' . chr(10) . ' // @$x doesn' . chr(39) . 't autovivify' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' return new PlArray();' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_arrayref()) {' . chr(10) . ' return this.o.get();' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not an ARRAY reference");' . chr(10) . ' }' . chr(10) . ' public PlObject array_deref_set(PlObject v) {' . chr(10) . ' // @$x = ...' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlArrayRef();' . chr(10) . ' return this.o.array_deref_set(v);' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_arrayref()) {' . chr(10) . ' return this.o.array_deref_set(v);' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not an ARRAY reference");' . chr(10) . ' }' . chr(10) . chr(10) . ' public PlObject hash_deref() {' . chr(10) . ' // %$x doesn' . chr(39) . 't autovivify' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' return new PlHash();' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_hashref()) {' . chr(10) . ' return this.o.get();' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not a HASH reference");' . chr(10) . ' }' . chr(10) . ' public PlObject hash_deref_set(PlObject v) {' . chr(10) . ' // %$x = ...' . chr(10) . ' if (this.o.is_undef()) {' . chr(10) . ' this.o = new PlHashRef();' . chr(10) . ' return this.o.hash_deref_set(v);' . chr(10) . ' }' . chr(10) . ' else if (this.o.is_hashref()) {' . chr(10) . ' return this.o.hash_deref_set(v);' . chr(10) . ' }' . chr(10) . ' return PlCORE.die("Not a HASH reference");' . chr(10) . ' }' . chr(10) . ' public PlObject apply(int want, PlArray List__) {' . chr(10) . ' return this.o.apply(want, List__);' . chr(10) . ' }' . chr(10) . chr(10) . ' // Note: several versions of set()' . chr(10) . ' public PlObject set(PlObject o) {' . chr(10) . ' if (o == null) {' . chr(10) . ' o = PlCx.UNDEF;' . chr(10) . ' }' . chr(10) . ' this.o = o;' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlObject set(PlLvalue o) {' . chr(10) . ' this.o = o.get();' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlObject set(PlArray o) {' . chr(10) . ' // $a = @x' . chr(10) . ' this.o = o.scalar();' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . ' public PlObject set(PlHash o) {' . chr(10) . ' // $a = %x' . chr(10) . ' this.o = o.scalar();' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) . (join('', map { my $native = $_; my $perl = $native_to_perl{$native}; $native && $perl ? ' public PlObject set(' . $native . ' s) {' . chr(10) . ' this.o = new ' . $perl . '(s);' . chr(10) . ' return this;' . chr(10) . ' }' . chr(10) : () @@ -17439,7 +17439,7 @@ ' public PlObject ' . $perl . '(PlObject s) {' . chr(10) . ' // num - int, num - num' . chr(10) . ' return new ' . $returns . '( this.i ' . $native . ' s.to_double() );' . chr(10) . ' }' . chr(10) . ' public PlObject ' . $perl . '2(PlObject s) {' . chr(10) . ' // int - num' . chr(10) . ' return new ' . $returns . '( s.to_double() ' . $native . ' this.i );' . chr(10) . ' }' . chr(10) } sort { $a cmp $b - } keys(%number_binop))) . ' public boolean is_num() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlString extends PlObject {' . chr(10) . ' private java.lang.String s;' . chr(10) . ' private PlObject numericValue;' . chr(10) . ' private boolean hasValue;' . chr(10) . chr(10) . ' public PlString(String s) {' . chr(10) . ' this.s = s;' . chr(10) . ' }' . chr(10) . ' public PlString(char s) {' . chr(10) . ' this.s = "" + s;' . chr(10) . ' }' . chr(10) . ' public PlObject parse() {' . chr(10) . ' if (!hasValue) {' . chr(10) . ' hasValue = true;' . chr(10) . ' numericValue = this._parse();' . chr(10) . ' }' . chr(10) . ' return numericValue;' . chr(10) . ' }' . chr(10) . ' private PlObject _parse_exp(int length, int signal, int offset, int next) {' . chr(10) . ' // 123.45E^^^' . chr(10) . ' int offset3 = next;' . chr(10) . ' for ( ; offset3 < length; ) {' . chr(10) . ' final int c3 = s.codePointAt(offset3);' . chr(10) . ' switch (c3) { ' . chr(10) . ' case ' . chr(39) . '+' . chr(39) . ': case ' . chr(39) . '-' . chr(39) . ':' . chr(10) . ' // TODO' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' break;' . chr(10) . ' default: // invalid' . chr(10) . ' return new PlDouble(Double.parseDouble(this.s.substring(0, offset3)));' . chr(10) . ' }' . chr(10) . ' offset3++;' . chr(10) . ' }' . chr(10) . ' return new PlDouble(Double.parseDouble(this.s.substring(0, offset3)));' . chr(10) . ' }' . chr(10) . ' private PlObject _parse_dot(int length, int signal, int offset, int next) {' . chr(10) . ' // 123.^^^' . chr(10) . ' int offset3 = next;' . chr(10) . ' for ( ; offset3 < length; ) {' . chr(10) . ' final int c3 = s.codePointAt(offset3);' . chr(10) . ' switch (c3) { ' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . 'E' . chr(39) . ': case ' . chr(39) . 'e' . chr(39) . ':' . chr(10) . ' // start exponential part' . chr(10) . ' return _parse_exp(length, signal, offset, offset3+1);' . chr(10) . ' default: // invalid' . chr(10) . ' return new PlDouble(Double.parseDouble(this.s.substring(0, offset3)));' . chr(10) . ' }' . chr(10) . ' offset3++;' . chr(10) . ' }' . chr(10) . ' return new PlDouble(Double.parseDouble(this.s.substring(0, offset3)));' . chr(10) . ' }' . chr(10) . ' private PlObject _parse() {' . chr(10) . ' final int length = s.length();' . chr(10) . ' int signal = 0;' . chr(10) . ' for (int offset = 0; offset < length; ) {' . chr(10) . ' final int c = s.codePointAt(offset);' . chr(10) . ' switch (c) { ' . chr(10) . ' case ' . chr(39) . 'i' . chr(39) . ': case ' . chr(39) . 'I' . chr(39) . ':' . chr(10) . ' if (this.s.substring(offset, offset+3).equalsIgnoreCase("inf")) {' . chr(10) . ' if (signal < 0) {' . chr(10) . ' return new PlDouble(Double.NEGATIVE_INFINITY);' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return new PlDouble(Double.POSITIVE_INFINITY);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' case ' . chr(39) . 'n' . chr(39) . ': case ' . chr(39) . 'N' . chr(39) . ':' . chr(10) . ' if (this.s.substring(offset, offset+3).equalsIgnoreCase("nan")) {' . chr(10) . ' return new PlDouble(Double.NaN);' . chr(10) . ' }' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' case ' . chr(39) . '.' . chr(39) . ': // starts with dot' . chr(10) . ' if (signal != 0) {' . chr(10) . ' signal = 1;' . chr(10) . ' }' . chr(10) . ' return _parse_dot(length, signal, offset, offset+1);' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' // starts with number' . chr(10) . ' if (signal == 0) {' . chr(10) . ' signal = 1;' . chr(10) . ' }' . chr(10) . ' int offset2 = offset+1;' . chr(10) . ' for ( ; offset2 < length; ) {' . chr(10) . ' final int c2 = s.codePointAt(offset2);' . chr(10) . ' switch (c2) { ' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' // more numbers' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . '.' . chr(39) . ':' . chr(10) . ' // start decimal part' . chr(10) . ' return _parse_dot(length, signal, offset, offset2+1);' . chr(10) . ' case ' . chr(39) . 'E' . chr(39) . ': case ' . chr(39) . 'e' . chr(39) . ':' . chr(10) . ' // start exponential part' . chr(10) . ' return _parse_exp(length, signal, offset, offset2+1);' . chr(10) . ' default:' . chr(10) . ' // return integer' . chr(10) . ' if (signal < 0) {' . chr(10) . ' return new PlInt(-Integer.parseInt(this.s.substring(offset, offset2)));' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return new PlInt(Integer.parseInt(this.s.substring(offset, offset2)));' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' offset2++;' . chr(10) . ' }' . chr(10) . ' // integer' . chr(10) . ' if (signal < 0) {' . chr(10) . ' return new PlInt(-Integer.parseInt(this.s.substring(offset, offset2)));' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return new PlInt(Integer.parseInt(this.s.substring(offset, offset2)));' . chr(10) . ' }' . chr(10) . ' case ' . chr(39) . '+' . chr(39) . ': // starts with +' . chr(10) . ' if (signal != 0) {' . chr(10) . ' // invalid' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' signal = 1;' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . '-' . chr(39) . ': // starts with -' . chr(10) . ' if (signal != 0) {' . chr(10) . ' // invalid' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' signal = -1;' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . ' ' . chr(39) . ': case ' . chr(39) . chr(92) . 't' . chr(39) . ': case ' . chr(39) . chr(92) . 'n' . chr(39) . ': case ' . chr(39) . chr(92) . 'r' . chr(39) . ':' . chr(10) . ' // starts with space' . chr(10) . ' if (signal != 0) {' . chr(10) . ' // invalid' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' break;' . chr(10) . ' default: // invalid' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' offset++;' . chr(10) . ' }' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' public long to_long() {' . chr(10) . ' return this.parse().to_long();' . chr(10) . ' }' . chr(10) . ' public double to_double() {' . chr(10) . ' return this.parse().to_double();' . chr(10) . ' }' . chr(10) . ' public String toString() {' . chr(10) . ' return this.s;' . chr(10) . ' }' . chr(10) . ' public boolean to_bool() {' . chr(10) . ' return this.s != ""' . chr(10) . ' && this.s != "0";' . chr(10) . ' }' . chr(10) . ' public boolean is_string() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public PlObject _decr() {' . chr(10) . ' // --$x' . chr(10) . ' return this.add(PlCx.MIN1);' . chr(10) . ' }' . chr(10) . chr(10) . ' // $x++ when $x is PlString' . chr(10) . ' private static final String _string_increment(String s) {' . chr(10) . ' if (s.length() < 2) {' . chr(10) . ' final int c = s.codePointAt(0);' . chr(10) . ' if ((c >= ' . chr(39) . '0' . chr(39) . ' && c <= ' . chr(39) . '8' . chr(39) . ') || (c >= ' . chr(39) . 'A' . chr(39) . ' && c <= ' . chr(39) . 'Y' . chr(39) . ') || (c >= ' . chr(39) . 'a' . chr(39) . ' && c <= ' . chr(39) . 'y' . chr(39) . ')) {' . chr(10) . ' return "" + (char)(c + 1);' . chr(10) . ' }' . chr(10) . ' if (c == ' . chr(39) . '9' . chr(39) . ') {' . chr(10) . ' return "10";' . chr(10) . ' }' . chr(10) . ' if (c == ' . chr(39) . 'Z' . chr(39) . ') {' . chr(10) . ' return "AA";' . chr(10) . ' }' . chr(10) . ' if (c == ' . chr(39) . 'z' . chr(39) . ') {' . chr(10) . ' return "aa";' . chr(10) . ' }' . chr(10) . ' return "1";' . chr(10) . ' }' . chr(10) . ' String c = _string_increment(s.substring(s.length()-1, s.length()));' . chr(10) . ' if (c.length() == 1) {' . chr(10) . ' return s.substring(0, s.length()-1) + c;' . chr(10) . ' }' . chr(10) . ' return _string_increment(s.substring(0, s.length()-1)) + c.substring(c.length()-1, c.length());' . chr(10) . ' }' . chr(10) . ' public PlObject _incr() {' . chr(10) . ' // ++$x' . chr(10) . ' final int length = s.length();' . chr(10) . ' if (length == 0) {' . chr(10) . ' return PlCx.INT1;' . chr(10) . ' }' . chr(10) . ' int c = this.s.codePointAt(0);' . chr(10) . ' switch (c) { ' . chr(10) . ' case ' . chr(39) . ' ' . chr(39) . ': case ' . chr(39) . chr(92) . 't' . chr(39) . ': case ' . chr(39) . chr(92) . 'n' . chr(39) . ': case ' . chr(39) . chr(92) . 'r' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '+' . chr(39) . ': case ' . chr(39) . '-' . chr(39) . ': case ' . chr(39) . '.' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' return this.add(PlCx.INT1);' . chr(10) . ' }' . chr(10) . ' c = s.codePointAt(length - 1);' . chr(10) . ' if ((c >= ' . chr(39) . '0' . chr(39) . ' && c <= ' . chr(39) . '8' . chr(39) . ') || (c >= ' . chr(39) . 'A' . chr(39) . ' && c <= ' . chr(39) . 'Y' . chr(39) . ') || (c >= ' . chr(39) . 'a' . chr(39) . ' && c <= ' . chr(39) . 'y' . chr(39) . ')) {' . chr(10) . ' return new PlString(s.substring(0, length-1) + (char)(c + 1));' . chr(10) . ' }' . chr(10) . ' return new PlString(_string_increment(this.s));' . chr(10) . ' }' . chr(10) . ' public PlObject neg() {' . chr(10) . ' final int length = s.length();' . chr(10) . ' if (length == 0) {' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' final int c = this.s.codePointAt(0);' . chr(10) . ' switch (c) { ' . chr(10) . ' case ' . chr(39) . '+' . chr(39) . ': case ' . chr(39) . '-' . chr(39) . ':' . chr(10) . ' if (c == ' . chr(39) . '+' . chr(39) . ') {' . chr(10) . ' return new PlString( ' . chr(39) . '-' . chr(39) . ' + s.substring(1) );' . chr(10) . ' }' . chr(10) . ' if (c == ' . chr(39) . '-' . chr(39) . ') {' . chr(10) . ' return new PlString( ' . chr(39) . '+' . chr(39) . ' + s.substring(1) );' . chr(10) . ' }' . chr(10) . ' case ' . chr(39) . '.' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . ' ' . chr(39) . ': case ' . chr(39) . chr(92) . 't' . chr(39) . ': case ' . chr(39) . chr(92) . 'n' . chr(39) . ': case ' . chr(39) . chr(92) . 'r' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' return this.parse().neg();' . chr(10) . ' }' . chr(10) . ' if ((c >= ' . chr(39) . 'A' . chr(39) . ' && c <= ' . chr(39) . 'Z' . chr(39) . ') || (c >= ' . chr(39) . 'a' . chr(39) . ' && c <= ' . chr(39) . 'z' . chr(39) . ')) {' . chr(10) . ' return new PlString( ' . chr(39) . '-' . chr(39) . ' + s );' . chr(10) . ' }' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' public PlObject abs() {' . chr(10) . ' return this.parse().abs();' . chr(10) . ' }' . chr(10) . ' public PlObject num_cmp(PlObject b) {' . chr(10) . ' return this.parse().num_cmp(b);' . chr(10) . ' }' . chr(10) . ' public PlObject num_cmp2(PlObject b) {' . chr(10) . ' return b.num_cmp2(this.parse());' . chr(10) . ' }' . chr(10) . (join('', map { + } keys(%number_binop))) . ' public boolean is_num() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . '}' . chr(10) . 'class PlString extends PlObject {' . chr(10) . ' private java.lang.String s;' . chr(10) . ' private PlObject numericValue;' . chr(10) . ' private boolean hasValue;' . chr(10) . chr(10) . ' public PlString(String s) {' . chr(10) . ' this.s = s;' . chr(10) . ' }' . chr(10) . ' public PlString(char s) {' . chr(10) . ' this.s = "" + s;' . chr(10) . ' }' . chr(10) . ' public PlObject parse() {' . chr(10) . ' if (!hasValue) {' . chr(10) . ' hasValue = true;' . chr(10) . ' numericValue = this._parse();' . chr(10) . ' }' . chr(10) . ' return numericValue;' . chr(10) . ' }' . chr(10) . ' private PlObject _parse_exp(int length, int signal, int offset, int next) {' . chr(10) . ' // 123.45E^^^' . chr(10) . ' int offset3 = next;' . chr(10) . ' for ( ; offset3 < length; ) {' . chr(10) . ' final int c3 = s.codePointAt(offset3);' . chr(10) . ' switch (c3) {' . chr(10) . ' case ' . chr(39) . '+' . chr(39) . ': case ' . chr(39) . '-' . chr(39) . ':' . chr(10) . ' // TODO' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' break;' . chr(10) . ' default: // invalid' . chr(10) . ' return new PlDouble(Double.parseDouble(this.s.substring(0, offset3)));' . chr(10) . ' }' . chr(10) . ' offset3++;' . chr(10) . ' }' . chr(10) . ' return new PlDouble(Double.parseDouble(this.s.substring(0, offset3)));' . chr(10) . ' }' . chr(10) . ' private PlObject _parse_dot(int length, int signal, int offset, int next) {' . chr(10) . ' // 123.^^^' . chr(10) . ' int offset3 = next;' . chr(10) . ' for ( ; offset3 < length; ) {' . chr(10) . ' final int c3 = s.codePointAt(offset3);' . chr(10) . ' switch (c3) {' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . 'E' . chr(39) . ': case ' . chr(39) . 'e' . chr(39) . ':' . chr(10) . ' // start exponential part' . chr(10) . ' return _parse_exp(length, signal, offset, offset3+1);' . chr(10) . ' default: // invalid' . chr(10) . ' return new PlDouble(Double.parseDouble(this.s.substring(0, offset3)));' . chr(10) . ' }' . chr(10) . ' offset3++;' . chr(10) . ' }' . chr(10) . ' return new PlDouble(Double.parseDouble(this.s.substring(0, offset3)));' . chr(10) . ' }' . chr(10) . ' private PlObject _parse() {' . chr(10) . ' final int length = s.length();' . chr(10) . ' int signal = 0;' . chr(10) . ' for (int offset = 0; offset < length; ) {' . chr(10) . ' final int c = s.codePointAt(offset);' . chr(10) . ' switch (c) {' . chr(10) . ' case ' . chr(39) . 'i' . chr(39) . ': case ' . chr(39) . 'I' . chr(39) . ':' . chr(10) . ' if (this.s.substring(offset, offset+3).equalsIgnoreCase("inf")) {' . chr(10) . ' if (signal < 0) {' . chr(10) . ' return new PlDouble(Double.NEGATIVE_INFINITY);' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return new PlDouble(Double.POSITIVE_INFINITY);' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' case ' . chr(39) . 'n' . chr(39) . ': case ' . chr(39) . 'N' . chr(39) . ':' . chr(10) . ' if (this.s.substring(offset, offset+3).equalsIgnoreCase("nan")) {' . chr(10) . ' return new PlDouble(Double.NaN);' . chr(10) . ' }' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' case ' . chr(39) . '.' . chr(39) . ': // starts with dot' . chr(10) . ' if (signal != 0) {' . chr(10) . ' signal = 1;' . chr(10) . ' }' . chr(10) . ' return _parse_dot(length, signal, offset, offset+1);' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' // starts with number' . chr(10) . ' if (signal == 0) {' . chr(10) . ' signal = 1;' . chr(10) . ' }' . chr(10) . ' int offset2 = offset+1;' . chr(10) . ' for ( ; offset2 < length; ) {' . chr(10) . ' final int c2 = s.codePointAt(offset2);' . chr(10) . ' switch (c2) {' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' // more numbers' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . '.' . chr(39) . ':' . chr(10) . ' // start decimal part' . chr(10) . ' return _parse_dot(length, signal, offset, offset2+1);' . chr(10) . ' case ' . chr(39) . 'E' . chr(39) . ': case ' . chr(39) . 'e' . chr(39) . ':' . chr(10) . ' // start exponential part' . chr(10) . ' return _parse_exp(length, signal, offset, offset2+1);' . chr(10) . ' default:' . chr(10) . ' // return integer' . chr(10) . ' if (signal < 0) {' . chr(10) . ' return new PlInt(-Integer.parseInt(this.s.substring(offset, offset2)));' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return new PlInt(Integer.parseInt(this.s.substring(offset, offset2)));' . chr(10) . ' }' . chr(10) . ' }' . chr(10) . ' offset2++;' . chr(10) . ' }' . chr(10) . ' // integer' . chr(10) . ' if (signal < 0) {' . chr(10) . ' return new PlInt(-Integer.parseInt(this.s.substring(offset, offset2)));' . chr(10) . ' }' . chr(10) . ' else {' . chr(10) . ' return new PlInt(Integer.parseInt(this.s.substring(offset, offset2)));' . chr(10) . ' }' . chr(10) . ' case ' . chr(39) . '+' . chr(39) . ': // starts with +' . chr(10) . ' if (signal != 0) {' . chr(10) . ' // invalid' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' signal = 1;' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . '-' . chr(39) . ': // starts with -' . chr(10) . ' if (signal != 0) {' . chr(10) . ' // invalid' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' signal = -1;' . chr(10) . ' break;' . chr(10) . ' case ' . chr(39) . ' ' . chr(39) . ': case ' . chr(39) . chr(92) . 't' . chr(39) . ': case ' . chr(39) . chr(92) . 'n' . chr(39) . ': case ' . chr(39) . chr(92) . 'r' . chr(39) . ':' . chr(10) . ' // starts with space' . chr(10) . ' if (signal != 0) {' . chr(10) . ' // invalid' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' break;' . chr(10) . ' default: // invalid' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' offset++;' . chr(10) . ' }' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' public long to_long() {' . chr(10) . ' return this.parse().to_long();' . chr(10) . ' }' . chr(10) . ' public double to_double() {' . chr(10) . ' return this.parse().to_double();' . chr(10) . ' }' . chr(10) . ' public String toString() {' . chr(10) . ' return this.s;' . chr(10) . ' }' . chr(10) . ' public boolean to_bool() {' . chr(10) . ' return this.s != ""' . chr(10) . ' && this.s != "0";' . chr(10) . ' }' . chr(10) . ' public boolean is_string() {' . chr(10) . ' return true;' . chr(10) . ' }' . chr(10) . ' public PlObject _decr() {' . chr(10) . ' // --$x' . chr(10) . ' return this.add(PlCx.MIN1);' . chr(10) . ' }' . chr(10) . chr(10) . ' // $x++ when $x is PlString' . chr(10) . ' private static final String _string_increment(String s) {' . chr(10) . ' if (s.length() < 2) {' . chr(10) . ' final int c = s.codePointAt(0);' . chr(10) . ' if ((c >= ' . chr(39) . '0' . chr(39) . ' && c <= ' . chr(39) . '8' . chr(39) . ') || (c >= ' . chr(39) . 'A' . chr(39) . ' && c <= ' . chr(39) . 'Y' . chr(39) . ') || (c >= ' . chr(39) . 'a' . chr(39) . ' && c <= ' . chr(39) . 'y' . chr(39) . ')) {' . chr(10) . ' return "" + (char)(c + 1);' . chr(10) . ' }' . chr(10) . ' if (c == ' . chr(39) . '9' . chr(39) . ') {' . chr(10) . ' return "10";' . chr(10) . ' }' . chr(10) . ' if (c == ' . chr(39) . 'Z' . chr(39) . ') {' . chr(10) . ' return "AA";' . chr(10) . ' }' . chr(10) . ' if (c == ' . chr(39) . 'z' . chr(39) . ') {' . chr(10) . ' return "aa";' . chr(10) . ' }' . chr(10) . ' return "1";' . chr(10) . ' }' . chr(10) . ' String c = _string_increment(s.substring(s.length()-1, s.length()));' . chr(10) . ' if (c.length() == 1) {' . chr(10) . ' return s.substring(0, s.length()-1) + c;' . chr(10) . ' }' . chr(10) . ' return _string_increment(s.substring(0, s.length()-1)) + c.substring(c.length()-1, c.length());' . chr(10) . ' }' . chr(10) . ' public PlObject _incr() {' . chr(10) . ' // ++$x' . chr(10) . ' final int length = s.length();' . chr(10) . ' if (length == 0) {' . chr(10) . ' return PlCx.INT1;' . chr(10) . ' }' . chr(10) . ' int c = this.s.codePointAt(0);' . chr(10) . ' switch (c) {' . chr(10) . ' case ' . chr(39) . ' ' . chr(39) . ': case ' . chr(39) . chr(92) . 't' . chr(39) . ': case ' . chr(39) . chr(92) . 'n' . chr(39) . ': case ' . chr(39) . chr(92) . 'r' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '+' . chr(39) . ': case ' . chr(39) . '-' . chr(39) . ': case ' . chr(39) . '.' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' return this.add(PlCx.INT1);' . chr(10) . ' }' . chr(10) . ' c = s.codePointAt(length - 1);' . chr(10) . ' if ((c >= ' . chr(39) . '0' . chr(39) . ' && c <= ' . chr(39) . '8' . chr(39) . ') || (c >= ' . chr(39) . 'A' . chr(39) . ' && c <= ' . chr(39) . 'Y' . chr(39) . ') || (c >= ' . chr(39) . 'a' . chr(39) . ' && c <= ' . chr(39) . 'y' . chr(39) . ')) {' . chr(10) . ' return new PlString(s.substring(0, length-1) + (char)(c + 1));' . chr(10) . ' }' . chr(10) . ' return new PlString(_string_increment(this.s));' . chr(10) . ' }' . chr(10) . ' public PlObject neg() {' . chr(10) . ' final int length = s.length();' . chr(10) . ' if (length == 0) {' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' final int c = this.s.codePointAt(0);' . chr(10) . ' switch (c) {' . chr(10) . ' case ' . chr(39) . '+' . chr(39) . ': case ' . chr(39) . '-' . chr(39) . ':' . chr(10) . ' if (c == ' . chr(39) . '+' . chr(39) . ') {' . chr(10) . ' return new PlString( ' . chr(39) . '-' . chr(39) . ' + s.substring(1) );' . chr(10) . ' }' . chr(10) . ' if (c == ' . chr(39) . '-' . chr(39) . ') {' . chr(10) . ' return new PlString( ' . chr(39) . '+' . chr(39) . ' + s.substring(1) );' . chr(10) . ' }' . chr(10) . ' case ' . chr(39) . '.' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . ' ' . chr(39) . ': case ' . chr(39) . chr(92) . 't' . chr(39) . ': case ' . chr(39) . chr(92) . 'n' . chr(39) . ': case ' . chr(39) . chr(92) . 'r' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '0' . chr(39) . ': case ' . chr(39) . '1' . chr(39) . ': case ' . chr(39) . '2' . chr(39) . ': case ' . chr(39) . '3' . chr(39) . ': case ' . chr(39) . '4' . chr(39) . ':' . chr(10) . ' case ' . chr(39) . '5' . chr(39) . ': case ' . chr(39) . '6' . chr(39) . ': case ' . chr(39) . '7' . chr(39) . ': case ' . chr(39) . '8' . chr(39) . ': case ' . chr(39) . '9' . chr(39) . ':' . chr(10) . ' return this.parse().neg();' . chr(10) . ' }' . chr(10) . ' if ((c >= ' . chr(39) . 'A' . chr(39) . ' && c <= ' . chr(39) . 'Z' . chr(39) . ') || (c >= ' . chr(39) . 'a' . chr(39) . ' && c <= ' . chr(39) . 'z' . chr(39) . ')) {' . chr(10) . ' return new PlString( ' . chr(39) . '-' . chr(39) . ' + s );' . chr(10) . ' }' . chr(10) . ' return PlCx.INT0;' . chr(10) . ' }' . chr(10) . ' public PlObject abs() {' . chr(10) . ' return this.parse().abs();' . chr(10) . ' }' . chr(10) . ' public PlObject num_cmp(PlObject b) {' . chr(10) . ' return this.parse().num_cmp(b);' . chr(10) . ' }' . chr(10) . ' public PlObject num_cmp2(PlObject b) {' . chr(10) . ' return b.num_cmp2(this.parse());' . chr(10) . ' }' . chr(10) . (join('', map { my $perl = $_; my $native = $number_binop{$perl}->{'op'}; my $returns = $number_binop{$perl}->{'returns'}; diff --git a/src5/lib/Perlito5/Java/Runtime.pm b/src5/lib/Perlito5/Java/Runtime.pm index d078f6040..ee9f20bd6 100644 --- a/src5/lib/Perlito5/Java/Runtime.pm +++ b/src5/lib/Perlito5/Java/Runtime.pm @@ -1412,18 +1412,21 @@ class PlReference extends PlObject { } class PlRegex extends PlReference { public Pattern p; + public String original_string; // public Matcher m; public static final PlString REF = new PlString("Regexp"); public PlRegex(String p, int flags) { - this.p = Pattern.compile(PerlOp.character_class_escape(p), flags); + this.original_string = p; + this.p = Pattern.compile(PerlOp.character_class_escape(this.original_string), flags); } public PlRegex(PlObject p, int flags) { - this.p = Pattern.compile(PerlOp.character_class_escape(p.toString()), flags); + this.original_string = p.toString(); + this.p = Pattern.compile(PerlOp.character_class_escape(this.original_string), flags); } public String toString() { // TODO - show flags - return this.p.toString(); + return this.original_string; } } class PlClosure extends PlReference implements Runnable {