Implement Python 3 division semantics
This commit is contained in:
parent
a90ca22f4c
commit
40836cba21
@ -54,11 +54,11 @@ class Gb18030IncrementalEncoder(IncrementalEncoder):
|
||||
basecodepoint = nextcodepoint
|
||||
pointer = (ord(i) - basecodepoint) + basepointer
|
||||
let running = pointer
|
||||
let first = 0x81 + (running / (10 * 126 * 10))
|
||||
let first = 0x81 + (running // (10 * 126 * 10))
|
||||
running %= 10 * 126 * 10
|
||||
let second = 0x30 + (running / (10 * 126))
|
||||
let second = 0x30 + (running // (10 * 126))
|
||||
running %= 10 * 126
|
||||
let third = 0x81 + (running / 10)
|
||||
let third = 0x81 + (running // 10)
|
||||
let fourth = 0x30 + (running % 10)
|
||||
out.add(bytes([first, second, third, fourth]))
|
||||
offset += 1
|
||||
|
@ -583,6 +583,7 @@ static void binary(int canAssign) {
|
||||
case TOKEN_ASTERISK: emitByte(OP_MULTIPLY); break;
|
||||
case TOKEN_POW: emitByte(OP_POW); break;
|
||||
case TOKEN_SOLIDUS: emitByte(OP_DIVIDE); break;
|
||||
case TOKEN_DOUBLE_SOLIDUS: emitByte(OP_FLOORDIV); break;
|
||||
case TOKEN_MODULO: emitByte(OP_MODULO); break;
|
||||
case TOKEN_IN: emitByte(OP_EQUAL); break;
|
||||
default: return;
|
||||
@ -625,6 +626,7 @@ static void assignmentValue(void) {
|
||||
case TOKEN_ASTERISK_EQUAL: emitByte(OP_MULTIPLY); break;
|
||||
case TOKEN_POW_EQUAL: emitByte(OP_POW); break;
|
||||
case TOKEN_SOLIDUS_EQUAL: emitByte(OP_DIVIDE); break;
|
||||
case TOKEN_DSOLIDUS_EQUAL: emitByte(OP_FLOORDIV); break;
|
||||
case TOKEN_MODULO_EQUAL: emitByte(OP_MODULO); break;
|
||||
|
||||
default:
|
||||
@ -2787,6 +2789,7 @@ ParseRule krk_parseRules[] = {
|
||||
RULE(TOKEN_PLUS, unary, binary, PREC_TERM),
|
||||
RULE(TOKEN_SEMICOLON, NULL, NULL, PREC_NONE),
|
||||
RULE(TOKEN_SOLIDUS, NULL, binary, PREC_FACTOR),
|
||||
RULE(TOKEN_DOUBLE_SOLIDUS,NULL, binary, PREC_FACTOR),
|
||||
RULE(TOKEN_ASTERISK, NULL, binary, PREC_FACTOR),
|
||||
RULE(TOKEN_POW, NULL, binary, PREC_EXPONENT),
|
||||
RULE(TOKEN_MODULO, NULL, binary, PREC_FACTOR),
|
||||
@ -2850,6 +2853,7 @@ ParseRule krk_parseRules[] = {
|
||||
RULE(TOKEN_RSHIFT_EQUAL, NULL, NULL, PREC_NONE),
|
||||
RULE(TOKEN_AMP_EQUAL, NULL, NULL, PREC_NONE),
|
||||
RULE(TOKEN_SOLIDUS_EQUAL, NULL, NULL, PREC_NONE),
|
||||
RULE(TOKEN_DSOLIDUS_EQUAL,NULL, NULL, PREC_NONE),
|
||||
RULE(TOKEN_ASTERISK_EQUAL,NULL, NULL, PREC_NONE),
|
||||
RULE(TOKEN_MODULO_EQUAL, NULL, NULL, PREC_NONE),
|
||||
|
||||
|
@ -71,7 +71,8 @@ typedef enum {
|
||||
OP_GREATER_EQUAL,
|
||||
OP_LESS_EQUAL,
|
||||
OP_INVOKE_AWAIT,
|
||||
/* current highest: 48 */
|
||||
OP_FLOORDIV,
|
||||
/* current highest: 49 */
|
||||
|
||||
OP_CALL = 64,
|
||||
OP_CLASS,
|
||||
|
@ -15,6 +15,7 @@ typedef enum {
|
||||
TOKEN_PLUS,
|
||||
TOKEN_SEMICOLON,
|
||||
TOKEN_SOLIDUS,
|
||||
TOKEN_DOUBLE_SOLIDUS,
|
||||
TOKEN_ASTERISK,
|
||||
TOKEN_POW,
|
||||
TOKEN_MODULO,
|
||||
@ -52,6 +53,7 @@ typedef enum {
|
||||
TOKEN_ASTERISK_EQUAL,
|
||||
TOKEN_POW_EQUAL,
|
||||
TOKEN_MODULO_EQUAL,
|
||||
TOKEN_DSOLIDUS_EQUAL,
|
||||
|
||||
TOKEN_STRING,
|
||||
TOKEN_BIG_STRING,
|
||||
|
@ -45,6 +45,7 @@ SIMPLE(OP_BEGIN_FINALLY)
|
||||
SIMPLE(OP_END_FINALLY)
|
||||
SIMPLE(OP_GREATER_EQUAL)
|
||||
SIMPLE(OP_LESS_EQUAL)
|
||||
SIMPLE(OP_FLOORDIV)
|
||||
CONSTANT(OP_DEFINE_GLOBAL,(void)0)
|
||||
CONSTANT(OP_CONSTANT,(void)0)
|
||||
CONSTANT(OP_GET_GLOBAL,(void)0)
|
||||
|
@ -360,7 +360,7 @@ KrkToken krk_scanToken() {
|
||||
case '^': return makeToken(match('=') ? TOKEN_CARET_EQUAL : TOKEN_CARET);
|
||||
case '|': return makeToken(match('=') ? TOKEN_PIPE_EQUAL : TOKEN_PIPE);
|
||||
case '&': return makeToken(match('=') ? TOKEN_AMP_EQUAL : TOKEN_AMPERSAND);
|
||||
case '/': return makeToken(match('=') ? TOKEN_SOLIDUS_EQUAL : TOKEN_SOLIDUS);
|
||||
case '/': return makeToken(match('=') ? TOKEN_SOLIDUS_EQUAL : (match('/') ? (match('=') ? TOKEN_DSOLIDUS_EQUAL : TOKEN_DOUBLE_SOLIDUS) : TOKEN_SOLIDUS));
|
||||
case '*': return makeToken(match('=') ? TOKEN_ASTERISK_EQUAL: (match('*') ? (match('=') ? TOKEN_POW_EQUAL : TOKEN_POW) : TOKEN_ASTERISK));
|
||||
case '%': return makeToken(match('=') ? TOKEN_MODULO_EQUAL : TOKEN_MODULO);
|
||||
|
||||
|
37
src/vm.c
37
src/vm.c
@ -1429,7 +1429,30 @@ _success:
|
||||
MAKE_BIN_OP(add,+,radd)
|
||||
MAKE_BIN_OP(sub,-,ssub)
|
||||
MAKE_BIN_OP(mul,*,rmul)
|
||||
MAKE_BIN_OP(div,/,rdiv)
|
||||
|
||||
/**
|
||||
* Division operators.
|
||||
*/
|
||||
KrkValue krk_operator_truediv(KrkValue a, KrkValue b) {
|
||||
if (IS_INTEGER(a)) {
|
||||
if (IS_INTEGER(b)) return FLOATING_VAL((double)AS_INTEGER(a) / (double)AS_INTEGER(b));
|
||||
else if (IS_FLOATING(b)) return FLOATING_VAL((double)AS_INTEGER(a) / AS_FLOATING(b));
|
||||
} else if (IS_FLOATING(a)) {
|
||||
if (IS_FLOATING(b)) return FLOATING_VAL(AS_FLOATING(a) / AS_FLOATING(b));
|
||||
else if (IS_INTEGER(b)) return FLOATING_VAL(AS_FLOATING(a) / (double)AS_INTEGER(b));
|
||||
}
|
||||
return tryBind("__truediv__", a, b, "/", "unsupported operand types for %s: '%s' and '%s'", "__rtruediv__");
|
||||
}
|
||||
|
||||
KrkValue krk_operator_floordiv(KrkValue numerator, KrkValue divisor) {
|
||||
if (IS_INTEGER(divisor) && IS_INTEGER(numerator)) return INTEGER_VAL(AS_INTEGER(numerator) / AS_INTEGER(divisor));
|
||||
else if (IS_INTEGER(divisor) && IS_FLOATING(numerator)) return FLOATING_VAL(__builtin_floor(AS_FLOATING(numerator) / (double)AS_INTEGER(divisor)));
|
||||
else if (IS_FLOATING(divisor)) {
|
||||
if (IS_FLOATING(numerator)) return FLOATING_VAL(__builtin_floor(AS_FLOATING(numerator) / AS_FLOATING(divisor)));
|
||||
else if (IS_INTEGER(numerator)) return FLOATING_VAL(__builtin_floor((double)AS_INTEGER(numerator) / AS_FLOATING(divisor)));
|
||||
}
|
||||
return tryBind("__floordiv__", numerator, divisor, "//", "unsupported operand types for %s: '%s' and '%s'", "__rfloordiv__");
|
||||
}
|
||||
|
||||
#define MAKE_UNOPTIMIZED_BIN_OP(name,operator,inv) \
|
||||
KrkValue krk_operator_ ## name (KrkValue a, KrkValue b) { \
|
||||
@ -1986,11 +2009,14 @@ KrkValue krk_valueSetAttribute(KrkValue owner, char * name, KrkValue to) {
|
||||
}
|
||||
|
||||
#define READ_BYTE() (*frame->ip++)
|
||||
#define BINARY_OP(op) { KrkValue b = krk_pop(); KrkValue a = krk_pop(); krk_push(krk_operator_ ## op (a,b)); break; }
|
||||
#define BINARY_OP_CHECK_ZERO(op) { KrkValue b = krk_pop(); KrkValue a = krk_pop(); \
|
||||
#define BINARY_OP(op) { KrkValue b = krk_peek(0); KrkValue a = krk_peek(1); \
|
||||
a = krk_operator_ ## op (a,b); \
|
||||
krk_currentThread.stackTop[-2] = a; krk_pop(); break; }
|
||||
#define BINARY_OP_CHECK_ZERO(op) { KrkValue b = krk_peek(0); KrkValue a = krk_peek(1); \
|
||||
if ((IS_INTEGER(b) && AS_INTEGER(b) == 0)) { krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division or modulo by zero"); goto _finishException; } \
|
||||
else if ((IS_FLOATING(b) && AS_FLOATING(b) == 0.0)) { krk_runtimeError(vm.exceptions->zeroDivisionError, "float division by zero"); goto _finishException; } \
|
||||
krk_push(krk_operator_ ## op (a,b)); break; }
|
||||
a = krk_operator_ ## op (a,b); \
|
||||
krk_currentThread.stackTop[-2] = a; krk_pop(); break; }
|
||||
#define READ_CONSTANT(s) (frame->closure->function->chunk.constants.values[OPERAND])
|
||||
#define READ_STRING(s) AS_STRING(READ_CONSTANT(s))
|
||||
|
||||
@ -2150,7 +2176,8 @@ _finishReturn: (void)0;
|
||||
case OP_ADD: BINARY_OP(add);
|
||||
case OP_SUBTRACT: BINARY_OP(sub)
|
||||
case OP_MULTIPLY: BINARY_OP(mul)
|
||||
case OP_DIVIDE: BINARY_OP_CHECK_ZERO(div)
|
||||
case OP_DIVIDE: BINARY_OP_CHECK_ZERO(truediv)
|
||||
case OP_FLOORDIV: BINARY_OP_CHECK_ZERO(floordiv)
|
||||
case OP_MODULO: BINARY_OP_CHECK_ZERO(mod)
|
||||
case OP_BITOR: BINARY_OP(or)
|
||||
case OP_BITXOR: BINARY_OP(xor)
|
||||
|
@ -9,10 +9,10 @@ def process_row(seat):
|
||||
let size = 128
|
||||
for c in seat[:7]:
|
||||
if c == 'F':
|
||||
top -= size / 2
|
||||
top -= size // 2
|
||||
else if c == 'B':
|
||||
bottom += size / 2
|
||||
size = size / 2
|
||||
bottom += size // 2
|
||||
size = size // 2
|
||||
return bottom
|
||||
|
||||
def process_seat(seat):
|
||||
@ -21,10 +21,10 @@ def process_seat(seat):
|
||||
let size = 8
|
||||
for c in seat[7:]:
|
||||
if c == 'L':
|
||||
top -= size / 2
|
||||
top -= size // 2
|
||||
else if c == 'R':
|
||||
bottom += size / 2
|
||||
size = size / 2
|
||||
bottom += size // 2
|
||||
size = size // 2
|
||||
return bottom
|
||||
|
||||
print(process_row("FBFBBFFRLR")) # 44
|
||||
|
@ -7,8 +7,8 @@ class RAdder:
|
||||
print("__rmul__ called", o)
|
||||
return f'{o} * RAdder()'
|
||||
|
||||
def __rdiv__(self, o):
|
||||
print("__rdiv__ called", o)
|
||||
def __rtruediv__(self, o):
|
||||
print("__rtruediv__ called", o)
|
||||
return f'{o} / RAdder()'
|
||||
|
||||
def __rpow__(self, o):
|
||||
@ -41,7 +41,7 @@ class RAdder:
|
||||
|
||||
print(42 + RAdder())
|
||||
print(42 * RAdder())
|
||||
#print(42 / RAdder())
|
||||
print(42 / RAdder())
|
||||
print(42 ** RAdder())
|
||||
print(42 >> RAdder())
|
||||
print(42 << RAdder())
|
||||
|
@ -2,6 +2,8 @@ __radd__ called 42
|
||||
42 + RAdder()
|
||||
__rmul__ called 42
|
||||
42 * RAdder()
|
||||
__rtruediv__ called 42
|
||||
42 / RAdder()
|
||||
__rpow__ called 42
|
||||
42 ** RAdder()
|
||||
__rrshift__ called 42
|
||||
|
@ -29,7 +29,7 @@ if __name__ == '__main__':
|
||||
print("Starting {} threads.".format(numThreads))
|
||||
let threads = []
|
||||
let totalCount = 5000000
|
||||
let chunkSize = totalCount / numThreads
|
||||
let chunkSize = totalCount // numThreads
|
||||
let numbers = list(range(totalCount))
|
||||
let cnt = 0
|
||||
if totalCount > chunkSize * numThreads:
|
||||
|
@ -107,7 +107,7 @@ let trailrange_big5 = tupleOf(*range(0x40, 0x7E + 1), *range(0xA1, 0xFE + 1))
|
||||
|
||||
for pointer, ucs in enumerate(indices['jis0208']):
|
||||
if ucs == None: continue
|
||||
let sku = (pointer / 188) + 1
|
||||
let sku = (pointer // 188) + 1
|
||||
let sten = (pointer % 188) + 1
|
||||
let first = 0x80 + sku
|
||||
if first >= 0xA0: first += 0x40
|
||||
@ -116,7 +116,7 @@ for pointer, ucs in enumerate(indices['jis0208']):
|
||||
decode_shiftjis[(first,second)] = ucs
|
||||
if ucs not in encode_shiftjis and not (8272 <= pointer and pointer <= 8835):
|
||||
encode_shiftjis[ucs] = (first, second)
|
||||
let ku = (pointer / 94) + 1
|
||||
let ku = (pointer // 94) + 1
|
||||
let ten = (pointer % 94) + 1
|
||||
if ku <= 94:
|
||||
let firste = 0xA0 + ku
|
||||
@ -130,7 +130,7 @@ for pointer, ucs in enumerate(indices['jis0208']):
|
||||
|
||||
for pointer, ucs in enumerate(indices['jis0212']):
|
||||
if ucs == None: continue
|
||||
let ku = (pointer / 94) + 1
|
||||
let ku = (pointer // 94) + 1
|
||||
let ten = (pointer % 94) + 1
|
||||
let second = 0xA0 + ku
|
||||
let third = 0xA0 + ten
|
||||
@ -150,7 +150,7 @@ for i in range(63):
|
||||
for i in range(94 * 20):
|
||||
let pointer = 8836 + i
|
||||
let ucs = 0xE000 + i
|
||||
let sku = (pointer / 188) + 1
|
||||
let sku = (pointer // 188) + 1
|
||||
let sten = (pointer % 188) + 1
|
||||
let first = 0xC0 + sku
|
||||
let second = 0x3F + sten
|
||||
@ -159,7 +159,7 @@ for i in range(94 * 20):
|
||||
|
||||
for pointer, ucs in enumerate(indices['euc-kr']):
|
||||
if ucs == None: continue
|
||||
let uku = (pointer / 190) + 1
|
||||
let uku = (pointer // 190) + 1
|
||||
let uten = (pointer % 190) + 1
|
||||
let first = 0x80 + uku
|
||||
let second = 0x40 + uten
|
||||
@ -168,7 +168,7 @@ for pointer, ucs in enumerate(indices['euc-kr']):
|
||||
|
||||
for pointer, ucs in enumerate(indices['gb18030']):
|
||||
if ucs == None: continue
|
||||
let uku = (pointer / 190) + 1
|
||||
let uku = (pointer // 190) + 1
|
||||
let uten = (pointer % 190) + 1
|
||||
let first = 0x80 + uku
|
||||
let second = 0x3F + uten
|
||||
@ -179,7 +179,7 @@ for pointer, ucs in enumerate(indices['gb18030']):
|
||||
|
||||
for pointer, ucs in enumerate(indices['big5']):
|
||||
if ucs == None: continue
|
||||
let bku = (pointer / 157) + 1
|
||||
let bku = (pointer // 157) + 1
|
||||
let bten = (pointer % 157) + 1
|
||||
let first = 0x80 + bku
|
||||
let second = 0x3F + bten
|
||||
|
Loading…
Reference in New Issue
Block a user