using System; using System.IO; using System.Collections.Generic; namespace Convention.Symbolization.Internal { public abstract class Keyword : CloneableVariable { protected Keyword(string keyword) : base(keyword) { Keywords.TryAdd(keyword, this); } public static readonly Dictionary Keywords = new(); public override bool Equals(Keyword other) { return this.GetType() == other.GetType(); } public virtual Keyword ControlContext(SymbolizationContext context, int line, int wordIndex, Variable next) { return ControlContext(context, next); } protected virtual Keyword ControlContext(SymbolizationContext context, Variable next) { return null; } } public abstract class Keyword : Keyword where T : Keyword, new() { private static T MyInstance = new(); protected Keyword(string keyword) : base(keyword) { } public override bool Equals(Variable other) { return MyInstance == other; } } } namespace Convention.Symbolization.Keyword { /// /// file /// public sealed class Import : Internal.Keyword { public Import() : base("import") { } public override Internal.Keyword CloneVariable(string targetSymbolName) { return new Import(); } private ToolFile ImportFile = new("./"); private string buffer = ""; protected override Internal.Keyword ControlContext(SymbolizationContext context, Internal.Variable next) { if (next is not Internal.ScriptWordVariable swv) { throw new InvalidGrammarException($"Not expected a key word: {next}"); } if (swv.word == ";") { var importContext = new SymbolizationContext(context); importContext.Compile(ImportFile); return null; } else if (swv.word == ".") { ImportFile = ImportFile | buffer; buffer = ""; if (ImportFile.Exists() == false) throw new FileNotFoundException($"File path not found: {ImportFile}", ImportFile); } else { buffer += swv.word; } return this; } } /// /// name { ... } /// public sealed class Namespace : Internal.Keyword { public Namespace() : base("namespace") { } public override Internal.Keyword CloneVariable(string targetSymbolName) { return new Namespace(); } private enum Pause { Name, Body } private Pause pause = Pause.Name; private int layer = 0; private SymbolizationContext bulidingContext = null; private Dictionary> subScriptWords = new(); public override Internal.Keyword ControlContext(SymbolizationContext context,int line,int wordIndex, Internal.Variable next) { if (next is not Internal.ScriptWordVariable swv) { throw new InvalidGrammarException($"Not expected a key word: {next}"); } if (pause == Pause.Name) { bulidingContext = new(context, context.CurrentNamespace.CreateOrGetSubNamespace(swv.word)); bulidingContext.CurrentNamespace.BeginUpdate(); pause = Pause.Body; } else { if (swv.word == "{") layer++; else if (swv.word == "}") layer--; if (layer == 0) { bulidingContext.Compile(subScriptWords); bulidingContext.CurrentNamespace.EndAndTryApplyUpdate(); return null; } else { if (subScriptWords.TryGetValue(line, out var rline) == false) { subScriptWords.Add(line, rline = new()); } rline.Add(wordIndex, next); } } return this; } } /// /// FunctionName(parameter-list) return-type { ... return return-type-instance; } /// public sealed class FunctionDef : Internal.Keyword { public FunctionDef() : base("def") { } } /// /// symbol; /// public sealed class Return : Internal.Keyword { public Return() : base("return") { } } /// /// (bool-expression) expression /// public sealed class If : Internal.Keyword { public If() : base("if") { } } /// /// expression expression /// public sealed class Else : Internal.Keyword { public Else() : base("else") { } } /// /// (bool-expression) expression /// public sealed class While : Internal.Keyword { public While() : base("while") { } } /// /// ; /// public sealed class Break : Internal.Keyword { public Break() : base("break") { } } /// /// ; /// public sealed class Continue : Internal.Keyword { public Continue() : base("continue") { } } /// /// structureName { ... } /// public sealed class Structure : Internal.Keyword { public Structure() : base("struct") { } } }