mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Renemed all variables to fit into a namespace
Basically, all Toy varaibles, functions, etc. are prepended with "Toy_", and macros are prepended with "TOY_". This is to reduce namespace pollution, which was an issue pointed out to be - blame @GyroVorbis. I've also bumped the minor version number - theoretically I should bump the major number, but I'm not quite ready for 1.0 yet.
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
#include "lib_runner.h"
|
||||
|
||||
#include "memory.h"
|
||||
#include "interpreter.h"
|
||||
#include "toy_memory.h"
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
#include "repl_tools.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Runner {
|
||||
Interpreter interpreter;
|
||||
typedef struct Toy_Runner {
|
||||
Toy_Interpreter interpreter;
|
||||
unsigned char* bytecode;
|
||||
size_t size;
|
||||
|
||||
bool dirty;
|
||||
} Runner;
|
||||
} Toy_Runner;
|
||||
|
||||
//Toy native functions
|
||||
static int nativeLoadScript(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to loadScript\n");
|
||||
@@ -25,60 +25,60 @@ static int nativeLoadScript(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
}
|
||||
|
||||
//get the argument
|
||||
Literal drivePathLiteral = popLiteralArray(arguments);
|
||||
RefString* drivePath = copyRefString(AS_STRING(drivePathLiteral));
|
||||
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
|
||||
Toy_RefString* drivePath = Toy_copyRefString(TOY_AS_STRING(drivePathLiteral));
|
||||
|
||||
//get the drive and path as a string (can't trust that pesky strtok - custom split) TODO: move this to refstring library
|
||||
int driveLength = 0;
|
||||
while (toCString(drivePath)[driveLength] != ':') {
|
||||
if (driveLength >= lengthRefString(drivePath)) {
|
||||
while (Toy_toCString(drivePath)[driveLength] != ':') {
|
||||
if (driveLength >= Toy_lengthRefString(drivePath)) {
|
||||
interpreter->errorOutput("Incorrect drive path format given to loadScript\n");
|
||||
deleteRefString(drivePath);
|
||||
freeLiteral(drivePathLiteral);
|
||||
Toy_deleteRefString(drivePath);
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
driveLength++;
|
||||
}
|
||||
|
||||
RefString* drive = createRefStringLength(toCString(drivePath), driveLength);
|
||||
RefString* path = createRefStringLength( &toCString(drivePath)[driveLength + 1], lengthRefString(drivePath) - driveLength );
|
||||
Toy_RefString* drive = Toy_createRefStringLength(Toy_toCString(drivePath), driveLength);
|
||||
Toy_RefString* path = Toy_createRefStringLength( &Toy_toCString(drivePath)[driveLength + 1], Toy_lengthRefString(drivePath) - driveLength );
|
||||
|
||||
//get the real drive file path
|
||||
Literal driveLiteral = TO_STRING_LITERAL(drive); //NOTE: driveLiteral takes ownership of the refString
|
||||
Literal realDriveLiteral = getLiteralDictionary(getDriveDictionary(), driveLiteral);
|
||||
Toy_Literal driveLiteral = TOY_TO_STRING_LITERAL(drive); //NOTE: driveLiteral takes ownership of the refString
|
||||
Toy_Literal realDriveLiteral = Toy_getLiteralDictionary(Toy_getDriveDictionary(), driveLiteral);
|
||||
|
||||
if (!IS_STRING(realDriveLiteral)) {
|
||||
if (!TOY_IS_STRING(realDriveLiteral)) {
|
||||
interpreter->errorOutput("Incorrect literal type found for drive: ");
|
||||
printLiteralCustom(realDriveLiteral, interpreter->errorOutput);
|
||||
Toy_printLiteralCustom(realDriveLiteral, interpreter->errorOutput);
|
||||
interpreter->errorOutput("\n");
|
||||
freeLiteral(realDriveLiteral);
|
||||
freeLiteral(driveLiteral);
|
||||
deleteRefString(path);
|
||||
deleteRefString(drivePath);
|
||||
freeLiteral(drivePathLiteral);
|
||||
Toy_freeLiteral(realDriveLiteral);
|
||||
Toy_freeLiteral(driveLiteral);
|
||||
Toy_deleteRefString(path);
|
||||
Toy_deleteRefString(drivePath);
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the final real file path (concat) TODO: move this concat to refstring library
|
||||
RefString* realDrive = copyRefString(AS_STRING(realDriveLiteral));
|
||||
int realLength = lengthRefString(realDrive) + lengthRefString(path);
|
||||
Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral));
|
||||
int realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
|
||||
|
||||
char* filePath = ALLOCATE(char, realLength + 1); //+1 for null
|
||||
snprintf(filePath, realLength, "%s%s", toCString(realDrive), toCString(path));
|
||||
char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null
|
||||
snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path));
|
||||
|
||||
//clean up the drivepath stuff
|
||||
deleteRefString(realDrive);
|
||||
freeLiteral(realDriveLiteral);
|
||||
freeLiteral(driveLiteral);
|
||||
deleteRefString(path);
|
||||
deleteRefString(drivePath);
|
||||
freeLiteral(drivePathLiteral);
|
||||
Toy_deleteRefString(realDrive);
|
||||
Toy_freeLiteral(realDriveLiteral);
|
||||
Toy_freeLiteral(driveLiteral);
|
||||
Toy_deleteRefString(path);
|
||||
Toy_deleteRefString(drivePath);
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
|
||||
//check for file extensions
|
||||
if (!(filePath[realLength - 5] == '.' && filePath[realLength - 4] == 't' && filePath[realLength - 3] == 'o' && filePath[realLength - 2] == 'y')) {
|
||||
interpreter->errorOutput("Bad script file extension (expected .toy)\n");
|
||||
FREE_ARRAY(char, filePath, realLength);
|
||||
TOY_FREE_ARRAY(char, filePath, realLength);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -86,21 +86,21 @@ static int nativeLoadScript(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
for (int i = 0; i < realLength - 1; i++) {
|
||||
if (filePath[i] == '.' && filePath[i + 1] == '.') {
|
||||
interpreter->errorOutput("Parent directory access not allowed\n");
|
||||
FREE_ARRAY(char, filePath, realLength);
|
||||
TOY_FREE_ARRAY(char, filePath, realLength);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//load and compile the bytecode
|
||||
size_t fileSize = 0;
|
||||
char* source = readFile(filePath, &fileSize);
|
||||
char* source = Toy_readFile(filePath, &fileSize);
|
||||
|
||||
if (!source) {
|
||||
interpreter->errorOutput("Failed to load source file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned char* bytecode = compileString(source, &fileSize);
|
||||
unsigned char* bytecode = Toy_compileString(source, &fileSize);
|
||||
free((void*)source);
|
||||
|
||||
if (!bytecode) {
|
||||
@@ -109,27 +109,27 @@ static int nativeLoadScript(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
}
|
||||
|
||||
//build the runner object
|
||||
Runner* runner = ALLOCATE(Runner, 1);
|
||||
setInterpreterPrint(&runner->interpreter, interpreter->printOutput);
|
||||
setInterpreterAssert(&runner->interpreter, interpreter->assertOutput);
|
||||
setInterpreterError(&runner->interpreter, interpreter->errorOutput);
|
||||
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;
|
||||
resetInterpreter(&runner->interpreter);
|
||||
Toy_resetInterpreter(&runner->interpreter);
|
||||
runner->bytecode = bytecode;
|
||||
runner->size = fileSize;
|
||||
runner->dirty = false;
|
||||
|
||||
//build the opaque object, and push it to the stack
|
||||
Literal runnerLiteral = TO_OPAQUE_LITERAL(runner, OPAQUE_TAG_RUNNER);
|
||||
pushLiteralArray(&interpreter->stack, runnerLiteral);
|
||||
Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER);
|
||||
Toy_pushLiteralArray(&interpreter->stack, runnerLiteral);
|
||||
|
||||
FREE_ARRAY(char, filePath, realLength);
|
||||
TOY_FREE_ARRAY(char, filePath, realLength);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeLoadScriptBytecode(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to loadScriptBytecode\n");
|
||||
@@ -137,60 +137,60 @@ static int nativeLoadScriptBytecode(Interpreter* interpreter, LiteralArray* argu
|
||||
}
|
||||
|
||||
//get the argument
|
||||
Literal drivePathLiteral = popLiteralArray(arguments);
|
||||
RefString* drivePath = copyRefString(AS_STRING(drivePathLiteral));
|
||||
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
|
||||
Toy_RefString* drivePath = Toy_copyRefString(TOY_AS_STRING(drivePathLiteral));
|
||||
|
||||
//get the drive and path as a string (can't trust that pesky strtok - custom split) TODO: move this to refstring library
|
||||
int driveLength = 0;
|
||||
while (toCString(drivePath)[driveLength] != ':') {
|
||||
if (driveLength >= lengthRefString(drivePath)) {
|
||||
while (Toy_toCString(drivePath)[driveLength] != ':') {
|
||||
if (driveLength >= Toy_lengthRefString(drivePath)) {
|
||||
interpreter->errorOutput("Incorrect drive path format given to loadScriptBytecode\n");
|
||||
deleteRefString(drivePath);
|
||||
freeLiteral(drivePathLiteral);
|
||||
Toy_deleteRefString(drivePath);
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
driveLength++;
|
||||
}
|
||||
|
||||
RefString* drive = createRefStringLength(toCString(drivePath), driveLength);
|
||||
RefString* path = createRefStringLength( &toCString(drivePath)[driveLength + 1], lengthRefString(drivePath) - driveLength );
|
||||
Toy_RefString* drive = Toy_createRefStringLength(Toy_toCString(drivePath), driveLength);
|
||||
Toy_RefString* path = Toy_createRefStringLength( &Toy_toCString(drivePath)[driveLength + 1], Toy_lengthRefString(drivePath) - driveLength );
|
||||
|
||||
//get the real drive file path
|
||||
Literal driveLiteral = TO_STRING_LITERAL(drive); //NOTE: driveLiteral takes ownership of the refString
|
||||
Literal realDriveLiteral = getLiteralDictionary(getDriveDictionary(), driveLiteral);
|
||||
Toy_Literal driveLiteral = TOY_TO_STRING_LITERAL(drive); //NOTE: driveLiteral takes ownership of the refString
|
||||
Toy_Literal realDriveLiteral = Toy_getLiteralDictionary(Toy_getDriveDictionary(), driveLiteral);
|
||||
|
||||
if (!IS_STRING(realDriveLiteral)) {
|
||||
if (!TOY_IS_STRING(realDriveLiteral)) {
|
||||
interpreter->errorOutput("Incorrect literal type found for drive: ");
|
||||
printLiteralCustom(realDriveLiteral, interpreter->errorOutput);
|
||||
Toy_printLiteralCustom(realDriveLiteral, interpreter->errorOutput);
|
||||
interpreter->errorOutput("\n");
|
||||
freeLiteral(realDriveLiteral);
|
||||
freeLiteral(driveLiteral);
|
||||
deleteRefString(path);
|
||||
deleteRefString(drivePath);
|
||||
freeLiteral(drivePathLiteral);
|
||||
Toy_freeLiteral(realDriveLiteral);
|
||||
Toy_freeLiteral(driveLiteral);
|
||||
Toy_deleteRefString(path);
|
||||
Toy_deleteRefString(drivePath);
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the final real file path (concat) TODO: move this concat to refstring library
|
||||
RefString* realDrive = copyRefString(AS_STRING(realDriveLiteral));
|
||||
int realLength = lengthRefString(realDrive) + lengthRefString(path);
|
||||
Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral));
|
||||
int realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
|
||||
|
||||
char* filePath = ALLOCATE(char, realLength + 1); //+1 for null
|
||||
snprintf(filePath, realLength, "%s%s", toCString(realDrive), toCString(path));
|
||||
char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null
|
||||
snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path));
|
||||
|
||||
//clean up the drivepath stuff
|
||||
deleteRefString(realDrive);
|
||||
freeLiteral(realDriveLiteral);
|
||||
freeLiteral(driveLiteral);
|
||||
deleteRefString(path);
|
||||
deleteRefString(drivePath);
|
||||
freeLiteral(drivePathLiteral);
|
||||
Toy_deleteRefString(realDrive);
|
||||
Toy_freeLiteral(realDriveLiteral);
|
||||
Toy_freeLiteral(driveLiteral);
|
||||
Toy_deleteRefString(path);
|
||||
Toy_deleteRefString(drivePath);
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
|
||||
//check for file extensions
|
||||
if (!(filePath[realLength - 4] == '.' && filePath[realLength - 3] == 't' && filePath[realLength - 2] == 'b')) {
|
||||
interpreter->errorOutput("Bad binary file extension (expected .tb)\n");
|
||||
FREE_ARRAY(char, filePath, realLength);
|
||||
TOY_FREE_ARRAY(char, filePath, realLength);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -198,14 +198,14 @@ static int nativeLoadScriptBytecode(Interpreter* interpreter, LiteralArray* argu
|
||||
for (int i = 0; i < realLength - 1; i++) {
|
||||
if (filePath[i] == '.' && filePath[i + 1] == '.') {
|
||||
interpreter->errorOutput("Parent directory access not allowed\n");
|
||||
FREE_ARRAY(char, filePath, realLength);
|
||||
TOY_FREE_ARRAY(char, filePath, realLength);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//load the bytecode
|
||||
size_t fileSize = 0;
|
||||
unsigned char* bytecode = (unsigned char*)readFile(filePath, &fileSize);
|
||||
unsigned char* bytecode = (unsigned char*)Toy_readFile(filePath, &fileSize);
|
||||
|
||||
if (!bytecode) {
|
||||
interpreter->errorOutput("Failed to load bytecode file\n");
|
||||
@@ -213,27 +213,27 @@ static int nativeLoadScriptBytecode(Interpreter* interpreter, LiteralArray* argu
|
||||
}
|
||||
|
||||
//build the runner object
|
||||
Runner* runner = ALLOCATE(Runner, 1);
|
||||
setInterpreterPrint(&runner->interpreter, interpreter->printOutput);
|
||||
setInterpreterAssert(&runner->interpreter, interpreter->assertOutput);
|
||||
setInterpreterError(&runner->interpreter, interpreter->errorOutput);
|
||||
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;
|
||||
resetInterpreter(&runner->interpreter);
|
||||
Toy_resetInterpreter(&runner->interpreter);
|
||||
runner->bytecode = bytecode;
|
||||
runner->size = fileSize;
|
||||
runner->dirty = false;
|
||||
|
||||
//build the opaque object, and push it to the stack
|
||||
Literal runnerLiteral = TO_OPAQUE_LITERAL(runner, OPAQUE_TAG_RUNNER);
|
||||
pushLiteralArray(&interpreter->stack, runnerLiteral);
|
||||
Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER);
|
||||
Toy_pushLiteralArray(&interpreter->stack, runnerLiteral);
|
||||
|
||||
FREE_ARRAY(char, filePath, realLength);
|
||||
TOY_FREE_ARRAY(char, filePath, realLength);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeRunScript(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeRunScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _runScript\n");
|
||||
@@ -241,40 +241,40 @@ static int nativeRunScript(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Literal runnerLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal runnerIdn = runnerLiteral;
|
||||
if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
freeLiteral(runnerIdn);
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) {
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in _runScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Runner* runner = AS_OPAQUE(runnerLiteral);
|
||||
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");
|
||||
freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned char* bytecodeCopy = ALLOCATE(unsigned char, runner->size);
|
||||
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
|
||||
|
||||
runInterpreter(&runner->interpreter, bytecodeCopy, runner->size);
|
||||
Toy_runInterpreter(&runner->interpreter, bytecodeCopy, runner->size);
|
||||
runner->dirty = true;
|
||||
|
||||
//cleanup
|
||||
freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nativeGetScriptVar(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeGetScriptVar(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 2) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _getScriptVar\n");
|
||||
@@ -282,50 +282,50 @@ static int nativeGetScriptVar(Interpreter* interpreter, LiteralArray* arguments)
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Literal varName = popLiteralArray(arguments);
|
||||
Literal runnerLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal varName = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal varNameIdn = varName;
|
||||
if (IS_IDENTIFIER(varName) && parseIdentifierToValue(interpreter, &varName)) {
|
||||
freeLiteral(varNameIdn);
|
||||
Toy_Literal varNameIdn = varName;
|
||||
if (TOY_IS_IDENTIFIER(varName) && Toy_parseIdentifierToValue(interpreter, &varName)) {
|
||||
Toy_freeLiteral(varNameIdn);
|
||||
}
|
||||
|
||||
Literal runnerIdn = runnerLiteral;
|
||||
if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
freeLiteral(runnerIdn);
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) {
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in _runScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Runner* runner = AS_OPAQUE(runnerLiteral);
|
||||
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");
|
||||
freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the desired variable
|
||||
Literal varIdn = TO_IDENTIFIER_LITERAL(copyRefString(AS_STRING(varName)));
|
||||
Literal result = TO_NULL_LITERAL;
|
||||
getScopeVariable(runner->interpreter.scope, varIdn, &result);
|
||||
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);
|
||||
|
||||
pushLiteralArray(&interpreter->stack, result);
|
||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(result);
|
||||
freeLiteral(varIdn);
|
||||
freeLiteral(varName);
|
||||
freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteral(result);
|
||||
Toy_freeLiteral(varIdn);
|
||||
Toy_freeLiteral(varName);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeCallScriptFn(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count < 2) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _callScriptFn\n");
|
||||
@@ -333,96 +333,96 @@ static int nativeCallScriptFn(Interpreter* interpreter, LiteralArray* arguments)
|
||||
}
|
||||
|
||||
//get the rest args
|
||||
LiteralArray tmp;
|
||||
initLiteralArray(&tmp);
|
||||
Toy_LiteralArray tmp;
|
||||
Toy_initLiteralArray(&tmp);
|
||||
|
||||
while (arguments->count > 2) {
|
||||
Literal lit = popLiteralArray(arguments);
|
||||
pushLiteralArray(&tmp, lit);
|
||||
freeLiteral(lit);
|
||||
Toy_Literal lit = Toy_popLiteralArray(arguments);
|
||||
Toy_pushLiteralArray(&tmp, lit);
|
||||
Toy_freeLiteral(lit);
|
||||
}
|
||||
|
||||
LiteralArray rest;
|
||||
initLiteralArray(&rest);
|
||||
Toy_LiteralArray rest;
|
||||
Toy_initLiteralArray(&rest);
|
||||
|
||||
while (tmp.count) { //correct the order of the rest args
|
||||
Literal lit = popLiteralArray(&tmp);
|
||||
pushLiteralArray(&rest, lit);
|
||||
freeLiteral(lit);
|
||||
Toy_Literal lit = Toy_popLiteralArray(&tmp);
|
||||
Toy_pushLiteralArray(&rest, lit);
|
||||
Toy_freeLiteral(lit);
|
||||
}
|
||||
|
||||
freeLiteralArray(&tmp);
|
||||
Toy_freeLiteralArray(&tmp);
|
||||
|
||||
|
||||
//get the runner object
|
||||
Literal varName = popLiteralArray(arguments);
|
||||
Literal runnerLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal varName = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal varNameIdn = varName;
|
||||
if (IS_IDENTIFIER(varName) && parseIdentifierToValue(interpreter, &varName)) {
|
||||
freeLiteral(varNameIdn);
|
||||
Toy_Literal varNameIdn = varName;
|
||||
if (TOY_IS_IDENTIFIER(varName) && Toy_parseIdentifierToValue(interpreter, &varName)) {
|
||||
Toy_freeLiteral(varNameIdn);
|
||||
}
|
||||
|
||||
Literal runnerIdn = runnerLiteral;
|
||||
if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
freeLiteral(runnerIdn);
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) {
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in _runScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Runner* runner = AS_OPAQUE(runnerLiteral);
|
||||
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");
|
||||
freeLiteral(runnerLiteral);
|
||||
freeLiteralArray(&rest);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteralArray(&rest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the desired variable
|
||||
Literal varIdn = TO_IDENTIFIER_LITERAL(copyRefString(AS_STRING(varName)));
|
||||
Literal fn = TO_NULL_LITERAL;
|
||||
getScopeVariable(runner->interpreter.scope, varIdn, &fn);
|
||||
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 (!IS_FUNCTION(fn)) {
|
||||
if (!TOY_IS_FUNCTION(fn)) {
|
||||
interpreter->errorOutput("Can't run a non-function literal\n");
|
||||
freeLiteral(fn);
|
||||
freeLiteral(varIdn);
|
||||
freeLiteral(varName);
|
||||
freeLiteral(runnerLiteral);
|
||||
freeLiteralArray(&rest);
|
||||
Toy_freeLiteral(fn);
|
||||
Toy_freeLiteral(varIdn);
|
||||
Toy_freeLiteral(varName);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteralArray(&rest);
|
||||
}
|
||||
|
||||
//call
|
||||
LiteralArray resultArray;
|
||||
initLiteralArray(&resultArray);
|
||||
Toy_LiteralArray resultArray;
|
||||
Toy_initLiteralArray(&resultArray);
|
||||
|
||||
callLiteralFn(interpreter, fn, &rest, &resultArray);
|
||||
Toy_callLiteralFn(interpreter, fn, &rest, &resultArray);
|
||||
|
||||
Literal result = TO_NULL_LITERAL;
|
||||
Toy_Literal result = TOY_TO_NULL_LITERAL;
|
||||
if (resultArray.count > 0) {
|
||||
result = popLiteralArray(&resultArray);
|
||||
result = Toy_popLiteralArray(&resultArray);
|
||||
}
|
||||
|
||||
pushLiteralArray(&interpreter->stack, result);
|
||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
||||
|
||||
//cleanup
|
||||
freeLiteralArray(&resultArray);
|
||||
freeLiteral(result);
|
||||
freeLiteral(fn);
|
||||
freeLiteral(varIdn);
|
||||
freeLiteral(varName);
|
||||
freeLiteral(runnerLiteral);
|
||||
freeLiteralArray(&rest);
|
||||
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(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeResetScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _resetScript\n");
|
||||
@@ -430,35 +430,35 @@ static int nativeResetScript(Interpreter* interpreter, LiteralArray* arguments)
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Literal runnerLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal runnerIdn = runnerLiteral;
|
||||
if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
freeLiteral(runnerIdn);
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) {
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in _runScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Runner* runner = AS_OPAQUE(runnerLiteral);
|
||||
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");
|
||||
freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
resetInterpreter(&runner->interpreter);
|
||||
Toy_resetInterpreter(&runner->interpreter);
|
||||
runner->dirty = false;
|
||||
freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nativeFreeScript(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeFreeScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _freeScript\n");
|
||||
@@ -466,33 +466,33 @@ static int nativeFreeScript(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Literal runnerLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal runnerIdn = runnerLiteral;
|
||||
if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
freeLiteral(runnerIdn);
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) {
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in _freeScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Runner* runner = AS_OPAQUE(runnerLiteral);
|
||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
||||
|
||||
//clear out the runner object
|
||||
runner->interpreter.hooks = NULL;
|
||||
freeInterpreter(&runner->interpreter);
|
||||
FREE_ARRAY(unsigned char, runner->bytecode, runner->size);
|
||||
Toy_freeInterpreter(&runner->interpreter);
|
||||
TOY_FREE_ARRAY(unsigned char, runner->bytecode, runner->size);
|
||||
|
||||
FREE(Runner, runner);
|
||||
TOY_FREE(Toy_Runner, runner);
|
||||
|
||||
freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nativeCheckScriptDirty(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeCheckScriptDirty(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _runScript\n");
|
||||
@@ -500,28 +500,28 @@ static int nativeCheckScriptDirty(Interpreter* interpreter, LiteralArray* argume
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Literal runnerLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal runnerIdn = runnerLiteral;
|
||||
if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
freeLiteral(runnerIdn);
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) {
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in _runScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Runner* runner = AS_OPAQUE(runnerLiteral);
|
||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
||||
|
||||
//run
|
||||
Literal result = TO_BOOLEAN_LITERAL(runner->dirty);
|
||||
Toy_Literal result = TOY_TO_BOOLEAN_LITERAL(runner->dirty);
|
||||
|
||||
pushLiteralArray(&interpreter->stack, result);
|
||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(result);
|
||||
freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteral(result);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -529,10 +529,10 @@ static int nativeCheckScriptDirty(Interpreter* interpreter, LiteralArray* argume
|
||||
//call the hook
|
||||
typedef struct Natives {
|
||||
char* name;
|
||||
NativeFn fn;
|
||||
Toy_NativeFn fn;
|
||||
} Natives;
|
||||
|
||||
int hookRunner(Interpreter* interpreter, Literal identifier, Literal alias) {
|
||||
int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
||||
//build the natives list
|
||||
Natives natives[] = {
|
||||
{"loadScript", nativeLoadScript},
|
||||
@@ -547,67 +547,67 @@ int hookRunner(Interpreter* interpreter, Literal identifier, Literal alias) {
|
||||
};
|
||||
|
||||
//store the library in an aliased dictionary
|
||||
if (!IS_NULL(alias)) {
|
||||
if (!TOY_IS_NULL(alias)) {
|
||||
//make sure the name isn't taken
|
||||
if (isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
freeLiteral(alias);
|
||||
Toy_freeLiteral(alias);
|
||||
return false;
|
||||
}
|
||||
|
||||
//create the dictionary to load up with functions
|
||||
LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1);
|
||||
initLiteralDictionary(dictionary);
|
||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
||||
Toy_initLiteralDictionary(dictionary);
|
||||
|
||||
//load the dict with functions
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Literal name = TO_STRING_LITERAL(createRefString(natives[i].name));
|
||||
Literal func = TO_FUNCTION_LITERAL((void*)natives[i].fn, 0);
|
||||
func.type = LITERAL_FUNCTION_NATIVE;
|
||||
Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
|
||||
Toy_Literal func = TOY_TO_FUNCTION_LITERAL((void*)natives[i].fn, 0);
|
||||
func.type = TOY_LITERAL_FUNCTION_NATIVE;
|
||||
|
||||
setLiteralDictionary(dictionary, name, func);
|
||||
Toy_setLiteralDictionary(dictionary, name, func);
|
||||
|
||||
freeLiteral(name);
|
||||
freeLiteral(func);
|
||||
Toy_freeLiteral(name);
|
||||
Toy_freeLiteral(func);
|
||||
}
|
||||
|
||||
//build the type
|
||||
Literal type = TO_TYPE_LITERAL(LITERAL_DICTIONARY, true);
|
||||
Literal strType = TO_TYPE_LITERAL(LITERAL_STRING, true);
|
||||
Literal fnType = TO_TYPE_LITERAL(LITERAL_FUNCTION_NATIVE, true);
|
||||
TYPE_PUSH_SUBTYPE(&type, strType);
|
||||
TYPE_PUSH_SUBTYPE(&type, fnType);
|
||||
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
|
||||
Literal dict = TO_DICTIONARY_LITERAL(dictionary);
|
||||
declareScopeVariable(interpreter->scope, alias, type);
|
||||
setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
|
||||
Toy_declareScopeVariable(interpreter->scope, alias, type);
|
||||
Toy_setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(dict);
|
||||
freeLiteral(type);
|
||||
Toy_freeLiteral(dict);
|
||||
Toy_freeLiteral(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//default
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//file system API
|
||||
static LiteralDictionary driveDictionary;
|
||||
static Toy_LiteralDictionary Toy_driveDictionary;
|
||||
|
||||
void initDriveDictionary() {
|
||||
initLiteralDictionary(&driveDictionary);
|
||||
void Toy_initDriveDictionary() {
|
||||
Toy_initLiteralDictionary(&Toy_driveDictionary);
|
||||
}
|
||||
|
||||
void freeDriveDictionary() {
|
||||
freeLiteralDictionary(&driveDictionary);
|
||||
void Toy_freeDriveDictionary() {
|
||||
Toy_freeLiteralDictionary(&Toy_driveDictionary);
|
||||
}
|
||||
|
||||
LiteralDictionary* getDriveDictionary() {
|
||||
return &driveDictionary;
|
||||
Toy_LiteralDictionary* Toy_getDriveDictionary() {
|
||||
return &Toy_driveDictionary;
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "interpreter.h"
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int hookRunner(Interpreter* interpreter, Literal identifier, Literal alias);
|
||||
int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
|
||||
//file system API - these need to be set by the host
|
||||
void initDriveDictionary();
|
||||
void freeDriveDictionary();
|
||||
LiteralDictionary* getDriveDictionary();
|
||||
void Toy_initDriveDictionary();
|
||||
void Toy_freeDriveDictionary();
|
||||
Toy_LiteralDictionary* Toy_getDriveDictionary();
|
||||
|
||||
#define OPAQUE_TAG_RUNNER 100
|
||||
#define TOY_OPAQUE_TAG_RUNNER 100
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "lib_standard.h"
|
||||
|
||||
#include "memory.h"
|
||||
#include "toy_memory.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static int nativeClock(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeClock(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 0) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to clock\n");
|
||||
@@ -19,13 +19,13 @@ static int nativeClock(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
|
||||
//push to the stack
|
||||
int len = strlen(timestr) - 1; //-1 for the newline
|
||||
Literal timeLiteral = TO_STRING_LITERAL(createRefStringLength(timestr, len));
|
||||
Toy_Literal timeLiteral = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(timestr, len));
|
||||
|
||||
//push to the stack
|
||||
pushLiteralArray(&interpreter->stack, timeLiteral);
|
||||
Toy_pushLiteralArray(&interpreter->stack, timeLiteral);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -33,10 +33,10 @@ static int nativeClock(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
//call the hook
|
||||
typedef struct Natives {
|
||||
char* name;
|
||||
NativeFn fn;
|
||||
Toy_NativeFn fn;
|
||||
} Natives;
|
||||
|
||||
int hookStandard(Interpreter* interpreter, Literal identifier, Literal alias) {
|
||||
int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
||||
//build the natives list
|
||||
Natives natives[] = {
|
||||
{"clock", nativeClock},
|
||||
@@ -44,51 +44,51 @@ int hookStandard(Interpreter* interpreter, Literal identifier, Literal alias) {
|
||||
};
|
||||
|
||||
//store the library in an aliased dictionary
|
||||
if (!IS_NULL(alias)) {
|
||||
if (!TOY_IS_NULL(alias)) {
|
||||
//make sure the name isn't taken
|
||||
if (isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
freeLiteral(alias);
|
||||
Toy_freeLiteral(alias);
|
||||
return false;
|
||||
}
|
||||
|
||||
//create the dictionary to load up with functions
|
||||
LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1);
|
||||
initLiteralDictionary(dictionary);
|
||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
||||
Toy_initLiteralDictionary(dictionary);
|
||||
|
||||
//load the dict with functions
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Literal name = TO_STRING_LITERAL(createRefString(natives[i].name));
|
||||
Literal func = TO_FUNCTION_LITERAL((void*)natives[i].fn, 0);
|
||||
func.type = LITERAL_FUNCTION_NATIVE;
|
||||
Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
|
||||
Toy_Literal func = TOY_TO_FUNCTION_LITERAL((void*)natives[i].fn, 0);
|
||||
func.type = TOY_LITERAL_FUNCTION_NATIVE;
|
||||
|
||||
setLiteralDictionary(dictionary, name, func);
|
||||
Toy_setLiteralDictionary(dictionary, name, func);
|
||||
|
||||
freeLiteral(name);
|
||||
freeLiteral(func);
|
||||
Toy_freeLiteral(name);
|
||||
Toy_freeLiteral(func);
|
||||
}
|
||||
|
||||
//build the type
|
||||
Literal type = TO_TYPE_LITERAL(LITERAL_DICTIONARY, true);
|
||||
Literal strType = TO_TYPE_LITERAL(LITERAL_STRING, true);
|
||||
Literal fnType = TO_TYPE_LITERAL(LITERAL_FUNCTION_NATIVE, true);
|
||||
TYPE_PUSH_SUBTYPE(&type, strType);
|
||||
TYPE_PUSH_SUBTYPE(&type, fnType);
|
||||
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
|
||||
Literal dict = TO_DICTIONARY_LITERAL(dictionary);
|
||||
declareScopeVariable(interpreter->scope, alias, type);
|
||||
setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
|
||||
Toy_declareScopeVariable(interpreter->scope, alias, type);
|
||||
Toy_setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(dict);
|
||||
freeLiteral(type);
|
||||
Toy_freeLiteral(dict);
|
||||
Toy_freeLiteral(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//default
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "interpreter.h"
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int hookStandard(Interpreter* interpreter, Literal identifier, Literal alias);
|
||||
int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
|
||||
|
||||
268
repl/lib_timer.c
268
repl/lib_timer.c
@@ -1,13 +1,13 @@
|
||||
#include "lib_timer.h"
|
||||
|
||||
#include "memory.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
|
||||
int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) {
|
||||
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;
|
||||
@@ -34,7 +34,7 @@ int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *
|
||||
|
||||
//god damn it
|
||||
static struct timeval* diff(struct timeval* lhs, struct timeval* rhs) {
|
||||
struct timeval* d = ALLOCATE(struct timeval, 1);
|
||||
struct timeval* d = TOY_ALLOCATE(struct timeval, 1);
|
||||
|
||||
//I gave up, copied from SO
|
||||
timeval_subtract(d, rhs, lhs);
|
||||
@@ -43,7 +43,7 @@ static struct timeval* diff(struct timeval* lhs, struct timeval* rhs) {
|
||||
}
|
||||
|
||||
//callbacks
|
||||
static int nativeStartTimer(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeStartTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 0) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to startTimer\n");
|
||||
@@ -51,19 +51,19 @@ static int nativeStartTimer(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
}
|
||||
|
||||
//get the timeinfo from C
|
||||
struct timeval* timeinfo = ALLOCATE(struct timeval, 1);
|
||||
struct timeval* timeinfo = TOY_ALLOCATE(struct timeval, 1);
|
||||
gettimeofday(timeinfo, NULL);
|
||||
|
||||
//wrap in an opaque literal for Toy
|
||||
Literal timeLiteral = TO_OPAQUE_LITERAL(timeinfo, -1);
|
||||
pushLiteralArray(&interpreter->stack, timeLiteral);
|
||||
Toy_Literal timeLiteral = TOY_TO_OPAQUE_LITERAL(timeinfo, -1);
|
||||
Toy_pushLiteralArray(&interpreter->stack, timeLiteral);
|
||||
|
||||
freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeStopTimer(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeStopTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _stopTimer\n");
|
||||
@@ -75,34 +75,34 @@ static int nativeStopTimer(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
gettimeofday(&timerStop, NULL);
|
||||
|
||||
//unwrap the opaque literal
|
||||
Literal timeLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal timeLiteralIdn = timeLiteral;
|
||||
if (IS_IDENTIFIER(timeLiteral) && parseIdentifierToValue(interpreter, &timeLiteral)) {
|
||||
freeLiteral(timeLiteralIdn);
|
||||
Toy_Literal timeLiteralIdn = timeLiteral;
|
||||
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
|
||||
Toy_freeLiteral(timeLiteralIdn);
|
||||
}
|
||||
|
||||
if (!IS_OPAQUE(timeLiteral)) {
|
||||
if (!TOY_IS_OPAQUE(timeLiteral)) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to _stopTimer\n");
|
||||
freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct timeval* timerStart = AS_OPAQUE(timeLiteral);
|
||||
struct timeval* timerStart = TOY_AS_OPAQUE(timeLiteral);
|
||||
|
||||
//determine the difference, and wrap it
|
||||
struct timeval* d = diff(timerStart, &timerStop);
|
||||
Literal diffLiteral = TO_OPAQUE_LITERAL(d, -1);
|
||||
pushLiteralArray(&interpreter->stack, diffLiteral);
|
||||
Toy_Literal diffLiteral = TOY_TO_OPAQUE_LITERAL(d, -1);
|
||||
Toy_pushLiteralArray(&interpreter->stack, diffLiteral);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(timeLiteral);
|
||||
freeLiteral(diffLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(diffLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeCreateTimer(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeCreateTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 2) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to createTimer\n");
|
||||
@@ -110,50 +110,50 @@ static int nativeCreateTimer(Interpreter* interpreter, LiteralArray* arguments)
|
||||
}
|
||||
|
||||
//get the args
|
||||
Literal microsecondLiteral = popLiteralArray(arguments);
|
||||
Literal secondLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal microsecondLiteral = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal secondLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal secondLiteralIdn = secondLiteral;
|
||||
if (IS_IDENTIFIER(secondLiteral) && parseIdentifierToValue(interpreter, &secondLiteral)) {
|
||||
freeLiteral(secondLiteralIdn);
|
||||
Toy_Literal secondLiteralIdn = secondLiteral;
|
||||
if (TOY_IS_IDENTIFIER(secondLiteral) && Toy_parseIdentifierToValue(interpreter, &secondLiteral)) {
|
||||
Toy_freeLiteral(secondLiteralIdn);
|
||||
}
|
||||
|
||||
Literal microsecondLiteralIdn = microsecondLiteral;
|
||||
if (IS_IDENTIFIER(microsecondLiteral) && parseIdentifierToValue(interpreter, µsecondLiteral)) {
|
||||
freeLiteral(microsecondLiteralIdn);
|
||||
Toy_Literal microsecondLiteralIdn = microsecondLiteral;
|
||||
if (TOY_IS_IDENTIFIER(microsecondLiteral) && Toy_parseIdentifierToValue(interpreter, µsecondLiteral)) {
|
||||
Toy_freeLiteral(microsecondLiteralIdn);
|
||||
}
|
||||
|
||||
if (!IS_INTEGER(secondLiteral) || !IS_INTEGER(microsecondLiteral)) {
|
||||
if (!TOY_IS_INTEGER(secondLiteral) || !TOY_IS_INTEGER(microsecondLiteral)) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to createTimer\n");
|
||||
freeLiteral(secondLiteral);
|
||||
freeLiteral(microsecondLiteral);
|
||||
Toy_freeLiteral(secondLiteral);
|
||||
Toy_freeLiteral(microsecondLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (AS_INTEGER(microsecondLiteral) <= -1000 * 1000 || AS_INTEGER(microsecondLiteral) >= 1000 * 1000 || (AS_INTEGER(secondLiteral) != 0 && AS_INTEGER(microsecondLiteral) < 0) ) {
|
||||
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");
|
||||
freeLiteral(secondLiteral);
|
||||
freeLiteral(microsecondLiteral);
|
||||
Toy_freeLiteral(secondLiteral);
|
||||
Toy_freeLiteral(microsecondLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the timeinfo from toy
|
||||
struct timeval* timeinfo = ALLOCATE(struct timeval, 1);
|
||||
timeinfo->tv_sec = AS_INTEGER(secondLiteral);
|
||||
timeinfo->tv_usec = AS_INTEGER(microsecondLiteral);
|
||||
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
|
||||
Literal timeLiteral = TO_OPAQUE_LITERAL(timeinfo, -1);
|
||||
pushLiteralArray(&interpreter->stack, timeLiteral);
|
||||
Toy_Literal timeLiteral = TOY_TO_OPAQUE_LITERAL(timeinfo, -1);
|
||||
Toy_pushLiteralArray(&interpreter->stack, timeLiteral);
|
||||
|
||||
freeLiteral(timeLiteral);
|
||||
freeLiteral(secondLiteral);
|
||||
freeLiteral(microsecondLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(secondLiteral);
|
||||
Toy_freeLiteral(microsecondLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeGetTimerSeconds(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeGetTimerSeconds(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _getTimerSeconds\n");
|
||||
@@ -161,33 +161,33 @@ static int nativeGetTimerSeconds(Interpreter* interpreter, LiteralArray* argumen
|
||||
}
|
||||
|
||||
//unwrap the opaque literal
|
||||
Literal timeLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal timeLiteralIdn = timeLiteral;
|
||||
if (IS_IDENTIFIER(timeLiteral) && parseIdentifierToValue(interpreter, &timeLiteral)) {
|
||||
freeLiteral(timeLiteralIdn);
|
||||
Toy_Literal timeLiteralIdn = timeLiteral;
|
||||
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
|
||||
Toy_freeLiteral(timeLiteralIdn);
|
||||
}
|
||||
|
||||
if (!IS_OPAQUE(timeLiteral)) {
|
||||
if (!TOY_IS_OPAQUE(timeLiteral)) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to _getTimerSeconds\n");
|
||||
freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct timeval* timer = AS_OPAQUE(timeLiteral);
|
||||
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
|
||||
|
||||
//create the result literal
|
||||
Literal result = TO_INTEGER_LITERAL(timer->tv_sec);
|
||||
pushLiteralArray(&interpreter->stack, result);
|
||||
Toy_Literal result = TOY_TO_INTEGER_LITERAL(timer->tv_sec);
|
||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(timeLiteral);
|
||||
freeLiteral(result);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(result);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeGetTimerMicroseconds(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeGetTimerMicroseconds(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _getTimerMicroseconds\n");
|
||||
@@ -195,33 +195,33 @@ static int nativeGetTimerMicroseconds(Interpreter* interpreter, LiteralArray* ar
|
||||
}
|
||||
|
||||
//unwrap the opaque literal
|
||||
Literal timeLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal timeLiteralIdn = timeLiteral;
|
||||
if (IS_IDENTIFIER(timeLiteral) && parseIdentifierToValue(interpreter, &timeLiteral)) {
|
||||
freeLiteral(timeLiteralIdn);
|
||||
Toy_Literal timeLiteralIdn = timeLiteral;
|
||||
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
|
||||
Toy_freeLiteral(timeLiteralIdn);
|
||||
}
|
||||
|
||||
if (!IS_OPAQUE(timeLiteral)) {
|
||||
if (!TOY_IS_OPAQUE(timeLiteral)) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to _getTimerMicroseconds\n");
|
||||
freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct timeval* timer = AS_OPAQUE(timeLiteral);
|
||||
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
|
||||
|
||||
//create the result literal
|
||||
Literal result = TO_INTEGER_LITERAL(timer->tv_usec);
|
||||
pushLiteralArray(&interpreter->stack, result);
|
||||
Toy_Literal result = TOY_TO_INTEGER_LITERAL(timer->tv_usec);
|
||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(timeLiteral);
|
||||
freeLiteral(result);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(result);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeCompareTimer(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeCompareTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 2) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _compareTimer\n");
|
||||
@@ -229,43 +229,43 @@ static int nativeCompareTimer(Interpreter* interpreter, LiteralArray* arguments)
|
||||
}
|
||||
|
||||
//unwrap the opaque literals
|
||||
Literal rhsLiteral = popLiteralArray(arguments);
|
||||
Literal lhsLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal rhsLiteral = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal lhsLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal lhsLiteralIdn = lhsLiteral;
|
||||
if (IS_IDENTIFIER(lhsLiteral) && parseIdentifierToValue(interpreter, &lhsLiteral)) {
|
||||
freeLiteral(lhsLiteralIdn);
|
||||
Toy_Literal lhsLiteralIdn = lhsLiteral;
|
||||
if (TOY_IS_IDENTIFIER(lhsLiteral) && Toy_parseIdentifierToValue(interpreter, &lhsLiteral)) {
|
||||
Toy_freeLiteral(lhsLiteralIdn);
|
||||
}
|
||||
|
||||
Literal rhsLiteralIdn = rhsLiteral;
|
||||
if (IS_IDENTIFIER(rhsLiteral) && parseIdentifierToValue(interpreter, &rhsLiteral)) {
|
||||
freeLiteral(rhsLiteralIdn);
|
||||
Toy_Literal rhsLiteralIdn = rhsLiteral;
|
||||
if (TOY_IS_IDENTIFIER(rhsLiteral) && Toy_parseIdentifierToValue(interpreter, &rhsLiteral)) {
|
||||
Toy_freeLiteral(rhsLiteralIdn);
|
||||
}
|
||||
|
||||
if (!IS_OPAQUE(lhsLiteral) || !IS_OPAQUE(rhsLiteral)) {
|
||||
if (!TOY_IS_OPAQUE(lhsLiteral) || !TOY_IS_OPAQUE(rhsLiteral)) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to _compareTimer\n");
|
||||
freeLiteral(lhsLiteral);
|
||||
freeLiteral(rhsLiteral);
|
||||
Toy_freeLiteral(lhsLiteral);
|
||||
Toy_freeLiteral(rhsLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct timeval* lhsTimer = AS_OPAQUE(lhsLiteral);
|
||||
struct timeval* rhsTimer = AS_OPAQUE(rhsLiteral);
|
||||
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);
|
||||
Literal diffLiteral = TO_OPAQUE_LITERAL(d, -1);
|
||||
pushLiteralArray(&interpreter->stack, diffLiteral);
|
||||
Toy_Literal diffLiteral = TOY_TO_OPAQUE_LITERAL(d, -1);
|
||||
Toy_pushLiteralArray(&interpreter->stack, diffLiteral);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(lhsLiteral);
|
||||
freeLiteral(rhsLiteral);
|
||||
freeLiteral(diffLiteral);
|
||||
Toy_freeLiteral(lhsLiteral);
|
||||
Toy_freeLiteral(rhsLiteral);
|
||||
Toy_freeLiteral(diffLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeTimerToString(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeTimerToString(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _timerToString\n");
|
||||
@@ -273,44 +273,44 @@ static int nativeTimerToString(Interpreter* interpreter, LiteralArray* arguments
|
||||
}
|
||||
|
||||
//unwrap in an opaque literal
|
||||
Literal timeLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal timeLiteralIdn = timeLiteral;
|
||||
if (IS_IDENTIFIER(timeLiteral) && parseIdentifierToValue(interpreter, &timeLiteral)) {
|
||||
freeLiteral(timeLiteralIdn);
|
||||
Toy_Literal timeLiteralIdn = timeLiteral;
|
||||
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
|
||||
Toy_freeLiteral(timeLiteralIdn);
|
||||
}
|
||||
|
||||
if (!IS_OPAQUE(timeLiteral)) {
|
||||
if (!TOY_IS_OPAQUE(timeLiteral)) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to _timerToString\n");
|
||||
freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct timeval* timer = AS_OPAQUE(timeLiteral);
|
||||
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
|
||||
|
||||
//create the string literal
|
||||
Literal resultLiteral = TO_NULL_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 = TO_STRING_LITERAL(createRefStringLength(buffer, strlen(buffer)));
|
||||
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 = TO_STRING_LITERAL(createRefStringLength(buffer, strlen(buffer)));
|
||||
resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, strlen(buffer)));
|
||||
}
|
||||
|
||||
pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(timeLiteral);
|
||||
freeLiteral(resultLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(resultLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeDestroyTimer(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
static int nativeDestroyTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to _destroyTimer\n");
|
||||
@@ -318,24 +318,24 @@ static int nativeDestroyTimer(Interpreter* interpreter, LiteralArray* arguments)
|
||||
}
|
||||
|
||||
//unwrap in an opaque literal
|
||||
Literal timeLiteral = popLiteralArray(arguments);
|
||||
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Literal timeLiteralIdn = timeLiteral;
|
||||
if (IS_IDENTIFIER(timeLiteral) && parseIdentifierToValue(interpreter, &timeLiteral)) {
|
||||
freeLiteral(timeLiteralIdn);
|
||||
Toy_Literal timeLiteralIdn = timeLiteral;
|
||||
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
|
||||
Toy_freeLiteral(timeLiteralIdn);
|
||||
}
|
||||
|
||||
if (!IS_OPAQUE(timeLiteral)) {
|
||||
if (!TOY_IS_OPAQUE(timeLiteral)) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to _destroyTimer\n");
|
||||
freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct timeval* timer = AS_OPAQUE(timeLiteral);
|
||||
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
|
||||
|
||||
FREE(struct timeval, timer);
|
||||
TOY_FREE(struct timeval, timer);
|
||||
|
||||
freeLiteral(timeLiteral);
|
||||
Toy_freeLiteral(timeLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -343,10 +343,10 @@ static int nativeDestroyTimer(Interpreter* interpreter, LiteralArray* arguments)
|
||||
//call the hook
|
||||
typedef struct Natives {
|
||||
char* name;
|
||||
NativeFn fn;
|
||||
Toy_NativeFn fn;
|
||||
} Natives;
|
||||
|
||||
int hookTimer(Interpreter* interpreter, Literal identifier, Literal alias) {
|
||||
int Toy_hookTimer(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
||||
//build the natives list
|
||||
Natives natives[] = {
|
||||
{"startTimer", nativeStartTimer},
|
||||
@@ -361,51 +361,51 @@ int hookTimer(Interpreter* interpreter, Literal identifier, Literal alias) {
|
||||
};
|
||||
|
||||
//store the library in an aliased dictionary
|
||||
if (!IS_NULL(alias)) {
|
||||
if (!TOY_IS_NULL(alias)) {
|
||||
//make sure the name isn't taken
|
||||
if (isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
freeLiteral(alias);
|
||||
Toy_freeLiteral(alias);
|
||||
return false;
|
||||
}
|
||||
|
||||
//create the dictionary to load up with functions
|
||||
LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1);
|
||||
initLiteralDictionary(dictionary);
|
||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
||||
Toy_initLiteralDictionary(dictionary);
|
||||
|
||||
//load the dict with functions
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Literal name = TO_STRING_LITERAL(createRefString(natives[i].name));
|
||||
Literal func = TO_FUNCTION_LITERAL((void*)natives[i].fn, 0);
|
||||
func.type = LITERAL_FUNCTION_NATIVE;
|
||||
Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
|
||||
Toy_Literal func = TOY_TO_FUNCTION_LITERAL((void*)natives[i].fn, 0);
|
||||
func.type = TOY_LITERAL_FUNCTION_NATIVE;
|
||||
|
||||
setLiteralDictionary(dictionary, name, func);
|
||||
Toy_setLiteralDictionary(dictionary, name, func);
|
||||
|
||||
freeLiteral(name);
|
||||
freeLiteral(func);
|
||||
Toy_freeLiteral(name);
|
||||
Toy_freeLiteral(func);
|
||||
}
|
||||
|
||||
//build the type
|
||||
Literal type = TO_TYPE_LITERAL(LITERAL_DICTIONARY, true);
|
||||
Literal strType = TO_TYPE_LITERAL(LITERAL_STRING, true);
|
||||
Literal fnType = TO_TYPE_LITERAL(LITERAL_FUNCTION_NATIVE, true);
|
||||
TYPE_PUSH_SUBTYPE(&type, strType);
|
||||
TYPE_PUSH_SUBTYPE(&type, fnType);
|
||||
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
|
||||
Literal dict = TO_DICTIONARY_LITERAL(dictionary);
|
||||
declareScopeVariable(interpreter->scope, alias, type);
|
||||
setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
|
||||
Toy_declareScopeVariable(interpreter->scope, alias, type);
|
||||
Toy_setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
|
||||
//cleanup
|
||||
freeLiteral(dict);
|
||||
freeLiteral(type);
|
||||
Toy_freeLiteral(dict);
|
||||
Toy_freeLiteral(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//default
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "interpreter.h"
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int hookTimer(Interpreter* interpreter, Literal identifier, Literal alias);
|
||||
int Toy_hookTimer(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
#include "lib_timer.h"
|
||||
#include "lib_runner.h"
|
||||
|
||||
#include "console_colors.h"
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
#include "lexer.h"
|
||||
#include "parser.h"
|
||||
#include "compiler.h"
|
||||
#include "interpreter.h"
|
||||
#include "toy_lexer.h"
|
||||
#include "toy_parser.h"
|
||||
#include "toy_compiler.h"
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -22,13 +22,13 @@ void repl() {
|
||||
char input[size];
|
||||
memset(input, 0, size);
|
||||
|
||||
Interpreter interpreter; //persist the interpreter for the scopes
|
||||
initInterpreter(&interpreter);
|
||||
Toy_Interpreter interpreter; //persist the interpreter for the scopes
|
||||
Toy_initInterpreter(&interpreter);
|
||||
|
||||
//inject the libs
|
||||
injectNativeHook(&interpreter, "standard", hookStandard);
|
||||
injectNativeHook(&interpreter, "timer", hookTimer);
|
||||
injectNativeHook(&interpreter, "runner", hookRunner);
|
||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||
Toy_injectNativeHook(&interpreter, "timer", Toy_hookTimer);
|
||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
||||
|
||||
for(;;) {
|
||||
printf("> ");
|
||||
@@ -44,100 +44,100 @@ void repl() {
|
||||
}
|
||||
|
||||
//setup this iteration
|
||||
Lexer lexer;
|
||||
Parser parser;
|
||||
Compiler compiler;
|
||||
Toy_Lexer lexer;
|
||||
Toy_Parser parser;
|
||||
Toy_Compiler compiler;
|
||||
|
||||
initLexer(&lexer, input);
|
||||
initParser(&parser, &lexer);
|
||||
initCompiler(&compiler);
|
||||
Toy_initLexer(&lexer, input);
|
||||
Toy_initParser(&parser, &lexer);
|
||||
Toy_initCompiler(&compiler);
|
||||
|
||||
//run this iteration
|
||||
ASTNode* node = scanParser(&parser);
|
||||
Toy_ASTNode* node = Toy_scanParser(&parser);
|
||||
while(node != NULL) {
|
||||
//pack up and restart
|
||||
if (node->type == AST_NODE_ERROR) {
|
||||
printf(ERROR "error node detected\n" RESET);
|
||||
if (node->type == TOY_AST_NODE_ERROR) {
|
||||
printf(TOY_CC_ERROR "error node detected\n" TOY_CC_RESET);
|
||||
error = true;
|
||||
freeASTNode(node);
|
||||
Toy_freeASTNode(node);
|
||||
break;
|
||||
}
|
||||
|
||||
writeCompiler(&compiler, node);
|
||||
freeASTNode(node);
|
||||
node = scanParser(&parser);
|
||||
Toy_writeCompiler(&compiler, node);
|
||||
Toy_freeASTNode(node);
|
||||
node = Toy_scanParser(&parser);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
//get the bytecode dump
|
||||
int size = 0;
|
||||
unsigned char* tb = collateCompiler(&compiler, &size);
|
||||
unsigned char* tb = Toy_collateCompiler(&compiler, &size);
|
||||
|
||||
//run the bytecode
|
||||
runInterpreter(&interpreter, tb, size);
|
||||
Toy_runInterpreter(&interpreter, tb, size);
|
||||
}
|
||||
|
||||
//clean up this iteration
|
||||
freeCompiler(&compiler);
|
||||
freeParser(&parser);
|
||||
Toy_freeCompiler(&compiler);
|
||||
Toy_freeParser(&parser);
|
||||
error = false;
|
||||
}
|
||||
|
||||
freeInterpreter(&interpreter);
|
||||
Toy_freeInterpreter(&interpreter);
|
||||
}
|
||||
|
||||
//entry point
|
||||
int main(int argc, const char* argv[]) {
|
||||
initCommand(argc, argv);
|
||||
Toy_initCommand(argc, argv);
|
||||
|
||||
//lib setup (hacky - only really for this program)
|
||||
initDriveDictionary();
|
||||
Toy_initDriveDictionary();
|
||||
|
||||
Literal driveLiteral = TO_STRING_LITERAL(createRefString("scripts"));
|
||||
Literal pathLiteral = TO_STRING_LITERAL(createRefString("scripts"));
|
||||
Toy_Literal driveLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("scripts"));
|
||||
Toy_Literal pathLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("scripts"));
|
||||
|
||||
setLiteralDictionary(getDriveDictionary(), driveLiteral, pathLiteral);
|
||||
Toy_setLiteralDictionary(Toy_getDriveDictionary(), driveLiteral, pathLiteral);
|
||||
|
||||
freeLiteral(driveLiteral);
|
||||
freeLiteral(pathLiteral);
|
||||
Toy_freeLiteral(driveLiteral);
|
||||
Toy_freeLiteral(pathLiteral);
|
||||
|
||||
//command specific actions
|
||||
if (command.error) {
|
||||
usageCommand(argc, argv);
|
||||
Toy_usageCommand(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (command.help) {
|
||||
helpCommand(argc, argv);
|
||||
Toy_helpCommand(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (command.version) {
|
||||
copyrightCommand(argc, argv);
|
||||
Toy_copyrightCommand(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//version
|
||||
if (command.verbose) {
|
||||
printf(NOTICE "Toy Programming Language Version %d.%d.%d\n" RESET, TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH);
|
||||
printf(TOY_CC_NOTICE "Toy Programming Language Version %d.%d.%d\n" TOY_CC_RESET, TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH);
|
||||
}
|
||||
|
||||
//run source file
|
||||
if (command.sourcefile) {
|
||||
runSourceFile(command.sourcefile);
|
||||
Toy_runSourceFile(command.sourcefile);
|
||||
|
||||
//lib cleanup
|
||||
freeDriveDictionary();
|
||||
Toy_freeDriveDictionary();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//run from stdin
|
||||
if (command.source) {
|
||||
runSource(command.source);
|
||||
Toy_runSource(command.source);
|
||||
|
||||
//lib cleanup
|
||||
freeDriveDictionary();
|
||||
Toy_freeDriveDictionary();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -145,21 +145,21 @@ int main(int argc, const char* argv[]) {
|
||||
//compile source file
|
||||
if (command.compilefile && command.outfile) {
|
||||
size_t size = 0;
|
||||
char* source = readFile(command.compilefile, &size);
|
||||
unsigned char* tb = compileString(source, &size);
|
||||
char* source = Toy_readFile(command.compilefile, &size);
|
||||
unsigned char* tb = Toy_compileString(source, &size);
|
||||
if (!tb) {
|
||||
return 1;
|
||||
}
|
||||
writeFile(command.outfile, tb, size);
|
||||
Toy_writeFile(command.outfile, tb, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//run binary
|
||||
if (command.binaryfile) {
|
||||
runBinaryFile(command.binaryfile);
|
||||
Toy_runBinaryFile(command.binaryfile);
|
||||
|
||||
//lib cleanup
|
||||
freeDriveDictionary();
|
||||
Toy_freeDriveDictionary();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -167,7 +167,7 @@ int main(int argc, const char* argv[]) {
|
||||
repl();
|
||||
|
||||
//lib cleanup
|
||||
freeDriveDictionary();
|
||||
Toy_freeDriveDictionary();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,22 +3,22 @@
|
||||
#include "lib_timer.h"
|
||||
#include "lib_runner.h"
|
||||
|
||||
#include "console_colors.h"
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
#include "lexer.h"
|
||||
#include "parser.h"
|
||||
#include "compiler.h"
|
||||
#include "interpreter.h"
|
||||
#include "toy_lexer.h"
|
||||
#include "toy_parser.h"
|
||||
#include "toy_compiler.h"
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//IO functions
|
||||
char* readFile(char* path, size_t* fileSize) {
|
||||
char* Toy_readFile(char* path, size_t* fileSize) {
|
||||
FILE* file = fopen(path, "rb");
|
||||
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, ERROR "Could not open file \"%s\"\n" RESET, path);
|
||||
fprintf(stderr, TOY_CC_ERROR "Could not open file \"%s\"\n" TOY_CC_RESET, path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ char* readFile(char* path, size_t* fileSize) {
|
||||
char* buffer = (char*)malloc(*fileSize + 1);
|
||||
|
||||
if (buffer == NULL) {
|
||||
fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path);
|
||||
fprintf(stderr, TOY_CC_ERROR "Not enough memory to read \"%s\"\n" TOY_CC_RESET, path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ char* readFile(char* path, size_t* fileSize) {
|
||||
buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this
|
||||
|
||||
if (bytesRead < *fileSize) {
|
||||
fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path);
|
||||
fprintf(stderr, TOY_CC_ERROR "Could not read file \"%s\"\n" TOY_CC_RESET, path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -47,18 +47,18 @@ char* readFile(char* path, size_t* fileSize) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int writeFile(char* path, unsigned char* bytes, size_t size) {
|
||||
int Toy_writeFile(char* path, unsigned char* bytes, size_t size) {
|
||||
FILE* file = fopen(path, "wb");
|
||||
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, ERROR "Could not open file \"%s\"\n" RESET, path);
|
||||
fprintf(stderr, TOY_CC_ERROR "Could not open file \"%s\"\n" TOY_CC_RESET, path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int written = fwrite(bytes, size, 1, file);
|
||||
|
||||
if (written != 1) {
|
||||
fprintf(stderr, ERROR "Could not write file \"%s\"\n" RESET, path);
|
||||
fprintf(stderr, TOY_CC_ERROR "Could not write file \"%s\"\n" TOY_CC_RESET, path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -68,79 +68,79 @@ int writeFile(char* path, unsigned char* bytes, size_t size) {
|
||||
}
|
||||
|
||||
//repl functions
|
||||
unsigned char* compileString(char* source, size_t* size) {
|
||||
Lexer lexer;
|
||||
Parser parser;
|
||||
Compiler compiler;
|
||||
unsigned char* Toy_compileString(char* source, size_t* size) {
|
||||
Toy_Lexer lexer;
|
||||
Toy_Parser parser;
|
||||
Toy_Compiler compiler;
|
||||
|
||||
initLexer(&lexer, source);
|
||||
initParser(&parser, &lexer);
|
||||
initCompiler(&compiler);
|
||||
Toy_initLexer(&lexer, source);
|
||||
Toy_initParser(&parser, &lexer);
|
||||
Toy_initCompiler(&compiler);
|
||||
|
||||
//run the parser until the end of the source
|
||||
ASTNode* node = scanParser(&parser);
|
||||
Toy_ASTNode* node = Toy_scanParser(&parser);
|
||||
while(node != NULL) {
|
||||
//pack up and leave
|
||||
if (node->type == AST_NODE_ERROR) {
|
||||
freeASTNode(node);
|
||||
freeCompiler(&compiler);
|
||||
freeParser(&parser);
|
||||
if (node->type == TOY_AST_NODE_ERROR) {
|
||||
Toy_freeASTNode(node);
|
||||
Toy_freeCompiler(&compiler);
|
||||
Toy_freeParser(&parser);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
writeCompiler(&compiler, node);
|
||||
freeASTNode(node);
|
||||
node = scanParser(&parser);
|
||||
Toy_writeCompiler(&compiler, node);
|
||||
Toy_freeASTNode(node);
|
||||
node = Toy_scanParser(&parser);
|
||||
}
|
||||
|
||||
//get the bytecode dump
|
||||
unsigned char* tb = collateCompiler(&compiler, (int*)(size));
|
||||
unsigned char* tb = Toy_collateCompiler(&compiler, (int*)(size));
|
||||
|
||||
//cleanup
|
||||
freeCompiler(&compiler);
|
||||
freeParser(&parser);
|
||||
Toy_freeCompiler(&compiler);
|
||||
Toy_freeParser(&parser);
|
||||
//no lexer to clean up
|
||||
|
||||
//finally
|
||||
return tb;
|
||||
}
|
||||
|
||||
void runBinary(unsigned char* tb, size_t size) {
|
||||
Interpreter interpreter;
|
||||
initInterpreter(&interpreter);
|
||||
void Toy_runBinary(unsigned char* tb, size_t size) {
|
||||
Toy_Interpreter interpreter;
|
||||
Toy_initInterpreter(&interpreter);
|
||||
|
||||
//inject the libs
|
||||
injectNativeHook(&interpreter, "standard", hookStandard);
|
||||
injectNativeHook(&interpreter, "timer", hookTimer);
|
||||
injectNativeHook(&interpreter, "runner", hookRunner);
|
||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||
Toy_injectNativeHook(&interpreter, "timer", Toy_hookTimer);
|
||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
||||
|
||||
runInterpreter(&interpreter, tb, size);
|
||||
freeInterpreter(&interpreter);
|
||||
Toy_runInterpreter(&interpreter, tb, size);
|
||||
Toy_freeInterpreter(&interpreter);
|
||||
}
|
||||
|
||||
void runBinaryFile(char* fname) {
|
||||
void Toy_runBinaryFile(char* fname) {
|
||||
size_t size = 0; //not used
|
||||
unsigned char* tb = (unsigned char*)readFile(fname, &size);
|
||||
unsigned char* tb = (unsigned char*)Toy_readFile(fname, &size);
|
||||
if (!tb) {
|
||||
return;
|
||||
}
|
||||
runBinary(tb, size);
|
||||
Toy_runBinary(tb, size);
|
||||
//interpreter takes ownership of the binary data
|
||||
}
|
||||
|
||||
void runSource(char* source) {
|
||||
void Toy_runSource(char* source) {
|
||||
size_t size = 0;
|
||||
unsigned char* tb = compileString(source, &size);
|
||||
unsigned char* tb = Toy_compileString(source, &size);
|
||||
if (!tb) {
|
||||
return;
|
||||
}
|
||||
|
||||
runBinary(tb, size);
|
||||
Toy_runBinary(tb, size);
|
||||
}
|
||||
|
||||
void runSourceFile(char* fname) {
|
||||
void Toy_runSourceFile(char* fname) {
|
||||
size_t size = 0; //not used
|
||||
char* source = readFile(fname, &size);
|
||||
runSource(source);
|
||||
char* source = Toy_readFile(fname, &size);
|
||||
Toy_runSource(source);
|
||||
free((void*)source);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
#include "toy_common.h"
|
||||
|
||||
char* readFile(char* path, size_t* fileSize);
|
||||
int writeFile(char* path, unsigned char* bytes, size_t size);
|
||||
char* Toy_readFile(char* path, size_t* fileSize);
|
||||
int Toy_writeFile(char* path, unsigned char* bytes, size_t size);
|
||||
|
||||
unsigned char* compileString(char* source, size_t* size);
|
||||
unsigned char* Toy_compileString(char* source, size_t* size);
|
||||
|
||||
void runBinary(unsigned char* tb, size_t size);
|
||||
void runBinaryFile(char* fname);
|
||||
void runSource(char* source);
|
||||
void runSourceFile(char* fname);
|
||||
void Toy_runBinary(unsigned char* tb, size_t size);
|
||||
void Toy_runBinaryFile(char* fname);
|
||||
void Toy_runSource(char* source);
|
||||
void Toy_runSourceFile(char* fname);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user