Merge branch 'improve-debugging' of git://github.com/gsmaverick/wren into gsmaverick-improve-debugging

This commit is contained in:
Bob Nystrom
2015-01-08 21:49:20 -08:00
10 changed files with 56 additions and 21 deletions

View File

@ -24,6 +24,34 @@ static void* defaultReallocate(void* memory, size_t oldSize, size_t newSize)
return realloc(memory, newSize);
}
char* methodNotFound(char* className, char* symbolName)
{
// Count the number of spaces to determine number of arguments for this
// symbol.
int pos = strlen(symbolName) - 1;
while (symbolName[pos] == ' ') pos--;
int arguments = strlen(symbolName) - pos - 1;
// Create a new string that contains only the symbol name.
char *canonicalizedSymbol = malloc(pos + 1);
strncpy(canonicalizedSymbol, symbolName, pos + 1);
int messageLength = strlen(className) + strlen(canonicalizedSymbol) +
(arguments > 9 ? 48 : 47) + (arguments == 1 ? 0 : 1);
char *message = malloc(messageLength);
snprintf(message, messageLength, "%s does not implement method '%s' with %d argument%s.",
className,
canonicalizedSymbol,
arguments,
arguments == 1 ? "" : "s");
free(canonicalizedSymbol);
return &message[0];
}
WrenVM* wrenNewVM(WrenConfiguration* configuration)
{
WrenReallocateFn reallocate = defaultReallocate;
@ -575,11 +603,10 @@ static bool runInterpreter(WrenVM* vm)
// If the class's method table doesn't include the symbol, bail.
if (symbol >= classObj->methods.count)
{
char message[100];
snprintf(message, 100, "%s does not implement method '%s'.",
classObj->name->value,
vm->methodNames.data[symbol]);
char *message = methodNotFound(classObj->name->value,
vm->methodNames.data[symbol]);
RUNTIME_ERROR(message);
free(message);
}
Method* method = &classObj->methods.data[symbol];
@ -628,11 +655,10 @@ static bool runInterpreter(WrenVM* vm)
case METHOD_NONE:
{
char message[100];
snprintf(message, 100, "%s does not implement method '%s'.",
classObj->name->value,
vm->methodNames.data[symbol]);
char *message = methodNotFound(classObj->name->value,
vm->methodNames.data[symbol]);
RUNTIME_ERROR(message);
free(message);
}
}
DISPATCH();
@ -679,10 +705,10 @@ static bool runInterpreter(WrenVM* vm)
// If the class's method table doesn't include the symbol, bail.
if (symbol >= classObj->methods.count)
{
char message[100];
snprintf(message, 100, "%s does not implement method '%s'.",
classObj->name->value, vm->methodNames.data[symbol]);
char *message = methodNotFound(classObj->name->value,
vm->methodNames.data[symbol]);
RUNTIME_ERROR(message);
free(message);
}
Method* method = &classObj->methods.data[symbol];
@ -731,10 +757,10 @@ static bool runInterpreter(WrenVM* vm)
case METHOD_NONE:
{
char message[100];
snprintf(message, 100, "%s does not implement method '%s'.",
classObj->name->value, vm->methodNames.data[symbol]);
char *message = methodNotFound(classObj->name->value,
vm->methodNames.data[symbol]);
RUNTIME_ERROR(message);
free(message);
}
}
DISPATCH();

View File

@ -3,5 +3,5 @@ var fiber = new Fiber {
}
IO.print(fiber.error) // expect: null
IO.print(fiber.try) // expect: String does not implement method 'unknown'.
IO.print(fiber.error) // expect: String does not implement method 'unknown'.
IO.print(fiber.try) // expect: String does not implement method 'unknown' with 0 arguments.
IO.print(fiber.error) // expect: String does not implement method 'unknown' with 0 arguments.

View File

@ -6,5 +6,5 @@ var fiber = new Fiber {
IO.print(fiber.try)
// expect: before
// expect: Bool does not implement method 'unknownMethod'.
// expect: Bool does not implement method 'unknownMethod' with 0 arguments.
IO.print("after try") // expect: after try

View File

@ -4,4 +4,4 @@ class Foo {
class Bar is Foo {}
Bar.methodOnFoo // expect runtime error: Bar metaclass does not implement method 'methodOnFoo'.
Bar.methodOnFoo // expect runtime error: Bar metaclass does not implement method 'methodOnFoo' with 0 arguments.

View File

@ -1,3 +1,3 @@
class Foo {}
(new Foo).someUnknownMethod // expect runtime error: Foo does not implement method 'someUnknownMethod'.
(new Foo).someUnknownMethod // expect runtime error: Foo does not implement method 'someUnknownMethod' with 0 arguments.

View File

@ -0,0 +1,3 @@
class Foo {}
(new Foo).someUnknownMethod(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) // expect runtime error: Foo does not implement method 'someUnknownMethod' with 11 arguments.

View File

@ -0,0 +1,3 @@
class Foo {}
(new Foo).someUnknownMethod(1, 2) // expect runtime error: Foo does not implement method 'someUnknownMethod' with 2 arguments.

View File

@ -0,0 +1,3 @@
class Foo {}
(new Foo).someUnknownMethod(1) // expect runtime error: Foo does not implement method 'someUnknownMethod' with 1 argument.

View File

@ -1,3 +1,3 @@
class Foo {}
Foo.bar // expect runtime error: Foo metaclass does not implement method 'bar'.
Foo.bar // expect runtime error: Foo metaclass does not implement method 'bar' with 0 arguments.

View File

@ -1,7 +1,7 @@
class Base {}
class Derived is Base {
foo { super.doesNotExist } // expect runtime error: Base does not implement method 'doesNotExist'.
foo { super.doesNotExist } // expect runtime error: Base does not implement method 'doesNotExist' with 0 arguments.
}
(new Derived).foo