예제 #1
0
        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);
        }
예제 #2
0
파일: CallStar.cs 프로젝트: SealedSun/prx
        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;
        }
예제 #3
0
파일: Pack.cs 프로젝트: SealedSun/prx
        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);
        }
예제 #4
0
파일: Unpack.cs 프로젝트: SealedSun/prx
        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]);
        }
예제 #5
0
파일: Reference.cs 프로젝트: SealedSun/prx
        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);
            }
        }
예제 #6
0
파일: CallStar.cs 프로젝트: SealedSun/prx
        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));
        }
예제 #7
0
파일: CallStar.cs 프로젝트: SealedSun/prx
        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;
        }
예제 #8
0
파일: CallMacro.cs 프로젝트: SealedSun/prx
 private static void _errorUsageFullRef(MacroContext context)
 {
     context.ReportMessage(
         Message.Error(
             Resources.CallMacro_errorUsageFullRef, context.Invocation.Position,
             MessageClasses.CallMacroUsage));
 }
예제 #9
0
파일: CallMacro.cs 프로젝트: SealedSun/prx
        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;
        }
예제 #10
0
파일: CallMacro.cs 프로젝트: SealedSun/prx
 private static void _errorUsagePrototype(MacroContext context)
 {
     context.ReportMessage(
         Message.Error(
             string.Format(Resources.CallMacro_errorUsagePrototype, Alias), context.Invocation.Position,
             MessageClasses.CallMacroUsage));
 }
예제 #11
0
파일: CallMacro.cs 프로젝트: SealedSun/prx
 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;
 }
예제 #12
0
파일: CallMacro.cs 프로젝트: SealedSun/prx
        /// <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);
        }