+2
-30
@@ -2964,7 +2964,7 @@ static void defineMethod(Compiler* compiler, int classSlot, bool isStatic,
|
||||
// Returns `true` if it compiled successfully, or `false` if the method couldn't
|
||||
// be parsed.
|
||||
static bool method(Compiler* compiler, ClassCompiler* classCompiler,
|
||||
int classSlot, bool* hasConstructor)
|
||||
int classSlot)
|
||||
{
|
||||
// TODO: What about foreign constructors?
|
||||
bool isForeign = match(compiler, TOKEN_FOREIGN);
|
||||
@@ -3030,31 +3030,11 @@ static bool method(Compiler* compiler, ClassCompiler* classCompiler,
|
||||
|
||||
createConstructor(compiler, &signature, methodSymbol);
|
||||
defineMethod(compiler, classSlot, true, constructorSymbol);
|
||||
|
||||
// We don't need a default constructor anymore.
|
||||
*hasConstructor = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Defines a default "new()" constructor on the current class.
|
||||
//
|
||||
// It just invokes "init new()" on the instance. If a base class defines that,
|
||||
// it will get invoked. Otherwise, it falls to the default one in Object which
|
||||
// does nothing.
|
||||
static void createDefaultConstructor(Compiler* compiler, int classSlot)
|
||||
{
|
||||
Signature signature = { "new", 3, SIG_INITIALIZER, 0 };
|
||||
int initializerSymbol = signatureSymbol(compiler, &signature);
|
||||
|
||||
signature.type = SIG_METHOD;
|
||||
int constructorSymbol = signatureSymbol(compiler, &signature);
|
||||
|
||||
createConstructor(compiler, &signature, initializerSymbol);
|
||||
defineMethod(compiler, classSlot, true, constructorSymbol);
|
||||
}
|
||||
|
||||
// Compiles a class definition. Assumes the "class" token has already been
|
||||
// consumed (along with a possibly preceding "foreign" token).
|
||||
static void classDefinition(Compiler* compiler, bool isForeign)
|
||||
@@ -3117,11 +3097,9 @@ static void classDefinition(Compiler* compiler, bool isForeign)
|
||||
consume(compiler, TOKEN_LEFT_BRACE, "Expect '{' after class declaration.");
|
||||
matchLine(compiler);
|
||||
|
||||
bool hasConstructor = false;
|
||||
|
||||
while (!match(compiler, TOKEN_RIGHT_BRACE))
|
||||
{
|
||||
if (!method(compiler, &classCompiler, slot, &hasConstructor)) break;
|
||||
if (!method(compiler, &classCompiler, slot)) break;
|
||||
|
||||
// Don't require a newline after the last definition.
|
||||
if (match(compiler, TOKEN_RIGHT_BRACE)) break;
|
||||
@@ -3129,12 +3107,6 @@ static void classDefinition(Compiler* compiler, bool isForeign)
|
||||
consumeLine(compiler, "Expect newline after definition in class.");
|
||||
}
|
||||
|
||||
// If no constructor was defined, create a default new() one.
|
||||
if (!hasConstructor)
|
||||
{
|
||||
createDefaultConstructor(compiler, slot);
|
||||
}
|
||||
|
||||
// Update the class with the number of fields.
|
||||
if (!isForeign)
|
||||
{
|
||||
|
||||
+6
-12
@@ -213,16 +213,6 @@ static const char* coreLibSource =
|
||||
"\n"
|
||||
"class Range is Sequence {}\n";
|
||||
|
||||
// A simple primitive that just returns "this". Used in a few different places:
|
||||
//
|
||||
// * The default new() initializer on Object needs no initialization so just
|
||||
// uses this.
|
||||
// * String's toString method obviously can use this.
|
||||
DEF_PRIMITIVE(return_this)
|
||||
{
|
||||
RETURN_VAL(args[0]);
|
||||
}
|
||||
|
||||
DEF_PRIMITIVE(bool_not)
|
||||
{
|
||||
RETURN_BOOL(!AS_BOOL(args[0]));
|
||||
@@ -1258,6 +1248,11 @@ DEF_PRIMITIVE(string_subscript)
|
||||
RETURN_ERROR("Subscript ranges for strings are not implemented yet.");
|
||||
}
|
||||
|
||||
DEF_PRIMITIVE(string_toString)
|
||||
{
|
||||
RETURN_VAL(args[0]);
|
||||
}
|
||||
|
||||
// Creates either the Object or Class class in the core library with [name].
|
||||
static ObjClass* defineClass(WrenVM* vm, ObjModule* module, const char* name)
|
||||
{
|
||||
@@ -1282,7 +1277,6 @@ void wrenInitializeCore(WrenVM* vm)
|
||||
PRIMITIVE(vm->objectClass, "!", object_not);
|
||||
PRIMITIVE(vm->objectClass, "==(_)", object_eqeq);
|
||||
PRIMITIVE(vm->objectClass, "!=(_)", object_bangeq);
|
||||
PRIMITIVE(vm->objectClass, "init new()", return_this);
|
||||
PRIMITIVE(vm->objectClass, "is(_)", object_is);
|
||||
PRIMITIVE(vm->objectClass, "toString", object_toString);
|
||||
PRIMITIVE(vm->objectClass, "type", object_type);
|
||||
@@ -1436,7 +1430,7 @@ void wrenInitializeCore(WrenVM* vm)
|
||||
PRIMITIVE(vm->stringClass, "iterateByte_(_)", string_iterateByte);
|
||||
PRIMITIVE(vm->stringClass, "iteratorValue(_)", string_iteratorValue);
|
||||
PRIMITIVE(vm->stringClass, "startsWith(_)", string_startsWith);
|
||||
PRIMITIVE(vm->stringClass, "toString", return_this);
|
||||
PRIMITIVE(vm->stringClass, "toString", string_toString);
|
||||
|
||||
vm->listClass = AS_CLASS(wrenFindVariable(vm, coreModule, "List"));
|
||||
PRIMITIVE(vm->listClass->obj.classObj, "new()", list_new);
|
||||
|
||||
Reference in New Issue
Block a user