2-27-2025
This commit is contained in:
@ -43,4 +43,3 @@ sudo make install
|
|||||||
```
|
```
|
||||||
Ye are of God, little children, and have overcome them: because greater is he that is in you, than he that is in the world. (1 John 4:4)
|
Ye are of God, little children, and have overcome them: because greater is he that is in you, than he that is in the world. (1 John 4:4)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -480,6 +480,16 @@ class CharInstruction : public ByteCodeInstruction {
|
|||||||
|
|
||||||
using SyntaxNode = std::variant<int64_t, double, std::string, char, bool, std::nullptr_t, Undefined, AdvancedSyntaxNode>;
|
using SyntaxNode = std::variant<int64_t, double, std::string, char, bool, std::nullptr_t, Undefined, AdvancedSyntaxNode>;
|
||||||
|
|
||||||
|
class ObjectEntry {
|
||||||
|
public:
|
||||||
|
std::vector<std::string> name;
|
||||||
|
std::string doc;
|
||||||
|
std::vector<std::pair<std::string,SyntaxNode>> variables;
|
||||||
|
std::vector<std::pair<std::pair<std::string,std::string>,uint32_t>> funcs;
|
||||||
|
std::vector<std::pair<std::pair<std::string,std::string>,uint32_t>> static_funcs;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class CodeGen {
|
class CodeGen {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint32_t NewId();
|
uint32_t NewId();
|
||||||
@ -494,6 +504,7 @@ class CodeGen {
|
|||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
std::vector<std::pair<std::vector<uint32_t>, std::vector<ByteCodeInstruction*>>> chunks;
|
std::vector<std::pair<std::vector<uint32_t>, std::vector<ByteCodeInstruction*>>> chunks;
|
||||||
std::vector<std::pair<std::vector<uint32_t>,uint32_t>> funcs;
|
std::vector<std::pair<std::vector<uint32_t>,uint32_t>> funcs;
|
||||||
|
std::vector<ObjectEntry> objectEntries;
|
||||||
void GenNode(std::vector<ByteCodeInstruction*>& instructions, SyntaxNode n,int32_t scope, int32_t contscope, int32_t brkscope, int32_t contI, int32_t brkI);
|
void GenNode(std::vector<ByteCodeInstruction*>& instructions, SyntaxNode n,int32_t scope, int32_t contscope, int32_t brkscope, int32_t contI, int32_t brkI);
|
||||||
void GenPop(std::vector<ByteCodeInstruction*>& instrs,SyntaxNode n);
|
void GenPop(std::vector<ByteCodeInstruction*>& instrs,SyntaxNode n);
|
||||||
public:
|
public:
|
||||||
@ -575,6 +586,11 @@ constexpr std::string_view EnumerableStatement = "enumerableStatement";
|
|||||||
constexpr std::string_view SwitchStatement = "switchStatement";
|
constexpr std::string_view SwitchStatement = "switchStatement";
|
||||||
constexpr std::string_view CaseStatement = "caseStatement";
|
constexpr std::string_view CaseStatement = "caseStatement";
|
||||||
constexpr std::string_view DefaultStatement = "defaultStatement";
|
constexpr std::string_view DefaultStatement = "defaultStatement";
|
||||||
|
constexpr std::string_view ObjectStatement = "objectStatement";
|
||||||
|
constexpr std::string_view StaticStatement = "staticStatement";
|
||||||
|
constexpr std::string_view MethodDeclaration = "methodDeclaration";
|
||||||
|
|
||||||
|
|
||||||
class AdvancedSyntaxNode {
|
class AdvancedSyntaxNode {
|
||||||
public:
|
public:
|
||||||
std::string nodeName;
|
std::string nodeName;
|
||||||
@ -659,7 +675,7 @@ class Parser {
|
|||||||
class MethodInvoker {
|
class MethodInvoker {
|
||||||
|
|
||||||
};
|
};
|
||||||
using TObject = std::variant<int64_t,double,char,bool,std::string,std::regex,Tesses::Framework::Filesystem::VFSPath,std::nullptr_t,Undefined,MethodInvoker,THeapObjectHolder>;
|
using TObject = std::variant<int64_t,double,char,bool,std::string,std::regex,Tesses::Framework::Filesystem::VFSPath,std::nullptr_t,Undefined,MethodInvoker,THeapObjectHolder,Tesses::Framework::Graphics::Color>;
|
||||||
class TRootEnvironment;
|
class TRootEnvironment;
|
||||||
class GC;
|
class GC;
|
||||||
class GC {
|
class GC {
|
||||||
|
|||||||
@ -911,7 +911,7 @@ namespace Tesses::CrossLang
|
|||||||
contscope = old_contscope;
|
contscope = old_contscope;
|
||||||
brkscope = old_brkscope;
|
brkscope = old_brkscope;
|
||||||
}
|
}
|
||||||
else if(adv.nodeName == CommaExpression && adv.nodeName.size() == 2)
|
else if(adv.nodeName == CommaExpression && adv.nodes.size() == 2)
|
||||||
{
|
{
|
||||||
GenNode(instructions,adv.nodes[0],scope,contscope,brkscope,contI,brkI);
|
GenNode(instructions,adv.nodes[0],scope,contscope,brkscope,contI,brkI);
|
||||||
GenPop(instructions,adv.nodes[0]);
|
GenPop(instructions,adv.nodes[0]);
|
||||||
|
|||||||
@ -165,6 +165,14 @@ namespace Tesses::CrossLang
|
|||||||
node = AdvancedSyntaxNode::Create(GetVariableExpression, true,{"operator"+variable.text});
|
node = AdvancedSyntaxNode::Create(GetVariableExpression, true,{"operator"+variable.text});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if(IsIdentifier("new"))
|
||||||
|
{
|
||||||
|
if(i >= tokens.size()) throw std::out_of_range("End of file");
|
||||||
|
auto variable = tokens[i];
|
||||||
|
i++;
|
||||||
|
if(variable.type != LexTokenType::Identifier && variable.type != LexTokenType::Symbol) throw SyntaxException(variable.lineInfo, "Expected an identifier or a symbol got a " + LexTokenType_ToString(variable.type) + " \"" + variable.text + "\"");
|
||||||
|
node = AdvancedSyntaxNode::Create(GetFieldExpression, true, {AdvancedSyntaxNode::Create(GetVariableExpression,true,{"New"}), variable.text});
|
||||||
|
}
|
||||||
else if(IsIdentifier("embed"))
|
else if(IsIdentifier("embed"))
|
||||||
{
|
{
|
||||||
EnsureSymbol("(");
|
EnsureSymbol("(");
|
||||||
@ -339,6 +347,7 @@ namespace Tesses::CrossLang
|
|||||||
{
|
{
|
||||||
return AdvancedSyntaxNode::Create(PrefixDecrementExpression,true,{ParseUnary()});
|
return AdvancedSyntaxNode::Create(PrefixDecrementExpression,true,{ParseUnary()});
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseValue();
|
return ParseValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,6 +566,10 @@ namespace Tesses::CrossLang
|
|||||||
}
|
}
|
||||||
return AdvancedSyntaxNode::Create(EachStatement,false,{item,list,body});
|
return AdvancedSyntaxNode::Create(EachStatement,false,{item,list,body});
|
||||||
}
|
}
|
||||||
|
if(IsIdentifier("object"))
|
||||||
|
{
|
||||||
|
//TODO: complete this
|
||||||
|
}
|
||||||
if(IsIdentifier("enumerable"))
|
if(IsIdentifier("enumerable"))
|
||||||
{
|
{
|
||||||
auto nameAndArgs = ParseExpression();
|
auto nameAndArgs = ParseExpression();
|
||||||
|
|||||||
@ -118,6 +118,18 @@ namespace Tesses::CrossLang
|
|||||||
TVFSHeapObject* vfs;
|
TVFSHeapObject* vfs;
|
||||||
return GetArgumentHeap(args,0,vfs);
|
return GetArgumentHeap(args,0,vfs);
|
||||||
}
|
}
|
||||||
|
static TObject New_Color(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
int64_t r,g,b,a;
|
||||||
|
if(GetArgument(args,0,r) && GetArgument(args,1,g) && GetArgument(args,2,b))
|
||||||
|
{
|
||||||
|
if(!GetArgument(args,3,a)) {
|
||||||
|
a = 255;
|
||||||
|
}
|
||||||
|
return Tesses::Framework::Graphics::Color((uint8_t)r,(uint8_t)g,(uint8_t)b,(uint8_t)a);
|
||||||
|
}
|
||||||
|
return Tesses::Framework::Graphics::Colors::Black;
|
||||||
|
}
|
||||||
static TObject TypeOf(GCList& ls, std::vector<TObject> args)
|
static TObject TypeOf(GCList& ls, std::vector<TObject> args)
|
||||||
{
|
{
|
||||||
if(args.size() < 1) return "Undefined";
|
if(args.size() < 1) return "Undefined";
|
||||||
@ -329,8 +341,10 @@ namespace Tesses::CrossLang
|
|||||||
|
|
||||||
void TStd::RegisterRoot(GC* gc, TRootEnvironment* env)
|
void TStd::RegisterRoot(GC* gc, TRootEnvironment* env)
|
||||||
{
|
{
|
||||||
|
GCList ls(gc);
|
||||||
|
|
||||||
env->permissions.canRegisterRoot=true;
|
env->permissions.canRegisterRoot=true;
|
||||||
|
TDictionary* newTypes = TDictionary::Create(ls);
|
||||||
env->DeclareFunction(gc, "ParseLong","Parse Long from String",{"arg","$base"},ParseLong);
|
env->DeclareFunction(gc, "ParseLong","Parse Long from String",{"arg","$base"},ParseLong);
|
||||||
env->DeclareFunction(gc, "ParseDouble","Parse Double from String",{"arg"},ParseDouble);
|
env->DeclareFunction(gc, "ParseDouble","Parse Double from String",{"arg"},ParseDouble);
|
||||||
env->DeclareFunction(gc, "YieldEmumerable","Turn yield in function into enumerable",{"closure"},YieldEnumerableFunc);
|
env->DeclareFunction(gc, "YieldEmumerable","Turn yield in function into enumerable",{"closure"},YieldEnumerableFunc);
|
||||||
@ -414,8 +428,10 @@ namespace Tesses::CrossLang
|
|||||||
return Undefined();
|
return Undefined();
|
||||||
});
|
});
|
||||||
env->DeclareFunction(gc,"ByteArray","Create bytearray, with optional either size (to size it) or string argument (to fill byte array)",{"$data"},ByteArray);
|
env->DeclareFunction(gc,"ByteArray","Create bytearray, with optional either size (to size it) or string argument (to fill byte array)",{"$data"},ByteArray);
|
||||||
|
newTypes->DeclareFunction(gc,"Color","Create a new color",{"red","green","blue","$alpha"},New_Color);
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
env->DeclareVariable("InvokeMethod",MethodInvoker());
|
env->DeclareVariable("InvokeMethod",MethodInvoker());
|
||||||
|
env->DeclareVariable("New", newTypes);
|
||||||
gc->BarrierEnd();
|
gc->BarrierEnd();
|
||||||
}
|
}
|
||||||
void TStd::RegisterStd(GC* gc, TRootEnvironment* env)
|
void TStd::RegisterStd(GC* gc, TRootEnvironment* env)
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
#include "CrossLang.hpp"
|
#include "CrossLang.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -6,6 +5,79 @@
|
|||||||
|
|
||||||
namespace Tesses::CrossLang
|
namespace Tesses::CrossLang
|
||||||
{
|
{
|
||||||
|
static TObject AstToTObject(GCList& ls,SyntaxNode node)
|
||||||
|
{
|
||||||
|
if(std::holds_alternative<std::nullptr_t>(node))
|
||||||
|
return nullptr;
|
||||||
|
if(std::holds_alternative<int64_t>(node))
|
||||||
|
{
|
||||||
|
return std::get<int64_t>(node);
|
||||||
|
}
|
||||||
|
if(std::holds_alternative<double>(node))
|
||||||
|
{
|
||||||
|
return std::get<double>(node);
|
||||||
|
}
|
||||||
|
if(std::holds_alternative<bool>(node))
|
||||||
|
{
|
||||||
|
return std::get<bool>(node);
|
||||||
|
}
|
||||||
|
if(std::holds_alternative<std::string>(node))
|
||||||
|
{
|
||||||
|
std::string str = std::get<std::string>(node);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
if(std::holds_alternative<char>(node))
|
||||||
|
{
|
||||||
|
char c = std::get<char>(node);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if(std::holds_alternative<Undefined>(node))
|
||||||
|
{
|
||||||
|
auto r = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
r->SetValue("Type",std::string(UndefinedExpression));
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(std::holds_alternative<AdvancedSyntaxNode>(node))
|
||||||
|
{
|
||||||
|
auto asn = std::get<AdvancedSyntaxNode>(node);
|
||||||
|
auto r = TDictionary::Create(ls);
|
||||||
|
ls.GetGC()->BarrierBegin();
|
||||||
|
r->SetValue("Type",asn.nodeName);
|
||||||
|
r->SetValue("IsExpression",asn.isExpression);
|
||||||
|
TList* ls2 = TList::Create(ls);
|
||||||
|
for(auto item : asn.nodes)
|
||||||
|
{
|
||||||
|
ls2->Add(AstToTObject(ls,item));
|
||||||
|
}
|
||||||
|
r->SetValue("Arguments", ls2);
|
||||||
|
ls.GetGC()->BarrierEnd();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
static TObject VM_SourceToAst(GCList& ls, std::vector<TObject> args)
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
if(GetArgument(args,0,str))
|
||||||
|
{
|
||||||
|
std::stringstream strm(str);
|
||||||
|
std::vector<LexToken> tokens;
|
||||||
|
int res = Lex("memory.tcross",strm,tokens);
|
||||||
|
if(res != 0)
|
||||||
|
{
|
||||||
|
throw VMException("Lex error at line: " + std::to_string(res));
|
||||||
|
}
|
||||||
|
Parser p(tokens);
|
||||||
|
auto res2 =p.ParseRoot();
|
||||||
|
return AstToTObject(ls,res2);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
static TObject VM_Eval(GCList& ls, std::vector<TObject> args)
|
static TObject VM_Eval(GCList& ls, std::vector<TObject> args)
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
@ -201,7 +273,7 @@ namespace Tesses::CrossLang
|
|||||||
dict->DeclareFunction(gc, "Eval", "Eval source code",{"source"}, VM_Eval);
|
dict->DeclareFunction(gc, "Eval", "Eval source code",{"source"}, VM_Eval);
|
||||||
dict->DeclareFunction(gc, "Compile", "Compile Source",{"dict"},VM_Compile);
|
dict->DeclareFunction(gc, "Compile", "Compile Source",{"dict"},VM_Compile);
|
||||||
|
|
||||||
|
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast", {"source"}, VM_SourceToAst);
|
||||||
|
|
||||||
gc->BarrierBegin();
|
gc->BarrierBegin();
|
||||||
env->DeclareVariable("VM", dict);
|
env->DeclareVariable("VM", dict);
|
||||||
|
|||||||
@ -158,10 +158,9 @@ namespace Tesses::CrossLang {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
}
|
||||||
this->call_stack_entries.back()->Push(ls.GetGC(),Undefined());
|
this->call_stack_entries.back()->Push(ls.GetGC(),Undefined());
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool InterperterThread::Sub(GC* gc)
|
bool InterperterThread::Sub(GC* gc)
|
||||||
|
|||||||
Reference in New Issue
Block a user