mirror of
https://git.tesses.org/tesses50/crosslang.git
synced 2026-09-30 16:54:14 +00:00
Add htmlparser, conditional variables, make alloc_threshold overridable in prefs.json
This commit is contained in:
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CROSSLANG_CUSTOM_CONSOLE
|
||||
#include "CrossLang.hpp"
|
||||
#include <iostream>
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
using namespace Tesses::Framework::Crypto;
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
#include "TessesFramework/Serialization/BitConverter.hpp"
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
using namespace Tesses::Framework::Serialization::Json;
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
#include <TessesFramework/Crypto/ClientTLSStream.hpp>
|
||||
#include <TessesFramework/Http/HttpClient.hpp>
|
||||
@@ -1449,6 +1469,315 @@ static TObject New_ServerSentEvents(GCList &ls, std::vector<TObject> args) {
|
||||
return std::make_shared<Tesses::Framework::Http::ServerSentEvents>();
|
||||
}
|
||||
|
||||
class TAttributeEnumerator : public TEnumerator {
|
||||
std::shared_ptr<Tesses::Framework::Serialization::Html::HtmlNode> node;
|
||||
std::unordered_map<
|
||||
std::string, std::optional<std::string>,
|
||||
Tesses::Framework::Serialization::Html::CaseInsensitiveHash,
|
||||
Tesses::Framework::Serialization::Html::CaseInsensitiveEqual>::iterator
|
||||
ittr;
|
||||
bool hasStarted;
|
||||
|
||||
public:
|
||||
TAttributeEnumerator(
|
||||
std::shared_ptr<Tesses::Framework::Serialization::Html::HtmlNode> node)
|
||||
: node(node), hasStarted(false) {}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (!node)
|
||||
return false;
|
||||
if (!this->hasStarted) {
|
||||
this->hasStarted = true;
|
||||
this->ittr = this->node->attributes.begin();
|
||||
return !this->node->attributes.empty();
|
||||
} else {
|
||||
this->ittr++;
|
||||
return this->ittr != this->node->attributes.end();
|
||||
}
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) {
|
||||
if (!this->hasStarted)
|
||||
return Undefined();
|
||||
if (this->ittr != this->node->attributes.end()) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
|
||||
auto kvp = TDictionary::Create(ls);
|
||||
kvp->SetValue("Key", this->ittr->first);
|
||||
kvp->SetValue("Value",
|
||||
this->ittr->second
|
||||
? static_cast<TObject>(this->ittr->second.value())
|
||||
: static_cast<TObject>(nullptr));
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return kvp;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
};
|
||||
|
||||
class TAttributeHolder : public TNativeObject {
|
||||
std::shared_ptr<Tesses::Framework::Serialization::Html::HtmlNode> node;
|
||||
|
||||
public:
|
||||
TAttributeHolder(
|
||||
std::shared_ptr<Tesses::Framework::Serialization::Html::HtmlNode> node)
|
||||
: node(node) {}
|
||||
std::string TypeName() { return "Net.Http.HtmlAttributeList"; }
|
||||
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args) {
|
||||
if (!node)
|
||||
return Undefined();
|
||||
if (key == "GetAt") {
|
||||
std::string key;
|
||||
if (GetArgument(args, 0, key)) {
|
||||
auto attr = node->attributes.find(key);
|
||||
if (attr != node->attributes.end()) {
|
||||
if (attr->second)
|
||||
return attr->second.value();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
if (key == "SetAt") {
|
||||
std::string key;
|
||||
if (args.size() == 2 && GetArgument(args, 0, key)) {
|
||||
if (std::holds_alternative<Undefined>(args[1])) {
|
||||
node->attributes.erase(key);
|
||||
return Undefined();
|
||||
}
|
||||
if (IsNull(args[1])) {
|
||||
node->attributes[key] = std::nullopt;
|
||||
return nullptr;
|
||||
}
|
||||
std::string str;
|
||||
if (GetArgument(args, 1, str)) {
|
||||
node->attributes[key] = str;
|
||||
return str;
|
||||
}
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
if (key == "GetEnumerator") {
|
||||
return ls.Create<TAttributeEnumerator>(this->node);
|
||||
}
|
||||
|
||||
if (key == "ToString") {
|
||||
std::string attr;
|
||||
for (auto &item : node->attributes) {
|
||||
attr += " ";
|
||||
attr += item.first;
|
||||
if (item.second) {
|
||||
attr += "\"";
|
||||
attr += HttpUtils::HtmlEncode(*item.second);
|
||||
attr += "\"";
|
||||
}
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
};
|
||||
class TChildrenEnumerator : public TEnumerator {
|
||||
int64_t index;
|
||||
std::shared_ptr<Tesses::Framework::Serialization::Html::HtmlNode> node;
|
||||
|
||||
public:
|
||||
TChildrenEnumerator(
|
||||
std::shared_ptr<Tesses::Framework::Serialization::Html::HtmlNode> node)
|
||||
: index(-1), node(node) {}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (!this->node)
|
||||
return false;
|
||||
this->index++;
|
||||
return this->index >= 0 &&
|
||||
static_cast<size_t>(this->index) < this->node->children.size();
|
||||
}
|
||||
TObject GetCurrent(GCList &ls);
|
||||
};
|
||||
class TChildrenHolder : public TNativeObject {
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Serialization::Html::HtmlNode> node;
|
||||
|
||||
public:
|
||||
TChildrenHolder(
|
||||
std::shared_ptr<Tesses::Framework::Serialization::Html::HtmlNode> node)
|
||||
: node(node) {}
|
||||
std::string TypeName() { return "Net.Http.HtmlChildrenList"; }
|
||||
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args);
|
||||
};
|
||||
|
||||
class THtmlNode : public TNativeObject {
|
||||
TAttributeHolder *attrHolder;
|
||||
TChildrenHolder *childrenHolder;
|
||||
|
||||
public:
|
||||
THtmlNode(
|
||||
std::shared_ptr<GC> gc,
|
||||
std::shared_ptr<Tesses::Framework::Serialization::Html::HtmlNode> node)
|
||||
: node(node) {
|
||||
GCList ls(gc);
|
||||
attrHolder = ls.Create<TAttributeHolder>(node);
|
||||
childrenHolder = ls.Create<TChildrenHolder>(node);
|
||||
}
|
||||
std::shared_ptr<Tesses::Framework::Serialization::Html::HtmlNode> node;
|
||||
std::string TypeName() { return "HtmlNode"; }
|
||||
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args) {
|
||||
if (!node)
|
||||
return Undefined();
|
||||
if (key == "getInnerText") {
|
||||
return node->InnerText();
|
||||
}
|
||||
|
||||
if (key == "getAttributes") {
|
||||
return this->attrHolder;
|
||||
}
|
||||
if (key == "getChildren") {
|
||||
return this->childrenHolder;
|
||||
}
|
||||
if (key == "FindNodes") {
|
||||
std::string tag;
|
||||
if (GetArgument(args, 0, tag)) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
TList *list = ls.Create<TList>();
|
||||
for (auto &item : node->FindNodes(tag)) {
|
||||
auto no = std::const_pointer_cast<
|
||||
Tesses::Framework::Serialization::Html::HtmlNode>(item);
|
||||
list->Add(ls.Create<THtmlNode>(ls.GetGC(), no));
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
if (key == "setIsText") {
|
||||
if (GetArgument(args, 0, node->isText))
|
||||
return node->isText;
|
||||
return Undefined();
|
||||
}
|
||||
if (key == "getIsText") {
|
||||
return node->isText;
|
||||
}
|
||||
if (key == "getText" || key == "getTag" || key == "getTextOrTag") {
|
||||
return node->text_or_tag;
|
||||
}
|
||||
if (key == "setText" || key == "setTag" || key == "setTextOrTag") {
|
||||
if (GetArgument(args, 0, node->text_or_tag))
|
||||
return node->text_or_tag;
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
if (key == "ToString") {
|
||||
return node->ToString();
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
attrHolder->Mark();
|
||||
childrenHolder->Mark();
|
||||
}
|
||||
};
|
||||
|
||||
TObject TChildrenEnumerator::GetCurrent(GCList &ls) {
|
||||
if (!this->node)
|
||||
return nullptr;
|
||||
if (this->index <= -1)
|
||||
return nullptr;
|
||||
if (this->node->children.empty())
|
||||
return nullptr;
|
||||
if (static_cast<size_t>(this->index) >= this->node->children.size())
|
||||
return nullptr;
|
||||
return ls.Create<THtmlNode>(
|
||||
ls.GetGC(), this->node->children[static_cast<size_t>(this->index)]);
|
||||
}
|
||||
TObject TChildrenHolder::CallMethod(GCList &ls, std::string key,
|
||||
std::vector<TObject> args) {
|
||||
if (!this->node)
|
||||
return Undefined();
|
||||
if (key == "Clear") {
|
||||
node->children.clear();
|
||||
return Undefined();
|
||||
}
|
||||
if (key == "getCount" || key == "getLength" || key == "Count" ||
|
||||
key == "Length") {
|
||||
return static_cast<int64_t>(this->node->children.size());
|
||||
}
|
||||
if (key == "GetAt") {
|
||||
int64_t n0;
|
||||
if (GetArgument(args, 0, n0)) {
|
||||
size_t num = static_cast<size_t>(n0);
|
||||
if (num < this->node->children.size()) {
|
||||
return ls.Create<THtmlNode>(ls.GetGC(),
|
||||
this->node->children[num]);
|
||||
}
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
if (key == "SetAt") {
|
||||
int64_t n0;
|
||||
THtmlNode *htmlNode;
|
||||
if (GetArgument(args, 0, n0) && GetArgumentHeap(args, 1, htmlNode)) {
|
||||
size_t num = static_cast<size_t>(n0);
|
||||
if (num < this->node->children.size() && htmlNode->node) {
|
||||
this->node->children[num] = htmlNode->node;
|
||||
ls.Add(htmlNode);
|
||||
return htmlNode;
|
||||
}
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
if (key == "RemoveAt") {
|
||||
int64_t n0;
|
||||
if (GetArgument(args, 0, n0)) {
|
||||
size_t num = static_cast<size_t>(n0);
|
||||
if (num < this->node->children.size()) {
|
||||
this->node->children.erase(this->node->children.cbegin() + num);
|
||||
}
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
if (key == "Add") {
|
||||
|
||||
THtmlNode *htmlNode;
|
||||
if (GetArgumentHeap(args, 0, htmlNode) && htmlNode->node) {
|
||||
this->node->children.push_back(htmlNode->node);
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
if (key == "GetEnumerator") {
|
||||
return ls.Create<TChildrenEnumerator>(this->node);
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
static TObject New_HtmlNode(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
return ls.Create<THtmlNode>(
|
||||
ls.GetGC(),
|
||||
std::make_shared<Tesses::Framework::Serialization::Html::HtmlNode>());
|
||||
}
|
||||
static TObject Net_Http_ParseHtml(GCList &ls, std::vector<TObject> args) {
|
||||
std::shared_ptr<Tesses::Framework::TextStreams::TextReader> textReader;
|
||||
if (GetArgument(args, 0, textReader)) {
|
||||
return ls.Create<THtmlNode>(
|
||||
ls.GetGC(),
|
||||
Tesses::Framework::Serialization::Html::Parse(textReader));
|
||||
}
|
||||
auto strReader =
|
||||
std::make_shared<Tesses::Framework::TextStreams::StringReader>();
|
||||
if (GetArgument(args, 0, strReader->GetString())) {
|
||||
return ls.Create<THtmlNode>(
|
||||
ls.GetGC(),
|
||||
Tesses::Framework::Serialization::Html::Parse(strReader));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TStd::RegisterNet(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
env->permissions.canRegisterNet = true;
|
||||
@@ -1489,6 +1818,8 @@ void TStd::RegisterNet(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
_new->DeclareFunction(gc, "ServerSentEvents",
|
||||
"Create server sent events object", {""},
|
||||
New_ServerSentEvents);
|
||||
_new->DeclareFunction(gc, "HtmlNode", "Create an html node", {},
|
||||
New_HtmlNode);
|
||||
|
||||
TDictionary *http = TDictionary::Create(ls);
|
||||
TDictionary *smtp = TDictionary::Create(ls);
|
||||
@@ -1574,6 +1905,9 @@ void TStd::RegisterNet(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
gc, "MountableServer",
|
||||
"Create a server you can mount to, must mount parents before child",
|
||||
{"root"}, New_MountableServer);
|
||||
|
||||
http->DeclareFunction(gc, "ParseHtml", "Parse html document",
|
||||
{"strOrTextReader"}, Net_Http_ParseHtml);
|
||||
dict->DeclareFunction(gc, "NetworkStream", "Create a network stream",
|
||||
{"ipv6", "datagram"}, New_NetworkStream);
|
||||
smtp->DeclareFunction(gc, "Send", "Send email via smtp server",
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
#if defined(GEKKO)
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
#include <TessesFramework/TessesFrameworkFeatures.h>
|
||||
|
||||
|
||||
+104
-20
@@ -1,4 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
#include "TessesFramework/Streams/ByteReader.hpp"
|
||||
#include "TessesFramework/Streams/Stream.hpp"
|
||||
@@ -31,7 +50,7 @@ std::string SharedExtension = ".dylib";
|
||||
std::string SharedExtension = ".so";
|
||||
#endif
|
||||
|
||||
class TMuxex : public TNativeObject {
|
||||
class TMutex : public TNativeObject {
|
||||
public:
|
||||
Tesses::Framework::Threading::Mutex mtx;
|
||||
|
||||
@@ -49,6 +68,33 @@ class TMuxex : public TNativeObject {
|
||||
return Undefined();
|
||||
}
|
||||
};
|
||||
class TCond : public TNativeObject {
|
||||
public:
|
||||
Tesses::Framework::Threading::Cond cond;
|
||||
std::string TypeName() { return "Cond"; }
|
||||
|
||||
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args) {
|
||||
if (key == "Broadcast") {
|
||||
cond.Broadcast();
|
||||
} else if (key == "Signal") {
|
||||
cond.Signal();
|
||||
} else if (key == "Wait") {
|
||||
TMutex *mtx;
|
||||
if (GetArgumentHeap(args, 0, mtx)) {
|
||||
std::shared_ptr<Tesses::Framework::Date::TimeSpan> ts;
|
||||
int64_t num;
|
||||
if (GetArgument(args, 1, ts)) {
|
||||
if (ts)
|
||||
return cond.Wait(&mtx->mtx, *ts);
|
||||
} else if (GetArgument(args, 1, num)) {
|
||||
return cond.Wait(&mtx->mtx, static_cast<uint32_t>(num));
|
||||
} else
|
||||
cond.Wait(&mtx->mtx);
|
||||
}
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(CROSSLANG_STATIC)
|
||||
class DL {
|
||||
@@ -443,6 +489,7 @@ static TObject TypeIsNumber(GCList &ls, std::vector<TObject> args) {
|
||||
return std::holds_alternative<int64_t>(args[0]) ||
|
||||
std::holds_alternative<double>(args[0]);
|
||||
}
|
||||
|
||||
static TObject TypeIsLong(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.empty())
|
||||
return nullptr;
|
||||
@@ -538,6 +585,16 @@ static TObject TypeIsQueryable(GCList &ls, std::vector<TObject> args) {
|
||||
TQueryable *queryable;
|
||||
return GetArgumentHeap(args, 0, queryable);
|
||||
}
|
||||
static TObject TypeIsException(GCList &ls, std::vector<TObject> args) {
|
||||
TException *ex;
|
||||
TNativeException *nex;
|
||||
return GetArgumentHeap(args, 0, ex) || GetArgumentHeap(args, 0, nex);
|
||||
}
|
||||
static TObject TypeIsNativeException(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
TNativeException *nex;
|
||||
return GetArgumentHeap(args, 0, nex);
|
||||
}
|
||||
static TObject New_SubdirFilesystem(GCList &ls, std::vector<TObject> args) {
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
@@ -917,14 +974,10 @@ TObject ParseLong(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
std::string str = ToString(ls.GetGC(), args[0]);
|
||||
|
||||
try {
|
||||
int64_t v = std::stoll(str, &pos, base);
|
||||
if (pos < str.size())
|
||||
return nullptr;
|
||||
return v;
|
||||
} catch (std::exception &ex) {
|
||||
return nullptr;
|
||||
}
|
||||
int64_t d;
|
||||
if (Tesses::Framework::Serialization::BitConverter::TryParseSigned(
|
||||
str, d, base))
|
||||
return d;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -936,14 +989,10 @@ TObject ParseDouble(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
std::string str = ToString(ls.GetGC(), args[0]);
|
||||
|
||||
try {
|
||||
double v = std::stod(str, &pos);
|
||||
if (pos < str.size())
|
||||
return nullptr;
|
||||
return v;
|
||||
} catch (std::exception &ex) {
|
||||
return nullptr;
|
||||
}
|
||||
double d;
|
||||
if (Tesses::Framework::Serialization::BitConverter::TryParseDouble(str,
|
||||
d))
|
||||
return d;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1212,6 +1261,26 @@ static TObject New_Queryable(GCList &ls, std::vector<TObject> args) {
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject New_Exception(GCList &ls, std::vector<TObject> args) {
|
||||
// TException(message,$type,$extrafields,$innerException);
|
||||
|
||||
std::string message;
|
||||
|
||||
if (GetArgument(args, 0, message)) {
|
||||
std::string type = "Exception";
|
||||
TDictionary *extraFields = nullptr;
|
||||
TObject innerException = Undefined();
|
||||
GetArgument(args, 1, type);
|
||||
GetArgumentHeap(args, 2, extraFields);
|
||||
if (args.size() > 3)
|
||||
innerException = args[3];
|
||||
|
||||
return ls.Create<TException>(message, type, extraFields,
|
||||
innerException);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TStd::RegisterRoot(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
GCList ls(gc);
|
||||
@@ -1426,7 +1495,13 @@ void TStd::RegisterRoot(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
env->DeclareFunction(gc, "TypeIsQueryable",
|
||||
"Get whether object is a Queryable", {"object"},
|
||||
TypeIsQueryable);
|
||||
|
||||
env->DeclareFunction(
|
||||
gc, "TypeIsException",
|
||||
"Get whether object is either an Exception or a NativeException",
|
||||
{"object"}, TypeIsException);
|
||||
env->DeclareFunction(gc, "TypeIsNativeException",
|
||||
"Get whether object is a NativeException", {"object"},
|
||||
TypeIsNativeException);
|
||||
newTypes->DeclareFunction(
|
||||
gc, "Regex", "Create regex object", {"regex"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
@@ -1438,9 +1513,14 @@ void TStd::RegisterRoot(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
return nullptr;
|
||||
});
|
||||
newTypes->DeclareFunction(
|
||||
gc, "Mutex", "Create mutex", {},
|
||||
gc, "Mutex", "Create a mutex", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return TNativeObject::Create<TMuxex>(ls);
|
||||
return TNativeObject::Create<TMutex>(ls);
|
||||
});
|
||||
newTypes->DeclareFunction(
|
||||
gc, "Cond", "Create a conditional variable", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return TNativeObject::Create<TCond>(ls);
|
||||
});
|
||||
newTypes->DeclareFunction(
|
||||
gc, "Thread", "Create thread", {"callback"},
|
||||
@@ -1481,6 +1561,10 @@ void TStd::RegisterRoot(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return TAssociativeArray::Create(ls);
|
||||
});
|
||||
|
||||
newTypes->DeclareFunction(
|
||||
gc, "Exception", "Create an Exception",
|
||||
{"message", "$type", "$extraFields", "$innerException"}, New_Exception);
|
||||
newTypes->DeclareFunction(
|
||||
gc, "ByteArray",
|
||||
"Create bytearray, with optional either size (to size it) or string "
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "TessesFramework/Uuid.hpp"
|
||||
#include "CrossLang.hpp"
|
||||
#include "TessesFramework/Serialization/BitConverter.hpp"
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
CrossLang is a dynamically-typed scripting language built on
|
||||
TessesFramework, named in honor of Jesus's sacrifice.
|
||||
|
||||
Copyright (C) 2026 Mike Nolan
|
||||
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "CrossLang.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
Reference in New Issue
Block a user