summaryrefslogtreecommitdiff
path: root/src/puzzles/puzzle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/puzzles/puzzle.c')
-rw-r--r--src/puzzles/puzzle.c104
1 files changed, 102 insertions, 2 deletions
diff --git a/src/puzzles/puzzle.c b/src/puzzles/puzzle.c
index 22f7a4d..286057b 100644
--- a/src/puzzles/puzzle.c
+++ b/src/puzzles/puzzle.c
@@ -4,6 +4,8 @@
#include <string.h>
#include <wren.h>
+static const char *USER_MODULE_NAME = "main";
+
/// Returns 1 test puzzle for the GetTestPuzzle segment
Test *getTestPuzzleTests() {
Test *outp = malloc(sizeof(Test));
@@ -53,10 +55,108 @@ void FreePuzzle(Puzzle *self) {
free(self);
}
+// We are currenttly
+void PutIOIntoSlot(int slot, PuzzleIO *io, WrenVM *vm) {
+ switch (io->type) {
+ case (WREN_TYPE_BOOL):
+ wrenSetSlotBool(vm, slot, *(bool *)io->value);
+ break;
+ case (WREN_TYPE_NUM):
+ wrenSetSlotDouble(vm, slot, *(double *)io->value);
+ break;
+ case (WREN_TYPE_LIST):
+ wrenSetSlotDouble(vm, slot, *(double *)io->value);
+ break;
+ case (WREN_TYPE_MAP):
+ // TODO
+ return;
+ case (WREN_TYPE_NULL):
+ wrenSetSlotNull(vm, slot);
+ break;
+ case (WREN_TYPE_STRING):
+ wrenSetSlotString(vm, slot, io->value);
+ break;
+ default:
+ return;
+ }
+}
+
+// The cleanest way to do it is move this from the CheckResult enum
+bool checkResultString(PuzzleIO *io, WrenVM *vm) {
+ const char *res = wrenGetSlotString(vm, 0);
+ if (res == NULL || io->value == NULL) return false;
+ return strcmp(res, io->value) == 0;
+}
+
+bool CheckResult(PuzzleIO *io, WrenVM *vm) {
+ WrenType actual_type = wrenGetSlotType(vm, 0);
+
+ switch (io->type) {
+ case (WREN_TYPE_BOOL):
+ if (actual_type != WREN_TYPE_BOOL) return false;
+ if (io->value == NULL) return false;
+ return wrenGetSlotBool(vm, 0) == *((bool *)io->value);
+
+ case (WREN_TYPE_NUM):
+ if (actual_type != WREN_TYPE_NUM) return false;
+ if (io->value == NULL) return false;
+ return wrenGetSlotDouble(vm, 0) == *((double *)io->value);
+
+ case (WREN_TYPE_NULL):
+ return actual_type == WREN_TYPE_NULL;
+
+ case (WREN_TYPE_STRING):
+ if (actual_type != WREN_TYPE_STRING) return false;
+ return checkResultString(io, vm);
+
+ case (WREN_TYPE_LIST):
+ case (WREN_TYPE_MAP):
+ default:
+ return false;
+ }
+}
enum PUZZLE_TEST_RESULT RunTest(Test *test, WrenVM *vm) {
- // TODO: finish this
- return RESULT_OK;
+ wrenEnsureSlots(vm, test->argc + 1); // finction handle + arguments
+ wrenGetVariable(vm, USER_MODULE_NAME, test->RecieverName, 0);
+
+ WrenHandle *obj_handle = wrenGetSlotHandle(vm, 0);
+ if (obj_handle == NULL) {
+ return RESULT_COMPTIME_NO_ENTRY;
+ }
+
+ WrenHandle *fn_handle = wrenMakeCallHandle(vm, test->MainMethodSignature);
+ if (fn_handle == NULL) {
+ wrenReleaseHandle(vm, obj_handle);
+ return RESULT_COMPTIME_NO_ENTRY;
+ }
+
+ wrenSetSlotHandle(vm, 0, obj_handle);
+ for (int i = 0; i < test->argc; ++i) {
+ PutIOIntoSlot(i+1, &test->argv[i], vm);
+ }
+
+ WrenInterpretResult call_result = wrenCall(vm, fn_handle);
+
+
+ switch (call_result) {
+ case WREN_RESULT_COMPILE_ERROR:
+ return RESULT_COMPTIME_ERR;
+ case WREN_RESULT_RUNTIME_ERROR:
+ return RESULT_RUNTIME_ERR;
+ default: break;
+ }
+
+ bool result = CheckResult(&test->ExpectedResult, vm);
+
+ wrenReleaseHandle(vm, fn_handle);
+ wrenReleaseHandle(vm, obj_handle);
+
+ if (result) {
+ return RESULT_OK;
+ } else {
+ return RESULT_WRONG_ANSWER;
+ }
}
// Returns the res ptr. Does not modify the address