mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-18 13:49:59 +01:00
Merge branch 'improve-debugging' of git://github.com/gsmaverick/wren into gsmaverick-improve-debugging
This commit is contained in:
@ -24,6 +24,34 @@ static void* defaultReallocate(void* memory, size_t oldSize, size_t newSize)
|
|||||||
return realloc(memory, 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)
|
WrenVM* wrenNewVM(WrenConfiguration* configuration)
|
||||||
{
|
{
|
||||||
WrenReallocateFn reallocate = defaultReallocate;
|
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 the class's method table doesn't include the symbol, bail.
|
||||||
if (symbol >= classObj->methods.count)
|
if (symbol >= classObj->methods.count)
|
||||||
{
|
{
|
||||||
char message[100];
|
char *message = methodNotFound(classObj->name->value,
|
||||||
snprintf(message, 100, "%s does not implement method '%s'.",
|
vm->methodNames.data[symbol]);
|
||||||
classObj->name->value,
|
|
||||||
vm->methodNames.data[symbol]);
|
|
||||||
RUNTIME_ERROR(message);
|
RUNTIME_ERROR(message);
|
||||||
|
free(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
Method* method = &classObj->methods.data[symbol];
|
Method* method = &classObj->methods.data[symbol];
|
||||||
@ -628,11 +655,10 @@ static bool runInterpreter(WrenVM* vm)
|
|||||||
|
|
||||||
case METHOD_NONE:
|
case METHOD_NONE:
|
||||||
{
|
{
|
||||||
char message[100];
|
char *message = methodNotFound(classObj->name->value,
|
||||||
snprintf(message, 100, "%s does not implement method '%s'.",
|
vm->methodNames.data[symbol]);
|
||||||
classObj->name->value,
|
|
||||||
vm->methodNames.data[symbol]);
|
|
||||||
RUNTIME_ERROR(message);
|
RUNTIME_ERROR(message);
|
||||||
|
free(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
@ -679,10 +705,10 @@ static bool runInterpreter(WrenVM* vm)
|
|||||||
// If the class's method table doesn't include the symbol, bail.
|
// If the class's method table doesn't include the symbol, bail.
|
||||||
if (symbol >= classObj->methods.count)
|
if (symbol >= classObj->methods.count)
|
||||||
{
|
{
|
||||||
char message[100];
|
char *message = methodNotFound(classObj->name->value,
|
||||||
snprintf(message, 100, "%s does not implement method '%s'.",
|
vm->methodNames.data[symbol]);
|
||||||
classObj->name->value, vm->methodNames.data[symbol]);
|
|
||||||
RUNTIME_ERROR(message);
|
RUNTIME_ERROR(message);
|
||||||
|
free(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
Method* method = &classObj->methods.data[symbol];
|
Method* method = &classObj->methods.data[symbol];
|
||||||
@ -731,10 +757,10 @@ static bool runInterpreter(WrenVM* vm)
|
|||||||
|
|
||||||
case METHOD_NONE:
|
case METHOD_NONE:
|
||||||
{
|
{
|
||||||
char message[100];
|
char *message = methodNotFound(classObj->name->value,
|
||||||
snprintf(message, 100, "%s does not implement method '%s'.",
|
vm->methodNames.data[symbol]);
|
||||||
classObj->name->value, vm->methodNames.data[symbol]);
|
|
||||||
RUNTIME_ERROR(message);
|
RUNTIME_ERROR(message);
|
||||||
|
free(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
|
|||||||
@ -3,5 +3,5 @@ var fiber = new Fiber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IO.print(fiber.error) // expect: null
|
IO.print(fiber.error) // expect: null
|
||||||
IO.print(fiber.try) // 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'.
|
IO.print(fiber.error) // expect: String does not implement method 'unknown' with 0 arguments.
|
||||||
|
|||||||
@ -6,5 +6,5 @@ var fiber = new Fiber {
|
|||||||
|
|
||||||
IO.print(fiber.try)
|
IO.print(fiber.try)
|
||||||
// expect: before
|
// 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
|
IO.print("after try") // expect: after try
|
||||||
|
|||||||
@ -4,4 +4,4 @@ class Foo {
|
|||||||
|
|
||||||
class Bar is 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.
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
class Foo {}
|
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.
|
||||||
|
|||||||
3
test/method/not_found_eleven_arguments.wren
Normal file
3
test/method/not_found_eleven_arguments.wren
Normal 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.
|
||||||
3
test/method/not_found_multiple_arguments.wren
Normal file
3
test/method/not_found_multiple_arguments.wren
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class Foo {}
|
||||||
|
|
||||||
|
(new Foo).someUnknownMethod(1, 2) // expect runtime error: Foo does not implement method 'someUnknownMethod' with 2 arguments.
|
||||||
3
test/method/not_found_one_argument.wren
Normal file
3
test/method/not_found_one_argument.wren
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class Foo {}
|
||||||
|
|
||||||
|
(new Foo).someUnknownMethod(1) // expect runtime error: Foo does not implement method 'someUnknownMethod' with 1 argument.
|
||||||
@ -1,3 +1,3 @@
|
|||||||
class Foo {}
|
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.
|
||||||
@ -1,7 +1,7 @@
|
|||||||
class Base {}
|
class Base {}
|
||||||
|
|
||||||
class Derived is 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
|
(new Derived).foo
|
||||||
|
|||||||
Reference in New Issue
Block a user