1
0
Fork 0
mirror of https://github.com/suchmememanyskill/TegraExplorer.git synced 2025-02-19 23:15:36 +00:00
TegraExplorer/source/tegraexplorer/script/functions.c
suchmememanyskill ba0ded0f8b start of tsV2
2020-11-06 21:19:29 +01:00

177 lines
No EOL
4.7 KiB
C

#include "functions.h"
#include "list.h"
#include "args.h"
#include "parser.h"
#include "lexer.h"
#include "types.h"
#include "scriptCtx.h"
#include "../../gfx/gfx.h"
#include "../../mem/heap.h"
#include <string.h>
#include "../../hid/hid.h"
dictValue_t funcPrint(scriptCtx_t* ctx, varVector_t* args) {
for (int i = 0; i < args->stored; i++) {
switch (args->vars[i].value.varType) {
case IntType:
gfx_printf("%d", args->vars[i].value.integer);
break;
case StringType:
gfx_printf("%s", args->vars[i].value.string);
break;
}
}
return NullDictValue();
}
dictValue_t funcPrintln(scriptCtx_t* ctx, varVector_t* args) {
funcPrint(ctx, args);
gfx_printf("\n");
return NullDictValue();
}
dictValue_t funcIf(scriptCtx_t* ctx, varVector_t* args) {
if (args->vars[0].value.varType == IntType) {
setCurIndentInstruction(ctx, (args->vars[0].value.integer == 0), -1);
return NullDictValue();
}
return ErrDictValue(ERRINVALIDTYPE);
}
dictValue_t scriptElse(scriptCtx_t* ctx, varVector_t* args) {
indentInstructor_t curInstruction = getCurIndentInstruction(ctx);
setCurIndentInstruction(ctx, !curInstruction.skip, -1);
return NullDictValue();
}
dictValue_t scriptWhile(scriptCtx_t* ctx, varVector_t* args) {
if (args->vars[0].value.varType == IntType) {
setCurIndentInstruction(ctx, (args->vars[0].value.integer == 0), ctx->lastTokenPos);
return NullDictValue();
}
return ErrDictValue(ERRINVALIDTYPE);
}
dictValue_t scriptLen(scriptCtx_t* ctx, varVector_t* args) {
if (args->vars[0].value.varType >= IntArrayType && args->vars[0].value.varType <= ByteArrayType)
return IntDictValue(args->vars[0].value.arrayLen);
else if (args->vars[0].value.varType == StringType) {
if (args->vars[0].value.string != NULL)
return IntDictValue(strlen(args->vars[0].value.string));
}
return ErrDictValue(ERRINVALIDTYPE);
}
dictValue_t scriptMakeByteArray(scriptCtx_t* ctx, varVector_t* args) {
if (args->vars[0].value.varType == IntArrayType) {
u8* buff = calloc(args->vars[0].value.arrayLen, 1);
for (int i = 0; i < args->vars[0].value.arrayLen; i++) {
buff[i] = (u8)(args->vars[0].value.integerArray[i] & 0xFF);
}
return DictValueCreate(ByteArrayType | FREEINDICT, args->vars[0].value.arrayLen, buff);
}
return ErrDictValue(ERRINVALIDTYPE);
}
dictValue_t scriptWait(scriptCtx_t*ctx, varVector_t* args){
Inputs* input = hidWait();
return IntDictValue(input->buttons);
}
dictValue_t scriptSetPixel(scriptCtx_t *ctx, varVector_t* args){
int pixelArgs[5] = {0};
for (int i = 0; i < args->stored; i++){
if (args->vars[i].value.varType != IntType)
return ErrDictValue(ERRINVALIDTYPE);
pixelArgs[i] = args->vars[i].value.integer;
}
u32 color = 0xFF000000 | ((pixelArgs[2] & 0xFF) << 16) | ((pixelArgs[3] & 0xFF) << 8) | ((pixelArgs[4] & 0xFF));
gfx_setPixel(pixelArgs[0], pixelArgs[1], color);
return NullDictValue();
}
const static str_fnc_struct functions[] = {
{"print", funcPrint, {0x40}},
{"println", funcPrintln, {0x40}},
{"if", funcIf, {1}},
{"while", scriptWhile, {1}},
{"else", scriptElse, {0}},
{"len", scriptLen, {1}},
{"byte", scriptMakeByteArray, {1}},
{"wait", scriptWait, {0}},
{"setPixel", scriptSetPixel, {5}},
{NULL, NULL, {0}},
};
varVector_t extractVars(scriptCtx_t* ctx, lexarToken_t* tokens, u32 len) {
varVector_t args = varVectorInit(4);
int lastLoc = 0;
for (int i = 0; i < len; i++) {
if (tokens[i].token == LSBracket) {
int distance = distanceBetweenTokens(&tokens[i + 1], len - i - 1, LSBracket, RSBracket);
i += distance + 1;
}
if (tokens[i].token == Seperator) {
dictValue_t res = solveEquation(ctx, &tokens[lastLoc], i - lastLoc);
lastLoc = i + 1;
varVectorAdd(&args, DictCreate(NULL, res));
}
if (i + 1 >= len) {
dictValue_t res = solveEquation(ctx, &tokens[lastLoc], i + 1 - lastLoc);
varVectorAdd(&args, DictCreate(NULL, res));
}
}
return args;
}
dictValue_t executeFunction(scriptCtx_t* ctx, char* func_name) {
int argCount = 0;
varVector_t args = { 0 };
if (ctx->args_loc.stored > 0) {
args = extractVars(ctx, ctx->args_loc.tokens, ctx->args_loc.stored);
for (int i = 0; i < args.stored; i++) {
if (args.vars[i].value.varType == ErrType)
return args.vars[i].value;
}
argCount = args.stored;
}
for (u32 i = 0; functions[i].key != NULL; i++) {
if (!strcmp(functions[i].key, func_name)) {
if (argCount != functions[i].argCount && !functions[i].varArgs)
continue;
dictValue_t val = functions[i].value(ctx, &args);
// free args
varVectorFree(&args);
return val;
}
}
dictValue_t* var = varVectorFind(&ctx->vars, func_name);
if (var != NULL) {
if (var->type == JumpType) {
setCurIndentInstruction(ctx, 0, ctx->curPos);
ctx->curPos = var->integer - 1;
ctx->lastToken.token = Invalid;
return NullDictValue();
}
}
return ErrDictValue(ERRNOFUNC);
}