Updated Toy, tweaked code to match new API

This commit is contained in:
2023-02-14 22:19:08 +00:00
parent 5efabde476
commit 9a1d81b7fb
14 changed files with 1610 additions and 2018 deletions

2
Toy

Submodule Toy updated: aeb008c684...501ff6fff4

View File

@@ -24,7 +24,7 @@ fn getY(node: opaque) {
//lifecycle functions
fn onInit(node: opaque) {
print "render.toy:onInit() called\n";
print "render.toy:onInit() called";
node.loadTexture("sprites:/character.png");
parent = node.getNodeParent();
@@ -36,13 +36,13 @@ fn onStep(node: opaque) {
}
fn onFree(node: opaque) {
print "render.toy:onFree() called\n";
print "render.toy:onFree() called";
node.freeTexture();
}
fn onDraw(node: opaque) {
// print "render.toy:onDraw() called\n";
// print "render.toy:onDraw() called";
var px = parent.callNode("getX");
var py = parent.callNode("getY");
@@ -104,11 +104,11 @@ fn onKeyUp(node: opaque, event: string) {
}
fn onMouseMotion(node: opaque, x: int, y: int, xrel: int, yrel: int) {
// print "entity.toy:onMouseMotion(" + string x + ", " + string y + ", " + string xrel + ", " + string yrel + ")\n";
// print "entity.toy:onMouseMotion(" + string x + ", " + string y + ", " + string xrel + ", " + string yrel + ")";
}
fn onMouseButtonDown(node: opaque, x: int, y: int, button: string) {
// print "entity.toy:onMouseButtonDown(" + string x + ", " + string y + ", " + button + ")\n";
// print "entity.toy:onMouseButtonDown(" + string x + ", " + string y + ", " + button + ")";
//jump to pos
posX = x - WIDTH / 2;
@@ -116,10 +116,10 @@ fn onMouseButtonDown(node: opaque, x: int, y: int, button: string) {
}
fn onMouseButtonUp(node: opaque, x: int, y: int, button: string) {
// print "entity.toy:onMouseButtonUp(" + string x + ", " + string y + ", " + button + ")\n";
// print "entity.toy:onMouseButtonUp(" + string x + ", " + string y + ", " + button + ")";
}
fn onMouseWheel(node: opaque, xrel: int, yrel: int) {
// print "entity.toy:onMouseWheel(" + string xrel + ", " + string yrel + ")\n";
// print "entity.toy:onMouseWheel(" + string xrel + ", " + string yrel + ")";
}

View File

@@ -3,7 +3,7 @@ import engine;
import node;
//util to generate and init a child node of a parent
fn _makeChild(parent: opaque, fname: string) {
fn makeChild(parent: opaque, fname: string) {
var child: opaque = loadNode(fname);
parent.pushNode(child);
child.initNode();
@@ -11,7 +11,7 @@ fn _makeChild(parent: opaque, fname: string) {
//NOTE: root node can load the whole scene, and essentially act as the scene object
fn onInit(node: opaque) {
print "root.toy:onInit() called\n";
print "root.toy:onInit() called";
//make a child
node.makeChild("scripts:/entity.toy");
@@ -21,9 +21,9 @@ fn onInit(node: opaque) {
}
fn onStep(node: opaque) {
//print clock() + "\n";
//print clock();
}
fn onFree(node: opaque) {
print "root.toy:onFree() called\n";
print "root.toy:onFree() called";
}

View File

@@ -4,8 +4,6 @@
#include "lib_input.h"
#include "lib_node.h"
#include "lib_standard.h"
#include "lib_compound.h"
#include "lib_timer.h"
#include "lib_runner.h"
#include "repl_tools.h"
@@ -51,13 +49,11 @@ void Box_initEngine() {
//init Toy
Toy_initInterpreter(&engine.interpreter);
Toy_injectNativeHook(&engine.interpreter, "standard", Toy_hookStandard);
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);
Toy_injectNativeHook(&engine.interpreter, "standard", Toy_hookStandard);
Toy_injectNativeHook(&engine.interpreter, "compound", Toy_hookCompound);
Toy_injectNativeHook(&engine.interpreter, "timer", Toy_hookTimer);
Toy_injectNativeHook(&engine.interpreter, "runner", Toy_hookRunner);
size_t size = 0;
const char* source = Toy_readFile("./assets/scripts/init.toy", &size);

View File

@@ -7,6 +7,7 @@
#include "toy_literal_array.h"
#include "toy_literal_dictionary.h"
//TODO: remove this, and replace with time.h
#include <sys/time.h>
//the base engine object, which represents the state of the game

View File

@@ -106,15 +106,15 @@ Toy_Literal Box_callEngineNodeLiteral(Box_EngineNode* node, Toy_Interpreter* int
Toy_initLiteralArray(&arguments);
Toy_initLiteralArray(&returns);
//feed the arguments in backwards!
//feed the arguments in
Toy_pushLiteralArray(&arguments, n);
if (args) {
for (int i = args->count -1; i >= 0; i--) {
for (int i = 0; i < args->count; i++) {
Toy_pushLiteralArray(&arguments, args->literals[i]);
}
}
Toy_pushLiteralArray(&arguments, n);
Toy_callLiteralFn(interpreter, fn, &arguments, &returns);
ret = Toy_popLiteralArray(&returns);
@@ -151,15 +151,15 @@ void Box_callRecursiveEngineNodeLiteral(Box_EngineNode* node, Toy_Interpreter* i
Toy_initLiteralArray(&arguments);
Toy_initLiteralArray(&returns);
//feed the arguments in backwards!
//feed the arguments in
Toy_pushLiteralArray(&arguments, n);
if (args) {
for (int i = args->count -1; i >= 0; i--) {
for (int i = 0; i < args->count; i++) {
Toy_pushLiteralArray(&arguments, args->literals[i]);
}
}
Toy_pushLiteralArray(&arguments, n);
Toy_callLiteralFn(interpreter, fn, &arguments, &returns);
Toy_freeLiteralArray(&arguments);

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +0,0 @@
#pragma once
#include "toy_interpreter.h"
int Toy_hookCompound(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);

View File

@@ -209,7 +209,7 @@ static int nativePushNode(Toy_Interpreter* interpreter, Toy_LiteralArray* argume
static int nativeGetNodeChild(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//checks
if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments passed to getNode\n");
interpreter->errorOutput("Incorrect number of arguments passed to getNodeChild\n");
return -1;
}
@@ -222,7 +222,7 @@ static int nativeGetNodeChild(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
}
if (!TOY_IS_OPAQUE(parent) || !TOY_IS_INTEGER(index)) {
interpreter->errorOutput("Incorrect argument type passed to getNode\n");
interpreter->errorOutput("Incorrect argument type passed to getNodeChild\n");
Toy_freeLiteral(parent);
Toy_freeLiteral(index);
return -1;
@@ -233,7 +233,7 @@ static int nativeGetNodeChild(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
int intIndex = TOY_AS_INTEGER(index);
if (intIndex < 0 || intIndex >= parentNode->count) {
interpreter->errorOutput("index out of bounds in getNode\n");
interpreter->errorOutput("index out of bounds in getNodeChild\n");
Toy_freeLiteral(parent);
Toy_freeLiteral(index);
return -1;
@@ -292,7 +292,7 @@ static int nativeGetNodeParent(Toy_Interpreter* interpreter, Toy_LiteralArray* a
static int nativeLoadTexture(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments passed to loadTextureEngineNode\n");
interpreter->errorOutput("Incorrect number of arguments passed to loadTexture\n");
return -1;
}
@@ -312,7 +312,7 @@ static int nativeLoadTexture(Toy_Interpreter* interpreter, Toy_LiteralArray* arg
//check argument types
if (!TOY_IS_STRING(drivePathLiteral) || !TOY_IS_OPAQUE(nodeLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to loadTextureEngineNode\n");
interpreter->errorOutput("Incorrect argument type passed to loadTexture\n");
Toy_freeLiteral(drivePathLiteral);
Toy_freeLiteral(nodeLiteral);
return -1;
@@ -351,7 +351,7 @@ static int nativeLoadTexture(Toy_Interpreter* interpreter, Toy_LiteralArray* arg
static int nativeFreeTexture(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments passed to freeTextureEngineNode\n");
interpreter->errorOutput("Incorrect number of arguments passed to freeTexture\n");
return -1;
}
@@ -365,7 +365,7 @@ static int nativeFreeTexture(Toy_Interpreter* interpreter, Toy_LiteralArray* arg
//check argument types
if (!TOY_IS_OPAQUE(nodeLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to freeTextureEngineNode\n");
interpreter->errorOutput("Incorrect argument type passed to freeTexture\n");
Toy_freeLiteral(nodeLiteral);
return -1;
}
@@ -385,7 +385,7 @@ static int nativeFreeTexture(Toy_Interpreter* interpreter, Toy_LiteralArray* arg
static int nativeSetRect(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
if (arguments->count != 5) {
interpreter->errorOutput("Incorrect number of arguments passed to setRectEngineNode\n");
interpreter->errorOutput("Incorrect number of arguments passed to setRect\n");
return -1;
}
@@ -423,7 +423,7 @@ static int nativeSetRect(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen
//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 setRectEngineNode\n");
interpreter->errorOutput("Incorrect argument type passed to setRect\n");
Toy_freeLiteral(nodeLiteral);
Toy_freeLiteral(x);
Toy_freeLiteral(y);
@@ -452,7 +452,7 @@ static int nativeSetRect(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen
static int nativeDrawNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
if (arguments->count != 3 && arguments->count != 5) {
interpreter->errorOutput("Incorrect number of arguments passed to drawEngineNode\n");
interpreter->errorOutput("Incorrect number of arguments passed to drawNode\n");
return -1;
}
@@ -494,7 +494,7 @@ static int nativeDrawNode(Toy_Interpreter* interpreter, Toy_LiteralArray* argume
//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 drawEngineNode\n");
interpreter->errorOutput("Incorrect argument type passed to drawNode\n");
Toy_freeLiteral(nodeLiteral);
Toy_freeLiteral(x);
Toy_freeLiteral(y);
@@ -528,51 +528,16 @@ static int nativeDrawNode(Toy_Interpreter* interpreter, Toy_LiteralArray* argume
return 0;
}
static int nativeGetNodeTag(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//checks
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments passed to getNodeTag\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 getNodeTag\n");
Toy_freeLiteral(nodeLiteral);
return -1;
}
//push the tag
Toy_Literal tagLiteral = TOY_TO_INTEGER_LITERAL( ((Box_EngineNode*)TOY_AS_OPAQUE(nodeLiteral))->tag );
Toy_pushLiteralArray(&interpreter->stack, tagLiteral);
//cleanup
Toy_freeLiteral(nodeLiteral);
Toy_freeLiteral(tagLiteral);
return 1;
}
static int nativeCallNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//checks
if (arguments->count < 2) {
interpreter->errorOutput("Too few arguments passed to callEngineNode\n");
interpreter->errorOutput("Too few arguments passed to callNode\n");
return -1;
}
Toy_LiteralArray extraArgs;
Toy_initLiteralArray(&extraArgs);
Toy_LiteralArray flippedExtraArgs;
Toy_initLiteralArray(&flippedExtraArgs);
//extract the extra arg values
while (arguments->count > 2) {
Toy_Literal tmp = Toy_popLiteralArray(arguments);
@@ -582,19 +547,10 @@ static int nativeCallNode(Toy_Interpreter* interpreter, Toy_LiteralArray* argume
Toy_freeLiteral(idn);
}
Toy_pushLiteralArray(&flippedExtraArgs, tmp);
Toy_freeLiteral(tmp);
}
//correct the order
while (flippedExtraArgs.count) {
Toy_Literal tmp = Toy_popLiteralArray(&flippedExtraArgs);
Toy_pushLiteralArray(&extraArgs, tmp);
Toy_freeLiteral(tmp);
}
Toy_freeLiteralArray(&flippedExtraArgs);
//back on track
Toy_Literal fnName = Toy_popLiteralArray(arguments);
Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
@@ -610,7 +566,7 @@ static int nativeCallNode(Toy_Interpreter* interpreter, Toy_LiteralArray* argume
}
if (!TOY_IS_OPAQUE(nodeLiteral) || !TOY_IS_STRING(fnName)) {
interpreter->errorOutput("Incorrect argument type passed to callEngineNode\n");
interpreter->errorOutput("Incorrect argument type passed to callNode\n");
Toy_freeLiteral(nodeLiteral);
Toy_freeLiteral(fnName);
return -1;
@@ -644,17 +600,16 @@ int Box_hookNode(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Liter
//build the natives list
Natives natives[] = {
{"loadNode", nativeLoadNode},
{"_initNode", nativeInitNode},
{"_freeChildNode", nativeFreeChildNode},
{"_pushNode", nativePushNode},
{"_getNodeChild", nativeGetNodeChild},
{"_getNodeParent", nativeGetNodeParent},
{"_loadTexture", nativeLoadTexture},
{"_freeTexture", nativeFreeTexture},
{"_setRect", nativeSetRect},
{"_drawNode", nativeDrawNode},
{"_callNode", nativeCallNode},
// {"getNodeTag", nativeGetNodeTag}, //not needed if there's only one node type
{"initNode", nativeInitNode},
{"freeChildNode", nativeFreeChildNode},
{"pushNode", nativePushNode},
{"getNodeChild", nativeGetNodeChild},
{"getNodeParent", nativeGetNodeParent},
{"loadTexture", nativeLoadTexture},
{"freeTexture", nativeFreeTexture},
{"setRect", nativeSetRect},
{"drawNode", nativeDrawNode},
{"callNode", nativeCallNode},
{NULL, NULL},
};

View File

@@ -44,7 +44,7 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
//use raw types - easier
const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
int filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
size_t filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
//load and compile the bytecode
size_t fileSize = 0;
@@ -138,7 +138,7 @@ static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArr
//get the final real file path (concat) TODO: move this concat to refstring library
Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral));
int realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
size_t realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null
snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path));
@@ -159,7 +159,7 @@ static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArr
}
//check for break-out attempts
for (int i = 0; i < realLength - 1; i++) {
for (size_t i = 0; i < realLength - 1; i++) {
if (filePath[i] == '.' && filePath[i + 1] == '.') {
interpreter->errorOutput("Parent directory access not allowed\n");
TOY_FREE_ARRAY(char, filePath, realLength);
@@ -200,7 +200,7 @@ static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArr
static int nativeRunScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _runScript\n");
interpreter->errorOutput("Incorrect number of arguments to runScript\n");
return -1;
}
@@ -213,7 +213,7 @@ static int nativeRunScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argum
}
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in _runScript\n");
interpreter->errorOutput("Unrecognized opaque literal in runScript\n");
return -1;
}
@@ -241,7 +241,7 @@ static int nativeRunScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argum
static int nativeGetScriptVar(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments to _getScriptVar\n");
interpreter->errorOutput("Incorrect number of arguments to getScriptVar\n");
return -1;
}
@@ -260,7 +260,7 @@ static int nativeGetScriptVar(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
}
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in _runScript\n");
interpreter->errorOutput("Unrecognized opaque literal in getScriptVar\n");
return -1;
}
@@ -292,7 +292,7 @@ static int nativeGetScriptVar(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count < 2) {
interpreter->errorOutput("Incorrect number of arguments to _callScriptFn\n");
interpreter->errorOutput("Incorrect number of arguments to callScriptFn\n");
return -1;
}
@@ -309,7 +309,7 @@ static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
Toy_LiteralArray rest;
Toy_initLiteralArray(&rest);
while (tmp.count) { //correct the order of the rest args
while (tmp.count > 0) { //correct the order of the rest args
Toy_Literal lit = Toy_popLiteralArray(&tmp);
Toy_pushLiteralArray(&rest, lit);
Toy_freeLiteral(lit);
@@ -317,7 +317,6 @@ static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
Toy_freeLiteralArray(&tmp);
//get the runner object
Toy_Literal varName = Toy_popLiteralArray(arguments);
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
@@ -333,7 +332,7 @@ static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
}
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in _runScript\n");
interpreter->errorOutput("Unrecognized opaque literal in callScriptFn\n");
return -1;
}
@@ -389,7 +388,7 @@ static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
static int nativeResetScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _resetScript\n");
interpreter->errorOutput("Incorrect number of arguments to resetScript\n");
return -1;
}
@@ -402,7 +401,7 @@ static int nativeResetScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arg
}
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in _runScript\n");
interpreter->errorOutput("Unrecognized opaque literal in resetScript\n");
return -1;
}
@@ -425,7 +424,7 @@ static int nativeResetScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arg
static int nativeFreeScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _freeScript\n");
interpreter->errorOutput("Incorrect number of arguments to freeScript\n");
return -1;
}
@@ -438,7 +437,7 @@ static int nativeFreeScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
}
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in _freeScript\n");
interpreter->errorOutput("Unrecognized opaque literal in freeScript\n");
return -1;
}
@@ -459,7 +458,7 @@ static int nativeFreeScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
static int nativeCheckScriptDirty(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _runScript\n");
interpreter->errorOutput("Incorrect number of arguments to checkScriptDirty\n");
return -1;
}
@@ -472,7 +471,7 @@ static int nativeCheckScriptDirty(Toy_Interpreter* interpreter, Toy_LiteralArray
}
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in _runScript\n");
interpreter->errorOutput("Unrecognized opaque literal in checkScriptDirty\n");
return -1;
}
@@ -501,12 +500,12 @@ int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Lit
Natives natives[] = {
{"loadScript", nativeLoadScript},
{"loadScriptBytecode", nativeLoadScriptBytecode},
{"_runScript", nativeRunScript},
{"_getScriptVar", nativeGetScriptVar},
{"_callScriptFn", nativeCallScriptFn},
{"_resetScript", nativeResetScript},
{"_freeScript", nativeFreeScript},
{"_checkScriptDirty", nativeCheckScriptDirty},
{"runScript", nativeRunScript},
{"getScriptVar", nativeGetScriptVar},
{"callScriptFn", nativeCallScriptFn},
{"resetScript", nativeResetScript},
{"freeScript", nativeFreeScript},
{"checkScriptDirty", nativeCheckScriptDirty},
{NULL, NULL}
};
@@ -617,7 +616,7 @@ Toy_Literal Toy_getFilePathLiteral(Toy_Interpreter* interpreter, Toy_Literal* dr
//get the final real file path (concat) TODO: move this concat to refstring library
Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral));
int realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
size_t realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null
snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path));
@@ -630,7 +629,7 @@ Toy_Literal Toy_getFilePathLiteral(Toy_Interpreter* interpreter, Toy_Literal* dr
Toy_deleteRefString(drivePath);
//check for break-out attempts
for (int i = 0; i < realLength - 1; i++) {
for (size_t i = 0; i < realLength - 1; i++) {
if (filePath[i] == '.' && filePath[i + 1] == '.') {
interpreter->errorOutput("Parent directory access not allowed\n");
TOY_FREE_ARRAY(char, filePath, realLength + 1);

File diff suppressed because it is too large Load Diff

View File

@@ -1,411 +0,0 @@
#include "lib_timer.h"
#include "toy_memory.h"
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
//GOD DAMN IT: https://stackoverflow.com/questions/15846762/timeval-subtract-explanation
static int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) {
//normallize
if (x->tv_usec > 999999) {
x->tv_sec += x->tv_usec / 1000000;
x->tv_usec %= 1000000;
}
if (y->tv_usec > 999999) {
y->tv_sec += y->tv_usec / 1000000;
y->tv_usec %= 1000000;
}
//calc
result->tv_sec = x->tv_sec - y->tv_sec;
if ((result->tv_usec = x->tv_usec - y->tv_usec) < 0) {
if (result->tv_sec != 0) { //only works far from 0
result->tv_usec += 1000000;
result->tv_sec--; // borrow
}
}
return result->tv_sec < 0 || (result->tv_sec == 0 && result->tv_usec < 0);
}
//god damn it
static struct timeval* diff(struct timeval* lhs, struct timeval* rhs) {
struct timeval* d = TOY_ALLOCATE(struct timeval, 1);
//I gave up, copied from SO
timeval_subtract(d, rhs, lhs);
return d;
}
//callbacks
static int nativeStartTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 0) {
interpreter->errorOutput("Incorrect number of arguments to startTimer\n");
return -1;
}
//get the timeinfo from C
struct timeval* timeinfo = TOY_ALLOCATE(struct timeval, 1);
gettimeofday(timeinfo, NULL);
//wrap in an opaque literal for Toy
Toy_Literal timeLiteral = TOY_TO_OPAQUE_LITERAL(timeinfo, -1);
Toy_pushLiteralArray(&interpreter->stack, timeLiteral);
Toy_freeLiteral(timeLiteral);
return 1;
}
static int nativeStopTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _stopTimer\n");
return -1;
}
//get the timeinfo from C
struct timeval timerStop;
gettimeofday(&timerStop, NULL);
//unwrap the opaque literal
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
Toy_Literal timeLiteralIdn = timeLiteral;
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
Toy_freeLiteral(timeLiteralIdn);
}
if (!TOY_IS_OPAQUE(timeLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to _stopTimer\n");
Toy_freeLiteral(timeLiteral);
return -1;
}
struct timeval* timerStart = TOY_AS_OPAQUE(timeLiteral);
//determine the difference, and wrap it
struct timeval* d = diff(timerStart, &timerStop);
Toy_Literal diffLiteral = TOY_TO_OPAQUE_LITERAL(d, -1);
Toy_pushLiteralArray(&interpreter->stack, diffLiteral);
//cleanup
Toy_freeLiteral(timeLiteral);
Toy_freeLiteral(diffLiteral);
return 1;
}
static int nativeCreateTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments to createTimer\n");
return -1;
}
//get the args
Toy_Literal microsecondLiteral = Toy_popLiteralArray(arguments);
Toy_Literal secondLiteral = Toy_popLiteralArray(arguments);
Toy_Literal secondLiteralIdn = secondLiteral;
if (TOY_IS_IDENTIFIER(secondLiteral) && Toy_parseIdentifierToValue(interpreter, &secondLiteral)) {
Toy_freeLiteral(secondLiteralIdn);
}
Toy_Literal microsecondLiteralIdn = microsecondLiteral;
if (TOY_IS_IDENTIFIER(microsecondLiteral) && Toy_parseIdentifierToValue(interpreter, &microsecondLiteral)) {
Toy_freeLiteral(microsecondLiteralIdn);
}
if (!TOY_IS_INTEGER(secondLiteral) || !TOY_IS_INTEGER(microsecondLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to createTimer\n");
Toy_freeLiteral(secondLiteral);
Toy_freeLiteral(microsecondLiteral);
return -1;
}
if (TOY_AS_INTEGER(microsecondLiteral) <= -1000 * 1000 || TOY_AS_INTEGER(microsecondLiteral) >= 1000 * 1000 || (TOY_AS_INTEGER(secondLiteral) != 0 && TOY_AS_INTEGER(microsecondLiteral) < 0) ) {
interpreter->errorOutput("Microseconds out of range in createTimer\n");
Toy_freeLiteral(secondLiteral);
Toy_freeLiteral(microsecondLiteral);
return -1;
}
//get the timeinfo from toy
struct timeval* timeinfo = TOY_ALLOCATE(struct timeval, 1);
timeinfo->tv_sec = TOY_AS_INTEGER(secondLiteral);
timeinfo->tv_usec = TOY_AS_INTEGER(microsecondLiteral);
//wrap in an opaque literal for Toy
Toy_Literal timeLiteral = TOY_TO_OPAQUE_LITERAL(timeinfo, -1);
Toy_pushLiteralArray(&interpreter->stack, timeLiteral);
Toy_freeLiteral(timeLiteral);
Toy_freeLiteral(secondLiteral);
Toy_freeLiteral(microsecondLiteral);
return 1;
}
static int nativeGetTimerSeconds(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _getTimerSeconds\n");
return -1;
}
//unwrap the opaque literal
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
Toy_Literal timeLiteralIdn = timeLiteral;
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
Toy_freeLiteral(timeLiteralIdn);
}
if (!TOY_IS_OPAQUE(timeLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to _getTimerSeconds\n");
Toy_freeLiteral(timeLiteral);
return -1;
}
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
//create the result literal
Toy_Literal result = TOY_TO_INTEGER_LITERAL(timer->tv_sec);
Toy_pushLiteralArray(&interpreter->stack, result);
//cleanup
Toy_freeLiteral(timeLiteral);
Toy_freeLiteral(result);
return 1;
}
static int nativeGetTimerMicroseconds(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _getTimerMicroseconds\n");
return -1;
}
//unwrap the opaque literal
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
Toy_Literal timeLiteralIdn = timeLiteral;
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
Toy_freeLiteral(timeLiteralIdn);
}
if (!TOY_IS_OPAQUE(timeLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to _getTimerMicroseconds\n");
Toy_freeLiteral(timeLiteral);
return -1;
}
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
//create the result literal
Toy_Literal result = TOY_TO_INTEGER_LITERAL(timer->tv_usec);
Toy_pushLiteralArray(&interpreter->stack, result);
//cleanup
Toy_freeLiteral(timeLiteral);
Toy_freeLiteral(result);
return 1;
}
static int nativeCompareTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments to _compareTimer\n");
return -1;
}
//unwrap the opaque literals
Toy_Literal rhsLiteral = Toy_popLiteralArray(arguments);
Toy_Literal lhsLiteral = Toy_popLiteralArray(arguments);
Toy_Literal lhsLiteralIdn = lhsLiteral;
if (TOY_IS_IDENTIFIER(lhsLiteral) && Toy_parseIdentifierToValue(interpreter, &lhsLiteral)) {
Toy_freeLiteral(lhsLiteralIdn);
}
Toy_Literal rhsLiteralIdn = rhsLiteral;
if (TOY_IS_IDENTIFIER(rhsLiteral) && Toy_parseIdentifierToValue(interpreter, &rhsLiteral)) {
Toy_freeLiteral(rhsLiteralIdn);
}
if (!TOY_IS_OPAQUE(lhsLiteral) || !TOY_IS_OPAQUE(rhsLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to _compareTimer\n");
Toy_freeLiteral(lhsLiteral);
Toy_freeLiteral(rhsLiteral);
return -1;
}
struct timeval* lhsTimer = TOY_AS_OPAQUE(lhsLiteral);
struct timeval* rhsTimer = TOY_AS_OPAQUE(rhsLiteral);
//determine the difference, and wrap it
struct timeval* d = diff(lhsTimer, rhsTimer);
Toy_Literal diffLiteral = TOY_TO_OPAQUE_LITERAL(d, -1);
Toy_pushLiteralArray(&interpreter->stack, diffLiteral);
//cleanup
Toy_freeLiteral(lhsLiteral);
Toy_freeLiteral(rhsLiteral);
Toy_freeLiteral(diffLiteral);
return 1;
}
static int nativeTimerToString(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _timerToString\n");
return -1;
}
//unwrap in an opaque literal
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
Toy_Literal timeLiteralIdn = timeLiteral;
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
Toy_freeLiteral(timeLiteralIdn);
}
if (!TOY_IS_OPAQUE(timeLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to _timerToString\n");
Toy_freeLiteral(timeLiteral);
return -1;
}
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
//create the string literal
Toy_Literal resultLiteral = TOY_TO_NULL_LITERAL;
if (timer->tv_sec == 0 && timer->tv_usec < 0) { //special case, for when the negative sign is encoded in the usec
char buffer[128];
snprintf(buffer, 128, "-%ld.%06ld", timer->tv_sec, -timer->tv_usec);
resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, strlen(buffer)));
}
else { //normal case
char buffer[128];
snprintf(buffer, 128, "%ld.%06ld", timer->tv_sec, timer->tv_usec);
resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, strlen(buffer)));
}
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
//cleanup
Toy_freeLiteral(timeLiteral);
Toy_freeLiteral(resultLiteral);
return 1;
}
static int nativeDestroyTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _destroyTimer\n");
return -1;
}
//unwrap in an opaque literal
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
Toy_Literal timeLiteralIdn = timeLiteral;
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
Toy_freeLiteral(timeLiteralIdn);
}
if (!TOY_IS_OPAQUE(timeLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to _destroyTimer\n");
Toy_freeLiteral(timeLiteral);
return -1;
}
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
TOY_FREE(struct timeval, timer);
Toy_freeLiteral(timeLiteral);
return 0;
}
//call the hook
typedef struct Natives {
char* name;
Toy_NativeFn fn;
} Natives;
int Toy_hookTimer(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
//build the natives list
Natives natives[] = {
{"startTimer", nativeStartTimer},
{"_stopTimer", nativeStopTimer},
{"createTimer", nativeCreateTimer},
{"_getTimerSeconds", nativeGetTimerSeconds},
{"_getTimerMicroseconds", nativeGetTimerMicroseconds},
{"_compareTimer", nativeCompareTimer},
{"_timerToString", nativeTimerToString},
{"_destroyTimer", nativeDestroyTimer},
{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;
}

View File

@@ -1,6 +0,0 @@
#pragma once
#include "toy_interpreter.h"
int Toy_hookTimer(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);

View File

@@ -1,8 +1,6 @@
#include "repl_tools.h"
#include "lib_about.h"
#include "lib_compound.h"
#include "lib_standard.h"
#include "lib_timer.h"
#include "lib_runner.h"
#include "toy_console_colors.h"
@@ -57,7 +55,7 @@ int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size) {
return -1;
}
int written = fwrite(bytes, size, 1, file);
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);
@@ -113,12 +111,10 @@ void Toy_runBinary(const unsigned char* tb, size_t size) {
//inject the libs
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
Toy_injectNativeHook(&interpreter, "compound", Toy_hookCompound);
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
Toy_injectNativeHook(&interpreter, "timer", Toy_hookTimer);
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
Toy_runInterpreter(&interpreter, tb, size);
Toy_runInterpreter(&interpreter, tb, (int)size);
Toy_freeInterpreter(&interpreter);
}