public Object SubArgumentsAndSymbols(Object original, Sequence macro, SequenceMacroReference macroReference, String expansionSymbol) //Substitute paramater references with arguments, prepend expansion symbol to internal symbol references { if (!(original is String)) { return(original); //No operation required if original is a literal value } String value = original as String; SymbolSelector sel = SymbolSelector.TryParse(value); if (sel != null) { value = sel.Symbol; Object newValue = (macro.Parameters.Contains(value)) ? macroReference.Arguments[macro.Parameters.IndexOf(value)] : (macro.Symbols.ContainsKey(value)) ? expansionSymbol + "." + value : value; return(newValue.ToString() + $"[{sel.Selector.ToString()}]"); } else { return((macro.Parameters.Contains(value)) ? macroReference.Arguments[macro.Parameters.IndexOf(value)] : (macro.Symbols.ContainsKey(value)) ? expansionSymbol + "." + value : value); } }
public void ResolveSymbols(Microprogram microprogram, List <Sequence> placedSequences) //Resolve all symbol references to numeric values { foreach (Sequence sequence in placedSequences) { foreach (SequenceStep step in sequence.Steps) { if (step is SequenceMacroReference) { throw new MicroassemblerLinkException($"Encountered unexpanded macro on line {step.Line}"); } if (step is SequenceAssertion) { SequenceAssertion assertion = step as SequenceAssertion; foreach (ControlWordLabel key in assertion.AssertedSignals.Keys.ToList()) { Object value = assertion.AssertedSignals[key]; if (!(value is long)) { String symbol = value.ToString(); SymbolSelector sel = SymbolSelector.TryParse(symbol); if (sel != null) { if (long.TryParse(sel.Symbol, out long intValue)) { assertion.AssertedSignals[key] = (intValue & sel.Selector.ToLongMask()) >> sel.Selector.LowerBound; } else { symbol = sel.Symbol; Object resolvedSymbol = (sequence[symbol] != null) ? sequence[symbol] : microprogram[symbol]; if (resolvedSymbol == null) { throw new MicroassemblerLinkException($"Symbol {symbol} referenced by assertion on line {assertion.Line} is not defined"); } if (resolvedSymbol is ISymbolResolver) { resolvedSymbol = (resolvedSymbol as ISymbolResolver).Resolve(); } if (!(resolvedSymbol is long)) { throw new MicroassemblerLinkException($"Symbol {symbol} resolved to {resolvedSymbol}, all symbols should resolve to a number"); } assertion.AssertedSignals[key] = ((long)resolvedSymbol & sel.Selector.ToLongMask()) >> sel.Selector.LowerBound; } } else { Object resolvedSymbol = (sequence[symbol] != null) ? sequence[symbol] : microprogram[symbol]; if (resolvedSymbol == null) { throw new MicroassemblerLinkException($"Symbol {symbol} referenced by assertion on line {assertion.Line} is not defined"); } if (resolvedSymbol is ISymbolResolver) { resolvedSymbol = (resolvedSymbol as ISymbolResolver).Resolve(); } if (!(resolvedSymbol is long)) { throw new MicroassemblerLinkException($"Symbol {symbol} resolved to {resolvedSymbol}, all symbols should resolve to a number"); } assertion.AssertedSignals[key] = resolvedSymbol; } } } } } } //Resolve empty step SequenceAssertion emptyAssertion = microprogram.EmptyAssertion; if (microprogram.EmptyAssertion == null) { throw new MicroassemblerLinkException("The empty/default sequence step is not defined"); } foreach (ControlWordLabel key in emptyAssertion.AssertedSignals.Keys.ToList()) { Object value = emptyAssertion.AssertedSignals[key]; if (!(value is long)) { String symbol = value.ToString(); Object resolvedSymbol = microprogram[symbol]; if (resolvedSymbol == null) { throw new MicroassemblerLinkException($"Symbol {symbol} referenced by assertion on line {emptyAssertion.Line} is not defined"); } if (resolvedSymbol is ISymbolResolver) { resolvedSymbol = (resolvedSymbol as ISymbolResolver).Resolve(); } emptyAssertion.AssertedSignals[key] = resolvedSymbol; } } }