add pic_add, pic_sub, ..., pic_eq, pic_lt, ...
This commit is contained in:
		
							parent
							
								
									b01042505f
								
							
						
					
					
						commit
						10522b54e9
					
				|  | @ -582,6 +582,45 @@ pic_eqv_p(pic_value x, pic_value y) | |||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #if PIC_ENABLE_FLOAT | ||||
| # define pic_aop(pic, a, b, op, name, guard)                            \ | ||||
|     ((pic_int_p(a) && pic_int_p(b)) ?                                   \ | ||||
|      ((INT_MIN <= (double)pic_int(a) op (double)pic_int(b) && (double)pic_int(a) op (double)pic_int(b) <= INT_MAX && guard) \ | ||||
|       ? pic_int_value((int)((double)pic_int(a) op (double)pic_int(b)))  \ | ||||
|       : pic_float_value((double)pic_int(a) op (double)pic_int(b)))      \ | ||||
|      : (pic_float_p(a) && pic_float_p(b)) ? pic_float_value(pic_float(a) op pic_float(b)) \ | ||||
|      : (pic_int_p(a) && pic_float_p(b)) ? pic_float_value(pic_int(a) op pic_float(b)) \ | ||||
|      : (pic_float_p(a) && pic_int_p(b)) ? pic_float_value(pic_float(a) op pic_int(b)) \ | ||||
|      : (pic_errorf(pic, name ": non-number operand given"), 0)) | ||||
| #else | ||||
| # define pic_aop(pic, a, b, op, name)                                   \ | ||||
|     ((pic_int_p(a) && pic_int_p(b))                                     \ | ||||
|      ? pic_int_value(pic_int(a) op pic_int(b))                          \ | ||||
|      : (pic_errorf(pic, name ": non-number operand given"), 0)) | ||||
| #endif | ||||
| 
 | ||||
| #define pic_add(pic, a, b) pic_aop(pic, a, b, +, "+", true) | ||||
| #define pic_sub(pic, a, b) pic_aop(pic, a, b, -, "-", true) | ||||
| #define pic_mul(pic, a, b) pic_aop(pic, a, b, *, "*", true) | ||||
| #define pic_div(pic, a, b) pic_aop(pic, a, b, /, "/", (double)pic_int(a) / (double)pic_int(b) == round((double)pic_int(a) / (double)pic_int(b))) | ||||
| 
 | ||||
| #if PIC_ENABLE_FLOAT | ||||
| # define pic_cmp(pic, a, b, op, name)                                   \ | ||||
|     ((pic_int_p(a) && pic_int_p(b)) ? pic_int(a) op pic_int(b)          \ | ||||
|      : (pic_float_p(a) && pic_float_p(b)) ? pic_float(a) op pic_float(b) \ | ||||
|      : (pic_int_p(a) && pic_float_p(b)) ? pic_int(a) op pic_float(b)    \ | ||||
|      : (pic_float_p(a) && pic_int_p(b)) ? pic_float(a) op pic_int(b)    \ | ||||
|      : (pic_errorf(pic, name ": non-number operand given"), 0)) | ||||
| #else | ||||
| # define pic_cmp(pic, a, b, op, name)                                   \ | ||||
|     ((pic_int_p(a) && pic_int_p(b)) ? pic_int(a) op pic_int(b)          \ | ||||
|      : (pic_errorf(pic, name ": non-number operand given"), 0)) | ||||
| #endif | ||||
| 
 | ||||
| #define pic_eq(pic, a, b) pic_cmp(pic, a, b, ==, "=") | ||||
| #define pic_le(pic, a, b) pic_cmp(pic, a, b, <=, "<=") | ||||
| #define pic_lt(pic, a, b) pic_cmp(pic, a, b, <, "<") | ||||
| 
 | ||||
| #if defined(__cplusplus) | ||||
| } | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										153
									
								
								extlib/benz/vm.c
								
								
								
								
							
							
						
						
									
										153
									
								
								extlib/benz/vm.c
								
								
								
								
							|  | @ -921,111 +921,62 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args) | |||
|       NEXT; | ||||
|     } | ||||
| 
 | ||||
| #define DEFINE_ARITH_OP(opcode, op, guard)			\ | ||||
|     CASE(opcode) {						\ | ||||
|       pic_value a, b;						\ | ||||
|       b = POP();						\ | ||||
|       a = POP();						\ | ||||
|       (void)POP();                                              \ | ||||
|       if (pic_int_p(a) && pic_int_p(b)) {			\ | ||||
| 	double f = (double)pic_int(a) op (double)pic_int(b);	\ | ||||
| 	if (INT_MIN <= f && f <= INT_MAX && (guard)) {		\ | ||||
| 	  PUSH(pic_int_value((int)f));				\ | ||||
| 	}							\ | ||||
| 	else {							\ | ||||
| 	  PUSH(pic_float_value(f));				\ | ||||
| 	}							\ | ||||
|       }								\ | ||||
|       else if (pic_float_p(a) && pic_float_p(b)) {		\ | ||||
| 	PUSH(pic_float_value(pic_float(a) op pic_float(b)));	\ | ||||
|       }								\ | ||||
|       else if (pic_int_p(a) && pic_float_p(b)) {		\ | ||||
| 	PUSH(pic_float_value(pic_int(a) op pic_float(b)));	\ | ||||
|       }								\ | ||||
|       else if (pic_float_p(a) && pic_int_p(b)) {		\ | ||||
| 	PUSH(pic_float_value(pic_float(a) op pic_int(b)));	\ | ||||
|       }								\ | ||||
|       else {							\ | ||||
| 	pic_errorf(pic, #op " got non-number operands");        \ | ||||
|       }								\ | ||||
|       NEXT;							\ | ||||
|     CASE(OP_ADD) { | ||||
|       pic_value a, b; | ||||
|       b = POP(); | ||||
|       a = POP(); | ||||
|       (void)POP(); | ||||
|       PUSH(pic_add(pic, a, b)); | ||||
|       NEXT; | ||||
|     } | ||||
| 
 | ||||
| #define DEFINE_ARITH_OP2(opcode, op)                            \ | ||||
|     CASE(opcode) {						\ | ||||
|       pic_value a, b;						\ | ||||
|       b = POP();						\ | ||||
|       a = POP();						\ | ||||
|       (void)POP();                                              \ | ||||
|       if (pic_int_p(a) && pic_int_p(b)) {			\ | ||||
|         PUSH(pic_int_value(pic_int(a) op pic_int(b)));          \ | ||||
|       }								\ | ||||
|       else {							\ | ||||
| 	pic_errorf(pic, #op " got non-number operands");        \ | ||||
|       }								\ | ||||
|       NEXT;							\ | ||||
|     CASE(OP_SUB) { | ||||
|       pic_value a, b; | ||||
|       b = POP(); | ||||
|       a = POP(); | ||||
|       (void)POP(); | ||||
|       PUSH(pic_sub(pic, a, b)); | ||||
|       NEXT; | ||||
|     } | ||||
| 
 | ||||
| #if PIC_ENABLE_FLOAT | ||||
|     DEFINE_ARITH_OP(OP_ADD, +, true); | ||||
|     DEFINE_ARITH_OP(OP_SUB, -, true); | ||||
|     DEFINE_ARITH_OP(OP_MUL, *, true); | ||||
|     DEFINE_ARITH_OP(OP_DIV, /, f == round(f)); | ||||
| #else | ||||
|     DEFINE_ARITH_OP2(OP_ADD, +); | ||||
|     DEFINE_ARITH_OP2(OP_SUB, -); | ||||
|     DEFINE_ARITH_OP2(OP_MUL, *); | ||||
|     DEFINE_ARITH_OP2(OP_DIV, /); | ||||
| #endif | ||||
| 
 | ||||
| #define DEFINE_COMP_OP(opcode, op)				\ | ||||
|     CASE(opcode) {						\ | ||||
|       pic_value a, b;						\ | ||||
|       b = POP();						\ | ||||
|       a = POP();						\ | ||||
|       (void)POP();                                              \ | ||||
|       if (pic_int_p(a) && pic_int_p(b)) {			\ | ||||
| 	PUSH(pic_bool_value(pic_int(a) op pic_int(b)));		\ | ||||
|       }								\ | ||||
|       else if (pic_float_p(a) && pic_float_p(b)) {		\ | ||||
| 	PUSH(pic_bool_value(pic_float(a) op pic_float(b)));	\ | ||||
|       }								\ | ||||
|       else if (pic_int_p(a) && pic_float_p(b)) {		\ | ||||
| 	PUSH(pic_bool_value(pic_int(a) op pic_float(b)));	\ | ||||
|       }								\ | ||||
|       else if (pic_float_p(a) && pic_int_p(b)) {		\ | ||||
| 	PUSH(pic_bool_value(pic_float(a) op pic_int(b)));	\ | ||||
|       }								\ | ||||
|       else {							\ | ||||
| 	pic_errorf(pic, #op " got non-number operands");        \ | ||||
|       }								\ | ||||
|       NEXT;							\ | ||||
|     CASE(OP_MUL) { | ||||
|       pic_value a, b; | ||||
|       b = POP(); | ||||
|       a = POP(); | ||||
|       (void)POP(); | ||||
|       PUSH(pic_mul(pic, a, b)); | ||||
|       NEXT; | ||||
|     } | ||||
| 
 | ||||
| #define DEFINE_COMP_OP2(opcode, op)				\ | ||||
|     CASE(opcode) {						\ | ||||
|       pic_value a, b;						\ | ||||
|       b = POP();						\ | ||||
|       a = POP();						\ | ||||
|       (void)POP();                                              \ | ||||
|       if (pic_int_p(a) && pic_int_p(b)) {			\ | ||||
| 	PUSH(pic_bool_value(pic_int(a) op pic_int(b)));		\ | ||||
|       }								\ | ||||
|       else {							\ | ||||
| 	pic_errorf(pic, #op " got non-number operands");        \ | ||||
|       }								\ | ||||
|       NEXT;							\ | ||||
|     CASE(OP_DIV) { | ||||
|       pic_value a, b; | ||||
|       b = POP(); | ||||
|       a = POP(); | ||||
|       (void)POP(); | ||||
|       PUSH(pic_div(pic, a, b)); | ||||
|       NEXT; | ||||
|     } | ||||
|     CASE(OP_EQ) { | ||||
|       pic_value a, b; | ||||
|       b = POP(); | ||||
|       a = POP(); | ||||
|       (void)POP(); | ||||
|       PUSH(pic_bool_value(pic_eq(pic, a, b))); | ||||
|       NEXT; | ||||
|     } | ||||
|     CASE(OP_LE) { | ||||
|       pic_value a, b; | ||||
|       b = POP(); | ||||
|       a = POP(); | ||||
|       (void)POP(); | ||||
|       PUSH(pic_bool_value(pic_le(pic, a, b))); | ||||
|       NEXT; | ||||
|     } | ||||
|     CASE(OP_LT) { | ||||
|       pic_value a, b; | ||||
|       b = POP(); | ||||
|       a = POP(); | ||||
|       (void)POP(); | ||||
|       PUSH(pic_bool_value(pic_lt(pic, a, b))); | ||||
|       NEXT; | ||||
|     } | ||||
| 
 | ||||
| #if PIC_ENABLE_FLOAT | ||||
|     DEFINE_COMP_OP(OP_EQ, ==); | ||||
|     DEFINE_COMP_OP(OP_LT, <); | ||||
|     DEFINE_COMP_OP(OP_LE, <=); | ||||
| #else | ||||
|     DEFINE_COMP_OP2(OP_EQ, ==); | ||||
|     DEFINE_COMP_OP2(OP_LT, <); | ||||
|     DEFINE_COMP_OP2(OP_LE, <=); | ||||
| #endif | ||||
| 
 | ||||
|     CASE(OP_STOP) { | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Yuichi Nishiwaki
						Yuichi Nishiwaki