#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 };