/// <summary> /// Perform a full reset on the block. /// </summary> void FullReset() { _breakBlock = null; _processedLines.Clear(); _currBlock = _rootBlock; _rootBlock.ResetEntries(); }
/// <summary> /// Add an entry to the block. /// </summary> /// <param name="line">The <see cref="T:DotNetAsm.SourceLine"/> of the entry</param> /// <param name="block">The <see cref="T:DotNetAsm.ForNextHandler.ForNextBlock"/> of the entry</param> public void AddEntry(SourceLine line, ForNextBlock block) { if (block != null) { block.Parent = this; } _entries.AddLast(new ForNextEntry(line, block)); }
/// <summary> /// Constructs a <see cref="T:DotNetAsm.RepetitionHandler.RepetitionBlock.RepetitionEntry"/>. /// </summary> /// <param name="line">The <see cref="T:DotNetAsm.SourceLine"/> to add. This value can /// be null.</param> /// <param name="block">The <see cref="T:DotNetAsm.RepetitionHandler.RepetitionBlock"/> /// to link to. This value can be null.</param> public ForNextEntry(SourceLine line, ForNextBlock block) { if (line != null) { Line = line.Clone() as SourceLine; } else { Line = null; } LinkedBlock = block; }
/// <summary> /// Constructs an instance of the <see cref="T:DotNetAsm.ForNextHandler"/>. /// </summary> public ForNextHandler() { Reserved.DefineType("Directives", ".for", ".next", ".break", "@@ for @@", "@@ next @@", "@@ break @@" ); _currBlock = _rootBlock = new ForNextBlock(); _breakBlock = null; _levels = 0; _processedLines = new List <SourceLine>(); }
public void Process(SourceLine line) { var instruction = line.Instruction.ToLower(); if (instruction.Equals(".for")) { if (string.IsNullOrEmpty(line.Operand)) { Controller.Log.LogEntry(line, ErrorStrings.TooFewArguments, line.Instruction); return; } if (string.IsNullOrEmpty(line.Label) == false) { // capture the label _processedLines.Add(new SourceLine { Label = line.Label, SourceString = line.Label, LineNumber = line.LineNumber, Filename = line.Filename }); } // .for <init_expression>, <condition>, <iteration_expression> var csvs = line.Operand.CommaSeparate(); if (csvs.Count < 2) { Controller.Log.LogEntry(line, ErrorStrings.TooFewArguments, line.Instruction); return; } if (_levels > 0) { var block = new ForNextBlock(); _currBlock.AddEntry(null, block); _currBlock = block; } else { _currBlock = _rootBlock; } _levels++; _currBlock.Scope = line.Scope; _currBlock.InitExpression = csvs.First(); _currBlock.Condition = csvs[1]; if (_currBlock == _rootBlock) { if (!string.IsNullOrEmpty(_currBlock.InitExpression)) { var iteratorvar = Controller.Symbols.Variables.SetVariable(_currBlock.InitExpression, _currBlock.Scope); if (string.IsNullOrEmpty(iteratorvar.Key)) { Controller.Log.LogEntry(line, ErrorStrings.BadExpression, csvs.First()); return; } _processedLines.Add(new SourceLine { SourceString = ConstStrings.SHADOW_SOURCE, Instruction = ConstStrings.VAR_DIRECTIVE, Operand = string.Format("{0}={1}", iteratorvar.Key, iteratorvar.Value) }); } } _currBlock.AddEntry(new SourceLine { SourceString = ConstStrings.SHADOW_SOURCE, Instruction = "@@ for @@" }, null); if (csvs.Count >= 3) { _currBlock.IterExpressions.Clear(); _currBlock.IterExpressions.AddRange(csvs.GetRange(2, csvs.Count - 2)); } } else if (instruction.Equals(".next")) { if (_levels == 0) { Controller.Log.LogEntry(line, ErrorStrings.ClosureDoesNotCloseBlock, line.Instruction); return; } if (string.IsNullOrEmpty(line.Operand) == false) { Controller.Log.LogEntry(line, ErrorStrings.TooManyArguments, line.Instruction); return; } if (string.IsNullOrEmpty(line.Label) == false) { Controller.Log.LogEntry(line, ErrorStrings.None); return; } var loopLine = new SourceLine { SourceString = ConstStrings.SHADOW_SOURCE, Instruction = "@@ next @@" }; _currBlock.AddEntry(loopLine, null); _currBlock.Begin(); _levels--; _currBlock = _currBlock.Parent; if (_levels == 0) { _currBlock = _rootBlock; _processedLines.AddRange(_rootBlock.GetProcessedLines()); } } else if (instruction.Equals(".break")) { if (_levels == 0) { Controller.Log.LogEntry(line, "Illegal use of .break"); return; } string procinst = "@@ break @@"; var shadow = new SourceLine { SourceString = ConstStrings.SHADOW_SOURCE, Instruction = procinst }; _currBlock.AddEntry(shadow, null); } else if (instruction.Equals("@@ for @@")) { if (_currBlock.IsBeginning()) { if (_currBlock == _rootBlock) { _currBlock.Begin(); } _currBlock.Advance(); } else { var child = _currBlock.NextChild(); _currBlock.Advance(); _currBlock = child; _currBlock.Begin(); _currBlock.Advance(); if (_breakBlock == null && !string.IsNullOrEmpty(_currBlock.InitExpression)) { var initval = Controller.Symbols.Variables.SetVariable(_currBlock.InitExpression, _currBlock.Scope); _processedLines.Add(new SourceLine { SourceString = ConstStrings.SHADOW_SOURCE, Instruction = ConstStrings.VAR_DIRECTIVE, Operand = string.Format("{0}={1}", initval.Key, initval.Value) }); } } } else if (instruction.Equals("@@ next @@")) { if (_breakBlock != null) { if (_currBlock == _breakBlock) { _breakBlock = null; } _currBlock = _currBlock.Parent; if (_currBlock == null) { FullReset(); } return; } // update each var in the expressions during runtime as well as // in output source (i.e., emit .let n = ... epxressions) foreach (var iterexp in _currBlock.IterExpressions) { var itervar = Controller.Symbols.Variables.SetVariable(iterexp, _currBlock.Scope); _processedLines.Add(new SourceLine { SourceString = ConstStrings.SHADOW_SOURCE, Instruction = ConstStrings.VAR_DIRECTIVE, Operand = string.Format("{0}={1}", itervar.Key, itervar.Value) }); } _currBlock.Begin(); if (Controller.Evaluator.EvalCondition(_currBlock.Condition)) { _processedLines.AddRange(_currBlock.GetProcessedLines()); } else { _breakBlock = null; _currBlock = _currBlock.Parent; if (_currBlock == null) { FullReset(); } } } else if (instruction.Equals("@@ break @@")) { if (_breakBlock == null) { _breakBlock = _currBlock; } } else if (_breakBlock == null) { _currBlock.AddEntry(line, null); } }