Revision: 4114 http://vexi.svn.sourceforge.net/vexi/?rev=4114&view=rev Author: mkpg2 Date: 2011-05-09 02:44:41 +0000 (Mon, 09 May 2011)
Log Message: ----------- Feature. New built in type, decimal. For precise arithmetic. Modified Paths: -------------- trunk/org.vexi-library.js/src/main/java/org/ibex/js/Constants.java trunk/org.vexi-library.js/src/main/java/org/ibex/js/JSNumber.java trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/Interpreter.jpp trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSDate.jpp trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSU.jpp trunk/org.vexi-library.js/src/main/jpp/org/vexi/js/VexiJS.jpp Added Paths: ----------- trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSDecimal.jpp trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/ trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/TestDecimal.java trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/lib.js trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/methods.js Modified: trunk/org.vexi-library.js/src/main/java/org/ibex/js/Constants.java =================================================================== --- trunk/org.vexi-library.js/src/main/java/org/ibex/js/Constants.java 2011-04-30 22:12:52 UTC (rev 4113) +++ trunk/org.vexi-library.js/src/main/java/org/ibex/js/Constants.java 2011-05-09 02:44:41 UTC (rev 4114) @@ -9,6 +9,7 @@ static final JS SC_cause = JSU.S("cause",true); static final JS SC_code = JSU.S("code",true); static final JS SC_date = JSU.S("date",true); + static final JS SC_decimal = JSU.S("decimal",true); static final JS SC_Elements = JSU.S("Elements",true); static final JS SC_error = JSU.S("error",true); static final JS SC_eval = JSU.S("eval",true); Modified: trunk/org.vexi-library.js/src/main/java/org/ibex/js/JSNumber.java =================================================================== --- trunk/org.vexi-library.js/src/main/java/org/ibex/js/JSNumber.java 2011-04-30 22:12:52 UTC (rev 4113) +++ trunk/org.vexi-library.js/src/main/java/org/ibex/js/JSNumber.java 2011-05-09 02:44:41 UTC (rev 4114) @@ -12,7 +12,7 @@ } if (o instanceof JSNumber) { JSNumber n = (JSNumber) o; - if (this instanceof D || n instanceof D) { + if (isFraction() || n.isFraction()) { return n.toDouble() == toDouble(); } return n.toLong() == toLong(); @@ -51,6 +51,7 @@ public int hashCode() { return toInt(); } abstract int toInt(); + boolean isFraction(){ return false; } long toLong() { return toInt(); } boolean toBoolean() { return toInt() != 0; } double toDouble() { return toLong(); } @@ -75,6 +76,7 @@ final static class D extends JSNumber { private final double d; D(double d) { this.d = d; } + boolean isFraction(){ return true; } int toInt() { return (int) d; } long toLong() { return (long) d; } double toDouble() { return d; } @@ -127,4 +129,6 @@ } public JS type() { return SC_number; } public boolean instanceOf(JS constructor) { return constructor==Constructor; } + + } Modified: trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/Interpreter.jpp =================================================================== --- trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/Interpreter.jpp 2011-04-30 22:12:52 UTC (rev 4113) +++ trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/Interpreter.jpp 2011-05-09 02:44:41 UTC (rev 4114) @@ -538,7 +538,7 @@ JS ret; if(left instanceof JSString || right instanceof JSString) ret = JSU.S(JSU.toString(left).concat(JSU.toString(right))); - else if(left instanceof JSNumber.D || right instanceof JSNumber.D) + else if(JSU.isFraction(left) || JSU.isFraction(right)) ret = JSU.N(JSU.toDouble(left) + JSU.toDouble(right)); else { long l = JSU.toLong(left) + JSU.toLong(right); Modified: trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSDate.jpp =================================================================== --- trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSDate.jpp 2011-04-30 22:12:52 UTC (rev 4113) +++ trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSDate.jpp 2011-05-09 02:44:41 UTC (rev 4114) @@ -48,8 +48,8 @@ static public JS Constructor = new JS.Constructor("Date") { public JS new_(JS[] args) throws JSExn { - if (args.length==1) new JSDate((int)JSU.toLong(args[0])); - return new JSArray(args); + throw new JSExn("Unimplemented!"); + // REMARK trivial to implement, but considering replacing the date with a better object } }; public boolean instanceOf(JS constructor){ return constructor==Constructor; } Added: trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSDecimal.jpp =================================================================== --- trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSDecimal.jpp (rev 0) +++ trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSDecimal.jpp 2011-05-09 02:44:41 UTC (rev 4114) @@ -0,0 +1,180 @@ +/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Rhino code, released + * May 6, 1999. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1997-1999 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Norris Boyd + * Mike McCabe + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU Public License (the "GPL"), in which case the + * provisions of the GPL are applicable instead of those above. + * If you wish to allow use of your version of this file only + * under the terms of the GPL and not to allow others to use your + * version of this file under the NPL, indicate your decision by + * deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete + * the provisions above, a recipient may use your version of this + * file under either the NPL or the GPL. + */ + +package org.ibex.js; + +import java.math.*; + +/** + * This class implements the Date native object. + * See ECMA 15.9. + * @author Mike McCabe + * @author Adam Megacz (many modifications + */ +public class JSDecimal extends JS.Immutable { + + static public JS Constructor = new JS.Constructor("Decimal") { + private BigDecimal tryParseString(JS arg){ + try{ + return new BigDecimal(JSU.toString(arg)); + }catch(NumberFormatException e){ + return null; + } + } + private BigDecimal cast(JS[] args, int index) throws JSExn{ + JS arg = (args.length<=index)?null:args[index]; + if(arg instanceof JSDecimal) { + return ((JSDecimal)arg).decimal; + }else if(arg instanceof JSNumber) { + if(JSU.isInt(arg)){ + return new BigDecimal(JSU.toLong(arg)); + }else{ + return new BigDecimal(JSU.toDouble(arg)); + } + }else{ + BigDecimal r = tryParseString(arg); + if(r!=null) return r; + } + throw new JSExn("Expected argument "+index+" to be valid decimal, got: "+JSU.toString(arg)); + + } + + public JS new_(JS[] args) throws JSExn { + BigDecimal arg; + if(args.length>0) arg = cast(args,0); + else arg = new BigDecimal(0); + return new JSDecimal(arg); + } + + public JS get(JS key) throws JSExn { + //#switch(JSU.toString(key)) + case "add": return METHOD; + case "compare": return METHOD; + case "divide": return METHOD; + case "max": return METHOD; + case "min": return METHOD; + case "multiply": return METHOD; + case "remainder": return METHOD; + case "subtract": return METHOD; + + case "tryParseString": return METHOD; + //#end + return super.get(key); + } + + public JS callMethod(JS this_, JS method, JS[] args) throws JSExn { + String methodStr = JSU.toString(method); + if(args.length==1){ + if("tryParseString".equals(methodStr)){ + BigDecimal r = tryParseString(args[0]); + if(r==null) return null; + return new JSDecimal(r); + } + } + + if(args.length>=2){ + BigDecimal a = cast(args,0); + BigDecimal b = cast(args,1); + + //#switch(methodStr) + case "add": return new JSDecimal(a.add(b)); + case "compare": return JSU.N(a.compareTo(b)); + case "divide": return new JSDecimal(a.divide(b, a.scale(), RoundingMode.HALF_UP)); + case "max": return new JSDecimal(a.max(b)); + case "min": return new JSDecimal(a.min(b)); + case "multiply": return new JSDecimal(a.multiply(b)); + case "remainder": return new JSDecimal(a.remainder(b)); + case "subtract": return new JSDecimal(a.subtract(b)); + //#end + } + return super.callMethod(this_, method, args); + } + + + }; + public boolean instanceOf(JS constructor){ return constructor==Constructor; } + public void addConstructor(JS constructor) throws JSExn {throw new JSExn("Attemted to add constructor to decimal"); } + + final BigDecimal decimal; + private JSDecimal(BigDecimal decimal) { + this.decimal = decimal; + } + + public String coerceToString() { return decimal.toPlainString(); } + public JS type() { return SC_decimal; } + + + public JS get(JS key) throws JSExn { + //#switch(JSU.toString(key)) + case "abs": return new JSDecimal(decimal.abs()); + case "after": return JSU.N(decimal.scale()); + case "before": return JSU.N(decimal.precision() - decimal.scale()); + case "negative": return new JSDecimal(decimal.negate()); + + case "precision": return JSU.N(decimal.precision()); + case "scale": return JSU.N(decimal.scale()); + + case "number": + if(decimal.stripTrailingZeros().scale()==0){ + return JSU.N(decimal.intValue()); + } + return JSU.N(decimal.doubleValue()); + case "pow": return METHOD; + case "round": return METHOD; + case "canonical": return new JSDecimal(decimal.stripTrailingZeros()); + case "engineeringString": return JSU.S(decimal.toEngineeringString()); + //#end + return super.get(key); + } + + + public JS callMethod(JS this_, JS method, JS[] args) throws JSExn { + if(args.length>=1){ + int n = JSU.toInt(args[0]); + //#switch(JSU.toString(method)) + case "pow": return new JSDecimal(decimal.pow(n)); + case "round": return new JSDecimal(decimal.setScale(n, RoundingMode.HALF_UP)); + //#end + } + return super.callMethod(this_, method, args); + } + + // REMARK may implement JSNumber +// int toInt() { return decimal.intValue(); } +// long toLong(){ return decimal.longValue(); } +// double toDouble() { return decimal.doubleValue(); } + +} Modified: trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSU.jpp =================================================================== --- trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSU.jpp 2011-04-30 22:12:52 UTC (rev 4113) +++ trunk/org.vexi-library.js/src/main/jpp/org/ibex/js/JSU.jpp 2011-05-09 02:44:41 UTC (rev 4114) @@ -134,6 +134,14 @@ return false; } + public static boolean isFraction(JS o) { + if(o instanceof JSNumber) { + return ((JSNumber)o).isFraction(); + }else{ + return false; + } + } + public static boolean isString(JS o) { if(o instanceof JSString) return true; return false; Modified: trunk/org.vexi-library.js/src/main/jpp/org/vexi/js/VexiJS.jpp =================================================================== --- trunk/org.vexi-library.js/src/main/jpp/org/vexi/js/VexiJS.jpp 2011-04-30 22:12:52 UTC (rev 4113) +++ trunk/org.vexi-library.js/src/main/jpp/org/vexi/js/VexiJS.jpp 2011-05-09 02:44:41 UTC (rev 4114) @@ -526,6 +526,7 @@ case "Array": return org.ibex.js.JSArray.Constructor; case "Boolean": return org.ibex.js.JSNumber.B.Constructor; case "Date": return org.ibex.js.JSDate.Constructor; + case "Decimal": return org.ibex.js.JSDecimal.Constructor; case "Exception": return org.ibex.js.JSExn.Constructor; case "Object": return org.ibex.js.JS.Obj.Constructor; case "Number": return org.ibex.js.JSNumber.Constructor; Added: trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/TestDecimal.java =================================================================== --- trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/TestDecimal.java (rev 0) +++ trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/TestDecimal.java 2011-05-09 02:44:41 UTC (rev 4114) @@ -0,0 +1,23 @@ +package test.js.exec.decimal; + +import junit.framework.Test; +import junit.framework.TestCase; +import test.js.exec.JSTestSuite; + +/** + * @author mike + */ +public class TestDecimal{ + + public static void main(String[] args) throws Throwable { + JSTestSuite jts = new JSTestSuite(TestDecimal.class); + String SCRIPT = "methods.js"; + //String SCRIPT = "testNumber2String.js"; + TestCase t = jts.createTestCase(jts.getResourceDirs(), SCRIPT); + t.runBare(); + } + + public static Test suite() { + return JSTestSuite.suite(TestDecimal.class); + } +} Property changes on: trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/TestDecimal.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/lib.js =================================================================== --- trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/lib.js (rev 0) +++ trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/lib.js 2011-05-09 02:44:41 UTC (rev 4114) @@ -0,0 +1,17 @@ +export.assertUndefined = function(v){ + if(v==null) + return; + sys.log.info("Expected null, got " + v); + assert(false); +}; + +export.assertEquals = function(a,b){ + if(a==b) + return; + sys.log.info("Expected equals: " + a + " != " + b); + assert(false); +}; + +export.skip = function(msg){ + sys.log.info("SKIPPING : " + msg); +}; Property changes on: trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/lib.js ___________________________________________________________________ Added: svn:mime-type + text/plain Added: trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/methods.js =================================================================== --- trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/methods.js (rev 0) +++ trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/methods.js 2011-05-09 02:44:41 UTC (rev 4114) @@ -0,0 +1,31 @@ +sys.import("lib"); + +const Decimal = sys.js.Decimal; + +const d123 = new Decimal("123"); +const d1_23 = new Decimal("1.23"); + +assertEquals(0, d123.scale); +assertEquals(2, d1_23.scale); + +assertEquals("124.23", Decimal.add(d123,d1_23)+""); +assertEquals("123", Decimal.max(d123,d1_23)+""); +assertEquals("1.23", Decimal.min(d123,d1_23)+""); +assertEquals("121.77", Decimal.subtract(d123,d1_23)+""); +assertEquals("151.29", Decimal.multiply(d123,d1_23)+""); +assertEquals("100", Decimal.divide(d123,d1_23)+""); +assertEquals("123.0000", d123.round(4)+""); +assertEquals("-123.0000", d123.round(4).negative+""); +assertEquals("1.2", d1_23.round(1)+""); +assertEquals("102.5000", Decimal.divide(d123.round(4),d1_23.round(1))+""); +assertEquals("102.5", Decimal.divide(d123.round(4),d1_23.round(1)).canonical+""); + +assertEquals(null, Decimal.tryParseString("abc")); +assertEquals("-0.1", Decimal.tryParseString("-.1")+""); +//assertEquals("-0.1", Decimal.tryParseString("-.")+""); + +//assertEquals("102.5000", Decimal.remainder(d123.round(4),d1_23.round(1))+""); + + +assert(0 < Decimal.compare(d123,d1_23)); +assert(0 > Decimal.compare(d1_23,d123)); Property changes on: trunk/org.vexi-library.js/src/test/java/test/js/exec/decimal/methods.js ___________________________________________________________________ Added: svn:mime-type + text/plain This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ WhatsUp Gold - Download Free Network Management Software The most intuitive, comprehensive, and cost-effective network management toolset available today. Delivers lowest initial acquisition cost and overall TCO of any competing solution. http://p.sf.net/sfu/whatsupgold-sd _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn