2023-07-29 00:11:09 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
namespace TLang.VM
|
|
|
|
{
|
|
|
|
public class TClassInstance : TObject
|
|
|
|
{
|
2023-07-30 07:55:10 +00:00
|
|
|
public override string Type => $"class {classEntry.Name} : {classEntry.InheritsFrom}";
|
|
|
|
public override bool True => true;
|
2023-07-29 00:11:09 +00:00
|
|
|
TVMFile file;
|
|
|
|
Class classEntry;
|
|
|
|
TLangEnvironment oGenv;
|
|
|
|
public TClassInstance(TVMFile file,Class classEntry,TLangEnvironment env)
|
|
|
|
{
|
|
|
|
this.file = file;
|
|
|
|
this.classEntry = classEntry;
|
|
|
|
this.oGenv = env;
|
|
|
|
}
|
|
|
|
public List<string> InheritenceTree {get;}=new List<string>();
|
|
|
|
public Dictionary<string,ClassMethod> Methods {get;} = new Dictionary<string, ClassMethod>();
|
|
|
|
|
2023-07-30 07:55:10 +00:00
|
|
|
public Dictionary<string,ClassField> Fields {get;} = new Dictionary<string, ClassField>();
|
|
|
|
|
2023-07-29 00:11:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
public void Init(params TObject[] args)
|
|
|
|
{
|
|
|
|
Environment = new ClassEnvironment(oGenv,this);
|
|
|
|
|
|
|
|
foreach(var item in classEntry.ClassEntries)
|
|
|
|
{
|
2023-07-30 07:55:10 +00:00
|
|
|
if(item.Method)
|
|
|
|
{
|
|
|
|
ClassMethod meth=new ClassMethod();
|
|
|
|
TClosure closure=new TClosure(file,file.Chunks[item.ChunkId],Environment);
|
|
|
|
|
|
|
|
meth.Private = item.Private;
|
|
|
|
meth.Protected = item.Protected;
|
|
|
|
meth.Closure = closure;
|
|
|
|
meth.ClassName = classEntry.Name;
|
|
|
|
|
|
|
|
Methods.Add(item.Name,meth);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ClassField field = new ClassField();
|
|
|
|
field.ClassName = classEntry.Name;
|
|
|
|
TClosure closure = new TClosure(file,file.Chunks[item.ChunkId],Environment);
|
|
|
|
field.Private = item.Private;
|
|
|
|
field.Protected = item.Protected;
|
|
|
|
field.Value = closure.Execute();
|
|
|
|
Fields.Add(item.Name,field);
|
|
|
|
|
|
|
|
}
|
2023-07-29 00:11:09 +00:00
|
|
|
}
|
|
|
|
var cE = classEntry;
|
|
|
|
var aC =oGenv.GetRootEnvironment().AvailableClasses;
|
|
|
|
//we need to check inheritence
|
2023-07-30 07:55:10 +00:00
|
|
|
while(cE.InheritsFrom != "object" && cE.InheritsFrom != "")
|
2023-07-29 00:11:09 +00:00
|
|
|
{
|
|
|
|
InheritenceTree.Add(cE.InheritsFrom);
|
|
|
|
if(aC.ContainsKey(cE.InheritsFrom))
|
|
|
|
{
|
|
|
|
var aC2 = aC[cE.InheritsFrom];
|
|
|
|
cE = aC2.ToClass(cE.InheritsFrom);
|
|
|
|
foreach(var item in cE.ClassEntries)
|
|
|
|
{
|
2023-07-30 07:55:10 +00:00
|
|
|
if(!Fields.ContainsKey(item.Name) && !item.Method)
|
|
|
|
{
|
|
|
|
ClassField field = new ClassField();
|
|
|
|
field.ClassName = cE.Name;
|
|
|
|
TClosure closure = new TClosure(aC2.File,aC2.File.Chunks[item.ChunkId],Environment);
|
|
|
|
field.Private = item.Private;
|
|
|
|
field.Protected = item.Protected;
|
|
|
|
field.Value = closure.Execute();
|
|
|
|
Fields.Add(item.Name,field);
|
|
|
|
}
|
2023-07-29 00:11:09 +00:00
|
|
|
if(!Methods.ContainsKey(item.Name) && item.Method)
|
|
|
|
{
|
|
|
|
if(item.Abstract) throw new Exception("Method is abstract");
|
|
|
|
ClassMethod meth=new ClassMethod();
|
2023-07-30 07:55:10 +00:00
|
|
|
TClosure closure=new TClosure(aC2.File,aC2.File.Chunks[item.ChunkId],Environment);
|
|
|
|
meth.ClassName = cE.Name;
|
|
|
|
meth.Closure = closure;
|
2023-07-29 00:11:09 +00:00
|
|
|
meth.Private = item.Private;
|
|
|
|
meth.Protected = item.Protected;
|
2023-07-30 07:55:10 +00:00
|
|
|
|
2023-07-29 00:11:09 +00:00
|
|
|
Methods.Add(item.Name,meth);
|
|
|
|
}
|
2023-07-30 07:55:10 +00:00
|
|
|
|
2023-07-29 00:11:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-07-30 07:55:10 +00:00
|
|
|
if(!Methods.ContainsKey("toString"))
|
|
|
|
{
|
|
|
|
Methods.Add("toString",new ClassMethod(){ClassName="object", Closure = new TExternalMethod(e=>new TString($"class {classEntry.Name} : {classEntry.InheritsFrom}")), Private=false, Protected = false});
|
|
|
|
}
|
|
|
|
if(Methods.ContainsKey(classEntry.Name))
|
|
|
|
{
|
|
|
|
var ctor=Methods[classEntry.Name];
|
|
|
|
if(ctor.ClassName == classEntry.Name)
|
|
|
|
{
|
|
|
|
ctor.Closure.ClassName = classEntry.Name;
|
|
|
|
ctor.Closure.Execute(args);
|
|
|
|
}
|
|
|
|
}
|
2023-07-29 00:11:09 +00:00
|
|
|
}
|
|
|
|
public TLangEnvironment Environment {get; private set;}
|
2023-07-30 07:55:10 +00:00
|
|
|
public void SetField(string className,string key,TObject obj)
|
2023-07-29 00:11:09 +00:00
|
|
|
{
|
2023-07-30 07:55:10 +00:00
|
|
|
if(Fields.ContainsKey(key))
|
|
|
|
{
|
|
|
|
var field=Fields[key];
|
|
|
|
if(field.Private && className != classEntry.Name) return;
|
|
|
|
if(field.Protected && className != classEntry.Name && !InheritenceTree.Contains(className)) return;
|
|
|
|
|
|
|
|
|
|
|
|
field.Value=obj;
|
|
|
|
}
|
2023-07-29 00:11:09 +00:00
|
|
|
}
|
|
|
|
public TObject GetField(string className,string key)
|
|
|
|
{
|
2023-07-30 07:55:10 +00:00
|
|
|
if(Fields.ContainsKey(key))
|
|
|
|
{
|
|
|
|
var field=Fields[key];
|
|
|
|
if(field.Private && className != classEntry.Name) return new TUndefined();
|
|
|
|
if(field.Protected && className != classEntry.Name && !InheritenceTree.Contains(className)) return new TUndefined();
|
|
|
|
|
|
|
|
|
|
|
|
return field.Value;
|
|
|
|
}
|
2023-07-29 00:11:09 +00:00
|
|
|
return new TUndefined();
|
|
|
|
}
|
2023-07-30 07:55:10 +00:00
|
|
|
|
|
|
|
public bool MethodExists(string className,string key)
|
|
|
|
{
|
|
|
|
if(Methods.ContainsKey(key))
|
|
|
|
{
|
|
|
|
var method=Methods[key];
|
|
|
|
if(method.Private && className != classEntry.Name) return false;
|
|
|
|
if(method.Protected && className != classEntry.Name && !InheritenceTree.Contains(className)) return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2023-07-29 00:11:09 +00:00
|
|
|
public TObject CallMethod(string className,string key,params TObject[] args)
|
|
|
|
{
|
|
|
|
if(Methods.ContainsKey(key))
|
|
|
|
{
|
|
|
|
var method=Methods[key];
|
|
|
|
if(method.Private && className != classEntry.Name) return new TUndefined();
|
2023-07-30 07:55:10 +00:00
|
|
|
if(method.Protected && className != classEntry.Name && !InheritenceTree.Contains(className)) return new TUndefined();
|
|
|
|
method.Closure.ClassName = method.ClassName;
|
2023-07-29 00:11:09 +00:00
|
|
|
|
2023-07-30 07:55:10 +00:00
|
|
|
return method.Closure.Execute(args);
|
2023-07-29 00:11:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return new TUndefined();
|
|
|
|
}
|
|
|
|
|
2023-07-30 07:55:10 +00:00
|
|
|
public override string ToString()
|
|
|
|
{
|
|
|
|
return CallMethod(classEntry.Name,"toString").ToString();
|
|
|
|
}
|
|
|
|
|
2023-07-29 00:11:09 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|