bool TrackToSpread(ref Callstack @Callstack, ref StringBuilder Queue, char Channel, MML Mml, int nMacro, int nNest) { var c = new Cursor(Mml.Text); bool Result = true; while (!c.IsTerm && Result) { if (c.IsMark('*', false) > 0) { c.Commit(); Callstack.Push(new Callstack.Record(Mml.Line, Mml.Base, c.Preview)); var nDecimal = c.IsDecimal(); if (nDecimal > 0) { c.Revert(); var MacroNumber = c.GetDecimal(); if (mMacro.ContainsKey(MacroNumber)) { var Macro = mMacro[MacroNumber]; if (nNest < NestDepth) { Queue.Append('{'); Queue.Append(String.Format($"{Mml.Line},{Mml.Base},{c.Preview},{Macro.Mml.Line},{Macro.Mml.Base},{MacroNumber},")); Result = TrackToSpread(ref Callstack, ref Queue, Channel, Macro.Mml, MacroNumber, nNest + 1); if (Result) { c.Commit(); Queue.Append('}'); Queue.Append(String.Format($"{c.Current},")); Callstack.Pop(); } } else { Console.WriteLine($"!! Error !! : Nesting too deep"); Callstack.Log(Mml.Line, Mml.Base + c.Preview, nMacro); Result = false; } } else { Console.WriteLine($"!! Error !! : Macro not defined"); Callstack.Log(Mml.Line, Mml.Base + c.Preview, nMacro); Result = false; } } else { Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack.Log(Mml.Line, Mml.Base + c.Preview, nMacro); Result = false; } } else { Queue.Append(c.Char); c.Offset(1); c.Commit(); } } return(Result); }
public bool SpreadToPacket(out List <Packet> aPacket, out CallstackLogger @CallstackLogger, Spread @Spread) { var c = new Cursor(Spread.Text); aPacket = new List <Packet>(); maPacket = aPacket; int oPacketScale = -1; int oPacketRepeatHead = -1; int oPacketRepeatBreak = -1; int oPacketRepeatTail = -1; CallstackLogger = new CallstackLogger(); mCallstackLogger = CallstackLogger; int oCallstackLogger = -1; var CallstackFrom = new Callstack(Spread.Channel); int Callstack_oPrev = 0; int Callstack_oText = 0; var CallMacro = new Stack <CallMacroProperty>(); int In_oLine = -1; int In_oBase = -1; int In_nMacro = -1; var aoStackRepeatHead = new Stack <int>(); var aoStackRepeatBreak = new Stack <int>(); bool Result = true; while (!c.IsTerm && Result && !mbAbort) { Callstack_oPrev = Callstack_oText; Callstack_oText += (c.Current - c.Preview); c.Commit(); eScale Scale = eScale.c; if (GetScale(ref Scale, c)) { c.SkipSpace(); Callstack_oPrev = Callstack_oText; Callstack_oText += (c.Current - c.Preview); c.Commit(); var oFullScale = (int)Scale; if (Packet.IsFullScale(oFullScale)) { int Clock = 0; if (c.GetClock(ref Clock, mSemibreve, mDefaultDuration)) { oPacketScale = AddPacketScale(((mbSilence)? (int)Packet.eCommand.r: oFullScale), Clock, Callstack_oPrev, oCallstackLogger); } else { Console.WriteLine($"!! Error !! : Illegal parameter"); Result = false; } } else { Console.WriteLine($"!! Error !! : Illegal scale"); Result = false; } } else { eFunction Function = eFunction.r; if (GetFunction(ref Function, c)) { c.SkipSpace(); Callstack_oPrev = Callstack_oText; Callstack_oText += (c.Current - c.Preview); c.Commit(); switch ((int)Function) { case (int)eFunction.r: { int Clock = 0; if (c.GetClock(ref Clock, mSemibreve, mDefaultDuration)) { AddPacketScale((int)Packet.eCommand.r, Clock, Callstack_oPrev, oCallstackLogger); oPacketScale = -1; break; } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.C: { int Value = 0; if (c.GetDecimal(ref Value, true)) { if (Value > 0) { mSemibreve = Value; break; } } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.t: { int Value = 0; if (c.GetDecimal(ref Value, true)) { if (Value >= 0x00 && Value <= 0xff) { maPacket.Add(new Packet(Packet.eCommand.t, Value, Callstack_oPrev, oCallstackLogger)); break; } } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.T: { int Value = 0; if (c.GetDecimal(ref Value, true)) { if (Value >= 1 && Value <= 255) { maPacket.Add(new Packet(Packet.eCommand.T, Value, Callstack_oPrev, oCallstackLogger)); break; } } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.v: { int Value = 0; if (c.GetDecimal(ref Value, true)) { if (Value >= 0 && Value <= 31) { maPacket.Add(new Packet(Packet.eCommand.v, Value, Callstack_oPrev, oCallstackLogger)); break; } } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.q: { int Value = 0; if (c.GetDecimal(ref Value, true)) { if (Value >= 0 && Value <= 255) { maPacket.Add(new Packet(Packet.eCommand.q, Value, Callstack_oPrev, oCallstackLogger)); break; } } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.pM: { maPacket.Add(new Packet(Packet.eCommand.pM, 0, Callstack_oPrev, oCallstackLogger)); break; } case (int)eFunction.pR: { maPacket.Add(new Packet(Packet.eCommand.pR, 0, Callstack_oPrev, oCallstackLogger)); break; } case (int)eFunction.pL: { maPacket.Add(new Packet(Packet.eCommand.pL, 0, Callstack_oPrev, oCallstackLogger)); break; } case (int)eFunction.pC: { maPacket.Add(new Packet(Packet.eCommand.pC, 0, Callstack_oPrev, oCallstackLogger)); break; } case (int)eFunction.l: { int Clock = 0; if (c.GetClock(ref Clock, mSemibreve, mDefaultDuration)) { if (Clock > 0) { mDefaultDuration = Clock; break; } } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.vUp: { int Value = 1; c.GetDecimal(ref Value, true); if (Value >= 1 && Value <= 31) { maPacket.Add(new Packet(Packet.eCommand.vUp, Value, Callstack_oPrev, oCallstackLogger)); break; } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.vDown: { int Value = 1; c.GetDecimal(ref Value, true); if (Value >= 1 && Value <= 31) { maPacket.Add(new Packet(Packet.eCommand.vDown, Value, Callstack_oPrev, oCallstackLogger)); break; } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.Slur: { if (oPacketScale >= 0 && maPacket[oPacketScale].IsScale && !maPacket[oPacketScale].IsSlur) { if (mbSilence) { break; } if (maPacket[oPacketScale].AddSlur()) { break; } } Console.WriteLine($"!! Error !! : Syntax error"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.Tie: { if (oPacketScale >= 0 && maPacket[oPacketScale].IsScale && !maPacket[oPacketScale].IsSlur) { var Command = maPacket[oPacketScale].Command; if (maPacket[oPacketScale].AddSlur()) { int Clock = 0; if (c.GetClock(ref Clock, mSemibreve, mDefaultDuration)) { oPacketScale = AddPacketScale(((mbSilence)? (int)Packet.eCommand.r: Command), Clock, Callstack_oPrev, oCallstackLogger); break; } } } Console.WriteLine($"!! Error !! : Syntax error"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.RepeatHead: { aoStackRepeatHead.Push(oPacketRepeatHead); oPacketRepeatHead = maPacket.Count; oPacketRepeatBreak = -1; oPacketRepeatTail = -1; break; } case (int)eFunction.RepeatTail: { if (aoStackRepeatHead.Count > 0 && oPacketRepeatHead >= 0) { int Value = 0; if (c.GetDecimal(ref Value, true)) { if (Value >= 2) { oPacketRepeatTail = maPacket.Count; for (int Repeat = Value - 1; Repeat > 0; --Repeat) { for (int oPacket = oPacketRepeatHead; oPacket < oPacketRepeatTail; ++oPacket) { if (oPacketRepeatBreak >= 0 && oPacketRepeatBreak == oPacket && Repeat == 1) { break; } maPacket.Add(new Packet(maPacket[oPacket].CommandEnum, maPacket[oPacket].Value, maPacket[oPacket].Column, maPacket[oPacket].Logger)); } } oPacketRepeatHead = aoStackRepeatHead.Pop(); oPacketRepeatBreak = (oPacketRepeatBreak >= 0)? aoStackRepeatBreak.Pop(): oPacketRepeatBreak; oPacketRepeatTail = -1; break; } } Console.WriteLine($"!! Error !! : Illegal parameter"); } else { Console.WriteLine($"!! Error !! : Syntax error"); } Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.RepeatBreak: { if (aoStackRepeatHead.Count > 0 && oPacketRepeatHead >= 0) { aoStackRepeatBreak.Push(oPacketRepeatBreak); oPacketRepeatBreak = maPacket.Count; break; } Console.WriteLine($"!! Error !! : Syntax error"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.L: { maPacket.Add(new Packet(Packet.eCommand.L, 0, Callstack_oPrev, oCallstackLogger)); break; } case (int)eFunction.V: { int Value = 0; if (c.GetDecimal(ref Value, true)) { maPacket.Add(new Packet(Packet.eCommand.V, Value, Callstack_oPrev, oCallstackLogger)); break; } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.R: { int Value = 0; if (c.GetDecimal(ref Value, true)) { maPacket.Add(new Packet(Packet.eCommand.R, Value, Callstack_oPrev, oCallstackLogger)); break; } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.RF: { int Value = 0; if (c.GetDecimal(ref Value, true)) { if (Value >= 0 && Value <= 1) { maPacket.Add(new Packet(Packet.eCommand.RF, Value, Callstack_oPrev, oCallstackLogger)); break; } } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.Rm: { int Value = 0; if (c.GetDecimal(ref Value, true)) { if (Value >= 0 && Value <= 1) { maPacket.Add(new Packet(Packet.eCommand.Rm, Value, Callstack_oPrev, oCallstackLogger)); break; } } Console.WriteLine($"!! Error !! : Illegal parameter"); Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.yRTL: { int Value = 0; if (c.IsMark(',', true) > 0) { if (c.GetValue(ref Value, true)) { if (Value >= 0 && Value <= 63) { maPacket.Add(new Packet(Packet.eCommand.yRTL, Value, Callstack_oPrev, oCallstackLogger)); break; } } Console.WriteLine($"!! Error !! : Illegal parameter"); } else { Console.WriteLine($"!! Error !! : Syntax error"); } Callstack_oText = Callstack_oPrev; Result = false; break; } case (int)eFunction.Abort: { mbAbort = true; break; } case (int)eFunction.Silence: { mbSilence = true; break; } case (int)eFunction.J: { maPacket.Add(new Packet(Packet.eCommand.J, 0, Callstack_oPrev, oCallstackLogger)); break; } case (int)eFunction.NOP: { break; } case (int)eFunction.CallstackPush: { int From_oLine = 0; int From_oBase = 0; int From_oText = 0; if (c.GetDecimal(ref From_oLine, false)) { if (c.GetDecimal(ref From_oBase, false)) { if (c.GetDecimal(ref From_oText, false)) { CallMacro.Push(new CallMacroProperty(In_oLine, In_nMacro)); if (c.GetDecimal(ref In_oLine, false)) { if (c.GetDecimal(ref In_oBase, false)) { if (c.GetDecimal(ref In_nMacro, true, false)) { CallstackFrom.Push(new Callstack.Record(From_oLine, From_oBase, From_oText)); oCallstackLogger = mCallstackLogger.Add(CallstackFrom, In_oLine, In_nMacro); if (c.IsMark(',', false) > 0) { c.Commit(); Callstack_oText = In_oBase; break; } } } } } } } Console.WriteLine($"!! Error !! : Fatal error"); Result = false; break; } case (int)eFunction.CallstackPop: { var Record = CallstackFrom.Pop(); int From_oBase = Record.Base; int From_oText = 0; var In = CallMacro.Pop(); In_oLine = In.Key; In_nMacro = In.Value; oCallstackLogger = mCallstackLogger.Add(CallstackFrom, In_oLine, In_nMacro); if (CallstackFrom.Count == 0 && CallMacro.Count == 0) { break; } if (c.GetDecimal(ref From_oText, true, false)) { if (c.IsMark(',', false) > 0) { c.Commit(); Callstack_oText = From_oBase + From_oText; break; } } Console.WriteLine($"!! Error !! : Fatal error"); Result = false; break; } } } else { Console.WriteLine($"!! Error !! : Unknown function \'{Spread.Text[c.Current]}\'"); Result = false; } } } if (Result && aoStackRepeatHead.Count > 0 && aoStackRepeatBreak.Count > 0) { Console.WriteLine($"!! Error !! : Repeat not closed"); Result = false; } if (!Result) { CallstackFrom.Log(In_oLine, Callstack_oText, In_nMacro); } return(Result); }