using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Anonymus
{
public abstract class TypeDeclRecognizer
{
public abstract List<TypeDecl> Recognize(ScopeNode Scope);
}
public enum TypeDeclType
{
Enum,
Flag,
Class,
Struct,
TypeDef,
}
public enum TypeDeclRes
{
Failed,
UnkownTypeDef,
Succeeded,
}
public class TypeDecl
{
public ModifierList Mods;
public TypeDeclType Type;
public ScopeNode Scope;
public PString Name;
public PString Base;
public PString[] Inner;
public ProcessableScope NewScope;
public TypeDecl(ScopeNode Scope, PString Name, TypeDeclType Type,
PString Base, PString[] Inner, ModifierList Mods)
{
this.Scope = Scope;
this.Name = Name;
this.Type = Type;
this.Base = Base;
this.Inner = Inner;
this.Mods = Mods;
}
public TypeDeclRes Declare()
{
if (Scope.IsIdDefined<Identifier>(Name.String, GetIdMode.Scope))
{
Scope.State.Messages.Add(MessageId.IdAlreadyDefined, Name);
return TypeDeclRes.Failed;
}
//------------------------------------------------------------------
else if (Type == TypeDeclType.TypeDef)
{
var NewType = Scope.GetId<Type>(Base, EnableMessages: false);
if (NewType != null)
{
NewType = NewType.CreateTypeDefType(Scope, Name);
if (!Scope.CanIdDeclared(NewType)) return TypeDeclRes.Failed;
if (!Mods.Apply(Scope, NewType)) return TypeDeclRes.Failed;
Scope.State.Arch.OnNewIdentifier(NewType);
Scope.Identifiers.Add(NewType);
NewType.DeclaredType = true;
return TypeDeclRes.Succeeded;
}
return TypeDeclRes.UnkownTypeDef;
}
//------------------------------------------------------------------
else if (Type == TypeDeclType.Struct || Type == TypeDeclType.Class)
{
var NewType = (StructuredType)null;
if (Type == TypeDeclType.Struct) NewType = new ValueType(Scope, Name);
else NewType = new ClassType(Scope, Name);
NewType.Str_Base = Base;
if (!Scope.CanIdDeclared(NewType)) return TypeDeclRes.Failed;
if (!Mods.Apply(Scope, NewType)) return TypeDeclRes.Failed;
NewScope = Scope.CreateStructuredTypeScope(Inner, NewType);
Scope.State.Arch.OnNewIdentifier(NewType);
Scope.Identifiers.Add(NewType);
return TypeDeclRes.Succeeded;
}
//------------------------------------------------------------------
else if (Type == TypeDeclType.Enum || Type == TypeDeclType.Flag)
{
if (Base != null)
{
Scope.State.Messages.Add(MessageId.CannotInherit, Base);
return TypeDeclRes.Failed;
}
var IntType = Scope.GetType(typeof(SignedType), 4);
var NewType = (EnumType)null;
if (Type == TypeDeclType.Flag) NewType = new FlagType(Scope, Name, IntType, null);
else NewType = new EnumType(Scope, Name, IntType, null);
if (!Scope.CanIdDeclared(NewType)) return TypeDeclRes.Failed;
if (!Mods.Apply(Scope, NewType)) return TypeDeclRes.Failed;
NewScope = Scope.CreateEnumTypeScope(Inner, NewType);
Scope.State.Arch.OnNewIdentifier(NewType);
Scope.Identifiers.Add(NewType);
return TypeDeclRes.Succeeded;
}
//------------------------------------------------------------------
else
{
throw new Exception("ERROR");
}
}
}
public class TypeDeclList : List<TypeDecl>
{
public TypeDeclList()
{
}
public bool IsDefined(string Name, ScopeNode Scope)
{
foreach (var e in this)
{
if (e.Name.String == Name && e.Scope == Scope)
return true;
}
return false;
}
public bool AddFromString(ScopeNode Scope)
{
var State = Scope.State;
var Rec = State.Language.TypeDeclRecognizer;
var RetValue = true;
var Res = Rec.Recognize(Scope);
if (Res == null) return false;
foreach (var e in Res)
{
if (IsDefined(e.Name.String, Scope))
{
State.Messages.Add(MessageId.IdAlreadyDefined, e.Name);
RetValue = false;
}
else
{
Add(e);
}
}
return RetValue;
}
public bool ResolveTypedefs()
{
var RetValue = true;
var Count = 1;
var List = new List<TypeDecl>();
foreach (var e in this)
if (e.Type == TypeDeclType.TypeDef)
List.Add(e);
while (Count > 0)
{
Count = 0;
for (var i = 0; i < List.Count; i++)
{
var Res = List[i].Declare();
if (Res == TypeDeclRes.Succeeded) Count++;
if (Res != TypeDeclRes.UnkownTypeDef)
{
List.RemoveAt(i);
i--;
}
}
}
foreach (var e in List)
{
if (e.Scope.GetId<Type>(e.Base) != null)
throw new Exception("ERROR");
RetValue = false;
}
return RetValue;
}
public IEnumerable<ProcessableScope> DeclaredScopes()
{
foreach (var e in this)
if (e.NewScope != null) yield return e.NewScope;
}
public IEnumerable<TypeDecl> EnumDeclarations(TypeDeclType Type)
{
foreach (var e in this)
if (e.Type == Type) yield return e;
}
public bool Declare()
{
var RetValue = true;
foreach (var e in this)
{
if (e.Type != TypeDeclType.TypeDef && e.Declare() != TypeDeclRes.Succeeded)
RetValue = false;
}
return RetValue;
}
}
public abstract class VarDeclRecognizer
{
public abstract List<VarDecl> Recognize(IdContainer Container, PString Code, bool EnableMessages);
}
public enum VarConvMode
{
Nothing,
Normal,
Assignment,
}
public class VarDecl
{
public PString Declaration;
public PString Name;
public PString InitString;
public PString TypeName;
public Type Type;
public VarDecl(PString Declaration, PString TypeName, Type Type, PString Name, PString InitString)
{
this.Declaration = Declaration;
this.TypeName = TypeName;
this.Type = Type;
this.Name = Name;
this.InitString = InitString;
}
public ExpressionNode GetVal(ExprPlugIn PlugIn, bool End = true)
{
return Expressions.NewExpressionTree(InitString, PlugIn, End);
}
public Variable ConvToVar(ExprPlugIn PlugIn, ModifierList Mods = null,
VarConvMode Mode = VarConvMode.Nothing)
{
var Container = PlugIn.Container;
var Ret = Container.CreateVariable(Name, Type, Mods);
if (Ret == null) return null;
Ret.InitString = InitString;
if (Mode != VarConvMode.Nothing)
{
if (!Ret.CalcValue(PlugIn, Mode == VarConvMode.Assignment))
return null;
}
return Ret;
}
}
public class VarDeclList : List<VarDecl>
{
public VarDeclList()
{
}
public bool IsDefined(string Name)
{
foreach (var e in this)
if (e.Name.String == Name) return true;
return false;
}
public bool AddFromString(IdContainer Container, PString String,
bool EnableUnnamed = false, bool EnableAutoType = true, bool EnableMessages = true)
{
var RetValue = true;
var State = Container.State;
var Rec = State.Language.VarDeclRecognizer;
var Res = Rec.Recognize(Container, String, EnableMessages);
if (Res == null) return false;
var Type = (Type)null;
foreach (var e in Res)
{
if (e.Name != null)
{
if (!Helper.IsValidIdentifierName(e.Name.String))
{
if (EnableMessages) State.Messages.Add(MessageId.NotValidName, e.Name);
RetValue = false;
}
if (IsDefined(e.Name.String))
{
if (EnableMessages) State.Messages.Add(MessageId.IdAlreadyDefined, e.Name.String);
RetValue = false;
}
}
else if (!EnableUnnamed)
{
if (EnableMessages) State.Messages.Add(MessageId.MustBeNamed, e.Declaration);
RetValue = false;
}
if (e.TypeName != null)
{
Type = e.Type;
Type.SetUsed();
if (Type is VoidType)
{
if (EnableMessages) State.Messages.Add(MessageId.CannotBeThisType, e.TypeName);
RetValue = false;
}
else if (Type is AutomaticType && !EnableAutoType)
{
if (EnableMessages) State.Messages.Add(MessageId.Untyped, e.TypeName);
RetValue = false;
}
}
else
{
if (Type != e.Type) throw new Exception("ERROR");
}
Add(e);
}
return RetValue;
}
public List<Variable> ConvToVariables(ExprPlugIn PlugIn, ModifierList Mods = null,
VarConvMode Mode = VarConvMode.Nothing)
{
var Ret = new List<Variable>();
foreach (var e in this)
Ret.Add(e.ConvToVar(PlugIn, Mods, Mode));
return Ret;
}
public Type[] GetTypes()
{
var Ret = new Type[Count];
for (var i = 0; i < Count; i++)
Ret[i] = this[i].Type;
return Ret;
}
}
}