Skip to content

Commit

Permalink
add wrenHasVariable and wrenHasModule
Browse files Browse the repository at this point in the history
  • Loading branch information
ruby0x1 committed Dec 3, 2020
1 parent bc7dd50 commit 182ca90
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/include/wren.h
Expand Up @@ -520,6 +520,14 @@ void wrenRemoveMapValue(WrenVM* vm, int mapSlot, int keySlot,
void wrenGetVariable(WrenVM* vm, const char* module, const char* name,
int slot);

// Looks up the top level variable with [name] in resolved [module],
// returns false if not found. The module must be imported at the time,
// use wrenHasModule to ensure that before calling.
bool wrenHasVariable(WrenVM* vm, const char* module, const char* name);

// Returns true if [module] has been imported/resolved before, false if not.
bool wrenHasModule(WrenVM* vm, const char* module);

// Sets the current fiber to be aborted, and uses the value in [slot] as the
// runtime error object.
void wrenAbortFiber(WrenVM* vm, int slot);
Expand Down
34 changes: 34 additions & 0 deletions src/vm/wren_vm.c
Expand Up @@ -1898,6 +1898,40 @@ void wrenGetVariable(WrenVM* vm, const char* module, const char* name,
setSlot(vm, slot, moduleObj->variables.data[variableSlot]);
}

bool wrenHasVariable(WrenVM* vm, const char* module, const char* name)
{
ASSERT(module != NULL, "Module cannot be NULL.");
ASSERT(name != NULL, "Variable name cannot be NULL.");

Value moduleName = wrenStringFormat(vm, "$", module);
wrenPushRoot(vm, AS_OBJ(moduleName));

//We don't use wrenHasModule since we want to use the module object.
ObjModule* moduleObj = getModule(vm, moduleName);
ASSERT(moduleObj != NULL, "Could not find module.");

wrenPopRoot(vm); // moduleName.

int variableSlot = wrenSymbolTableFind(&moduleObj->variableNames,
name, strlen(name));

return variableSlot != -1;
}

bool wrenHasModule(WrenVM* vm, const char* module)
{
ASSERT(module != NULL, "Module cannot be NULL.");

Value moduleName = wrenStringFormat(vm, "$", module);
wrenPushRoot(vm, AS_OBJ(moduleName));

ObjModule* moduleObj = getModule(vm, moduleName);

wrenPopRoot(vm); // moduleName.

return moduleObj != NULL;
}

void wrenAbortFiber(WrenVM* vm, int slot)
{
validateApiSlot(vm, slot);
Expand Down
22 changes: 22 additions & 0 deletions test/api/get_variable.c
Expand Up @@ -32,13 +32,35 @@ static void otherModule(WrenVM* vm)
wrenGetVariable(vm, "./test/api/get_variable_module", "Variable", 0);
}

static void hasVariable(WrenVM* vm)
{
const char* module = wrenGetSlotString(vm, 1);
const char* variable = wrenGetSlotString(vm, 2);

bool result = wrenHasVariable(vm, module, variable);
wrenEnsureSlots(vm, 1);
wrenSetSlotBool(vm, 0, result);
}

static void hasModule(WrenVM* vm)
{
const char* module = wrenGetSlotString(vm, 1);

bool result = wrenHasModule(vm, module);
wrenEnsureSlots(vm, 1);
wrenSetSlotBool(vm, 0, result);
}

WrenForeignMethodFn getVariableBindMethod(const char* signature)
{
if (strcmp(signature, "static GetVariable.beforeDefined()") == 0) return beforeDefined;
if (strcmp(signature, "static GetVariable.afterDefined()") == 0) return afterDefined;
if (strcmp(signature, "static GetVariable.afterAssigned()") == 0) return afterAssigned;
if (strcmp(signature, "static GetVariable.otherSlot()") == 0) return otherSlot;
if (strcmp(signature, "static GetVariable.otherModule()") == 0) return otherModule;

if (strcmp(signature, "static Has.variable(_,_)") == 0) return hasVariable;
if (strcmp(signature, "static Has.module(_)") == 0) return hasModule;

return NULL;
}
15 changes: 15 additions & 0 deletions test/api/get_variable.wren
Expand Up @@ -8,6 +8,11 @@ class GetVariable {
foreign static otherModule()
}

class Has {
foreign static variable(module, variable)
foreign static module(module)
}

System.print(GetVariable.beforeDefined()) // expect: null

var A = "a"
Expand All @@ -22,3 +27,13 @@ var B = "b"
System.print(GetVariable.otherSlot()) // expect: b

System.print(GetVariable.otherModule()) // expect: value


System.print(Has.variable("./test/api/get_variable_module", "Variable")) // expect: true
System.print(Has.variable("./test/api/get_variable_module", "NotAVariable")) // expect: false
System.print(Has.variable("./test/api/get_variable", "Has")) // expect: true
System.print(Has.variable("./test/api/get_variable", "Fake")) // expect: false

System.print(Has.module("./test/api/get_variable_module")) // expect: true
System.print(Has.module("./test/api/get_variable")) // expect: true
System.print(Has.module("not a module")) // expect: false

0 comments on commit 182ca90

Please sign in to comment.