start of tsV2

This commit is contained in:
suchmememanyskill
2020-11-06 21:19:29 +01:00
parent 024ef7cd6e
commit ba0ded0f8b
21 changed files with 1235 additions and 1205 deletions

View File

@@ -1,307 +1,263 @@
#include "args.h"
#include "parser.h"
#include "types.h"
#include "list.h"
#include "functions.h"
#include "scriptCtx.h"
#include "lexer.h"
#include <string.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 "../../utils/btn.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 "functions.h"
#include "variables.h"
#include "../fs/fsreader.h"
#include "../utils/utils.h"
#include "../../storage/nx_sd.h"
#include "../../gfx/gfx.h"
#include "../../hid/hid.h"
#include "../gfx/gfxutils.h"
int countchars(const char* in, char target) {
u32 len = strlen(in);
u32 count = 0;
for (u32 i = 0; i < len; i++) {
if (in[i] == '"'){
while (in[++i] != '"'){
if (i >= len)
return -1;
}
}
if (in[i] == target)
count++;
}
//#define DPRINTF(str, ...) printf(str, __VA_ARGS__)
#define DPRINTF
return count;
#define findNextCharsCtx(ctx, targets) findNextChars(&(ctx->curPos), targets)
int checkIfVar(u16 token) {
return (token == StrLit || token == IntLit || token == Variable || token == RSBracket);
}
char **argv = NULL;
u32 argc;
u32 splitargs(const char* in) {
// arg like '5, "6", @arg7'
u32 i = 0, count = 1, len = strlen(in), curcount = 0, begin, end;
void printToken(lexarToken_t* token) {
switch (token->token) {
case 1:
gfx_printf("%s ", token->text);
break;
case 6:
//printf("%d: '%s'\n", vec.tokens[i].token, vec.tokens[i].text);
gfx_printf("\"%s\" ", token->text);
break;
case 7:
//printf("%d: %d\n", vec.tokens[i].token, vec.tokens[i].val);
gfx_printf("%d ", token->val);
break;
default:
//printf("%d: %c\n", vec.tokens[i].token, lexarDebugGetTokenC(vec.tokens[i].token));
gfx_printf("%c ", lexarDebugGetTokenC(token->token));
break;
}
}
count += countchars(in, ',');
scriptResult_t runFunction(scriptCtx_t* ctx) {
dictValue_t res = solveEquation(ctx, &ctx->script->tokens[ctx->startEq], ctx->curPos - ctx->startEq);
if (!count)
return 0;
argv = calloc(count + 1, sizeof(char*));
while (i < len && curcount < count) {
if (in[i] == ' ' || in[i] == ','){
i++;
continue;
}
begin = i;
if (res.varType == ErrType)
return scriptResultCreate(res.integer, &ctx->script->tokens[ctx->startEq]);
while (strrchr(" ,)", in[i]) == NULL){
if (in[i] == '"'){
begin = i + 1;
while (in[++i] != '"'){
if (in[i] == '\0')
return 0;
ctx->startEq = ctx->curPos;
if (ctx->varToken.token != Invalid) { // we should not assign null's
ctx->varToken.token = Invalid;
if (ctx->varIndexSet) {
ctx->varIndexSet = 0;
dictValue_t* arrayVal = varVectorFind(&ctx->vars, ctx->varToken.text);
if (!(arrayVal == NULL || arrayVal->arrayLen <= ctx->varIndex)) {
if (arrayVal->varType == IntArrayType && res.varType == IntType) {
arrayVal->integerArray[ctx->varIndex] = res.integer;
}
else if (arrayVal->varType == StringArrayType && res.varType == StringType) {
free(arrayVal->stringArray[ctx->varIndex]);
arrayVal->stringArray[ctx->varIndex] = res.string;
}
else if (arrayVal->varType == ByteArrayType && res.varType == IntType) {
arrayVal->byteArray[ctx->varIndex] = (u8)(res.integer & 0xFF);
}
else {
return scriptResultCreate(ERRINVALIDTYPE, &ctx->script->tokens[ctx->startEq]);
}
}
else {
return scriptResultCreate(ERRNOVAR, &ctx->script->tokens[ctx->startEq]);
}
}
else {
varVectorAdd(&ctx->vars, DictCreate(util_cpyStr(ctx->varToken.text), res));
}
}
else {
freeDictValueOnVar(res);
}
if (in[i] == '\0')
return 0;
return scriptResultCreate(0, 0);
}
// TODO
// Make sure mem gets free'd properly
// Fix bug that custom functions cannot be run from end of script
// add arrays
#define RUNFUNCWITHPANIC(ctx) scriptResult_t res = runFunction(ctx); if (res.resCode != 0) return res
scriptResult_t mainLoop(scriptCtx_t* ctx) {
for (ctx->curPos = 0; ctx->curPos < ctx->script->stored; ctx->curPos++) {
u32 i = ctx->curPos;
lexarToken_t curToken = ctx->script->tokens[i];
//printToken(&curToken);
if (checkIfVar(ctx->lastToken.token) && curToken.token == Variable) {
RUNFUNCWITHPANIC(ctx);
}
else if (curToken.token == Equal) {
// Set last var to lastToken, if lastToken is var
if (ctx->lastToken.token == RSBracket) {
int layer = 0;
i = ctx->lastTokenPos - 1;
for (; i > 0; i--) {
if (ctx->script->tokens[i].token == RSBracket)
layer++;
else if (ctx->script->tokens[i].token == LSBracket) {
if (layer == 0)
break;
layer--;
}
}
i--;
if (ctx->script->tokens[i].token == Variable) {
dictValue_t index = solveEquation(ctx, &ctx->script->tokens[i + 2], ctx->lastTokenPos - i - 2);
ctx->lastTokenPos = i;
ctx->lastToken = ctx->script->tokens[i];
if (index.varType == IntType) {
ctx->varIndex = index.integer;
ctx->varIndexSet = 1;
if (ctx->varIndexSet) {
dictValue_t* arrayVal = varVectorFind(&ctx->vars, ctx->varToken.text);
if (arrayVal == NULL) {
return scriptResultCreate(ERRSYNTAX, &ctx->script->tokens[ctx->curPos]);
}
if (ctx->varIndex < 0 || ctx->varIndex >= arrayVal->arrayLen || arrayVal->varType < IntArrayType)
return scriptResultCreate(ERRSYNTAX, &ctx->script->tokens[ctx->curPos]);
}
}
else
return scriptResultCreate(ERRINVALIDTYPE, &ctx->script->tokens[ctx->curPos]);
}
else
return scriptResultCreate(ERRSYNTAX, &ctx->script->tokens[ctx->curPos]);
}
if (ctx->lastToken.token == Variable) {
ctx->startEq = ctx->curPos + 1;
ctx->varToken = ctx->lastToken;
}
else
return scriptResultCreate(ERRSYNTAX, &ctx->script->tokens[ctx->curPos]);
//printf("Setting token %s to next assignment", ctx->lastToken.text);
// !! check prev for ] for arrays
}
else if (curToken.token == LBracket) {
i++;
}
int distance = distanceBetweenTokens(&ctx->script->tokens[i], ctx->script->stored - i, LBracket, RBracket);
if (distance < 0)
return scriptResultCreate(ERRSYNTAX, &ctx->script->tokens[ctx->curPos]);
end = i;
i += distance;
ctx->curPos = i;
if (in[i - 1] == '"'){
end--;
}
argv[curcount++] = utils_copyStringSize(in + begin, (u32)(end - begin));
}
return curcount;
}
FIL scriptin;
UINT endByte = 0;
int forceExit = false;
char currentchar = 0;
char getnextchar(){
f_read(&scriptin, &currentchar, sizeof(char), &endByte);
if (sizeof(char) != endByte)
forceExit = true;
//gfx_printf("|%c|", currentchar);
return currentchar;
}
void getfollowingchar(char end){
while (currentchar != end && !f_eof(&scriptin)){
if (currentchar == '"'){
while (getnextchar() != '"' && !f_eof(&scriptin));
}
getnextchar();
}
}
void getnextvalidchar(){
while ((!((currentchar >= '?' && currentchar <= 'Z') || (currentchar >= 'a' && currentchar <= 'z') || currentchar == '#') && !f_eof(&scriptin)) /*|| currentchar == ';' */)
getnextchar();
}
char *makestr(u32 size, char ignore){
char *str;
u32 count = 0;
str = calloc(size + 1, sizeof(char));
for (u32 i = 0; i < size; i++){
getnextchar();
if (ignore != 0 && ignore == currentchar)
if (ctx->curPos + 1 >= ctx->script->stored && checkIfVar(ctx->lastToken.token)) {
solveEquation(ctx, &ctx->script->tokens[ctx->startEq], i + 1 - ctx->startEq);
}
continue;
str[count++] = currentchar;
}
return str;
}
}
else if (curToken.token == LCBracket) {
if (ctx->lastToken.token == Equal && ctx->varToken.token == Variable) {
varVectorAdd(&ctx->vars, DictCreate(util_cpyStr(ctx->varToken.text), DictValueCreate(JumpType, 0, ctx->curPos)));
ctx->varToken.token = Invalid;
setCurIndentInstruction(ctx, 1, -1);
}
char *readtilchar(char end, char ignore){
FSIZE_t offset, size;
if (checkIfVar(ctx->lastToken.token)) {
RUNFUNCWITHPANIC(ctx);
}
offset = f_tell(&scriptin);
getfollowingchar(end);
size = f_tell(&scriptin) - offset;
ctx->startEq = ctx->curPos + 1;
if (size <= 0)
return NULL;
indentInstructor_t ins = getCurIndentInstruction(ctx);
if (ins.active) {
if (ins.skip) {
int distance = distanceBetweenTokens(&ctx->script->tokens[i + 1], ctx->script->stored - i - 1, LCBracket, RCBracket);
if (distance < 0)
return scriptResultCreate(ERRSYNTAX, &ctx->script->tokens[ctx->curPos]);
ctx->curPos += distance + 1;
ctx->startEq = ctx->curPos + 1;
}
else {
ctx->indentLevel++;
}
}
else
return scriptResultCreate(ERRINACTIVEINDENT, &ctx->script->tokens[ctx->curPos]);
}
else if (curToken.token == RCBracket) {
if (checkIfVar(ctx->lastToken.token)) {
RUNFUNCWITHPANIC(ctx);
if (i != ctx->curPos)
continue;
}
f_lseek(&scriptin, offset - 1);
ctx->indentLevel--;
return makestr((u32)size, ignore);
}
indentInstructor_t ins = getCurIndentInstruction(ctx);
if (ins.active && ins.jump) {
ctx->curPos = ins.jumpLoc - 1;
}
char *funcbuff = NULL;
void functionparser(){
char *unsplitargs;
/*
if (funcbuff != NULL)
free(funcbuff);
*/
funcbuff = readtilchar('(', ' ');
getfollowingchar('(');
getnextchar();
unsplitargs = readtilchar(')', 0);
if (unsplitargs != NULL){
argc = splitargs(unsplitargs);
getnextchar();
}
else {
argc = 0;
}
getnextchar();
free(unsplitargs);
}
char *gettargetvar(){
char *variable = NULL;
variable = readtilchar('=', ' ');
getfollowingchar('=');
getnextchar();
return variable;
}
void mainparser(){
char *variable = NULL;
int res, out = 0;
getnextvalidchar();
if (f_eof(&scriptin))
return;
if (currentchar == '#'){
getfollowingchar('\n');
return;
}
if (currentchar == '@'){
variable = gettargetvar();
getnextvalidchar();
}
functionparser();
res = run_function(funcbuff, &out);
if (res < 0){
printerrors = true;
//gfx_printf("%s|%s|%d", funcbuff, argv[0], argc);
//btn_wait();
int lineNumber = 1;
u64 end = f_tell(&scriptin);
f_lseek(&scriptin, 0);
while (f_tell(&scriptin) < end && !f_eof(&scriptin)){
if (getnextchar() == '\n')
lineNumber++;
ctx->startEq = ctx->curPos + 1;
}
else if (ctx->curPos + 1 >= ctx->script->stored && checkIfVar(ctx->lastToken.token)) {
solveEquation(ctx, &ctx->script->tokens[ctx->startEq], i + 1 - ctx->startEq);
}
gfx_errDisplay((res == -1) ? funcbuff : "run_function", (res == -1) ? ERR_IN_FUNC : ERR_SCRIPT_LOOKUP_FAIL, lineNumber);
forceExit = true;
//gfx_printf("Func: %s\nArg1: %s\n", funcbuff, argv[0]);
}
else {
str_int_add("@RESULT", out);
if (variable != NULL)
str_int_add(variable, out);
ctx->lastToken = ctx->script->tokens[ctx->curPos];
ctx->lastTokenPos = ctx->curPos;
}
//gfx_printf("\nGoing to next func %c\n", currentchar);
if (funcbuff != NULL){
free(funcbuff);
funcbuff = NULL;
}
if (argv != NULL) {
for (int i = 0; argv[i] != NULL; i++)
free(argv[i]);
free(argv);
argv = NULL;
}
if (variable != NULL){
free(variable);
}
return scriptResultCreate(0, 0);
}
void skipbrackets(){
u32 bracketcounter = 0;
const char* functionFails[] = {
"An invalid operation was performed",
"Double Nots are not allowed",
"A syntax error was found",
"The recieved type was incorrect",
"The variable could not be found",
"The specified function could not be found",
"An inactive indent was found"
};
getfollowingchar('{');
getnextchar();
void startScript(char* path) {
char* file = sd_file_read(path, NULL);
while ((currentchar != '}' || bracketcounter != 0) && !f_eof(&scriptin)){
if (currentchar == '{')
bracketcounter++;
else if (currentchar == '}')
bracketcounter--;
getnextchar();
}
}
extern u32 currentcolor;
extern char *currentpath;
void runScript(char *path){
int res;
char *path_local = NULL;
forceExit = false;
currentchar = 0;
currentcolor = COLOR_WHITE;
gfx_clearscreen();
utils_copystring(path, &path_local);
res = f_open(&scriptin, path, FA_READ | FA_OPEN_EXISTING);
if (res != FR_OK){
gfx_errDisplay("ParseScript", res, 1);
if (file == NULL)
return;
gfx_clearscreen();
scriptCtx_t ctx = createScriptCtx();
lexarVector_t vec = lexarGo(file);
free(file);
ctx.script = &vec;
scriptResult_t res = mainLoop(&ctx);
gfx_printf("end of script\n");
if (res.resCode) {
gfx_printf("[ERROR] %d\n%s\nNear:", res.resCode, functionFails[res.resCode - 1]);
printToken(res.nearToken);
}
printerrors = false;
//add builtin vars
str_int_add("@EMUMMC", emu_cfg.enabled);
str_int_add("@RESULT", 0);
str_int_add("@JOYCONN", hidConnected());
str_str_add("$CURRENTPATH", currentpath);
//str_int_printall();
while (!f_eof(&scriptin) && !forceExit){
mainparser();
}
printerrors = true;
//str_int_printall();
f_close(&scriptin);
str_int_clear();
//str_jmp_clear();
str_str_clear();
free(path_local);
//btn_wait();
gfx_printf("\n\n");
//mainLoop2(&ctx, &vec);
lexarVectorClear(&vec);
destroyScriptCtx(&ctx);
hidWait();
}