internal static MacroMode GetMacroMode(ref LNodeList attrs, LNode pattern) { MacroMode modes = 0; attrs = attrs.SmartWhere(attr => { if (attr.IsId && Enum.TryParse(attr.Name.Name, out MacroMode mode)) { modes |= mode; return(false); } return(true); }); if (pattern.IsLiteral) { modes |= MacroMode.MatchEveryLiteral; } else if (pattern.IsId) { modes |= MacroMode.MatchIdentifierOnly; } else if (DecodeSubstitutionExpr(pattern, out _, out _, out _) != null) { modes |= MacroMode.MatchEveryCall | MacroMode.MatchEveryIdentifier | MacroMode.MatchEveryLiteral; } else if (!pattern.Target.IsId) { modes |= MacroMode.MatchEveryCall; // custom matching code needed } return(modes); }
public static void Start() { //Invoker SpaceShipsCommandConsole spaceShipsCommandConsole = new SpaceShipsCommandConsole(); //Receivers PowerShieldSystem powerShieldSystem = new PowerShieldSystem(); WeaponSystem weaponSystem = new WeaponSystem(); //Requests ICommand aimEnemy = new AimEnemy(weaponSystem); ICommand attack = new Attack(weaponSystem); ICommand reloadWeapons = new ReloadWeapons(weaponSystem); ICommand openPowerShield = new OpenPowerShield(powerShieldSystem); ICommand closePowerShield = new ClosePowerShield(powerShieldSystem); ICommand decreasePowerShield = new DecreasePowerShieldLevel(powerShieldSystem); ICommand increasePowerShield = new IncreasePowerShieldLevel(powerShieldSystem); ICommand setHalfPowerOfPowerShieldLevel = new SetHalfPowerOfPowerShieldLevel(powerShieldSystem); ICommand macro = new MacroMode(new List <ICommand> { aimEnemy, attack, openPowerShield, increasePowerShield }); //Set Commands to Slots spaceShipsCommandConsole.SetCommand(0, setHalfPowerOfPowerShieldLevel); spaceShipsCommandConsole.SetCommand(1, aimEnemy); spaceShipsCommandConsole.SetCommand(2, attack); spaceShipsCommandConsole.SetCommand(3, reloadWeapons); spaceShipsCommandConsole.SetCommand(4, openPowerShield); spaceShipsCommandConsole.SetCommand(5, closePowerShield); spaceShipsCommandConsole.SetCommand(7, increasePowerShield); spaceShipsCommandConsole.SetCommand(8, decreasePowerShield); spaceShipsCommandConsole.SetCommand(9, macro); //Try spaceShipsCommandConsole.PushButton(1); spaceShipsCommandConsole.PushButton(2); spaceShipsCommandConsole.PushButton(0); spaceShipsCommandConsole.Undo(); spaceShipsCommandConsole.PushButton(3); spaceShipsCommandConsole.Undo(); spaceShipsCommandConsole.PushButton(4); spaceShipsCommandConsole.Undo(); spaceShipsCommandConsole.PushButton(5); spaceShipsCommandConsole.PushButton(6); spaceShipsCommandConsole.Undo(); spaceShipsCommandConsole.PushButton(0); spaceShipsCommandConsole.Undo(); spaceShipsCommandConsole.PushButton(7); spaceShipsCommandConsole.PushButton(7); spaceShipsCommandConsole.PushButton(7); spaceShipsCommandConsole.PushButton(7); spaceShipsCommandConsole.Undo(); spaceShipsCommandConsole.PushButton(8); spaceShipsCommandConsole.PushButton(0); spaceShipsCommandConsole.Undo(); spaceShipsCommandConsole.PushButton(8); spaceShipsCommandConsole.PushButton(9); spaceShipsCommandConsole.Undo(); }
public MacroInfo(Symbol @namespace, Symbol name, SimpleMacro macro, MacroMode mode) { Namespace = @namespace; Name = name; Macro = macro; Mode = mode; if ((Mode & MacroMode.PriorityMask) == 0) { Mode |= MacroMode.NormalPriority; } }
private static LNode RegisterSimpleMacro(LNodeList attrs, LNode pattern, LNode body, IMacroContext context) { if (DecodeSubstitutionExpr(pattern, out _, out _, out _) != null) { return(Reject(context, pattern, "Defining a macro that could match everything is not allowed.")); } MacroMode modes = GetMacroMode(ref attrs, pattern); LNode macroName = pattern.Target ?? pattern; LNode replacement = body.AsList(S.Braces).AsLNode(S.Splice); if (pattern.IsCall) { WarnAboutMissingDollarSigns(pattern.Args, context, pattern, replacement); } // Note: we could fill out the macro's Syntax and Description with the // pattern and replacement converted to strings, but it's generally a // waste of CPU time as those strings are usually not requested. // Compromise: provide syntax pattern only var syntax = pattern.ToString(); var lma = new LexicalMacroAttribute(syntax, "User-defined macro at {0}".Localized(pattern.Range.Start), macroName.Name.Name) { Mode = modes }; if ((modes & (MacroMode.MatchEveryLiteral | MacroMode.MatchEveryCall | MacroMode.MatchEveryIdentifier)) != 0) { lma = new LexicalMacroAttribute(syntax, lma.Description) { Mode = modes } } ; var macroInfo = new MacroInfo(null, lma, UserDefinedMacro); macroInfo.Mode |= MacroMode.UseLogicalNameInErrorMessages; context.RegisterMacro(macroInfo); return(F.Splice()); // delete the `define` node from the output LNode UserDefinedMacro(LNode candidate, IMacroContext context2) { MMap <Symbol, LNode> captures = new MMap <Symbol, LNode>(); if (candidate.MatchesPattern(pattern, ref captures, out LNodeList unmatchedAttrs)) { LNode replacement2 = WithUniqueIdentifiers(replacement, context.IncrementTempCounter, out _); return(ReplaceCaptures(replacement2, captures).PlusAttrsBefore(unmatchedAttrs)); } return(null); } }
public static LNode replaceFn(LNode node, IMacroContext context1) { var retType = node.Args[0, LNode.Missing].Name; if (retType != _replace && retType != _define) { return(null); } LNode replaceKw, macroName, args, body; if (EcsValidators.MethodDefinitionKind(node, out replaceKw, out macroName, out args, out body, allowDelegate: false) != S.Fn || body == null) { return(null); } MacroMode mode, modes = 0; var leftoverAttrs = node.Attrs.SmartWhere(attr => { if (attr.IsId && Loyc.Compatibility.EnumStatic.TryParse(attr.Name.Name, out mode)) { modes |= mode; return(false); } return(true); }); LNode pattern = F.Call(macroName, args.Args).PlusAttrs(leftoverAttrs); LNode replacement = body.AsList(S.Braces).AsLNode(S.Splice).PlusAttrs(replaceKw.Attrs); replacement.Style &= ~NodeStyle.OneLiner; WarnAboutMissingDollarSigns(args, context1, pattern, replacement); // Note: we could fill out the macro's Syntax and Description with the // pattern and replacement converted to strings, but it's generally a // waste of CPU time as those strings are usually not requested. var lma = new LexicalMacroAttribute( string.Concat(macroName.Name, "(", args.Args.Count.ToString(), " args)"), "", macroName.Name.Name); var macroInfo = new MacroInfo(null, lma, (candidate, context2) => { MMap <Symbol, LNode> captures = new MMap <Symbol, LNode>(); VList <LNode> unmatchedAttrs; if (candidate.MatchesPattern(pattern, ref captures, out unmatchedAttrs)) { return(ReplaceCaptures(replacement, captures).PlusAttrsBefore(unmatchedAttrs)); } return(null); }) { Mode = modes }; context1.RegisterMacro(macroInfo); return(F.Splice()); }
private CommandOutput CancelMacro(Context context) { if (CurrentMode != MacroMode.Recording) { return(new CommandOutput($"cannot cancel as no macro recording", false)); } CurrentMacro = null; CurrentMode = MacroMode.Sleeping; return(new CommandOutput($"Cancelled.", true)); }
private CommandOutput SaveMacro(Context context) { if (CurrentMode != MacroMode.Recording) { return(new CommandOutput($"cannot save as no macro recording", false)); } CurrentMacro.Save(); CurrentMacro = null; CurrentMode = MacroMode.Sleeping; return(new CommandOutput($"Saved.", true)); }
private CommandOutput RecordMacro(string macroName) { if (CurrentMode != MacroMode.Sleeping) { return(new CommandOutput($"cannot start recording as currently in mode '{CurrentMode}'", false)); } CurrentMacro = new Macro { Name = macroName, RecordedOn = DateTime.Now, Steps = new List <Macro.MacroStep>() }; CurrentMode = MacroMode.Recording; return(new CommandOutput($"Starting recording for macro {CurrentMacro.Name}", true)); }
private CommandOutput RunMacro(string macroName, Context context) { if (CurrentMode == MacroMode.Recording) { return(new CommandOutput($"cannot run a macro if recording", false)); } var macro = Macro.Load(macroName); if (macro == null) { return(new CommandOutput($"macro with name {macroName} not found", false)); } CurrentMode = MacroMode.Running; var output = new StringBuilder(); output.AppendLine($"----- Macro '{macro.Name}' -----"); try { macro.Steps.ForEach(step => { var cmd = _cmdManager.KnownCommands.FirstOrDefault(kc => kc.CommandName == step.CommandName); if (cmd == null) { throw new Exception($"Command '{step.CommandName}' is unknown.Macro terminated."); } var result = _cmdManager.ExecuteCommand(cmd, step.CommandArgs.ToList()); output.AppendLine(result?.ToString()); // TODO: clean this up, not pretty if (!result.IsSuccessful) { throw new Exception($"Errors while running"); } }); } catch (Exception ex) { return(new CommandOutput($"Macro execution encountered issues", ex, false)); } finally { CurrentMode = MacroMode.Sleeping; } output.AppendLine("-------------------------------"); return(new CommandOutput(output.ToString(), true)); }
public override void Handle(GameSession session, PacketReader packet) { MacroMode mode = (MacroMode)packet.ReadByte(); switch (mode) { case MacroMode.OpenSettings: HandleOpenSettings(session); break; case MacroMode.CloseSettings: HandleCloseSettings(session, packet); break; default: LogUnknownMode(mode); break; } }
public static LNode CompileMacro(LNode pattern, LNode body, IMacroContext context, LNodeList attrs) { var modeNodes = attrs.Where(a => Enum.TryParse(a.Name.Name, out MacroMode _)); // unwrap braces (they're not part of the pattern, they just enable statement syntax in EC#) var pattern_apos = pattern.UnwrapBraces(); MacroMode modes = GetMacroMode(ref attrs, pattern_apos); // compileTime {...} can recognize macro method definitions. // Take advantage of this by generating a macro method which it will register for us. LNode macroName = pattern_apos.Target ?? pattern_apos; LNode syntax = F.Literal(pattern_apos.ToString()); LNode description = attrs.FirstOrDefault(a => a.Value is string) ?? F.Literal("User-defined macro at {0}".Localized(pattern.Range.Start)); attrs = attrs.SmartWhere(a => !(a.Value is string)); // remove docstring, if any var extraArgs = LNode.List(); if (macroName.IsId) { extraArgs.Add(F.Literal(macroName.Name.Name)); } else { Debug.Assert((modes & (MacroMode.MatchEveryCall | MacroMode.MatchEveryIdentifier | MacroMode.MatchEveryLiteral)) != 0); } // ensure operator macros like `'+` are not printed as `operator+` which C# will reject if (EcsValidators.IsOperator(macroName.Name)) { macroName = F.Id(EcsValidators.SanitizeIdentifier(macroName.Name.Name)); } LNode modesExpr = null; foreach (LNode mode in modeNodes) { modesExpr = LNode.MergeBinary(modesExpr, LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.ColonColon, LNode.List(LNode.Id((Symbol)"global"), LNode.Id((Symbol)"LeMP"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"MacroMode"))).SetStyle(NodeStyle.Operator), mode)).SetStyle(NodeStyle.Operator), S.OrBits); } if (modesExpr != null) { extraArgs.Add(LNode.Call(CodeSymbols.Assign, LNode.List(LNode.Id((Symbol)"Mode"), modesExpr)).SetStyle(NodeStyle.Operator)); } LNode lmAttribute = LNode.Call(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.ColonColon, LNode.List(LNode.Id((Symbol)"global"), LNode.Id((Symbol)"LeMP"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"LexicalMacroAttribute"))).SetStyle(NodeStyle.Operator), LNode.List().Add(syntax).Add(description).AddRange(extraArgs)); if (!body.Calls(S.Braces)) { body = LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(body)))).SetStyle(NodeStyle.StatementBlock); } body = context.PreProcess(body); // Look for "using" statements above the macro() call LNodeList usingDirectives = LNode.List(context.PreviousSiblings.Where(n => n.Calls(S.Import))); // Look for "using" and "#r" statements at the beginning of the body if (body.Calls(S.Braces)) { var bodyUsings = body.Args.TakeNowWhile(stmt => stmt.Calls(S.Import) || stmt.Calls(S.CsiReference)); usingDirectives.AddRange(bodyUsings); body = body.WithArgs(body.Args.Slice(bodyUsings.Count)); } // Create a matchCode statement unless the pattern is MacroName($(.._)), which always matches if (!(pattern_apos.HasSimpleHeadWithoutPAttrs() && pattern_apos.Target.IsId && pattern_apos.ArgCount == 1 && pattern_apos[0].Equals(LNode.Call(CodeSymbols.Substitute, LNode.List(LNode.Call(CodeSymbols.DotDot, LNode.List(LNode.Id((Symbol)"_"))).SetStyle(NodeStyle.Operator))).SetStyle(NodeStyle.Operator)))) { // Note: the body is already preprocessed; #noLexicalMacros prevents double-processing body = LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call((Symbol)"matchCode", LNode.List(LNode.Id((Symbol)"#node"), LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Case, LNode.List(pattern)), LNode.Call((Symbol)"#noLexicalMacros", LNode.List(body.AsList(S.Braces))))).SetStyle(NodeStyle.StatementBlock))).SetStyle(NodeStyle.Special), LNode.Call(CodeSymbols.Return, LNode.List(LNode.Literal(null))))).SetStyle(NodeStyle.StatementBlock); } return(LNode.Call((Symbol)"compileTime", LNode.List(LNode.Call(CodeSymbols.Braces, LNode.List().AddRange(usingDirectives).Add(LNode.Call(LNode.List().Add(lmAttribute).AddRange(attrs).Add(LNode.Id(CodeSymbols.Public)).Add(LNode.Id(CodeSymbols.Static)), CodeSymbols.Fn, LNode.List(LNode.Id((Symbol)"LNode"), macroName, LNode.Call(CodeSymbols.AltList, LNode.List(LNode.Call(CodeSymbols.Var, LNode.List(LNode.Id((Symbol)"LNode"), LNode.Id((Symbol)"#node"))), LNode.Call(CodeSymbols.Var, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Call(CodeSymbols.ColonColon, LNode.List(LNode.Id((Symbol)"global"), LNode.Id((Symbol)"LeMP"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"IMacroContext"))).SetStyle(NodeStyle.Operator), LNode.Id((Symbol)"#context"))))), body)))).SetStyle(NodeStyle.StatementBlock))).SetStyle(NodeStyle.Special)); }