started adding fpdec calculation functions

This commit is contained in:
hyung-hwan 2018-03-28 16:40:42 +00:00
parent 3a30ffda7b
commit 116512ae9d
8 changed files with 190 additions and 19 deletions

View File

@ -56,6 +56,7 @@ libhcl_la_SOURCES = \
hcl.c \
heap.c \
logfmt.c \
number.c \
obj.c \
opt-imp.h \
opt.c \

View File

@ -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

View File

@ -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 */
/* ========================================================================= */

View File

@ -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 */

126
lib/number.c Normal file
View File

@ -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);
}
}
}

View File

@ -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
* ------------------------------------------------------------------------ */

View File

@ -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;
}

View File

@ -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)