From 1bbc6e4c5af2642783c19da40e2b31fa32c99ba6 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 12 May 2004 06:58:45 +0000 Subject: [PATCH] Test cases and bug fixes for mathematical operations. --- ChangeLog | 3 ++ dpas/dpas-parser.y | 15 +++++++ jit/jit-interp.cpp | 4 +- tests/Makefile.am | 3 +- tests/math.pas | 110 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 tests/math.pas diff --git a/ChangeLog b/ChangeLog index db7f6c2..9ab07a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,9 @@ * dpas/dpas-builtin.c, jit/jit-dump.c, jit/jit-value.c: add builtins for mathematical operations. + * dpas/dpas-parser.y, jit/jit-interp.cpp, tests/Makefile.am, + tests/math.pas: test cases and bug fixes for mathematical operations. + 2004-05-11 Rhys Weatherley * include/jit/jit-insn.h, jit/jit-insn.c, jit/jit-interp.cpp, diff --git a/dpas/dpas-parser.y b/dpas/dpas-parser.y index 91f68f1..959d9be 100644 --- a/dpas/dpas-parser.y +++ b/dpas/dpas-parser.y @@ -2548,6 +2548,21 @@ Factor (0, 0, dpas_sem_get_type($1), dpas_sem_get_value($1), $3.exprs, $3.len); } + else if(dpas_sem_is_type($1) && $3.len == 1 && + dpas_sem_is_rvalue($3.exprs[0])) + { + /* Cast a value to a new type */ + jit_value_t conv; + conv = jit_insn_convert + (dpas_current_function(), + dpas_sem_get_value(dpas_lvalue_to_rvalue($3.exprs[0])), + dpas_sem_get_type($1), 0); + if(!conv) + { + dpas_out_of_memory(); + } + dpas_sem_set_rvalue($$, dpas_sem_get_type($1), conv); + } else { if(!dpas_sem_is_error($1)) diff --git a/jit/jit-interp.cpp b/jit/jit-interp.cpp index 7f18793..ed2b60c 100644 --- a/jit/jit-interp.cpp +++ b/jit/jit-interp.cpp @@ -4010,7 +4010,7 @@ void _jit_run_function(jit_function_interp *func, jit_item *args, VMCASE(JIT_OP_LDARG_NFLOAT): { /* Load a native float argument onto the stack */ - VM_STK_NFLOATP = *VM_ARG(jit_float64); + VM_STK_NFLOATP = *VM_ARG(jit_nfloat); VM_MODIFY_PC_AND_STACK(2, -1); } VMBREAK; @@ -4170,7 +4170,7 @@ void _jit_run_function(jit_function_interp *func, jit_item *args, VMCASE(JIT_OP_LDLOC_NFLOAT): { /* Load a native float local onto the stack */ - VM_STK_NFLOATP = *VM_LOC(jit_float64); + VM_STK_NFLOATP = *VM_LOC(jit_nfloat); VM_MODIFY_PC_AND_STACK(2, -1); } VMBREAK; diff --git a/tests/Makefile.am b/tests/Makefile.am index c8e1bbd..bdb7ad5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,3 +1,4 @@ -TESTS = coerce.pas +TESTS = coerce.pas \ + math.pas TESTS_ENVIRONMENT = $(top_builddir)/dpas/dpas diff --git a/tests/math.pas b/tests/math.pas new file mode 100644 index 0000000..efefdaa --- /dev/null +++ b/tests/math.pas @@ -0,0 +1,110 @@ +(* + * math.pas - Test mathematical operators. + * + * Copyright (C) 2004 Southern Storm Software, Pty Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + *) + +program coerce; + +const + pi = 3.14159265358979323846; + +var + failed: Boolean; + +procedure run(msg: String; value: Boolean); +begin + Write(msg); + Write(" ... "); + if value then begin + WriteLn("ok"); + end else begin + WriteLn("failed"); + failed := True; + end; +end; + +procedure runf(msg: String; value, expected, delta: ShortReal); +begin + run(msg, Abs(value - expected) <= delta); +end; + +procedure rund(msg: String; value, expected, delta: Real); +begin + run(msg, Abs(value - expected) <= delta); +end; + +procedure runn(msg: String; value, expected, delta: LongReal); +begin + run(msg, Abs(value - expected) <= delta); +end; + +procedure run_tests; +var + b: Byte; + s: ShortInt; + f: ShortReal; + d: Real; + n: LongReal; +begin + { Initialize some values of odd type sizes } + b := 3; + s := 67; + f := 24.0; + d := 56.0; + n := 123.5; + + { Test coercion rules for mathematical operators } + run("math_coerce_byte", SameType(LongReal, Sin(b))); + run("math_coerce_short", SameType(LongReal, Cos(s))); + run("math_coerce_int", SameType(LongReal, 3 pow 5)); + run("math_coerce_uint", SameType(LongReal, Atan2(3, 080000005H))); + run("math_coerce_long", SameType(LongReal, Round(0100000000H))); + run("math_coerce_ulong", SameType(LongReal, Log(08000000000000000H))); + run("math_coerce_float32", SameType(ShortReal, Log10(f))); + run("math_coerce_float64", SameType(Real, Atan(d))); + run("math_coerce_nfloat", SameType(LongReal, Abs(n))); + + { Test that the operators give sane answers } + runf("math_sin_0", Sin(ShortReal(0.0)), ShortReal(0.0), 0.00001); + runf("math_sin_pi_2", Sin(ShortReal(pi / 2)), ShortReal(1.0), 0.00001); + f := ShortReal(pi); + runf("math_sin_pi", Sin(f), ShortReal(0.0), 0.00001); + runf("math_cos_0", Cos(ShortReal(0.0)), ShortReal(1.0), 0.00001); + runf("math_sqrt_1", Sqrt(ShortReal(1.0)), ShortReal(1.0), 0.00001); + runf("math_sqrt_2", Sqrt(ShortReal(2.0)), ShortReal(1.4142), 0.0001); + f := Sqrt(ShortReal(-1.0)); + run("math_sqrt_m1", IsNaN(f)); + rund("math_ceil_1.5", Ceil(Real(1.5)), Real(2.0), 0.00001); + rund("math_ceil_m1.5", Ceil(Real(-1.5)), Real(-1.0), 0.00001); + rund("math_floor_1.5", Floor(Real(1.5)), Real(1.0), 0.00001); + rund("math_floor_m1.5", Floor(Real(-1.5)), Real(-2.0), 0.00001); + rund("math_rint_1.5", Rint(Real(1.5)), Real(2.0), 0.00001); + rund("math_rint_2.5", Rint(Real(2.5)), Real(2.0), 0.00001); + rund("math_round_1.5", Round(Real(1.5)), Real(2.0), 0.00001); + rund("math_round_2.5", Round(Real(2.5)), Real(3.0), 0.00001); + runn("math_max_1_6", Max(1.0, 6.0), 6.0, 0.00001); + runn("math_min_1_6", Min(1.0, 6.0), 1.0, 0.00001); +end; + +begin + failed := False; + run_tests; + if failed then begin + Terminate(1); + end; +end. -- 2.47.3