diff --git a/lib/Makefile.am b/lib/Makefile.am index 5d0e7f7..66a6da4 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -56,6 +56,7 @@ libhcl_la_SOURCES = \ hcl.c \ heap.c \ logfmt.c \ + number.c \ obj.c \ opt-imp.h \ opt.c \ diff --git a/lib/Makefile.in b/lib/Makefile.in index ddd8e03..39e9f5b 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -160,10 +160,10 @@ am_libhcl_la_OBJECTS = libhcl_la-bigint.lo libhcl_la-comp.lo \ libhcl_la-debug.lo libhcl_la-decode.lo libhcl_la-dic.lo \ libhcl_la-err.lo libhcl_la-exec.lo libhcl_la-gc.lo \ libhcl_la-hcl.lo libhcl_la-heap.lo libhcl_la-logfmt.lo \ - libhcl_la-obj.lo libhcl_la-opt.lo libhcl_la-prim.lo \ - libhcl_la-print.lo libhcl_la-rbt.lo libhcl_la-read.lo \ - libhcl_la-sym.lo libhcl_la-tmr.lo libhcl_la-utf8.lo \ - libhcl_la-utl.lo + libhcl_la-number.lo libhcl_la-obj.lo libhcl_la-opt.lo \ + libhcl_la-prim.lo libhcl_la-print.lo libhcl_la-rbt.lo \ + libhcl_la-read.lo libhcl_la-sym.lo libhcl_la-tmr.lo \ + libhcl_la-utf8.lo libhcl_la-utl.lo libhcl_la_OBJECTS = $(am_libhcl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -420,6 +420,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -468,6 +469,7 @@ libhcl_la_SOURCES = \ hcl.c \ heap.c \ logfmt.c \ + number.c \ obj.c \ opt-imp.h \ opt.c \ @@ -684,6 +686,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-hcl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-heap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-logfmt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-number.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-obj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-opt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-prim.Plo@am__quote@ @@ -798,6 +801,13 @@ libhcl_la-logfmt.lo: logfmt.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-logfmt.lo `test -f 'logfmt.c' || echo '$(srcdir)/'`logfmt.c +libhcl_la-number.lo: number.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-number.lo -MD -MP -MF $(DEPDIR)/libhcl_la-number.Tpo -c -o libhcl_la-number.lo `test -f 'number.c' || echo '$(srcdir)/'`number.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-number.Tpo $(DEPDIR)/libhcl_la-number.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='number.c' object='libhcl_la-number.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-number.lo `test -f 'number.c' || echo '$(srcdir)/'`number.c + libhcl_la-obj.lo: obj.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-obj.lo -MD -MP -MF $(DEPDIR)/libhcl_la-obj.Tpo -c -o libhcl_la-obj.lo `test -f 'obj.c' || echo '$(srcdir)/'`obj.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-obj.Tpo $(DEPDIR)/libhcl_la-obj.Plo diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index 94cfb20..e10001f 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -831,7 +831,7 @@ int hcl_utf8toucs ( ); /* ========================================================================= */ -/* bigint.c TODO: remove bigint */ +/* bigint.c */ /* ========================================================================= */ int hcl_isint ( hcl_t* hcl, @@ -963,6 +963,20 @@ hcl_oop_t hcl_inttostr ( int ngc ); +/* ========================================================================= */ +/* number.c */ +/* ========================================================================= */ +hcl_oop_t hcl_addnums ( + hcl_t* hcl, + hcl_oop_t x, + hcl_oop_t y +); + +hcl_oop_t hcl_subnums ( + hcl_t* hcl, + hcl_oop_t x, + hcl_oop_t y +); /* ========================================================================= */ /* comp.c */ /* ========================================================================= */ diff --git a/lib/hcl.h b/lib/hcl.h index abca4d4..b33b118 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -1435,6 +1435,7 @@ typedef enum hcl_concode_t hcl_concode_t; #define HCL_IS_NBIGINT(hcl,v) (HCL_OOP_IS_POINTER(v) && HCL_OBJ_GET_FLAGS_BRAND(v) == HCL_BRAND_NBIGINT) #define HCL_IS_BIGINT(hcl,v) (HCL_OOP_IS_POINTER(v) && (HCL_OBJ_GET_FLAGS_BRAND(v) == HCL_BRAND_PBIGINT || HCL_OBJ_GET_FLAGS_BRAND(v) == HCL_BRAND_NBIGINT)) #define HCL_IS_STRING(hcl,v) (HCL_OOP_IS_POINTER(v) && HCL_OBJ_GET_FLAGS_BRAND(v) == HCL_BRAND_STRING) +#define HCL_IS_FPDEC(hcl,v) (HCL_OOP_IS_POINTER(v) && HCL_OBJ_GET_FLAGS_BRAND(v) == HCL_BRAND_FPDEC) #define HCL_CONS_CAR(v) (((hcl_cons_t*)(v))->car) #define HCL_CONS_CDR(v) (((hcl_cons_t*)(v))->cdr) @@ -1905,6 +1906,12 @@ HCL_EXPORT hcl_oop_t hcl_makestring ( int ngc ); +HCL_EXPORT hcl_oop_t hcl_makefpdec ( + hcl_t* hcl, + hcl_oop_t value, + hcl_ooi_t scale +); + HCL_EXPORT hcl_oop_t hcl_makedic ( hcl_t* hcl, hcl_oow_t inisize /* initial bucket size */ diff --git a/lib/number.c b/lib/number.c new file mode 100644 index 0000000..5c6515a --- /dev/null +++ b/lib/number.c @@ -0,0 +1,126 @@ +/* + * $Id$ + * + Copyright (c) 2016-2018 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "hcl-prv.h" + +static hcl_ooi_t equalize_scale (hcl_t* hcl, hcl_oop_fpdec_t x, hcl_oop_fpdec_t y) +{ + hcl_ooi_t xs, ys; + + xs = HCL_OOP_TO_SMOOI(x->scale); + ys = HCL_OOP_TO_SMOOI(y->scale); + + if (xs < ys) + { + /* TODO: don't change x or y. create new objects */ + x->scale = y->scale; + hcl_pushtmp(hcl, &x); + while (xs < ys) + { + x->value = hcl_mulints(hcl, x->value, HCL_SMOOI_TO_OOP(10)); + xs++; + } + hcl_poptmp(hcl); + } + else if (xs > ys) + { + y->scale = x->scale; + hcl_pushtmp(hcl, &y); + while (ys < xs) + { + y->value = hcl_mulints(hcl, y->value, HCL_SMOOI_TO_OOP(10)); + ys++; + } + hcl_poptmp(hcl); + } + + return xs; +} + +hcl_oop_t hcl_addnums (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y) +{ + if (HCL_IS_FPDEC(hcl, x)) + { + if (HCL_IS_FPDEC(hcl, y)) + { + hcl_oop_t v; + hcl_ooi_t scale; + +/* TODO: error handling */ + hcl_pushtmp (hcl, &x); + hcl_pushtmp (hcl, &y); + scale = equalize_scale (hcl, x, y); + v = hcl_addints(hcl, ((hcl_oop_fpdec_t)x)->value, ((hcl_oop_fpdec_t)y)->value); + hcl_poptmps (hcl, 2); + return hcl_makefpdec(hcl, v, scale); + } + else + { + } + } + else + { + if (HCL_IS_FPDEC(hcl, y)) + { + } + else + { + return hcl_addints(hcl, x, y); + } + } +} + +hcl_oop_t hcl_subnums (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y) +{ + if (HCL_IS_FPDEC(hcl, x)) + { + if (HCL_IS_FPDEC(hcl, y)) + { + hcl_oop_t v; + hcl_ooi_t scale; + + hcl_pushtmp (hcl, &x); + hcl_pushtmp (hcl, &y); + scale = equalize_scale (hcl, x, y); + v = hcl_subints(hcl, ((hcl_oop_fpdec_t)x)->value, ((hcl_oop_fpdec_t)y)->value); + hcl_poptmps (hcl, 2); + return hcl_makefpdec(hcl, v, scale); + } + else + { + } + } + else + { + if (HCL_IS_FPDEC(hcl, y)) + { + } + else + { + return hcl_subints(hcl, x, y); + } + } +} diff --git a/lib/obj.c b/lib/obj.c index 7b10758..b232174 100644 --- a/lib/obj.c +++ b/lib/obj.c @@ -269,6 +269,28 @@ hcl_oop_t hcl_makestring (hcl_t* hcl, const hcl_ooch_t* ptr, hcl_oow_t len, int } +hcl_oop_t hcl_makefpdec (hcl_t* hcl, hcl_oop_t value, hcl_ooi_t scale) +{ + hcl_oop_fpdec_t f; + + if (!HCL_IN_SMOOI_RANGE(scale)) + { + hcl_seterrbfmt (hcl, HCL_EINVAL, "fpdec scale too large - %zd", scale); + return HCL_NULL; + } + + hcl_pushtmp (hcl, &value); + f = (hcl_oop_fpdec_t)hcl_allocoopobj (hcl, HCL_BRAND_FPDEC, HCL_FPDEC_NAMED_INSTVARS); + hcl_poptmp (hcl); + + if (!f) return HCL_NULL; + + f->value = value; + f->scale = HCL_SMOOI_TO_OOP(scale); + + return (hcl_oop_t)f; +} + /* ------------------------------------------------------------------------ * * NGC HANDLING * ------------------------------------------------------------------------ */ diff --git a/lib/prim.c b/lib/prim.c index ffbb76e..a077ada 100644 --- a/lib/prim.c +++ b/lib/prim.c @@ -385,7 +385,8 @@ static hcl_pfrc_t pf_integer_add (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) for (i = 1; i < nargs; i++) { arg = HCL_STACK_GETARG(hcl, nargs, i); - ret = hcl_addints(hcl, ret, arg); + /*ret = hcl_addints(hcl, ret, arg);*/ + ret = hcl_addnums(hcl, ret, arg); if (!ret) return HCL_PF_FAILURE; } @@ -402,7 +403,8 @@ static hcl_pfrc_t pf_integer_sub (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) for (i = 1; i < nargs; i++) { arg = HCL_STACK_GETARG(hcl, nargs, i); - ret = hcl_subints(hcl, ret, arg); + /*ret = hcl_subints(hcl, ret, arg);*/ + ret = hcl_subnums(hcl, ret, arg); if (!ret) return HCL_PF_FAILURE; } diff --git a/lib/read.c b/lib/read.c index 8e86a02..ba6ee44 100644 --- a/lib/read.c +++ b/lib/read.c @@ -246,7 +246,6 @@ static hcl_oop_t string_to_fpdec (hcl_t* hcl, hcl_oocs_t* str, const hcl_ioloc_t hcl_oow_t pos; hcl_oow_t scale = 0; hcl_oop_t v; - hcl_oop_fpdec_t f; pos = str->len; while (pos > 0) @@ -269,17 +268,7 @@ static hcl_oop_t string_to_fpdec (hcl_t* hcl, hcl_oocs_t* str, const hcl_ioloc_t if (scale > 0) HCL_MEMMOVE (&str->ptr[pos + 1], &str->ptr[pos], scale * HCL_SIZEOF(str->ptr[0])); if (!v) return HCL_NULL; - hcl_pushtmp (hcl, &v); - f = (hcl_oop_fpdec_t)hcl_makearray (hcl, HCL_FPDEC_NAMED_INSTVARS, 0); - hcl_poptmp (hcl); - - if (!f) return HCL_NULL; - - HCL_OBJ_SET_FLAGS_BRAND(f, HCL_BRAND_FPDEC); - f->value = v; - f->scale = HCL_SMOOI_TO_OOP(scale); - - return f; + return hcl_makefpdec (hcl, v, scale); } static HCL_INLINE int is_spacechar (hcl_ooci_t c)