Remove str-nonstr concatenation / implicit coercion
This commit is contained in:
parent
a7e110cad9
commit
e0adfcdc80
@ -1865,10 +1865,10 @@ static void string(int type) {
|
||||
krk_rewindScanner(beforeExpression); /* To get us back to where we were with a string token */
|
||||
parser = parserBefore;
|
||||
c = inner.start;
|
||||
KrkToken which = syntheticToken("str");
|
||||
if (*c == '!') {
|
||||
c++;
|
||||
/* Conversion specifiers, must only be one */
|
||||
KrkToken which;
|
||||
if (*c == 'r') {
|
||||
which = syntheticToken("repr");
|
||||
} else if (*c == 's') {
|
||||
@ -1877,12 +1877,12 @@ static void string(int type) {
|
||||
error("Unsupported conversion flag for f-string expression");
|
||||
goto _cleanupError;
|
||||
}
|
||||
size_t ind = identifierConstant(&which);
|
||||
EMIT_CONSTANT_OP(OP_GET_GLOBAL, ind);
|
||||
emitByte(OP_SWAP);
|
||||
emitBytes(OP_CALL, 1);
|
||||
c++;
|
||||
}
|
||||
size_t ind = identifierConstant(&which);
|
||||
EMIT_CONSTANT_OP(OP_GET_GLOBAL, ind);
|
||||
emitByte(OP_SWAP);
|
||||
emitBytes(OP_CALL, 1);
|
||||
if (*c == ':') {
|
||||
/* TODO format specs */
|
||||
error("Format spec not supported in f-string");
|
||||
|
@ -38,6 +38,7 @@ KRK_METHOD(str,__init__,{
|
||||
|
||||
KRK_METHOD(str,__add__,{
|
||||
METHOD_TAKES_EXACTLY(1);
|
||||
CHECK_ARG(1,str,KrkString*,them);
|
||||
const char * a;
|
||||
const char * b;
|
||||
size_t al;
|
||||
@ -47,24 +48,8 @@ KRK_METHOD(str,__add__,{
|
||||
a = AS_CSTRING(argv[0]);
|
||||
al = self->length;
|
||||
|
||||
if (!IS_STRING(argv[1])) {
|
||||
KrkClass * type = krk_getType(argv[1]);
|
||||
if (type->_tostr) {
|
||||
krk_push(argv[1]);
|
||||
KrkValue result = krk_callSimple(OBJECT_VAL(type->_tostr), 1, 0);
|
||||
krk_push(result);
|
||||
needsPop = 1;
|
||||
if (!IS_STRING(result)) return krk_runtimeError(vm.exceptions->typeError, "__str__ produced something that was not a string: '%s'", krk_typeName(result));
|
||||
b = AS_CSTRING(result);
|
||||
bl = AS_STRING(result)->length;
|
||||
} else {
|
||||
b = krk_typeName(argv[1]);
|
||||
bl = strlen(b);
|
||||
}
|
||||
} else {
|
||||
b = AS_CSTRING(argv[1]);
|
||||
bl = AS_STRING(argv[1])->length;
|
||||
}
|
||||
b = AS_CSTRING(argv[1]);
|
||||
bl = them->length;
|
||||
|
||||
size_t length = al + bl;
|
||||
char * chars = ALLOCATE(char, length + 1);
|
||||
|
7
src/vm.c
7
src/vm.c
@ -1814,11 +1814,8 @@ static KrkValue run() {
|
||||
break;
|
||||
}
|
||||
case OP_LESS: BINARY_OP(lt);
|
||||
case OP_GREATER: BINARY_OP(gt)
|
||||
case OP_ADD:
|
||||
if (IS_STRING(krk_peek(1))) krk_addObjects(); /* Shortcut for strings */
|
||||
else BINARY_OP(add)
|
||||
break;
|
||||
case OP_GREATER: BINARY_OP(gt);
|
||||
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)
|
||||
|
@ -13,9 +13,8 @@ if False:
|
||||
|
||||
print("This is the first line that should print.")
|
||||
|
||||
# Concatenation currently requires the first argument be a string.
|
||||
# Other values then get converted to strings as you go.
|
||||
print("We can do simple concatenation " + 123 + ".")
|
||||
# Only str can be concatenated with str
|
||||
print("We can do simple concatenation " + str(123) + ".")
|
||||
|
||||
# Lox only has a 'Number' type for numerical values, but we have
|
||||
# Integer and Floating to separate the two.
|
||||
@ -23,13 +22,13 @@ print(4.2 * 9.7) # Should be 40.74
|
||||
print(1 + 2 + 3)
|
||||
|
||||
# Other bases:
|
||||
print("Hex: " + 0xFF + " Octal: " + 0o123 + " Binary: " + 0b1010)
|
||||
print("Hex:", 0xFF, "Octal:", 0o123, "Binary:", 0b1010)
|
||||
|
||||
# This `for init, cond, step:` syntax is possibly temporary? I do intend to
|
||||
# implement iterators and `for VAR in ITER:` like in Python, but C-style for
|
||||
# loops are also useful...
|
||||
for i = 0; i < 10; i = i + 1:
|
||||
print("i = " + i)
|
||||
print("i =", i)
|
||||
|
||||
# Functions work like in Python, though currently no default values.
|
||||
def function(arg): # And of course the parser will handle comments here...
|
||||
@ -49,7 +48,7 @@ print("This code is after the function definition")
|
||||
# now we're following traditional scoping rules, and a simple `let foo` at
|
||||
# the head of the appropriate block should work okay.
|
||||
let result = function("demo")
|
||||
print("The function call returned: " + result)
|
||||
print("The function call returned:", result)
|
||||
|
||||
# `sleep()` is a native function bind. Lox has `clock` as an example, but I
|
||||
# figured something with arguments would be more useful? The purpose of this
|
||||
@ -57,7 +56,7 @@ print("The function call returned: " + result)
|
||||
# plugins for bim, so native bindings are going to be very important.
|
||||
result = time.sleep(0.1)
|
||||
|
||||
print("Call to sleep returned: " + result)
|
||||
print("Call to sleep returned:", result)
|
||||
|
||||
function("something else")
|
||||
|
||||
@ -125,9 +124,9 @@ class SuperClass():
|
||||
def __str__(self):
|
||||
return "(I am a " + self.a + ")"
|
||||
def __get__(self, ind):
|
||||
return "(get[" + ind + "])"
|
||||
return "(get[" + str(ind) + "])"
|
||||
def __set__(self, ind, val):
|
||||
print("(set[" + ind + "] = " + val + ")")
|
||||
print("(set[" + str(ind) + "] = " + val + ")")
|
||||
|
||||
class SubClass(SuperClass):
|
||||
def __init__(self):
|
||||
@ -145,7 +144,7 @@ subclass.aMethod()
|
||||
#def notAMethoDeither(self):
|
||||
# print(self)
|
||||
|
||||
print("Subclass says: " + subclass)
|
||||
print("Subclass says:", subclass)
|
||||
|
||||
subclass.__get__(123)
|
||||
print(subclass[123])
|
||||
@ -158,13 +157,13 @@ print(hash["hello"])
|
||||
|
||||
print("Let's make some lists:")
|
||||
let l = list()
|
||||
print("Length before: " + len(l))
|
||||
print("Length before:", len(l))
|
||||
l.append(1)
|
||||
l.append(2)
|
||||
l.append(3)
|
||||
print("Length after: " + len(l))
|
||||
print("Length after:", len(l))
|
||||
for j = 0; j < len(l); j = j + 1:
|
||||
print("j=" + j + ", list[j]=" + l[j])
|
||||
print("j=" + str(j) + ", list[j]=" + str(l[j]))
|
||||
|
||||
print("Can we call properties of strings?".__len__()) # Of course we can.
|
||||
|
||||
|
@ -9,4 +9,4 @@ for v in h.keys():
|
||||
print(v)
|
||||
|
||||
for v in h.keys():
|
||||
print("" + v + ": " + h[v])
|
||||
print(str(v) + ": " + str(h[v]))
|
||||
|
Loading…
Reference in New Issue
Block a user