Add classes

This commit is contained in:
2025-05-24 09:39:59 -05:00
parent 87784e1279
commit 12f443a593
16 changed files with 2389 additions and 197 deletions

View File

@@ -65,7 +65,8 @@ namespace Tesses::CrossLang
if(!this->icon.empty())
sections++;
if(!this->classes.empty())
sections++;
WriteInt(stream,sections);
uint32_t strSz=4;
@@ -181,6 +182,54 @@ namespace Tesses::CrossLang
Write(stream,buffer.data(),buffer.size());
}
if(!classes.empty())
{
uint32_t len = 4;
for(auto& cls : classes)
{
len += 8;
len += cls.name.size() * 4;
len += 4;
len += cls.inherits.size() * 4;
len += 4;
for(auto& clsEnt : cls.entries)
{
len += 17;
for(auto& arg : clsEnt.arguments) len+=4;
}
}
memcpy(buffer,"CLSS",4);
Write(stream,buffer,4);
WriteInt(stream,len);
WriteInt(stream,(uint32_t)classes.size());
for(auto& cls : classes)
{
WriteInt(stream,cls.documentation);
WriteInt(stream,(uint32_t)cls.name.size());
for(auto namePart : cls.name) WriteInt(stream,namePart);
WriteInt(stream,(uint32_t)cls.inherits.size());
for(auto inhPart : cls.inherits) WriteInt(stream,inhPart);
WriteInt(stream,(uint32_t)cls.entries.size());
for(auto& ent : cls.entries)
{
buffer[0] = ent.type;
Write(stream,buffer,1);
WriteInt(stream,ent.documentation);
WriteInt(stream,ent.name);
WriteInt(stream,(uint32_t)ent.arguments.size());
for(auto ar : ent.arguments)
{
WriteInt(stream,ar);
}
WriteInt(stream,ent.closure);
}
}
}
for(auto& reso : res)
{
memcpy(buffer,"RESO",4);
@@ -489,7 +538,122 @@ namespace Tesses::CrossLang
TWO_EXPR(NotEqualsExpression, NEQ)
TWO_EXPR(EqualsExpression, EQ)
TWO_EXPR(XOrExpression, XOR)
if(adv.nodeName == RelativePathExpression)
if(adv.nodeName == ClassStatement && adv.nodes.size() >= 3 && std::holds_alternative<std::string>(adv.nodes[0]))
{
CodeGenClass cls;
cls.documentation = GetString(std::get<std::string>(adv.nodes[0]));
GetFunctionName(cls.name,adv.nodes[1]);
GetFunctionName(cls.inherits,adv.nodes[2]);
for(size_t i = 3; i < adv.nodes.size(); i++)
{
auto& node = adv.nodes[i];
if(std::holds_alternative<AdvancedSyntaxNode>(node))
{
auto& adv2 = std::get<AdvancedSyntaxNode>(node);
CodeGenClassEntry ent;
ent.type = 0;
if(adv2.nodes.size() >= 2 && std::holds_alternative<std::string>(adv2.nodes[0]) && std::holds_alternative<std::string>(adv2.nodes[1]))
{
ent.documentation=GetString(std::get<std::string>(adv2.nodes[0]));
std::string type=std::get<std::string>(adv2.nodes[1]);
if(type == "private") ent.type = 0;
else if(type == "protected") ent.type = 1;
else if(type == "public") ent.type = 2;
else if(type == "static") ent.type = 3;
}
if(adv2.nodeName == MethodStatement && adv2.nodes.size() == 4 && std::holds_alternative<AdvancedSyntaxNode>(adv2.nodes[2]) )
{
//documentation,myTkn.text,nameAndArgs,closureData
size_t fnindex=this->chunks.size();
ent.closure=(uint32_t)fnindex;
this->chunks.resize(fnindex+1);
auto& nameAndArgs= std::get<AdvancedSyntaxNode>(adv2.nodes[2]);
if(nameAndArgs.nodeName == FunctionCallExpression && !nameAndArgs.nodes.empty() && std::holds_alternative<AdvancedSyntaxNode>(nameAndArgs.nodes[0]))
{
auto& getvar = std::get<AdvancedSyntaxNode>(nameAndArgs.nodes[0]);
if(getvar.nodeName == GetVariableExpression && getvar.nodes.size() == 1 && std::holds_alternative<std::string>(getvar.nodes[0]))
{
ent.name = GetString(std::get<std::string>(getvar.nodes[0]));
if(nameAndArgs.nodes.size() > 1)
{
GetFunctionArgs(ent.arguments, nameAndArgs.nodes[1]);
}
}
else continue;
}
std::vector<ByteCodeInstruction*> fnInstructions;
GenNode(fnInstructions,adv2.nodes[3],0,-1,-1,-1,-1);
this->chunks[fnindex] = std::pair<std::vector<uint32_t>,std::vector<ByteCodeInstruction*>>(ent.arguments, fnInstructions);
}
else if(adv2.nodeName == AbstractMethodStatement && adv2.nodes.size() == 3 && std::holds_alternative<AdvancedSyntaxNode>(adv2.nodes[2]))
{
ent.closure = 0;
ent.type |= 0b00001000;
//documentation,myTkn.text,nameAndArgs
auto& nameAndArgs= std::get<AdvancedSyntaxNode>(adv2.nodes[2]);
if(nameAndArgs.nodeName == FunctionCallExpression && !nameAndArgs.nodes.empty() && std::holds_alternative<AdvancedSyntaxNode>(nameAndArgs.nodes[0]))
{
auto& getvar = std::get<AdvancedSyntaxNode>(nameAndArgs.nodes[0]);
if(getvar.nodeName == GetVariableExpression && getvar.nodes.size() == 1 && std::holds_alternative<std::string>(getvar.nodes[0]))
{
ent.name = GetString(std::get<std::string>(getvar.nodes[0]));
if(nameAndArgs.nodes.size() > 1)
{
GetFunctionArgs(ent.arguments, nameAndArgs.nodes[1]);
}
} else continue;
}
}
else if(adv2.nodeName == FieldStatement && adv2.nodes.size() == 3 && std::holds_alternative<AdvancedSyntaxNode>(adv2.nodes[2]))
{
auto& setter = std::get<AdvancedSyntaxNode>(adv2.nodes[2]);
if(setter.nodeName == GetVariableExpression && setter.nodes.size() == 1 && std::holds_alternative<std::string>(setter.nodes[0]))
{
ent.closure = 0;
ent.type |= 0b00001100;
ent.name = GetString(std::get<std::string>(setter.nodes[0]));
}
else if(setter.nodeName == AssignExpression && setter.nodes.size() == 2 && std::holds_alternative<AdvancedSyntaxNode>(setter.nodes[0]))
{
auto& getvar = std::get<AdvancedSyntaxNode>(setter.nodes[0]);
if(getvar.nodeName == GetVariableExpression && getvar.nodes.size() == 1 && std::holds_alternative<std::string>(getvar.nodes[0]))
{
ent.type |= 0b00000100;
ent.name = GetString(std::get<std::string>(getvar.nodes[0]));
size_t fnindex=this->chunks.size();
ent.closure=(uint32_t)fnindex;
ent.arguments={};
this->chunks.resize(fnindex+1);
std::vector<ByteCodeInstruction*> fnInstructions;
GenNode(fnInstructions,AdvancedSyntaxNode::Create(ReturnStatement,false,{setter.nodes[1]}),0,-1,-1,-1,-1);
this->chunks[fnindex] = std::pair<std::vector<uint32_t>,std::vector<ByteCodeInstruction*>>({}, fnInstructions);
}
else continue;
}
else continue;
}
cls.entries.push_back(ent);
}
}
classes.push_back(cls);
}
else if(adv.nodeName == RelativePathExpression)
{
instructions.push_back(new SimpleInstruction(Instruction::PUSHRELATIVEPATH));
}

View File

@@ -928,11 +928,15 @@ namespace Tesses::CrossLang
}
SyntaxNode Parser::ParseNode(bool isRoot)
{
std::string documentation="";
if(i < tokens.size() && !isRoot && tokens[i].type == Documentation)
{
auto txt = tokens[i].text;
i++;
return AdvancedSyntaxNode::Create(DocumentationStatement,false,{txt,ParseNode()});
if(i < tokens.size() && tokens[i].text == "class" && tokens[i].type == LexTokenType::Identifier)
documentation = txt;
else
return AdvancedSyntaxNode::Create(DocumentationStatement,false,{txt,ParseNode()});
}
if(IsSymbol("{") || isRoot)
{
@@ -1056,99 +1060,93 @@ namespace Tesses::CrossLang
}
return AdvancedSyntaxNode::Create(EachStatement,false,{item,list,body});
}
if(IsIdentifier("object"))
if(IsIdentifier("class"))
{
//TODO: complete this
if(i < tokens.size())
{
std::string name = tokens[i++].text;
EnsureSymbol("{");
std::vector<SyntaxNode> name_and_methods;
std::vector<SyntaxNode> name_and_methods={documentation};
auto name = ParseExpression();
name_and_methods.push_back(name);
if(IsSymbol(":",true))
{
name_and_methods.push_back(ParseExpression());
}
else
{
name_and_methods.push_back(AdvancedSyntaxNode::Create(GetVariableExpression,true,{"ClassObject"}));
}
EnsureSymbol("{");
while(!IsSymbol("}",false) && i < tokens.size())
{
std::string documentation = "";
bool hasDocumentation=false;
documentation="";
if(tokens[i].type == LexTokenType::Documentation)
{
hasDocumentation=true;
documentation = tokens[i++].text;
}
if(i < tokens.size())
{
if(IsIdentifier("method"))
if(IsAnyIdentifier({"public","private","protected","static"}))
{
auto nameAndArgs = ParseExpression();
if(IsSymbol("{",false))
auto myTkn = tkn;
if(IsIdentifier("abstract"))
{
auto r = AdvancedSyntaxNode::Create(MethodDeclaration,false,{nameAndArgs,ParseNode()});
if(hasDocumentation)
{
name_and_methods.push_back(AdvancedSyntaxNode::Create(DocumentationStatement,false,{documentation,r}));
}
else
{
name_and_methods.push_back(r);
}
}
else
{
auto v = ParseExpression();
if(myTkn.text == "static") throw SyntaxException(myTkn.lineInfo,"Static abstract function doesn't make sense");
auto nameAndArgs = ParseExpression();
EnsureSymbol(";");
auto r= AdvancedSyntaxNode::Create(MethodDeclaration,false,{nameAndArgs,AdvancedSyntaxNode::Create(ReturnStatement,false,{v})});
if(hasDocumentation)
{
name_and_methods.push_back(AdvancedSyntaxNode::Create(DocumentationStatement,false,{documentation,r}));
}
else
{
name_and_methods.push_back(r);
}
name_and_methods.push_back(AdvancedSyntaxNode::Create(AbstractMethodStatement,false,{documentation,myTkn.text,nameAndArgs}));
}
}
else if(IsIdentifier("static"))
{
auto nameAndArgs = ParseExpression();
if(IsSymbol("{",false))
else if(i + 1 < tokens.size() && (tokens[i+1].text == "=" || tokens[i+1].text == ";") && tokens[i+1].type == LexTokenType::Symbol)
{
auto r = AdvancedSyntaxNode::Create(StaticStatement,false,{nameAndArgs,ParseNode()});
if(hasDocumentation)
{
name_and_methods.push_back(AdvancedSyntaxNode::Create(DocumentationStatement,false,{documentation,r}));
}
else
{
name_and_methods.push_back(r);
}
}
else
{
auto v = ParseExpression();
auto setter = ParseExpression();
EnsureSymbol(";");
auto r= AdvancedSyntaxNode::Create(StaticStatement,false,{nameAndArgs,AdvancedSyntaxNode::Create(ReturnStatement,false,{v})});
if(hasDocumentation)
SyntaxNode field = AdvancedSyntaxNode::Create(FieldStatement,false,{
documentation,
myTkn.text,
setter
});
name_and_methods.push_back(field);
}
else
{
auto nameAndArgs = ParseExpression();
if(IsSymbol("{",false))
{
name_and_methods.push_back(AdvancedSyntaxNode::Create(DocumentationStatement,false,{documentation,r}));
name_and_methods.push_back(AdvancedSyntaxNode::Create(MethodStatement,false,{documentation,myTkn.text,nameAndArgs,ParseNode()}));
}
else
else
{
name_and_methods.push_back(r);
auto v = ParseExpression();
EnsureSymbol(";");
name_and_methods.push_back(AdvancedSyntaxNode::Create(MethodStatement,false,{documentation,myTkn.text,nameAndArgs,AdvancedSyntaxNode::Create(ReturnStatement,false,{v})}));
}
}
}
}
}
EnsureSymbol("}");
return AdvancedSyntaxNode::Create(ObjectStatement, false, name_and_methods);
return AdvancedSyntaxNode::Create(ClassStatement, false, name_and_methods);
}
else throw std::out_of_range("End of file");
}