protected override void DoExpand(MacroContext context) { if (context.Invocation.Arguments.Count == 0) { context.ReportMessage( Message.Error( string.Format(Resources.CallSubInterpret_OneArgument, Alias), context.Invocation.Position, MessageClasses.SubUsage)); return; } if (context.CurrentLoopBlock != null && !context.IsJustEffect) { context.ReportMessage( Message.Error( string.Format( Resources.CallSubInterpret_asExpressionInLoop, CallSub.Alias, Alias), context.Invocation.Position, MessageClasses.SubAsExpressionInLoop)); return; } //Store result of call var resultV = context.AllocateTemporaryVariable(); _storeResult(context, resultV); //Extract return variant as int into retVarV var retVarV = context.AllocateTemporaryVariable(); _extractReturnVariant(context, resultV, retVarV); Func<AstGetSet> retVar = () => context.CreateCall(EntityRef.Variable.Local.Create(retVarV)); //Extract return value into retValueV (which happens to be the same as resultV) var retValueV = resultV; _extractReturnValue(context, resultV, retValueV); // ReSharper disable ImplicitlyCapturedClosure // perfectly safe as neither lambda survives the method Func<AstGetSet> retValue = () => context.CreateCall(EntityRef.Variable.Local.Create(retValueV)); // ReSharper restore ImplicitlyCapturedClosure //Break and Continue behave differently outside loop blocks AstNode contStmt, breakStmt; _determineActions(context, retValue, out contStmt, out breakStmt); //Generate check for continue _genChecks(context, retVar, contStmt, breakStmt); context.Block.Expression = retValue(); context.FreeTemporaryVariable(retVarV); context.FreeTemporaryVariable(resultV); }
protected override bool DoExpandPartialApplication(MacroContext context) { if (context.Invocation.Arguments.Count < 1) { context.ReportMessage(Message.Error( string.Format(Resources.CallStar_usage, Id), context.Invocation.Position, MessageClasses.CallStarUsage)); return true; } int passThrough; List<AstExpr> arguments; _determinePassThrough(context, out passThrough, out arguments); _expandPartialApplication(context, passThrough, arguments); return true; }
protected override void DoExpand(MacroContext context) { if (context.Invocation.Arguments.Count < 1) { context.ReportMessage( Message.Error( string.Format(Resources.Pack_Usage_obj_missing, Alias), context.Invocation.Position, MessageClasses.PackUsage)); return; } context.EstablishMacroContext(); // [| context.StoreForTransport(boxed($arg0)) |] var getContext = context.CreateIndirectCall(context.CreateCall( EntityRef.Variable.Local.Create(MacroAliases.ContextAlias))); var boxedArg0 = context.CreateCall(EntityRef.Command.Create(Engine.BoxedAlias),PCall.Get, context.Invocation.Arguments[0]); context.Block.Expression = context.CreateGetSetMember(getContext, PCall.Get, "StoreForTransport", boxedArg0); }
protected override void DoExpand(MacroContext context) { if (context.Invocation.Arguments.Count < 1) { context.ReportMessage( Message.Error( string.Format( "{0} requires at least one argument, the id of the object to unpack.", Alias), context.Invocation.Position, MessageClasses.UnpackUsage)); return; } context.EstablishMacroContext(); // [| macro\unpack\impl(context, $arg0) |] var getContext = context.CreateIndirectCall(context.CreateCall(EntityRef.Variable.Local.Create(MacroAliases.ContextAlias))); context.Block.Expression = context.CreateCall(EntityRef.Command.Create(Impl.Alias), PCall.Get, getContext, context.Invocation.Arguments[0]); }
protected override void DoExpand(MacroContext context) { if (!context.CallerIsMacro()) { context.ReportMessage( Message.Error( string.Format(Resources.Reference_can_only_be_used_in_a_macro_context, Alias), context.Invocation.Position, MessageClasses.ReferenceUsage)); return; } if (context.Invocation.Arguments.Count == 0) { context.ReportMessage( Message.Error( string.Format(Resources.Reference_requires_at_least_one_argument, Alias), context.Invocation.Position, MessageClasses.ReferenceUsage)); return; } var prototype = context.Invocation.Arguments[0] as AstExpand; if (prototype == null) { context.ReportMessage( Message.Error( string.Format(Resources.Reference_requires_argument_to_be_a_prototype_of_a_macro_invocation, Alias), context.Invocation.Position, MessageClasses.ReferenceUsage)); } else { context.Block.Expression = _assembleImplCall(context, prototype.Entity.ToSymbolEntry(), prototype.Position); } }
private static void _determinePassThrough(MacroContext context, out int passThrough, out List<AstExpr> arguments) { var arg0 = context.Invocation.Arguments[0]; var passThroughNode = arg0 as AstConstant; if (passThroughNode != null && passThroughNode.Constant is int) { arguments = new List<AstExpr>(context.Invocation.Arguments.Skip(1)); passThrough = (int) passThroughNode.Constant; } else { arguments = new List<AstExpr>(context.Invocation.Arguments); passThrough = 1; } if (passThrough < 1) context.ReportMessage( Message.Error( string.Format(Resources.CallStar__invalid_PassThrough, passThrough), (ISourcePosition)passThroughNode ?? context.Invocation.Position, MessageClasses.CallStarPassThrough)); }
protected override void DoExpand(MacroContext context) { if (context.Invocation.Arguments.Count < 1) { context.ReportMessage( Message.Error( string.Format(Resources.CallStar_usage, Id), context.Invocation.Position, MessageClasses.CallStarUsage)); return; } int passThrough; List<AstExpr> arguments; _determinePassThrough(context, out passThrough, out arguments); if (arguments.Skip(passThrough).Any(_isPartialList)) { _expandPartialApplication(context, passThrough, arguments); return; } // "Fallback" direct invocation var ic = new AstIndirectCall(context.Invocation.File, context.Invocation.Line, context.Invocation.Column, context.Invocation.Call, arguments[0]); ic.Arguments.AddRange(arguments.Skip(1)); context.Block.Expression = ic; }
private static void _errorUsageFullRef(MacroContext context) { context.ReportMessage( Message.Error( Resources.CallMacro_errorUsageFullRef, context.Invocation.Position, MessageClasses.CallMacroUsage)); }
private static bool _parseReference(MacroContext context, AstExpr macroRef) { if (macroRef.IsPlaceholder()) { context.ReportMessage( Message.Error( Resources.CallMacro_notOnPlaceholder, context.Invocation.Position, MessageClasses.CallMacroNotOnPlaceholder)); return false; } return true; }
private static void _errorUsagePrototype(MacroContext context) { context.ReportMessage( Message.Error( string.Format(Resources.CallMacro_errorUsagePrototype, Alias), context.Invocation.Position, MessageClasses.CallMacroUsage)); }
private static bool _ensureExplicitPlaceholder(MacroContext context, AstExpr arg) { var setPlaceholder = arg as AstPlaceholder; if (setPlaceholder != null && !setPlaceholder.Index.HasValue) { context.ReportMessage( Message.Error( string.Format(Resources.CallMacro_SpecifyPlaceholderIndexExplicitly, Alias), setPlaceholder.Position, MessageClasses.SpecifyPlaceholderIndexExplicitly)); return false; } return true; }
/// <summary> /// Establishes macro context and parses arguments. /// </summary> /// <param name = "context">The macro context.</param> /// <returns>The call to call\macro\perform expression on success; null otherwise.</returns> private static AstGetSet _assembleCallPerform(MacroContext context) { if (context.Invocation.Arguments.Count == 0) { context.ReportMessage( Message.Error( Resources.CallMacro_call_macro_must_be_supplied_a_macro_reference, context.Invocation.Position, MessageClasses.MacroReferenceForCallMacroMissing)); return null; } if (!context.CallerIsMacro()) { context.ReportMessage( Message.Error( string.Format( Resources.CallMacro_CalledFromNonMacro, context.Function.LogicalId), context.Invocation.Position, MessageClasses.CallMacroCalledFromNonMacro)); return null; } context.EstablishMacroContext(); AstExpr call; AstExpr justEffect; AstExpr[] args; AstExpr macroSpec; if (!_parseArguments(context, out call, out justEffect, out args, out macroSpec)) return null; // [| call\macro\prepare_macro($macroEntityRef, context, $call, $justEffect, $args...) |] return _prepareMacro(context, macroSpec, call, justEffect, args); }