protected TALCommand Compile_METAL_FILL_SLOT(string argument) { if (argument.Length == 0) { // No argument passed string msg = "No argument passed! fill-slot commands must be of the form: 'fill-slot: name'"; throw new TemplateParseException(this.currentStartTag, msg); } // Check that the name of the slot is valid if (Constants.METAL_NAME_REGEX.Match(argument).Length != argument.Length) { string msg = string.Format("Slot name {0} is invalid.", argument); throw new TemplateParseException(this.currentStartTag, msg); } // Determine what use-macro statement this belongs to by working through the list backwards int? ourMacroLocation = null; int location = this.tagStack.Count - 1; while (ourMacroLocation == null) { int macroLocation = this.tagStack[location].UseMacroLocation; if (macroLocation != -1) { ourMacroLocation = macroLocation; } else { location -= 1; if (location < 0) { string msg = string.Format("metal:fill-slot must be used inside a metal:use-macro call"); throw new TemplateParseException(this.currentStartTag, msg); } } } // Get the use-macro command we are going to adjust TALCommand cmnd = this.commandList[(int)ourMacroLocation]; string macroName = (string)cmnd.Attributes[0]; Dictionary<string, TALSubProgram> slotMap = (Dictionary<string, TALSubProgram>)cmnd.Attributes[1]; List<DefineInfo> paramMap = (List<DefineInfo>)cmnd.Attributes[2]; int endSymbol = (int)cmnd.Attributes[3]; if (slotMap.ContainsKey(argument)) { string msg = string.Format("Slot {0} has already been filled!", argument); throw new TemplateParseException(this.currentStartTag, msg); } // The slot starts at the next command. TALSubProgram slot = new TALSubProgram(this.commandList.Count, this.endTagSymbol); slotMap.Add(argument, slot); // Update the command TALCommand ci = new TALCommand(); ci.Tag = cmnd.Tag; ci.ID = cmnd.ID; ci.Attributes = new List<object>(); ci.Attributes.Add(macroName); ci.Attributes.Add(slotMap); ci.Attributes.Add(paramMap); ci.Attributes.Add(endSymbol); this.commandList[(int)ourMacroLocation] = ci; return null; }
// METAL compilation commands go here protected TALCommand Compile_METAL_DEFINE_MACRO(string argument) { if (argument.Length == 0) { // No argument passed string msg = "No argument passed! define-macro commands must be of the form: 'define-macro: name'"; throw new TemplateParseException(this.currentStartTag, msg); } // Check that the name of the macro is valid if (Constants.METAL_NAME_REGEX.Match(argument).Length != argument.Length) { string msg = string.Format("Macro name {0} is invalid.", argument); throw new TemplateParseException(this.currentStartTag, msg); } if (this.macroMap.ContainsKey(argument)) { string msg = string.Format("Macro name {0} is already defined!", argument); throw new TemplateParseException(this.currentStartTag, msg); } // The macro starts at the next command. TALSubProgram macro = new TALSubProgram(this.commandList.Count, this.endTagSymbol); this.macroMap.Add(argument, macro); return null; }