I am writing a toy language with Antlr4 and C#. Now i am trying to write a class system. But a big problem stopped my all work. When i try to clone instance of a user created class , everything in it references to original class. My 'Class' code is here
[Serializable]
public class Class : ICloneable
{
public string ID;
public ClassDef ClassContent = new ClassDef();
public Helper ErrorHandler = new Helper();
public Class()
{
ID = "";
}
public Class(string id)
{
ID = id;
}
public void Create(MainGrammarParser.ClassblockContext block)
{
ClassDef def = new ClassDef();
def.Visit(block);
ClassContent = def;
}
public object Clone()
{
Class clone = new Class(ID);
clone.ClassContent = ClassContent.DeepClone();
return clone;
}
}
and code for 'ClassDef'
public class ClassDef : SuperClass, ICloneable
{
public override bool VisitClassStatFunctionDef([NotNull] MainGrammarParser.ClassStatFunctionDefContext context)
{
FunctionDefParser fd = GetFunctionDefParser();
fd.Visit(context.functiondef());
return true;
}
public override bool VisitClassStatElementDef([NotNull] MainGrammarParser.ClassStatElementDefContext context)
{
string id = context.classelem().ID().GetText();
if (IsVarExists(id) || IsFunctionExists(id) || IsClassExists(id))
{
ErrorHandler.DuplicateError("[ELEMENT] '" + id + "'");
}
ExpParser exp = GetExpParser();
VarObject v = new VarObject(id);
v.Value = exp.Visit(context.classelem().exp());
Variables.Add(v);
return true;
}
}
and a superclass code
public class SuperClass : MainGrammarBaseVisitor<bool>, ICloneable
{
public VarCollection Variables = new VarCollection();
public FunctionCollection Functions = new FunctionCollection();
public ClassCollection Classes = new ClassCollection();
public Helper ErrorHandler = new Helper();
public VarObject GetVar(string id)
{
if (!IsVarExists(id))
{
ErrorHandler.NotFoundError("[DEFINITION] '" + id + "'");
}
return Variables.Find(id);
}
public Function GetFunction(string id)
{
if (!IsFunctionExists(id))
{
ErrorHandler.NotFoundError("[METHOD] '" + id + "'");
}
return Functions.Find(id);
}
public Class GetClass(string id)
{
if (!IsClassExists(id))
{
ErrorHandler.NotFoundError("[CLASS] '" + id + "'");
}
return Classes.Find(id);
}
public bool IsVarExists(string id)
{
if (!Variables.Contains(id)) { return false; }
return true;
}
public bool IsFunctionExists(string id)
{
if (!Functions.Contains(id)) { return false; }
return true;
}
public bool IsClassExists(string id)
{
if (!Classes.Contains(id)) { return false; }
return true;
}
public ExpParser GetExpParser()
{
ExpParser output = new ExpParser();
output.Parent = this;
return output;
}
public EqualityParser GetEqualityParser()
{
EqualityParser output = new EqualityParser();
output.Parent = this;
return output;
}
public FunctionDefParser GetFunctionDefParser()
{
FunctionDefParser output = new FunctionDefParser();
output.Parent = this;
return output;
}
public IfParser GetIfParser()
{
IfParser output = new IfParser();
output.Parent = this;
return output;
}
public object Clone()
{
SuperClass output = new SuperClass();
output.Variables = Variables.DeepClone();
output.Functions = Functions.DeepClone();
output.Classes = Classes.DeepClone();
return output;
}
public SuperClass()
{ }
}
I writed VarCollection, FunctionCollection and ClassCollection myself They are just lists with find and exists methods. When i try a code like this in my language
class abc
{
this a = "a"
this b = "b"
this c = "c"
void abc(){}
}
newabc1 = new abc()
newabc1.a = 10
new1a = newabc1.a
newabc2 = new abc()
new2a = newabc2.a
both 'new1a' and new2a is set to 10. I tried most of techniques including: Reflection, Serialization, JsonSerialization, ICloneable, MemberWiseClone...
In serialization, I need to put [Serializable] to every class, including Antlr4 auto generated classes. So when I update grammar I need to put them again.
In Json Serialization(NewtonJson), serialization enters a infinite loop (Serializator warned me about self referencing loop and i disabled loop error).
Reflection, IClonable, MemberWiseClone, none of these worked correctly. They reference same address at memory so i get same error.
Any help?
Aucun commentaire:
Enregistrer un commentaire