Refactor cali.c

This commit is contained in:
kichikuou
2025-02-02 09:00:24 +09:00
parent 03f9b36ff0
commit bc5d72b6fe
6 changed files with 141 additions and 141 deletions
+104 -141
View File
@@ -18,11 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* 0.00 97/11/27 初版
* 0.01 97/12/06 計算式の評価順序がおかしかった
* @version 0.01-01 97/12/06 メッセージから日本語を削除
*
*/
/* $Id: cali.c,v 1.16 2002/12/31 04:11:19 chikama Exp $ */
@@ -34,19 +29,25 @@
#include "nact.h"
#include "xsystem35.h"
#define CALI_TRUE (1) /* comparison is ture */
#define CALI_FALSE (0) /* comparison is false */
#define CALI_MAX_VAL (65535) /* maxinum of value */
#define CALI_MIN_VAL (0) /* mininum of value */
#define CALI_NaN (CALI_MIN_VAL) /* devied by 0 */
#define CALI_OF (CALI_MAX_VAL) /* calculate over flow */
#define CALI_SubNG (CALI_MIN_VAL) /* nagative result */
#define CALI_TERMINATER (0x7f) /* terminater */
#define OP_AND 0x74
#define OP_OR 0x75
#define OP_XOR 0x76
#define OP_MUL 0x77
#define OP_DIV 0x78
#define OP_ADD 0x79
#define OP_SUB 0x7a
#define OP_EQUAL 0x7b
#define OP_LT 0x7c
#define OP_GT 0x7d
#define OP_NEQUAL 0x7e
#define OP_END 0x7f
#define CALI_DEPTH_MAX (256)
#define OP_C0_INDEX 1
#define OP_C0_MOD 2
#define OP_C0_LE 3
#define OP_C0_GE 4
static int buf[CALI_DEPTH_MAX]; /* 計算式バッファ */
static int *cali = buf; /* インデックス */
#define CALI_DEPTH_MAX 256
static int *getVar(int c0, struct VarRef *ref) {
int addr = sl_getIndex();
@@ -55,9 +56,9 @@ static int *getVar(int c0, struct VarRef *ref) {
var = c0 & 0x3f; // 0 - 0x3f
} else {
int c1 = sl_getc();
if (c0 != 0xc0)
if (c0 != 0xc0) {
var = (c0 & 0x3f) * 256 + c1; // 0x100 - 0x3fff
else if (c1 == 1) {
} else if (c1 == 1) {
c0 = sl_getc();
c1 = sl_getc();
var = c0 << 8 | c1;
@@ -79,178 +80,140 @@ static int *getVar(int c0, struct VarRef *ref) {
return store;
}
/* 変数番号が返る */
// Returns a pointer to the variable
int *getCaliVariable(void) {
int *c0 = getVar(sl_getc(), NULL);
if (sl_getc() != 0x7f) {
SYSERROR("Something is Wrong @ %03d:%05x", sl_getPage(), sl_getIndex());
if (sl_getc() != OP_END) {
SYSERROR("Invalid variable expression at %03d:%05x", sl_getPage(), sl_getIndex());
}
return c0;
}
bool getCaliArray(struct VarRef *ref) {
bool ok = getVar(sl_getc(), ref) != NULL;
if (sl_getc() != 0x7f) {
SYSERROR("Something is Wrong @ %03d:%05x", sl_getPage(), sl_getIndex());
if (sl_getc() != OP_END) {
SYSERROR("Invalid variable expression at %03d:%05x", sl_getPage(), sl_getIndex());
}
return ok;
}
/* 変数代入コマンド用 */
// For variable assignment commands
int *getVariable(void) {
return getVar(sl_getc(), NULL);
}
/* 計算式の評価後の値が返る */
// Returns the result of the calculation
int getCaliValue(void) {
register int ingVal,edVal,rstVal;
uint16_t stack[CALI_DEPTH_MAX];
uint16_t *sp = stack;
int rhs, lhs, result;
int c0,c1;
int *bufc = cali;
while((c0 = sl_getc()) != CALI_TERMINATER) {
if ((c0 & 0x80) != 0) { /* variable */
while ((c0 = sl_getc()) != OP_END) {
if (c0 & 0x80) { // variable
int c1 = sl_getcAt(sl_getIndex());
int *t;
if (c0 == 0xc0) {
if (c1 == 1 || c1 >= 0x34) goto l_var;
if (c1 == OP_C0_INDEX || c1 >= 0x34) goto l_var;
c1 = sl_getc();
if (c1 == 2) { /* % */
ingVal = *--cali;
edVal = *--cali;
if (ingVal == 0) {
*cali = CALI_NaN;
} else {
rstVal = edVal % ingVal;
*cali = rstVal;
}
cali++;
if (c1 == OP_C0_MOD) {
rhs = *--sp;
lhs = *--sp;
*sp++ = rhs ? lhs % rhs : 0;
continue;
} else if (c1 == 3) { /* <= */
ingVal = *--cali;
edVal = *--cali;
if (edVal <= ingVal) { *cali = CALI_TRUE; }
else { *cali = CALI_FALSE; }
cali++;
} else if (c1 == OP_C0_LE) {
rhs = *--sp;
lhs = *--sp;
*sp++ = (lhs <= rhs);
continue;
} else if (c1 == 4) { /* >= */
ingVal = *--cali;
edVal = *--cali;
if (edVal >= ingVal) { *cali = CALI_TRUE; }
else { *cali = CALI_FALSE; }
cali++;
} else if (c1 == OP_C0_GE) {
rhs = *--sp;
lhs = *--sp;
*sp++ = (lhs >= rhs);
continue;
} else if (c1 < 0x34) {
SYSERROR("Unknow Parameter @ %03d:%05x", sl_getPage(), sl_getIndex());
SYSERROR("Unknown operator at %03d:%05x", sl_getPage(), sl_getIndex());
}
}
l_var:
t = getVar(c0, NULL);
*cali++ = t ? *t : 0;
*sp++ = t ? *t : 0;
} else {
switch(c0) {
case 0x7e: /* != */
ingVal = *--cali;
edVal = *--cali;
if (edVal != ingVal) { *cali = CALI_TRUE; }
else { *cali = CALI_FALSE; }
cali++;
case OP_NEQUAL:
rhs = *--sp;
lhs = *--sp;
*sp++ = (lhs != rhs);
break;
case 0x7d: /* > */
ingVal = *--cali;
edVal = *--cali;
if (edVal > ingVal) { *cali = CALI_TRUE; }
else { *cali = CALI_FALSE; }
cali++;
case OP_GT:
rhs = *--sp;
lhs = *--sp;
*sp++ = (lhs > rhs);
break;
case 0x7c: /* < */
ingVal = *--cali;
edVal = *--cali;
if (edVal < ingVal) { *cali = CALI_TRUE; }
else { *cali = CALI_FALSE; }
cali++;
case OP_LT:
rhs = *--sp;
lhs = *--sp;
*sp++ = (lhs < rhs);
break;
case 0x7b: /* == */
ingVal = *--cali;
edVal = *--cali;
if (edVal == ingVal) { *cali = CALI_TRUE; }
else { *cali = CALI_FALSE; }
cali++;
case OP_EQUAL:
rhs = *--sp;
lhs = *--sp;
*sp++ = (lhs == rhs);
break;
case 0x7a: /* - */
ingVal = *--cali;
edVal = *--cali;
rstVal = edVal - ingVal;
if (rstVal < CALI_MIN_VAL) { *cali = CALI_SubNG; }
else { *cali = rstVal; }
cali++;
case OP_SUB:
rhs = *--sp;
lhs = *--sp;
result = lhs - rhs;
*sp++ = result < 0 ? 0 : result;
break;
case 0x79: /* + */
ingVal = *--cali;
edVal = *--cali;
rstVal = edVal + ingVal;
if (rstVal > CALI_MAX_VAL) { *cali = CALI_OF; }
else { *cali = rstVal; }
cali++;
case OP_ADD:
rhs = *--sp;
lhs = *--sp;
result = lhs + rhs;
*sp++ = result > 0xffff ? 0xffff : result;
break;
case 0x78: /* / */
ingVal = *--cali;
edVal = *--cali;
if (ingVal == 0) {
*cali = CALI_NaN;
} else {
rstVal = edVal / ingVal;
*cali = rstVal;
}
cali++;
case OP_DIV:
rhs = *--sp;
lhs = *--sp;
*sp++ = rhs ? lhs / rhs : 0;
break;
case 0x77: /* * */
ingVal = *--cali;
edVal = *--cali;
rstVal = edVal * ingVal;
if (rstVal > CALI_MAX_VAL) { *cali = CALI_OF; }
else { *cali = rstVal; }
cali++;
case OP_MUL:
rhs = *--sp;
lhs = *--sp;
result = lhs * rhs;
*sp++ = result > 0xffff ? 0xffff : result;
break;
case 0x76: /* XOR */
ingVal = *--cali;
edVal = *--cali;
*cali = (edVal ^ ingVal); cali++;
case OP_XOR:
rhs = *--sp;
lhs = *--sp;
*sp++ = (lhs ^ rhs);
break;
case 0x75: /* OR */
ingVal = *--cali;
edVal = *--cali;
*cali = (edVal | ingVal); cali++;
case OP_OR:
rhs = *--sp;
lhs = *--sp;
*sp++ = (lhs | rhs);
break;
case 0x74: /* AND */
ingVal = *--cali;
edVal = *--cali;
*cali = (edVal & ingVal); cali++;
case OP_AND:
rhs = *--sp;
lhs = *--sp;
*sp++ = (lhs & rhs);
break;
default:
if ((c0 & 0x40) == 0) { /* WORD const */
default: // immediate value
if (c0 & 0x40) { // 0x0 - 0x33
*sp++ = (c0 & 0x3f);
} else { // 0x34 - 0x3fff
c1 = sl_getc();
if (c0 == 0) { /* 34h-ffh */
if (c1 <= 0x33) {
SYSERROR("Unknown Parameter @ %03d:%05x", sl_getPage(), sl_getIndex());
}
} else { /* 100h- 3fff */
c1 += ((c0 & 0x3f) * 256);
}
} else { /* byte const 0-33h */
c1 = (c0 & 0x3f);
if (c0 == 0 && c1 <= 0x33)
SYSERROR("Invalid cali at %03d:%05x", sl_getPage(), sl_getIndex());
*sp++ = (c0 & 0x3f) << 8 | c1;
}
// printf("c1 = %d ",c1);
*cali = c1; cali++;
}
}
}
c0 = *--cali;
if (cali != bufc) {
WARNING("Something is wrong @ %03d:%05x", sl_getPage(), sl_getIndex());
cali = bufc;
if (sp != stack + 1) {
WARNING("Unexpected end of expression at %03d:%05x", sl_getPage(), sl_getIndex());
return 0;
}
return c0;
return *--sp;
}
BIN
View File
Binary file not shown.
+35
View File
@@ -0,0 +1,35 @@
MS FILE, "arith.adv":
~AssertEquals 3+4, 7, __LINE__:
~AssertEquals 50000+50000, 65535, __LINE__:
~AssertEquals 10-3, 7, __LINE__:
~AssertEquals 3-10, 0, __LINE__:
~AssertEquals 3*4, 12, __LINE__:
~AssertEquals 1000*1000, 65535, __LINE__:
~AssertEquals 1000*1000-1, 65534, __LINE__:
~AssertEquals 10/2, 5, __LINE__:
~AssertEquals 10/3, 3, __LINE__:
~AssertEquals 10/0, 0, __LINE__:
~AssertEquals 10%3, 1, __LINE__:
~AssertEquals 10%0, 0, __LINE__:
~AssertEquals 5&3, 1, __LINE__:
~AssertEquals 5|3, 7, __LINE__:
~AssertEquals 5^3, 6, __LINE__:
~AssertEquals 3<2, 0, __LINE__:
~AssertEquals 3<3, 0, __LINE__:
~AssertEquals 3<4, 1, __LINE__:
~AssertEquals 3<=2, 0, __LINE__:
~AssertEquals 3<=3, 1, __LINE__:
~AssertEquals 3<=4, 1, __LINE__:
~AssertEquals 3>2, 1, __LINE__:
~AssertEquals 3>3, 0, __LINE__:
~AssertEquals 3>4, 0, __LINE__:
~AssertEquals 3>=2, 1, __LINE__:
~AssertEquals 3>=3, 1, __LINE__:
~AssertEquals 3>=4, 0, __LINE__:
~AssertEquals 3=2, 0, __LINE__:
~AssertEquals 3=3, 1, __LINE__:
~AssertEquals 3\2, 1, __LINE__:
~AssertEquals 3\3, 0, __LINE__:
%0:
+1
View File
@@ -9,6 +9,7 @@
!tests_passed:0!
!tests_failed:0!
%#arith.adv:
%#array.adv:
%#strvar.adv:
%#stack.adv:
+1
View File
@@ -1,6 +1,7 @@
#SYSTEM35
test.adv
util.adv
arith.adv
array.adv
strvar.adv
stack.adv
BIN
View File
Binary file not shown.