537 lines
16 KiB
C++
537 lines
16 KiB
C++
#pragma once
|
|
|
|
#define _FILE_OFFSET_BITS 64
|
|
#include <string>
|
|
#include <cstdint>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <cstdbool>
|
|
#include <atomic>
|
|
#include "config.h"
|
|
#include "lexer.hpp"
|
|
|
|
#if defined(GEKKO) && !defined(LIBWIISOCKET)
|
|
#define OGC_NETWORKING
|
|
#include <network.h>
|
|
typedef int SOCKET;
|
|
#elif defined(_WIN32) || defined(WIN32)
|
|
#define WINDOWS_NETWORKING
|
|
#include <conio.h>
|
|
#include <windows.h>
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
#pragma comment(lib, "ws2_32.lib")
|
|
WSADATA wsaData;
|
|
#else
|
|
typedef int SOCKET;
|
|
#define SYS_SOCKET_NETWORKING
|
|
#if defined(HW_RVL) && defined(LIBWIISOCKET)
|
|
#include <wiisocket.h>
|
|
#endif
|
|
#include <unistd.h>
|
|
#include <arpa/inet.h>
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
|
|
#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<Expression*> 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<Expression*> expressions)=0;
|
|
virtual bool HasRuntimeFunction(string str)=0;
|
|
virtual bool HasFunction(string str)=0;
|
|
virtual void AddFunction(string str,vector<string> 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<int64_t,pair<vector<int64_t>,bool>> boxes;
|
|
unordered_map<int64_t,Expression*> expressions;
|
|
unordered_map<int64_t,Stream*> streams;
|
|
unordered_map<string,int64_t> variables;
|
|
unordered_map<string,pair<vector<string>,Expression*>> methods;
|
|
unordered_map<string,internal_func> 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<Expression*> expressions);
|
|
bool HasRuntimeFunction(string str);
|
|
bool HasFunction(string str);
|
|
void AddFunction(string str,vector<string> 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<string,int64_t> 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<Expression*> expressions);
|
|
internal_func GetRuntimeFunction(string str);
|
|
bool HasRuntimeFunction(string str);
|
|
bool HasFunction(string str);
|
|
void AddFunction(string str,vector<string> 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<Expression*> expressions;
|
|
public:
|
|
~FunctionCallNode();
|
|
string GetNodeName();
|
|
FunctionCallNode(string _name,vector<Expression*> 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<Expression*> 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<Expression*> exp;
|
|
public:
|
|
ExpressionStream(IApplicationState* state,vector<Expression*> 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<Lexer::LexToken> tokens);
|
|
ListNode* Parse(vector<Lexer::LexToken> tokens);
|
|
void ParseNode(ListNode* node,vector<Lexer::LexToken> tokens,int* i);
|
|
void ParseNode(ListNode* node,vector<Lexer::LexToken> tokens,int* i,bool root);
|
|
Expression* ParseExpression(vector<Lexer::LexToken> tokens,int* i);
|
|
Expression* ParseTerm(vector<Lexer::LexToken> tokens,int* i);
|
|
Expression* ParseFactor(vector<Lexer::LexToken> tokens,int* i);int NetworkInit();
|
|
};
|
|
|
|
void RegisterMainRuntimeFunctions(BoxScript::IApplicationState* state);
|
|
void DestroyApp(int);
|
|
std::vector<std::string> get_files(std::string path);
|
|
std::vector<std::string> get_directories(std::string path);
|
|
|
|
std::vector<std::pair<std::string,bool>> get_entries(std::string path);
|
|
|
|
#if defined(GEKKO)
|
|
void clear_screen_ogc();
|
|
#endif |