start of tsV2
This commit is contained in:
@@ -1,664 +1,177 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../mem/heap.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../emmc/emmc.h"
|
||||
#include "../../utils/types.h"
|
||||
#include "../../libs/fatfs/ff.h"
|
||||
#include "../../utils/sprintf.h"
|
||||
#include "../../hid/hid.h"
|
||||
#include "../../gfx/gfx.h"
|
||||
#include "../../utils/util.h"
|
||||
#include "../../storage/emummc.h"
|
||||
#include "parser.h"
|
||||
#include "../common/common.h"
|
||||
#include "../fs/fsactions.h"
|
||||
#include "variables.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "functions.h"
|
||||
#include "../fs/fsutils.h"
|
||||
#include "../../utils/sprintf.h"
|
||||
#include "../fs/fsactions.h"
|
||||
#include "../emmc/emmcoperations.h"
|
||||
#include "../emmc/emmcmenu.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"
|
||||
|
||||
extern FIL scriptin;
|
||||
extern char **argv;
|
||||
extern u32 argc;
|
||||
extern int forceExit;
|
||||
extern short currentlyMounted;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int parseIntInput(char *in, int *out){
|
||||
if (in[0] == '@'){
|
||||
if (str_int_find(in, out))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
*out = atoi(in);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
int parseJmpInput(char *in, u64 *out){
|
||||
if (in[0] == '?'){
|
||||
if (str_jmp_find(in, out))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
int parseStringInput(char *in, char **out){
|
||||
if (in[0] == '$'){
|
||||
if (str_str_find(in, out))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else{
|
||||
*out = in;
|
||||
return 0;
|
||||
}
|
||||
return NullDictValue();
|
||||
}
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
u32 currentcolor = COLOR_WHITE;
|
||||
int part_printf(){
|
||||
SWAPCOLOR(currentcolor);
|
||||
for (int i = 0; i < argc; i++){
|
||||
if (argv[i][0] == '@'){
|
||||
int toprintint;
|
||||
if (parseIntInput(argv[i], &toprintint))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
gfx_printf("%d", toprintint);
|
||||
}
|
||||
else {
|
||||
char *toprintstring;
|
||||
if (parseStringInput(argv[i], &toprintstring))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
gfx_printf(toprintstring);
|
||||
}
|
||||
}
|
||||
|
||||
gfx_printf("\n");
|
||||
return 0;
|
||||
dictValue_t funcPrintln(scriptCtx_t* ctx, varVector_t* args) {
|
||||
funcPrint(ctx, args);
|
||||
gfx_printf("\n");
|
||||
return NullDictValue();
|
||||
}
|
||||
|
||||
int part_print_int(){
|
||||
int toprint;
|
||||
if (parseIntInput(argv[0], &toprint))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
SWAPCOLOR(currentcolor);
|
||||
gfx_printf("%s: %d\n", argv[0], toprint);
|
||||
return 0;
|
||||
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);
|
||||
}
|
||||
|
||||
int part_Wait(){
|
||||
int arg;
|
||||
u32 begintime;
|
||||
SWAPCOLOR(currentcolor);
|
||||
|
||||
if (parseIntInput(argv[0], &arg))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
begintime = get_tmr_s();
|
||||
|
||||
while (begintime + arg > get_tmr_s()){
|
||||
gfx_printf("\r<Wait %d seconds> ", (begintime + arg) - get_tmr_s());
|
||||
}
|
||||
|
||||
gfx_printf("\r \r");
|
||||
return 0;
|
||||
dictValue_t scriptElse(scriptCtx_t* ctx, varVector_t* args) {
|
||||
indentInstructor_t curInstruction = getCurIndentInstruction(ctx);
|
||||
setCurIndentInstruction(ctx, !curInstruction.skip, -1);
|
||||
return NullDictValue();
|
||||
}
|
||||
|
||||
int part_Check(){
|
||||
int left, right;
|
||||
if (parseIntInput(argv[0], &left))
|
||||
return INFUNC_FAIL;
|
||||
if (parseIntInput(argv[2], &right))
|
||||
return INFUNC_FAIL;
|
||||
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();
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "=="))
|
||||
return (left == right);
|
||||
else if (!strcmp(argv[1], "!="))
|
||||
return (left != right);
|
||||
else if (!strcmp(argv[1], ">="))
|
||||
return (left >= right);
|
||||
else if (!strcmp(argv[1], "<="))
|
||||
return (left <= right);
|
||||
else if (!strcmp(argv[1], ">"))
|
||||
return (left > right);
|
||||
else if (!strcmp(argv[1], "<"))
|
||||
return (left < right);
|
||||
else
|
||||
return INFUNC_FAIL;
|
||||
return ErrDictValue(ERRINVALIDTYPE);
|
||||
}
|
||||
|
||||
int part_if(){
|
||||
int condition;
|
||||
if (parseIntInput(argv[0], &condition))
|
||||
return INFUNC_FAIL;
|
||||
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));
|
||||
}
|
||||
|
||||
getfollowingchar('{');
|
||||
|
||||
if (!condition)
|
||||
skipbrackets();
|
||||
|
||||
return 0;
|
||||
|
||||
/*
|
||||
if (condition)
|
||||
return 0;
|
||||
else {
|
||||
skipbrackets();
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
return ErrDictValue(ERRINVALIDTYPE);
|
||||
}
|
||||
|
||||
int part_if_args(){
|
||||
int condition;
|
||||
if ((condition = part_Check()) < 0)
|
||||
return INFUNC_FAIL;
|
||||
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);
|
||||
}
|
||||
|
||||
getfollowingchar('{');
|
||||
return DictValueCreate(ByteArrayType | FREEINDICT, args->vars[0].value.arrayLen, buff);
|
||||
}
|
||||
|
||||
if (!condition)
|
||||
skipbrackets();
|
||||
|
||||
return 0;
|
||||
return ErrDictValue(ERRINVALIDTYPE);
|
||||
}
|
||||
|
||||
int part_Math(){
|
||||
int left, right;
|
||||
if (parseIntInput(argv[0], &left))
|
||||
return INFUNC_FAIL;
|
||||
if (parseIntInput(argv[2], &right))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
switch (argv[1][0]){
|
||||
case '+':
|
||||
return left + right;
|
||||
case '-':
|
||||
return left - right;
|
||||
case '*':
|
||||
return left * right;
|
||||
case '/':
|
||||
return left / right;
|
||||
}
|
||||
return INFUNC_FAIL;
|
||||
dictValue_t scriptWait(scriptCtx_t*ctx, varVector_t* args){
|
||||
Inputs* input = hidWait();
|
||||
|
||||
return IntDictValue(input->buttons);
|
||||
}
|
||||
|
||||
int part_SetInt(){
|
||||
int out;
|
||||
parseIntInput(argv[0], &out);
|
||||
return out;
|
||||
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();
|
||||
}
|
||||
|
||||
int part_SetString(){
|
||||
char *arg0;
|
||||
if (parseStringInput(argv[0], &arg0))
|
||||
return INFUNC_FAIL;
|
||||
if (argv[1][0] != '$')
|
||||
return INFUNC_FAIL;
|
||||
|
||||
str_str_add(argv[1], arg0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_SetStringIndex(){
|
||||
int index;
|
||||
char *out;
|
||||
if (parseIntInput(argv[0], &index))
|
||||
return INFUNC_FAIL;
|
||||
if (argv[1][0] != '$')
|
||||
return INFUNC_FAIL;
|
||||
if (str_str_index(index, &out))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
str_str_add(argv[1], out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_goto(){
|
||||
int target = 0;
|
||||
if (parseIntInput(argv[0], &target))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
str_int_add("@RETURN", (int)f_tell(&scriptin));
|
||||
|
||||
f_lseek(&scriptin, target);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_invert(){
|
||||
int arg;
|
||||
if (parseIntInput(argv[0], &arg))
|
||||
return INFUNC_FAIL;
|
||||
return (arg) ? 0 : 1;
|
||||
}
|
||||
|
||||
int part_fs_exists(){
|
||||
char *path;
|
||||
if (parseStringInput(argv[0], &path))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
return fsutil_checkfile(path);
|
||||
}
|
||||
|
||||
int part_ConnectMMC(){
|
||||
char *arg;
|
||||
parseStringInput(argv[0], &arg);
|
||||
|
||||
if (!strcmp(arg, "SYSMMC"))
|
||||
connect_mmc(SYSMMC);
|
||||
else if (!strcmp(arg, "EMUMMC"))
|
||||
connect_mmc(EMUMMC);
|
||||
else
|
||||
return INFUNC_FAIL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_MountMMC(){
|
||||
char *arg;
|
||||
parseStringInput(argv[0], &arg);
|
||||
return mount_mmc(arg, 2);
|
||||
}
|
||||
|
||||
int part_Pause(){
|
||||
Inputs *input = hidWaitMask(KEY_A | KEY_B | KEY_X | KEY_Y | KEY_POW | KEY_VOLP | KEY_VOLM | KEY_LUP | KEY_LDOWN | KEY_LLEFT | KEY_LRIGHT);
|
||||
|
||||
str_int_add("@BTN_POWER", input->pow);
|
||||
str_int_add("@BTN_VOL+", input->volp);
|
||||
str_int_add("@BTN_VOL-", input->volm);
|
||||
str_int_add("@BTN_A", input->a);
|
||||
str_int_add("@BTN_B", input->b);
|
||||
str_int_add("@BTN_X", input->x);
|
||||
str_int_add("@BTN_Y", input->y);
|
||||
str_int_add("@BTN_UP", input->Lup);
|
||||
str_int_add("@BTN_DOWN", input->Ldown);
|
||||
str_int_add("@BTN_LEFT", input->Lleft);
|
||||
str_int_add("@BTN_RIGHT", input->Lright);
|
||||
str_int_add("@JOYCONN", hidConnected());
|
||||
|
||||
return input->buttons;
|
||||
}
|
||||
|
||||
int part_addstrings(){
|
||||
char *combined, *left, *middle;
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return INFUNC_FAIL;
|
||||
if (parseStringInput(argv[1], &middle))
|
||||
return INFUNC_FAIL;
|
||||
if (argv[2][0] != '$')
|
||||
return INFUNC_FAIL;
|
||||
|
||||
combined = calloc(strlen(left) + strlen(middle) + 1, sizeof(char));
|
||||
sprintf(combined, "%s%s", left, middle);
|
||||
|
||||
str_str_add(argv[2], combined);
|
||||
free(combined);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_setColor(){
|
||||
char *arg;
|
||||
if (parseStringInput(argv[0], &arg))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
if (!strcmp(arg, "RED"))
|
||||
currentcolor = COLOR_RED;
|
||||
else if (!strcmp(arg, "ORANGE"))
|
||||
currentcolor = COLOR_ORANGE;
|
||||
else if (!strcmp(arg, "YELLOW"))
|
||||
currentcolor = COLOR_YELLOW;
|
||||
else if (!strcmp(arg, "GREEN"))
|
||||
currentcolor = COLOR_GREEN;
|
||||
else if (!strcmp(arg, "BLUE"))
|
||||
currentcolor = COLOR_BLUE;
|
||||
else if (!strcmp(arg, "VIOLET"))
|
||||
currentcolor = COLOR_VIOLET;
|
||||
else if (!strcmp(arg, "WHITE"))
|
||||
currentcolor = COLOR_WHITE;
|
||||
else
|
||||
return INFUNC_FAIL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_Exit(){
|
||||
forceExit = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_fs_Move(){
|
||||
char *left, *right;
|
||||
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return INFUNC_FAIL;
|
||||
if (parseStringInput(argv[1], &right))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
int res;
|
||||
res = f_rename(left, right);
|
||||
if (res)
|
||||
res = f_rename(left, right);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int part_fs_Delete(){
|
||||
char *arg;
|
||||
|
||||
if (parseStringInput(argv[0], &arg))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
int res;
|
||||
res = f_unlink(arg);
|
||||
if (res)
|
||||
res = f_unlink(arg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int part_fs_DeleteRecursive(){
|
||||
char *arg;
|
||||
|
||||
if (parseStringInput(argv[0], &arg))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
return fsact_del_recursive(arg);
|
||||
}
|
||||
|
||||
int part_fs_Copy(){
|
||||
char *left, *right;
|
||||
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return INFUNC_FAIL;
|
||||
if (parseStringInput(argv[1], &right))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
return fsact_copy(left, right, COPY_MODE_PRINT);
|
||||
}
|
||||
|
||||
int part_fs_CopyRecursive(){
|
||||
char *left, *right;
|
||||
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return INFUNC_FAIL;
|
||||
if (parseStringInput(argv[1], &right))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
return fsact_copy_recursive(left, right);
|
||||
}
|
||||
|
||||
int part_fs_MakeDir(){
|
||||
char *arg;
|
||||
|
||||
if (parseStringInput(argv[0], &arg))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
int res;
|
||||
res = f_mkdir(arg);
|
||||
if (res)
|
||||
res = f_mkdir(arg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
DIR dir;
|
||||
FILINFO fno;
|
||||
int isdirvalid = false;
|
||||
int part_fs_OpenDir(){
|
||||
char *path;
|
||||
|
||||
if (parseStringInput(argv[0], &path))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
if (f_opendir(&dir, path))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
isdirvalid = true;
|
||||
str_int_add("@ISDIRVALID", isdirvalid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_fs_CloseDir(){
|
||||
if (!isdirvalid)
|
||||
return 0;
|
||||
|
||||
f_closedir(&dir);
|
||||
isdirvalid = false;
|
||||
str_int_add("@ISDIRVALID", isdirvalid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_fs_ReadDir(){
|
||||
if (!isdirvalid)
|
||||
return INFUNC_FAIL;
|
||||
|
||||
if (!f_readdir(&dir, &fno) && fno.fname[0]){
|
||||
str_str_add("$FILENAME", fno.fname);
|
||||
str_int_add("@ISDIR", (fno.fattrib & AM_DIR) ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
part_fs_CloseDir();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_setPrintPos(){
|
||||
int left, right;
|
||||
|
||||
if (parseIntInput(argv[0], &left))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
if (parseIntInput(argv[1], &right))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
if (left > 78)
|
||||
return INFUNC_FAIL;
|
||||
|
||||
if (right > 42)
|
||||
return INFUNC_FAIL;
|
||||
|
||||
gfx_con_setpos(left * 16, right * 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_stringcompare(){
|
||||
char *left, *right;
|
||||
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return INFUNC_FAIL;
|
||||
if (parseStringInput(argv[1], &right))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
return (strcmp(left, right)) ? 0 : 1;
|
||||
}
|
||||
|
||||
int part_fs_combinePath(){
|
||||
char *combined, *left, *middle;
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return INFUNC_FAIL;
|
||||
if (parseStringInput(argv[1], &middle))
|
||||
return INFUNC_FAIL;
|
||||
if (argv[2][0] != '$')
|
||||
return INFUNC_FAIL;
|
||||
|
||||
combined = fsutil_getnextloc(left, middle);
|
||||
|
||||
str_str_add(argv[2], combined);
|
||||
free(combined);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_mmc_dumpPart(){
|
||||
char *left, *right;
|
||||
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return INFUNC_FAIL;
|
||||
if (parseStringInput(argv[1], &right))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
if (!strcmp(left, "BOOT")){
|
||||
return emmcDumpBoot(right);
|
||||
}
|
||||
else {
|
||||
return emmcDumpSpecific(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
int part_mmc_restorePart(){
|
||||
char *path;
|
||||
|
||||
if (parseStringInput(argv[0], &path))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
if (currentlyMounted < 0)
|
||||
return INFUNC_FAIL;
|
||||
|
||||
return mmcFlashFile(path, currentlyMounted, false);
|
||||
}
|
||||
|
||||
int part_fs_extractBisFile(){
|
||||
char *path, *outfolder;
|
||||
|
||||
if (parseStringInput(argv[0], &path))
|
||||
return INFUNC_FAIL;
|
||||
if (parseStringInput(argv[1], &outfolder))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
return extract_bis_file(path, outfolder);
|
||||
}
|
||||
|
||||
int part_clearscreen(){
|
||||
gfx_clearscreen();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_getPos(){
|
||||
return (int)f_tell(&scriptin);
|
||||
}
|
||||
|
||||
int part_subString(){
|
||||
char *str, *sub;
|
||||
int start, size;
|
||||
|
||||
if (parseStringInput(argv[0], &str))
|
||||
return INFUNC_FAIL;
|
||||
if (parseIntInput(argv[1], &start))
|
||||
return INFUNC_FAIL;
|
||||
if (parseIntInput(argv[2], &size))
|
||||
return INFUNC_FAIL;
|
||||
if (argv[3][0] != '$')
|
||||
return INFUNC_FAIL;
|
||||
|
||||
if (start >= strlen(str))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
sub = utils_copyStringSize(str + start, size);
|
||||
str_str_add(argv[3], sub);
|
||||
free(sub);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_inputString(){
|
||||
char *start, *out;
|
||||
int len;
|
||||
|
||||
if (parseStringInput(argv[0], &start))
|
||||
return INFUNC_FAIL;
|
||||
if (parseIntInput(argv[1], &len))
|
||||
return INFUNC_FAIL;
|
||||
if (argv[2][0] != '$')
|
||||
return INFUNC_FAIL;
|
||||
|
||||
if (len > 39)
|
||||
return INFUNC_FAIL;
|
||||
|
||||
out = utils_InputText(start, len);
|
||||
if (out == NULL)
|
||||
return 1;
|
||||
|
||||
str_str_add(argv[2], out);
|
||||
free(out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_strLen(){
|
||||
char *in;
|
||||
|
||||
if (parseStringInput(argv[0], &in))
|
||||
return INFUNC_FAIL;
|
||||
|
||||
return strlen(in);
|
||||
}
|
||||
|
||||
str_fnc_struct functions[] = {
|
||||
{"printf", part_printf, 255},
|
||||
{"printInt", part_print_int, 1},
|
||||
{"setPrintPos", part_setPrintPos, 2},
|
||||
{"clearscreen", part_clearscreen, 0},
|
||||
{"if", part_if, 1},
|
||||
{"if", part_if_args, 3}, // function overloading
|
||||
{"math", part_Math, 3},
|
||||
{"check", part_Check, 3},
|
||||
{"setInt", part_SetInt, 1},
|
||||
{"goto", part_goto, 1},
|
||||
{"setString", part_SetString, 2},
|
||||
{"setStringIndex", part_SetStringIndex, 2},
|
||||
{"setColor", part_setColor, 1},
|
||||
{"combineStrings", part_addstrings, 3},
|
||||
{"compareStrings", part_stringcompare, 2},
|
||||
{"subString", part_subString, 4},
|
||||
{"inputString", part_inputString, 3},
|
||||
{"stringLength", part_strLen, 1},
|
||||
{"invert", part_invert, 1},
|
||||
{"fs_exists", part_fs_exists, 1},
|
||||
{"fs_move", part_fs_Move, 2},
|
||||
{"fs_mkdir", part_fs_MakeDir, 1},
|
||||
{"fs_del", part_fs_Delete, 1},
|
||||
{"fs_delRecursive", part_fs_DeleteRecursive, 1},
|
||||
{"fs_copy", part_fs_Copy, 2},
|
||||
{"fs_copyRecursive", part_fs_CopyRecursive, 2},
|
||||
{"fs_openDir", part_fs_OpenDir, 1},
|
||||
{"fs_closeDir", part_fs_CloseDir, 0},
|
||||
{"fs_readDir", part_fs_ReadDir, 0},
|
||||
{"fs_combinePath", part_fs_combinePath, 3},
|
||||
{"fs_extractBisFile", part_fs_extractBisFile, 2},
|
||||
{"mmc_connect", part_ConnectMMC, 1},
|
||||
{"mmc_mount", part_MountMMC, 1},
|
||||
{"mmc_dumpPart", part_mmc_dumpPart, 2},
|
||||
{"mmc_restorePart", part_mmc_restorePart, 1},
|
||||
{"getPosition", part_getPos, 0},
|
||||
{"pause", part_Pause, 0},
|
||||
{"wait", part_Wait, 1},
|
||||
{"exit", part_Exit, 0},
|
||||
{NULL, NULL, 0}
|
||||
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}},
|
||||
};
|
||||
|
||||
#pragma GCC pop_options
|
||||
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));
|
||||
}
|
||||
|
||||
int run_function(char *func_name, int *out){
|
||||
for (u32 i = 0; functions[i].key != NULL; i++){
|
||||
if (!strcmp(functions[i].key, func_name)){
|
||||
if (argc != functions[i].arg_count && functions[i].arg_count != 255)
|
||||
continue;
|
||||
if (i + 1 >= len) {
|
||||
dictValue_t res = solveEquation(ctx, &tokens[lastLoc], i + 1 - lastLoc);
|
||||
varVectorAdd(&args, DictCreate(NULL, res));
|
||||
}
|
||||
}
|
||||
|
||||
*out = functions[i].value();
|
||||
return (*out == INFUNC_FAIL) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user