using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Anonymus
{
public abstract class InnerScopeRecognizer
{
public abstract PString[] GetInnerScope(ScopeNode Scope, PString Line, int Index, bool Mod = true, object Data = null);
}
public abstract class DeclarationRecognizer
{
public abstract bool Recognize(ProcessableScope Scope);
}
public delegate bool OnVarCreatedFunc(Variable Var);
public abstract class ScopeNode : IdContainer
{
public PString[] Source;
public ScopeNode(IdContainer Parent, PString[] Source)
: base(Parent)
{
this.Source = Source;
}
public int CalcSourceLength()
{
if (Source == null) return 0;
var Ret = 0;
foreach (var e in Source)
if (e != null) Ret += e.StrLen;
return Ret;
}
public virtual void GetMTProcIds(List<Identifier> Ids)
{
}
public override IEnumerable<IdContainer> EnumChildren
{
get
{
foreach (var Id in Identifiers)
{
var Func = Id as Function;
if (Func != null && Func.FunctionScope != null)
yield return Func.FunctionScope;
}
foreach (var e in base.EnumChildren)
yield return e;
}
}
public PString[] InnerScope(PString Line, int Index, bool Mod = true)
{
return State.Language.InnerScopeRecognizer.GetInnerScope(this, Line, Index, Mod);
}
public PString[] FInnerScope(PString Command, PString Line, int Index, bool Mod = true, bool Warning = true)
{
var Inner = InnerScope(Line, Index, Mod);
if (Inner == null) return null;
if (Inner.Length == 0 && Warning)
{
State.Messages.Add(MessageId.EmptyScope, Command);
return null;
}
return Inner;
}
public virtual void GetAsmCode(Compiler Comp, GetAsmCodeMode Mode)
{
foreach (var Id in Identifiers)
if (Id.DeclInThis) Id.GetAsmCode(Comp, Mode);
}
}
public abstract class ProcessableScope : ScopeNode
{
public TypeDeclList TypeDeclarations = new TypeDeclList();
public bool DeclareTypes()
{
var RetValue = TypeDeclarations.AddFromString(this) && TypeDeclarations.Declare();
foreach (var e in TypeDeclarations.DeclaredScopes())
if (!e.DeclareTypes()) RetValue = false;
return RetValue;
}
public virtual void GetTypeDeclarations(TypeDeclList List, int Depth = 0)
{
List.AddRange(TypeDeclarations);
var NDepth = Depth + 1;
foreach (var e in TypeDeclarations.DeclaredScopes())
e.GetTypeDeclarations(List, NDepth);
}
public virtual TypeDeclList GetTypeDeclarations()
{
var Ret = new TypeDeclList();
GetTypeDeclarations(Ret);
return Ret;
}
public virtual bool ProcessScope()
{
return State.Language.DeclarationRecognizer.Recognize(this);
}
public ProcessableScope(IdContainer Parent, PString[] Source)
: base(Parent, Source)
{
}
public virtual bool OnUnTypedFuncDecl(ModifierList Mods, PString Name,
VarDeclList Params, PString[] Inner)
{
State.Messages.Add(MessageId.Unnamed, Name);
return false;
}
public virtual bool OnTypedFuncDecl(ModifierList Mods, PString TypeName,
PString Name, VarDeclList Params, PString[] Inner)
{
return DeclareFunction(TypeName, Name, Params, Inner, Mods) != null;
}
}
public class ImportScopeNode : ExternScopeNode
{
public string Library;
public string Name;
public ImportScopeNode(IdContainer Parent, string Library, PString[] Source)
: base(Parent, Source)
{
this.Library = Library;
}
}
public class ExternScopeNode : ProcessableScope
{
public ExternScopeNode(IdContainer Parent, PString[] Source)
: base(Parent, Source)
{
}
public override Variable CreateVariable(PString Name, Type Type, ModifierList Mods = null)
{
throw new NotImplementedException();
}
public override Function DeclareFunction(Type RetType, PString Name, VarDeclList Params,
PString[] Inner, ModifierList Mods = null, Function Func = null)
{
var Type = new FunctionType(this, Name, CallConv.AsCall, RetType, Params);
Type.SetUsed();
if (Inner.Length > 0)
{
State.Messages.Add(MessageId.FuncCannotHaveInnerScope, Name);
return null;
}
return DeclareFunction(Type, Name, null, Mods, Func);
}
}
public abstract class GlobalScopeProcessor
{
public abstract bool Process(GlobalScopeNode Scope);
}
public class GlobalScopeNode : ProcessableScope
{
CompilerState _State;
PreprocessorState _PreState;
public override CompilerState State
{
get { return _State; }
}
public override PreprocessorState PreState
{
get { return _PreState; }
}
public List<ImportScopeNode> ImportScopes;
public List<ExternScopeNode> ExternScopes;
public List<GlobalVariable> ExprConsts = new List<GlobalVariable>();
public List<Type> BasicTypes = new List<Type>();
public List<NumberType> NumTypes = new List<NumberType>();
public BoolType BoolType;
public VoidType VoidType;
public AutomaticType AutoType;
public ConstStringType CStrType;
public TypeOfType TypeOfType;
public override IEnumerable<IdContainer> EnumChildren
{
get
{
if (ImportScopes != null)
foreach (var e in ImportScopes)
yield return e;
if (ExternScopes != null)
foreach (var e in ExternScopes)
yield return e;
foreach (var e in base.EnumChildren)
yield return e;
}
}
public override T GetIdRec<T>(PString Name, GetIdMode Mode = GetIdMode.Everywhere,
bool SearchedInBasicTypes = false)
{
if (ImportScopes != null)
foreach (var e in ImportScopes)
{
var Ret = e.Identifiers.GetIdRec<T>(Name.String);
if (Ret != null) return Ret;
}
if (ExternScopes != null)
foreach (var e in ExternScopes)
{
var Ret = e.Identifiers.GetIdRec<T>(Name.String);
if (Ret != null) return Ret;
}
return base.GetIdRec<T>(Name, Mode, SearchedInBasicTypes);
}
public override void GetMTProcIds(List<Identifier> Ids)
{
Func<Identifier, bool> Func = x => x is Function || x is Variable;
Ids.AddRange(Identifiers.Where(Func));
}
public GlobalVariable CreateExprConst(ConstData Value, Type Type)
{
foreach (var e in ExprConsts)
if (e.Type == Type && Value.IsEqual(e.GlbInitVal))
return e;
var Name = new PString(State.NextLabelIndex.ToString());
var Ret = CreateVariable(Name, Type) as GlobalVariable;
Ret.GlbInitVal = Value;
ExprConsts.Add(Ret);
return Ret;
}
public GlobalVariable CreateExprConst(ConstExpressionNode Node)
{
return CreateExprConst(Node.Value, Node.Type);
}
public ExpressionNode CreateConstRId(ConstExpressionNode ConstNode, ExprPlugIn PlugIn)
{
var Glb = CreateExprConst(ConstNode);
var RIdNode = new IdExpressionNode(Glb, ConstNode.Code);
return PlugIn.NewNode(RIdNode);
}
public Function GetEntry()
{
if (!State.HasMainFunc) return null;
var Fun = GlobalScope.GetId<Function>(new PString(State.Entry), EnableMessages: false);
if (Fun == null)
{
State.Messages.Add(MessageId.EntryNotFound, (PString)null, State.Entry);
return null;
}
return Fun;
}
public override Variable CreateVariable(PString Name, Type Type, ModifierList Mods = null)
{
var Ret = new GlobalVariable(this, Name, Type);
if (Mods != null && !Mods.Apply(this, Ret)) return null;
State.Arch.OnNewIdentifier(Ret);
return Ret;
}
public bool ProcessTypes(MTCompiler C)
{
var RetValue = DeclareTypes();
var Decls = GetTypeDeclarations();
if (!Decls.ResolveTypedefs()) RetValue = false;
if (!ProcessScope()) RetValue = false;
else GetMTProcIds(C.Identifiers);
foreach (var e in Decls.DeclaredScopes())
{
if (!e.ProcessScope()) RetValue = false;
else e.GetMTProcIds(C.Identifiers);
}
return RetValue;
}
public bool Process()
{
if (!State.Language.GlobalScopeProcessor.Process(this))
return false;
var Compiler = new MTCompiler(State, this);
if (!ProcessTypes(Compiler)) return false;
if (!Compiler.Run()) return false;
ChkUnusedIds();
PreState.ChkUnusedMacros();
return true;
}
public GlobalScopeNode(PreprocessorState PreState, CompilerState State, PString[] Source)
: base(null, Source)
{
this._PreState = PreState;
this._State = State;
// ----------------------------------------------------------------------------------------------------
NumTypes.Add(new SignedType(this, new PString("sbyte"), 1, "sb") { DeclInThis = false, DeclaredType = true });
NumTypes.Add(new SignedType(this, new PString("short"), 2, "s") { DeclInThis = false, DeclaredType = true });
NumTypes.Add(new SignedType(this, new PString("int"), 4, "i") { DeclInThis = false, DeclaredType = true });
NumTypes.Add(new SignedType(this, new PString("long"), 8, "l") { DeclInThis = false, DeclaredType = true });
NumTypes.Add(new UnsignedType(this, new PString("byte"), 1, "b") { DeclInThis = false, DeclaredType = true });
NumTypes.Add(new UnsignedType(this, new PString("ushort"), 2, "us") { DeclInThis = false, DeclaredType = true });
NumTypes.Add(new UnsignedType(this, new PString("uint"), 4, "u") { DeclInThis = false, DeclaredType = true });
NumTypes.Add(new UnsignedType(this, new PString("ulong"), 8, "ul") { DeclInThis = false, DeclaredType = true });
NumTypes.Add(new FloatType(this, new PString("float"), 4, "f") { DeclInThis = false, DeclaredType = true });
NumTypes.Add(new FloatType(this, new PString("double"), 8, "d") { DeclInThis = false, DeclaredType = true });
BoolType = new BoolType(this, new PString("bool"), 1, 1UL, 0UL) { DeclInThis = false, DeclaredType = true };
VoidType = new VoidType(this, new PString("void")) { DeclInThis = false, DeclaredType = true };
CStrType = new ConstStringType(this, new PString("string")) { DeclInThis = false, DeclaredType = true };
AutoType = new AutomaticType(this, new PString("var")) { DeclInThis = false, DeclaredType = true };
TypeOfType = new TypeOfType(this, new PString("type")) { DeclInThis = false, DeclaredType = true };
// ----------------------------------------------------------------------------------------------------
BasicTypes.AddRange(NumTypes);
BasicTypes.Add(BoolType);
BasicTypes.Add(VoidType);
BasicTypes.Add(AutoType);
//BasicTypes.Add(TypeOfType);
State.Arch.OnNewContainer(this);
}
public override void GetAsmCode(Compiler Comp, GetAsmCodeMode Mode)
{
base.GetAsmCode(Comp, Mode);
if (Mode == GetAsmCodeMode.Data)
{
foreach (var e in ExprConsts)
{
Comp.Label(e.AsmName);
Comp.Declare(e.Type, e.GlbInitVal);
}
foreach (var Scope in TypeDeclarations.DeclaredScopes())
Scope.GetAsmCode(Comp, Mode);
}
}
public StringBuilder GetExternCode()
{
var Ret = new StringBuilder();
if (ExternScopes != null)
{
foreach (var Scope in ExternScopes)
foreach (var Id in Scope.Identifiers)
if (Id.Used) Ret.Append("\textrn " + Id.AsmName + "\n");
}
return Ret;
}
public StringBuilder GetImportCode()
{
var Ret = new StringBuilder();
var Index = 0;
var Lst = new StringBuilder();
if (ImportScopes != null)
{
foreach (var Scope in ImportScopes)
{
Index++;
Scope.Name = "dll" + Index.ToString();
if (Index > 1) Lst.Append(", \\\n\t ");
Lst.Append(Scope.Name + ", \"" + Scope.Library + "\"");
}
}
if (Lst.Length > 0)
{
Ret.Append("\tlibrary ");
Ret.Append(Lst);
Ret.Append("\n\n");
foreach (var Scope in ImportScopes)
{
Lst = new StringBuilder();
Index = 0;
foreach (var Id in Scope.Identifiers)
{
Index++;
if (Index > 1) Lst.Append(", \\\n\t ");
Lst.Append(Id.AsmName + ", \"" + Id.Name + "\"");
}
if (Lst.Length > 0)
{
Ret.Append("\timport " + Scope.Name);
Ret.Append(", \\\n\t ");
Ret.Append(Lst);
Ret.Append("\n\n");
}
}
}
return Ret;
}
}
}