diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index a6da6ec..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "Toy"]
- path = Toy
- url = https://github.com/Ratstail91/Toy
diff --git a/Airport.sln b/Airport.sln
deleted file mode 100644
index c1eb04c..0000000
--- a/Airport.sln
+++ /dev/null
@@ -1,58 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.4.33213.308
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Box", "Box.vcxproj", "{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}"
- ProjectSection(ProjectDependencies) = postProject
- {26360002-CC2A-469A-9B28-BA0C1AF41657} = {26360002-CC2A-469A-9B28-BA0C1AF41657}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Toy", "Toy\Toy.vcxproj", "{26360002-CC2A-469A-9B28-BA0C1AF41657}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Airport", "Airport.vcxproj", "{97F823E5-3AB8-47EF-B142-C15DD7CADF76}"
- ProjectSection(ProjectDependencies) = postProject
- {26360002-CC2A-469A-9B28-BA0C1AF41657} = {26360002-CC2A-469A-9B28-BA0C1AF41657}
- {348A36D9-181E-46AD-BEEB-8A3FFAA50E79} = {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Debug|x86 = Debug|x86
- Release|x64 = Release|x64
- Release|x86 = Release|x86
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x64.ActiveCfg = Debug|x64
- {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x64.Build.0 = Debug|x64
- {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x86.ActiveCfg = Debug|Win32
- {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x86.Build.0 = Debug|Win32
- {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x64.ActiveCfg = Release|x64
- {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x64.Build.0 = Release|x64
- {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x86.ActiveCfg = Release|Win32
- {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x86.Build.0 = Release|Win32
- {26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x64.ActiveCfg = Debug|x64
- {26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x64.Build.0 = Debug|x64
- {26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x86.ActiveCfg = Debug|Win32
- {26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x86.Build.0 = Debug|Win32
- {26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x64.ActiveCfg = Release|x64
- {26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x64.Build.0 = Release|x64
- {26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x86.ActiveCfg = Release|Win32
- {26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x86.Build.0 = Release|Win32
- {97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x64.ActiveCfg = Debug|x64
- {97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x64.Build.0 = Debug|x64
- {97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x86.ActiveCfg = Debug|Win32
- {97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x86.Build.0 = Debug|Win32
- {97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x64.ActiveCfg = Release|x64
- {97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x64.Build.0 = Release|x64
- {97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x86.ActiveCfg = Release|Win32
- {97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x86.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {11A7E1C9-DA78-4754-9B70-3B328B0B5471}
- EndGlobalSection
-EndGlobal
diff --git a/Airport.vcxproj b/Airport.vcxproj
deleted file mode 100644
index 14a001b..0000000
--- a/Airport.vcxproj
+++ /dev/null
@@ -1,161 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Release
- Win32
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 17.0
- {97F823E5-3AB8-47EF-B142-C15DD7CADF76}
- Win32Proj
- 10.0
-
-
-
- Application
- true
- v143
-
-
- Application
- false
- v143
-
-
- Application
- true
- v143
-
-
- Application
- false
- v143
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
- true
-
-
- false
- $(SolutionDir)out\$(Configuration)\
- $(Platform)\$(ProjectName)\$(Configuration)\
-
-
- $(SolutionDir)out\$(Configuration)\
- $(Platform)\$(ProjectName)\$(Configuration)\
-
-
-
- WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
- MultiThreadedDebugDLL
- Level3
- ProgramDatabase
- Disabled
-
-
- MachineX86
- true
- Console
-
-
-
-
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
- MultiThreadedDLL
- Level3
- ProgramDatabase
-
-
- MachineX86
- true
- Console
- true
- true
-
-
-
-
- SDL2main.lib;SDL2.lib;SDL2_image.lib;Toy.lib;Box.lib;%(AdditionalDependencies)
- $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration);%(AdditionalLibraryDirectories)
-
-
- $(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;$(SolutionDir)box;%(AdditionalIncludeDirectories)
- stdc17
- TOY_DISABLE_REPL
-
-
-
-
-
-
-
-
- stdc17
- TOY_DISABLE_REPL
- $(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;$(SolutionDir)box;%(AdditionalIncludeDirectories)
-
-
- $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration);%(AdditionalLibraryDirectories)
- SDL2main.lib;SDL2.lib;SDL2_image.lib;Toy.lib;Box.lib;%(AdditionalDependencies)
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Box.vcxproj b/Box.vcxproj
deleted file mode 100644
index 9037151..0000000
--- a/Box.vcxproj
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Release
- Win32
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
- 17.0
- {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}
- Win32Proj
- 10.0
-
-
-
- DynamicLibrary
- true
- v143
-
-
- DynamicLibrary
- false
- v143
-
-
- DynamicLibrary
- true
- v143
-
-
- DynamicLibrary
- false
- v143
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
- true
-
-
- $(SolutionDir)out\$(Configuration)\
- $(Platform)\$(ProjectName)\$(Configuration)\
-
-
- $(SolutionDir)out\$(Configuration)\
- $(Platform)\$(ProjectName)\$(Configuration)\
-
-
-
- WIN32;_DEBUG;_WINDOWS;_USRDLL;BOX_EXPORTS;BOX_EXPORT;%(PreprocessorDefinitions)
- MultiThreadedDebugDLL
- Level3
- ProgramDatabase
- Disabled
-
-
- MachineX86
- true
- Windows
-
-
-
-
- WIN32;NDEBUG;_WINDOWS;_USRDLL;BOX_EXPORTS;BOX_EXPORT;%(PreprocessorDefinitions)
- MultiThreadedDLL
- Level3
- ProgramDatabase
-
-
- MachineX86
- true
- Windows
- true
- true
-
-
-
-
- stdc17
- TOY_DISABLE_REPL;BOX_EXPORT;%(PreprocessorDefinitions)
- $(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;%(AdditionalIncludeDirectories)
-
-
- $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration)\;%(AdditionalLibraryDirectories)
- SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;Toy.lib;%(AdditionalDependencies)
-
-
- xcopy "$(SolutionDir)Toy\repl\lib*.*" "$(SolutionDir)box" /Y /I /E
-xcopy "$(SolutionDir)Toy\repl\repl_tools.*" "$(SolutionDir)box" /Y /I /E
-
-
-
-
- stdc17
- TOY_DISABLE_REPL;BOX_EXPORT;%(PreprocessorDefinitions)
- $(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;%(AdditionalIncludeDirectories)
-
-
- $(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration)\;%(AdditionalLibraryDirectories)
- SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;Toy.lib;%(AdditionalDependencies)
-
-
- xcopy "$(SolutionDir)Toy\repl\lib*.*" "$(SolutionDir)box" /Y /I /E
-xcopy "$(SolutionDir)Toy\repl\repl_tools.*" "$(SolutionDir)box" /Y /I /E
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index 84adf7d..433aa9a 100644
--- a/README.md
+++ b/README.md
@@ -2,27 +2,21 @@
The best way to build a game engine, is to build a game first.
-This project has now been adapted into a roguelike for the 7 day roguelike jam.
+This game utilizes the [Box Game Engine](https://github.com/Ratstail91/Box) the [Toy Programming Language](https://toylang.com).
-This game/engine utilizes the [Toy programming langauge](https://toylang.com).
-
-## Cloning
+# Cloning
Either clone recursively, or run `git submodule update --init` after cloning.
-## Building
+# Building
-We're now using Visual Studio - define the following environment variables to point to the root of each SDL2 lib:
+WIP
-* `SDL2Dir`
-* `SDL2ImageDir`
-* `SDL2TTFDir`
-
-## Running
+# Running
Make sure the program can see the `assets` folder (symbolic links can help), and all of the required DLLs are present.
-## Dependencies
+# Dependencies
* SDL2
* SDL2_image
@@ -32,6 +26,6 @@ Make sure the program can see the `assets` folder (symbolic links can help), and
* Art - Evan Hartshorn
* Coding - Kayne Ruse
-* Font - Ancient God (Koczman Bálint)
+* Font - Ancient God (Koczman B�lint)
* Font - AlphaBeta (Brian Kent)
diff --git a/Toy b/Toy
deleted file mode 160000
index 0e41b00..0000000
--- a/Toy
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 0e41b00ef4634bfe3a068a2b274fa7d89420502a
diff --git a/box/box_common.c b/box/box_common.c
deleted file mode 100644
index 3371c20..0000000
--- a/box/box_common.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "box_common.h"
-
-STATIC_ASSERT(sizeof(char) == 1);
-STATIC_ASSERT(sizeof(short) == 2);
-STATIC_ASSERT(sizeof(int) == 4);
-STATIC_ASSERT(sizeof(float) == 4);
-STATIC_ASSERT(sizeof(unsigned char) == 1);
-STATIC_ASSERT(sizeof(unsigned short) == 2);
-STATIC_ASSERT(sizeof(unsigned int) == 4);
-
diff --git a/box/box_common.h b/box/box_common.h
deleted file mode 100644
index 5e10b94..0000000
--- a/box/box_common.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-
-#define BOX_VERSION_MAJOR 0
-#define BOX_VERSION_MINOR 1
-#define BOX_VERSION_PATCH 0
-#define BOX_VERSION_BUILD __DATE__ " " __TIME__
-
-//platform/compiler-specific instructions
-#if defined(__linux__) || defined(__MINGW32__) || defined(__GNUC__)
-
-#include
-#include
-#include
-
-#include
-#define BOX_API extern
-
-#elif defined(_MSC_VER)
-
-#include
-#include
-#include
-
-#include
-#include
-
-#ifndef BOX_EXPORT
-#define BOX_API __declspec(dllimport)
-#else
-#define BOX_API __declspec(dllexport)
-#endif
-
-//TODO: figure out the sleep issue
-#define sleep Sleep
-
-#else
-
-#define BOX_API extern
-
-#endif
-
-#include
-
-//test variable sizes based on platform
-#define STATIC_ASSERT(test_for_true) static_assert((test_for_true), "(" #test_for_true ") failed")
-
-//debugging
-#include "dbg_profiler.h"
diff --git a/box/box_engine.c b/box/box_engine.c
deleted file mode 100644
index 492bde7..0000000
--- a/box/box_engine.c
+++ /dev/null
@@ -1,482 +0,0 @@
-#include "box_engine.h"
-
-#include "lib_about.h"
-#include "lib_standard.h"
-#include "lib_random.h"
-#include "lib_runner.h"
-#include "lib_engine.h"
-#include "lib_node.h"
-#include "lib_input.h"
-
-#include "repl_tools.h"
-
-#include "toy_memory.h"
-#include "toy_lexer.h"
-#include "toy_parser.h"
-#include "toy_compiler.h"
-#include "toy_interpreter.h"
-#include "toy_literal_array.h"
-#include "toy_literal_dictionary.h"
-
-#include "toy_console_colors.h"
-
-#include
-#include
-#include
-
-//define the extern engine object
-Box_Engine engine;
-
-//errors here should be fatal
-static void fatalError(char* message) {
- fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, message);
- exit(-1);
-}
-
-//exposed functions
-void Box_initEngine() {
- //clear
- engine.rootNode = NULL;
- engine.nextRootNodeFilename = TOY_TO_NULL_LITERAL;
- engine.running = false;
- engine.window = NULL;
- engine.renderer = NULL;
-
- //init SDL
- if (SDL_Init(SDL_INIT_VIDEO) != 0) {
- fatalError("Failed to initialize SDL2");
- }
-
- //init SDL_image
- int imageFlags = IMG_INIT_PNG | IMG_INIT_JPG;
- if (IMG_Init(imageFlags) != imageFlags) {
- fatalError("Failed to initialize SDL2_image");
- }
-
- //init SDL_ttf
- if (TTF_Init() == -1) {
- fatalError("Failed to initialize SDL2_ttf");
- }
-
- //init events
- Toy_initLiteralDictionary(&engine.symKeyDownEvents);
- Toy_initLiteralDictionary(&engine.symKeyUpEvents);
-
- //init Toy
- Toy_initInterpreter(&engine.interpreter);
- Toy_injectNativeHook(&engine.interpreter, "about", Toy_hookAbout);
- Toy_injectNativeHook(&engine.interpreter, "standard", Toy_hookStandard);
- Toy_injectNativeHook(&engine.interpreter, "random", Toy_hookRandom);
- Toy_injectNativeHook(&engine.interpreter, "runner", Toy_hookRunner);
- Toy_injectNativeHook(&engine.interpreter, "engine", Box_hookEngine);
- Toy_injectNativeHook(&engine.interpreter, "node", Box_hookNode);
- Toy_injectNativeHook(&engine.interpreter, "input", Box_hookInput);
-
- //run the init
- size_t size = 0;
- const unsigned char* source = Toy_readFile("./assets/scripts/init.toy", &size);
-
- if (!source) {
- fatalError("Couldn't read /assets/scripts/init.toy");
- }
-
- const unsigned char* tb = Toy_compileString((const char*)source, &size);
- free((void*)source);
-
- //A quirk of the setup is that anything defined in `init.toy` becomes a global object
- Toy_runInterpreter(&engine.interpreter, tb, size);
-}
-
-void Box_freeEngine() {
- //clear existing root node
- if (engine.rootNode != NULL) {
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onFree", NULL);
- Box_freeNode(engine.rootNode);
- engine.rootNode = NULL;
- }
-
- if (!TOY_IS_NULL(engine.nextRootNodeFilename)) {
- Toy_freeLiteral(engine.nextRootNodeFilename);
- }
-
- Toy_freeInterpreter(&engine.interpreter);
-
- //free events
- Toy_freeLiteralDictionary(&engine.symKeyDownEvents);
- Toy_freeLiteralDictionary(&engine.symKeyUpEvents);
-
- //free SDL
- SDL_DestroyRenderer(engine.renderer);
- SDL_DestroyWindow(engine.window);
- SDL_Quit();
-
- engine.renderer = NULL;
- engine.window = NULL;
-}
-
-static inline void execLoadRootNode() {
- //if a new root node is NOT needed, skip out
- if (TOY_IS_NULL(engine.nextRootNodeFilename)) {
- return;
- }
-
- //free the existing root node
- if (engine.rootNode != NULL) {
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onFree", NULL);
- Box_freeNode(engine.rootNode);
- engine.rootNode = NULL;
- }
-
- //compile the new root node
- size_t size = 0;
- const unsigned char* source = Toy_readFile(Toy_toCString(TOY_AS_STRING(engine.nextRootNodeFilename)), &size);
- const unsigned char* tb = Toy_compileString((const char*)source, &size);
- free((void*)source);
-
- //allocate the new root node
- engine.rootNode = TOY_ALLOCATE(Box_Node, 1);
-
- //BUGFIX: make an inner-interpreter
- Toy_Interpreter inner;
-
- //init the inner interpreter manually
- Toy_initLiteralArray(&inner.literalCache);
- inner.scope = Toy_pushScope(engine.interpreter.scope);
- inner.bytecode = tb;
- inner.length = size;
- inner.count = 0;
- inner.codeStart = -1;
- inner.depth = engine.interpreter.depth + 1;
- inner.panic = false;
- Toy_initLiteralArray(&inner.stack);
- inner.hooks = engine.interpreter.hooks;
- Toy_setInterpreterPrint(&inner, engine.interpreter.printOutput);
- Toy_setInterpreterAssert(&inner, engine.interpreter.assertOutput);
- Toy_setInterpreterError(&inner, engine.interpreter.errorOutput);
-
- Box_initNode(engine.rootNode, &inner, tb, size);
-
- //immediately call onLoad() after running the script - for loading other nodes
- Box_callNode(engine.rootNode, &inner, "onLoad", NULL);
-
- //cache the scope for later freeing
- engine.rootNode->scope = inner.scope;
-
- //manual cleanup
- Toy_freeLiteralArray(&inner.stack);
- Toy_freeLiteralArray(&inner.literalCache);
-
- //cleanup
- Toy_freeLiteral(engine.nextRootNodeFilename);
- engine.nextRootNodeFilename = TOY_TO_NULL_LITERAL;
-
- //init the new node-tree
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onInit", NULL);
-}
-
-static inline void execEvents() {
- Toy_LiteralArray args; //save some allocation by reusing this
- Toy_initLiteralArray(&args);
-
- //poll all events
- SDL_Event event;
-
- while (SDL_PollEvent(&event)) {
- switch(event.type) {
- //quit
- case SDL_QUIT: {
- engine.running = false;
- }
- break;
-
- //window events are handled internally
- case SDL_WINDOWEVENT: {
- switch(event.window.event) {
- case SDL_WINDOWEVENT_RESIZED:
- //TODO: toy onWindowResized, setLogicalWindowSize, getLogicalWindowSize
- //engine.screenWidth = event.window.data1;
- //engine.screenHeight = event.window.data2;
- //SDL_RenderSetLogicalSize(engine.renderer, engine.screenWidth, engine.screenHeight);
- break;
- }
- }
- break;
-
- //input
- case SDL_KEYDOWN: {
- //bugfix: ignore repeat messages
- if (event.key.repeat) {
- break;
- }
-
- //determine the given keycode
- Toy_Literal keycodeLiteral = TOY_TO_INTEGER_LITERAL( (int)(event.key.keysym.sym) );
- if (!Toy_existsLiteralDictionary(&engine.symKeyDownEvents, keycodeLiteral)) {
- Toy_freeLiteral(keycodeLiteral);
- break;
- }
-
- //get the event name
- Toy_Literal eventLiteral = Toy_getLiteralDictionary(&engine.symKeyDownEvents, keycodeLiteral);
-
- //call the function
- Toy_pushLiteralArray(&args, eventLiteral);
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onKeyDown", &args);
- Toy_freeLiteral(Toy_popLiteralArray(&args));
-
- //push to the event list
- Toy_freeLiteral(eventLiteral);
- Toy_freeLiteral(keycodeLiteral);
- }
- break;
-
- case SDL_KEYUP: {
- //bugfix: ignore repeat messages
- if (event.key.repeat) {
- break;
- }
-
- //determine the given keycode
- Toy_Literal keycodeLiteral = TOY_TO_INTEGER_LITERAL( (int)(event.key.keysym.sym) );
- if (!Toy_existsLiteralDictionary(&engine.symKeyUpEvents, keycodeLiteral)) {
- Toy_freeLiteral(keycodeLiteral);
- break;
- }
-
- //get the event name
- Toy_Literal eventLiteral = Toy_getLiteralDictionary(&engine.symKeyUpEvents, keycodeLiteral);
-
- //call the function
- Toy_pushLiteralArray(&args, eventLiteral);
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onKeyUp", &args);
- Toy_freeLiteral(Toy_popLiteralArray(&args));
-
- //push to the event list
- Toy_freeLiteral(eventLiteral);
- Toy_freeLiteral(keycodeLiteral);
- }
- break;
-
- //mouse motion
- case SDL_MOUSEMOTION: {
- Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.motion.x) );
- Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.motion.y) );
- Toy_Literal mouseXRel = TOY_TO_INTEGER_LITERAL( (int)(event.motion.xrel) );
- Toy_Literal mouseYRel = TOY_TO_INTEGER_LITERAL( (int)(event.motion.yrel) );
-
- Toy_pushLiteralArray(&args, mouseX);
- Toy_pushLiteralArray(&args, mouseY);
- Toy_pushLiteralArray(&args, mouseXRel);
- Toy_pushLiteralArray(&args, mouseYRel);
-
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseMotion", &args);
-
- Toy_freeLiteral(mouseX);
- Toy_freeLiteral(mouseY);
- Toy_freeLiteral(mouseXRel);
- Toy_freeLiteral(mouseYRel);
-
- //hack: manual free
- for(int i = 0; i < args.count; i++) {
- Toy_freeLiteral(args.literals[i]);
- }
- args.count = 0;
- }
- break;
-
- //mouse button down
- case SDL_MOUSEBUTTONDOWN: {
- Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.button.x) );
- Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.button.y) );
- Toy_Literal mouseButton;
-
- switch (event.button.button) {
- case SDL_BUTTON_LEFT:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("left"));
- break;
-
- case SDL_BUTTON_MIDDLE:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("middle"));
- break;
-
- case SDL_BUTTON_RIGHT:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("right"));
- break;
-
- case SDL_BUTTON_X1:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x1"));
- break;
-
- case SDL_BUTTON_X2:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x2"));
- break;
-
- default:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("unknown"));
- break;
- }
-
- Toy_pushLiteralArray(&args, mouseX);
- Toy_pushLiteralArray(&args, mouseY);
- Toy_pushLiteralArray(&args, mouseButton);
-
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseButtonDown", &args);
-
- Toy_freeLiteral(mouseX);
- Toy_freeLiteral(mouseY);
- Toy_freeLiteral(mouseButton);
-
- //hack: manual free
- for(int i = 0; i < args.count; i++) {
- Toy_freeLiteral(args.literals[i]);
- }
- args.count = 0;
- }
- break;
-
- //mouse button up
- case SDL_MOUSEBUTTONUP: {
- Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.button.x) );
- Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.button.y) );
- Toy_Literal mouseButton;
-
- switch (event.button.button) {
- case SDL_BUTTON_LEFT:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("left"));
- break;
-
- case SDL_BUTTON_MIDDLE:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("middle"));
- break;
-
- case SDL_BUTTON_RIGHT:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("right"));
- break;
-
- case SDL_BUTTON_X1:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x1"));
- break;
-
- case SDL_BUTTON_X2:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x2"));
- break;
-
- default:
- mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("unknown"));
- break;
- }
-
- Toy_pushLiteralArray(&args, mouseX);
- Toy_pushLiteralArray(&args, mouseY);
- Toy_pushLiteralArray(&args, mouseButton);
-
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseButtonUp", &args);
-
- Toy_freeLiteral(mouseX);
- Toy_freeLiteral(mouseY);
- Toy_freeLiteral(mouseButton);
-
- //hack: manual free
- for(int i = 0; i < args.count; i++) {
- Toy_freeLiteral(args.literals[i]);
- }
- args.count = 0;
- }
- break;
-
- //mouse wheel
- case SDL_MOUSEWHEEL: {
- Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.wheel.x) );
- Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.wheel.y) );
- Toy_pushLiteralArray(&args, mouseX);
- Toy_pushLiteralArray(&args, mouseY);
-
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseWheel", &args);
-
- Toy_freeLiteral(mouseX);
- Toy_freeLiteral(mouseY);
-
- //hack: manual free
- for(int i = 0; i < args.count; i++) {
- Toy_freeLiteral(args.literals[i]);
- }
- args.count = 0;
- }
- break;
- }
- }
-
- Toy_freeLiteralArray(&args);
-}
-
-static inline void execStep() {
- if (engine.rootNode != NULL) {
- //steps
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onStep", NULL);
- }
-}
-
-//the heart of the engine
-void Box_execEngine() {
- if (!engine.running) {
- fatalError("Can't execute the engine (did you forget to initialize the screen?)");
- }
-
- //set up time
- engine.realTime = clock();
- engine.simTime = engine.realTime;
- clock_t delta = (double) CLOCKS_PER_SEC / 30.0;
-
- Dbg_Timer dbgTimer;
- Dbg_FPSCounter fps;
-
- Dbg_initTimer(&dbgTimer);
- Dbg_initFPSCounter(&fps);
-
- while (engine.running) {
- Dbg_tickFPSCounter(&fps);
-
- Dbg_clearConsole();
- Dbg_printTimerLog(&dbgTimer);
- Dbg_printFPSCounter(&fps);
-
- Dbg_startTimer(&dbgTimer, "execLoadRootNode()");
- execLoadRootNode();
- Dbg_stopTimer(&dbgTimer);
-
- Dbg_startTimer(&dbgTimer, "execEvents()");
- execEvents();
- Dbg_stopTimer(&dbgTimer);
-
- //calc the time passed
- engine.realTime = clock();
-
- Dbg_startTimer(&dbgTimer, "execStep() (variable)");
- //while not enough time has passed
- while(engine.simTime < engine.realTime) {
- //simulate the world
- execStep();
-
- //calc the time simulation
- engine.simTime += delta;
- }
- Dbg_stopTimer(&dbgTimer);
-
- //render the world
- Dbg_startTimer(&dbgTimer, "clear screen");
- SDL_SetRenderDrawColor(engine.renderer, 128, 128, 128, 255); //NOTE: This line can be disabled later
- SDL_RenderClear(engine.renderer); //NOTE: This line can be disabled later
- Dbg_stopTimer(&dbgTimer);
-
- Dbg_startTimer(&dbgTimer, "onDraw() calls");
- Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onDraw", NULL);
- Dbg_stopTimer(&dbgTimer);
-
- Dbg_startTimer(&dbgTimer, "render screen");
- SDL_RenderPresent(engine.renderer);
- Dbg_stopTimer(&dbgTimer);
- }
-
- Dbg_freeTimer(&dbgTimer);
- Dbg_freeFPSCounter(&fps);
-}
diff --git a/box/box_engine.h b/box/box_engine.h
deleted file mode 100644
index 18e5b2e..0000000
--- a/box/box_engine.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-
-#include "box_common.h"
-#include "box_node.h"
-
-#include "toy_interpreter.h"
-#include "toy_literal_array.h"
-#include "toy_literal_dictionary.h"
-
-#include
-
-//the base engine object, which represents the state of the game
-typedef struct Box_private_engine {
- //engine stuff
- Box_Node* rootNode;
- Toy_Literal nextRootNodeFilename;
- clock_t simTime;
- clock_t realTime;
- bool running;
-
- //Toy stuff
- Toy_Interpreter interpreter;
-
- //SDL stuff
- SDL_Window* window;
- SDL_Renderer* renderer;
- int screenWidth;
- int screenHeight;
-
- //input syms mapped to events
- Toy_LiteralDictionary symKeyDownEvents; //keysym -> event names
- Toy_LiteralDictionary symKeyUpEvents; //keysym -> event names
-} Box_Engine;
-
-//extern singleton - used by various libraries
-extern Box_Engine engine;
-
-//APIs for running the engine in main()
-BOX_API void Box_initEngine();
-BOX_API void Box_execEngine();
-BOX_API void Box_freeEngine();
-
diff --git a/box/box_node.c b/box/box_node.c
deleted file mode 100644
index 7b543c2..0000000
--- a/box/box_node.c
+++ /dev/null
@@ -1,395 +0,0 @@
-#include "box_node.h"
-#include "box_engine.h"
-
-#include "toy_memory.h"
-
-void Box_initNode(Box_Node* node, Toy_Interpreter* interpreter, const unsigned char* tb, size_t size) {
- //init
- // node->freeMemory = freeMemory;
- node->functions = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
- node->parent = NULL;
- node->scope = NULL;
- node->tag = OPAQUE_TAG_NODE;
- node->children = NULL;
- node->capacity = 0;
- node->count = 0;
- node->childCount = 0;
- node->texture = NULL;
- node->rect = ((SDL_Rect) { 0, 0, 0, 0 });
- node->frames = 0;
-
- Toy_initLiteralDictionary(node->functions);
-
- //run bytecode
- Toy_runInterpreter(interpreter, tb, size);
-
- //grab all top-level functions from the dirty interpreter
- Toy_LiteralDictionary* variablesPtr = &interpreter->scope->variables;
-
- for (int i = 0; i < variablesPtr->capacity; i++) {
- //skip empties and tombstones
- if (TOY_IS_NULL(variablesPtr->entries[i].key)) {
- continue;
- }
-
- //if this variable is a function (this outmodes import and export)
- Toy_private_dictionary_entry* entry = &variablesPtr->entries[i];
- if (TOY_IS_FUNCTION(entry->value)) {
- //save a copy
- Toy_setLiteralDictionary(node->functions, entry->key, entry->value);
- }
- }
-}
-
-void Box_pushNode(Box_Node* node, Box_Node* child) {
- //push to the array
- if (node->count + 1 > node->capacity) {
- int oldCapacity = node->capacity;
-
- node->capacity = TOY_GROW_CAPACITY(oldCapacity);
- node->children = TOY_GROW_ARRAY(Box_Node*, node->children, oldCapacity, node->capacity);
- }
-
- //assign
- node->children[node->count++] = child;
-
- //reverse-assign
- child->parent = node;
-
- //count
- node->childCount++;
-}
-
-void Box_freeNode(Box_Node* node) {
- if (node == NULL) {
- return; //NO-OP
- }
-
- //free this node's children
- for (int i = 0; i < node->count; i++) {
- Box_freeNode(node->children[i]);
- }
-
- //free the pointer array to the children
- TOY_FREE_ARRAY(Box_Node*, node->children, node->capacity);
-
- if (node->functions != NULL) {
- Toy_freeLiteralDictionary(node->functions);
- TOY_FREE(Toy_LiteralDictionary, node->functions);
- }
-
- if (node->scope != NULL) {
- Toy_popScope(node->scope);
- }
-
- if (node->texture != NULL) {
- Box_freeTextureNode(node);
- }
-
- //free this node's memory
- TOY_FREE(Box_Node, node);
-}
-
-Box_Node* Box_getChildNode(Box_Node* node, int index) {
- if (index < 0 || index > node->count) {
- return NULL;
- }
-
- return node->children[index];
-}
-
-void Box_freeChildNode(Box_Node* node, int index) {
- //get the child node
- Box_Node* childNode = node->children[index];
-
- //free the node
- if (childNode != NULL) {
- Box_freeNode(childNode);
- node->childCount--;
- }
-
- node->children[index] = NULL;
-}
-
-static void swapUtil(Box_Node** lhs, Box_Node** rhs) {
- Box_Node* tmp = *lhs;
- *lhs = *rhs;
- *rhs = tmp;
-}
-
-//copied from lib_standard.c
-static void recursiveLiteralQuicksortUtil(Toy_Interpreter* interpreter, Box_Node** ptr, int count, Toy_Literal fnCompare) {
- //base case
- if (count <= 1) {
- return;
- }
-
- int runner = 0;
-
- //iterate through the array
- for (int checker = 0; checker < count - 1; checker++) {
- //if node is null, it is always "sorted" to the end
- while (ptr[checker] == NULL && count > 0) {
- swapUtil(&ptr[checker], &ptr[count - 1]);
- count--;
- }
-
- //base case
- if (count < 2) {
- return;
- }
-
- Toy_LiteralArray arguments;
- Toy_LiteralArray returns;
-
- Toy_initLiteralArray(&arguments);
- Toy_initLiteralArray(&returns);
-
- Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(ptr[checker], OPAQUE_TAG_NODE));
- Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(ptr[count - 1], OPAQUE_TAG_NODE));
-
- Toy_callLiteralFn(interpreter, fnCompare, &arguments, &returns);
-
- Toy_Literal lessThan = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
-
- if (TOY_IS_TRUTHY(lessThan)) {
- swapUtil(&ptr[runner++], &ptr[checker]);
- }
-
- Toy_freeLiteral(lessThan);
- }
-
- //"shift everything up" so the pivot is in the middle
- swapUtil(&ptr[runner], &ptr[count - 1]);
-
- //recurse on each end
- recursiveLiteralQuicksortUtil(interpreter, &ptr[0], runner, fnCompare);
- recursiveLiteralQuicksortUtil(interpreter, &ptr[runner + 1], count - runner - 1, fnCompare);
-}
-
-BOX_API void Box_sortChildrenNode(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal fnCompare) {
- //check that this node's children aren't already sorted
- bool sorted = true;
- for (int checker = 0; checker < node->count - 1 && sorted; checker++) {
- //NULL (tombstone) is always considered unsorted
- if (node->children[checker] == NULL || node->children[checker + 1] == NULL) {
- sorted = false;
- break;
- }
-
- Toy_LiteralArray arguments;
- Toy_LiteralArray returns;
-
- Toy_initLiteralArray(&arguments);
- Toy_initLiteralArray(&returns);
-
- Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(node->children[checker], OPAQUE_TAG_NODE));
- Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(node->children[checker + 1], OPAQUE_TAG_NODE));
-
- Toy_callLiteralFn(interpreter, fnCompare, &arguments, &returns);
-
- Toy_Literal lessThan = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
-
- if (!TOY_IS_TRUTHY(lessThan)) {
- sorted = false;
- }
-
- Toy_freeLiteral(lessThan);
- }
-
- //sort the children
- if (!sorted) {
- recursiveLiteralQuicksortUtil(interpreter, node->children, node->count, fnCompare);
- }
-
- //re-count the newly-sorted children
- for (int i = node->count - 1; node->children[i] == NULL; i--) {
- node->count--;
- }
-}
-
-Toy_Literal Box_callNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args) {
- Toy_Literal ret = TOY_TO_NULL_LITERAL;
-
- //if this fn exists
- if (Toy_existsLiteralDictionary(node->functions, key)) {
- Toy_Literal fn = Toy_getLiteralDictionary(node->functions, key);
- Toy_Literal n = TOY_TO_OPAQUE_LITERAL(node, node->tag);
-
- Toy_LiteralArray arguments;
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&arguments);
- Toy_initLiteralArray(&returns);
-
- //feed the arguments in
- Toy_pushLiteralArray(&arguments, n);
-
- if (args) {
- for (int i = 0; i < args->count; i++) {
- Toy_pushLiteralArray(&arguments, args->literals[i]);
- }
- }
-
- Toy_callLiteralFn(interpreter, fn, &arguments, &returns);
-
- ret = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
-
- Toy_freeLiteral(n);
- Toy_freeLiteral(fn);
- }
-
- return ret;
-}
-
-Toy_Literal Box_callNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args) {
- //call "fnName" on this node, and all children, if it exists
- Toy_Literal key = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(fnName));
-
- Toy_Literal ret = Box_callNodeLiteral(node, interpreter, key, args);
-
- Toy_freeLiteral(key);
-
- return ret;
-}
-
-void Box_callRecursiveNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args) {
- //if this fn exists
- if (Toy_existsLiteralDictionary(node->functions, key)) {
- Toy_Literal fn = Toy_getLiteralDictionary(node->functions, key);
- Toy_Literal n = TOY_TO_OPAQUE_LITERAL(node, node->tag);
-
- Toy_LiteralArray arguments;
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&arguments);
- Toy_initLiteralArray(&returns);
-
- //feed the arguments in
- Toy_pushLiteralArray(&arguments, n);
-
- if (args) {
- for (int i = 0; i < args->count; i++) {
- Toy_pushLiteralArray(&arguments, args->literals[i]);
- }
- }
-
- Toy_callLiteralFn(interpreter, fn, &arguments, &returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
-
- Toy_freeLiteral(n);
- Toy_freeLiteral(fn);
- }
-
- //recurse to the (non-tombstone) children
- for (int i = 0; i < node->count; i++) {
- if (node->children[i] != NULL) {
- Box_callRecursiveNodeLiteral(node->children[i], interpreter, key, args);
- }
- }
-}
-
-void Box_callRecursiveNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args) {
- //call "fnName" on this node, and all children, if it exists
- Toy_Literal key = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(fnName));
-
- Box_callRecursiveNodeLiteral(node, interpreter, key, args);
-
- Toy_freeLiteral(key);
-}
-
-int Box_getChildCountNode(Box_Node* node) {
- return node->childCount;
-}
-
-int Box_loadTextureNode(Box_Node* node, const char* fname) {
- SDL_Surface* surface = IMG_Load(fname);
-
- if (surface == NULL) {
- return -1;
- }
-
- node->texture = SDL_CreateTextureFromSurface(engine.renderer, surface);
-
- if (node->texture == NULL) {
- return -2;
- }
-
- SDL_FreeSurface(surface);
-
- int w, h;
- SDL_QueryTexture(node->texture, NULL, NULL, &w, &h);
- SDL_Rect r = { 0, 0, w, h };
- Box_setRectNode(node, r);
- Box_setFramesNode(node, 1); //default
-
- return 0;
-}
-
-void Box_freeTextureNode(Box_Node* node) {
- if (node->texture != NULL) {
- SDL_DestroyTexture(node->texture);
- node->texture = NULL;
- }
-}
-
-void Box_setRectNode(Box_Node* node, SDL_Rect rect) {
- node->rect = rect;
-}
-
-SDL_Rect Box_getRectNode(Box_Node* node) {
- return node->rect;
-}
-
-void Box_setFramesNode(Box_Node* node, int frames) {
- node->frames = frames;
- node->currentFrame = 0; //just in case
-}
-
-int Box_getFramesNode(Box_Node* node) {
- return node->frames;
-}
-
-void Box_setCurrentFrameNode(Box_Node* node, int currentFrame) {
- node->currentFrame = currentFrame;
-}
-
-int Box_getCurrentFrameNode(Box_Node* node) {
- return node->currentFrame;
-}
-
-void Box_incrementCurrentFrame(Box_Node* node) {
- node->currentFrame++;
- if (node->currentFrame >= node->frames) {
- node->currentFrame = 0;
- }
-}
-
-void Box_setTextNode(Box_Node* node, TTF_Font* font, const char* text, SDL_Color color) {
- SDL_Surface* surface = TTF_RenderText_Solid(font, text, color);
-
- node->texture = SDL_CreateTextureFromSurface(engine.renderer, surface);
-
- node->rect = (SDL_Rect){ .x = 0, .y = 0, .w = surface->w, .h = surface->h };
- node->frames = 1;
- node->currentFrame = 0;
-
- SDL_FreeSurface(surface);
-}
-
-
-void Box_drawNode(Box_Node* node, SDL_Rect dest) {
- if (!node->texture) return;
- SDL_Rect src = node->rect;
- src.x += src.w * node->currentFrame;
- SDL_RenderCopy(engine.renderer, node->texture, &src, &dest);
-}
diff --git a/box/box_node.h b/box/box_node.h
deleted file mode 100644
index b223e75..0000000
--- a/box/box_node.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#pragma once
-
-#include "box_common.h"
-
-#include "toy_literal_dictionary.h"
-#include "toy_interpreter.h"
-
-#define OPAQUE_TAG_NODE 1001
-
-//forward declare
-typedef struct Box_private_node Box_Node;
-
-//the node object, which forms a tree
-typedef struct Box_private_node {
- //toy functions, stored in a dict for flexibility
- Toy_LiteralDictionary* functions;
-
- //point to the parent
- Box_Node* parent;
-
- //BUGFIX: hold the node's scope so it can be popped
- Toy_Scope* scope;
-
- //my opaque type tag
- int tag;
-
- //use Toy's memory model
- Box_Node** children;
- int capacity;
- int count; //includes tombstones
- int childCount;
-
- //rendering-specific features
- SDL_Texture* texture;
- SDL_Rect rect; //rendered rect
- int frames; //horizontal-strip based animations
- int currentFrame;
-} Box_Node;
-
-BOX_API void Box_initNode(Box_Node* node, Toy_Interpreter* interpreter, const unsigned char* tb, size_t size); //run bytecode, then grab all top-level function literals
-BOX_API void Box_pushNode(Box_Node* node, Box_Node* child); //push to the array (prune tombstones when expanding/copying)
-BOX_API void Box_freeNode(Box_Node* node); //free this node and all children
-
-BOX_API Box_Node* Box_getChildNode(Box_Node* node, int index);
-BOX_API void Box_freeChildNode(Box_Node* node, int index);
-
-BOX_API void Box_sortChildrenNode(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal fnCompare);
-
-BOX_API Toy_Literal Box_callNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args);
-BOX_API Toy_Literal Box_callNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args); //call "fnName" on this node, and only this node, if it exists
-
-//for calling various lifecycle functions
-BOX_API void Box_callRecursiveNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args);
-BOX_API void Box_callRecursiveNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args); //call "fnName" on this node, and all children, if it exists
-
-BOX_API int Box_getChildCountNode(Box_Node* node);
-
-BOX_API int Box_loadTextureNode(Box_Node* node, const char* fname);
-BOX_API void Box_freeTextureNode(Box_Node* node);
-
-BOX_API void Box_setRectNode(Box_Node* node, SDL_Rect rect);
-BOX_API SDL_Rect Box_getRectNode(Box_Node* node);
-
-BOX_API void Box_setFramesNode(Box_Node* node, int frames);
-BOX_API int Box_getFramesNode(Box_Node* node);
-BOX_API void Box_setCurrentFrameNode(Box_Node* node, int currentFrame);
-BOX_API int Box_getCurrentFrameNode(Box_Node* node);
-BOX_API void Box_incrementCurrentFrame(Box_Node* node);
-
-BOX_API void Box_setTextNode(Box_Node* node, TTF_Font* font, const char* text, SDL_Color color);
-
-BOX_API void Box_drawNode(Box_Node* node, SDL_Rect dest);
diff --git a/box/dbg_profiler.c b/box/dbg_profiler.c
deleted file mode 100644
index 340d939..0000000
--- a/box/dbg_profiler.c
+++ /dev/null
@@ -1,114 +0,0 @@
-#include "dbg_profiler.h"
-
-#include "toy_memory.h"
-
-#include
-
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include
-
-//https://stackoverflow.com/questions/2347770/how-do-you-clear-the-console-screen-in-c
-void Dbg_clearConsole()
-{
- HANDLE hStdOut;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- DWORD count;
- DWORD cellCount;
- COORD homeCoords = { 0, 0 };
-
- hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
- if (hStdOut == INVALID_HANDLE_VALUE) return;
-
- /* Get the number of cells in the current buffer */
- if (!GetConsoleScreenBufferInfo(hStdOut, &csbi)) return;
- cellCount = csbi.dwSize.X * csbi.dwSize.Y;
-
- /* Fill the entire buffer with spaces */
- if (!FillConsoleOutputCharacter(
- hStdOut,
- (TCHAR)' ',
- cellCount,
- homeCoords,
- &count
- )) return;
-
- /* Fill the entire buffer with the current colors and attributes */
- if (!FillConsoleOutputAttribute(
- hStdOut,
- csbi.wAttributes,
- cellCount,
- homeCoords,
- &count
- )) return;
-
- /* Move the cursor home */
- SetConsoleCursorPosition(hStdOut, homeCoords);
-}
-
-#else // !_WIN32
-#include
-#include
-
-void Dbg_clearConsole()
-{
- if (!cur_term)
- {
- int result;
- setupterm(NULL, STDOUT_FILENO, &result);
- if (result <= 0) return;
- }
-
- putp(tigetstr("clear"));
-}
-#endif
-
-void Dbg_initTimer(Dbg_Timer* timer) {
- timer->name = NULL;
- timer->start = 0;
- memset(timer->log, 0, 2048);
- timer->logPos = 0;
-}
-
-void Dbg_startTimer(Dbg_Timer* timer, const char* name) {
- timer->name = name;
- timer->start = clock();
-}
-
-void Dbg_stopTimer(Dbg_Timer* timer) {
- double duration = (clock() - timer->start) / (double) CLOCKS_PER_SEC * 1000;
- timer->logPos += sprintf(&(timer->log[timer->logPos]), "%.3fms %s\n", duration, timer->name);
-}
-
-void Dbg_printTimerLog(Dbg_Timer* timer) {
- printf("%.*s", timer->logPos, timer->log);
- timer->logPos = 0;
-}
-
-void Dbg_freeTimer(Dbg_Timer* timer) {
- //
-}
-
-void Dbg_initFPSCounter(Dbg_FPSCounter* counter) {
- counter->count = 0;
- counter->start = clock();
- memset(counter->log, 0, 256);
-}
-
-void Dbg_tickFPSCounter(Dbg_FPSCounter* counter) {
- counter->count++;
-
- if (clock() - counter->start > CLOCKS_PER_SEC) {
- sprintf(counter->log, "%d FPS", counter->count);
- counter->start = clock();
- counter->count = 0;
- }
-}
-
-void Dbg_printFPSCounter(Dbg_FPSCounter* counter) {
- printf("%s\n", counter->log);
-}
-
-void Dbg_freeFPSCounter(Dbg_FPSCounter* counter) {
- //
-}
\ No newline at end of file
diff --git a/box/dbg_profiler.h b/box/dbg_profiler.h
deleted file mode 100644
index 7cd9309..0000000
--- a/box/dbg_profiler.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include
-
-void Dbg_clearConsole();
-
-typedef struct Dbg_Timer {
- const char* name;
- clock_t start;
- char log[2048];
- int logPos;
-} Dbg_Timer;
-
-void Dbg_initTimer(Dbg_Timer*);
-void Dbg_startTimer(Dbg_Timer*, const char* name);
-void Dbg_stopTimer(Dbg_Timer*);
-void Dbg_printTimerLog(Dbg_Timer*);
-void Dbg_freeTimer(Dbg_Timer*);
-
-typedef struct Dbg_FPSCounter {
- int count;
- clock_t start;
- char log[256];
-} Dbg_FPSCounter;
-
-void Dbg_initFPSCounter(Dbg_FPSCounter*);
-void Dbg_tickFPSCounter(Dbg_FPSCounter*);
-void Dbg_printFPSCounter(Dbg_FPSCounter*);
-void Dbg_freeFPSCounter(Dbg_FPSCounter*);
diff --git a/box/lib_about.c b/box/lib_about.c
deleted file mode 100644
index fe5b0c8..0000000
--- a/box/lib_about.c
+++ /dev/null
@@ -1,162 +0,0 @@
-#include "lib_about.h"
-
-#include "toy_memory.h"
-
-int Toy_hookAbout(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
- //the about keys
- Toy_Literal majorKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("major"));
- Toy_Literal minorKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("minor"));
- Toy_Literal patchKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("patch"));
- Toy_Literal buildKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("build"));
- Toy_Literal authorKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("author"));
-
- //the about identifiers
- Toy_Literal majorIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("major"));
- Toy_Literal minorIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("minor"));
- Toy_Literal patchIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("patch"));
- Toy_Literal buildIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("build"));
- Toy_Literal authorIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("author"));
-
- //the about values
- Toy_Literal majorLiteral = TOY_TO_INTEGER_LITERAL(TOY_VERSION_MAJOR);
- Toy_Literal minorLiteral = TOY_TO_INTEGER_LITERAL(TOY_VERSION_MINOR);
- Toy_Literal patchLiteral = TOY_TO_INTEGER_LITERAL(TOY_VERSION_PATCH);
- Toy_Literal buildLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(TOY_VERSION_BUILD));
- Toy_Literal authorLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("Kayne Ruse, KR Game Studios"));
-
- //store as an aliased dictionary
- if (!TOY_IS_NULL(alias)) {
- //make sure the name isn't taken
- if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
- interpreter->errorOutput("Can't override an existing variable\n");
- Toy_freeLiteral(alias);
-
- Toy_freeLiteral(majorKeyLiteral);
- Toy_freeLiteral(minorKeyLiteral);
- Toy_freeLiteral(patchKeyLiteral);
- Toy_freeLiteral(buildKeyLiteral);
- Toy_freeLiteral(authorKeyLiteral);
-
- Toy_freeLiteral(majorIdentifierLiteral);
- Toy_freeLiteral(minorIdentifierLiteral);
- Toy_freeLiteral(patchIdentifierLiteral);
- Toy_freeLiteral(buildIdentifierLiteral);
- Toy_freeLiteral(authorIdentifierLiteral);
-
- Toy_freeLiteral(majorLiteral);
- Toy_freeLiteral(minorLiteral);
- Toy_freeLiteral(patchLiteral);
- Toy_freeLiteral(buildLiteral);
- Toy_freeLiteral(authorLiteral);
-
- return -1;
- }
-
- //create the dictionary to load up with values
- Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
- Toy_initLiteralDictionary(dictionary);
-
- //set each key/value pair
- Toy_setLiteralDictionary(dictionary, majorKeyLiteral, majorLiteral);
- Toy_setLiteralDictionary(dictionary, minorKeyLiteral, minorLiteral);
- Toy_setLiteralDictionary(dictionary, patchKeyLiteral, patchLiteral);
- Toy_setLiteralDictionary(dictionary, buildKeyLiteral, buildLiteral);
- Toy_setLiteralDictionary(dictionary, authorKeyLiteral, authorLiteral);
-
- //build the type
- Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
- Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
- Toy_Literal anyType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_ANY, true);
- TOY_TYPE_PUSH_SUBTYPE(&type, strType);
- TOY_TYPE_PUSH_SUBTYPE(&type, anyType);
-
- //set scope
- Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
- Toy_declareScopeVariable(interpreter->scope, alias, type);
- Toy_setScopeVariable(interpreter->scope, alias, dict, false);
-
- //cleanup
- Toy_freeLiteral(dict);
- Toy_freeLiteral(type);
- }
-
- //store globally
- else {
- //make sure the names aren't taken
- if (Toy_isDelcaredScopeVariable(interpreter->scope, majorKeyLiteral) ||
- Toy_isDelcaredScopeVariable(interpreter->scope, minorKeyLiteral) ||
- Toy_isDelcaredScopeVariable(interpreter->scope, patchKeyLiteral) ||
- Toy_isDelcaredScopeVariable(interpreter->scope, buildKeyLiteral) ||
- Toy_isDelcaredScopeVariable(interpreter->scope, authorKeyLiteral)) {
- interpreter->errorOutput("Can't override an existing variable\n");
- Toy_freeLiteral(alias);
-
- Toy_freeLiteral(majorKeyLiteral);
- Toy_freeLiteral(minorKeyLiteral);
- Toy_freeLiteral(patchKeyLiteral);
- Toy_freeLiteral(buildKeyLiteral);
- Toy_freeLiteral(authorKeyLiteral);
-
- Toy_freeLiteral(majorIdentifierLiteral);
- Toy_freeLiteral(minorIdentifierLiteral);
- Toy_freeLiteral(patchIdentifierLiteral);
- Toy_freeLiteral(buildIdentifierLiteral);
- Toy_freeLiteral(authorIdentifierLiteral);
-
- Toy_freeLiteral(majorLiteral);
- Toy_freeLiteral(minorLiteral);
- Toy_freeLiteral(patchLiteral);
- Toy_freeLiteral(buildLiteral);
- Toy_freeLiteral(authorLiteral);
-
- return -1;
- }
-
- Toy_Literal intType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_INTEGER, true);
- Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
-
- //major
- Toy_declareScopeVariable(interpreter->scope, majorIdentifierLiteral, intType);
- Toy_setScopeVariable(interpreter->scope, majorIdentifierLiteral, majorLiteral, false);
-
- //minor
- Toy_declareScopeVariable(interpreter->scope, minorIdentifierLiteral, intType);
- Toy_setScopeVariable(interpreter->scope, minorIdentifierLiteral, minorLiteral, false);
-
- //patch
- Toy_declareScopeVariable(interpreter->scope, patchIdentifierLiteral, intType);
- Toy_setScopeVariable(interpreter->scope, patchIdentifierLiteral, patchLiteral, false);
-
- //build
- Toy_declareScopeVariable(interpreter->scope, buildIdentifierLiteral, strType);
- Toy_setScopeVariable(interpreter->scope, buildIdentifierLiteral, buildLiteral, false);
-
- //author
- Toy_declareScopeVariable(interpreter->scope, authorIdentifierLiteral, strType);
- Toy_setScopeVariable(interpreter->scope, authorIdentifierLiteral, authorLiteral, false);
-
- Toy_freeLiteral(intType);
- Toy_freeLiteral(strType);
- }
-
- //cleanup
- Toy_freeLiteral(majorKeyLiteral);
- Toy_freeLiteral(minorKeyLiteral);
- Toy_freeLiteral(patchKeyLiteral);
- Toy_freeLiteral(buildKeyLiteral);
- Toy_freeLiteral(authorKeyLiteral);
-
- Toy_freeLiteral(majorIdentifierLiteral);
- Toy_freeLiteral(minorIdentifierLiteral);
- Toy_freeLiteral(patchIdentifierLiteral);
- Toy_freeLiteral(buildIdentifierLiteral);
- Toy_freeLiteral(authorIdentifierLiteral);
-
- Toy_freeLiteral(majorLiteral);
- Toy_freeLiteral(minorLiteral);
- Toy_freeLiteral(patchLiteral);
- Toy_freeLiteral(buildLiteral);
- Toy_freeLiteral(authorLiteral);
-
- return 0;
-}
diff --git a/box/lib_about.h b/box/lib_about.h
deleted file mode 100644
index 26b1d4a..0000000
--- a/box/lib_about.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include "toy_interpreter.h"
-
-int Toy_hookAbout(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
-
diff --git a/box/lib_engine.c b/box/lib_engine.c
deleted file mode 100644
index 41f5f5c..0000000
--- a/box/lib_engine.c
+++ /dev/null
@@ -1,221 +0,0 @@
-#include "lib_engine.h"
-
-#include "box_engine.h"
-
-#include "repl_tools.h"
-#include "toy_memory.h"
-#include "toy_drive_system.h"
-#include "toy_literal_array.h"
-
-#include "toy_console_colors.h"
-
-#include
-
-//errors here should be fatal
-static void fatalError(char* message) {
- fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, message);
- exit(-1);
-}
-
-//native functions to be called
-static int nativeInitWindow(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (engine.window != NULL) {
- fatalError("Can't re-initialize the window\n");
- }
-
- if (arguments->count != 4) {
- fatalError("Incorrect number of arguments passed to initWindow\n");
- }
-
- //extract the arguments
- Toy_Literal fscreen = Toy_popLiteralArray(arguments);
- Toy_Literal screenHeight = Toy_popLiteralArray(arguments);
- Toy_Literal screenWidth = Toy_popLiteralArray(arguments);
- Toy_Literal caption = Toy_popLiteralArray(arguments);
-
- Toy_Literal captionIdn = caption;
- if (TOY_IS_IDENTIFIER(caption) && Toy_parseIdentifierToValue(interpreter, &caption)) {
- Toy_freeLiteral(captionIdn);
- }
-
- Toy_Literal screenWidthIdn = screenWidth;
- if (TOY_IS_IDENTIFIER(screenWidth) && Toy_parseIdentifierToValue(interpreter, &screenWidth)) {
- Toy_freeLiteral(screenWidthIdn);
- }
-
- Toy_Literal screenHeightIdn = screenHeight;
- if (TOY_IS_IDENTIFIER(screenHeight) && Toy_parseIdentifierToValue(interpreter, &screenHeight)) {
- Toy_freeLiteral(screenHeightIdn);
- }
-
- Toy_Literal fscreenIdn = fscreen;
- if (TOY_IS_IDENTIFIER(fscreen) && Toy_parseIdentifierToValue(interpreter, &fscreen)) {
- Toy_freeLiteral(fscreenIdn);
- }
-
- //check argument types
- if (!TOY_IS_STRING(caption) || !TOY_IS_INTEGER(screenWidth) || !TOY_IS_INTEGER(screenHeight) || !TOY_IS_BOOLEAN(fscreen)) {
- fatalError("Incorrect argument type passed to initWindow\n");
- }
-
- //init the window
- engine.window = SDL_CreateWindow(
- Toy_toCString(TOY_AS_STRING(caption)),
- SDL_WINDOWPOS_UNDEFINED,
- SDL_WINDOWPOS_UNDEFINED,
- engine.screenWidth = TOY_AS_INTEGER(screenWidth),
- engine.screenHeight = TOY_AS_INTEGER(screenHeight),
- TOY_IS_TRUTHY(fscreen) ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE
- );
-
- if (engine.window == NULL) {
- fatalError("Failed to initialize the window\n");
- }
-
- //init the renderer
- // SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
- engine.renderer = SDL_CreateRenderer(engine.window, -1, SDL_RENDERER_ACCELERATED);
-
- if (engine.renderer == NULL) {
- fatalError("Failed to initialize the renderer\n");
- }
-
- SDL_RendererInfo rendererInfo;
- SDL_GetRendererInfo(engine.renderer, &rendererInfo);
-
- printf("Renderer: %s (HW %s)\n", rendererInfo.name, rendererInfo.flags & SDL_RENDERER_ACCELERATED ? "yes" : "no");
-
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
- SDL_RenderSetLogicalSize(engine.renderer, engine.screenWidth, engine.screenHeight);
-
- //only run with a window
- engine.running = true;
-
- Toy_freeLiteral(caption);
- Toy_freeLiteral(screenWidth);
- Toy_freeLiteral(screenHeight);
- Toy_freeLiteral(fscreen);
-
- return 0;
-}
-
-static int nativeLoadRootNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to loadRootNode\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal drivePathLiteralIdn = drivePathLiteral;
- if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
- Toy_freeLiteral(drivePathLiteralIdn);
- }
-
- //check argument types
- if (!TOY_IS_STRING(drivePathLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to loadRootNode\n");
- Toy_freeLiteral(drivePathLiteral);
- return -1;
- }
-
- Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
-
- Toy_freeLiteral(drivePathLiteral); //not needed anymore
-
- if (!TOY_IS_STRING(filePathLiteral)) {
- Toy_freeLiteral(filePathLiteral);
- return -1;
- }
-
- //set the signal that a new node is needed
- engine.nextRootNodeFilename = Toy_copyLiteral(filePathLiteral);
-
- Toy_freeLiteral(filePathLiteral);
-
- return 0;
-}
-
-static int nativeGetRootNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 0) {
- interpreter->errorOutput("Incorrect number of arguments passed to getRootNode\n");
- return -1;
- }
-
- if (engine.rootNode == NULL) {
- interpreter->errorOutput("Can't access root node until after initialization\n");
- return -1;
- }
-
- Toy_Literal resultLiteral = TOY_TO_OPAQUE_LITERAL(engine.rootNode, engine.rootNode->tag);
-
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
-
- return 1;
-}
-
-//call the hook
-typedef struct Natives {
- char* name;
- Toy_NativeFn fn;
-} Natives;
-
-int Box_hookEngine(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
- //build the natives list
- Natives natives[] = {
- {"initWindow", nativeInitWindow},
- {"loadRootNode", nativeLoadRootNode},
- {"getRootNode", nativeGetRootNode},
- {NULL, NULL}
- };
-
- //store the library in an aliased dictionary
- if (!TOY_IS_NULL(alias)) {
- //make sure the name isn't taken
- if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
- interpreter->errorOutput("Can't override an existing variable\n");
- Toy_freeLiteral(alias);
- return false;
- }
-
- //create the dictionary to load up with functions
- Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
- Toy_initLiteralDictionary(dictionary);
-
- //load the dict with functions
- for (int i = 0; natives[i].name; i++) {
- Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
- Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
-
- Toy_setLiteralDictionary(dictionary, name, func);
-
- Toy_freeLiteral(name);
- Toy_freeLiteral(func);
- }
-
- //build the type
- Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
- Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
- Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
- TOY_TYPE_PUSH_SUBTYPE(&type, strType);
- TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
-
- //set scope
- Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
- Toy_declareScopeVariable(interpreter->scope, alias, type);
- Toy_setScopeVariable(interpreter->scope, alias, dict, false);
-
- //cleanup
- Toy_freeLiteral(dict);
- Toy_freeLiteral(type);
- return 0;
- }
-
- //default
- for (int i = 0; natives[i].name; i++) {
- Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
- }
-
- return 0;
-}
diff --git a/box/lib_engine.h b/box/lib_engine.h
deleted file mode 100644
index 02699b7..0000000
--- a/box/lib_engine.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include "toy_interpreter.h"
-
-int Box_hookEngine(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
-
diff --git a/box/lib_input.c b/box/lib_input.c
deleted file mode 100644
index a0c05a4..0000000
--- a/box/lib_input.c
+++ /dev/null
@@ -1,130 +0,0 @@
-#include "lib_input.h"
-
-#include "box_common.h"
-#include "box_engine.h"
-
-#include "toy_memory.h"
-
-static int nativeMapInputEventToKey(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments, Toy_LiteralDictionary* symKeyEventsPtr, char* fnName) {
- //checks
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments passed to ");
- interpreter->errorOutput(fnName);
- interpreter->errorOutput("\n");
- return -1;
- }
-
- Toy_Literal symLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal evtLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal evtLiteralIdn = evtLiteral;
- if (TOY_IS_IDENTIFIER(evtLiteral) && Toy_parseIdentifierToValue(interpreter, &evtLiteral)) {
- Toy_freeLiteral(evtLiteralIdn);
- }
-
- Toy_Literal symLiteralIdn = symLiteral;
- if (TOY_IS_IDENTIFIER(symLiteral) && Toy_parseIdentifierToValue(interpreter, &symLiteral)) {
- Toy_freeLiteral(symLiteralIdn);
- }
-
- if (!TOY_IS_STRING(symLiteral) || !TOY_IS_STRING(evtLiteral)) {
- interpreter->errorOutput("Incorrect type of arguments passed to mapInputEventToKey\n");
- return -1;
- }
-
- //use the keycode for faster lookups
- SDL_Keycode keycode = SDL_GetKeyFromName( Toy_toCString(TOY_AS_STRING(symLiteral)) );
-
- if (keycode == SDLK_UNKNOWN) {
- interpreter->errorOutput("Unknown key found: ");
- interpreter->errorOutput(SDL_GetError());
- interpreter->errorOutput("\n");
- return -1;
- }
-
- Toy_Literal keycodeLiteral = TOY_TO_INTEGER_LITERAL( (int)keycode );
-
- //save the sym-event pair
- Toy_setLiteralDictionary(symKeyEventsPtr, keycodeLiteral, evtLiteral); //I could possibly map multiple events to one sym
-
- //cleanup
- Toy_freeLiteral(symLiteral);
- Toy_freeLiteral(evtLiteral);
- Toy_freeLiteral(keycodeLiteral);
-
- return 0;
-}
-
-//dry wrappers
-static int nativeMapInputEventToKeyDown(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- return nativeMapInputEventToKey(interpreter, arguments, &engine.symKeyDownEvents, "mapInputEventToKeyDown");
-}
-
-static int nativeMapInputEventToKeyUp(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- return nativeMapInputEventToKey(interpreter, arguments, &engine.symKeyUpEvents, "mapInputEventToKeyUp");
-}
-
-//call the hook
-typedef struct Natives {
- char* name;
- Toy_NativeFn fn;
-} Natives;
-
-int Box_hookInput(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
- //build the natives list
- Natives natives[] = {
- {"mapInputEventToKeyDown", nativeMapInputEventToKeyDown},
- {"mapInputEventToKeyUp", nativeMapInputEventToKeyUp},
- // {"mapInputEventToMouse", nativeMapInputEventToMouse},
- {NULL, NULL}
- };
-
- //store the library in an aliased dictionary
- if (!TOY_IS_NULL(alias)) {
- //make sure the name isn't taken
- if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
- interpreter->errorOutput("Can't override an existing variable\n");
- Toy_freeLiteral(alias);
- return false;
- }
-
- //create the dictionary to load up with functions
- Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
- Toy_initLiteralDictionary(dictionary);
-
- //load the dict with functions
- for (int i = 0; natives[i].name; i++) {
- Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
- Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
-
- Toy_setLiteralDictionary(dictionary, name, func);
-
- Toy_freeLiteral(name);
- Toy_freeLiteral(func);
- }
-
- //build the type
- Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
- Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
- Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
- TOY_TYPE_PUSH_SUBTYPE(&type, strType);
- TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
-
- //set scope
- Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
- Toy_declareScopeVariable(interpreter->scope, alias, type);
- Toy_setScopeVariable(interpreter->scope, alias, dict, false);
-
- //cleanup
- Toy_freeLiteral(dict);
- Toy_freeLiteral(type);
- return 0;
- }
-
- //default
- for (int i = 0; natives[i].name; i++) {
- Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
- }
-
- return 0;
-}
diff --git a/box/lib_input.h b/box/lib_input.h
deleted file mode 100644
index 34e2bd4..0000000
--- a/box/lib_input.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include "toy_interpreter.h"
-
-int Box_hookInput(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
-
diff --git a/box/lib_node.c b/box/lib_node.c
deleted file mode 100644
index 7e4cd5e..0000000
--- a/box/lib_node.c
+++ /dev/null
@@ -1,1209 +0,0 @@
-#include "lib_node.h"
-
-#include "box_node.h"
-#include "box_engine.h"
-
-#include "repl_tools.h"
-#include "toy_drive_system.h"
-#include "toy_literal_array.h"
-#include "toy_memory.h"
-
-#include
-
-static int nativeLoadNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to loadNode\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal drivePathLiteralIdn = drivePathLiteral;
- if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
- Toy_freeLiteral(drivePathLiteralIdn);
- }
-
- //check argument types
- if (!TOY_IS_STRING(drivePathLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to loadNode\n");
- Toy_freeLiteral(drivePathLiteral);
- return -1;
- }
-
- Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
-
- if (!TOY_IS_STRING(filePathLiteral)) {
- Toy_freeLiteral(drivePathLiteral);
- Toy_freeLiteral(filePathLiteral);
- return -1;
- }
-
- Toy_freeLiteral(drivePathLiteral); //not needed anymore
-
- //load the new node
- size_t size = 0;
- const unsigned char* source = Toy_readFile(Toy_toCString(TOY_AS_STRING(filePathLiteral)), &size);
- const unsigned char* tb = Toy_compileString((const char*)source, &size);
- free((void*)source);
-
- Box_Node* node = TOY_ALLOCATE(Box_Node, 1);
-
- //BUGFIX: make an -interpreter
- Toy_Interpreter inner;
-
- //init the inner interpreter manually
- Toy_initLiteralArray(&inner.literalCache);
- Toy_initLiteralArray(&inner.stack);
- inner.hooks = interpreter->hooks;
- inner.scope = Toy_pushScope(interpreter->scope);
- inner.bytecode = tb;
- inner.length = size;
- inner.count = 0;
- inner.codeStart = -1;
- inner.depth = interpreter->depth + 1;
- inner.panic = false;
- Toy_setInterpreterPrint(&inner, interpreter->printOutput);
- Toy_setInterpreterAssert(&inner, interpreter->assertOutput);
- Toy_setInterpreterError(&inner, interpreter->errorOutput);
-
- Box_initNode(node, &inner, tb, size);
-
- //immediately call onLoad() after running the script - for loading other nodes
- Box_callNode(node, &inner, "onLoad", NULL);
-
- // return the node
- Toy_Literal nodeLiteral = TOY_TO_OPAQUE_LITERAL(node, node->tag);
- Toy_pushLiteralArray(&interpreter->stack, nodeLiteral);
-
- //cleanup (NOT the scope - that needs to hang around)
- node->scope = inner.scope;
-
- Toy_freeLiteralArray(&inner.stack);
- Toy_freeLiteralArray(&inner.literalCache);
- Toy_freeLiteral(filePathLiteral);
- Toy_freeLiteral(nodeLiteral);
-
- return 1;
-}
-
-static int nativeInitNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to initNode\n");
- return -1;
- }
-
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to initNode\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- Box_Node* node = TOY_AS_OPAQUE(nodeLiteral);
-
- //init the new node (and ONLY this node)
- Box_callNode(node, &engine.interpreter, "onInit", NULL);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- return 0;
-}
-
-static int nativePushNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //checks
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments passed to pushNode\n");
- return -1;
- }
-
- Toy_Literal child = Toy_popLiteralArray(arguments);
- Toy_Literal parent = Toy_popLiteralArray(arguments);
-
- Toy_Literal parentIdn = parent;
- if (TOY_IS_IDENTIFIER(parent) && Toy_parseIdentifierToValue(interpreter, &parent)) {
- Toy_freeLiteral(parentIdn);
- }
-
- Toy_Literal childIdn = child;
- if (TOY_IS_IDENTIFIER(child) && Toy_parseIdentifierToValue(interpreter, &child)) {
- Toy_freeLiteral(childIdn);
- }
-
- if (!TOY_IS_OPAQUE(parent) || !TOY_IS_OPAQUE(child)) {
- interpreter->errorOutput("Incorrect argument type passed to pushNode\n");
- Toy_freeLiteral(parent);
- Toy_freeLiteral(child);
- return -1;
- }
-
- //push the node
- Box_Node* parentNode = TOY_AS_OPAQUE(parent);
- Box_Node* childNode = TOY_AS_OPAQUE(child);
-
- Box_pushNode(parentNode, childNode);
-
- //no return value
- Toy_freeLiteral(parent);
- Toy_freeLiteral(child);
-
- return 0;
-}
-
-static int nativeGetChildNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //checks
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments passed to getChildNode\n");
- return -1;
- }
-
- Toy_Literal index = Toy_popLiteralArray(arguments);
- Toy_Literal parent = Toy_popLiteralArray(arguments);
-
- Toy_Literal parentIdn = parent;
- if (TOY_IS_IDENTIFIER(parent) && Toy_parseIdentifierToValue(interpreter, &parent)) {
- Toy_freeLiteral(parentIdn);
- }
-
- Toy_Literal indexIdn = index;
- if (TOY_IS_IDENTIFIER(index) && Toy_parseIdentifierToValue(interpreter, &index)) {
- Toy_freeLiteral(indexIdn);
- }
-
- if (!TOY_IS_OPAQUE(parent) || !TOY_IS_INTEGER(index)) {
- interpreter->errorOutput("Incorrect argument type passed to getChildNode\n");
- Toy_freeLiteral(parent);
- Toy_freeLiteral(index);
- return -1;
- }
-
- //push the node
- Box_Node* parentNode = TOY_AS_OPAQUE(parent);
- int intIndex = TOY_AS_INTEGER(index);
-
- if (intIndex < 0 || intIndex >= parentNode->count) {
- interpreter->errorOutput("index out of bounds in getChildNode\n");
- Toy_freeLiteral(parent);
- Toy_freeLiteral(index);
- return -1;
- }
-
- Box_Node* childNode = Box_getChildNode(parentNode, intIndex);
- Toy_Literal child;
-
- if (childNode == NULL) {
- child = TOY_TO_NULL_LITERAL;
- }
- else {
- child = TOY_TO_OPAQUE_LITERAL(childNode, childNode->tag);
- }
-
- Toy_pushLiteralArray(&interpreter->stack, child);
-
- //cleanup
- Toy_freeLiteral(parent);
- Toy_freeLiteral(child);
- Toy_freeLiteral(index);
-
- return 1;
-}
-
-static int nativeFreeChildNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments passed to freeChildNode\n");
- return -1;
- }
-
- Toy_Literal indexLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeLiteralIdn = nodeLiteral; //annoying
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeLiteralIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral) || !TOY_IS_INTEGER(indexLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to freeChildNode\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- Box_Node* node = TOY_AS_OPAQUE(nodeLiteral);
- int idx = TOY_AS_INTEGER(indexLiteral);
-
- //check bounds
- if (idx < 0 || idx >= node->count) {
- interpreter->errorOutput("Node index out of bounds in freeChildNode\n");
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(indexLiteral);
- return -1;
- }
-
- //TODO: differentiate between onFree() and freeing memory
- Box_callRecursiveNode(node, interpreter, "onFree", NULL);
- Box_freeChildNode(node, idx);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(indexLiteral);
- return 0;
-}
-
-static int nativeSortChildrenNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments passed to sortChildrenNode\n");
- return -1;
- }
-
- Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeLiteralIdn = nodeLiteral; //annoying
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeLiteralIdn);
- }
-
- Toy_Literal fnLiteralIdn = fnLiteral; //annoying
- if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
- Toy_freeLiteral(fnLiteralIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral) || !TOY_IS_FUNCTION(fnLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to sortChildrenNode\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- Box_Node* node = TOY_AS_OPAQUE(nodeLiteral);
-
- Box_sortChildrenNode(node, interpreter, fnLiteral);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(fnLiteral);
- return 0;
-}
-
-static int nativeGetParentNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //checks
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to getParentNode\n");
- return -1;
- }
-
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to getParentNode\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //push the node
- Box_Node* node = TOY_AS_OPAQUE(nodeLiteral);
- Box_Node* parent = node->parent;
-
- Toy_Literal parentLiteral = TOY_TO_NULL_LITERAL;
- if (parent != NULL) {
- parentLiteral = TOY_TO_OPAQUE_LITERAL(parent, parent->tag);
- }
-
- Toy_pushLiteralArray(&interpreter->stack, parentLiteral);
-
- //cleanup
- Toy_freeLiteral(parentLiteral);
- Toy_freeLiteral(nodeLiteral);
-
- return 1;
-}
-
-static int nativeGetChildNodeCount(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //checks
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to getChildNodeCount\n");
- return -1;
- }
-
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeLiteralIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeLiteralIdn);
- }
-
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to getChildNodeCount\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //get the count
- Box_Node* node = TOY_AS_OPAQUE(nodeLiteral);
- int childCount = Box_getChildCountNode(node);
- Toy_Literal childCountLiteral = TOY_TO_INTEGER_LITERAL(childCount);
-
- Toy_pushLiteralArray(&interpreter->stack, childCountLiteral);
-
- //no return value
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(childCountLiteral);
-
- return 0;
-}
-
-static int nativeLoadNodeTexture(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments passed to loadNodeTexture\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal drivePathLiteralIdn = drivePathLiteral;
- if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
- Toy_freeLiteral(drivePathLiteralIdn);
- }
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- //check argument types
- if (!TOY_IS_STRING(drivePathLiteral) || !TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to loadNodeTexture\n");
- Toy_freeLiteral(drivePathLiteral);
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
-
- if (!TOY_IS_STRING(filePathLiteral)) {
- Toy_freeLiteral(drivePathLiteral);
- Toy_freeLiteral(filePathLiteral);
- return -1;
- }
-
- Toy_freeLiteral(drivePathLiteral); //not needed anymore
-
- //actually load TODO: number the opaques, and check the tag
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
-
- if (node->texture != NULL) {
- Box_freeTextureNode(node);
- }
-
- if (Box_loadTextureNode(node, Toy_toCString(TOY_AS_STRING(filePathLiteral))) != 0) {
- interpreter->errorOutput("Failed to load the texture into the Box_Node\n");
- Toy_freeLiteral(filePathLiteral);
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //cleanup
- Toy_freeLiteral(filePathLiteral);
- Toy_freeLiteral(nodeLiteral);
-
- return 0;
-}
-
-static int nativeFreeNodeTexture(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to freeNodeTexture\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to freeNodeTexture\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //actually load TODO: number the opaques, and check the numbers
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
-
- if (node->texture != NULL) {
- Box_freeTextureNode(node);
- }
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
-
- return 0;
-}
-
-static int nativeSetNodeRect(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 5) {
- interpreter->errorOutput("Incorrect number of arguments passed to setNodeRect\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal h = Toy_popLiteralArray(arguments);
- Toy_Literal w = Toy_popLiteralArray(arguments);
- Toy_Literal y = Toy_popLiteralArray(arguments);
- Toy_Literal x = Toy_popLiteralArray(arguments);
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- Toy_Literal xi = x;
- if (TOY_IS_IDENTIFIER(x) && Toy_parseIdentifierToValue(interpreter, &x)) {
- Toy_freeLiteral(xi);
- }
-
- Toy_Literal yi = y;
- if (TOY_IS_IDENTIFIER(y) && Toy_parseIdentifierToValue(interpreter, &y)) {
- Toy_freeLiteral(yi);
- }
-
- Toy_Literal wi = w;
- if (TOY_IS_IDENTIFIER(w) && Toy_parseIdentifierToValue(interpreter, &w)) {
- Toy_freeLiteral(wi);
- }
-
- Toy_Literal hi = h;
- if (TOY_IS_IDENTIFIER(h) && Toy_parseIdentifierToValue(interpreter, &h)) {
- Toy_freeLiteral(hi);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral) || !TOY_IS_INTEGER(x) || !TOY_IS_INTEGER(y) || !TOY_IS_INTEGER(w) || !TOY_IS_INTEGER(h)) {
- interpreter->errorOutput("Incorrect argument type passed to setNodeRect\n");
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(x);
- Toy_freeLiteral(y);
- Toy_freeLiteral(w);
- Toy_freeLiteral(h);
- return -1;
- }
-
- //actually set
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
-
- SDL_Rect r = {TOY_AS_INTEGER(x), TOY_AS_INTEGER(y), TOY_AS_INTEGER(w), TOY_AS_INTEGER(h)};
- Box_setRectNode(node, r);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(x);
- Toy_freeLiteral(y);
- Toy_freeLiteral(w);
- Toy_freeLiteral(h);
-
- return 0;
-}
-
-static int nativeGetNodeRectX(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to getNodeRectX\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to getNodeRectX\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //actually get
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
- Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(node->rect.x);
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(resultLiteral);
-
- return 1;
-}
-
-static int nativeGetNodeRectY(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to getNodeRectY\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to getNodeRectY\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //actually get
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
- Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(node->rect.y);
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(resultLiteral);
-
- return 1;
-}
-
-static int nativeGetNodeRectW(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to getNodeRectW\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to getNodeRectW\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //actually get
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
- Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(node->rect.w);
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(resultLiteral);
-
- return 1;
-}
-
-static int nativeGetNodeRectH(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to getNodeRectH\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to getNodeRectH\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //actually get
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
- Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(node->rect.h);
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(resultLiteral);
-
- return 1;
-}
-
-static int nativeSetNodeFrames(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments passed to setNodeFrames\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal framesLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- Toy_Literal frameLiteralIdn = framesLiteral;
- if (TOY_IS_IDENTIFIER(framesLiteral) && Toy_parseIdentifierToValue(interpreter, &framesLiteral)) {
- Toy_freeLiteral(frameLiteralIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral) || !TOY_IS_INTEGER(framesLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to setNodeFrames\n");
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(framesLiteral);
- return -1;
- }
-
- //actually set
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
-
- Box_setFramesNode(node, TOY_AS_INTEGER(framesLiteral));
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(framesLiteral);
-
- return 0;
-}
-
-static int nativeGetNodeFrames(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to getNodeFrames\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to getNodeFrames\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //actually get
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
- Toy_Literal framesLiteral = TOY_TO_INTEGER_LITERAL(node->frames);
-
- Toy_pushLiteralArray(&interpreter->stack, framesLiteral);
-
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(framesLiteral);
-
- return 1;
-}
-
-static int nativeSetCurrentNodeFrame(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments passed to setCurrentNodeFrame\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal currentFrameLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- Toy_Literal currentFrameLiteralIdn = currentFrameLiteral;
- if (TOY_IS_IDENTIFIER(currentFrameLiteral) && Toy_parseIdentifierToValue(interpreter, ¤tFrameLiteral)) {
- Toy_freeLiteral(currentFrameLiteralIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral) || !TOY_IS_INTEGER(currentFrameLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to setCurrentNodeFrame\n");
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(currentFrameLiteral);
- return -1;
- }
-
- //actually set
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
-
- Box_setCurrentFrameNode(node, TOY_AS_INTEGER(currentFrameLiteral));
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(currentFrameLiteral);
-
- return 0;
-}
-
-static int nativeGetCurrentNodeFrame(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to getCurrentNodeFrame\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to getCurrentNodeFrame\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //actually get
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
- Toy_Literal currentFrameLiteral = TOY_TO_INTEGER_LITERAL(node->currentFrame);
-
- Toy_pushLiteralArray(&interpreter->stack, currentFrameLiteral);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(currentFrameLiteral);
-
- return 1;
-}
-
-static int nativeIncrementCurrentNodeFrame(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments passed to incrementCurrentNodeFrame\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to incrementCurrentNodeFrame\n");
- Toy_freeLiteral(nodeLiteral);
- return -1;
- }
-
- //actually get
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
-
- Box_incrementCurrentFrame(node);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
-
- return 0;
-}
-
-static int nativeDrawNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 3 && arguments->count != 5) {
- interpreter->errorOutput("Incorrect number of arguments passed to drawNode\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal w = TOY_TO_NULL_LITERAL, h = TOY_TO_NULL_LITERAL;
- if (arguments->count == 5) {
- h = Toy_popLiteralArray(arguments);
- w = Toy_popLiteralArray(arguments);
- }
-
- Toy_Literal y = Toy_popLiteralArray(arguments);
- Toy_Literal x = Toy_popLiteralArray(arguments);
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- Toy_Literal xi = x;
- if (TOY_IS_IDENTIFIER(x) && Toy_parseIdentifierToValue(interpreter, &x)) {
- Toy_freeLiteral(xi);
- }
-
- Toy_Literal yi = y;
- if (TOY_IS_IDENTIFIER(y) && Toy_parseIdentifierToValue(interpreter, &y)) {
- Toy_freeLiteral(yi);
- }
-
- Toy_Literal wi = w;
- if (TOY_IS_IDENTIFIER(w) && Toy_parseIdentifierToValue(interpreter, &w)) {
- Toy_freeLiteral(wi);
- }
-
- Toy_Literal hi = h;
- if (TOY_IS_IDENTIFIER(h) && Toy_parseIdentifierToValue(interpreter, &h)) {
- Toy_freeLiteral(hi);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral) || !TOY_IS_INTEGER(x) || !TOY_IS_INTEGER(y) || (!TOY_IS_INTEGER(w) && !TOY_IS_NULL(w)) || (!TOY_IS_INTEGER(h) && !TOY_IS_NULL(h))) {
- interpreter->errorOutput("Incorrect argument type passed to drawNode\n");
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(x);
- Toy_freeLiteral(y);
- Toy_freeLiteral(w);
- Toy_freeLiteral(h);
- return -1;
- }
-
- //actually render
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
-
- SDL_Rect r = {TOY_AS_INTEGER(x), TOY_AS_INTEGER(y), 0, 0};
- if (TOY_IS_INTEGER(w) && TOY_IS_INTEGER(h)) {
- r.w = TOY_AS_INTEGER(w);
- r.h = TOY_AS_INTEGER(h);
- }
- else {
- r.w = node->rect.w;
- r.h = node->rect.h;
- }
-
- Box_drawNode(node, r);
-
- //cleanup
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(x);
- Toy_freeLiteral(y);
- Toy_freeLiteral(w);
- Toy_freeLiteral(h);
-
- return 0;
-}
-
-static int nativeSetNodeText(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 8) {
- interpreter->errorOutput("Incorrect number of arguments passed to setNodeText\n");
- return -1;
- }
-
- //extract the arguments
- Toy_Literal aLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal bLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal gLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal rLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal textLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal sizeLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal fontLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeLiteralIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeLiteralIdn);
- }
-
- Toy_Literal fontLiteralIdn = fontLiteral;
- if (TOY_IS_IDENTIFIER(fontLiteral) && Toy_parseIdentifierToValue(interpreter, &fontLiteral)) {
- Toy_freeLiteral(fontLiteralIdn);
- }
-
- Toy_Literal sizeLiteralIdn = sizeLiteral;
- if (TOY_IS_IDENTIFIER(sizeLiteral) && Toy_parseIdentifierToValue(interpreter, &sizeLiteral)) {
- Toy_freeLiteral(sizeLiteralIdn);
- }
-
- Toy_Literal textLiteralIdn = textLiteral;
- if (TOY_IS_IDENTIFIER(textLiteral) && Toy_parseIdentifierToValue(interpreter, &textLiteral)) {
- Toy_freeLiteral(textLiteralIdn);
- }
-
- Toy_Literal rLiteralIdn = rLiteral;
- if (TOY_IS_IDENTIFIER(rLiteral) && Toy_parseIdentifierToValue(interpreter, &rLiteral)) {
- Toy_freeLiteral(rLiteralIdn);
- }
-
- Toy_Literal gLiteralIdn = gLiteral;
- if (TOY_IS_IDENTIFIER(gLiteral) && Toy_parseIdentifierToValue(interpreter, &gLiteral)) {
- Toy_freeLiteral(gLiteralIdn);
- }
-
- Toy_Literal bLiteralIdn = bLiteral;
- if (TOY_IS_IDENTIFIER(bLiteral) && Toy_parseIdentifierToValue(interpreter, &bLiteral)) {
- Toy_freeLiteral(bLiteralIdn);
- }
-
- Toy_Literal aLiteralIdn = aLiteral;
- if (TOY_IS_IDENTIFIER(aLiteral) && Toy_parseIdentifierToValue(interpreter, &aLiteral)) {
- Toy_freeLiteral(aLiteralIdn);
- }
-
- //check argument types
- if (!TOY_IS_OPAQUE(nodeLiteral) || !TOY_IS_STRING(fontLiteral) || !TOY_IS_INTEGER(sizeLiteral) || !TOY_IS_STRING(textLiteral)
- || !TOY_IS_INTEGER(rLiteral) || !TOY_IS_INTEGER(gLiteral) || !TOY_IS_INTEGER(bLiteral) || !TOY_IS_INTEGER(aLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to setNodeText\n");
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(fontLiteral);
- Toy_freeLiteral(sizeLiteral);
- Toy_freeLiteral(textLiteral);
- Toy_freeLiteral(rLiteral);
- Toy_freeLiteral(gLiteral);
- Toy_freeLiteral(bLiteral);
- Toy_freeLiteral(aLiteral);
- return -1;
- }
-
- //bounds checks
- if (TOY_AS_INTEGER(rLiteral) < 0 || TOY_AS_INTEGER(rLiteral) > 255 ||
- TOY_AS_INTEGER(gLiteral) < 0 || TOY_AS_INTEGER(gLiteral) > 255 ||
- TOY_AS_INTEGER(bLiteral) < 0 || TOY_AS_INTEGER(bLiteral) > 255 ||
- TOY_AS_INTEGER(aLiteral) < 0 || TOY_AS_INTEGER(aLiteral) > 255) {
- interpreter->errorOutput("Color out of bounds in to setNodeText\n");
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(fontLiteral);
- Toy_freeLiteral(sizeLiteral);
- Toy_freeLiteral(textLiteral);
- Toy_freeLiteral(rLiteral);
- Toy_freeLiteral(gLiteral);
- Toy_freeLiteral(bLiteral);
- Toy_freeLiteral(aLiteral);
- return -1;
- }
-
- //get the font
- Toy_Literal fileLiteral = Toy_getDrivePathLiteral(interpreter, &fontLiteral);
-
- TTF_Font* font = TTF_OpenFont( Toy_toCString(TOY_AS_STRING(fileLiteral)), TOY_AS_INTEGER(sizeLiteral) );
-
- if (!font) {
- interpreter->errorOutput("Failed to open a font file: ");
- interpreter->errorOutput(SDL_GetError());
- interpreter->errorOutput("\n");
-
- Toy_freeLiteral(fileLiteral);
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(fontLiteral);
- Toy_freeLiteral(sizeLiteral);
- Toy_freeLiteral(textLiteral);
- Toy_freeLiteral(rLiteral);
- Toy_freeLiteral(gLiteral);
- Toy_freeLiteral(bLiteral);
- Toy_freeLiteral(aLiteral);
- return -1;
- }
-
- //make the color
- SDL_Color color = (SDL_Color){ .r = TOY_AS_INTEGER(rLiteral), .g = TOY_AS_INTEGER(gLiteral), .b = TOY_AS_INTEGER(bLiteral), .a = TOY_AS_INTEGER(aLiteral) };
-
- //actually set
- Box_Node* node = (Box_Node*)TOY_AS_OPAQUE(nodeLiteral);
- Box_setTextNode(node, font, Toy_toCString(TOY_AS_STRING(textLiteral)), color);
-
- //cleanup
- TTF_CloseFont(font);
-
- Toy_freeLiteral(fileLiteral);
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(fontLiteral);
- Toy_freeLiteral(sizeLiteral);
- Toy_freeLiteral(textLiteral);
- Toy_freeLiteral(rLiteral);
- Toy_freeLiteral(gLiteral);
- Toy_freeLiteral(bLiteral);
- Toy_freeLiteral(aLiteral);
-
- return 0;
-}
-
-static int nativeCallNodeFn(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //checks
- if (arguments->count < 2) {
- interpreter->errorOutput("Too few arguments passed to callNodeFn\n");
- return -1;
- }
-
- Toy_LiteralArray extraArgsBackwards;
- Toy_initLiteralArray(&extraArgsBackwards);
-
- //extract the extra arg values
- while (arguments->count > 2) {
- Toy_Literal tmp = Toy_popLiteralArray(arguments);
-
- Toy_Literal idn = tmp; //there's almost certainly a better way of doing all of this stuff
- if (TOY_IS_IDENTIFIER(tmp) && Toy_parseIdentifierToValue(interpreter, &tmp)) {
- Toy_freeLiteral(idn);
- }
-
- Toy_pushLiteralArray(&extraArgsBackwards, tmp);
- Toy_freeLiteral(tmp);
- }
-
- //reverse the extra args
- Toy_LiteralArray extraArgs;
- Toy_initLiteralArray(&extraArgs);
-
- while (extraArgsBackwards.count > 0) {
- Toy_Literal tmp = Toy_popLiteralArray(&extraArgsBackwards);
- Toy_pushLiteralArray(&extraArgs, tmp);
- Toy_freeLiteral(tmp);
- }
-
- Toy_freeLiteralArray(&extraArgsBackwards);
-
- //back on track
- Toy_Literal fnName = Toy_popLiteralArray(arguments);
- Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal nodeIdn = nodeLiteral;
- if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
- Toy_freeLiteral(nodeIdn);
- }
-
- Toy_Literal fnNameIdn = fnName;
- if (TOY_IS_IDENTIFIER(fnName) && Toy_parseIdentifierToValue(interpreter, &fnName)) {
- Toy_freeLiteral(fnNameIdn);
- }
-
- if (!TOY_IS_OPAQUE(nodeLiteral) || !TOY_IS_STRING(fnName)) {
- interpreter->errorOutput("Incorrect argument type passed to callNodeFn\n");
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(fnName);
- return -1;
- }
-
- //allow refstring to do it's magic
- Toy_Literal fnNameIdentifier = TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_STRING(fnName)));
-
- //call the function
- Toy_Literal result = Box_callNodeLiteral(TOY_AS_OPAQUE(nodeLiteral), interpreter, fnNameIdentifier, &extraArgs);
-
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- //cleanup
- Toy_freeLiteralArray(&extraArgs);
- Toy_freeLiteral(fnNameIdentifier);
- Toy_freeLiteral(nodeLiteral);
- Toy_freeLiteral(fnName);
- Toy_freeLiteral(result);
-
- return 1;
-}
-
-//call the hook
-typedef struct Natives {
- char* name;
- Toy_NativeFn fn;
-} Natives;
-
-int Box_hookNode(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
- //build the natives list
- Natives natives[] = {
- {"loadNode", nativeLoadNode},
- {"initNode", nativeInitNode},
- {"pushNode", nativePushNode},
- {"getChildNode", nativeGetChildNode},
- {"freeChildNode", nativeFreeChildNode},
- {"sortChildrenNode", nativeSortChildrenNode},
- {"getParentNode", nativeGetParentNode},
- {"getChildNodeCount", nativeGetChildNodeCount},
- {"loadNodeTexture", nativeLoadNodeTexture},
- {"freeNodeTexture", nativeFreeNodeTexture},
- {"setNodeRect", nativeSetNodeRect},
- {"getNodeRectX", nativeGetNodeRectX},
- {"getNodeRectY", nativeGetNodeRectY},
- {"getNodeRectW", nativeGetNodeRectW},
- {"getNodeRectH", nativeGetNodeRectH},
- {"setNodeFrames", nativeSetNodeFrames},
- {"getNodeFrames", nativeGetNodeFrames},
- {"setCurrentNodeFrame", nativeSetCurrentNodeFrame},
- {"getCurrentNodeFrame", nativeGetCurrentNodeFrame},
- {"incrementCurrentNodeFrame", nativeIncrementCurrentNodeFrame},
- {"drawNode", nativeDrawNode},
- {"setNodeText", nativeSetNodeText},
- {"callNodeFn", nativeCallNodeFn},
-
- //TODO: get rect, get node var, create empty node, set node color (tinting)
- {NULL, NULL},
- };
-
- //store the library in an aliased dictionary
- if (!TOY_IS_NULL(alias)) {
- //make sure the name isn't taken
- if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
- interpreter->errorOutput("Can't override an existing variable\n");
- Toy_freeLiteral(alias);
- return false;
- }
-
- //create the dictionary to load up with functions
- Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
- Toy_initLiteralDictionary(dictionary);
-
- //load the dict with functions
- for (int i = 0; natives[i].name; i++) {
- Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
- Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
-
- Toy_setLiteralDictionary(dictionary, name, func);
-
- Toy_freeLiteral(name);
- Toy_freeLiteral(func);
- }
-
- //build the type
- Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
- Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
- Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
- TOY_TYPE_PUSH_SUBTYPE(&type, strType);
- TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
-
- //set scope
- Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
- Toy_declareScopeVariable(interpreter->scope, alias, type);
- Toy_setScopeVariable(interpreter->scope, alias, dict, false);
-
- //cleanup
- Toy_freeLiteral(dict);
- Toy_freeLiteral(type);
- return 0;
- }
-
- //default
- for (int i = 0; natives[i].name; i++) {
- Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
- }
-
- return 0;
-}
diff --git a/box/lib_node.h b/box/lib_node.h
deleted file mode 100644
index febf912..0000000
--- a/box/lib_node.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include "toy_interpreter.h"
-
-int Box_hookNode(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
-
diff --git a/box/lib_random.c b/box/lib_random.c
deleted file mode 100644
index 6b70cc8..0000000
--- a/box/lib_random.c
+++ /dev/null
@@ -1,196 +0,0 @@
-#include "lib_random.h"
-
-#include "toy_memory.h"
-
-static int hashInt(int x) {
- x = ((x >> 16) ^ x) * 0x45d9f3b;
- x = ((x >> 16) ^ x) * 0x45d9f3b;
- x = ((x >> 16) ^ x) * 0x45d9f3b;
- x = (x >> 16) ^ x;
- return x;
-}
-
-typedef struct Toy_RandomGenerator {
- int seed; //mutated with each call
-} Toy_RandomGenerator;
-
-//Toy native functions
-static int nativeCreateRandomGenerator(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to createRandomGenerator\n");
- return -1;
- }
-
- //get the seed argument
- Toy_Literal seedLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal seedLiteralIdn = seedLiteral;
- if (TOY_IS_IDENTIFIER(seedLiteral) && Toy_parseIdentifierToValue(interpreter, &seedLiteral)) {
- Toy_freeLiteral(seedLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(seedLiteral)) {
- Toy_freeLiteral(seedLiteral);
- return -1;
- }
-
- if (!TOY_IS_INTEGER(seedLiteral)) {
- interpreter->errorOutput("Incorrect literal type passed to createRandomGenerator");
- Toy_freeLiteral(seedLiteral);
- return -1;
- }
-
- //generate the generator object
- Toy_RandomGenerator* generator = TOY_ALLOCATE(Toy_RandomGenerator, 1);
- generator->seed = TOY_AS_INTEGER(seedLiteral);
- Toy_Literal generatorLiteral = TOY_TO_OPAQUE_LITERAL(generator, TOY_OPAQUE_TAG_RANDOM);
-
- //return and cleanup
- Toy_pushLiteralArray(&interpreter->stack, generatorLiteral);
-
- Toy_freeLiteral(seedLiteral);
- Toy_freeLiteral(generatorLiteral);
-
- return 1;
-}
-
-static int nativeGenerateRandomNumber(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to generateRandomNumber\n");
- return -1;
- }
-
- //get the runner object
- Toy_Literal generatorLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal generatorLiteralIdn = generatorLiteral;
- if (TOY_IS_IDENTIFIER(generatorLiteral) && Toy_parseIdentifierToValue(interpreter, &generatorLiteral)) {
- Toy_freeLiteral(generatorLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(generatorLiteral)) {
- Toy_freeLiteral(generatorLiteral);
- return -1;
- }
-
- if (TOY_GET_OPAQUE_TAG(generatorLiteral) != TOY_OPAQUE_TAG_RANDOM) {
- interpreter->errorOutput("Unrecognized opaque literal in generateRandomNumber\n");
- return -1;
- }
-
- Toy_RandomGenerator* generator = TOY_AS_OPAQUE(generatorLiteral);
-
- //generate the new value and package up the return
- generator->seed = hashInt(generator->seed);
-
- Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(generator->seed);
-
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
-
- //cleanup
- Toy_freeLiteral(generatorLiteral);
- Toy_freeLiteral(resultLiteral);
-
- return 0;
-}
-
-static int nativeFreeRandomGenerator(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to freeRandomGenerator\n");
- return -1;
- }
-
- //get the runner object
- Toy_Literal generatorLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal generatorLiteralIdn = generatorLiteral;
- if (TOY_IS_IDENTIFIER(generatorLiteral) && Toy_parseIdentifierToValue(interpreter, &generatorLiteral)) {
- Toy_freeLiteral(generatorLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(generatorLiteral)) {
- Toy_freeLiteral(generatorLiteral);
- return -1;
- }
-
- if (TOY_GET_OPAQUE_TAG(generatorLiteral) != TOY_OPAQUE_TAG_RANDOM) {
- interpreter->errorOutput("Unrecognized opaque literal in freeRandomGenerator\n");
- return -1;
- }
-
- Toy_RandomGenerator* generator = TOY_AS_OPAQUE(generatorLiteral);
-
- //clear out the runner object
- TOY_FREE(Toy_RandomGenerator, generator);
- Toy_freeLiteral(generatorLiteral);
-
- return 0;
-}
-
-//call the hook
-typedef struct Natives {
- const char* name;
- Toy_NativeFn fn;
-} Natives;
-
-int Toy_hookRandom(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
- //build the natives list
- Natives natives[] = {
- {"createRandomGenerator", nativeCreateRandomGenerator},
- {"generateRandomNumber", nativeGenerateRandomNumber},
- {"freeRandomGenerator", nativeFreeRandomGenerator},
- {NULL, NULL}
- };
-
- //store the library in an aliased dictionary
- if (!TOY_IS_NULL(alias)) {
- //make sure the name isn't taken
- if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
- interpreter->errorOutput("Can't override an existing variable\n");
- Toy_freeLiteral(alias);
- return -1;
- }
-
- //create the dictionary to load up with functions
- Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
- Toy_initLiteralDictionary(dictionary);
-
- //load the dict with functions
- for (int i = 0; natives[i].name; i++) {
- Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
- Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
-
- Toy_setLiteralDictionary(dictionary, name, func);
-
- Toy_freeLiteral(name);
- Toy_freeLiteral(func);
- }
-
- //build the type
- Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
- Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
- Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
- TOY_TYPE_PUSH_SUBTYPE(&type, strType);
- TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
-
- //set scope
- Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
- Toy_declareScopeVariable(interpreter->scope, alias, type);
- Toy_setScopeVariable(interpreter->scope, alias, dict, false);
-
- //cleanup
- Toy_freeLiteral(dict);
- Toy_freeLiteral(type);
- return 0;
- }
-
- //default
- for (int i = 0; natives[i].name; i++) {
- Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
- }
-
- return 0;
-}
diff --git a/box/lib_random.h b/box/lib_random.h
deleted file mode 100644
index 2dfae4d..0000000
--- a/box/lib_random.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-#include "toy_interpreter.h"
-
-int Toy_hookRandom(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
-
-#define TOY_OPAQUE_TAG_RANDOM 200
diff --git a/box/lib_runner.c b/box/lib_runner.c
deleted file mode 100644
index 27f05e7..0000000
--- a/box/lib_runner.c
+++ /dev/null
@@ -1,553 +0,0 @@
-#include "lib_runner.h"
-
-#include "toy_memory.h"
-#include "toy_drive_system.h"
-#include "toy_interpreter.h"
-
-#include "repl_tools.h"
-
-#include
-
-typedef struct Toy_Runner {
- Toy_Interpreter interpreter;
- const unsigned char* bytecode;
- size_t size;
-
- bool dirty;
-} Toy_Runner;
-
-//Toy native functions
-static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to loadScript\n");
- return -1;
- }
-
- //get the file path literal with a handle
- Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal drivePathLiteralIdn = drivePathLiteral;
- if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
- Toy_freeLiteral(drivePathLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(drivePathLiteral)) {
- Toy_freeLiteral(drivePathLiteral);
- return -1;
- }
-
- Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
-
- if (TOY_IS_NULL(filePathLiteral)) {
- Toy_freeLiteral(filePathLiteral);
- Toy_freeLiteral(drivePathLiteral);
- return -1;
- }
-
- Toy_freeLiteral(drivePathLiteral);
-
- //use raw types - easier
- const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
- size_t filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
-
- //load and compile the bytecode
- size_t fileSize = 0;
- const char* source = (const char*)Toy_readFile(filePath, &fileSize);
-
- if (!source) {
- interpreter->errorOutput("Failed to load source file\n");
- Toy_freeLiteral(filePathLiteral);
- return -1;
- }
-
- const unsigned char* bytecode = Toy_compileString(source, &fileSize);
- free((void*)source);
-
- if (!bytecode) {
- interpreter->errorOutput("Failed to compile source file\n");
- Toy_freeLiteral(filePathLiteral);
- return -1;
- }
-
- //build the runner object
- Toy_Runner* runner = TOY_ALLOCATE(Toy_Runner, 1);
- Toy_setInterpreterPrint(&runner->interpreter, interpreter->printOutput);
- Toy_setInterpreterAssert(&runner->interpreter, interpreter->assertOutput);
- Toy_setInterpreterError(&runner->interpreter, interpreter->errorOutput);
- runner->interpreter.hooks = interpreter->hooks;
- runner->interpreter.scope = NULL;
- Toy_resetInterpreter(&runner->interpreter);
- runner->bytecode = bytecode;
- runner->size = fileSize;
- runner->dirty = false;
-
- //build the opaque object, and push it to the stack
- Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER);
- Toy_pushLiteralArray(&interpreter->stack, runnerLiteral);
-
- //free the drive path
- Toy_freeLiteral(filePathLiteral);
-
- return 1;
-}
-
-static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to loadScriptBytecode\n");
- return -1;
- }
-
- //get the argument
- Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal drivePathLiteralIdn = drivePathLiteral;
- if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
- Toy_freeLiteral(drivePathLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(drivePathLiteral)) {
- Toy_freeLiteral(drivePathLiteral);
- return -1;
- }
-
- Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
-
- if (TOY_IS_NULL(filePathLiteral)) {
- Toy_freeLiteral(filePathLiteral);
- Toy_freeLiteral(drivePathLiteral);
- return -1;
- }
-
- Toy_freeLiteral(drivePathLiteral);
-
- //use raw types - easier
- const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
- size_t filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
-
- //load the bytecode
- size_t fileSize = 0;
- unsigned char* bytecode = (unsigned char*)Toy_readFile(filePath, &fileSize);
-
- if (!bytecode) {
- interpreter->errorOutput("Failed to load bytecode file\n");
- return -1;
- }
-
- //build the runner object
- Toy_Runner* runner = TOY_ALLOCATE(Toy_Runner, 1);
- Toy_setInterpreterPrint(&runner->interpreter, interpreter->printOutput);
- Toy_setInterpreterAssert(&runner->interpreter, interpreter->assertOutput);
- Toy_setInterpreterError(&runner->interpreter, interpreter->errorOutput);
- runner->interpreter.hooks = interpreter->hooks;
- runner->interpreter.scope = NULL;
- Toy_resetInterpreter(&runner->interpreter);
- runner->bytecode = bytecode;
- runner->size = fileSize;
- runner->dirty = false;
-
- //build the opaque object, and push it to the stack
- Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER);
- Toy_pushLiteralArray(&interpreter->stack, runnerLiteral);
-
- //free the drive path
- Toy_freeLiteral(filePathLiteral);
-
- return 1;
-}
-
-static int nativeRunScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to runScript\n");
- return -1;
- }
-
- //get the runner object
- Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal runnerIdn = runnerLiteral;
- if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
- Toy_freeLiteral(runnerIdn);
- }
-
- if (TOY_IS_IDENTIFIER(runnerLiteral)) {
- Toy_freeLiteral(runnerLiteral);
- return -1;
- }
-
- if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
- interpreter->errorOutput("Unrecognized opaque literal in runScript\n");
- return -1;
- }
-
- Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
-
- //run
- if (runner->dirty) {
- interpreter->errorOutput("Can't re-run a dirty script (try resetting it first)\n");
- Toy_freeLiteral(runnerLiteral);
- return -1;
- }
-
- unsigned char* bytecodeCopy = TOY_ALLOCATE(unsigned char, runner->size);
- memcpy(bytecodeCopy, runner->bytecode, runner->size); //need a COPY of the bytecode, because the interpreter eats it
-
- Toy_runInterpreter(&runner->interpreter, bytecodeCopy, runner->size);
- runner->dirty = true;
-
- //cleanup
- Toy_freeLiteral(runnerLiteral);
-
- return 0;
-}
-
-static int nativeGetScriptVar(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to getScriptVar\n");
- return -1;
- }
-
- //get the runner object
- Toy_Literal varName = Toy_popLiteralArray(arguments);
- Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal varNameIdn = varName;
- if (TOY_IS_IDENTIFIER(varName) && Toy_parseIdentifierToValue(interpreter, &varName)) {
- Toy_freeLiteral(varNameIdn);
- }
-
- Toy_Literal runnerIdn = runnerLiteral;
- if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
- Toy_freeLiteral(runnerIdn);
- }
-
- if (TOY_IS_IDENTIFIER(varName) || TOY_IS_IDENTIFIER(runnerLiteral)) {
- Toy_freeLiteral(varName);
- Toy_freeLiteral(runnerLiteral);
- return -1;
- }
-
- if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
- interpreter->errorOutput("Unrecognized opaque literal in getScriptVar\n");
- return -1;
- }
-
- Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
-
- //dirty check
- if (!runner->dirty) {
- interpreter->errorOutput("Can't access variable from a non-dirty script (try running it first)\n");
- Toy_freeLiteral(runnerLiteral);
- return -1;
- }
-
- //get the desired variable
- Toy_Literal varIdn = TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_STRING(varName)));
- Toy_Literal result = TOY_TO_NULL_LITERAL;
- Toy_getScopeVariable(runner->interpreter.scope, varIdn, &result);
-
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- //cleanup
- Toy_freeLiteral(result);
- Toy_freeLiteral(varIdn);
- Toy_freeLiteral(varName);
- Toy_freeLiteral(runnerLiteral);
-
- return 1;
-}
-
-static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count < 2) {
- interpreter->errorOutput("Incorrect number of arguments to callScriptFn\n");
- return -1;
- }
-
- //get the rest args
- Toy_LiteralArray tmp;
- Toy_initLiteralArray(&tmp);
-
- while (arguments->count > 2) {
- Toy_Literal lit = Toy_popLiteralArray(arguments);
- Toy_pushLiteralArray(&tmp, lit);
- Toy_freeLiteral(lit);
- }
-
- Toy_LiteralArray rest;
- Toy_initLiteralArray(&rest);
-
- while (tmp.count > 0) { //correct the order of the rest args
- Toy_Literal lit = Toy_popLiteralArray(&tmp);
- Toy_pushLiteralArray(&rest, lit);
- Toy_freeLiteral(lit);
- }
-
- Toy_freeLiteralArray(&tmp);
-
- //get the runner object
- Toy_Literal varName = Toy_popLiteralArray(arguments);
- Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal varNameIdn = varName;
- if (TOY_IS_IDENTIFIER(varName) && Toy_parseIdentifierToValue(interpreter, &varName)) {
- Toy_freeLiteral(varNameIdn);
- }
-
- Toy_Literal runnerIdn = runnerLiteral;
- if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
- Toy_freeLiteral(runnerIdn);
- }
-
- if (TOY_IS_IDENTIFIER(varName) || TOY_IS_IDENTIFIER(runnerLiteral)) {
- Toy_freeLiteral(varName);
- Toy_freeLiteral(runnerLiteral);
- return -1;
- }
-
- if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
- interpreter->errorOutput("Unrecognized opaque literal in callScriptFn\n");
- return -1;
- }
-
- Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
-
- //dirty check
- if (!runner->dirty) {
- interpreter->errorOutput("Can't access fn from a non-dirty script (try running it first)\n");
- Toy_freeLiteral(runnerLiteral);
- Toy_freeLiteralArray(&rest);
- return -1;
- }
-
- //get the desired variable
- Toy_Literal varIdn = TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_STRING(varName)));
- Toy_Literal fn = TOY_TO_NULL_LITERAL;
- Toy_getScopeVariable(runner->interpreter.scope, varIdn, &fn);
-
- if (!TOY_IS_FUNCTION(fn)) {
- interpreter->errorOutput("Can't run a non-function literal\n");
- Toy_freeLiteral(fn);
- Toy_freeLiteral(varIdn);
- Toy_freeLiteral(varName);
- Toy_freeLiteral(runnerLiteral);
- Toy_freeLiteralArray(&rest);
- }
-
- //call
- Toy_LiteralArray resultArray;
- Toy_initLiteralArray(&resultArray);
-
- Toy_callLiteralFn(interpreter, fn, &rest, &resultArray);
-
- Toy_Literal result = TOY_TO_NULL_LITERAL;
- if (resultArray.count > 0) {
- result = Toy_popLiteralArray(&resultArray);
- }
-
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- //cleanup
- Toy_freeLiteralArray(&resultArray);
- Toy_freeLiteral(result);
- Toy_freeLiteral(fn);
- Toy_freeLiteral(varIdn);
- Toy_freeLiteral(varName);
- Toy_freeLiteral(runnerLiteral);
- Toy_freeLiteralArray(&rest);
-
- return 1;
-}
-
-static int nativeResetScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to resetScript\n");
- return -1;
- }
-
- //get the runner object
- Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal runnerIdn = runnerLiteral;
- if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
- Toy_freeLiteral(runnerIdn);
- }
-
- if (TOY_IS_IDENTIFIER(runnerLiteral)) {
- Toy_freeLiteral(runnerLiteral);
- return -1;
- }
-
- if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
- interpreter->errorOutput("Unrecognized opaque literal in resetScript\n");
- return -1;
- }
-
- Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
-
- //reset
- if (!runner->dirty) {
- interpreter->errorOutput("Can't reset a non-dirty script (try running it first)\n");
- Toy_freeLiteral(runnerLiteral);
- return -1;
- }
-
- Toy_resetInterpreter(&runner->interpreter);
- runner->dirty = false;
- Toy_freeLiteral(runnerLiteral);
-
- return 0;
-}
-
-static int nativeFreeScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to freeScript\n");
- return -1;
- }
-
- //get the runner object
- Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal runnerIdn = runnerLiteral;
- if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
- Toy_freeLiteral(runnerIdn);
- }
-
- if (TOY_IS_IDENTIFIER(runnerLiteral)) {
- Toy_freeLiteral(runnerLiteral);
- return -1;
- }
-
- if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
- interpreter->errorOutput("Unrecognized opaque literal in freeScript\n");
- return -1;
- }
-
- Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
-
- //clear out the runner object
- runner->interpreter.hooks = NULL;
- Toy_freeInterpreter(&runner->interpreter);
- TOY_FREE_ARRAY(unsigned char, runner->bytecode, runner->size);
-
- TOY_FREE(Toy_Runner, runner);
-
- Toy_freeLiteral(runnerLiteral);
-
- return 0;
-}
-
-static int nativeCheckScriptDirty(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to checkScriptDirty\n");
- return -1;
- }
-
- //get the runner object
- Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal runnerIdn = runnerLiteral;
- if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
- Toy_freeLiteral(runnerIdn);
- }
-
- if (TOY_IS_IDENTIFIER(runnerLiteral)) {
- Toy_freeLiteral(runnerLiteral);
- return -1;
- }
-
- if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
- interpreter->errorOutput("Unrecognized opaque literal in checkScriptDirty\n");
- return -1;
- }
-
- Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
-
- //run
- Toy_Literal result = TOY_TO_BOOLEAN_LITERAL(runner->dirty);
-
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- //cleanup
- Toy_freeLiteral(result);
- Toy_freeLiteral(runnerLiteral);
-
- return 0;
-}
-
-//call the hook
-typedef struct Natives {
- const char* name;
- Toy_NativeFn fn;
-} Natives;
-
-int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
- //build the natives list
- Natives natives[] = {
- {"loadScript", nativeLoadScript},
- {"loadScriptBytecode", nativeLoadScriptBytecode},
- {"runScript", nativeRunScript},
- {"getScriptVar", nativeGetScriptVar},
- {"callScriptFn", nativeCallScriptFn},
- {"resetScript", nativeResetScript},
- {"freeScript", nativeFreeScript},
- {"checkScriptDirty", nativeCheckScriptDirty},
- {NULL, NULL}
- };
-
- //store the library in an aliased dictionary
- if (!TOY_IS_NULL(alias)) {
- //make sure the name isn't taken
- if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
- interpreter->errorOutput("Can't override an existing variable\n");
- Toy_freeLiteral(alias);
- return -1;
- }
-
- //create the dictionary to load up with functions
- Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
- Toy_initLiteralDictionary(dictionary);
-
- //load the dict with functions
- for (int i = 0; natives[i].name; i++) {
- Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
- Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
-
- Toy_setLiteralDictionary(dictionary, name, func);
-
- Toy_freeLiteral(name);
- Toy_freeLiteral(func);
- }
-
- //build the type
- Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
- Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
- Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
- TOY_TYPE_PUSH_SUBTYPE(&type, strType);
- TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
-
- //set scope
- Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
- Toy_declareScopeVariable(interpreter->scope, alias, type);
- Toy_setScopeVariable(interpreter->scope, alias, dict, false);
-
- //cleanup
- Toy_freeLiteral(dict);
- Toy_freeLiteral(type);
- return 0;
- }
-
- //default
- for (int i = 0; natives[i].name; i++) {
- Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
- }
-
- return 0;
-}
-
diff --git a/box/lib_runner.h b/box/lib_runner.h
deleted file mode 100644
index 549c2ac..0000000
--- a/box/lib_runner.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-#include "toy_interpreter.h"
-
-int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
-
-#define TOY_OPAQUE_TAG_RUNNER 100
-
diff --git a/box/lib_standard.c b/box/lib_standard.c
deleted file mode 100644
index 2a348b1..0000000
--- a/box/lib_standard.c
+++ /dev/null
@@ -1,2117 +0,0 @@
-#include "lib_standard.h"
-
-#include "toy_memory.h"
-
-#include
-#include
-#include
-#include
-
-static int nativeClock(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 0) {
- interpreter->errorOutput("Incorrect number of arguments to clock\n");
- return -1;
- }
-
- //get the time from C (what a pain)
- time_t rawtime = time(NULL);
- struct tm* timeinfo = localtime( &rawtime );
- char* timestr = asctime(timeinfo);
-
- //push to the stack
- size_t len = strlen(timestr) - 1; //-1 for the newline
- Toy_Literal timeLiteral = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(timestr, len));
-
- //push to the stack
- Toy_pushLiteralArray(&interpreter->stack, timeLiteral);
-
- //cleanup
- Toy_freeLiteral(timeLiteral);
-
- return 1;
-}
-
-static int nativeHash(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to hash\n");
- return -1;
- }
-
- //get the self
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- Toy_Literal result = TOY_TO_INTEGER_LITERAL(Toy_hashLiteral(selfLiteral));
-
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- Toy_freeLiteral(result);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeAbs(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to abs\n");
- return -1;
- }
-
- //get the self
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- if (!(TOY_IS_INTEGER(selfLiteral) || TOY_IS_FLOAT(selfLiteral))) {
- interpreter->errorOutput("Incorrect argument type passed to abs\n");
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- Toy_Literal result;
-
- if (TOY_IS_INTEGER(selfLiteral)) {
- result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(selfLiteral) > 0 ? TOY_AS_INTEGER(selfLiteral) : -TOY_AS_INTEGER(selfLiteral) );
- }
- if (TOY_IS_FLOAT(selfLiteral)) {
- result = TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(selfLiteral) > 0 ? TOY_AS_FLOAT(selfLiteral) : -TOY_AS_FLOAT(selfLiteral) );
- }
-
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- Toy_freeLiteral(result);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeCeil(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to ceil\n");
- return -1;
- }
-
- //get the self
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- if (!(TOY_IS_INTEGER(selfLiteral) || TOY_IS_FLOAT(selfLiteral))) {
- interpreter->errorOutput("Incorrect argument type passed to ceil\n");
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- Toy_Literal result;
-
- if (TOY_IS_INTEGER(selfLiteral)) {
- //NO-OP
- result = Toy_copyLiteral(selfLiteral);
- }
- if (TOY_IS_FLOAT(selfLiteral)) {
- result = TOY_TO_INTEGER_LITERAL( (int)TOY_AS_FLOAT(selfLiteral) - TOY_AS_FLOAT(selfLiteral) == 0 ? (int)TOY_AS_FLOAT(selfLiteral) : (int)TOY_AS_FLOAT(selfLiteral) + 1 );
- }
-
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- Toy_freeLiteral(result);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeFloor(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to floor\n");
- return -1;
- }
-
- //get the self
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- if (!(TOY_IS_INTEGER(selfLiteral) || TOY_IS_FLOAT(selfLiteral))) {
- interpreter->errorOutput("Incorrect argument type passed to floor\n");
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- Toy_Literal result;
-
- if (TOY_IS_INTEGER(selfLiteral)) {
- //NO-OP
- result = Toy_copyLiteral(selfLiteral);
- }
- if (TOY_IS_FLOAT(selfLiteral)) {
- result = TOY_TO_INTEGER_LITERAL( (int)TOY_AS_FLOAT(selfLiteral) );
- }
-
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- Toy_freeLiteral(result);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeMax(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //return value
- Toy_Literal resultLiteral = TOY_TO_NULL_LITERAL;
-
- //iterate over all arguments
- do {
- //get the self
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- if (!(TOY_IS_INTEGER(selfLiteral) || TOY_IS_FLOAT(selfLiteral))) {
- interpreter->errorOutput("Incorrect argument type passed to max\n");
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //if not comparing yet...
- if (TOY_IS_NULL(resultLiteral)) {
- resultLiteral = selfLiteral;
- continue;
- }
-
- //cooerce if needed
- if (TOY_IS_INTEGER(resultLiteral) && TOY_IS_FLOAT(selfLiteral)) {
- resultLiteral = TOY_TO_FLOAT_LITERAL( TOY_AS_INTEGER(resultLiteral) );
- }
-
- if (TOY_IS_FLOAT(resultLiteral) && TOY_IS_INTEGER(selfLiteral)) {
- selfLiteral = TOY_TO_FLOAT_LITERAL( TOY_AS_INTEGER(selfLiteral) );
- }
-
- //compare
- if (TOY_IS_INTEGER(resultLiteral) && TOY_AS_INTEGER(resultLiteral) < TOY_AS_INTEGER(selfLiteral)) {
- //NOTE: just ints, don't free
- resultLiteral = selfLiteral;
- }
-
- else if (TOY_IS_FLOAT(resultLiteral) && TOY_AS_FLOAT(resultLiteral) < TOY_AS_FLOAT(selfLiteral)) {
- //NOTE: just floats, don't free
- resultLiteral = selfLiteral;
- }
- }
- while (arguments->count > 0);
-
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
-
- Toy_freeLiteral(resultLiteral);
-
- return 1;
-}
-
-static int nativeMin(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //return value
- Toy_Literal resultLiteral = TOY_TO_NULL_LITERAL;
-
- //iterate over all arguments
- do {
- //get the self
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- if (!(TOY_IS_INTEGER(selfLiteral) || TOY_IS_FLOAT(selfLiteral))) {
- interpreter->errorOutput("Incorrect argument type passed to min\n");
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //if not comparing yet...
- if (TOY_IS_NULL(resultLiteral)) {
- resultLiteral = selfLiteral;
- continue;
- }
-
- //cooerce if needed
- if (TOY_IS_INTEGER(resultLiteral) && TOY_IS_FLOAT(selfLiteral)) {
- resultLiteral = TOY_TO_FLOAT_LITERAL( TOY_AS_INTEGER(resultLiteral) );
- }
-
- if (TOY_IS_FLOAT(resultLiteral) && TOY_IS_INTEGER(selfLiteral)) {
- selfLiteral = TOY_TO_FLOAT_LITERAL( TOY_AS_INTEGER(selfLiteral) );
- }
-
- //compare
- if (TOY_IS_INTEGER(resultLiteral) && TOY_AS_INTEGER(resultLiteral) > TOY_AS_INTEGER(selfLiteral)) {
- //NOTE: just ints, don't free
- resultLiteral = selfLiteral;
- }
-
- else if (TOY_IS_FLOAT(resultLiteral) && TOY_AS_FLOAT(resultLiteral) > TOY_AS_FLOAT(selfLiteral)) {
- //NOTE: just floats, don't free
- resultLiteral = selfLiteral;
- }
- }
- while (arguments->count > 0);
-
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
-
- Toy_freeLiteral(resultLiteral);
-
- return 1;
-}
-
-static int nativeRound(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to round\n");
- return -1;
- }
-
- //get the self
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- if (!(TOY_IS_INTEGER(selfLiteral) || TOY_IS_FLOAT(selfLiteral))) {
- interpreter->errorOutput("Incorrect argument type passed to round\n");
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- Toy_Literal result;
-
- if (TOY_IS_INTEGER(selfLiteral)) {
- //NO-OP
- result = Toy_copyLiteral(selfLiteral);
- }
- if (TOY_IS_FLOAT(selfLiteral)) {
- //catch the already-rounded case
- if (TOY_AS_FLOAT(selfLiteral) == (int)TOY_AS_FLOAT(selfLiteral)) {
- result = TOY_TO_INTEGER_LITERAL((int)TOY_AS_FLOAT(selfLiteral));
- }
- else {
- result = TOY_TO_INTEGER_LITERAL( TOY_AS_FLOAT(selfLiteral) - (int)TOY_AS_FLOAT(selfLiteral) < 0.5 ? (int)TOY_AS_FLOAT(selfLiteral) : (int)TOY_AS_FLOAT(selfLiteral) + 1 );
- }
- }
-
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- Toy_freeLiteral(result);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeConcat(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to concat\n");
- return -1;
- }
-
- //get the args
- Toy_Literal otherLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal otherLiteralIdn = otherLiteral;
- if (TOY_IS_IDENTIFIER(otherLiteral) && Toy_parseIdentifierToValue(interpreter, &otherLiteral)) {
- Toy_freeLiteral(otherLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(otherLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(otherLiteral);
- return -1;
- }
-
- //for each self type
- if (TOY_IS_ARRAY(selfLiteral)) {
- if (!TOY_IS_ARRAY(otherLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to concat (unknown type for other)\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(otherLiteral);
- return -1;
- }
-
- //append each element of other to self, one-by-one
- for (int i = 0; i < TOY_AS_ARRAY(otherLiteral)->count; i++) {
- Toy_pushLiteralArray(TOY_AS_ARRAY(selfLiteral), TOY_AS_ARRAY(otherLiteral)->literals[i]);
- }
-
- //return and clean up
- Toy_pushLiteralArray(&interpreter->stack, selfLiteral);
-
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(otherLiteral);
-
- return 1;
- }
-
- if (TOY_IS_DICTIONARY(selfLiteral)) {
- if (!TOY_IS_DICTIONARY(otherLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to concat (unknown type for other)\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(otherLiteral);
- return -1;
- }
-
- //append each element of self to other, which will overwrite existing entries
- for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
- if (!TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key)) {
- Toy_setLiteralDictionary(TOY_AS_DICTIONARY(otherLiteral), TOY_AS_DICTIONARY(selfLiteral)->entries[i].key, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
- }
- }
-
- //return and clean up
- Toy_pushLiteralArray(&interpreter->stack, otherLiteral);
-
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(otherLiteral);
-
- return 1;
- }
-
- if (TOY_IS_STRING(selfLiteral)) { //a little redundant
- if (!TOY_IS_STRING(otherLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to concat (unknown type for other)\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(otherLiteral);
- return -1;
- }
-
- //get the combined length for the new string
- size_t length = TOY_AS_STRING(selfLiteral)->length + TOY_AS_STRING(otherLiteral)->length + 1;
-
- if (length > TOY_MAX_STRING_LENGTH) {
- interpreter->errorOutput("Can't concatenate these strings, result is too long (error found in concat)\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(otherLiteral);
- return -1;
- }
-
- //allocate the space and generate
- char* buffer = TOY_ALLOCATE(char, length);
- snprintf(buffer, length, "%s%s", Toy_toCString(TOY_AS_STRING(selfLiteral)), Toy_toCString(TOY_AS_STRING(otherLiteral)));
-
- Toy_Literal result = TOY_TO_STRING_LITERAL(Toy_createRefString(buffer));
-
- //push and clean up
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- TOY_FREE_ARRAY(char, buffer, length);
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(otherLiteral);
- Toy_freeLiteral(result);
-
- return 1;
- }
-
- interpreter->errorOutput("Incorrect argument type passed to concat (unknown type for self)\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(otherLiteral);
- return -1;
-}
-
-static int nativeContainsKey(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to containsKey\n");
- return -1;
- }
-
- //get the args
- Toy_Literal keyLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal keyLiteralIdn = keyLiteral;
- if (TOY_IS_IDENTIFIER(keyLiteral) && Toy_parseIdentifierToValue(interpreter, &keyLiteral)) {
- Toy_freeLiteral(keyLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(keyLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(keyLiteral);
- return -1;
- }
-
- //check type
- if (!(/* TOY_IS_ARRAY(selfLiteral) || */ TOY_IS_DICTIONARY(selfLiteral) )) {
- interpreter->errorOutput("Incorrect argument type passed to containsKey\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(keyLiteral);
- return -1;
- }
-
- Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(false);
- if (TOY_IS_DICTIONARY(selfLiteral) && Toy_existsLiteralDictionary( TOY_AS_DICTIONARY(selfLiteral), keyLiteral )) {
- //return true of it contains the key
- Toy_freeLiteral(resultLiteral);
- resultLiteral = TOY_TO_BOOLEAN_LITERAL(true);
- }
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
- Toy_freeLiteral(resultLiteral);
-
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(keyLiteral);
-
- return 1;
-}
-
-static int nativeContainsValue(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to containsValue\n");
- return -1;
- }
-
- //get the args
- Toy_Literal valueLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal valueLiteralIdn = valueLiteral;
- if (TOY_IS_IDENTIFIER(valueLiteral) && Toy_parseIdentifierToValue(interpreter, &valueLiteral)) {
- Toy_freeLiteral(valueLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(valueLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(valueLiteral);
- return -1;
- }
-
- //check type
- if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) )) {
- interpreter->errorOutput("Incorrect argument type passed to containsValue\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(valueLiteral);
- return -1;
- }
-
- Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(false);
- if (TOY_IS_DICTIONARY(selfLiteral)) {
- for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
- if (!TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key) && Toy_literalsAreEqual( TOY_AS_DICTIONARY(selfLiteral)->entries[i].value, valueLiteral )) {
- //return true of it contains the value
- Toy_freeLiteral(resultLiteral);
- resultLiteral = TOY_TO_BOOLEAN_LITERAL(true);
- break;
- }
- }
- }
- else if (TOY_IS_ARRAY(selfLiteral)) {
- for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
- Toy_Literal indexLiteral = TOY_TO_INTEGER_LITERAL(i);
- Toy_Literal elementLiteral = Toy_getLiteralArray(TOY_AS_ARRAY(selfLiteral), indexLiteral);
-
-
- if (Toy_literalsAreEqual(elementLiteral, valueLiteral)) {
- Toy_freeLiteral(indexLiteral);
- Toy_freeLiteral(elementLiteral);
-
- //return true of it contains the value
- Toy_freeLiteral(resultLiteral);
- resultLiteral = TOY_TO_BOOLEAN_LITERAL(true);
- break;
- }
-
- Toy_freeLiteral(indexLiteral);
- Toy_freeLiteral(elementLiteral);
- }
- }
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
- Toy_freeLiteral(resultLiteral);
-
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(valueLiteral);
-
- return 1;
-}
-
-static int nativeEvery(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to every\n");
- return -1;
- }
-
- //get the args
- Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal fnLiteralIdn = fnLiteral;
- if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
- Toy_freeLiteral(fnLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //check type
- if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
- interpreter->errorOutput("Incorrect argument type passed to every\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //call the given function on each element, based on the compound type
- if (TOY_IS_ARRAY(selfLiteral)) {
- bool result = true;
-
- //
- for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
- Toy_Literal indexLiteral = TOY_TO_INTEGER_LITERAL(i);
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, indexLiteral);
- Toy_pushLiteralArray(&arguments, TOY_AS_ARRAY(selfLiteral)->literals[i]);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- //grab the results
- Toy_Literal lit = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
- Toy_freeLiteral(indexLiteral);
-
- //if not truthy
- if (!TOY_IS_TRUTHY(lit)) {
- Toy_freeLiteral(lit);
- result = false;
- break;
- }
-
- Toy_freeLiteral(lit);
- }
-
- Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result);
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
- Toy_freeLiteral(resultLiteral);
- }
-
- if (TOY_IS_DICTIONARY(selfLiteral)) {
- bool result = true;
-
- for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
- //skip nulls
- if (TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key)) {
- continue;
- }
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].key);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- //grab the results
- Toy_Literal lit = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
-
- //if not truthy
- if (!TOY_IS_TRUTHY(lit)) {
- Toy_freeLiteral(lit);
- result = false;
- break;
- }
-
- Toy_freeLiteral(lit);
- }
-
- Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result);
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
- Toy_freeLiteral(resultLiteral);
- }
-
- Toy_freeLiteral(fnLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeFilter(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to filter\n");
- return -1;
- }
-
- //get the args
- Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal fnLiteralIdn = fnLiteral;
- if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
- Toy_freeLiteral(fnLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //check type
- if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
- interpreter->errorOutput("Incorrect argument type passed to filter\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //call the given function on each element, based on the compound type
- if (TOY_IS_ARRAY(selfLiteral)) {
- Toy_LiteralArray* result = TOY_ALLOCATE(Toy_LiteralArray, 1);
- Toy_initLiteralArray(result);
-
- //
- for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
- Toy_Literal indexLiteral = TOY_TO_INTEGER_LITERAL(i);
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, indexLiteral);
- Toy_pushLiteralArray(&arguments, TOY_AS_ARRAY(selfLiteral)->literals[i]);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- //grab the results
- Toy_Literal lit = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
- Toy_freeLiteral(indexLiteral);
-
- //if truthy
- if (TOY_IS_TRUTHY(lit)) {
- Toy_pushLiteralArray(result, TOY_AS_ARRAY(selfLiteral)->literals[i]);
- }
-
- Toy_freeLiteral(lit);
- }
-
- Toy_Literal resultLiteral = TOY_TO_ARRAY_LITERAL(result);
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
- Toy_freeLiteral(resultLiteral);
- }
-
- if (TOY_IS_DICTIONARY(selfLiteral)) {
- Toy_LiteralDictionary* result = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
- Toy_initLiteralDictionary(result);
-
- for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
- //skip nulls
- if (TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key)) {
- continue;
- }
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].key);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- //grab the results
- Toy_Literal lit = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
-
- //if truthy
- if (TOY_IS_TRUTHY(lit)) {
- Toy_setLiteralDictionary(result, TOY_AS_DICTIONARY(selfLiteral)->entries[i].key, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
- }
-
- Toy_freeLiteral(lit);
- }
-
- Toy_Literal resultLiteral = TOY_TO_DICTIONARY_LITERAL(result);
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
- Toy_freeLiteral(resultLiteral);
- }
-
- Toy_freeLiteral(fnLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeForEach(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to forEach\n");
- return -1;
- }
-
- //get the args
- Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal fnLiteralIdn = fnLiteral;
- if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
- Toy_freeLiteral(fnLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //check type
- if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
- interpreter->errorOutput("Incorrect argument type passed to forEach\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //call the given function on each element, based on the compound type
- if (TOY_IS_ARRAY(selfLiteral)) {
- for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
- Toy_Literal indexLiteral = TOY_TO_INTEGER_LITERAL(i);
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, indexLiteral);
- Toy_pushLiteralArray(&arguments, TOY_AS_ARRAY(selfLiteral)->literals[i]);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
- Toy_freeLiteral(indexLiteral);
- }
- }
-
- if (TOY_IS_DICTIONARY(selfLiteral)) {
- for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
- //skip nulls
- if (TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key)) {
- continue;
- }
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].key);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
- }
- }
-
- Toy_freeLiteral(fnLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 0;
-}
-
-static int nativeGetKeys(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to getKeys\n");
- return -1;
- }
-
- //get the self
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //check type
- if (!TOY_IS_DICTIONARY(selfLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to getKeys\n");
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //generate the result literal
- Toy_LiteralArray* resultPtr = TOY_ALLOCATE(Toy_LiteralArray, 1);
- Toy_initLiteralArray(resultPtr);
-
- //get each key from the dictionary, pass it to the array
- for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
- if (!TOY_IS_NULL( TOY_AS_DICTIONARY(selfLiteral)->entries[i].key )) {
- Toy_pushLiteralArray(resultPtr, TOY_AS_DICTIONARY(selfLiteral)->entries[i].key);
- }
- }
-
- //return the result
- Toy_Literal result = TOY_TO_ARRAY_LITERAL(resultPtr); //no copy
- Toy_pushLiteralArray(&interpreter->stack, result); //internal copy
-
- //clean up
- Toy_freeLiteralArray(resultPtr);
- TOY_FREE(Toy_LiteralArray, resultPtr);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeGetValues(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to getValues\n");
- return -1;
- }
-
- //get the self
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //check type
- if (!TOY_IS_DICTIONARY(selfLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to getValues\n");
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //generate the result literal
- Toy_LiteralArray* resultPtr = TOY_ALLOCATE(Toy_LiteralArray, 1);
- Toy_initLiteralArray(resultPtr);
-
- //get each key from the dictionary, pass it to the array
- for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
- if (!TOY_IS_NULL( TOY_AS_DICTIONARY(selfLiteral)->entries[i].key )) {
- Toy_pushLiteralArray(resultPtr, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
- }
- }
-
- //return the result
- Toy_Literal result = TOY_TO_ARRAY_LITERAL(resultPtr); //no copy
- Toy_pushLiteralArray(&interpreter->stack, result); //internal copy
-
- //clean up
- Toy_freeLiteralArray(resultPtr);
- TOY_FREE(Toy_LiteralArray, resultPtr);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeIndexOf(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to indexOf\n");
- return -1;
- }
-
- //get the args
- Toy_Literal valueLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal valueLiteralIdn = valueLiteral;
- if (TOY_IS_IDENTIFIER(valueLiteral) && Toy_parseIdentifierToValue(interpreter, &valueLiteral)) {
- Toy_freeLiteral(valueLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(valueLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(valueLiteral);
- return -1;
- }
-
- //check type
- if (!TOY_IS_ARRAY(selfLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to indexOf\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(valueLiteral);
- return -1;
- }
-
- //search the array for the matching literal
- Toy_Literal resultLiteral = TOY_TO_NULL_LITERAL;
- for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
- if (Toy_literalsAreEqual(valueLiteral, TOY_AS_ARRAY(selfLiteral)->literals[i])) {
- resultLiteral = TOY_TO_INTEGER_LITERAL(i);
- break;
- }
- }
-
- //return the result and clean up
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
- Toy_freeLiteral(resultLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeMap(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to map\n");
- return -1;
- }
-
- //get the args
- Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal fnLiteralIdn = fnLiteral;
- if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
- Toy_freeLiteral(fnLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //check type
- if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
- interpreter->errorOutput("Incorrect argument type passed to map\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //call the given function on each element, based on the compound type
- if (TOY_IS_ARRAY(selfLiteral)) {
- Toy_LiteralArray* returnsPtr = TOY_ALLOCATE(Toy_LiteralArray, 1);
- Toy_initLiteralArray(returnsPtr);
-
- for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
- Toy_Literal indexLiteral = TOY_TO_INTEGER_LITERAL(i);
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, indexLiteral);
- Toy_pushLiteralArray(&arguments, TOY_AS_ARRAY(selfLiteral)->literals[i]);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- //grab the results
- Toy_Literal lit = Toy_popLiteralArray(&returns);
- Toy_pushLiteralArray(returnsPtr, lit);
- Toy_freeLiteral(lit);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
- Toy_freeLiteral(indexLiteral);
- }
-
- Toy_Literal returnsLiteral = TOY_TO_ARRAY_LITERAL(returnsPtr);
- Toy_pushLiteralArray(&interpreter->stack, returnsLiteral);
- Toy_freeLiteral(returnsLiteral);
- }
-
- if (TOY_IS_DICTIONARY(selfLiteral)) {
- Toy_LiteralArray* returnsPtr = TOY_ALLOCATE(Toy_LiteralArray, 1);
- Toy_initLiteralArray(returnsPtr);
-
- for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
- //skip nulls
- if (TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key)) {
- continue;
- }
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].key);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- //grab the results
- Toy_Literal lit = Toy_popLiteralArray(&returns);
- Toy_pushLiteralArray(returnsPtr, lit);
- Toy_freeLiteral(lit);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
- }
-
- Toy_Literal returnsLiteral = TOY_TO_ARRAY_LITERAL(returnsPtr);
- Toy_pushLiteralArray(&interpreter->stack, returnsLiteral);
- Toy_freeLiteral(returnsLiteral);
- }
-
- Toy_freeLiteral(fnLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 0;
-}
-
-static int nativeReduce(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 3) {
- interpreter->errorOutput("Incorrect number of arguments to reduce\n");
- return -1;
- }
-
- //get the args
- Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal defaultLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal defaultLiteralIdn = defaultLiteral;
- if (TOY_IS_IDENTIFIER(defaultLiteral) && Toy_parseIdentifierToValue(interpreter, &defaultLiteral)) {
- Toy_freeLiteral(defaultLiteralIdn);
- }
-
- Toy_Literal fnLiteralIdn = fnLiteral;
- if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
- Toy_freeLiteral(fnLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(defaultLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(defaultLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //check type
- if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
- interpreter->errorOutput("Incorrect argument type passed to reduce\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(defaultLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //call the given function on each element, based on the compound type
- if (TOY_IS_ARRAY(selfLiteral)) {
- for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
- Toy_Literal indexLiteral = TOY_TO_INTEGER_LITERAL(i);
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, defaultLiteral);
- Toy_pushLiteralArray(&arguments, indexLiteral);
- Toy_pushLiteralArray(&arguments, TOY_AS_ARRAY(selfLiteral)->literals[i]);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- //grab the results
- Toy_freeLiteral(defaultLiteral);
- defaultLiteral = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
- Toy_freeLiteral(indexLiteral);
- }
-
- Toy_pushLiteralArray(&interpreter->stack, defaultLiteral);
- }
-
- if (TOY_IS_DICTIONARY(selfLiteral)) {
- for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
- //skip nulls
- if (TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key)) {
- continue;
- }
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, defaultLiteral);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].key);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- //grab the results
- Toy_freeLiteral(defaultLiteral);
- defaultLiteral = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
- }
-
- Toy_pushLiteralArray(&interpreter->stack, defaultLiteral);
- }
-
- Toy_freeLiteral(fnLiteral);
- Toy_freeLiteral(defaultLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 0;
-}
-
-static int nativeSome(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to some\n");
- return -1;
- }
-
- //get the args
- Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal fnLiteralIdn = fnLiteral;
- if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
- Toy_freeLiteral(fnLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //check type
- if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
- interpreter->errorOutput("Incorrect argument type passed to some\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //call the given function on each element, based on the compound type
- if (TOY_IS_ARRAY(selfLiteral)) {
- bool result = false;
-
- //
- for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
- Toy_Literal indexLiteral = TOY_TO_INTEGER_LITERAL(i);
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, indexLiteral);
- Toy_pushLiteralArray(&arguments, TOY_AS_ARRAY(selfLiteral)->literals[i]);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- //grab the results
- Toy_Literal lit = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
- Toy_freeLiteral(indexLiteral);
-
- //if not truthy
- if (TOY_IS_TRUTHY(lit)) {
- Toy_freeLiteral(lit);
- result = true;
- break;
- }
-
- Toy_freeLiteral(lit);
- }
-
- Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result);
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
- Toy_freeLiteral(resultLiteral);
- }
-
- if (TOY_IS_DICTIONARY(selfLiteral)) {
- bool result = false;
-
- for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
- //skip nulls
- if (TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key)) {
- continue;
- }
-
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].key);
- Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
-
- Toy_LiteralArray returns;
- Toy_initLiteralArray(&returns);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- //grab the results
- Toy_Literal lit = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
-
- //if not truthy
- if (TOY_IS_TRUTHY(lit)) {
- Toy_freeLiteral(lit);
- result = true;
- break;
- }
-
- Toy_freeLiteral(lit);
- }
-
- Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result);
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
- Toy_freeLiteral(resultLiteral);
- }
-
- Toy_freeLiteral(fnLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static void swapLiteralsUtil(Toy_Literal* lhs, Toy_Literal* rhs) {
- Toy_Literal tmp = *lhs;
- *lhs = *rhs;
- *rhs = tmp;
-}
-
-//https://www.youtube.com/watch?v=MZaf_9IZCrc
-static void recursiveLiteralQuicksortUtil(Toy_Interpreter* interpreter, Toy_Literal* ptr, int literalCount, Toy_Literal fnCompareLiteral) {
- //base case
- if (literalCount <= 1) {
- return;
- }
-
- int runner = 0;
-
- //iterate through the array
- for (int checker = 0; checker < literalCount - 1; checker++) {
- Toy_LiteralArray arguments;
- Toy_LiteralArray returns;
-
- Toy_initLiteralArray(&arguments);
- Toy_initLiteralArray(&returns);
-
- Toy_pushLiteralArray(&arguments, ptr[checker]);
- Toy_pushLiteralArray(&arguments, ptr[literalCount - 1]);
-
- Toy_callLiteralFn(interpreter, fnCompareLiteral, &arguments, &returns);
-
- Toy_Literal lessThan = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
-
- if (TOY_IS_TRUTHY(lessThan)) {
- swapLiteralsUtil(&ptr[runner++], &ptr[checker]);
- }
-
- Toy_freeLiteral(lessThan);
- }
-
- //"shift everything up" so the pivot is in the middle
- swapLiteralsUtil(&ptr[runner], &ptr[literalCount - 1]);
-
- //recurse on each end
- if (runner > 0) {
- recursiveLiteralQuicksortUtil(interpreter, &ptr[0], runner, fnCompareLiteral);
- }
-
- if (runner < literalCount) {
- recursiveLiteralQuicksortUtil(interpreter, &ptr[runner + 1], literalCount - runner - 1, fnCompareLiteral);
- }
-}
-
-static int nativeSort(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 2) {
- interpreter->errorOutput("Incorrect number of arguments to sort\n");
- return -1;
- }
-
- //get the args
- Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to value if needed
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- Toy_Literal fnLiteralIdn = fnLiteral;
- if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
- Toy_freeLiteral(fnLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //check type
- if (!TOY_IS_ARRAY(selfLiteral) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
- interpreter->errorOutput("Incorrect argument type passed to sort\n");
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(fnLiteral);
- return -1;
- }
-
- //BUGFIX: check if the array is already sorted
- bool sorted = true;
- for (int checker = 0; checker < TOY_AS_ARRAY(selfLiteral)->count - 1 && sorted; checker++) {
- Toy_LiteralArray arguments;
- Toy_LiteralArray returns;
-
- Toy_initLiteralArray(&arguments);
- Toy_initLiteralArray(&returns);
-
- Toy_pushLiteralArray(&arguments, TOY_AS_ARRAY(selfLiteral)->literals[checker]);
- Toy_pushLiteralArray(&arguments, TOY_AS_ARRAY(selfLiteral)->literals[checker + 1]);
-
- Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
-
- Toy_Literal lessThan = Toy_popLiteralArray(&returns);
-
- Toy_freeLiteralArray(&arguments);
- Toy_freeLiteralArray(&returns);
-
- if (!TOY_IS_TRUTHY(lessThan)) {
- sorted = false;
- }
-
- Toy_freeLiteral(lessThan);
- }
-
- //call the quicksort util
- if (!sorted) {
- recursiveLiteralQuicksortUtil(interpreter, TOY_AS_ARRAY(selfLiteral)->literals, TOY_AS_ARRAY(selfLiteral)->count, fnLiteral);
- }
-
- Toy_pushLiteralArray(&interpreter->stack, selfLiteral);
-
- Toy_freeLiteral(fnLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeToLower(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to toLower\n");
- return -1;
- }
-
- //get the argument to a C-string
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- if (!TOY_IS_STRING(selfLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to toLower\n");
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- Toy_RefString* selfRefString = TOY_AS_STRING(selfLiteral);
- const char* self = Toy_toCString(selfRefString);
-
- //allocate buffer space for the result
- char* result = TOY_ALLOCATE(char, Toy_lengthRefString(selfRefString) + 1);
-
- //set each new character
- for (int i = 0; i < (int)Toy_lengthRefString(selfRefString); i++) {
- result[i] = tolower(self[i]);
- }
- result[Toy_lengthRefString(selfRefString)] = '\0'; //end the string
-
- //wrap up and push the new result onto the stack
- Toy_RefString* resultRefString = Toy_createRefStringLength(result, Toy_lengthRefString(selfRefString)); //internal copy
- Toy_Literal resultLiteral = TOY_TO_STRING_LITERAL(resultRefString); //NO copy
-
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral); //internal copy
-
- //cleanup
- TOY_FREE_ARRAY(char, result, Toy_lengthRefString(resultRefString) + 1);
- Toy_freeLiteral(resultLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static char* toStringUtilObject = NULL;
-static void toStringUtil(const char* input) {
- size_t len = strlen(input) + 1;
-
- if (len > TOY_MAX_STRING_LENGTH) {
- len = TOY_MAX_STRING_LENGTH; //TODO: don't truncate
- }
-
- toStringUtilObject = TOY_ALLOCATE(char, len);
-
- snprintf(toStringUtilObject, len, "%s", input);
-}
-
-static int nativeToString(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to toString\n");
- return -1;
- }
-
- //get the argument
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- //parse to a value
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //BUGFIX: probably an undefined variable
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //print it to a custom function
- Toy_printLiteralCustom(selfLiteral, toStringUtil);
-
- //create the resulting string and push it
- Toy_Literal result = TOY_TO_STRING_LITERAL(Toy_createRefString(toStringUtilObject)); //internal copy
-
- Toy_pushLiteralArray(&interpreter->stack, result);
-
- //cleanup
- TOY_FREE_ARRAY(char, toStringUtilObject, Toy_lengthRefString( TOY_AS_STRING(result) ) + 1);
- toStringUtilObject = NULL;
-
- Toy_freeLiteral(result);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeToUpper(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- //no arguments
- if (arguments->count != 1) {
- interpreter->errorOutput("Incorrect number of arguments to toUpper\n");
- return -1;
- }
-
- //get the argument to a C-string
- Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral)) {
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- if (!TOY_IS_STRING(selfLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to toUpper\n");
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- Toy_RefString* selfRefString = TOY_AS_STRING(selfLiteral);
- const char* self = Toy_toCString(selfRefString);
-
- //allocate buffer space for the result
- char* result = TOY_ALLOCATE(char, Toy_lengthRefString(selfRefString) + 1);
-
- //set each new character
- for (int i = 0; i < (int)Toy_lengthRefString(selfRefString); i++) {
- result[i] = toupper(self[i]);
- }
- result[Toy_lengthRefString(selfRefString)] = '\0'; //end the string
-
- //wrap up and push the new result onto the stack
- Toy_RefString* resultRefString = Toy_createRefStringLength(result, Toy_lengthRefString(selfRefString)); //internal copy
- Toy_Literal resultLiteral = TOY_TO_STRING_LITERAL(resultRefString); //NO copy
-
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral); //internal copy
-
- //cleanup
- TOY_FREE_ARRAY(char, result, Toy_lengthRefString(resultRefString) + 1);
- Toy_freeLiteral(resultLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeTrim(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count < 1 || arguments->count > 2) {
- interpreter->errorOutput("Incorrect number of arguments to trim\n");
- return -1;
- }
-
- //get the arguments
- Toy_Literal trimCharsLiteral;
- Toy_Literal selfLiteral;
-
- if (arguments->count == 2) {
- trimCharsLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal trimCharsLiteralIdn = trimCharsLiteral;
- if (TOY_IS_IDENTIFIER(trimCharsLiteral) && Toy_parseIdentifierToValue(interpreter, &trimCharsLiteral)) {
- Toy_freeLiteral(trimCharsLiteralIdn);
- }
- }
- else {
- trimCharsLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(" \t\n\r"));
- }
- selfLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(trimCharsLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(trimCharsLiteral);
- return -1;
- }
-
- if (!TOY_IS_STRING(selfLiteral) || !TOY_IS_STRING(trimCharsLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to trim\n");
- Toy_freeLiteral(trimCharsLiteral);
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //unwrap the arguments
- Toy_RefString* trimCharsRefString = TOY_AS_STRING(trimCharsLiteral);
- Toy_RefString* selfRefString = TOY_AS_STRING(selfLiteral);
-
- //allocate space for the new string
- size_t bufferBegin = 0;
- size_t bufferEnd = Toy_lengthRefString(selfRefString);
-
- //for each character in self, check it against each character in trimChars - on a fail, go to end
- for (int i = 0; i < (int)Toy_lengthRefString(selfRefString); i++) {
- int trimIndex = 0;
-
- while (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) {
- //there is a match - DON'T increment anymore
- if (Toy_toCString(selfRefString)[i] == Toy_toCString(trimCharsRefString)[trimIndex]) {
- break;
- }
-
- trimIndex++;
- }
-
- //if the match is found, increment buffer begin
- if (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) {
- bufferBegin++;
- continue;
- }
- else {
- break;
- }
- }
-
- //again, from the back
- for (int i = (int)Toy_lengthRefString(selfRefString); i >= 0; i--) {
- int trimIndex = 0;
-
- while (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) {
- //there is a match - DON'T increment anymore
- if (Toy_toCString(selfRefString)[i-1] == Toy_toCString(trimCharsRefString)[trimIndex]) {
- break;
- }
-
- trimIndex++;
- }
-
- //if the match is found, increment buffer begin
- if (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) {
- bufferEnd--;
- continue;
- }
- else {
- break;
- }
- }
-
- //generate the result
- Toy_Literal resultLiteral;
- if (bufferBegin >= bufferEnd) { //catch errors
- resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(""));
- }
- else {
- char buffer[TOY_MAX_STRING_LENGTH];
- snprintf(buffer, bufferEnd - bufferBegin + 1, "%s", &Toy_toCString(selfRefString)[ bufferBegin ]);
- resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(buffer)); //internal copy
- }
-
- //wrap up the buffer and return it
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral); //internal copy
-
- //cleanup
- Toy_freeLiteral(resultLiteral);
- Toy_freeLiteral(trimCharsLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeTrimBegin(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count < 1 || arguments->count > 2) {
- interpreter->errorOutput("Incorrect number of arguments to trimBegin\n");
- return -1;
- }
-
- //get the arguments
- Toy_Literal trimCharsLiteral;
- Toy_Literal selfLiteral;
-
- if (arguments->count == 2) {
- trimCharsLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal trimCharsLiteralIdn = trimCharsLiteral;
- if (TOY_IS_IDENTIFIER(trimCharsLiteral) && Toy_parseIdentifierToValue(interpreter, &trimCharsLiteral)) {
- Toy_freeLiteral(trimCharsLiteralIdn);
- }
- }
- else {
- trimCharsLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(" \t\n\r"));
- }
- selfLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(trimCharsLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(trimCharsLiteral);
- return -1;
- }
-
- if (!TOY_IS_STRING(selfLiteral) || !TOY_IS_STRING(trimCharsLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to trimBegin\n");
- Toy_freeLiteral(trimCharsLiteral);
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //unwrap the arguments
- Toy_RefString* trimCharsRefString = TOY_AS_STRING(trimCharsLiteral);
- Toy_RefString* selfRefString = TOY_AS_STRING(selfLiteral);
-
- //allocate space for the new string
- size_t bufferBegin = 0;
- size_t bufferEnd = Toy_lengthRefString(selfRefString);
-
- //for each character in self, check it against each character in trimChars - on a fail, go to end
- for (int i = 0; i < (int)Toy_lengthRefString(selfRefString); i++) {
- int trimIndex = 0;
-
- while (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) {
- //there is a match - DON'T increment anymore
- if (Toy_toCString(selfRefString)[i] == Toy_toCString(trimCharsRefString)[trimIndex]) {
- break;
- }
-
- trimIndex++;
- }
-
- //if the match is found, increment buffer begin
- if (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) {
- bufferBegin++;
- continue;
- }
- else {
- break;
- }
- }
-
- //generate the result
- Toy_Literal resultLiteral;
- if (bufferBegin >= bufferEnd) { //catch errors
- resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(""));
- }
- else {
- char buffer[TOY_MAX_STRING_LENGTH];
- snprintf(buffer, bufferEnd - bufferBegin + 1, "%s", &Toy_toCString(selfRefString)[ bufferBegin ]);
- resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(buffer)); //internal copy
- }
-
- //wrap up the buffer and return it
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral); //internal copy
-
- //cleanup
- Toy_freeLiteral(resultLiteral);
- Toy_freeLiteral(trimCharsLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-static int nativeTrimEnd(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
- if (arguments->count < 1 || arguments->count > 2) {
- interpreter->errorOutput("Incorrect number of arguments to trimEnd\n");
- return -1;
- }
-
- //get the arguments
- Toy_Literal trimCharsLiteral;
- Toy_Literal selfLiteral;
-
- if (arguments->count == 2) {
- trimCharsLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal trimCharsLiteralIdn = trimCharsLiteral;
- if (TOY_IS_IDENTIFIER(trimCharsLiteral) && Toy_parseIdentifierToValue(interpreter, &trimCharsLiteral)) {
- Toy_freeLiteral(trimCharsLiteralIdn);
- }
- }
- else {
- trimCharsLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(" \t\n\r"));
- }
- selfLiteral = Toy_popLiteralArray(arguments);
-
- Toy_Literal selfLiteralIdn = selfLiteral;
- if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
- Toy_freeLiteral(selfLiteralIdn);
- }
-
- if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(trimCharsLiteral)) {
- Toy_freeLiteral(selfLiteral);
- Toy_freeLiteral(trimCharsLiteral);
- return -1;
- }
-
- if (!TOY_IS_STRING(selfLiteral) || !TOY_IS_STRING(trimCharsLiteral)) {
- interpreter->errorOutput("Incorrect argument type passed to trimEnd\n");
- Toy_freeLiteral(trimCharsLiteral);
- Toy_freeLiteral(selfLiteral);
- return -1;
- }
-
- //unwrap the arguments
- Toy_RefString* trimCharsRefString = TOY_AS_STRING(trimCharsLiteral);
- Toy_RefString* selfRefString = TOY_AS_STRING(selfLiteral);
-
- //allocate space for the new string
- size_t bufferBegin = 0;
- size_t bufferEnd = Toy_lengthRefString(selfRefString);
-
- //again, from the back
- for (int i = (int)Toy_lengthRefString(selfRefString); i >= 0; i--) {
- int trimIndex = 0;
-
- while (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) {
- //there is a match - DON'T increment anymore
- if (Toy_toCString(selfRefString)[i-1] == Toy_toCString(trimCharsRefString)[trimIndex]) {
- break;
- }
-
- trimIndex++;
- }
-
- //if the match is found, increment buffer begin
- if (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) {
- bufferEnd--;
- continue;
- }
- else {
- break;
- }
- }
-
- //generate the result
- Toy_Literal resultLiteral;
- if (bufferBegin >= bufferEnd) { //catch errors
- resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(""));
- }
- else {
- char buffer[TOY_MAX_STRING_LENGTH];
- snprintf(buffer, bufferEnd - bufferBegin + 1, "%s", &Toy_toCString(selfRefString)[ bufferBegin ]);
- resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(buffer)); //internal copy
- }
-
- //wrap up the buffer and return it
- Toy_pushLiteralArray(&interpreter->stack, resultLiteral); //internal copy
-
- //cleanup
- Toy_freeLiteral(resultLiteral);
- Toy_freeLiteral(trimCharsLiteral);
- Toy_freeLiteral(selfLiteral);
-
- return 1;
-}
-
-//call the hook
-typedef struct Natives {
- char* name;
- Toy_NativeFn fn;
-} Natives;
-
-int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
- //build the natives list
- Natives natives[] = {
- //misc. utils
- {"clock", nativeClock},
- {"hash", nativeHash},
-
- //math utils
- {"abs", nativeAbs},
- {"ceil", nativeCeil},
- {"floor", nativeFloor},
- {"max", nativeMax},
- {"min", nativeMin},
- {"round", nativeRound},
-
- //compound utils
- {"concat", nativeConcat}, //array, dictionary, string
- {"containsKey", nativeContainsKey}, //dictionary
- {"containsValue", nativeContainsValue}, //array, dictionary
- {"every", nativeEvery}, //array, dictionary
- {"filter", nativeFilter}, //array, dictionary
- {"forEach", nativeForEach}, //array, dictionary
- {"getKeys", nativeGetKeys}, //dictionary
- {"getValues", nativeGetValues}, //dictionary
- {"indexOf", nativeIndexOf}, //array
- {"map", nativeMap}, //array, dictionary
- {"reduce", nativeReduce}, //array, dictionary
- {"some", nativeSome}, //array, dictionary
- {"sort", nativeSort}, //array
- {"toLower", nativeToLower}, //string
- {"toString", nativeToString}, //array, dictionary
- {"toUpper", nativeToUpper}, //string
- {"trim", nativeTrim}, //string
- {"trimBegin", nativeTrimBegin}, //string
- {"trimEnd", nativeTrimEnd}, //string
- {NULL, NULL}
- };
-
- //store the library in an aliased dictionary
- if (!TOY_IS_NULL(alias)) {
- //make sure the name isn't taken
- if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
- interpreter->errorOutput("Can't override an existing variable\n");
- Toy_freeLiteral(alias);
- return -1;
- }
-
- //create the dictionary to load up with functions
- Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
- Toy_initLiteralDictionary(dictionary);
-
- //load the dict with functions
- for (int i = 0; natives[i].name; i++) {
- Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
- Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
-
- Toy_setLiteralDictionary(dictionary, name, func);
-
- Toy_freeLiteral(name);
- Toy_freeLiteral(func);
- }
-
- //build the type
- Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
- Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
- Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
- TOY_TYPE_PUSH_SUBTYPE(&type, strType);
- TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
-
- //set scope
- Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
- Toy_declareScopeVariable(interpreter->scope, alias, type);
- Toy_setScopeVariable(interpreter->scope, alias, dict, false);
-
- //cleanup
- Toy_freeLiteral(dict);
- Toy_freeLiteral(type);
- return 0;
- }
-
- //default
- for (int i = 0; natives[i].name; i++) {
- Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
- }
-
- return 0;
-}
diff --git a/box/lib_standard.h b/box/lib_standard.h
deleted file mode 100644
index d1b9816..0000000
--- a/box/lib_standard.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include "toy_interpreter.h"
-
-int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
-
diff --git a/box/makefile b/box/makefile
deleted file mode 100644
index 75dbbb9..0000000
--- a/box/makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-CC=gcc
-
-IDIR+=. ../Toy/source
-CFLAGS+=$(addprefix -I,$(IDIR)) -g -Wall -W -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable
-LIBS+=-lSDL2 -lSDL2_image -ltoy
-
-ODIR = obj
-SRC = $(wildcard *.c)
-OBJ = $(addprefix $(ODIR)/,$(SRC:.c=.o))
-
-REPLLIBS = $(wildcard ../Toy/repl/lib*) $(wildcard ../Toy/repl/repl_tools.*)
-
-OUTNAME=box
-
-ifeq ($(findstring CYGWIN, $(shell uname)),CYGWIN)
- LIBLINE =-Wl,--out-implib=$(BOX_OUTDIR)/lib$(OUTNAME).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive $(OBJ) -Wl,--no-whole-archive
- OUT=$(BOX_OUTDIR)/$(OUTNAME).dll
-else ifeq ($(shell uname),Linux)
- LIBLINE=-Wl,--out-implib=./$(BOX_OUTDIR)/lib$(OUTNAME).a -Wl,--whole-archive $(OBJ) -Wl,--no-whole-archive
- OUT=./$(BOX_OUTDIR)/lib$(OUTNAME).so
- CFLAGS += -fPIC
-else ifeq ($(OS),Windows_NT)
- LIBLINE =-Wl,--out-implib=$(BOX_OUTDIR)/lib$(OUTNAME).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive $(OBJ) -Wl,--no-whole-archive
- OUT=$(BOX_OUTDIR)/$(OUTNAME).dll
-else
- @echo "Platform test failed - what platform is this?"
- exit 1
-endif
-
-library: repllibs $(OBJ)
- $(CC) -DBOX_EXPORT $(CFLAGS) -shared -o $(OUT) $(LIBLINE) -L../$(LIBDIR) $(LIBS)
-
-static: repllibs $(OBJ)
- ar crs $(BOX_OUTDIR)/lib$(OUTNAME).a $(OBJ) -L../$(LIBDIR) $(LIBS)
-
-#copy the stuff from Toy/repl that is needed
-repllibs:
- cp $(REPLLIBS) .
-
-$(OBJ): | $(ODIR)
-
-$(ODIR):
- mkdir $(ODIR)
-
-$(ODIR)/%.o: %.c
- $(CC) -c -o $@ $< $(CFLAGS)
-
-.PHONY: clean
-
-clean-repllibs:
- $(RM) $(notdir $(REPLLIBS))
\ No newline at end of file
diff --git a/box/repl_tools.c b/box/repl_tools.c
deleted file mode 100644
index 63090f9..0000000
--- a/box/repl_tools.c
+++ /dev/null
@@ -1,207 +0,0 @@
-#include "repl_tools.h"
-#include "lib_about.h"
-#include "lib_standard.h"
-#include "lib_random.h"
-#include "lib_runner.h"
-
-#include "toy_console_colors.h"
-
-#include "toy_lexer.h"
-#include "toy_parser.h"
-#include "toy_compiler.h"
-#include "toy_interpreter.h"
-
-#include
-#include
-
-//IO functions
-const unsigned char* Toy_readFile(const char* path, size_t* fileSize) {
- FILE* file = fopen(path, "rb");
-
- if (file == NULL) {
- fprintf(stderr, TOY_CC_ERROR "Could not open file \"%s\"\n" TOY_CC_RESET, path);
- return NULL;
- }
-
- fseek(file, 0L, SEEK_END);
- *fileSize = ftell(file);
- rewind(file);
-
- unsigned char* buffer = (unsigned char*)malloc(*fileSize + 1);
-
- if (buffer == NULL) {
- fprintf(stderr, TOY_CC_ERROR "Not enough memory to read \"%s\"\n" TOY_CC_RESET, path);
- return NULL;
- }
-
- size_t bytesRead = fread(buffer, sizeof(unsigned char), *fileSize, file);
-
- buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this
-
- if (bytesRead < *fileSize) {
- fprintf(stderr, TOY_CC_ERROR "Could not read file \"%s\"\n" TOY_CC_RESET, path);
- return NULL;
- }
-
- fclose(file);
-
- return buffer;
-}
-
-int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size) {
- FILE* file = fopen(path, "wb");
-
- if (file == NULL) {
- fprintf(stderr, TOY_CC_ERROR "Could not open file \"%s\"\n" TOY_CC_RESET, path);
- return -1;
- }
-
- size_t written = fwrite(bytes, size, 1, file);
-
- if (written != 1) {
- fprintf(stderr, TOY_CC_ERROR "Could not write file \"%s\"\n" TOY_CC_RESET, path);
- return -1;
- }
-
- fclose(file);
-
- return 0;
-}
-
-//repl functions
-const unsigned char* Toy_compileString(const char* source, size_t* size) {
- Toy_Lexer lexer;
- Toy_Parser parser;
- Toy_Compiler compiler;
-
- Toy_initLexer(&lexer, source);
- Toy_initParser(&parser, &lexer);
- Toy_initCompiler(&compiler);
-
- //step 1 - run the parser until the end of the source
- Toy_ASTNode* node = Toy_scanParser(&parser);
- while(node != NULL) {
- //on error, pack up and leave
- if (node->type == TOY_AST_NODE_ERROR) {
- Toy_freeASTNode(node);
- Toy_freeCompiler(&compiler);
- Toy_freeParser(&parser);
- return NULL;
- }
-
- Toy_writeCompiler(&compiler, node);
- Toy_freeASTNode(node);
- node = Toy_scanParser(&parser);
- }
-
- //step 2 - get the bytecode dump
- const unsigned char* tb = Toy_collateCompiler(&compiler, size);
-
- //cleanup
- Toy_freeCompiler(&compiler);
- Toy_freeParser(&parser);
- //no lexer to clean up
-
- //finally
- return tb;
-}
-
-void Toy_runBinary(const unsigned char* tb, size_t size) {
- Toy_Interpreter interpreter;
- Toy_initInterpreter(&interpreter);
-
- //inject the libs
- Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
- Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
- Toy_injectNativeHook(&interpreter, "random", Toy_hookRandom);
- Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
-
- Toy_runInterpreter(&interpreter, tb, (int)size);
- Toy_freeInterpreter(&interpreter);
-}
-
-void Toy_runBinaryFile(const char* fname) {
- size_t size = 0; //not used
- const unsigned char* tb = Toy_readFile(fname, &size);
- if (!tb) {
- return;
- }
- Toy_runBinary(tb, size);
- //interpreter takes ownership of the binary data
-}
-
-void Toy_runSource(const char* source) {
- size_t size = 0;
- const unsigned char* tb = Toy_compileString(source, &size);
- if (!tb) {
- return;
- }
-
- Toy_runBinary(tb, size);
-}
-
-void Toy_runSourceFile(const char* fname) {
- size_t size = 0; //not used
- const char* source = (const char*)Toy_readFile(fname, &size);
- if (!source) {
- return;
- }
- Toy_runSource(source);
- free((void*)source);
-}
-
-//utils for debugging the header
-static unsigned char readByte(const unsigned char* tb, int* count) {
- unsigned char ret = *(unsigned char*)(tb + *count);
- *count += 1;
- return ret;
-}
-
-static const char* readString(const unsigned char* tb, int* count) {
- const unsigned char* ret = tb + *count;
- *count += strlen((char*)ret) + 1; //+1 for null character
- return (const char*)ret;
-}
-
-void Toy_parseBinaryFileHeader(const char* fname) {
- size_t size = 0; //not used
- const unsigned char* tb = Toy_readFile(fname, &size);
- if (!tb || size < 4) {
- return;
- }
-
- int count = 0;
-
- //header section
- const unsigned char major = readByte(tb, &count);
- const unsigned char minor = readByte(tb, &count);
- const unsigned char patch = readByte(tb, &count);
-
- const char* build = readString(tb, &count);
-
- printf("Toy Programming Language Interpreter Version %d.%d.%d (interpreter built on %s)\n\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH, TOY_VERSION_BUILD);
-
- printf("Toy Programming Language Bytecode Version ");
-
- //print the output
- if (major == TOY_VERSION_MAJOR && minor == TOY_VERSION_MINOR && patch == TOY_VERSION_PATCH) {
- printf("%d.%d.%d", major, minor, patch);
- }
- else {
- printf(TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK "%d.%d.%d" TOY_CC_RESET, major, minor, patch);
- }
-
- printf(" (interpreter built on ");
-
- if (strncmp(build, TOY_VERSION_BUILD, strlen(TOY_VERSION_BUILD)) == 0) {
- printf("%s", build);
- }
- else {
- printf(TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK "%s" TOY_CC_RESET, build);
- }
-
- printf(")\n");
-
- //cleanup
- free((void*)tb);
-}
\ No newline at end of file
diff --git a/box/repl_tools.h b/box/repl_tools.h
deleted file mode 100644
index 5fda23e..0000000
--- a/box/repl_tools.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "toy_common.h"
-
-const unsigned char* Toy_readFile(const char* path, size_t* fileSize);
-int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size);
-
-const unsigned char* Toy_compileString(const char* source, size_t* size);
-
-void Toy_runBinary(const unsigned char* tb, size_t size);
-void Toy_runBinaryFile(const char* fname);
-void Toy_runSource(const char* source);
-void Toy_runSourceFile(const char* fname);
-
-void Toy_parseBinaryFileHeader(const char* fname);
\ No newline at end of file
diff --git a/makefile b/makefile
index 6389a3c..0c3763d 100644
--- a/makefile
+++ b/makefile
@@ -1,34 +1,19 @@
export OUTDIR = out
-export LIBDIR = lib
-export TOY_OUTDIR = ../$(LIBDIR)
-export BOX_OUTDIR = ../$(LIBDIR)
+export BOX_OUTDIR = ../$(OUTDIR)
+export TOY_OUTDIR = ../../$(OUTDIR)
-all: $(OUTDIR) $(LIBDIR) toy box
+all: $(OUTDIR) toy box
$(MAKE) -j8 -C source
-ifeq ($(findstring CYGWIN, $(shell uname)),CYGWIN)
- cp $(LIBDIR)/*.dll $(OUTDIR)
-else ifeq ($(shell uname),Linux)
- cp $(LIBDIR)/*.so $(OUTDIR)
-else ifeq ($(OS),Windows_NT)
- cp $(LIBDIR)/*.dll $(OUTDIR)
-endif
-
-test: clean $(OUTDIR) toy box
- $(MAKE) -C test
toy: $(LIBDIR)
- $(MAKE) -j8 -C Toy/source
+ $(MAKE) -j8 -C Box/Toy/source
box: $(LIBDIR)
- $(MAKE) -j8 -C box repllibs
- $(MAKE) -j8 -C box library
+ $(MAKE) -j8 -C Box/source
$(OUTDIR):
mkdir $(OUTDIR)
-$(LIBDIR):
- mkdir $(LIBDIR)
-
.PHONY: clean
clean:
@@ -56,24 +41,3 @@ else
endif
rebuild: clean all
-
-
-#utils for the manual android build
-INCLUDEDIR=include
-
-SOURCEDIR=bundle
-
-$(INCLUDEDIR):
- mkdir $(INCLUDEDIR)
-
-$(SOURCEDIR):
- mkdir $(SOURCEDIR)
-
-sourcelist:
- @echo $(addprefix ../airport/,$(wildcard Toy/source/*.c) $(wildcard box/*.c) $(wildcard source/*.c)) > source.list
-
-bundleincludes: $(INCLUDEDIR)
- cp $(addprefix ../airport/,$(wildcard Toy/source/*.h) $(wildcard box/*.h) $(wildcard source/*.h)) $(INCLUDEDIR)
-
-bundlesource: $(SOURCEDIR)
- cp $(addprefix ../airport/,$(wildcard Toy/source/*.c) $(wildcard box/*.c) $(wildcard source/*.c)) $(SOURCEDIR)
\ No newline at end of file
diff --git a/test/makefile b/test/makefile
deleted file mode 100644
index b3866bd..0000000
--- a/test/makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-CC=gcc
-
-IDIR+=. ../Toy/source ../box
-CFLAGS+=$(addprefix -I,$(IDIR)) -DSDL_MAIN_HANDLED -g -Wall -W -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable
-LIBS+=-lSDL2 -lSDL2_image -ltoy -lbox
-
-ODIR = obj
-TARGETS = $(wildcard ../box/*.c)
-TESTS = $(wildcard *.c)
-OBJ = $(addprefix $(ODIR)/,$(TARGETS:../box/%.c=%.o)) $(addprefix $(ODIR)/,$(TESTS:.c=.o))
-
-.PRECIOUS: $(TESTS:%.c=../$(OUTDIR)/%.exe)
-
-all: $(OBJ) $(TESTS:%.c=../$(OUTDIR)/%.exe)
-
-../$(OUTDIR)/%.exe: $(ODIR)/%.o
-ifeq ($(shell uname),Linux)
- @$(CC) -o $@ $< $(TARGETS:../box/%.c=$(ODIR)/%.o) $(CFLAGS) -Wl,-rpath,../out -L../$(LIBDIR) $(LIBS)
- cp ../$(LIBDIR)/*.so ../$(OUTDIR)
- valgrind --leak-check=full --track-origins=yes $@
-else
- @$(CC) -o $@ $< $(TARGETS:../box/%.c=$(ODIR)/%.o) $(CFLAGS) -L../$(LIBDIR) $(LIBS)
- cp ../$(LIBDIR)/*.dll ../$(OUTDIR)
- $@
-endif
-
-$(OBJ): | $(ODIR)
-
-$(ODIR):
- mkdir $(ODIR)
-
-$(ODIR)/%.o: %.c
- @$(CC) -c -o $@ $< $(CFLAGS)
-
-$(ODIR)/%.o: ../box/%.c
- @$(CC) -c -o $@ $< $(CFLAGS)
-
-.PHONY: clean
-
-clean:
- $(RM) $(ODIR)
diff --git a/test/scripts/child_engine_node.toy b/test/scripts/child_engine_node.toy
deleted file mode 100644
index ee6f6f9..0000000
--- a/test/scripts/child_engine_node.toy
+++ /dev/null
@@ -1,14 +0,0 @@
-var tally: int = 0;
-
-fn onInit(node: opaque) {
- print "child init called";
-}
-
-fn onStep(node: opaque) {
- print "child step called";
- print ++tally;
-}
-
-fn onFree(node: opaque) {
- print "child free called";
-}
\ No newline at end of file
diff --git a/test/scripts/parent_engine_node.toy b/test/scripts/parent_engine_node.toy
deleted file mode 100644
index 4d85bf4..0000000
--- a/test/scripts/parent_engine_node.toy
+++ /dev/null
@@ -1,11 +0,0 @@
-fn onInit(node: opaque) {
- print "init called";
-}
-
-fn onStep(node: opaque) {
- print "step called";
-}
-
-fn onFree(node: opaque) {
- print "free called";
-}
\ No newline at end of file
diff --git a/test/test_engine_node.c b/test/test_engine_node.c
deleted file mode 100644
index d6e1d8d..0000000
--- a/test/test_engine_node.c
+++ /dev/null
@@ -1,110 +0,0 @@
-#include "box_engine_node.h"
-
-#include "toy_lexer.h"
-#include "toy_parser.h"
-#include "toy_compiler.h"
-#include "toy_interpreter.h"
-#include "toy_console_colors.h"
-#include "toy_memory.h"
-
-#include "repl_tools.h"
-
-#include
-#include
-#include
-
-//suppress the print keyword
-static void noPrintFn(const char* output) {
- //NO OP
-}
-
-int main() {
- {
- //setup interpreter
- Toy_Interpreter interpreter;
- Toy_initInterpreter(&interpreter);
- Toy_setInterpreterPrint(&interpreter, noPrintFn);
-
- size_t size = 0;
-
- const char* source = Toy_readFile("./scripts/parent_engine_node.toy", &size);
- const unsigned char* tb = Toy_compileString(source, &size);
-
- //create and test the engine node
- Box_EngineNode* node = TOY_ALLOCATE(Box_EngineNode, 1);
-
- Box_initEngineNode(node, &interpreter, tb, size);
-
- Toy_Literal nodeLiteral = TOY_TO_OPAQUE_LITERAL(node, OPAQUE_TAG_ENGINE_NODE);
-
- //argument list to pass in the node
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
-
- //call each function
- Box_callRecursiveEngineNode(node, &interpreter, "onInit", &arguments);
- Box_callRecursiveEngineNode(node, &interpreter, "onStep", &arguments);
- Box_callRecursiveEngineNode(node, &interpreter, "onQuit", &arguments);
-
- //cleanup
- Toy_freeLiteralArray(&arguments);
- Box_freeEngineNode(node);
- free((void*)source);
-
- Toy_freeInterpreter(&interpreter);
- }
-
- {
- //setup interpreter
- Toy_Interpreter interpreter;
- Toy_initInterpreter(&interpreter);
- Toy_setInterpreterPrint(&interpreter, noPrintFn);
-
- size_t size = 0;
-
- const char* source = Toy_readFile("./scripts/parent_engine_node.toy", &size);
- const unsigned char* tb = Toy_compileString(source, &size);
-
- //create and test the engine node
- Box_EngineNode* node = TOY_ALLOCATE(Box_EngineNode, 1);
-
- Box_initEngineNode(node, &interpreter, tb, size);
- Toy_resetInterpreter(&interpreter);
-
- for (int i = 0; i < 10; i++) {
- const char* source = Toy_readFile("./scripts/child_engine_node.toy", &size);
- const unsigned char* tb = Toy_compileString(source, &size);
-
- Box_EngineNode* child = TOY_ALLOCATE(Box_EngineNode, 1);
- Box_initEngineNode(child, &interpreter, tb, size);
- Toy_resetInterpreter(&interpreter);
-
- Box_pushEngineNode(node, child);
-
- free((void*)source);
- }
-
- //argument list to pass in each time
- Toy_LiteralArray arguments;
- Toy_initLiteralArray(&arguments);
-
- //test the calls
- Box_callRecursiveEngineNode(node, &interpreter, "onInit", &arguments);
-
- for (int i = 0; i < 10; i++) {
- Box_callRecursiveEngineNode(node, &interpreter, "onStep", &arguments);
- }
-
- Box_callRecursiveEngineNode(node, &interpreter, "onFree", &arguments);
-
- //cleanup
- Toy_freeLiteralArray(&arguments);
- Box_freeEngineNode(node); //frees all children
- free((void*)source);
-
- Toy_freeInterpreter(&interpreter);
- }
-
- printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
- return 0;
-}