mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Merge remote-tracking branch 'refs/remotes/origin/main'
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -19,6 +19,8 @@ bin/
|
|||||||
*.db
|
*.db
|
||||||
*.o
|
*.o
|
||||||
*.a
|
*.a
|
||||||
|
*.so
|
||||||
|
*.dll
|
||||||
*.exe
|
*.exe
|
||||||
*.meta
|
*.meta
|
||||||
*.log
|
*.log
|
||||||
|
|||||||
196
repl/lib_random.c
Normal file
196
repl/lib_random.c
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
7
repl/lib_random.h
Normal file
7
repl/lib_random.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "toy_interpreter.h"
|
||||||
|
|
||||||
|
int Toy_hookRandom(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||||
|
|
||||||
|
#define TOY_OPAQUE_TAG_RANDOM 200
|
||||||
@@ -7,6 +7,49 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
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 nativeClock(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
static int nativeClock(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||||
//no arguments
|
//no arguments
|
||||||
if (arguments->count != 0) {
|
if (arguments->count != 0) {
|
||||||
@@ -702,6 +745,36 @@ static int nativeGetValues(Toy_Interpreter* interpreter, Toy_LiteralArray* argum
|
|||||||
return 1;
|
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 nativeIndexOf(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
static int nativeIndexOf(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||||
//no arguments
|
//no arguments
|
||||||
if (arguments->count != 2) {
|
if (arguments->count != 2) {
|
||||||
@@ -1667,6 +1740,7 @@ typedef struct Natives {
|
|||||||
int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
||||||
//build the natives list
|
//build the natives list
|
||||||
Natives natives[] = {
|
Natives natives[] = {
|
||||||
|
{"abs", nativeAbs},
|
||||||
{"clock", nativeClock},
|
{"clock", nativeClock},
|
||||||
{"concat", nativeConcat}, //array, dictionary, string
|
{"concat", nativeConcat}, //array, dictionary, string
|
||||||
{"containsKey", nativeContainsKey}, //dictionary
|
{"containsKey", nativeContainsKey}, //dictionary
|
||||||
@@ -1676,6 +1750,7 @@ int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L
|
|||||||
{"forEach", nativeForEach}, //array, dictionary
|
{"forEach", nativeForEach}, //array, dictionary
|
||||||
{"getKeys", nativeGetKeys}, //dictionary
|
{"getKeys", nativeGetKeys}, //dictionary
|
||||||
{"getValues", nativeGetValues}, //dictionary
|
{"getValues", nativeGetValues}, //dictionary
|
||||||
|
{"hash", nativeHash},
|
||||||
{"indexOf", nativeIndexOf}, //array
|
{"indexOf", nativeIndexOf}, //array
|
||||||
{"map", nativeMap}, //array, dictionary
|
{"map", nativeMap}, //array, dictionary
|
||||||
{"reduce", nativeReduce}, //array, dictionary
|
{"reduce", nativeReduce}, //array, dictionary
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "repl_tools.h"
|
#include "repl_tools.h"
|
||||||
#include "lib_about.h"
|
#include "lib_about.h"
|
||||||
#include "lib_standard.h"
|
#include "lib_standard.h"
|
||||||
|
#include "lib_random.h"
|
||||||
#include "lib_runner.h"
|
#include "lib_runner.h"
|
||||||
|
|
||||||
#include "toy_console_colors.h"
|
#include "toy_console_colors.h"
|
||||||
@@ -29,6 +30,7 @@ void repl(const char* initialInput) {
|
|||||||
//inject the libs
|
//inject the libs
|
||||||
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
||||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||||
|
Toy_injectNativeHook(&interpreter, "random", Toy_hookRandom);
|
||||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "repl_tools.h"
|
#include "repl_tools.h"
|
||||||
#include "lib_about.h"
|
#include "lib_about.h"
|
||||||
#include "lib_standard.h"
|
#include "lib_standard.h"
|
||||||
|
#include "lib_random.h"
|
||||||
#include "lib_runner.h"
|
#include "lib_runner.h"
|
||||||
|
|
||||||
#include "toy_console_colors.h"
|
#include "toy_console_colors.h"
|
||||||
@@ -112,6 +113,7 @@ void Toy_runBinary(const unsigned char* tb, size_t size) {
|
|||||||
//inject the libs
|
//inject the libs
|
||||||
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
||||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||||
|
Toy_injectNativeHook(&interpreter, "random", Toy_hookRandom);
|
||||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
||||||
|
|
||||||
Toy_runInterpreter(&interpreter, tb, (int)size);
|
Toy_runInterpreter(&interpreter, tb, (int)size);
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
import node;
|
|
||||||
|
|
||||||
//constants
|
|
||||||
var SPEED: int const = 10;
|
|
||||||
|
|
||||||
//variables
|
|
||||||
var parent: opaque = null;
|
|
||||||
var posX: int = 50;
|
|
||||||
var posY: int = 50;
|
|
||||||
var WIDTH: int const = 100;
|
|
||||||
var HEIGHT: int const = 100;
|
|
||||||
|
|
||||||
var xspeed: int = 0;
|
|
||||||
var yspeed: int = 0;
|
|
||||||
|
|
||||||
//accessors - variables are private, functions are public
|
|
||||||
fn getX(node: opaque) {
|
|
||||||
return posX;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn getY(node: opaque) {
|
|
||||||
return posY;
|
|
||||||
}
|
|
||||||
|
|
||||||
//lifecycle functions
|
|
||||||
fn onInit(node: opaque) {
|
|
||||||
print "render.toy:onInit() called\n";
|
|
||||||
|
|
||||||
node.loadTexture("sprites:/character.png");
|
|
||||||
parent = node.getNodeParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onStep(node: opaque) {
|
|
||||||
posX += xspeed;
|
|
||||||
posY += yspeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onFree(node: opaque) {
|
|
||||||
print "render.toy:onFree() called\n";
|
|
||||||
|
|
||||||
node.freeTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onDraw(node: opaque) {
|
|
||||||
// print "render.toy:onDraw() called\n";
|
|
||||||
|
|
||||||
var px = parent.callNode("getX");
|
|
||||||
var py = parent.callNode("getY");
|
|
||||||
|
|
||||||
if (px == null) {
|
|
||||||
px = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (py == null) {
|
|
||||||
py = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
node.drawNode(posX + px, posY + py, WIDTH, HEIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
//event functions
|
|
||||||
fn onKeyDown(node: opaque, event: string) {
|
|
||||||
if (event == "character_up") {
|
|
||||||
yspeed -= SPEED;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event == "character_down") {
|
|
||||||
yspeed += SPEED;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event == "character_left") {
|
|
||||||
xspeed -= SPEED;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event == "character_right") {
|
|
||||||
xspeed += SPEED;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onKeyUp(node: opaque, event: string) {
|
|
||||||
if (event == "character_up" && yspeed < 0) {
|
|
||||||
yspeed = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event == "character_down" && yspeed > 0) {
|
|
||||||
yspeed = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event == "character_left" && xspeed < 0) {
|
|
||||||
xspeed = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event == "character_right" && xspeed > 0) {
|
|
||||||
xspeed = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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";
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onMouseButtonDown(node: opaque, x: int, y: int, button: string) {
|
|
||||||
// print "entity.toy:onMouseButtonDown(" + string x + ", " + string y + ", " + button + ")\n";
|
|
||||||
|
|
||||||
//jump to pos
|
|
||||||
posX = x - WIDTH / 2;
|
|
||||||
posY = y - HEIGHT / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onMouseButtonUp(node: opaque, x: int, y: int, button: string) {
|
|
||||||
// print "entity.toy:onMouseButtonUp(" + string x + ", " + string y + ", " + button + ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onMouseWheel(node: opaque, xrel: int, yrel: int) {
|
|
||||||
// print "entity.toy:onMouseWheel(" + string xrel + ", " + string yrel + ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
//single line comment
|
|
||||||
|
|
||||||
/*
|
|
||||||
multi line comment
|
|
||||||
*/
|
|
||||||
|
|
||||||
//test primitive literals
|
|
||||||
print "hello world";
|
|
||||||
print null;
|
|
||||||
print true;
|
|
||||||
print false;
|
|
||||||
print 42;
|
|
||||||
print 3.14;
|
|
||||||
print -69;
|
|
||||||
print -4.20;
|
|
||||||
print 2 + (3 * 3);
|
|
||||||
|
|
||||||
//test operators (integers)
|
|
||||||
print 1 + 1;
|
|
||||||
print 1 - 1;
|
|
||||||
print 2 * 2;
|
|
||||||
print 1 / 2;
|
|
||||||
print 4 % 2;
|
|
||||||
|
|
||||||
//test operators (floats)
|
|
||||||
print 1.0 + 1.0;
|
|
||||||
print 1.0 - 1.0;
|
|
||||||
print 2.0 * 2.0;
|
|
||||||
print 1.0 / 2.0;
|
|
||||||
|
|
||||||
//test scopes
|
|
||||||
{
|
|
||||||
print "This statement is within a scope.";
|
|
||||||
{
|
|
||||||
print "This is a deeper scope.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print "Back to the outer scope.";
|
|
||||||
|
|
||||||
//test scope will delegate to higher scope
|
|
||||||
var a = 1;
|
|
||||||
{
|
|
||||||
a = 2;
|
|
||||||
print a;
|
|
||||||
}
|
|
||||||
print a;
|
|
||||||
|
|
||||||
//test scope will shadow higher scope on redefine
|
|
||||||
var b: int = 3;
|
|
||||||
{
|
|
||||||
var b = 4;
|
|
||||||
print b;
|
|
||||||
}
|
|
||||||
print b;
|
|
||||||
|
|
||||||
//test compounds, repeatedly
|
|
||||||
print [1, 2, 3];
|
|
||||||
print [4, 5];
|
|
||||||
print ["key":"value"];
|
|
||||||
print [1, 2, 3];
|
|
||||||
print [4, 5];
|
|
||||||
print ["key":"value"];
|
|
||||||
|
|
||||||
//test empties
|
|
||||||
print [];
|
|
||||||
print [:];
|
|
||||||
|
|
||||||
//test nested compounds
|
|
||||||
print [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
|
|
||||||
|
|
||||||
//var declarations
|
|
||||||
var x = 31;
|
|
||||||
var y : int = 42;
|
|
||||||
var arr : [int] = [1, 2, 3, 42];
|
|
||||||
var dict : [string:int] = ["hello": 1, "world":2];
|
|
||||||
|
|
||||||
//printing expressions
|
|
||||||
print x;
|
|
||||||
print x + y;
|
|
||||||
print arr;
|
|
||||||
print dict;
|
|
||||||
|
|
||||||
//test asserts at the end of the file
|
|
||||||
assert x, "This won't be seen";
|
|
||||||
assert true, "This won't be seen";
|
|
||||||
assert false, "This is a failed assert, and will end execution";
|
|
||||||
|
|
||||||
print "This will not be printed because of the above assert";
|
|
||||||
|
|
||||||
36
scripts/roguelike-seeds.toy
Normal file
36
scripts/roguelike-seeds.toy
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Since this is a pseudo-random generator, and there's no internal state to the algorithm other
|
||||||
|
than the generator opaque, there needs to be a "call counter" (current depth) to shuffle the
|
||||||
|
initial seeds, otherwise generators created from other generators will resemble their parents,
|
||||||
|
but one call greater.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import standard;
|
||||||
|
import random;
|
||||||
|
|
||||||
|
var DEPTH: int const = 20;
|
||||||
|
var levels = [];
|
||||||
|
|
||||||
|
//generate the level seeds
|
||||||
|
var generator: opaque = createRandomGenerator(clock().hash());
|
||||||
|
|
||||||
|
for (var i: int = 0; i < DEPTH; i++) {
|
||||||
|
levels.push(generator.generateRandomNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
generator.freeRandomGenerator();
|
||||||
|
|
||||||
|
//generate "levels" of a roguelike
|
||||||
|
for (var i = 0; i < DEPTH; i++) {
|
||||||
|
var rng: opaque = createRandomGenerator(levels[i] + i);
|
||||||
|
|
||||||
|
print "---";
|
||||||
|
print levels[i];
|
||||||
|
print rng.generateRandomNumber();
|
||||||
|
print rng.generateRandomNumber();
|
||||||
|
print rng.generateRandomNumber();
|
||||||
|
|
||||||
|
rng.freeRandomGenerator();
|
||||||
|
}
|
||||||
17
test/scripts/lib/random.toy
Normal file
17
test/scripts/lib/random.toy
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import standard;
|
||||||
|
import random;
|
||||||
|
|
||||||
|
var generator: opaque = createRandomGenerator(clock().hash()); //create a new generator object, from a non-determinant source
|
||||||
|
|
||||||
|
var a: int = generator.generateRandomNumber();
|
||||||
|
var b: int = generator.generateRandomNumber();
|
||||||
|
var c: int = generator.generateRandomNumber();
|
||||||
|
|
||||||
|
generator.freeRandomGenerator();
|
||||||
|
|
||||||
|
assert a != b, "random a != random b failed";
|
||||||
|
assert a != c, "random a != random c failed";
|
||||||
|
assert b != c, "random b != random c failed";
|
||||||
|
|
||||||
|
|
||||||
|
print "All good";
|
||||||
@@ -1,5 +1,18 @@
|
|||||||
import standard;
|
import standard;
|
||||||
|
|
||||||
|
//test abs
|
||||||
|
{
|
||||||
|
assert abs(-5) == 5, "abs(-integer) failed";
|
||||||
|
assert abs(-5.5) == 5.5, "abs(-float) failed";
|
||||||
|
assert abs(5) == 5, "abs(+integer) failed";
|
||||||
|
assert abs(5.5) == 5.5, "abs(+float) failed";
|
||||||
|
|
||||||
|
var x = -5;
|
||||||
|
|
||||||
|
assert x.abs() == 5, "var.abs() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//test clock
|
//test clock
|
||||||
{
|
{
|
||||||
//this depends on external factors, so only check the length
|
//this depends on external factors, so only check the length
|
||||||
@@ -162,6 +175,13 @@ import standard;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test hash
|
||||||
|
{
|
||||||
|
assert typeof "Hello world".hash() == int, "typeof \"Hello world\".hash() failed";
|
||||||
|
assert "Hello world".hash() == 994097935, "\"Hello world\".hash() failed"; //NOTE: specific value based on algorithm
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//test indexOf
|
//test indexOf
|
||||||
{
|
{
|
||||||
var a = [1, 2, 42, 3];
|
var a = [1, 2, 42, 3];
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "../repl/repl_tools.h"
|
#include "../repl/repl_tools.h"
|
||||||
|
|
||||||
#include "../repl/lib_about.h"
|
#include "../repl/lib_about.h"
|
||||||
|
#include "../repl/lib_random.h"
|
||||||
#include "../repl/lib_runner.h"
|
#include "../repl/lib_runner.h"
|
||||||
#include "../repl/lib_standard.h"
|
#include "../repl/lib_standard.h"
|
||||||
|
|
||||||
@@ -45,25 +46,10 @@ void runBinaryWithLibrary(const unsigned char* tb, size_t size, const char* libr
|
|||||||
Toy_setInterpreterError(&interpreter, errorWrapper);
|
Toy_setInterpreterError(&interpreter, errorWrapper);
|
||||||
|
|
||||||
//inject the standard libraries into this interpreter
|
//inject the standard libraries into this interpreter
|
||||||
Toy_injectNativeHook(&interpreter, library, hook);
|
if (hook != Toy_hookStandard) {
|
||||||
|
|
||||||
Toy_runInterpreter(&interpreter, tb, size);
|
|
||||||
Toy_freeInterpreter(&interpreter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void runBinaryQuietly(const unsigned char* tb, size_t size) {
|
|
||||||
Toy_Interpreter interpreter;
|
|
||||||
Toy_initInterpreter(&interpreter);
|
|
||||||
|
|
||||||
//NOTE: supress print output for testing
|
|
||||||
Toy_setInterpreterPrint(&interpreter, noPrintFn);
|
|
||||||
Toy_setInterpreterAssert(&interpreter, assertWrapper);
|
|
||||||
Toy_setInterpreterError(&interpreter, errorWrapper);
|
|
||||||
|
|
||||||
//inject the libs
|
|
||||||
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
|
||||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
}
|
||||||
|
Toy_injectNativeHook(&interpreter, library, hook);
|
||||||
|
|
||||||
Toy_runInterpreter(&interpreter, tb, size);
|
Toy_runInterpreter(&interpreter, tb, size);
|
||||||
Toy_freeInterpreter(&interpreter);
|
Toy_freeInterpreter(&interpreter);
|
||||||
@@ -94,6 +80,7 @@ int main() {
|
|||||||
{"about.toy", "about", Toy_hookAbout},
|
{"about.toy", "about", Toy_hookAbout},
|
||||||
{"standard.toy", "standard", Toy_hookStandard},
|
{"standard.toy", "standard", Toy_hookStandard},
|
||||||
{"runner.toy", "runner", Toy_hookRunner},
|
{"runner.toy", "runner", Toy_hookRunner},
|
||||||
|
{"random.toy", "random", Toy_hookRandom},
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -125,41 +112,6 @@ int main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
//run whatever, testing stuff together to check for memory leaks
|
|
||||||
char* whatever[] = {
|
|
||||||
"random-stuff.toy",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; whatever[i]; i++) {
|
|
||||||
printf("Running %s\n", whatever[i]);
|
|
||||||
|
|
||||||
char fname[128];
|
|
||||||
snprintf(fname, 128, "scripts/lib/%s", whatever[i]);
|
|
||||||
|
|
||||||
//compile the source
|
|
||||||
size_t size = 0;
|
|
||||||
const char* source = (const char*)Toy_readFile(fname, &size);
|
|
||||||
if (!source) {
|
|
||||||
printf(TOY_CC_ERROR "Failed to load file: %s\n" TOY_CC_RESET, fname);
|
|
||||||
failedAsserts++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned char* tb = Toy_compileString(source, &size);
|
|
||||||
free((void*)source);
|
|
||||||
|
|
||||||
if (!tb) {
|
|
||||||
printf(TOY_CC_ERROR "Failed to compile file: %s\n" TOY_CC_RESET, fname);
|
|
||||||
failedAsserts++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
runBinaryQuietly(tb, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//lib cleanup
|
//lib cleanup
|
||||||
Toy_freeDriveDictionary();
|
Toy_freeDriveDictionary();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user