mirror of
https://onedev.site.tesses.net/crosslang
synced 2026-02-09 01:25:45 +00:00
Fix for tessesframework migration
This commit is contained in:
@@ -57,7 +57,7 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
if(!this->icon.empty())
|
||||
{
|
||||
this->GetResource(this->icon);
|
||||
this->GetResource(std::make_shared<ResourceFile>(this->icon));
|
||||
|
||||
}
|
||||
for(auto& res : this->res)
|
||||
@@ -234,38 +234,15 @@ namespace Tesses::CrossLang
|
||||
{
|
||||
memcpy(buffer,"RESO",4);
|
||||
Write(stream,buffer,4);
|
||||
|
||||
if(vfs == nullptr)
|
||||
{
|
||||
WriteInt(stream,0);
|
||||
continue;
|
||||
}
|
||||
auto f = vfs->OpenFile(reso,"rb");
|
||||
if(f != NULL)
|
||||
{
|
||||
|
||||
uint32_t len = (uint32_t)f->GetLength();
|
||||
|
||||
WriteInt(stream,len);
|
||||
uint8_t buff[1024];
|
||||
size_t read;
|
||||
do {
|
||||
read = f->Read(buff,1024);
|
||||
Write(stream,buff,read);
|
||||
} while(read > 0);
|
||||
delete f;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInt(stream,0);
|
||||
}
|
||||
WriteInt(stream,reso->GetLength(vfs));
|
||||
reso->Write(stream);
|
||||
}
|
||||
if(!this->icon.empty())
|
||||
{
|
||||
memcpy(buffer,"ICON",4);
|
||||
Write(stream,buffer,4);
|
||||
WriteInt(stream,4);
|
||||
WriteInt(stream,this->GetResource(this->icon));
|
||||
WriteInt(stream,this->GetResource(std::make_shared<ResourceFile>(this->icon)));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -448,14 +425,14 @@ namespace Tesses::CrossLang
|
||||
this->strs.push_back(str);
|
||||
return strI;
|
||||
}
|
||||
uint32_t CodeGen::GetResource(std::string res)
|
||||
uint32_t CodeGen::GetResource(std::shared_ptr<ResourceBase> resource)
|
||||
{
|
||||
for(uint32_t i = 0; i < (uint32_t)this->res.size();i++)
|
||||
{
|
||||
if(this->res[i] == res) return i;
|
||||
if(this->res[i]->IsEqual(resource.get())) return i;
|
||||
}
|
||||
uint32_t resI = (uint32_t)this->res.size();
|
||||
this->res.push_back(res);
|
||||
this->res.push_back(resource);
|
||||
return resI;
|
||||
}
|
||||
#define ONE_EXPR(EXPRESSION, INSTRUCTION) if(adv.nodeName == EXPRESSION && adv.nodes.size() == 1) {GenNode(instructions,adv.nodes[0],scope,contscope,brkscope,contI,brkI);instructions.push_back(new SimpleInstruction(INSTRUCTION));}
|
||||
@@ -516,6 +493,12 @@ namespace Tesses::CrossLang
|
||||
{
|
||||
instructions.push_back(new DoubleInstruction(std::get<double>(n)));
|
||||
}
|
||||
else if(std::holds_alternative<std::vector<uint8_t>>(n))
|
||||
{
|
||||
ResourceByteArray ba;
|
||||
ba.data = std::get<std::vector<uint8_t>>(n);
|
||||
instructions.push_back(new EmbedInstruction(GetResource(std::make_shared<ResourceByteArray>(ba))));
|
||||
}
|
||||
else if(std::holds_alternative<AdvancedSyntaxNode>(n))
|
||||
{
|
||||
auto adv = std::get<AdvancedSyntaxNode>(n);
|
||||
@@ -1337,7 +1320,7 @@ namespace Tesses::CrossLang
|
||||
else if(adv.nodeName == EmbedExpression && adv.nodes.size() == 1 && std::holds_alternative<std::string>(adv.nodes[0]))
|
||||
{
|
||||
std::string filename = std::get<std::string>(adv.nodes[0]);
|
||||
instructions.push_back(new EmbedInstruction(GetResource(filename)));
|
||||
instructions.push_back(new EmbedInstruction(GetResource(std::make_shared<ResourceFile>(filename))));
|
||||
|
||||
}
|
||||
else if(adv.nodeName == HtmlRootExpression)
|
||||
@@ -1520,20 +1503,6 @@ namespace Tesses::CrossLang
|
||||
this->chunks[fnindex] = std::pair<std::vector<uint32_t>,std::vector<ByteCodeInstruction*>>(args, fnInstructions);
|
||||
instructions.push_back(new ClosureInstruction((uint32_t)fnindex));
|
||||
}
|
||||
else if(adv.nodeName == EnumerableStatement && adv.nodes.size() == 2 && std::holds_alternative<AdvancedSyntaxNode>(adv.nodes[0]))
|
||||
{
|
||||
SyntaxNode n = AdvancedSyntaxNode::Create(FunctionStatement,false,{
|
||||
adv.nodes[0],
|
||||
AdvancedSyntaxNode::Create(ReturnStatement,false,{
|
||||
AdvancedSyntaxNode::Create(FunctionCallExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetVariableExpression,true,{"YieldEmumerable"}),
|
||||
AdvancedSyntaxNode::Create(ClosureExpression,true,{AdvancedSyntaxNode::Create(ParenthesesExpression,true,{}), adv.nodes[1]})
|
||||
})
|
||||
})
|
||||
});
|
||||
GenNode(instructions,n,scope,contscope,brkscope,contI,brkI);
|
||||
|
||||
}
|
||||
else if(adv.nodeName == FunctionStatement && adv.nodes.size() == 2 && std::holds_alternative<AdvancedSyntaxNode>(adv.nodes[0]))
|
||||
{
|
||||
//func NAME(ARGS) {}
|
||||
@@ -1763,4 +1732,58 @@ namespace Tesses::CrossLang
|
||||
instrs.push_back(new SimpleInstruction(POP));
|
||||
}
|
||||
}
|
||||
|
||||
ResourceBase::~ResourceBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ResourceBase::IsEqual(ResourceBase* base)
|
||||
{
|
||||
return this == base;
|
||||
}
|
||||
|
||||
ResourceFile::ResourceFile()
|
||||
{
|
||||
|
||||
}
|
||||
ResourceFile::ResourceFile(std::string f)
|
||||
{
|
||||
this->file = f;
|
||||
}
|
||||
ResourceFile::~ResourceFile()
|
||||
{
|
||||
delete this->strm;
|
||||
}
|
||||
|
||||
uint32_t ResourceFile::GetLength(Tesses::Framework::Filesystem::VFS* embedFS)
|
||||
{
|
||||
if(embedFS == nullptr) return 0;
|
||||
if(strm != nullptr) return strm->GetLength();
|
||||
this->strm = embedFS->OpenFile(this->file,"rb");
|
||||
if(strm != nullptr) return this->strm->GetLength();
|
||||
|
||||
return 0;
|
||||
}
|
||||
bool ResourceFile::IsEqual(ResourceBase* base)
|
||||
{
|
||||
auto res = dynamic_cast<ResourceFile*>(base);
|
||||
if(res != nullptr) return this->file == res->file;
|
||||
return ResourceBase::IsEqual(base);
|
||||
}
|
||||
void ResourceFile::Write(Tesses::Framework::Streams::Stream* output)
|
||||
{
|
||||
if(this->strm != nullptr)
|
||||
this->strm->CopyTo(output);
|
||||
}
|
||||
|
||||
uint32_t ResourceByteArray::GetLength(Tesses::Framework::Filesystem::VFS* embedFS)
|
||||
{
|
||||
return (uint32_t)this->data.size();
|
||||
}
|
||||
void ResourceByteArray::Write(Tesses::Framework::Streams::Stream* output)
|
||||
{
|
||||
output->WriteBlock(this->data.data(),this->data.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,65 @@
|
||||
#include <stdexcept>
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
SyntaxNode TObject2SyntaxNode(TObject o)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(o)) return Undefined();
|
||||
if(std::holds_alternative<std::nullptr_t>(o)) return nullptr;
|
||||
if(std::holds_alternative<std::string>(o)) return std::get<std::string>(o);
|
||||
if(std::holds_alternative<int64_t>(o)) return std::get<int64_t>(o);
|
||||
if(std::holds_alternative<double>(o)) return std::get<double>(o);
|
||||
if(std::holds_alternative<char>(o)) return std::get<char>(o);
|
||||
if(std::holds_alternative<bool>(o)) return std::get<bool>(o);
|
||||
TList* list;
|
||||
TDictionary* dict;
|
||||
TByteArray* byteArray;
|
||||
|
||||
|
||||
if(GetObjectHeap(o,list))
|
||||
{
|
||||
if(list->Count() == 0) return AdvancedSyntaxNode::Create(ArrayExpression, true, {});
|
||||
|
||||
SyntaxNode node = TObject2SyntaxNode(list->Get(0));
|
||||
|
||||
for(int64_t i = 1; i < list->Count(); i++)
|
||||
node = AdvancedSyntaxNode::Create(CommaExpression,true,{node,TObject2SyntaxNode(list->Get(i))});
|
||||
|
||||
return AdvancedSyntaxNode::Create(ArrayExpression, true, {node});
|
||||
}
|
||||
if(GetObjectHeap(o,dict))
|
||||
{
|
||||
bool has=false;
|
||||
SyntaxNode node=nullptr;
|
||||
|
||||
for(auto item : dict->items)
|
||||
{
|
||||
if(has)
|
||||
{
|
||||
node = AdvancedSyntaxNode::Create(CommaExpression,true, {node,AdvancedSyntaxNode::Create(AssignExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetVariableExpression,true,{TObject2SyntaxNode(item.first)}),
|
||||
TObject2SyntaxNode(item.second)
|
||||
})});
|
||||
}
|
||||
else {
|
||||
node = AdvancedSyntaxNode::Create(AssignExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetVariableExpression,true,{TObject2SyntaxNode(item.first)}),
|
||||
TObject2SyntaxNode(item.second)
|
||||
});
|
||||
has=true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(has) return AdvancedSyntaxNode::Create(DictionaryExpression,true,{node});
|
||||
return AdvancedSyntaxNode::Create(DictionaryExpression,true,{});
|
||||
}
|
||||
if(GetObjectHeap(o,byteArray)) {
|
||||
return byteArray->data;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
|
||||
std::string LexTokenType_ToString(LexTokenType t)
|
||||
{
|
||||
switch(t)
|
||||
@@ -103,10 +162,16 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
throw std::out_of_range("End of file");
|
||||
}
|
||||
Parser::Parser(std::vector<LexToken> tokens)
|
||||
Parser::Parser(std::vector<LexToken> tokens) : Parser(tokens,nullptr,nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
Parser::Parser(std::vector<LexToken> tokens, GC* gc, TRootEnvironment* env)
|
||||
{
|
||||
this->i = 0;
|
||||
this->tokens = tokens;
|
||||
this->gc = gc;
|
||||
this->env = env;
|
||||
}
|
||||
void Parser::ParseHtml(std::vector<SyntaxNode>& nodes,std::string var)
|
||||
{
|
||||
@@ -625,6 +690,42 @@ namespace Tesses::CrossLang
|
||||
node = AdvancedSyntaxNode::Create(DeclareExpression,true,{variable.text});
|
||||
}
|
||||
}
|
||||
else if(IsIdentifier("comptime"))
|
||||
{
|
||||
SyntaxNode n = nullptr;
|
||||
if(IsSymbol("{",false))
|
||||
{
|
||||
n = ParseNode();
|
||||
if(std::holds_alternative<AdvancedSyntaxNode>(n))
|
||||
{
|
||||
std::get<AdvancedSyntaxNode>(n).nodeName = NodeList;
|
||||
}
|
||||
} else {
|
||||
n = AdvancedSyntaxNode::Create(ReturnStatement,false,{ParseExpression()});
|
||||
}
|
||||
if(gc != nullptr && env != nullptr)
|
||||
{
|
||||
GCList ls(gc);
|
||||
|
||||
CodeGen gen;
|
||||
gen.GenRoot(n);
|
||||
|
||||
Tesses::Framework::Streams::MemoryStream ms(true);
|
||||
|
||||
gen.Save(nullptr,&ms);
|
||||
|
||||
ms.Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||
|
||||
TFile* f = TFile::Create(ls);
|
||||
f->Load(gc,&ms);
|
||||
|
||||
node = TObject2SyntaxNode(env->LoadFile(gc,f));
|
||||
}
|
||||
else {
|
||||
node = Undefined();
|
||||
}
|
||||
|
||||
}
|
||||
else if(IsIdentifier("operator"))
|
||||
{
|
||||
if(i >= tokens.size()) throw std::out_of_range("End of file");
|
||||
@@ -823,6 +924,69 @@ namespace Tesses::CrossLang
|
||||
{
|
||||
return AdvancedSyntaxNode::Create(PrefixDecrementExpression,true,{ParseUnary()});
|
||||
}
|
||||
else if(IsIdentifier("await"))
|
||||
{
|
||||
return AdvancedSyntaxNode::Create(YieldStatement,true,{ParseValue()});
|
||||
}
|
||||
else if(IsIdentifier("async"))
|
||||
{
|
||||
auto tkn = this->tkn;
|
||||
auto v = ParseValue();
|
||||
if(std::holds_alternative<AdvancedSyntaxNode>(v))
|
||||
{
|
||||
auto asn = std::get<AdvancedSyntaxNode>(v);
|
||||
if(asn.nodeName != ClosureExpression)
|
||||
throw SyntaxException(tkn.lineInfo,"async must be used only with a closure");
|
||||
if(asn.nodes.size() != 2)
|
||||
throw SyntaxException(tkn.lineInfo,"invalid closure");
|
||||
|
||||
|
||||
|
||||
|
||||
return AdvancedSyntaxNode::Create(ClosureExpression,true,{
|
||||
asn.nodes[0],
|
||||
AdvancedSyntaxNode::Create(ReturnStatement,false,{
|
||||
AdvancedSyntaxNode::Create(FunctionCallExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetFieldExpression,true,{AdvancedSyntaxNode::Create(GetVariableExpression,true,{"Task"}),"AsyncClosure"}),
|
||||
AdvancedSyntaxNode::Create(ClosureExpression,true,{AdvancedSyntaxNode::Create(ParenthesesExpression,true,{}), asn.nodes[1]})
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
else {
|
||||
throw SyntaxException(tkn.lineInfo,"async must be used only with a closure, not a simple value");
|
||||
}
|
||||
}
|
||||
else if(IsIdentifier("enumerable"))
|
||||
{
|
||||
|
||||
auto tkn = this->tkn;
|
||||
auto v = ParseValue();
|
||||
if(std::holds_alternative<AdvancedSyntaxNode>(v))
|
||||
{
|
||||
auto asn = std::get<AdvancedSyntaxNode>(v);
|
||||
if(asn.nodeName != ClosureExpression)
|
||||
throw SyntaxException(tkn.lineInfo,"enumerable must be used only with a closure");
|
||||
if(asn.nodes.size() != 2)
|
||||
throw SyntaxException(tkn.lineInfo,"invalid closure");
|
||||
|
||||
|
||||
|
||||
|
||||
return AdvancedSyntaxNode::Create(ClosureExpression,true,{
|
||||
asn.nodes[0],
|
||||
AdvancedSyntaxNode::Create(ReturnStatement,false,{
|
||||
AdvancedSyntaxNode::Create(FunctionCallExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetVariableExpression,true,{"YieldEmumerable"}),
|
||||
AdvancedSyntaxNode::Create(ClosureExpression,true,{AdvancedSyntaxNode::Create(ParenthesesExpression,true,{}), asn.nodes[1]})
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
else {
|
||||
throw SyntaxException(tkn.lineInfo,"enumerable must be used only with a closure, not a simple value");
|
||||
}
|
||||
}
|
||||
else if(IsSymbol("/"))
|
||||
{
|
||||
if(this->i < this->tokens.size() && (this->tokens[this->i].type == LexTokenType::String || this->tokens[this->i].type == LexTokenType::Identifier))
|
||||
@@ -1124,21 +1288,83 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
else
|
||||
{
|
||||
auto nameAndArgs = ParseExpression();
|
||||
|
||||
if(IsSymbol("{",false))
|
||||
if(IsIdentifier("async"))
|
||||
{
|
||||
auto nameAndArgs = ParseExpression();
|
||||
|
||||
if(IsSymbol("{",false))
|
||||
{
|
||||
|
||||
|
||||
name_and_methods.push_back(AdvancedSyntaxNode::Create(MethodStatement,false,{documentation,myTkn.text,nameAndArgs,ParseNode()}));
|
||||
name_and_methods.push_back(AdvancedSyntaxNode::Create(MethodStatement,false,{documentation,myTkn.text,nameAndArgs,
|
||||
AdvancedSyntaxNode::Create(ReturnStatement,false,{
|
||||
AdvancedSyntaxNode::Create(FunctionCallExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetFieldExpression,true,{AdvancedSyntaxNode::Create(GetVariableExpression,true,{"Task"}),"AsyncClosure"}),
|
||||
AdvancedSyntaxNode::Create(ClosureExpression,true,{AdvancedSyntaxNode::Create(ParenthesesExpression,true,{}), ParseNode()})
|
||||
})
|
||||
})
|
||||
}));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
auto v = ParseExpression();
|
||||
EnsureSymbol(";");
|
||||
|
||||
name_and_methods.push_back(AdvancedSyntaxNode::Create(MethodStatement,false,{documentation,myTkn.text,nameAndArgs,
|
||||
AdvancedSyntaxNode::Create(ReturnStatement,false,{
|
||||
AdvancedSyntaxNode::Create(FunctionCallExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetFieldExpression,true,{AdvancedSyntaxNode::Create(GetVariableExpression,true,{"Task"}),"AsyncClosure"}),
|
||||
AdvancedSyntaxNode::Create(ClosureExpression,true,{AdvancedSyntaxNode::Create(ParenthesesExpression,true,{}), AdvancedSyntaxNode::Create(ReturnStatement,false,{v})})
|
||||
})
|
||||
})
|
||||
}));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
auto v = ParseExpression();
|
||||
EnsureSymbol(";");
|
||||
name_and_methods.push_back(AdvancedSyntaxNode::Create(MethodStatement,false,{documentation,myTkn.text,nameAndArgs,AdvancedSyntaxNode::Create(ReturnStatement,false,{v})}));
|
||||
|
||||
}
|
||||
}
|
||||
else if(IsIdentifier("enumerable"))
|
||||
{
|
||||
auto nameAndArgs = ParseExpression();
|
||||
|
||||
if(IsSymbol("{",false))
|
||||
{
|
||||
|
||||
|
||||
name_and_methods.push_back(AdvancedSyntaxNode::Create(MethodStatement,false,{documentation,myTkn.text,nameAndArgs,
|
||||
AdvancedSyntaxNode::Create(ReturnStatement,false,{
|
||||
AdvancedSyntaxNode::Create(FunctionCallExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetVariableExpression,true,{"YieldEmumerable"}),
|
||||
AdvancedSyntaxNode::Create(ClosureExpression,true,{AdvancedSyntaxNode::Create(ParenthesesExpression,true,{}), ParseNode()})
|
||||
})
|
||||
})
|
||||
}));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SyntaxException(tokens[i].lineInfo, "expected the symbol \"{\" on enumerable but got the symbol or other token \"" + tokens[i].text + "\"");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto nameAndArgs = ParseExpression();
|
||||
|
||||
if(IsSymbol("{",false))
|
||||
{
|
||||
|
||||
|
||||
name_and_methods.push_back(AdvancedSyntaxNode::Create(MethodStatement,false,{documentation,myTkn.text,nameAndArgs,ParseNode()}));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
auto v = ParseExpression();
|
||||
EnsureSymbol(";");
|
||||
name_and_methods.push_back(AdvancedSyntaxNode::Create(MethodStatement,false,{documentation,myTkn.text,nameAndArgs,AdvancedSyntaxNode::Create(ReturnStatement,false,{v})}));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1150,21 +1376,66 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
else throw std::out_of_range("End of file");
|
||||
}
|
||||
if(IsIdentifier("enumerable"))
|
||||
|
||||
if(IsIdentifier("enumerable",false) && i+1<tokens.size() && tokens[i+1].text == "func" && i+1<tokens.size() && tokens[i+1].type == LexTokenType::Identifier)
|
||||
{
|
||||
i+=2;
|
||||
auto nameAndArgs = ParseExpression();
|
||||
|
||||
if(IsSymbol("{",false))
|
||||
{
|
||||
return AdvancedSyntaxNode::Create(EnumerableStatement,false,{nameAndArgs,ParseNode()});
|
||||
return AdvancedSyntaxNode::Create(FunctionStatement,false,{
|
||||
nameAndArgs,
|
||||
AdvancedSyntaxNode::Create(ReturnStatement,false,{
|
||||
AdvancedSyntaxNode::Create(FunctionCallExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetVariableExpression,true,{"YieldEmumerable"}),
|
||||
AdvancedSyntaxNode::Create(ClosureExpression,true,{AdvancedSyntaxNode::Create(ParenthesesExpression,true,{}), ParseNode()})
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SyntaxException(tokens[i].lineInfo, "expected the symbol \"{\" on enumerable but got the symbol or other token \"" + tokens[i].text + "\"");
|
||||
}
|
||||
}
|
||||
if(IsIdentifier("async",false) && i+1<tokens.size() && tokens[i+1].text == "func" && tokens[i+1].type == LexTokenType::Identifier)
|
||||
{
|
||||
i+=2;
|
||||
//async func
|
||||
auto nameAndArgs = ParseExpression();
|
||||
|
||||
if(IsSymbol("{",false))
|
||||
{
|
||||
return AdvancedSyntaxNode::Create(FunctionStatement,false,{
|
||||
nameAndArgs,
|
||||
AdvancedSyntaxNode::Create(ReturnStatement,false,{
|
||||
AdvancedSyntaxNode::Create(FunctionCallExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetFieldExpression,true,{AdvancedSyntaxNode::Create(GetVariableExpression,true,{"Task"}),"AsyncClosure"}),
|
||||
AdvancedSyntaxNode::Create(ClosureExpression,true,{AdvancedSyntaxNode::Create(ParenthesesExpression,true,{}), ParseNode()})
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
auto v = ParseExpression();
|
||||
|
||||
EnsureSymbol(";");
|
||||
return AdvancedSyntaxNode::Create(FunctionStatement,false,{
|
||||
nameAndArgs,
|
||||
AdvancedSyntaxNode::Create(ReturnStatement,false,{
|
||||
AdvancedSyntaxNode::Create(FunctionCallExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetFieldExpression,true,{AdvancedSyntaxNode::Create(GetVariableExpression,true,{"Task"}),"AsyncClosure"}),
|
||||
AdvancedSyntaxNode::Create(ClosureExpression,true,{AdvancedSyntaxNode::Create(ParenthesesExpression,true,{}), AdvancedSyntaxNode::Create(ReturnStatement,false,{v})})
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
if(IsIdentifier("func"))
|
||||
{
|
||||
|
||||
auto nameAndArgs = ParseExpression();
|
||||
|
||||
if(IsSymbol("{",false))
|
||||
|
||||
Reference in New Issue
Block a user