From 9a8ad9985d4cbb96152accf7f1bd82932d88efe6 Mon Sep 17 00:00:00 2001 From: Mike Nolan Date: Wed, 30 Nov 2022 21:27:30 -0600 Subject: [PATCH] First commit --- .gitignore | 60 ++ .vscode/c_cpp_properties.json | 17 + .vscode/launch.json | 33 + .vscode/settings.json | 58 ++ Makefile.am | 12 + config.h | 127 ++++ config.h.in~ | 123 ++++ configure.ac | 36 + source/dirent.cpp | 56 ++ source/expressions.cpp | 258 +++++++ source/lexer.cpp | 293 ++++++++ source/lexer.hpp | 34 + source/networkstream.cpp | 352 ++++++++++ source/parser.cpp | 984 +++++++++++++++++++++++++++ source/parser.hpp | 537 +++++++++++++++ source/pcapp.cpp | 47 ++ source/runtimefuncs.cpp | 1186 +++++++++++++++++++++++++++++++++ source/wiiapp.cpp | 233 +++++++ wii/Makefile | 138 ++++ wii/include/config.h | 10 + 20 files changed, 4594 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 Makefile.am create mode 100644 config.h create mode 100644 config.h.in~ create mode 100644 configure.ac create mode 100644 source/dirent.cpp create mode 100644 source/expressions.cpp create mode 100644 source/lexer.cpp create mode 100644 source/lexer.hpp create mode 100644 source/networkstream.cpp create mode 100644 source/parser.cpp create mode 100644 source/parser.hpp create mode 100644 source/pcapp.cpp create mode 100644 source/runtimefuncs.cpp create mode 100644 source/wiiapp.cpp create mode 100644 wii/Makefile create mode 100644 wii/include/config.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..43d7835 --- /dev/null +++ b/.gitignore @@ -0,0 +1,60 @@ +# http://www.gnu.org/software/automake + + +Makefile.in +/ar-lib +/mdate-sh +/py-compile +/test-driver +/ylwrap +.deps/ +.dirstamp + +# http://www.gnu.org/software/autoconf + +autom4te.cache +/autoscan.log +/autoscan-*.log +/aclocal.m4 +/compile +/config.cache +/config.guess +/config.h.in +/config.log +/config.status +/config.sub +/configure +/configure.scan +/depcomp +/install-sh +/missing +/stamp-h1 + +# https://www.gnu.org/software/libtool/ + +/ltmain.sh + +# http://www.gnu.org/software/texinfo + +/texinfo.tex + +# http://www.gnu.org/software/m4/ + +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 + +# Generated Makefile +# (meta build system like autotools, +# can automatically generate from config.status script +# (which is called by configure script)) +Makefile +Footer +!wii/Makefile +wii/boot.elf +wii/boot.dol +wii/build +/boxscript +*.o \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..4f6e41e --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "/usr/include/SDL2" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-gcc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..fb21f6c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/source/a.out", + "args": ["/media/mike/BOOTMII/BoxScript/webide/app.bs"], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + } + + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a3d0ed4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,58 @@ +{ + "files.associations": { + "*.tcc": "cpp", + "string": "cpp", + "iostream": "cpp", + "vector": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "map": "cpp", + "unordered_map": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp", + "chrono": "cpp", + "ctime": "cpp", + "ratio": "cpp", + "thread": "cpp", + "filesystem": "cpp", + "codecvt": "cpp", + "iomanip": "cpp" + } +} \ No newline at end of file diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..9e5eca1 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,12 @@ +AM_CXXFLAGS = -std=c++17 +AUTOMAKE_OPTIONS = subdir-objects +bin_PROGRAMS = boxscript + +boxscript_SOURCES = \ + source/pcapp.cpp \ + source/parser.cpp \ + source/dirent.cpp \ + source/expressions.cpp \ + source/lexer.cpp \ + source/networkstream.cpp \ + source/runtimefuncs.cpp \ No newline at end of file diff --git a/config.h b/config.h new file mode 100644 index 0000000..a6edf2c --- /dev/null +++ b/config.h @@ -0,0 +1,127 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#define HAVE_FSEEKO 1 + +/* Define to 1 if you have the `gethostbyname' function. */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the `inet_ntoa' function. */ +#define HAVE_INET_NTOA 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `curl' library (-lcurl). */ +#define HAVE_LIBCURL 1 + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#define HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mkdir' function. */ +#define HAVE_MKDIR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if the system has the type `_Bool'. */ +#define HAVE__BOOL 1 + +/* Name of package */ +#define PACKAGE "boxscript" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "boxscript" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "boxscript VERSION" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "boxscript" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "VERSION" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "VERSION" + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +/* #undef _LARGEFILE_SOURCE */ + +/* Define for Solaris 2.5.1 so the uint32_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT32_T */ + +/* Define for Solaris 2.5.1 so the uint8_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT8_T */ + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +/* #undef int64_t */ + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define to `int' if does not define. */ +/* #undef ssize_t */ + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint16_t */ + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint32_t */ + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint8_t */ diff --git a/config.h.in~ b/config.h.in~ new file mode 100644 index 0000000..a60e4ff --- /dev/null +++ b/config.h.in~ @@ -0,0 +1,123 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#undef HAVE_FSEEKO + +/* Define to 1 if you have the `gethostbyname' function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define to 1 if you have the `inet_ntoa' function. */ +#undef HAVE_INET_NTOA + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#undef HAVE_LIBPTHREAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mkdir' function. */ +#undef HAVE_MKDIR + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +#undef _LARGEFILE_SOURCE + +/* Define for Solaris 2.5.1 so the uint32_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT32_T + +/* Define for Solaris 2.5.1 so the uint8_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT8_T + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef int64_t + +/* Define to `long int' if does not define. */ +#undef off_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define to `int' if does not define. */ +#undef ssize_t + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef uint16_t + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef uint32_t + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +#undef uint8_t diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..d2e3399 --- /dev/null +++ b/configure.ac @@ -0,0 +1,36 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.69]) +AC_INIT([boxscript], [VERSION], []) +AC_CONFIG_SRCDIR([source/dirent.cpp]) +AC_CONFIG_HEADERS([config.h]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC + +#AC_CHECK_LIB([m], [main]) +AC_CHECK_LIB([pthread],[pthread_create]) +AC_CHECK_LIB([curl],[curl_easy_init]) + +# Checks for header files. +AC_CHECK_HEADERS([arpa/inet.h netdb.h sys/socket.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_CHECK_HEADER_STDBOOL +AC_TYPE_INT64_T +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT8_T + +# Checks for library functions. +AC_FUNC_FSEEKO +AC_CHECK_FUNCS([gethostbyname inet_ntoa mkdir socket]) + +AC_CONFIG_FILES([Makefile]) + +AC_OUTPUT diff --git a/source/dirent.cpp b/source/dirent.cpp new file mode 100644 index 0000000..6888a13 --- /dev/null +++ b/source/dirent.cpp @@ -0,0 +1,56 @@ +#include "parser.hpp" +#include +#include +#include +#include +namespace fs = std::filesystem; + + +std::vector> get_entries(std::string path) +{ + std::vector> entries; + #if defined(GEKKO) + DIR* dir = opendir(path.c_str()); + if(dir == NULL) + { + return entries; + } + struct dirent* entry; + entry = readdir(dir); + while(entry != NULL) + { + entries.push_back({entry->d_name,entry->d_type == DT_DIR}); + entry = readdir(dir); + } + closedir(dir); + #else + for (const auto & entry : fs::directory_iterator(path)) + entries.push_back({entry.path().filename().c_str(),entry.is_directory()}); + #endif + return entries; + +} +std::vector get_files(std::string path) +{ + std::vector files; + for(auto f : get_entries(path)) + { + if(f.first!="." && f.first != ".." && !f.second ) + { + files.push_back(f.first); + } + } + return files; +} +std::vector get_directories(std::string path) +{ + std::vector files; + for(auto f : get_entries(path)) + { + if(f.first!="." && f.first != ".." && f.second ) + { + files.push_back(f.first); + } + } + return files; +} \ No newline at end of file diff --git a/source/expressions.cpp b/source/expressions.cpp new file mode 100644 index 0000000..eec7d64 --- /dev/null +++ b/source/expressions.cpp @@ -0,0 +1,258 @@ +#include "parser.hpp" +namespace BoxScript +{ +#pragma region "ConstantNumber" +ConstantNumber::ConstantNumber(string num) +{ + this->num=stoll(num); +} +int64_t ConstantNumber::Evaluate(IApplicationState* state) +{ + return this->num; +} +string ConstantNumber::GetNodeName() +{ + return "ConstantNumber"; +} +#pragma endregion +#pragma region "VariableGetValueNode" +string VariableGetValueNode::GetName() +{ + return this->var; +} +string VariableGetValueNode::GetNodeName() +{ + return "VariableGetValueNode"; +} +VariableGetValueNode::VariableGetValueNode(string var) +{ + this->var = var; +} +int64_t VariableGetValueNode::Evaluate(IApplicationState* state) +{ + return state->GetVariable(this->var); +} +#pragma endregion +#pragma region "StringNode" +string StringNode::GetText() +{ + return this->text; +} +string StringNode::GetNodeName() +{ + return "StringNode"; +} +StringNode::StringNode(string var) +{ + this->boxId=-1; + this->text=var; +} +int64_t StringNode::Evaluate(IApplicationState* state) +{ + if(boxId > -1) + return boxId; + + boxId = state->CreateBoxPermanent(text); + return boxId; +} + +#pragma endregion +#pragma region "SetVariableNode" +SetVariableNode::~SetVariableNode() +{ + delete this->e; +} +string SetVariableNode::GetNodeName() +{ + return "SetVariableNode"; +} +SetVariableNode::SetVariableNode(Expression* expression,string name) +{ + this->e = expression; + this->vname =name; +} +int64_t SetVariableNode::Evaluate(IApplicationState* state) +{ + int64_t v = e->Evaluate(state); + state->SetVariable(vname,v); + return 0; +} +#pragma endregion +#pragma region "FunctionCallNode" +FunctionCallNode::~FunctionCallNode() +{ + for(auto node: this->expressions) + { + delete node; + } +} +string FunctionCallNode::GetNodeName() +{ + return "FunctionCallNode"; +} +FunctionCallNode::FunctionCallNode(string _name,vector exps) +{ + this->name = _name; + this->expressions =exps; +} +int64_t FunctionCallNode::Evaluate(IApplicationState* state) +{ + if(state->HasRuntimeFunction(name)) + { + return state->GetRuntimeFunction(name)(state,expressions); + } + if(state->HasFunction(name)) + { + return state->ExecuteFunction(name,expressions); + } + return 0; +} + +#pragma endregion +#pragma region "AddNode" +AddNode::~AddNode() +{ + delete left; + delete right; +} +string AddNode::GetNodeName() +{ + return "AddNode"; +} +AddNode::AddNode(Expression* _left,Expression* _right) +{ + this->left=_left; + this->right = _right; +} +int64_t AddNode::Evaluate(IApplicationState* state) +{ + return this->left->Evaluate(state) + this->right->Evaluate(state); +} + +#pragma endregion +#pragma region "MinusNode" +MinusNode::~MinusNode() +{ + delete left; + delete right; +} +string MinusNode::GetNodeName() +{ + return "MinusNode"; +} +MinusNode::MinusNode(Expression* _left,Expression* _right) +{ + this->left=_left; + this->right = _right; +} +int64_t MinusNode::Evaluate(IApplicationState* state) +{ + return this->left->Evaluate(state) - this->right->Evaluate(state); +} + +#pragma endregion +#pragma region "MultiplyNode" +MultiplyNode::~MultiplyNode() +{ + delete left; + delete right; +} +string MultiplyNode::GetNodeName() +{ + return "MultiplyNode"; +} +MultiplyNode::MultiplyNode(Expression* _left,Expression* _right) +{ + this->left=_left; + this->right = _right; +} +int64_t MultiplyNode::Evaluate(IApplicationState* state) +{ + return this->left->Evaluate(state) * this->right->Evaluate(state); +} + +#pragma endregion +#pragma region "DivideNode" +DivideNode::~DivideNode() +{ + delete left; + delete right; +} +string DivideNode::GetNodeName() +{ + return "DivideNode"; +} +DivideNode::DivideNode(Expression* _left,Expression* _right) +{ + this->left=_left; + this->right = _right; +} +int64_t DivideNode::Evaluate(IApplicationState* state) +{ + return this->left->Evaluate(state) / this->right->Evaluate(state); +} + +#pragma endregion +#pragma region "ModulusNode" +ModulusNode::~ModulusNode() +{ + delete left; + delete right; +} +string ModulusNode::GetNodeName() +{ + return "ModulusNode"; +} +ModulusNode::ModulusNode(Expression* _left,Expression* _right) +{ + this->left=_left; + this->right = _right; +} +int64_t ModulusNode::Evaluate(IApplicationState* state) +{ + return this->left->Evaluate(state) % this->right->Evaluate(state); +} +#pragma endregion +#pragma region "ListNode" +void ListNode::DisableScope() +{ + this->root=true; +} +ListNode::~ListNode() +{ + for(auto node : nodes) + { + delete node; + } +} +string ListNode::GetNodeName() +{ + return "ListNode"; +} + +int64_t ListNode::Evaluate(IApplicationState* state) +{ + int64_t res=0; + IApplicationState* s=state; + if(!root) + { + s=s->NewScope(); + s->AddThreadOwner(); + } + for(auto node : nodes) + { + state->ExitIfNotRunning(); + res= node->Evaluate(state); + } + if(!root) + { + s->RemoveThreadOwner(); + } + return res; +} +#pragma endregion +void Expression::DisableScope() +{ + +} +}; \ No newline at end of file diff --git a/source/lexer.cpp b/source/lexer.cpp new file mode 100644 index 0000000..584ae33 --- /dev/null +++ b/source/lexer.cpp @@ -0,0 +1,293 @@ +#include "lexer.hpp" +namespace BoxScript::Lexer +{ +LexToken::LexToken() +{ + this->text=""; + this->type = ERROR; +} +LexToken::LexToken(std::string _text) +{ + this->text = _text; + if(_text.size() > 0) + { + this->type=_text[0] >= '0' && _text[0] <= '9' ? NUMBER : IDENTIFER; + } + else{ + this->type = ERROR; + } +} +class Lexer +{ + private: + std::string text; + int filePos; + void read_char(char* chr,bool* esc) + { + int txt = text[filePos++]; + if(txt == '\\') + { + txt = text[filePos++]; + if(txt == 'x') + { + std::string txt="0x"; + filePos+=2; + for(int i = 0;i<2;i++) + { + txt += text[filePos++]; + } + *chr= (char)std::stol(txt,0,0); + }else + { + if(txt == 'n') + { + *chr= '\n'; + }else + if(txt == 'r') + { + *chr='\r'; + }else + if(txt == 't') + { + *chr='\t'; + }else{ + *chr = (char)txt; + } + } + *esc=true; + } + else{ + *esc=false; + *chr=(char)txt; + } + } + std::string read_string() + { + std::string b=""; + while(true) + { + char chr='\0'; + bool esc=false; + read_char(&chr,&esc); + if(chr == '\"' && !esc) + { + break; + } + b+=chr; + } + return b; + } + public: + Lexer(std::string _text) + { + this->text=_text; + this->filePos=0; + } + std::vector Lex() + { + std::vector tokens; + std::string b=""; + while(filePos < text.length()) + { + char c = text[filePos++]; + if(c == '\"') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + std::string str = read_string(); + LexToken token; + token.text = str; + token.type = STRING; + tokens.push_back(token); + }else if(c == '#') + { + while(text[filePos++] != '\n'); + } + else + if(c == '\'') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + char chr='\0'; + bool esc; + read_char(&chr,&esc); + LexToken token; + token.text=""; + token.text += chr; + token.type = NUMBER; + tokens.push_back(token); + + }else if(c == '+') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text="+"; + token.type = PLUS; + tokens.push_back(token); + }else if(c == '-') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text="-"; + token.type = MINUS; + tokens.push_back(token); + }else if(c == '+') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text="*"; + token.type = MULTIPLY; + tokens.push_back(token); + } + else if(c == '/') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text="/"; + token.type = DIVIDE; + tokens.push_back(token); + }else if(c == '%') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text="%"; + token.type = MOD; + tokens.push_back(token); + } + else if(c == '{') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text="{"; + token.type = LBRACE; + tokens.push_back(token); + } + else if(c == '}') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text="}"; + token.type = RBRACE; + tokens.push_back(token); + } + else if(c == '(') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text="("; + token.type = LPAREN; + tokens.push_back(token); + } + else if(c == ')') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text=")"; + token.type = RPAREN; + tokens.push_back(token); + } + else if(c == '=') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text="="; + token.type = EQUALS; + tokens.push_back(token); + } + else if(c == ',') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text=","; + token.type = COMMA; + tokens.push_back(token); + } + else if(c == ';') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + LexToken token; + token.text=";"; + token.type = SEMI; + tokens.push_back(token); + } + else if(c == '\n' || c == ' ' || c == '\t') + { + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + + }else{ + b += c; + } + } + if(b.length() > 0) + { + tokens.push_back(LexToken(b)); + b=""; + } + return tokens; + } + +}; +std::vector Lex(std::string text) +{ + Lexer l(text); + return l.Lex(); +} +}; \ No newline at end of file diff --git a/source/lexer.hpp b/source/lexer.hpp new file mode 100644 index 0000000..840f370 --- /dev/null +++ b/source/lexer.hpp @@ -0,0 +1,34 @@ +#pragma once +#include +#include +namespace BoxScript::Lexer +{ +enum LexTokenType +{ + PLUS, + MINUS, + MULTIPLY, + DIVIDE, + MOD, + LPAREN, + RPAREN, + IDENTIFER, + NUMBER, + EQUALS, + COMMA, + ERROR, + SEMI, + LBRACE, + RBRACE, + STRING +}; +class LexToken +{ + public: + std::string text; + LexTokenType type; + LexToken(); + LexToken(std::string _text); +}; +std::vector Lex(std::string text); +}; \ No newline at end of file diff --git a/source/networkstream.cpp b/source/networkstream.cpp new file mode 100644 index 0000000..969d64c --- /dev/null +++ b/source/networkstream.cpp @@ -0,0 +1,352 @@ + +#include "parser.hpp" +#include +#if defined(GEKKO) + int net_initialized = 0; + char bba_local_ip[16]; +char bba_netmask[16]; +char bba_gateway[16]; + #if defined(HW_DOL) + #include + +int bba_exists = 0; +unsigned int exi_get_id(int chn, int dev) +{ + u32 cid = 0; + EXI_GetID(chn,dev,&cid); + return cid; +} + +int exi_bba_exists() +{ + return exi_get_id(EXI_CHANNEL_0,EXI_DEVICE_2) == EXI_BBA_ID; +} + + + + #endif +#endif + + + + + +namespace BoxScript +{ +void sockets_free() +{ + #if defined(HW_RVL) && defined(LIBWIISOCKET) + wiisocket_deinit(); + #elif defined(HW_RVL) && !defined(LIBWIISOCKET) + net_deinit(); + #elif defined(_WIN32) || defined(WIN32) + WSACleanup(); + #endif +} + +int NetworkInit() +{ + #if defined(LIBWIISOCKET) + return wiisocket_init(); + #endif + #if defined(GEKKO) && !defined(LIBWIISOCKET) +int res; +#if defined(HW_DOL) + +bba_exists = exi_bba_exists(); + if(bba_exists && !net_initialized) { +#else + if(!net_initialized){ +#endif + res = if_config(bba_local_ip, bba_netmask, bba_gateway, true,20); + if(res >= 0 && strcmp("255.255.255.255", bba_local_ip)) { + net_initialized = 1; + } + else { + net_initialized = 0; + } + } + #elif defined(_WIN32) || defined(WIN32) + int err= WSAStartup(0x202, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + printf("WSAStartup failed with error: %d\n", err); + return 1; + } + +/* Confirm that the WinSock DLL supports 2.2.*/ +/* Note that if the DLL supports versions greater */ +/* than 2.2 in addition to 2.2, it will still return */ +/* 2.2 in wVersion since that is the version we */ +/* requested. */ + + if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + printf("Could not find a usable version of Winsock.dll\n"); + WSACleanup(); + return 1; + } + +#else + +#endif +return 0; +} + +NetworkStream::NetworkStream(SOCKET i) +{ + this->fd = i; +} + +void NetworkStream::Write(uint8_t* data,size_t len) +{ + #if defined(OGC_NETWORKING) + net_send(this->fd,data,len,0); + #else + int flags=0; + #if __linux__ + flags=MSG_NOSIGNAL; + #endif + send(this->fd,data,len,flags); + #endif +} +size_t NetworkStream::Read(uint8_t* data,size_t len) +{ + #if defined(OGC_NETWORKING) + ssize_t v=(ssize_t)net_recv(this->fd,data,len,0); + if(v < 0) return 0; + return (size_t)v; + #else + int flags=0; + #if __linux__ + flags=MSG_NOSIGNAL; + #endif + ssize_t v=recv(this->fd,data,len,flags); + if(v < 0) return 0; + return (size_t)v; + #endif +} +int64_t NetworkStream::GetPosition() +{ + return 0; +} +int64_t NetworkStream::GetLength() +{ + return 0; +} +void NetworkStream::SetPosition(int64_t pos) +{ + +} +void NetworkStream::Flush() +{ + +} +void NetworkStream::Close() +{ + #if defined(OGC_NETWORKING) + net_close(this->fd); + #else + close(this->fd); + #endif + +} +bool NetworkStream::CanRead() +{ + return true; +} +bool NetworkStream::CanWrite() +{ + return true; +} +bool NetworkStream::CanSeek() +{ + return false; +} +struct hostent* _______ghbn(string ip) +{ + #if defined(GEKKO) && !defined(LIBWIISOCKET) + return net_gethostbyname(ip.c_str()); + #else + return gethostbyname(ip.c_str()); + #endif +} + +NetworkStream* NetClient(string ip,int64_t port,SOCKET fd) + +{ + struct sockaddr_in serv_addr; + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons((uint16_t)port); + + if (inet_aton( ip.c_str(), &serv_addr.sin_addr) + <= 0) { + struct hostent* host=_______ghbn(ip); + struct in_addr **addr_list; + + addr_list = (struct in_addr **)host->h_addr_list; + if(host->h_length > 0) + { + memcpy(&serv_addr.sin_addr,addr_list[0],sizeof(struct in_addr)); + }else{ + return NULL; + } + } + + #if defined(GEKKO) && !defined(LIBWIISOCKET) + if(net_connect(fd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr_in))) + { + return NULL; + } + #else + if(connect(fd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr_in))) + { + return NULL; + } + #endif + return new NetworkStream(fd); +} +SOCKET NetServerInit(string ip,int64_t port,int fd) +{ + struct sockaddr_in serv_addr; + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(port); + + if (inet_aton( ip.c_str(), &serv_addr.sin_addr) + <= 0) { + struct hostent* host=_______ghbn(ip); + struct in_addr **addr_list; + + addr_list = (struct in_addr **)host->h_addr_list; + if(host->h_length > 0) + { + memcpy(&serv_addr.sin_addr,addr_list[0],sizeof(struct in_addr)); + }else{ + throw exception(); + } + } + #if defined(GEKKO) && !defined(LIBWIISOCKET) + if(net_bind(fd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr_in))< 0) + { + printf("bind error, is your computer already listening on that port\n"); + throw exception(); + } + if(net_listen(fd,100) > 0) + { + printf("listen error"); + throw exception(); + } + #else + if(bind(fd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr_in))< 0) + { + printf("bind error, is your computer already listening on that port\n"); + throw exception(); + } + if(listen(fd,100) > 0) + { + printf("listen error"); + throw exception(); + } + #endif + return fd; +} + +SOCKET TcpServerInit(string ip,int64_t port) +{ + SOCKET fd; + + #if defined(GEKKO) && !defined(LIBWIISOCKET) + if ((fd = net_socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("\n Socket creation error \n"); + return -1; + } + #else + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("\n Socket creation error \n"); + return -1; + } + #endif + return NetServerInit(ip,port,fd); +} +SOCKET UdpServerInit(string ip,int64_t port) +{ + SOCKET fd; + + #if defined(GEKKO) && !defined(LIBWIISOCKET) + if ((fd = net_socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("\n Socket creation error \n"); + return -1; + } + #else + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("\n Socket creation error \n"); + return -1; + } + #endif + return NetServerInit(ip,port,fd); +} + + +Stream* AcceptClient(SOCKET fd,string* ip) +{ + struct sockaddr_in clt_addr; + socklen_t clt_addr_len = sizeof(struct sockaddr_in); + #if defined(GEKKO) && !defined(LIBWIISOCKET) + int cltFd=net_accept(fd,(struct sockaddr*)&clt_addr,&clt_addr_len); + #else + #if defined(_WIN32) || defined(WIN32) + SOCKET cltFd=accept(fd,(struct sockaddr*)&clt_addr,&clt_addr_len); + #else + int cltFd=accept(fd,(struct sockaddr*)&clt_addr,&clt_addr_len); + #endif + #endif + ip->append(inet_ntoa(clt_addr.sin_addr)); + + return new NetworkStream(cltFd); +} +NetworkStream* TcpClient(string ip,int64_t port) +{ + + #if defined(_WIN32) || defined(WIN32) + SOCKET fd; + #else + int fd; + #endif + #if defined(GEKKO) && !defined(LIBWIISOCKET) + if ((fd = net_socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("\n Socket creation error \n"); + return NULL; + } + #else + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("\n Socket creation error \n"); + return NULL; + } + #endif + return NetClient(ip,port,fd); +} + +NetworkStream* UdpClient(string ip,int64_t port) +{ + #if defined(_WIN32) || defined(WIN32) + SOCKET fd; + #else + int fd; + #endif + #if defined(GEKKO) && !defined(LIBWIISOCKET) + if ((fd = net_socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("\n Socket creation error \n"); + return NULL; + } + #else + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("\n Socket creation error \n"); + return NULL; + } + #endif + return NetClient(ip,port,fd); +} + +}; \ No newline at end of file diff --git a/source/parser.cpp b/source/parser.cpp new file mode 100644 index 0000000..101cf1d --- /dev/null +++ b/source/parser.cpp @@ -0,0 +1,984 @@ +#include "parser.hpp" +#include +#include +namespace BoxScript +{ + void IApplicationState::AddThreadOwner() + { + + } + void IApplicationState::RemoveThreadOwner() + { + + } + void SubscopeApplicationState::AddThreadOwner() + { + this->state->AddThreadOwner(); + this->threads++; + } + void SubscopeApplicationState::RemoveThreadOwner() + { + this->state->RemoveThreadOwner(); + if(this->threads <= 0) + { + delete this; + } + } + ApplicationState::ApplicationState() + { + this->isRunning=true; + this->NoBoxes=0; + this->NoExpressions=0; + this->NoStreams=0; + } + int64_t ApplicationState::CreateBox(string text) + { + int64_t boxId=this->NoBoxes++; + if(this->boxes.count(boxId) <= 0) + { + this->boxes.insert({boxId,{vector(), false}}); + } + for(int i =0;iboxes[boxId].first.push_back(text[i]); + } + + return boxId; + } + + Expression* ApplicationState::Calln(int64_t e) + { + if(this->expressions.count(e) > 0) + { + return expressions[e]; + } + return new ConstantNumber("0"); + } + int64_t ApplicationState::ReadByteFromStream(int64_t streamId) + { + Stream* strm = GetStream(streamId); + return strm->ReadByte(); + } + int64_t ApplicationState::CreateBufferedStream(int64_t existingStreamId) + { + Stream* strm = GetStream(existingStreamId); + return CreateStream(new BufferedStream(strm)); + } + int64_t ApplicationState::e2n(Expression* e) + { + int64_t eId = this->NoExpressions++; + this->expressions.insert({eId,e}); + return eId; + } + string ApplicationState::BoxToString(int64_t boxId) + { + string s =""; + if(boxes.count(boxId) == 0) + { + throw exception(); + } + else + { + for(int i =0;iboxes.count(i) <= 0) + { + this->boxes.insert({i,{vector(), false}}); + } + this->boxes[i].first.reserve(boxLen); + return i; + } + void ApplicationState::AddRuntimeFunction(string str,internal_func func) + { + if(!HasRuntimeFunction(str)) + { + runtime_funcs.insert({str,func}); + } + } + + void ApplicationState::DestroyBox(int64_t boxId) + { + if(boxes.count(boxId) == 0) return; + if(!boxes[boxId].second) + { + boxes[boxId].first.clear(); + boxes.erase(boxId); + } + } + int64_t ApplicationState::CreateStream(Stream* strm) + { + int64_t i = NoStreams++; + streams.insert({i,strm}); + return i; + } + int64_t ApplicationState::GetBoxValue(int64_t bId,int index) + { + if(boxes.count(bId) == 0) + { + throw exception(); + }else + { + if(index>boxes[bId].first.size()) + { + throw exception(); + }else{ + return boxes[bId].first[index]; + } + } + } + void ApplicationState::SetBoxValue(int64_t bId,int index,int64_t value) + { + if(value > 2147483647) throw exception(); + + if(boxes.count(bId) == 0) + { + throw exception(); + } + else + { + if(boxes[bId].second) throw new exception(); + if(index > boxes[bId].first.size()) + { + throw exception(); + }else{ + boxes[bId].first[index] = value; + } + } + } + bool ApplicationState::HasVariable(string name) + { + return variables.count(name) > 0; + } + int64_t ApplicationState::GetVariable(string name) + { + if(variables.count(name) > 0) + { + return variables[name]; + }else{ + return 0; + } + } + IApplicationState* ApplicationState::NewScope() + { + return new SubscopeApplicationState(this); + } + void ApplicationState::SetVariable(string name,int64_t value) + { + if(variables.count(name) > 0) + { + variables[name]=value; + }else{ + variables.insert({name,value}); + } + } + void ApplicationState::ClearBox(int64_t bId) + { + if(boxes.count(bId) == 0) + { + throw exception(); + } + else + { + if(boxes[bId].second) throw exception(); + boxes[bId].first.clear(); + } + } + void ApplicationState::AddToBox(int64_t bId,int64_t value) + { + if(boxes.count(bId) == 0) + { + throw exception(); + }else + { + if(boxes[bId].second) throw exception(); + boxes[bId].first.push_back(value); + } + } + void ApplicationState::RemoveFromBox(int64_t bId,int64_t value) + { + if(boxes.count(bId)==0) + { + throw exception(); + } + else + { + if(boxes[bId].second) throw exception(); + vector::iterator itr= find(boxes[bId].first.begin(),boxes[bId].first.end(),value); + if(itr < boxes[bId].first.end()) + { + boxes[bId].first.erase(itr); + } + } + } + void ApplicationState::RemoveAtFromBox(int64_t bId,int index) + { + if(boxes.count(bId)==0) + { + throw exception(); + } + else + { + if(boxes[bId].second) throw exception(); + vector::iterator itr= boxes[bId].first.begin() + index; + if(itr < boxes[bId].first.end()) + { + boxes[bId].first.erase(itr); + } + } + } + void ApplicationState::InsertToBox(int64_t bId,int index,int64_t value) + { + if(boxes.count(bId)==0) + { + throw exception(); + } + else + { + if(boxes[bId].second) throw exception(); + vector::iterator itr= boxes[bId].first.begin() + index; + if(itr != boxes[bId].first.end()) + { + boxes[bId].first.insert(itr,value); + } + + } + } + int64_t ApplicationState::BoxLength(int64_t boxId) + { + if(boxes.count(boxId)==0) + { + throw exception(); + } + else + { + return boxes[boxId].first.size(); + } + } + bool ApplicationState::HasRuntimeFunction(string str) + { + return runtime_funcs.count(str) > 0; + } + internal_func ApplicationState::GetRuntimeFunction(string str) + { + return runtime_funcs[str]; + } + int64_t ApplicationState::ExecuteFunction(string str,vector expressions) + { + if(!HasFunction(str)) return 0; + //var func=methods[str] + IApplicationState* res = NewScope(); + res->AddThreadOwner(); + for(int i = 0;iSetVariable(methods[str].first[i],expressions[i]->Evaluate(res)); + } + int64_t result= methods[str].second->Evaluate(res); + res->RemoveThreadOwner(); + return result; + } + int64_t ApplicationState::CreateBoxPermanent(string text) + { + int64_t boxId=this->NoBoxes++; + if(this->boxes.count(boxId) <= 0) + { + this->boxes.insert({boxId,{vector(), true}}); + } + for(int i =0;iboxes[boxId].first.push_back(text[i]); + } + + return boxId; + } + bool ApplicationState::HasFunction(string str) + { + return methods.count(str) > 0; + } + void ApplicationState::AddFunction(string str,vector args,Expression* exp) + { + if(!HasFunction(str)) + { + methods.insert({str,{args,exp}}); + } + } + void ApplicationState::CopyStream(int64_t src,int64_t dest) + { + if(streams.count(src) == 0 || streams.count(dest) == 0) return; + GetStream(src)->CopyTo(GetStream(dest)); + } + Stream* ApplicationState::GetStream(int64_t streamId) + { + if(streams.count(streamId) == 0) throw exception(); + return streams[streamId]; + } + void ApplicationState::CloseStream(int64_t streamId) + { + + if(streams.count(streamId)==0) throw exception(); + streams[streamId]->Close(); + delete streams[streamId]; + streams.erase(streamId); + + } + void ApplicationState::WriteToStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len) + { + if(streams.count(streamId) == 0) return; + Stream* strm=GetStream(streamId); + if(!strm->CanWrite())return; + size_t len2=boxes[boxId].first.size(); + len2-=offset; + int64_t len3=min(len,(int64_t)len2); + uint8_t data[len3]; + for(int64_t i = 0;iWrite(data,(size_t)len3); + } + int64_t ApplicationState::ReadFromStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len) + { + if(streams.count(streamId) == 0) return 0; + Stream* strm=GetStream(streamId); + if(boxes[boxId].second || !strm->CanRead()) return 0; + size_t len2=boxes[boxId].first.size(); + len2-=offset; + int64_t len3=min(len,(int64_t)len2); + uint8_t data[len3]; + len3=strm->Read(data,len3); + for(int64_t i = 0;iCanSeek()) return; + strm->SetPosition(streamPos); + } + int64_t ApplicationState::GetStreamLength(int64_t streamId) + { + if(streams.count(streamId) == 0) return 0; + Stream* strm=GetStream(streamId); + return strm->GetLength(); + } + int64_t ApplicationState::GetStreamPosition(int64_t streamId) + { + if(streams.count(streamId) == 0) return 0; + Stream* strm=GetStream(streamId); + if(!strm->CanSeek()) return 0; + return strm->GetPosition(); + } + bool ApplicationState::CanRead(int64_t streamId) + { + if(streams.count(streamId) == 0) return false; + return GetStream(streamId)->CanRead(); + } + bool ApplicationState::CanWrite(int64_t streamId) + { + if(streams.count(streamId) == 0) return false; + return GetStream(streamId)->CanWrite(); + } + bool ApplicationState::CanSeek(int64_t streamId) + { + if(streams.count(streamId) == 0) return false; + return GetStream(streamId)->CanSeek(); + } + void ApplicationState::FlushStream(int64_t streamId) + { + if(streams.count(streamId) == 0) return; + GetStream(streamId)->Flush(); + } + + #pragma region SubscopeApplicationState + SubscopeApplicationState::SubscopeApplicationState(IApplicationState* _state) + { + this->threads=0; + this->state=_state; + } + internal_func SubscopeApplicationState::GetRuntimeFunction(string str) + { + return this->state->GetRuntimeFunction(str); + } + void SubscopeApplicationState::FlushStream(int64_t stream) + { + this->state->FlushStream(stream); + } + void SubscopeApplicationState::DestroyBox(int64_t id) + { + this->state->DestroyBox(id); + } + int64_t SubscopeApplicationState::e2n(Expression* e) + { + return this->state->e2n(e); + } + Expression* SubscopeApplicationState::Calln(int64_t e) + { + return this->state->Calln(e); + } + int64_t SubscopeApplicationState::CreateStream(Stream* strm) + { + return this->state->CreateStream(strm); + } + void SubscopeApplicationState::CopyStream(int64_t strmSrc,int64_t strmDest) + { + this->state->CopyStream(strmSrc,strmDest); + } + void SubscopeApplicationState::CloseStream(int64_t streamId) + { + this->state->CloseStream(streamId); + } + void SubscopeApplicationState::WriteToStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len) + { + this->state->WriteToStream(streamId,boxId,offset,len); + } + int64_t SubscopeApplicationState::ReadFromStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len) + { + return this->state->ReadFromStream(streamId,boxId,offset,len); + } + void SubscopeApplicationState::SetStreamPosition(int64_t streamId,int64_t streamPos) + { + this->state->SetStreamPosition(streamId,streamPos); + } + int64_t SubscopeApplicationState::GetStreamPosition(int64_t streamId) + { + return this->state->GetStreamPosition(streamId); + } + int64_t SubscopeApplicationState::GetStreamLength(int64_t streamId) + { + return this->state->GetStreamLength(streamId); + } + bool SubscopeApplicationState::CanRead(int64_t streamId) + { + return this->state->CanRead(streamId); + } + bool SubscopeApplicationState::CanWrite(int64_t streamId) + { + return this->state->CanWrite(streamId); + } + bool SubscopeApplicationState::CanSeek(int64_t streamId) + { + return this->state->CanSeek(streamId); + } + int64_t SubscopeApplicationState::ExecuteFunction(string str,vector expressions) + { + return this->state->ExecuteFunction(str,expressions); + } + bool SubscopeApplicationState::HasRuntimeFunction(string str) + { + return this->state->HasRuntimeFunction(str); + } + bool SubscopeApplicationState::HasFunction(string str) + { + return this->state->HasFunction(str); + } + void SubscopeApplicationState::AddFunction(string str,vector args,Expression* exp) + { + this->state->AddFunction(str,args,exp); + } + void SubscopeApplicationState::AddRuntimeFunction(string str,internal_func func) + { + this->state->AddRuntimeFunction(str,func); + } + string SubscopeApplicationState::BoxToString(int64_t boxId) + { + return this->state->BoxToString(boxId); + } + void SubscopeApplicationState::ClearBox(int64_t bId) + { + this->state->ClearBox(bId); + } + int64_t SubscopeApplicationState::ReadByteFromStream(int64_t streamId) + { + return this->state->ReadByteFromStream(streamId); + } + int64_t SubscopeApplicationState::CreateBufferedStream(int64_t existingStreamId) + { + return this->state->CreateBufferedStream(existingStreamId); + } + void SubscopeApplicationState::AddToBox(int64_t bId,int64_t value) + { + this->state->AddToBox(bId,value); + } + void SubscopeApplicationState::RemoveFromBox(int64_t bId,int64_t value) + { + this->state->RemoveFromBox(bId,value); + } + void SubscopeApplicationState::RemoveAtFromBox(int64_t bId,int index) + { + this->state->RemoveAtFromBox(bId,index); + } + void SubscopeApplicationState::InsertToBox(int64_t bId,int index,int64_t value) + { + this->state->InsertToBox(bId,index,value); + } + void SubscopeApplicationState::SetBoxValue(int64_t bId,int index,int64_t value) + { + this->state->SetBoxValue(bId,index,value); + } + int64_t SubscopeApplicationState::BoxLength(int64_t boxId) + { + return this->state->BoxLength(boxId); + } + int64_t SubscopeApplicationState::CreateBox(int len) + { + return this->state->CreateBox(len); + } + int64_t SubscopeApplicationState::CreateBox(string text) + { + return this->state->CreateBox(text); + } + int64_t SubscopeApplicationState::CreateBoxPermanent(string text) + { + return this->state->CreateBoxPermanent(text); + } + int64_t SubscopeApplicationState::GetBoxValue(int64_t bId, int index) + { + return this->state->GetBoxValue(bId,index); + } + bool SubscopeApplicationState::HasVariable(string name) + { + return variables.count(name) > 0 || (name.substr(0,4) != "cur." && this->state->HasVariable(name)); + } + void SubscopeApplicationState::SetVariable(string name,int64_t value) + { + if(name.substr(0,4) != "cur." && state->HasVariable(name)) + { + this->state->SetVariable(name,value); + }else{ + if(this->variables.count(name) > 0) + { + variables[name]=value; + }else{ + variables.insert({name,value}); + } + } + } + int64_t SubscopeApplicationState::GetVariable(string name) + { + if(name.substr(0,4) != "cur." && state->HasVariable(name)) + { + return this->state->GetVariable(name); + }else{ + if(this->variables.count(name) > 0) return this->variables[name]; + } + return 0; + } + + + IApplicationState* SubscopeApplicationState::NewScope() + { + return new SubscopeApplicationState(this); + } + #pragma endregion + + + void Stream::CopyTo(Stream* strm) + { + uint8_t buffer[4096]; + size_t read; + do + { + read = this->Read(buffer,4096); + strm->Write(buffer,read); + } while (read != 0); + + } + + ExpressionStream::ExpressionStream(IApplicationState* state,vector expressions) + { + this->st = state; + this->exp = exp; + + } + void ExpressionStream::Write(uint8_t* data,size_t len) + { + int64_t box = st->CreateBox((int64_t)len); + IApplicationState* newSc = st->NewScope(); + newSc->AddThreadOwner(); + newSc->SetVariable("stream_count_value",len); + newSc->SetVariable("stream_buffer",box); + + for(size_t i = 0;iAddToBox(box,data[i]); + } + exp[1]->Evaluate(newSc); + newSc->DestroyBox(box); + newSc->RemoveThreadOwner(); + } + size_t ExpressionStream::Read(uint8_t* data,size_t len) + { + int64_t box = st->CreateBox((int64_t)len); + IApplicationState* newSc = st->NewScope(); + newSc->AddThreadOwner(); + newSc->SetVariable("stream_count_value",len); + newSc->SetVariable("stream_buffer",box); + size_t read = (size_t)exp[0]->Evaluate(newSc); + for(size_t i = 0;iGetBoxValue(box,(int)i); + data[i]=v; + } + newSc->DestroyBox(box); + newSc->RemoveThreadOwner(); + return min(read,len); + } + int64_t ExpressionStream::GetPosition() + { + //3 + return exp[3]->Evaluate(st); + } + int64_t ExpressionStream::GetLength() + { + //4 + return exp[4]->Evaluate(st) > 0; + } + void ExpressionStream::SetPosition(int64_t pos) + { + //2 + IApplicationState* newSc = st->NewScope(); + newSc->AddThreadOwner(); + newSc->SetVariable("stream_length_value",pos); + exp[2]->Evaluate(newSc); + newSc->RemoveThreadOwner(); + } + void ExpressionStream::Flush() + { + //8 + exp[8]->Evaluate(st); + } + void ExpressionStream::Close() + { + //9 + exp[9]->Evaluate(st); + } + bool ExpressionStream::CanRead() + { + //5 + return exp[5]->Evaluate(st) > 0; + } + bool ExpressionStream::CanWrite() + { + //6 + return exp[6]->Evaluate(st) > 0; + } + bool ExpressionStream::CanSeek() + { + //7 + return exp[7]->Evaluate(st) > 0; + } + FileStream::FileStream(FILE* fs,bool canRead,bool canWrite,bool canSeek,bool ownFile) + { + this->f=fs; + this->cr = canRead; + this->cw = canWrite; + this->cs = canSeek; + this->own=ownFile; + } + bool FileStream::CanSeek() + { + return this->cs; + } + bool FileStream::CanRead() + { + return this->cr; + } + bool FileStream::CanWrite() + { + return this->cw; + } + void FileStream::Write(uint8_t* data,size_t len) + { + if(!cw) return; + fwrite(data,1,len,f); + } + size_t FileStream::Read(uint8_t* data,size_t len) + { + if(!cr) return 0; + return fread(data,1,len,f); + } + void FileStream::Flush() + { + fflush(f); + } + void FileStream::Close() + { + if(own) + fclose(f); + } + int64_t FileStream::GetPosition() + { + if(!cs) return 0; + return (int64_t)ftello(f); + } + int64_t FileStream::GetLength() + { + if(!cs) return 0; + fpos_t pos; + + + fgetpos(f,&pos); + fseeko(f,0,SEEK_END); + int64_t len= (int64_t)ftello(f); + fsetpos(f,&pos); + return len; + } + void FileStream::SetPosition(int64_t pos) + { + if(!cs) return; + fseeko(f,(off_t)pos,SEEK_SET); + } + +void Parse(ListNode* node,vector tokens) +{ + int i = 0; + ParseNode(node,tokens,&i,true); +} +ListNode* Parse(vector tokens) +{ + ListNode* node = new ListNode(); + Parse(node,tokens); + return node; +} +void ParseNode(ListNode* node,vector tokens,int* i) +{ + ParseNode(node,tokens,i,false); +} +void ParseNode(ListNode* node,vector tokens,int* i,bool root) +{ + node->root = root; + while(*i < tokens.size() && tokens[*i].type != Lexer::RBRACE) + { + if(tokens[*i].type == Lexer::SEMI) (*i)++; + if(*i+2 < tokens.size() && tokens[*i+1].type == Lexer::EQUALS ) + { + string varname = tokens[*i].text; + *i=*i+2; + node->nodes.push_back(new SetVariableNode(ParseExpression(tokens,i),varname)); + if(!root && *inodes.push_back(ParseExpression(tokens,i)); + if(!root && *inodes.push_back(ParseExpression(tokens,i)); + if(!root && *i tokens,int* i) +{ + Expression* res = ParseTerm(tokens,i); + while(*i < tokens.size() && (tokens[*i].type == Lexer::PLUS||tokens[*i].type == Lexer::MINUS)) + { + if(*i < tokens.size() && tokens[*i].type == Lexer::PLUS) + { + (*i)++; + res = (Expression*)new AddNode(res,ParseTerm(tokens,i)); + } + if(*i < tokens.size() && tokens[*i].type == Lexer::MINUS) + { + (*i)++; + res = (Expression*)new MinusNode(res,ParseTerm(tokens,i)); + } + } + return res; +} +Expression* ParseTerm(vector tokens,int* i) +{ + Expression* res = ParseFactor(tokens,i); + while(*i < tokens.size() && (tokens[*i].type == Lexer::MULTIPLY||tokens[*i].type == Lexer::DIVIDE ||tokens[*i].type == Lexer::MOD)) + { + if(*i < tokens.size() && tokens[*i].type == Lexer::MULTIPLY) + { + (*i)++; + res = (Expression*)new MultiplyNode(res,ParseFactor(tokens,i)); + } + if(*i < tokens.size() && tokens[*i].type == Lexer::DIVIDE) + { + (*i)++; + res = (Expression*)new DivideNode(res,ParseFactor(tokens,i)); + } + if(*i < tokens.size() && tokens[*i].type == Lexer::MOD) + { + (*i)++; + res = (Expression*)new ModulusNode(res,ParseFactor(tokens,i)); + } + } + return res; +} +Expression* ParseFactor(vector tokens,int* i) +{ + if(*i>=tokens.size()) throw exception(); + Lexer::LexToken token = tokens[*i]; + if(token.type == Lexer::LPAREN) + { + (*i)++; + Expression* res = ParseExpression(tokens,i); + if(*i>=tokens.size()) throw exception(); + if(tokens[*i].type != Lexer::RPAREN) throw exception(); + (*i)++; + return res; + } + if(token.type == Lexer::LBRACE) + { + (*i)++; + ListNode* res = new ListNode(); + ParseNode(res,tokens,i,false); + if(*i>=tokens.size()) throw exception(); + if(tokens[*i].type != Lexer::RBRACE) throw exception(); + (*i)++; + return (Expression*)res; + } + if(token.type == Lexer::IDENTIFER) + { + (*i)++; + if(*i funcArgs; + (*i)++; + while(*i exp; + this->isRunning=(bool)this->ExecuteFunction("stopinterrupt",exp); +} +void ApplicationState::ExitIfNotRunning() +{ + if(!isRunning) + { + exit(0); + } +} +void SubscopeApplicationState::StopRunning() +{ + this->state->StopRunning(); +} +void SubscopeApplicationState::ExitIfNotRunning() +{ + this->state->ExitIfNotRunning(); +} + +#pragma region "BufferedStream" +BufferedStream::BufferedStream(Stream* parent) +{ + + this->strm = parent; + +} +int64_t Stream::ReadByte() +{ + uint8_t buffer[1]; + return this->Read(buffer,1) > 0 ? buffer[0] : -1; +} +int64_t BufferedStream::ReadByte() +{ + if(posreadIn,4096)) + { + return (int64_t)this->buffer[this->pos]; + }else{ + this->readIn=this->strm->Read(this->buffer,4096); + this->pos = 0; + + if(this->readIn > 0) + { + return this->buffer[this->pos++]; + }else{ + return -1; + } + + + + } +} +void BufferedStream::Write(uint8_t* data,size_t len) +{ + this->strm->Write(data,len); +} + size_t BufferedStream::Read(uint8_t* data,size_t len) + { + if(this->posreadIn,4096) && this->pos > 0) + { + int _len=min((int)this->readIn-this->pos,(int)len); + memcpy(data,this->buffer + this->pos,_len); + this->pos+=_len; + return _len; + }else{ + return this->strm->Read(data,len); + } + } + int64_t BufferedStream::GetPosition() + { + return 0; + } + int64_t BufferedStream::GetLength() + { + return 0; + } + void BufferedStream::SetPosition(int64_t pos) + { + + } + void BufferedStream::Flush() + { + this->strm->Flush(); + } + void BufferedStream::Close() + { + + } + bool BufferedStream::CanRead() + { + return this->strm->CanRead(); + } + bool BufferedStream::CanWrite() + { + return this->strm->CanWrite(); + } + bool BufferedStream::CanSeek() + { + return false; + } +#pragma endregion +}; diff --git a/source/parser.hpp b/source/parser.hpp new file mode 100644 index 0000000..9bb924a --- /dev/null +++ b/source/parser.hpp @@ -0,0 +1,537 @@ +#pragma once + +#define _FILE_OFFSET_BITS 64 +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "lexer.hpp" + +#if defined(GEKKO) && !defined(LIBWIISOCKET) + #define OGC_NETWORKING + #include + typedef int SOCKET; +#elif defined(_WIN32) || defined(WIN32) + #define WINDOWS_NETWORKING +#include +#include +#include +#include + #pragma comment(lib, "ws2_32.lib") + WSADATA wsaData; +#else + typedef int SOCKET; + #define SYS_SOCKET_NETWORKING + #if defined(HW_RVL) && defined(LIBWIISOCKET) + #include + #endif + #include + #include + #include + #include + +#endif +using namespace std; + +namespace BoxScript +{ +class Expression; +class Stream; +class IApplicationState; +class ConstantNumber; + +class Expression +{ + public: + virtual void DisableScope(); + virtual string GetNodeName()=0; + virtual int64_t Evaluate(IApplicationState* state)=0; + +}; + +class Stream +{ + public: + void CopyTo(Stream* strm); + virtual int64_t ReadByte(); + virtual void Write(uint8_t* data,size_t len)=0; + virtual size_t Read(uint8_t* data,size_t len)=0; + virtual int64_t GetPosition()=0; + virtual int64_t GetLength()=0; + virtual void SetPosition(int64_t pos)=0; + virtual void Flush()=0; + virtual void Close()=0; + virtual bool CanRead()=0; + virtual bool CanWrite()=0; + virtual bool CanSeek()=0; + +}; +class BufferedStream : public Stream +{ + private: + Stream* strm; + int16_t pos=-1; + int16_t readIn=-1; + uint8_t buffer[4096]; + public: + BufferedStream(Stream* parent); + int64_t ReadByte(); + void Write(uint8_t* data,size_t len); + size_t Read(uint8_t* data,size_t len); + int64_t GetPosition(); + int64_t GetLength(); + void SetPosition(int64_t pos); + void Flush(); + void Close(); + bool CanRead(); + bool CanWrite(); + bool CanSeek(); +}; +class NetworkStream : public Stream +{ + private: + SOCKET fd; + + public: + + NetworkStream(SOCKET i); + + void Write(uint8_t* data,size_t len); + size_t Read(uint8_t* data,size_t len); + int64_t GetPosition(); + int64_t GetLength(); + void SetPosition(int64_t pos); + void Flush(); + void Close(); + bool CanRead(); + bool CanWrite(); + bool CanSeek(); +}; +typedef int64_t (*internal_func)(IApplicationState* state,vector expressions); +class IApplicationState +{ + public: + virtual void StopRunning()=0; + virtual void ExitIfNotRunning()=0; + virtual void AddThreadOwner(); + virtual void RemoveThreadOwner(); + virtual void FlushStream(int64_t stream)=0; + virtual void DestroyBox(int64_t id)=0; + virtual int64_t e2n(Expression* e)=0; + virtual Expression* Calln(int64_t e)=0; + virtual int64_t CreateStream(Stream* strm)=0; + virtual internal_func GetRuntimeFunction(string str)=0; + virtual void CopyStream(int64_t strmSrc,int64_t strmDest)=0; + + virtual void CloseStream(int64_t streamId)=0; + + virtual void WriteToStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len)=0; + + virtual int64_t ReadFromStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len)=0; + virtual int64_t ReadByteFromStream(int64_t streamId)=0; + virtual int64_t CreateBufferedStream(int64_t existingStreamId)=0; + virtual void SetStreamPosition(int64_t streamId,int64_t streamPos)=0; + + virtual int64_t GetStreamPosition(int64_t streamId)=0; + + virtual int64_t GetStreamLength(int64_t streamId)=0; + + virtual bool CanRead(int64_t streamId)=0; + virtual bool CanWrite(int64_t streamId)=0; + virtual bool CanSeek(int64_t streamId)=0; + + virtual int64_t ExecuteFunction(string str,vector expressions)=0; + virtual bool HasRuntimeFunction(string str)=0; + virtual bool HasFunction(string str)=0; + virtual void AddFunction(string str,vector args,Expression* exp)=0; + virtual void AddRuntimeFunction(string str,internal_func func)=0; + virtual string BoxToString(int64_t boxId)=0; + virtual void ClearBox(int64_t bId)=0; + virtual void AddToBox(int64_t bId,int64_t value)=0; + virtual void RemoveFromBox(int64_t bId,int64_t value)=0; + virtual void RemoveAtFromBox(int64_t bId,int index)=0; + virtual void InsertToBox(int64_t bId,int index,int64_t value)=0; + + virtual void SetBoxValue(int64_t bId,int index,int64_t value)=0; + virtual void SetVariable(string name,int64_t value)=0; + virtual int64_t GetVariable(string name)=0; + + virtual int64_t BoxLength(int64_t boxId)=0; + + virtual int64_t CreateBox(int len)=0; + virtual int64_t CreateBox(string text)=0; + virtual int64_t CreateBoxPermanent(string text)=0; + virtual int64_t GetBoxValue(int64_t bId, int index)=0; + virtual bool HasVariable(string name)=0; + + virtual IApplicationState* NewScope()=0; +}; + + +class ApplicationState : public IApplicationState +{ + private: + unordered_map,bool>> boxes; + unordered_map expressions; + unordered_map streams; + unordered_map variables; + unordered_map,Expression*>> methods; + unordered_map runtime_funcs; + atomic_int64_t NoBoxes; + atomic_int64_t NoStreams; + atomic_int64_t NoExpressions; + atomic_bool isRunning; + + public: + void StopRunning(); + void ExitIfNotRunning(); + ApplicationState(); + internal_func GetRuntimeFunction(string str); + void FlushStream(int64_t stream); + void DestroyBox(int64_t id); + int64_t e2n(Expression* e); + Expression* Calln(int64_t e); + int64_t CreateStream(Stream* strm); + + void CopyStream(int64_t strmSrc,int64_t strmDest); + + void CloseStream(int64_t streamId); + + void WriteToStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len); + + int64_t ReadFromStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len); + + void SetStreamPosition(int64_t streamId,int64_t streamPos); + + int64_t GetStreamPosition(int64_t streamId); + + int64_t GetStreamLength(int64_t streamId); + + + + bool CanRead(int64_t streamId); + bool CanWrite(int64_t streamId); + bool CanSeek(int64_t streamId); + + int64_t ExecuteFunction(string str,vector expressions); + bool HasRuntimeFunction(string str); + bool HasFunction(string str); + void AddFunction(string str,vector args,Expression* exp); + void AddRuntimeFunction(string str,internal_func func); + string BoxToString(int64_t boxId); + void ClearBox(int64_t bId); + void AddToBox(int64_t bId,int64_t value); + void RemoveFromBox(int64_t bId,int64_t value); + void RemoveAtFromBox(int64_t bId,int index); + void InsertToBox(int64_t bId,int index,int64_t value); + int64_t ReadByteFromStream(int64_t streamId); + int64_t CreateBufferedStream(int64_t existingStreamId); + void SetBoxValue(int64_t bId,int index,int64_t value); + void SetVariable(string name,int64_t value); + int64_t GetVariable(string name); + + int64_t BoxLength(int64_t boxId); + + int64_t CreateBox(int len); + int64_t CreateBox(string text); + int64_t CreateBoxPermanent(string text); + int64_t GetBoxValue(int64_t bId, int index); + bool HasVariable(string name); + + IApplicationState* NewScope(); + + private: + Stream* GetStream(int64_t id); +}; +class SubscopeApplicationState : public IApplicationState +{ + + private: + atomic_char threads; + IApplicationState* state; + unordered_map variables; + public: + void StopRunning(); + void ExitIfNotRunning(); + void AddThreadOwner(); + void RemoveThreadOwner(); + SubscopeApplicationState(IApplicationState* _state); + void FlushStream(int64_t stream); + void DestroyBox(int64_t id); + int64_t e2n(Expression* e); + Expression* Calln(int64_t e); + int64_t CreateStream(Stream* strm); + + void CopyStream(int64_t strmSrc,int64_t strmDest); + + void CloseStream(int64_t streamId); + + void WriteToStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len); + int64_t ReadByteFromStream(int64_t streamId); + int64_t CreateBufferedStream(int64_t existingStreamId); + int64_t ReadFromStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len); + + void SetStreamPosition(int64_t streamId,int64_t streamPos); + + int64_t GetStreamPosition(int64_t streamId); + + int64_t GetStreamLength(int64_t streamId); + + + + bool CanRead(int64_t streamId); + bool CanWrite(int64_t streamId); + bool CanSeek(int64_t streamId); + + int64_t ExecuteFunction(string str,vector expressions); + internal_func GetRuntimeFunction(string str); + bool HasRuntimeFunction(string str); + bool HasFunction(string str); + void AddFunction(string str,vector args,Expression* exp); + void AddRuntimeFunction(string str,internal_func func); + string BoxToString(int64_t boxId); + void ClearBox(int64_t bId); + void AddToBox(int64_t bId,int64_t value); + void RemoveFromBox(int64_t bId,int64_t value); + void RemoveAtFromBox(int64_t bId,int index); + void InsertToBox(int64_t bId,int index,int64_t value); + + void SetBoxValue(int64_t bId,int index,int64_t value); + void SetVariable(string name,int64_t value); + int64_t GetVariable(string name); + + int64_t BoxLength(int64_t boxId); + + int64_t CreateBox(int len); + int64_t CreateBox(string text); + int64_t CreateBoxPermanent(string text); + int64_t GetBoxValue(int64_t bId, int index); + bool HasVariable(string name); + + IApplicationState* NewScope(); +}; + + +class ConstantNumber : public Expression +{ + private: + int64_t num; + public: + string GetNodeName(); + ConstantNumber(string num); + int64_t Evaluate(IApplicationState* state); +}; +/*public class VariableGetValueNode : Expression + { + public string Name {get{return var;}} + string var; + public VariableGetValueNode(string var) + { + this.var=var; + } + + public override long Evaluate(IApplicationState state) + { + return state.GetVariable(var); + } + }*/ +class VariableGetValueNode : public Expression +{ + private: + string var; + public: + string GetName(); + string GetNodeName(); + VariableGetValueNode(string var); + int64_t Evaluate(IApplicationState* state); +}; +#pragma region "StringNode" +class StringNode : public Expression +{ + private: + string text; + int64_t boxId; + public: + string GetText(); + string GetNodeName(); + StringNode(string var); + int64_t Evaluate(IApplicationState* state); + +}; +#pragma endregion +#pragma region "SetVariableNode" +class SetVariableNode : public Expression +{ + private: + Expression* e; + string vname; + public: + ~SetVariableNode(); + string GetNodeName(); + SetVariableNode(Expression* expression,string name); + int64_t Evaluate(IApplicationState* state); +}; +#pragma endregion +#pragma region "FunctionCallNode" +class FunctionCallNode :public Expression +{ + private: + string name; + vector expressions; + public: + ~FunctionCallNode(); + string GetNodeName(); + FunctionCallNode(string _name,vector exps); + int64_t Evaluate(IApplicationState* state); + +}; +#pragma endregion +#pragma region "AddNode" +class AddNode : public Expression +{ + public: + ~AddNode(); + Expression* left; + Expression* right; + string GetNodeName(); + AddNode(Expression* left,Expression* right); + int64_t Evaluate(IApplicationState* state); + +}; +#pragma endregion +#pragma region "MinusNode" +class MinusNode : public Expression +{ + public: + ~MinusNode(); + Expression* left; + Expression* right; + string GetNodeName(); + MinusNode(Expression* left,Expression* right); + int64_t Evaluate(IApplicationState* state); + +}; + +#pragma endregion +#pragma region "MultiplyNode" +class MultiplyNode : public Expression +{ + public: + ~MultiplyNode(); + Expression* left; + Expression* right; + string GetNodeName(); + MultiplyNode(Expression* left,Expression* right); + int64_t Evaluate(IApplicationState* state); + +}; +#pragma endregion +#pragma region "DivideNode" +class DivideNode : public Expression +{ + public: + ~DivideNode(); + Expression* left; + Expression* right; + string GetNodeName(); + DivideNode(Expression* left,Expression* right); + int64_t Evaluate(IApplicationState* state); + +}; +#pragma endregion +#pragma region "ModulusNode" +class ModulusNode : public Expression +{ + public: + ~ModulusNode(); + Expression* left; + Expression* right; + string GetNodeName(); + ModulusNode(Expression* left,Expression* right); + int64_t Evaluate(IApplicationState* state); + +}; +#pragma endregion +#pragma region "ListNode" +class ListNode : public Expression +{ + public: + ~ListNode(); + bool root; + void DisableScope(); + vector nodes; + string GetNodeName(); + int64_t Evaluate(IApplicationState* state); + +}; +#pragma endregion + +NetworkStream* TcpClient(string ip,int64_t port); +NetworkStream* UdpClient(string ip,int64_t port); + +class ExpressionStream : public Stream +{ + private: + IApplicationState* st; + vector exp; + public: + ExpressionStream(IApplicationState* state,vector expressions); + void Write(uint8_t* data,size_t len); + size_t Read(uint8_t* data,size_t len); + int64_t GetPosition(); + int64_t GetLength(); + void SetPosition(int64_t pos); + void Flush(); + void Close(); + bool CanRead(); + bool CanWrite(); + bool CanSeek(); +}; +class FileStream : public Stream +{ + private: + FILE* f; + bool cr,cw,cs,own; + public: + FileStream(FILE* fs,bool canRead,bool canWrite,bool canSeek,bool ownFile); + void Write(uint8_t* data,size_t len); + size_t Read(uint8_t* data,size_t len); + int64_t GetPosition(); + int64_t GetLength(); + void SetPosition(int64_t pos); + void Flush(); + void Close(); + bool CanRead(); + bool CanWrite(); + bool CanSeek(); +}; + + +SOCKET TcpServerInit(string ip,int64_t port); +SOCKET UdpServerInit(string ip,int64_t port); + +Stream* AcceptClient(SOCKET fd,string* ip); + + +void Parse(ListNode* node,vector tokens); +ListNode* Parse(vector tokens); +void ParseNode(ListNode* node,vector tokens,int* i); +void ParseNode(ListNode* node,vector tokens,int* i,bool root); +Expression* ParseExpression(vector tokens,int* i); +Expression* ParseTerm(vector tokens,int* i); +Expression* ParseFactor(vector tokens,int* i);int NetworkInit(); +}; + +void RegisterMainRuntimeFunctions(BoxScript::IApplicationState* state); +void DestroyApp(int); +std::vector get_files(std::string path); +std::vector get_directories(std::string path); + +std::vector> get_entries(std::string path); + +#if defined(GEKKO) +void clear_screen_ogc(); +#endif \ No newline at end of file diff --git a/source/pcapp.cpp b/source/pcapp.cpp new file mode 100644 index 0000000..e5cc002 --- /dev/null +++ b/source/pcapp.cpp @@ -0,0 +1,47 @@ +#if !defined(GEKKO) +#include "lexer.hpp" +#include "parser.hpp" +#include +namespace fs = std::filesystem; +using namespace BoxScript; +ListNode* _root_node; +std::string read_file(std::string name) +{ + FILE* f=fopen(name.c_str(),"r"); + std::string text=""; + while(true) + { + int read = fgetc(f); + if(read == EOF) break; + text += (char)read; + } + fclose(f); + return text; +} +#if !defined(LIBRARY) +int main(int argc,char** argv) +{ + if(argc < 2) return 1; + _root_node = new BoxScript::ListNode(); + for(int i = 1;i tokens=BoxScript::Lexer::Lex(read_file(argv[i])); + + BoxScript::Parse(_root_node,tokens); + } + BoxScript::ApplicationState* state=new BoxScript::ApplicationState(); + + RegisterMainRuntimeFunctions(state); + + _root_node->Evaluate(state); + + DestroyApp(0); +} +#endif + +void DestroyApp(int a) +{ + delete _root_node; + exit(a); +} + +#endif \ No newline at end of file diff --git a/source/runtimefuncs.cpp b/source/runtimefuncs.cpp new file mode 100644 index 0000000..d9e43b9 --- /dev/null +++ b/source/runtimefuncs.cpp @@ -0,0 +1,1186 @@ +#include +#include "parser.hpp" + + +#if defined(HAVE_LIBCURL) +#include +#endif + +#if defined(HAVE_LIBSDL2) +#include +#endif + +#if defined(GEKKO) +//#include +#else +#include +#endif + +#if defined(HW_RVL) +#include +#include +#endif +#include + +string GetLabelText(BoxScript::Expression* exp) +{ + if(exp->GetNodeName()=="VariableGetValueNode") + { + return ((BoxScript::VariableGetValueNode*)exp)->GetName(); + } + throw exception(); +} + +int64_t runtime_gt(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) > expressions[1]->Evaluate(state); +} +int64_t runtime_gte(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) >= expressions[1]->Evaluate(state); +} +int64_t runtime_lt(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) < expressions[1]->Evaluate(state); +} +int64_t runtime_lte(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) <= expressions[1]->Evaluate(state); +} +int64_t runtime_eq(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) == expressions[1]->Evaluate(state); +} +int64_t runtime_not(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + return !expressions[0]->Evaluate(state); +} +int64_t runtime_xor(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) ^ expressions[1]->Evaluate(state); +} +int64_t runtime_bor(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) | expressions[1]->Evaluate(state); +} +int64_t runtime_cor(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) || expressions[1]->Evaluate(state); +} +int64_t runtime_band(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) & expressions[1]->Evaluate(state); +} +int64_t runtime_cand(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) && expressions[1]->Evaluate(state); +} +int64_t runtime_lshift(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) << (int)(expressions[1]->Evaluate(state)); +} +int64_t runtime_rshift(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + return expressions[0]->Evaluate(state) >> (int)(expressions[1]->Evaluate(state)); +} + +int64_t runtime_printint(BoxScript::IApplicationState* state,std::vector expressions) +{ + for(auto val : expressions) + { + printf("%i",(int)val->Evaluate(state)); + } + return 0; +} +int64_t runtime_printintln(BoxScript::IApplicationState* state,std::vector expressions) +{ + for(auto val : expressions) + { + printf("%i\n",(int)val->Evaluate(state)); + } + return 0; +} +int64_t runtime_printchars(BoxScript::IApplicationState* state,std::vector expressions) +{ + for(auto val : expressions) + { + printf("%c",(char)val->Evaluate(state)); + } + return 0; +} +int64_t runtime_udpclient(BoxScript::IApplicationState* state,std::vector expressions) +{ + BoxScript::Stream* strm=BoxScript::UdpClient(state->BoxToString(expressions[0]->Evaluate(state)),expressions[1]->Evaluate(state)); + return state->CreateStream(strm); +} +int64_t runtime_tcpclient(BoxScript::IApplicationState* state,std::vector expressions) +{ + BoxScript::Stream* strm=BoxScript::TcpClient(state->BoxToString(expressions[0]->Evaluate(state)),expressions[1]->Evaluate(state)); + return state->CreateStream(strm); +} +class threadctx_t +{ + public: + BoxScript::Expression* expression; + BoxScript::IApplicationState* appstate; + + +}; +class clientctx_t +{ + public: + BoxScript::Expression* expression; + BoxScript::IApplicationState* appstate; + int64_t stream; + int64_t ip; + +} ; +static void* __me_create_thread(void* t) +{ + fprintf(stdout,"\t\tMECREATETHREAD\n"); + fflush(stdout); + threadctx_t* tInfo = static_cast(t); + //this is a thread + + tInfo->expression->Evaluate(tInfo->appstate); + + tInfo->appstate->RemoveThreadOwner(); + delete tInfo; + + return NULL; +} +static void* __me_create_thread2(void* t) +{ + clientctx_t* tInfo = static_cast(t); + //this is a thread + + tInfo->expression->Evaluate(tInfo->appstate); + tInfo->appstate->CloseStream(tInfo->stream); + tInfo->appstate->DestroyBox(tInfo->ip); + tInfo->appstate->RemoveThreadOwner(); + + delete tInfo; + + return NULL; +} + + +int64_t runtime_threadcreate(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + + threadctx_t* tInfo = new threadctx_t(); + + tInfo->expression = expressions[0]; + tInfo->appstate=state->NewScope(); + tInfo->appstate->AddThreadOwner(); + #if defined(GEKKO) + lwp_t pthread = LWP_THREAD_NULL; + + auto res = LWP_CreateThread (&pthread, __me_create_thread, tInfo, NULL, 8196, 80); + + // return (int64_t)pthread; + #else + std::thread* t = new std::thread(__me_create_thread,tInfo); + return (int64_t)t; + #endif + + return 0; +} +class serverctx_t +{ + public: + BoxScript::Expression* expression; + BoxScript::IApplicationState* appstate; + + string variable_name; + string ip_name; + string ip; + int64_t port; +}; + +static void* __udp_server_thread(void* t) +{ + serverctx_t* tInfo = (serverctx_t*)t; + //this is a thread + #if defined(_WIN32) || defined(WIN32) + SOCKET fd=BoxScript::UdpServerInit(tInfo->ip,tInfo->port); + #else + int fd=BoxScript::UdpServerInit(tInfo->ip,tInfo->port); + #endif + + while(true) + { + string ip_addr=""; + BoxScript::Stream* strm= BoxScript::AcceptClient(fd,&ip_addr); + BoxScript::IApplicationState* state2=tInfo->appstate->NewScope(); + state2->AddThreadOwner(); + + + + clientctx_t* tInfo2=new clientctx_t(); + tInfo2->expression = tInfo->expression; + tInfo2->appstate=state2; + tInfo2->ip=state2->CreateBox(ip_addr); + tInfo2->stream = state2->CreateStream(strm); + state2->SetVariable(tInfo->ip_name,tInfo2->ip); + state2->SetVariable(tInfo->variable_name,tInfo2->stream); + //start for thread + #if defined(GEKKO) + lwp_t pthread = LWP_THREAD_NULL; + LWP_CreateThread (&pthread, __me_create_thread2, tInfo2, NULL, 8196, 80); + + #else + std::thread t(__me_create_thread2,tInfo2); + + #endif + + } + + /*BoxScript::IApplicationState* state=tInfo->appstate->NewScope(); + state->AddThreadOwner(); + tInfo->expression->Evaluate(state); + state->RemoveThreadOwner();*/ + tInfo->appstate->RemoveThreadOwner(); + delete tInfo; + + return NULL; +} +static void* __tcp_server_thread(void* t) +{ + serverctx_t* tInfo = (serverctx_t*)t; + //this is a thread + #if defined(_WIN32) || defined(WIN32) + SOCKET fd=BoxScript::TcpServerInit(tInfo->ip,tInfo->port); + #else + int fd=BoxScript::TcpServerInit(tInfo->ip,tInfo->port); + #endif + + while(true) + { + string ip_addr=""; + BoxScript::Stream* strm= BoxScript::AcceptClient(fd,&ip_addr); + BoxScript::IApplicationState* state2=tInfo->appstate->NewScope(); + state2->AddThreadOwner(); + + + + clientctx_t* tInfo2=new clientctx_t(); + tInfo2->expression = tInfo->expression; + tInfo2->appstate=state2; + tInfo2->ip=state2->CreateBox(ip_addr); + tInfo2->stream = state2->CreateStream(strm); + state2->SetVariable(tInfo->ip_name,tInfo2->ip); + state2->SetVariable(tInfo->variable_name,tInfo2->stream); + //start for thread + #if defined(GEKKO) + lwp_t pthread = LWP_THREAD_NULL; + LWP_CreateThread (&pthread, __me_create_thread2, tInfo2, NULL, 8196, 80); + + #else + std::thread t(__me_create_thread2,tInfo2); + + #endif + + + } + + /*BoxScript::IApplicationState* state=tInfo->appstate->NewScope(); + state->AddThreadOwner(); + tInfo->expression->Evaluate(state); + state->RemoveThreadOwner();*/ + tInfo->appstate->RemoveThreadOwner(); + delete tInfo; + + return NULL; +} +int64_t runtime_tcpserver(BoxScript::IApplicationState* state,std::vector expressions) +{ + //tcpserver("0.0.0.0",4202,strm,ip,{}) + if(expressions.size() < 5) throw exception(); + serverctx_t* tInfo = new serverctx_t(); + state->AddThreadOwner(); + tInfo->appstate=state; + tInfo->ip=""; + tInfo->ip += state->BoxToString(expressions[0]->Evaluate(state)); + tInfo->port = expressions[1]->Evaluate(state); + tInfo->variable_name = GetLabelText(expressions[2]); + tInfo->ip_name = GetLabelText(expressions[3]); + tInfo->expression = expressions[4]; + + #if defined(GEKKO) + lwp_t pthread = LWP_THREAD_NULL; + LWP_CreateThread (&pthread, __tcp_server_thread, tInfo, NULL, 8196, 80); + return (int64_t)pthread; + #else + std::thread* t = new std::thread(__tcp_server_thread,tInfo); + return (int64_t)t; + #endif + +} +int64_t runtime_udpserver(BoxScript::IApplicationState* state,std::vector expressions) +{ + //udpserver("0.0.0.0",4202,strm,ip,{}) + if(expressions.size() < 5) throw exception(); + serverctx_t* tInfo = new serverctx_t(); + state->AddThreadOwner(); + tInfo->appstate=state; + tInfo->ip = state->BoxToString(expressions[0]->Evaluate(state)); + tInfo->port = expressions[1]->Evaluate(state); + tInfo->variable_name = GetLabelText(expressions[2]); + tInfo->ip_name = GetLabelText(expressions[3]); + tInfo->expression = expressions[4]; + #if defined(GEKKO) + lwp_t pthread = LWP_THREAD_NULL; + LWP_CreateThread (&pthread, __udp_server_thread, tInfo, NULL, 8196, 80); + return (int64_t)pthread; + #else + std::thread* t = new std::thread(__udp_server_thread,tInfo); + return (int64_t)t; + #endif + + +} +int64_t runtime_clearscreen(BoxScript::IApplicationState* state,std::vector expressions) +{ + #if defined(_WIN32) || defined(WIN32) + clrscr(); + #else + printf("\e[3J\033c"); + #endif + #if defined(GEKKO) + clear_screen_ogc(); + printf ("\x1b[%d;%dH",2,2); + #endif + return 0; +} +int64_t runtime_setpos(BoxScript::IApplicationState* state,std::vector expressions) +{ + int x=0,y=0; + if(expressions.size() >= 2) + { + x = (int)expressions[0]->Evaluate(state); + y = (int)expressions[1]->Evaluate(state); + } + #if defined(_WIN32) || defined(WIN32) + + #else + printf ("\x1b[%d;%dH",y ,x); + #endif + return 0; +} +int64_t runtime_exit(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() > 0) + { + DestroyApp((int)expressions[0]->Evaluate(state)); + }else{ + DestroyApp(0); + } + return 0; +} +int64_t runtime_updatescreen(BoxScript::IApplicationState* state,std::vector expressions) +{ + #if defined(GEKKO) + VIDEO_WaitVSync(); + #endif + return 0; +} +#if defined(HAVE_LIBCURL) +int64_t runtime_httpclient_create(BoxScript::IApplicationState* state,std::vector expressions) +{ + CURL* curl = curl_easy_init(); + return (int64_t)curl; +} +int64_t runtime_httpclient_seturl(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + CURL* curl=(CURL*)expressions[0]->Evaluate(state); + curl_easy_setopt(curl, CURLOPT_URL,state->BoxToString(expressions[1]->Evaluate(state)).c_str()); + return 0; +} + +#else +int64_t runtime_httpclient_create(BoxScript::IApplicationState* state,std::vector expressions) +{ + + return 0; +} +#endif +#if defined(HW_RVL) + +int64_t runtime_wpadscanpads(BoxScript::IApplicationState* state,std::vector expressions) +{ + return (int64_t)WPAD_ScanPads(); +} +int64_t runtime_wpadbuttonsdown(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + return (int64_t)WPAD_ButtonsDown(expressions[0]->Evaluate(state)); +} +int64_t runtime_wpadbuttonsup(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + return (int64_t)WPAD_ButtonsUp(expressions[0]->Evaluate(state)); +} +int64_t runtime_wpadbuttona(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_A; +} +int64_t runtime_wpadbuttonb(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_B; +} +int64_t runtime_wpadbutton1(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_1; +} +int64_t runtime_wpadbutton2(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_2; +} +int64_t runtime_wpadbuttonhome(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_HOME; +} +int64_t runtime_wpadbuttonplus(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_PLUS; +} +int64_t runtime_wpadbuttonminus(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_MINUS; +} +int64_t runtime_wpadbuttonup(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_UP; +} +int64_t runtime_wpadbuttondown(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_DOWN; +} +int64_t runtime_wpadbuttonleft(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_LEFT; +} +int64_t runtime_wpadbuttonright(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + uint32_t btn= (uint32_t)expressions[0]->Evaluate(state); + return btn & WPAD_BUTTON_RIGHT; +} +#endif +#if defined(USE_LIBSDL2) +int64_t runtime_sdl2init(BoxScript::IApplicationState* state,std::vector expressions) +{ + return SDL_Init(SDL_INIT_EVERYTHING); +} +int64_t runtime_sdl2createwindow(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 6) throw exception(); + string title=state->BoxToString(expressions[0]->Evaluate(state)); + return (int64_t)SDL_CreateWindow(title.c_str(),(int)expressions[1]->Evaluate(state),(int)expressions[2]->Evaluate(state),(int)expressions[3]->Evaluate(state),(int)expressions[4]->Evaluate(state),(Uint32)expressions[5]->Evaluate(state)); +} +#endif +int64_t runtime_for(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 4) throw exception(); + + string variableName=GetLabelText(expressions[0]); + int64_t max = expressions[1]->Evaluate(state); + BoxScript::Expression* increment = expressions[2]; + increment->DisableScope(); + BoxScript::Expression* runInFor = expressions[3]; + runInFor->DisableScope(); + BoxScript::IApplicationState* scope = state->NewScope(); + scope->AddThreadOwner(); + for(;state->GetVariable(variableName) < max;state->SetVariable(variableName,increment->Evaluate(scope))) + { + scope->ExitIfNotRunning(); + runInFor->Evaluate(scope); + + } + scope->RemoveThreadOwner(); + return 0; +} +int64_t runtime_if(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 3) throw exception(); + BoxScript::Expression* condition = expressions[0]; + condition->DisableScope(); + BoxScript::Expression* truth = expressions[1]; + truth->DisableScope(); + BoxScript::Expression* falsey = expressions[2]; + truth->DisableScope(); + bool num=condition->Evaluate(state) != 0; + if(num) + { + truth->Evaluate(state); + }else{ + falsey->Evaluate(state); + } + return 0; +} +int64_t runtime_e2n(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() > 0) + { + return state->e2n(expressions[0]); + } + throw exception(); +} +int64_t runtime_calln(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() > 0) + { + return state->Calln(expressions[0]->Evaluate(state))->Evaluate(state); + } + throw exception(); +} +int64_t runtime_readchar(BoxScript::IApplicationState* state,std::vector expressions) +{ + return getchar(); +} +int64_t runtime_mean(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() == 0) return 0; + int64_t mean=0; + for(auto exp : expressions) + { + mean += exp->Evaluate(state); + } + mean /= (int64_t)expressions.size(); + return mean; +} +int64_t runtime_boxcreate(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() > 0) + { + int64_t esize = expressions[0]->Evaluate(state); + if(esize > 2147483647) throw exception(); + int size = (int)esize; + return state->CreateBox(size); + } + return state->CreateBox(100); +} +int64_t runtime_boxgetvalue(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t bId = expressions[0]->Evaluate(state); + int64_t eindex = expressions[1]->Evaluate(state); + if(eindex > 2147483647) throw exception(); + int index = (int)eindex; + return state->GetBoxValue(bId,index); +} +int64_t runtime_boxsetvalue(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 3) throw exception(); + int64_t bId = expressions[0]->Evaluate(state); + int64_t eindex = expressions[1]->Evaluate(state); + if(eindex > 2147483647) throw exception(); + int index = (int)eindex; + int64_t value = expressions[2]->Evaluate(state); + state->SetBoxValue(bId,index,value); + return 0; +} +int64_t runtime_boxprint(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t bId = expressions[0]->Evaluate(state); + cout << state->BoxToString(bId); + return 0; +} +int64_t runtime_boxprintln(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t bId = expressions[0]->Evaluate(state); + cout << state->BoxToString(bId) << endl; + return 0; +} +int64_t runtime_boxlen(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t bId = expressions[0]->Evaluate(state); + return state->BoxLength(bId); +} +int64_t runtime_boxadd(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t bId = expressions[0]->Evaluate(state); + int64_t value = expressions[1]->Evaluate(state); + state->AddToBox(bId,value); + return 0; +} +int64_t runtime_boxremove(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t bId = expressions[0]->Evaluate(state); + int64_t value = expressions[1]->Evaluate(state); + state->RemoveFromBox(bId,value); + return 0; +} +int64_t runtime_boxinsert(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 3) throw exception(); + int64_t bId = expressions[0]->Evaluate(state); + int64_t eindex = expressions[1]->Evaluate(state); + if(eindex > 2147483647) throw exception(); + int index = (int)eindex; + int64_t value = expressions[2]->Evaluate(state); + + state->InsertToBox(bId,index,value); + return 0; +} +int64_t runtime_boxremoveat(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t bId = expressions[0]->Evaluate(state); + int64_t eindex = expressions[1]->Evaluate(state); + if(eindex > 2147483647) throw exception(); + int index = (int)eindex; + + state->RemoveAtFromBox(bId,index); + return 0; +} +int64_t runtime_streamcreate(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 10) throw exception(); + return state->CreateStream(new BoxScript::ExpressionStream(state,expressions)); +} + +int64_t runtime_boxclear(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t bId = expressions[0]->Evaluate(state); + state->ClearBox(bId); + return 0; +} +int64_t runtime_streamcopy(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t sId1 = expressions[0]->Evaluate(state); + int64_t sId2 = expressions[1]->Evaluate(state); + state->CopyStream(sId1,sId2); + return 0; +} +int64_t runtime_streamread(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 4) throw exception(); + int64_t sId = expressions[0]->Evaluate(state); + int64_t bId = expressions[1]->Evaluate(state); + int64_t offset = expressions[2]->Evaluate(state); + int64_t len = expressions[3]->Evaluate(state); + return state->ReadFromStream(sId,bId,offset,len); +} +int64_t runtime_streamwrite(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 4) throw exception(); + int64_t sId = expressions[0]->Evaluate(state); + int64_t bId = expressions[1]->Evaluate(state); + int64_t offset = expressions[2]->Evaluate(state); + int64_t len = expressions[3]->Evaluate(state); + state->WriteToStream(sId,bId,offset,len); + return 0; +} +int64_t runtime_closestream(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t sId = expressions[0]->Evaluate(state); + state->CloseStream(sId); + return 0; +} +int64_t runtime_boxreadline(BoxScript::IApplicationState* state,std::vector expressions) +{ + string text; + int chr; + while((chr = getchar()) != '\n') + { + if(chr == EOF) break; + text += (char)chr; + } + return state->CreateBox(text); +} + +int64_t runtime_createfunction(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + string func_name = GetLabelText(expressions[0]); + BoxScript::Expression* func_body = expressions[expressions.size()-1]; + vector args; + for(int i =1;iAddFunction(func_name,args,func_body); + return 0; +} + +int64_t runtime_filecreate(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() <1) throw exception(); + string name = state->BoxToString(expressions[0]->Evaluate(state)); + FILE* f = fopen(name.c_str(),"wb"); + return state->CreateStream(new BoxScript::FileStream(f,false,true,true,true)); +} +int64_t runtime_fileopenread(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() <1) throw exception(); + string name = state->BoxToString(expressions[0]->Evaluate(state)); + FILE* f = fopen(name.c_str(),"rb"); + return state->CreateStream(new BoxScript::FileStream(f,true,false,true,true)); +} + +int64_t runtime_fileopenreadwrite(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() <1) throw exception(); + string name = state->BoxToString(expressions[0]->Evaluate(state)); + FILE* f = fopen(name.c_str(),"rb+"); + return state->CreateStream(new BoxScript::FileStream(f,true,true,true,true)); +} +int64_t runtime_stdin(BoxScript::IApplicationState* state,std::vector expressions) +{ + return state->CreateStream(new BoxScript::FileStream(stdin,true,false,false,false)); +} +int64_t runtime_stdout(BoxScript::IApplicationState* state,std::vector expressions) +{ + return state->CreateStream(new BoxScript::FileStream(stdout,false,true,false,false)); +} +int64_t runtime_stderr(BoxScript::IApplicationState* state,std::vector expressions) +{ + return state->CreateStream(new BoxScript::FileStream(stderr,false,true,false,false)); +} +int64_t runtime_streamflush(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + state->FlushStream(expressions[0]->Evaluate(state)); + return 0; +} +int64_t runtime_streamsetpos(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) return 0; + state->SetStreamPosition(expressions[0]->Evaluate(state),expressions[1]->Evaluate(state)); + return 0; +} +int64_t runtime_streamgetpos(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + return state->GetStreamPosition(expressions[0]->Evaluate(state)); + +} +int64_t runtime_streamgetlen(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + return state->GetStreamLength(expressions[0]->Evaluate(state)); + +} +int64_t runtime_streamcanread(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + return state->CanRead(expressions[0]->Evaluate(state)) ? 1 : 0; + +} +int64_t runtime_streamcanwrite(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + return state->CanWrite(expressions[0]->Evaluate(state)) ? 1 : 0; + +} +int64_t runtime_streamcanseek(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + return state->CanSeek(expressions[0]->Evaluate(state)) ? 1 : 0; + +} + +int64_t runtime_isplatform(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) return 0; + string platform=state->BoxToString(expressions[0]->Evaluate(state)); + if(platform == "c++" || platform == "C++" || platform == "cpp" || platform == "CPP") + { + return 1; + } + #if defined(HW_RVL) + if(platform == "wii" || platform == "Wii" || platform == "WII" || platform == "RVL" || platform == "rvl") + { + return 1; + } + #endif + #if defined(HW_DOL) + if(platform == "GameCube" || platform == "GC" || platform == "Gamecube" || platform == "cube" || platform == "gcn" || platform == "ngc" || platform == "GCN" || platform == "NGC" || platform == "Cube" || platform == "gamecube") + { + return 1; + } + #endif + #if __unix__ + if(platform == "linux" || platform == "unix" || platform == "mac" || platform == "Mac" || platform == "Linux" || platform == "Unix") + { + return 1; + } + #endif + #if defined(_WIN32) || defined(WIN32) + if(platform == "win" || platform == "windows" || platform == "Windows" || platform == "win32" || platform == "WINDOWS" || platform == "Win32" || platform=="Win") + { + return 1; + } + #endif + #if defined(HAVE_LIBCURL) + if(platform == "curl" || platform == "libcurl") + { + return 1; + } + #endif + #if defined(HAVE_LIBSDL2) + if(platform == "sdl2" || platform == "libsdl2") + { + return 1; + } + #endif + #if defined(USE_MBED) + if(platform == "mbed") + { + return 1; + } + #endif + return 0; +} +int64_t runtime_bufferedstreamcreate(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t num= expressions[0]->Evaluate(state); + return state->CreateBufferedStream(num); +} +int64_t runtime_readbyte(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t num= expressions[0]->Evaluate(state); + return state->ReadByteFromStream(num); +} +int64_t runtime_d2i(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + + int64_t num= expressions[0]->Evaluate(state); + double val = *((double*)&num); + return (int64_t) val; +} +int64_t runtime_i2d(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + + double num= (double)expressions[0]->Evaluate(state); + int64_t val = *((int64_t*)&num); + return val; +} +int64_t runtime_dadd(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t num= expressions[0]->Evaluate(state); + double val = *((double*)&num); + num= expressions[1]->Evaluate(state); + val += *((double*)&num); + + return *((int64_t*)&num); +} +int64_t runtime_dsub(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t num= expressions[0]->Evaluate(state); + double val = *((double*)&num); + num= expressions[1]->Evaluate(state); + val -= *((double*)&num); + + return *((int64_t*)&num); +} +int64_t runtime_dmul(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t num= expressions[0]->Evaluate(state); + double val = *((double*)&num); + num= expressions[1]->Evaluate(state); + val *= *((double*)&num); + + return *((int64_t*)&num); +} +int64_t runtime_ddiv(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t num= expressions[0]->Evaluate(state); + double val = *((double*)&num); + num= expressions[1]->Evaluate(state); + val /= *((double*)&num); + + return *((int64_t*)&num); +} +int64_t runtime_dfloor(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t num= expressions[0]->Evaluate(state); + double val = *((double*)&num); + val = floorl(val); + return *((int64_t*)&val); +} +int64_t runtime_dceil(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t num= expressions[0]->Evaluate(state); + double val = *((double*)&num); + val = ceill(val); + return *((int64_t*)&val); +} +int64_t runtime_dfloorint(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t num= expressions[0]->Evaluate(state); + double val = *((double*)&num); + val = floorl(val); + return (int64_t)val; +} +int64_t runtime_dceilint(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t num= expressions[0]->Evaluate(state); + double val = *((double*)&num); + val = ceill(val); + return (int64_t)val; +} +double __zero=0; +int64_t runtime_dmean(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() == 0) return *((int64_t*)&__zero); + double mean=0; + for(auto exp : expressions) + { + int64_t num= exp->Evaluate(state); + mean += *((double*)&num); + } + mean /= (int64_t)expressions.size(); + return *((int64_t*)&mean); +} +int64_t runtime_boxdestroy(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 1) throw exception(); + int64_t boxId = expressions[0]->Evaluate(state); + state->DestroyBox(boxId); + return 0; +} +int64_t runtime_getbytesnumber(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t boxId = expressions[0]->Evaluate(state); + int64_t number = expressions[1]->Evaluate(state); + for(int64_t i = state->BoxLength(boxId);i<8;i++) + { + state->AddToBox(boxId,0); + } + state->SetBoxValue(boxId,0,number >> 56); + state->SetBoxValue(boxId,1,number >> 48 & 0x00000000000000FF); + state->SetBoxValue(boxId,2,number >> 40 & 0x00000000000000FF); + state->SetBoxValue(boxId,3,number >> 32 & 0x00000000000000FF); + state->SetBoxValue(boxId,4,number >> 24 & 0x00000000000000FF); + state->SetBoxValue(boxId,5,number >> 16 & 0x00000000000000FF); + state->SetBoxValue(boxId,6,number >> 8 & 0x00000000000000FF); + state->SetBoxValue(boxId,7,number & 0x00000000000000FF); +} +int64_t runtime_setbytesnumber(BoxScript::IApplicationState* state,std::vector expressions) +{ + if(expressions.size() < 2) throw exception(); + int64_t boxId = expressions[0]->Evaluate(state); + switch(state->BoxLength(boxId)) + { + case 0: + return 0; + case 1: + return (state->GetBoxValue(boxId,0) & 0x00000000000000FF); + case 2: + return (state->GetBoxValue(boxId,0) & 0x00000000000000FF) << 8 | (state->GetBoxValue(boxId,1) & 0x00000000000000FF); + case 3: + return (state->GetBoxValue(boxId,0) & 0x00000000000000FF) << 16 | (state->GetBoxValue(boxId,1) & 0x00000000000000FF) << 8 | (state->GetBoxValue(boxId,2) & 0x00000000000000FF); + case 4: + return (state->GetBoxValue(boxId,0) & 0x00000000000000FF) << 24 | (state->GetBoxValue(boxId,1) & 0x00000000000000FF) << 16 | (state->GetBoxValue(boxId,2) & 0x00000000000000FF) << 8 | (state->GetBoxValue(boxId,3) & 0x00000000000000FF); + case 5: + return (state->GetBoxValue(boxId,0) & 0x00000000000000FF) << 32 | (state->GetBoxValue(boxId,1) & 0x00000000000000FF) << 24 | (state->GetBoxValue(boxId,2) & 0x00000000000000FF) << 16 | (state->GetBoxValue(boxId,3) & 0x00000000000000FF) << 8 | (state->GetBoxValue(boxId,4) & 0x00000000000000FF); + case 6: + return (state->GetBoxValue(boxId,0) & 0x00000000000000FF) << 40 | (state->GetBoxValue(boxId,1) & 0x00000000000000FF) << 32 | (state->GetBoxValue(boxId,2) & 0x00000000000000FF) << 24 | (state->GetBoxValue(boxId,3) & 0x00000000000000FF) << 16 | (state->GetBoxValue(boxId,4) & 0x00000000000000FF) << 8 | (state->GetBoxValue(boxId,5) & 0x00000000000000FF); + case 7: + return (state->GetBoxValue(boxId,0) & 0x00000000000000FF) << 48 | (state->GetBoxValue(boxId,1) & 0x00000000000000FF) << 40 | (state->GetBoxValue(boxId,2) & 0x00000000000000FF) << 32 | (state->GetBoxValue(boxId,3) & 0x00000000000000FF) << 24 | (state->GetBoxValue(boxId,4) & 0x00000000000000FF) << 16 | (state->GetBoxValue(boxId,5) & 0x00000000000000FF) << 8 | (state->GetBoxValue(boxId,6) & 0x00000000000000FF); + default: + return (state->GetBoxValue(boxId,0) & 0x00000000000000FF) << 56 | (state->GetBoxValue(boxId,1) & 0x00000000000000FF) << 48 | (state->GetBoxValue(boxId,2) & 0x00000000000000FF) << 40 | (state->GetBoxValue(boxId,3) & 0x00000000000000FF) << 32 | (state->GetBoxValue(boxId,4) & 0x00000000000000FF) << 24 | (state->GetBoxValue(boxId,5) & 0x00000000000000FF) << 16 | (state->GetBoxValue(boxId,6) & 0x00000000000000FF) << 8 | (state->GetBoxValue(boxId,7) & 0x00000000000000FF); + } + //(uint64_t)data[0] << 56 | (uint64_t)data[1] << 48 | (uint64_t)(data[2] & 0x00000000000000FF) << 40 | (ulong)data[3] << 32 | (ulong)data[4] << 24 | (ulong)data[5] << 16 | (ulong)data[6] << 8 | (ulong)data[7]; +} + +void RegisterDoubleFunctions(BoxScript::IApplicationState* state) +{ + state->AddRuntimeFunction("i2d",runtime_i2d); + state->AddRuntimeFunction("d2i",runtime_d2i); + state->AddRuntimeFunction("dadd",runtime_dadd); +state->AddRuntimeFunction("dsub",runtime_dsub); +state->AddRuntimeFunction("dmul",runtime_dmul); +state->AddRuntimeFunction("ddiv",runtime_ddiv); +state->AddRuntimeFunction("dfloor",runtime_dfloor); +state->AddRuntimeFunction("dfloorint",runtime_dfloorint); +state->AddRuntimeFunction("dceil",runtime_dceil); +state->AddRuntimeFunction("dceilint",runtime_dceilint); +state->AddRuntimeFunction("dmean",runtime_dmean); + +/*state->AddRuntimeFunction("printdbl",runtime_printdbl); +state->AddRuntimeFunction("printdblln",runtime_printdblln); +state->AddRuntimeFunction("box_adddblstr",runtime_boxadddblstr); +state->AddRuntimeFunction("box_addintstr",runtime_addintstr); +state->AddRuntimeFunction("box_toint",runtime_boxtoint); +state->AddRuntimeFunction("box_todbl",runtime_boxtodbl);*/ +} + +void RegisterMainRuntimeFunctions(BoxScript::IApplicationState* state) +{ + state->AddRuntimeFunction("gt",runtime_gt); + state->AddRuntimeFunction("gte",runtime_gte); + state->AddRuntimeFunction("lt",runtime_lt); + state->AddRuntimeFunction("lte",runtime_lte); + state->AddRuntimeFunction("eq",runtime_eq); + state->AddRuntimeFunction("not",runtime_not); + state->AddRuntimeFunction("xor",runtime_xor); + state->AddRuntimeFunction("bor",runtime_bor); + state->AddRuntimeFunction("cor",runtime_cor); + state->AddRuntimeFunction("band",runtime_band); + state->AddRuntimeFunction("cand",runtime_cand); + state->AddRuntimeFunction("lshift",runtime_lshift); + state->AddRuntimeFunction("rshirt",runtime_rshift); + state->AddRuntimeFunction("printchars",runtime_printchars); + state->AddRuntimeFunction("printint",runtime_printint); + state->AddRuntimeFunction("printintln",runtime_printintln); + state->AddRuntimeFunction("tcp_client",runtime_tcpclient); + state->AddRuntimeFunction("udp_client",runtime_tcpclient); + + state->AddRuntimeFunction("tcp_server",runtime_tcpserver); + state->AddRuntimeFunction("udp_server",runtime_udpserver); + + state->AddRuntimeFunction("clear",runtime_clearscreen); + state->AddRuntimeFunction("exit",runtime_exit); + state->AddRuntimeFunction("setpos",runtime_setpos); + + state->AddRuntimeFunction("update_screen",runtime_updatescreen); + + //state->AddRuntimeFunction("httpclient_create",runtime_httpclient_create); + + //state->AddRuntimeFunction("httpclient_seturl",runtime_httpclient_seturl); + state->AddRuntimeFunction("thread_create",runtime_threadcreate); + state->AddRuntimeFunction("is_platform",runtime_isplatform); + state->AddRuntimeFunction("for",runtime_for); + state->AddRuntimeFunction("if",runtime_if); + state->AddRuntimeFunction("e2n",runtime_e2n); + state->AddRuntimeFunction("calln",runtime_calln); + state->AddRuntimeFunction("readchar",runtime_readchar); + state->AddRuntimeFunction("mean",runtime_mean); + state->AddRuntimeFunction("box_create",runtime_boxcreate); + state->AddRuntimeFunction("box_getvalue",runtime_boxgetvalue); + state->AddRuntimeFunction("box_setvalue",runtime_boxsetvalue); + state->AddRuntimeFunction("box_print",runtime_boxprint); + state->AddRuntimeFunction("box_println",runtime_boxprintln); + state->AddRuntimeFunction("box_len",runtime_boxlen); + state->AddRuntimeFunction("box_add",runtime_boxadd); + + state->AddRuntimeFunction("box_remove",runtime_boxremove); + state->AddRuntimeFunction("box_clear",runtime_boxclear); + state->AddRuntimeFunction("box_insert",runtime_boxinsert); + state->AddRuntimeFunction("box_removeat",runtime_boxremoveat); + state->AddRuntimeFunction("box_readline",runtime_boxreadline); + state->AddRuntimeFunction("box_destroy",runtime_boxdestroy); + state->AddRuntimeFunction("file_create",runtime_filecreate); + state->AddRuntimeFunction("file_open_read",runtime_fileopenread); + state->AddRuntimeFunction("file_open_write",runtime_fileopenreadwrite); + state->AddRuntimeFunction("stdin",runtime_stdin); + state->AddRuntimeFunction("stdout",runtime_stdout); + state->AddRuntimeFunction("stderr",runtime_stderr); + state->AddRuntimeFunction("stream_create",runtime_streamcreate); + state->AddRuntimeFunction("stream_copy",runtime_streamcopy); + state->AddRuntimeFunction("stream_read",runtime_streamread); + state->AddRuntimeFunction("stream_write",runtime_streamwrite); + state->AddRuntimeFunction("stream_flush",runtime_streamflush); + state->AddRuntimeFunction("stream_setpos",runtime_streamsetpos); + state->AddRuntimeFunction("stream_getpos",runtime_streamgetpos); + state->AddRuntimeFunction("stream_getlen",runtime_streamgetlen); + state->AddRuntimeFunction("stream_canread",runtime_streamcanread); + state->AddRuntimeFunction("stream_canwrite",runtime_streamcanwrite); + state->AddRuntimeFunction("stream_canseek",runtime_streamcanseek); + state->AddRuntimeFunction("stream_close",runtime_closestream); + state->AddRuntimeFunction("stream_createbuffered",runtime_bufferedstreamcreate); + state->AddRuntimeFunction("stream_readbyte",runtime_readbyte); + state->AddRuntimeFunction("create_function",runtime_createfunction); + state->AddRuntimeFunction("get_bytes_number",runtime_getbytesnumber); + state->AddRuntimeFunction("set_bytes_number",runtime_setbytesnumber); + /* state->AddRuntimeFunction("dictionary_box_create",runtime_createdictionarybox); + state->AddRuntimeFunction("dictionary_val_create",runtime_createdictionaryval); + state->AddRuntimeFunction("dictionary_add",runtime_addtodictionary); + state->AddRuntimeFunction("dictionary_getvalue",runtime_getvaluedict); + state->AddRuntimeFunction("dictionary_setvalue",runtime_setvaluedict); + state->AddRuntimeFunction("dictionary_contains",runtime_dictcontains); + state->AddRuntimeFunction("dictionary_clear",runtime_dictclear); + state->AddRuntimeFunction("dictionary_ittr",runtime_dictittr); + state->AddRuntimeFunction("dictionary_destroy",runtime_dictdestroy);*/ +#if defined(HW_RVL) + + state->AddRuntimeFunction("wpad_scanpads",runtime_wpadscanpads); + state->AddRuntimeFunction("wpad_buttonsdown",runtime_wpadbuttonsdown); + state->AddRuntimeFunction("wpad_buttonsup",runtime_wpadbuttonsup); + state->AddRuntimeFunction("wpad_button_a",runtime_wpadbuttona); + state->AddRuntimeFunction("wpad_button_b",runtime_wpadbuttonb); + state->AddRuntimeFunction("wpad_button_1",runtime_wpadbutton1); + state->AddRuntimeFunction("wpad_button_2",runtime_wpadbutton2); + state->AddRuntimeFunction("wpad_button_home",runtime_wpadbuttonhome); + state->AddRuntimeFunction("wpad_button_plus",runtime_wpadbuttonplus); + state->AddRuntimeFunction("wpad_button_minus",runtime_wpadbuttonminus); + state->AddRuntimeFunction("wpad_button_up",runtime_wpadbuttonup); + state->AddRuntimeFunction("wpad_button_down",runtime_wpadbuttondown); + state->AddRuntimeFunction("wpad_button_left",runtime_wpadbuttonleft); + state->AddRuntimeFunction("wpad_button_right",runtime_wpadbuttonright); + #endif + + #if defined(HAVE_LIBSDL2) + state->AddRuntimeFunction("sdl_init",runtime_sdl2init); + state->AddRuntimeFunction("sdl_createwindow",runtime_sdl2createwindow); + + #endif + + #if defined(USE_MBED) + + #endif + + //state->AddRuntimeFunction("httpclient_followurl",runtime_httpclient_followurl); + +} + diff --git a/source/wiiapp.cpp b/source/wiiapp.cpp new file mode 100644 index 0000000..c139eb5 --- /dev/null +++ b/source/wiiapp.cpp @@ -0,0 +1,233 @@ + +#if defined(GEKKO) +#include "lexer.hpp" +#include "parser.hpp" +#include +#include +#include +#include +#include + +#include +#if defined(HW_RVL) +#include +#endif +#include +static void *xfb = NULL; +static GXRModeObj *rmode = NULL; +BoxScript::ListNode* _root_node; + +void clear_screen_ogc() +{ + VIDEO_ClearFrameBuffer(rmode,xfb,0); +} +int appstate=0; +std::string read_file(std::string name) +{ + FILE* f=fopen(name.c_str(),"r"); + std::string text=""; + while(true) + { + int read = fgetc(f); + if(read == EOF) break; + text += (char)read; + } + fclose(f); + return text; +} +bool DirExists(std::string path) +{ + DIR* dir; + bool exists = false; + dir = opendir(path.c_str()); + if(dir != NULL) + { + exists=true; + (void)closedir(dir); + } + return exists; +} + +void LoadSubscripts(BoxScript::ListNode* nodes,std::string path) +{ + std::vector files = get_files(path); + for(std::string file : files) + { + std::string newPath = path + "/" + file; + std::vector tokens=BoxScript::Lexer::Lex(read_file(newPath)); + BoxScript::Parse(nodes,tokens); + } + +} +void PrintElement(std::string text,bool checked) +{ + printf("\t[%c] %s\n",checked ? '*' : ' ', text.c_str()); +} +void LoadScript(BoxScript::ListNode* nodes) +{ + if(!DirExists("/BoxScript")) + { + mkdir("/BoxScript",0755); + } + if(DirExists("/BoxScript/Autoboot")) + { + if(DirExists("/BoxScript/Autoboot/deps")) + LoadSubscripts(nodes,"/BoxScript/Autoboot/deps"); + + std::vector tokens=BoxScript::Lexer::Lex(read_file("/BoxScript/Autoboot/app.bs")); + BoxScript::Parse(nodes,tokens); + }else{ + std::vector dirs= get_directories("/BoxScript"); + int item=0; + while(appstate != -1) + { + #if defined(HW_RVL) + WPAD_ScanPads(); + + #endif + PAD_ScanPads(); + if(PAD_ButtonsDown(0) & PAD_BUTTON_UP) + { + item--; + if(item < 0) + { + item = dirs.size()-1; + } + } + if(PAD_ButtonsDown(0) & PAD_BUTTON_DOWN) + { + item++; + if(item >= dirs.size()) + { + item=0; + } + } + if(PAD_ButtonsDown(0) & PAD_BUTTON_A) + { + break; + } + #if defined(HW_RVL) + if(WPAD_ButtonsDown(0) & WPAD_BUTTON_UP) + { + item--; + if(item < 0) + { + item = dirs.size()-1; + } + } + if(WPAD_ButtonsDown(0) & WPAD_BUTTON_DOWN) + { + item++; + if(item >= dirs.size()) + { + item=0; + } + } + if(WPAD_ButtonsDown(0) & WPAD_BUTTON_A) + { + break; + } + #endif + + clear_screen_ogc(); + printf("\x1b[2;2H"); + printf("\n\n"); + printf("\tBoxScript 1.0 Wii Version\n"); + int indexOnScreen = item % 14; + int screenOffset = (item - indexOnScreen); + int i=0; + for(i = 0;i<14;i++) + { + if(screenOffset + i < dirs.size()) + PrintElement(dirs[i+screenOffset],i == indexOnScreen); + } + //printf("\tNo Items: %i",i); + VIDEO_WaitVSync(); + } + if(appstate == -1) exit(0); + if(DirExists("/BoxScript/" + dirs[item])) + LoadSubscripts(nodes,"/BoxScript/" + dirs[item] + "/deps"); + + std::vector tokens=BoxScript::Lexer::Lex(read_file("/BoxScript/" + dirs[item] + "/app.bs")); + BoxScript::Parse(nodes,tokens); + + } +} + BoxScript::ApplicationState* state; +void WiiResetPressed(unsigned int a,void* ptr) +{ + if(appstate <= 0) + { + appstate= -1; + }else{ + state->StopRunning(); + } +} +//--------------------------------------------------------------------------------- +int main(int argc, char **argv) { +//--------------------------------------------------------------------------------- + BoxScript::NetworkInit(); + fatInitDefault(); + SYS_SetResetCallback(WiiResetPressed); + // Initialise the video system + VIDEO_Init(); + PAD_Init(); + #if defined(HW_RVL) + WPAD_Init(); + #endif + // This function initialises the attached controllers + + + // Obtain the preferred video mode from the system + // This will correspond to the settings in the Wii menu + rmode = VIDEO_GetPreferredMode(NULL); + + // Allocate memory for the display in the uncached region + xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + + // Initialise the console, required for printf + console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ); + + // Set up the video registers with the chosen mode + VIDEO_Configure(rmode); + + // Tell the video hardware where our display memory is + VIDEO_SetNextFramebuffer(xfb); + + // Make the display visible + VIDEO_SetBlack(FALSE); + + // Flush the video register changes to the hardware + VIDEO_Flush(); + + // Wait for Video setup to complete + VIDEO_WaitVSync(); + if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); + + + // The console understands VT terminal escape codes + // This positions the cursor on row 2, column 0 + // we can use variables for this with format codes too + // e.g. printf ("\x1b[%d;%dH", row, column ); + printf("\x1b[2;2H"); + + + + _root_node = new BoxScript::ListNode(); + LoadScript(_root_node); + appstate=1; + state=new BoxScript::ApplicationState(); + RegisterMainRuntimeFunctions(state); + + _root_node->Evaluate(state); + + DestroyApp(0); +} + +void DestroyApp(int a) +{ + delete _root_node; + exit(a); +} + +#endif \ No newline at end of file diff --git a/wii/Makefile b/wii/Makefile new file mode 100644 index 0000000..0669610 --- /dev/null +++ b/wii/Makefile @@ -0,0 +1,138 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/wii_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := boot +BUILD := build +SOURCES := ../source +DATA := data +INCLUDES := include + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) +CXXFLAGS = $(CFLAGS) + +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lwiisocket -lfat -lwiiuse -lbte -logc -lm + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS)/wii $(PORTLIBS)/ppc + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(sFILES:.s=.o) $(SFILES:.S=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) + +export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := -L$(LIBOGC_LIB) $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol + +#--------------------------------------------------------------------------------- +run: + wiiload $(TARGET).dol + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +$(OFILES_SOURCES) : $(HFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.jpg.o %_jpg.h : %.jpg +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- \ No newline at end of file diff --git a/wii/include/config.h b/wii/include/config.h new file mode 100644 index 0000000..2db79d5 --- /dev/null +++ b/wii/include/config.h @@ -0,0 +1,10 @@ +#pragma once + +//#define HAVE_LIBSDL2 +//#define HAVE_LIBCURL + +//#define HAVE_GRRLIB + +#if defined(HW_RVL) +#define LIBWIISOCKET +#endif \ No newline at end of file