Replace time-based GC with allocation-count trigger, migrate all Create factories to GCList::Create(), fix VFSPath root path, reorder TObject variant
Build and Deploy on Tag / 🔨 Build for PowerPC (push) Successful in 1m11s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-riscv64:latest, riscv64-linux-gnu, riscv64) (push) Successful in 3m22s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x64:latest, x86_64-linux-gnu, amd64) (push) Successful in 3m34s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm:latest, arm-linux-gnueabihf, arm7) (push) Successful in 3m37s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm64:latest, aarch64-linux-gnu, arm64) (push) Successful in 3m39s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x86:latest, i386-linux-gnu, 386) (push) Successful in 55s
Build and Deploy on Tag / update-tap (push) Failing after 4m8s

This commit is contained in:
2026-09-01 05:15:43 -05:00
parent 56b74dc6fc
commit 2430b62232
38 changed files with 888 additions and 806 deletions
+118 -34
View File
@@ -175,7 +175,7 @@ void CodeGen::WriteMetadataObject(std::vector<uint8_t> &bytes, SyntaxNode n) {
std::vector<SyntaxNode> itms;
if (asn.nodes.size() > 0)
GetFunctionArgs(itms, asn.nodes[0]);
FlattenCommas(itms, asn.nodes[0]);
bytes.push_back(7);
size_t offset = bytes.size();
bytes.resize(offset + 4);
@@ -189,7 +189,7 @@ void CodeGen::WriteMetadataObject(std::vector<uint8_t> &bytes, SyntaxNode n) {
std::vector<SyntaxNode> itms;
if (asn.nodes.size() > 0)
GetFunctionArgs(itms, asn.nodes[0]);
FlattenCommas(itms, asn.nodes[0]);
bytes.push_back(8);
size_t offset = bytes.size();
bytes.resize(offset + 4);
@@ -827,6 +827,8 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
size_t fnindex = this->chunks.size();
ent.closure = (uint32_t)fnindex;
this->chunks.resize(fnindex + 1);
std::vector<ByteCodeInstruction *> fnInstructions;
auto &nameAndArgs =
std::get<AdvancedSyntaxNode>(adv2.nodes[2]);
if (nameAndArgs.nodeName == FunctionCallExpression &&
@@ -844,14 +846,13 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
std::get<std::string>(getvar.nodes[0]));
if (nameAndArgs.nodes.size() > 1) {
GetFunctionArgs(ent.arguments,
fnInstructions,
nameAndArgs.nodes[1]);
}
} else
continue;
}
std::vector<ByteCodeInstruction *> fnInstructions;
GenNode(fnInstructions, adv2.nodes[3], 0, -1, -1, -1,
-1);
@@ -881,8 +882,8 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
ent.name = GetString(
std::get<std::string>(getvar.nodes[0]));
if (nameAndArgs.nodes.size() > 1) {
GetFunctionArgs(ent.arguments,
nameAndArgs.nodes[1]);
FlattenCommas(ent.arguments,
nameAndArgs.nodes[1]);
}
} else
continue;
@@ -1041,13 +1042,13 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
}
if (item.first.second.nodeName == DefaultStatement) {
if (!defaultJmp.empty())
std::cout << "ERROR: multiple default in "
"switch statement will cause "
"undefined behaviour, this is not "
"an exception due to not allowing "
"exceptions in codegen stage (the "
"compilation shouldn't fail)"
<< std::endl;
Tesses::Framework::Console::WriteLine(
"ERROR: multiple default in "
"switch statement will cause "
"undefined behaviour, this is not "
"an exception due to not allowing "
"exceptions in codegen stage (the "
"compilation shouldn't fail)");
defaultJmp = item.first.first;
}
}
@@ -1223,7 +1224,7 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
std::vector<SyntaxNode> itms;
if (adv.nodes.size() > 0)
GetFunctionArgs(itms, adv.nodes[0]);
FlattenCommas(itms, adv.nodes[0]);
for (auto item : itms) {
GenNode(instructions, item, scope, contscope, brkscope, contI,
brkI);
@@ -1233,7 +1234,7 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
instructions.push_back(new SimpleInstruction(CREATEDICTIONARY));
std::vector<SyntaxNode> itms;
if (adv.nodes.size() > 0)
GetFunctionArgs(itms, adv.nodes[0]);
FlattenCommas(itms, adv.nodes[0]);
for (auto item : itms) {
if (std::holds_alternative<AdvancedSyntaxNode>(item)) {
auto tkn = std::get<AdvancedSyntaxNode>(item);
@@ -1273,7 +1274,7 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
contI, brkI);
if (adv.nodes.size() == 2) {
std::vector<SyntaxNode> nodes;
GetFunctionArgs(nodes, adv.nodes[1]);
FlattenCommas(nodes, adv.nodes[1]);
for (auto item : nodes)
GenNode(instructions, item, scope, contscope, brkscope,
contI, brkI);
@@ -1288,7 +1289,7 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
contI, brkI);
if (adv.nodes.size() == 2) {
std::vector<SyntaxNode> nodes;
GetFunctionArgs(nodes, adv.nodes[1]);
FlattenCommas(nodes, adv.nodes[1]);
for (auto item : nodes)
GenNode(instructions, item, scope, contscope, brkscope,
contI, brkI);
@@ -1555,7 +1556,8 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
} else if (adv.nodeName == ContinueStatement) {
if (contscope == -1) {
std::cout << "WARN: continue does nothing here\n";
Tesses::Framework::Console::WriteLine(
"WARN: continue does nothing here");
} else if (contscope == -2) {
instructions.push_back(new SimpleInstruction(PUSHCONTINUE));
instructions.push_back(new SimpleInstruction(RET));
@@ -1572,7 +1574,8 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
}
} else if (adv.nodeName == BreakStatement) {
if (brkscope == -1) {
std::cout << "WARN: break does nothing here\n";
Tesses::Framework::Console::WriteLine(
"WARN: break does nothing here");
} else if (brkscope == -2) {
instructions.push_back(new SimpleInstruction(PUSHBREAK));
instructions.push_back(new SimpleInstruction(RET));
@@ -1978,7 +1981,7 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
//(a,b) => {}
// it has two args
std::vector<uint32_t> args;
GetFunctionArgs(args, adv.nodes[0]);
FlattenCommas(args, adv.nodes[0]);
std::vector<ByteCodeInstruction *> fnInstructions;
size_t fnindex = this->chunks.size();
@@ -2008,12 +2011,11 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
// Name => {}
//(a,b) => {}
// it has two args
std::vector<uint32_t> args;
GetFunctionArgs(args, adv.nodes[0]);
std::vector<ByteCodeInstruction *> fnInstructions;
size_t fnindex = this->chunks.size();
this->chunks.resize(fnindex + 1);
std::vector<uint32_t> args;
GetFunctionArgs(args, fnInstructions, adv.nodes[0]);
auto body = adv.nodes[1];
@@ -2060,18 +2062,20 @@ void CodeGen::GenNode(std::vector<ByteCodeInstruction *> &instructions,
}
}
}
void CodeGen::GetFunctionArgs(std::vector<SyntaxNode> &args, SyntaxNode n) {
void CodeGen::FlattenCommas(std::vector<SyntaxNode> &args, SyntaxNode n) {
AdvancedSyntaxNode sn;
if (std::holds_alternative<AdvancedSyntaxNode>(n) &&
(sn = std::get<AdvancedSyntaxNode>(n)).nodeName == CommaExpression &&
sn.nodes.size() == 2) {
GetFunctionArgs(args, sn.nodes[0]);
GetFunctionArgs(args, sn.nodes[1]);
FlattenCommas(args, sn.nodes[0]);
FlattenCommas(args, sn.nodes[1]);
} else {
args.push_back(n);
}
}
void CodeGen::GetFunctionArgs(std::vector<uint32_t> &name, SyntaxNode n) {
void CodeGen::GetFunctionArgs(std::vector<uint32_t> &name,
std::vector<ByteCodeInstruction *> &instrs,
SyntaxNode n) {
if (std::holds_alternative<std::nullptr_t>(n))
return;
@@ -2079,10 +2083,90 @@ void CodeGen::GetFunctionArgs(std::vector<uint32_t> &name, SyntaxNode n) {
auto res = std::get<AdvancedSyntaxNode>(n);
if (res.nodeName == ParenthesesExpression) {
for (auto n : res.nodes)
GetFunctionArgs(name, n);
GetFunctionArgs(name, instrs, n);
} else if (res.nodeName == AssignExpression && res.nodes.size() == 2) {
// ennsure the left argument is a getVariableExpression
if (std::holds_alternative<AdvancedSyntaxNode>(res.nodes[0])) {
auto left = std::get<AdvancedSyntaxNode>(res.nodes[0]);
if (left.nodeName == GetVariableExpression &&
!left.nodes.empty() &&
std::holds_alternative<std::string>(left.nodes[0])) {
std::string key = std::get<std::string>(left.nodes[0]);
if (key.size() >= 2 && key[0] == '$' && key[1] == '$') {
Tesses::Framework::Console::WriteLine(
"WARN: you can't assign variadic functions to a "
"default value, this will be an "
"error on future release.");
return;
}
if (key.size() > 0 && key[0] == '$') {
key.erase(key.cbegin());
}
name.push_back(GetString('$' + key));
uint32_t ifId = NewId();
std::string compGenSetVar = "__compGenSetVar";
compGenSetVar.append(std::to_string(ifId));
std::string compGenSetVarEnd = "__compGenSetVarEnd";
compGenSetVarEnd.append(std::to_string(ifId));
GenNode(instrs,
AdvancedSyntaxNode::Create(GetVariableExpression,
true, {key}),
0, -1, -1, -1, -1);
instrs.push_back(new JumpStyleInstruction(
Tesses::CrossLang::Instruction::JMPUNDEFINED,
compGenSetVar));
instrs.push_back(new SimpleInstruction(POP));
instrs.push_back(new JumpStyleInstruction(
Tesses::CrossLang::Instruction::JMP, compGenSetVarEnd));
instrs.push_back(new LabelInstruction(compGenSetVar));
GenNode(instrs,
AdvancedSyntaxNode::Create(
AssignExpression, true,
{AdvancedSyntaxNode::Create(DeclareExpression,
true, {key}),
res.nodes[1]}),
0, -1, -1, -1, -1);
instrs.push_back(new SimpleInstruction(POP));
instrs.push_back(new LabelInstruction(compGenSetVarEnd));
} else {
Tesses::Framework::Console::WriteLine(
"WARN: assignment does not assign arg, this will be an "
"error on future release.");
}
} else {
Tesses::Framework::Console::WriteLine(
"WARN: assignment does not assign arg, this will be an "
"error on future release.");
}
} else if (res.nodeName == CommaExpression && res.nodes.size() == 2) {
GetFunctionArgs(name, res.nodes[0]);
GetFunctionArgs(name, res.nodes[1]);
GetFunctionArgs(name, instrs, res.nodes[0]);
GetFunctionArgs(name, instrs, res.nodes[1]);
} else if (res.nodeName == GetVariableExpression &&
res.nodes.size() == 1) {
if (std::holds_alternative<std::string>(res.nodes[0])) {
name.push_back(GetString(std::get<std::string>(res.nodes[0])));
}
}
}
}
void CodeGen::FlattenCommas(std::vector<uint32_t> &name, SyntaxNode n) {
if (std::holds_alternative<std::nullptr_t>(n))
return;
if (std::holds_alternative<AdvancedSyntaxNode>(n)) {
auto res = std::get<AdvancedSyntaxNode>(n);
if (res.nodeName == ParenthesesExpression) {
for (auto n : res.nodes)
FlattenCommas(name, n);
} else if (res.nodeName == CommaExpression && res.nodes.size() == 2) {
FlattenCommas(name, res.nodes[0]);
FlattenCommas(name, res.nodes[1]);
} else if (res.nodeName == GetVariableExpression &&
res.nodes.size() == 1) {
if (std::holds_alternative<std::string>(res.nodes[0])) {
@@ -2175,14 +2259,14 @@ void CodeGen::GenRoot(SyntaxNode n) {
functionName.insert(
functionName.begin(),
{GetString(documentation)});
if (fcalli.nodes.size() == 2)
GetFunctionArgs(args,
fcalli.nodes[1]);
std::vector<ByteCodeInstruction *>
fnInstructions;
size_t fnindex = this->chunks.size();
this->chunks.resize(fnindex + 1);
if (fcalli.nodes.size() == 2)
GetFunctionArgs(args,
fnInstructions,
fcalli.nodes[1]);
GenNode(fnInstructions, res2.nodes[1],
0, -1, -1, -1, -1);
+1 -1
View File
@@ -482,6 +482,7 @@ int Lex(std::string filename, std::istream &strm,
}
break;
case '<':
case '>':
case '?':
if (peek == read) {
Flush();
@@ -532,7 +533,6 @@ int Lex(std::string filename, std::istream &strm,
case '^':
case '~':
case '!':
case '>':
case '*':
case '%':
//*
+14 -153
View File
@@ -115,58 +115,16 @@ bool Parser::IsIdentifier(std::string txt, bool pop) {
}
return false;
}
bool Parser::IsAnySymbol(std::initializer_list<std::string> idents, bool pop) {
if (i < tokens.size()) {
if (tokens[i].type != LexTokenType::Symbol)
return false;
for (auto item : idents) {
if (item == ">") {
if (i + 1 < tokens.size()) {
if ((tokens[i + 1].text == ">" ||
tokens[i + 1].text == ">=") &&
tokens[i + 1].type == LexTokenType::Symbol)
continue;
}
if (item == tokens[i].text) {
tkn = tokens[i];
if (pop)
i++;
return true;
}
} else if (item == ">>=") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">=" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
tkn.text = ">>=";
if (pop)
i += 2;
return true;
}
}
} else if (item == ">>") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
tkn.text = ">>";
if (pop)
i += 2;
return true;
}
}
} else {
if (item == tokens[i].text) {
tkn = tokens[i];
if (pop)
i++;
return true;
}
if (item == tokens[i].text) {
tkn = tokens[i];
if (pop)
i++;
return true;
}
}
}
@@ -176,45 +134,7 @@ bool Parser::IsSymbol(std::string txt, bool pop) {
if (i < tokens.size()) {
if (tokens[i].type != LexTokenType::Symbol)
return false;
if (txt == ">") {
if (i + 1 < tokens.size()) {
if ((tokens[i + 1].text == ">" || tokens[i + 1].text == ">=") &&
tokens[i + 1].type == LexTokenType::Symbol)
return false;
}
if (txt == tokens[i].text) {
tkn = tokens[i];
if (pop)
i++;
return true;
}
} else if (txt == ">>=") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">=" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
tkn.text = ">>=";
if (pop)
i += 2;
return true;
}
}
} else if (txt == ">>") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
tkn.text = ">>";
if (pop)
i += 2;
return true;
}
}
} else if (tokens[i].text == txt) {
if (tokens[i].text == txt) {
tkn = tokens[i];
if (pop)
i++;
@@ -233,7 +153,6 @@ static std::string EnsureSafeVariable(LexToken token) {
}
void Parser::EnsureSymbol(std::string txt) {
if (i < tokens.size()) {
if (tokens[i].type != LexTokenType::Symbol) {
throw SyntaxException(
tokens[i].lineInfo,
@@ -241,69 +160,7 @@ void Parser::EnsureSymbol(std::string txt) {
LexTokenType_ToString(tokens[i].type) + " \"" +
tokens[i].text + "\" which is not a symbol at all.");
}
if (txt == ">") {
if (i + 1 < tokens.size()) {
if ((tokens[i + 1].text == ">" || tokens[i + 1].text == ">=") &&
tokens[i + 1].type == LexTokenType::Symbol)
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
"\" but got the symbol \"" +
tokens[i].text +
tokens[i + 1].text + "\"");
;
}
if (txt == tokens[i].text) {
tkn = tokens[i];
i++;
return;
}
}
if (txt == ">>=") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">=" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
i += 2;
return;
}
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
"\" but got the symbol \"" +
tokens[i].text + tokens[i + 1].text +
"\"");
}
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
"\" but got the symbol \"" +
tokens[i].text + "\"");
} else if (txt == ">>") {
if (i + 1 < tokens.size()) {
if (tokens[i].text == ">" && tokens[i + 1].text == ">" &&
tokens[i].type == LexTokenType::Symbol &&
tokens[i + 1].type == LexTokenType::Symbol) {
tkn = tokens[i];
i += 2;
return;
}
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
"\" but got the symbol \"" +
tokens[i].text + tokens[i + 1].text +
"\"");
}
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
"\" but got the symbol \"" +
tokens[i].text + "\"");
} else if (tokens[i].text != txt) {
if (tokens[i].text != txt) {
throw SyntaxException(tokens[i].lineInfo,
"expected the symbol \"" + txt +
@@ -633,6 +490,11 @@ void Parser::ParseHtml(std::vector<SyntaxNode> &nodes, std::string var) {
EnsureSymbol(")");
EnsureSymbol(">");
if (std::holds_alternative<std::nullptr_t>(item))
item = AdvancedSyntaxNode::Create(
DeclareExpression, true,
{"item"});
std::vector<SyntaxNode> _nodes;
parseFn(_nodes, "each");
body = AdvancedSyntaxNode::Create(ScopeNode, false, _nodes);
@@ -1411,7 +1273,7 @@ SyntaxNode Parser::ParseNode(bool isRoot) {
}
if (!isRoot)
i++;
EnsureSymbol("}");
return aSN;
}
@@ -1519,8 +1381,7 @@ SyntaxNode Parser::ParseNode(bool isRoot) {
if (std::holds_alternative<std::nullptr_t>(item))
item = AdvancedSyntaxNode::Create(
DeclareExpression, true,
{AdvancedSyntaxNode::Create(GetVariableExpression, true,
{"item"})});
{"item"});
return AdvancedSyntaxNode::Create(EachStatement, false,
{item, list, body});