Esempio n. 1
0
        public FuncTagBlueprint(VM interpreter, RantPattern source, Stringe name, IEnumerable <Token <R> >[] argData = null)
            : base(interpreter)
        {
            Source = source;
            Name   = name.Trim();

            RantFuncSigs defs;

            if (!RantFuncs.F.TryGetValue(Name.Value, out defs))
            {
                throw new RantException(Source, Name, "A function of the name '" + Name.Value + "' does not exist.");
            }

            if ((_tagDef = defs.GetSignature((argData == null ? 0 : argData.Length))) == null)
            {
                throw new RantException(Source, Name, "The function '" + Name.Value + "' has no signature that accepts " + (argData == null ? 0 : argData.Length) + " argument(s).");
            }

            if (argData == null)
            {
                _args = new Argument[0];
            }
            else
            {
                var lastType = _tagDef.Parameters.Last();

                // Insert token arguments into the array, set string args to null.
                _args = argData.Select((a, i) =>
                                       (i >= _tagDef.ParamCount
                    ? (lastType & ParamFlags.Code) == ParamFlags.Code // Covers multi params
                    : (_tagDef.Parameters[i] & ParamFlags.Code) == ParamFlags.Code)
                        ? Argument.FromTokens(a)
                        : null).ToArray();

                // Queue string arguments on the stack.
                for (int i = 0; i < argData.Length; i++)
                {
                    if ((i >= _tagDef.ParamCount && (lastType & ParamFlags.Code) != ParamFlags.Code) ||
                        (_tagDef.Parameters[i] & ParamFlags.Code) != ParamFlags.Code)
                    {
                        interpreter.PushState(VM.State.CreateSub(source, argData[i], interpreter));
                    }
                }
            }
        }
Esempio n. 2
0
        static RantFuncs()
        {
            F = new Dictionary <string, RantFuncSigs>(StringComparer.InvariantCultureIgnoreCase);

            // Repeaters, probability, and block attributes
            F["rep"]      = F["r"] = new RantFunc(Repeat, ParamFlags.None);
            F["sep"]      = F["s"] = new RantFunc(Separator, ParamFlags.Code);
            F["before"]   = new RantFunc(Before, ParamFlags.Code);
            F["after"]    = new RantFunc(After, ParamFlags.Code);
            F["chance"]   = new RantFunc(Chance, ParamFlags.None);
            F["break"]    = new RantFunc(Break);
            F["repnum"]   = F["rn"] = new RantFunc(RepNum);
            F["repindex"] = F["ri"] = new RantFunc(RepIndex);
            F["repcount"] = F["rc"] = new RantFunc(RepCount);

            // Synchronizers
            F["sync"] = F["x"] = new RantFuncSigs(
                new RantFunc(SyncCreateApply, ParamFlags.None, ParamFlags.None),
                new RantFunc(SyncApply, ParamFlags.None)
                );
            F["xreset"] = new RantFunc(SyncReset, ParamFlags.None);
            F["xseed"]  = new RantFunc(SyncReseed, ParamFlags.None, ParamFlags.None);
            F["xnone"]  = new RantFunc(Desync);
            F["xnew"]   = new RantFunc(SyncCreate, ParamFlags.None, ParamFlags.None);
            F["xpin"]   = new RantFunc(Pin, ParamFlags.None);
            F["xunpin"] = new RantFunc(Unpin, ParamFlags.None);
            F["xstep"]  = new RantFunc(Step, ParamFlags.None);

            // RNG manipulation
            F["branch"] = F["b"] = new RantFuncSigs(
                new RantFunc(Branch, ParamFlags.None),
                new RantFunc(BranchScope, ParamFlags.None, ParamFlags.Code)
                );
            F["merge"]      = F["m"] = new RantFunc(Merge);
            F["generation"] = F["g"] = new RantFuncSigs(new RantFunc(Generation), new RantFunc(GenerationSet, ParamFlags.None));

            // Repeater conditionals
            F["first"]     = new RantFunc(First, ParamFlags.Code);
            F["last"]      = new RantFunc(Last, ParamFlags.Code);
            F["middle"]    = new RantFunc(Middle, ParamFlags.Code);
            F["notfirst"]  = new RantFunc(NotFirst, ParamFlags.Code);
            F["notlast"]   = new RantFunc(NotLast, ParamFlags.Code);
            F["notmiddle"] = new RantFunc(NotMiddle, ParamFlags.Code);
            F["odd"]       = new RantFunc(Odd, ParamFlags.Code);
            F["even"]      = new RantFunc(Even, ParamFlags.Code);
            F["nth"]       = new RantFuncSigs(
                new RantFunc(Nth, ParamFlags.None, ParamFlags.None, ParamFlags.Code),
                new RantFunc(NthSimple, ParamFlags.None, ParamFlags.Code)
                );

            // Quantifier conditionals
            F["alt"] = new RantFunc(Alt, ParamFlags.Code, ParamFlags.Code);
            F["any"] = new RantFunc(Any, ParamFlags.Code, ParamFlags.Code);

            // Replacers
            F["match"] = new RantFunc(ReplaceMatch);
            F["group"] = new RantFunc(ReplaceGroup, ParamFlags.None);

            // Subrotuine interaction
            F["arg"] = new RantFunc(Arg, ParamFlags.None);

            // Formatting
            F["numfmt"] = new RantFuncSigs(
                new RantFunc(NumFmt, ParamFlags.None),
                new RantFunc(NumFmtScope, ParamFlags.None, ParamFlags.Code));
            F["digits"] = new RantFuncSigs(
                new RantFunc(Digits, ParamFlags.None),
                new RantFunc(DigitsScope, ParamFlags.None, ParamFlags.Code));
            F["endian"] = new RantFunc(Endian, ParamFlags.None);
            F["caps"]   = F["case"] = new RantFuncSigs(
                new RantFunc(Case, ParamFlags.None),
                new RantFunc(CaseScope, ParamFlags.None, ParamFlags.Code));
            F["capsinfer"] = new RantFunc(CapsInfer, ParamFlags.None);
            F["quot"]      = F["q"] = new RantFunc(Quote, ParamFlags.Code);

            // Channels
            F["out"]   = new RantFunc(Out, ParamFlags.None, ParamFlags.None);
            F["close"] = new RantFunc(Close, ParamFlags.None);

            // External interaction
            F["extern"] = F["ext"] = new RantFunc(Extern, ParamFlags.None, ParamFlags.Multi);

            // Markers and targets
            F["mark"]  = new RantFunc(Mark, ParamFlags.None);
            F["dist"]  = new RantFunc(Dist, ParamFlags.None, ParamFlags.None);
            F["get"]   = new RantFunc(Get, ParamFlags.None);
            F["send"]  = new RantFunc(Send, ParamFlags.None, ParamFlags.None);
            F["osend"] = new RantFunc(SendOverwrite, ParamFlags.None, ParamFlags.None);
            F["clrt"]  = new RantFunc(ClearTarget, ParamFlags.None);
            F["copy"]  = new RantFunc(Copy, ParamFlags.None, ParamFlags.None);

            // String generation, manipulation, and analysis
            F["len"]  = new RantFunc(Length, ParamFlags.None);
            F["char"] = new RantFuncSigs(
                new RantFunc(Character, ParamFlags.None),
                new RantFunc(CharacterMulti, ParamFlags.None, ParamFlags.None));
            F["num"] = F["n"] = new RantFunc(Number, ParamFlags.None, ParamFlags.None);
            F["dec"] = new RantFunc(NumberDec);

            // Flags
            F["define"] = new RantFunc(DefineFlag, ParamFlags.None | ParamFlags.Multi);
            F["undef"]  = new RantFunc(UndefineFlag, ParamFlags.None | ParamFlags.Multi);
            F["ifdef"]  = new RantFunc(IfDef, ParamFlags.None, ParamFlags.Code);
            F["ifndef"] = new RantFunc(IfNDef, ParamFlags.None, ParamFlags.Code);
            F["else"]   = new RantFunc(Else, ParamFlags.Code);

            // Comparisons
            F["cmp"] = new RantFunc(Compare, ParamFlags.None, ParamFlags.None, ParamFlags.Code);
            F["is"]  = new RantFunc(CmpIs, ParamFlags.None, ParamFlags.Code);

            // Misc
            F["src"]       = new RantFunc(Src);
            F["rhymemode"] = new RantFunc(RhymeMode, ParamFlags.None);
        }