예제 #1
0
        //    Accepts pattersn:
        //    , @method @prose ,
        //    , @method ,
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            PatternMatcher match = successfulMatch;

            //	Extract the "arguments" from the PatternMatcher.
            List<PNode> M = match.Matching;			//	The pattern -> prose index from the match

            MethodNameWord methodWord = (MethodNameWord) M[1].value;
            List<ProseObject> args;
            ProseObject terminalPunctuation;
            //	Depending on whether or not our method has arguments.
            if (successfulMatch.NumObjectsMatched > 3) {
                args = successfulMatch.getArgumentAsProseAtIndex(2);
                terminalPunctuation = M[3].value;
            }
            else {
                args = new List<ProseObject>();
                terminalPunctuation = M[2].value;
            }

            ProseAction action = new MethodDelegateAction(methodWord, args);

            value = new ProseObject[3];
            value[0] = M[0].value;
            value[1] = action;
            value[2] = terminalPunctuation;

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);
            value = null;
            return ret;
        }
예제 #2
0
        //    Expects the pattern:
        //
        //    , word[parent] : word[child] ,
        //
        //    Replaces a "parent : child" expression with an action that effects the
        //    word creation/inheritance assertion.
        //override
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            //	Extract the "arguments" from the PatternMatcher.
            List<PNode> M = successfulMatch.Matching;		//	The pattern -> prose index from the match
            ProseObject parentObject = M[1].value;
            ProseObject childObject = M[3].value;

            //	The childObject must be either a word or raw-word.  Either way we just use the raw word
            //	data because it will result in looking up the correct word in the end anyway.
            RawWord[] childObjectRawWords;
            if (childObject is RawWordObject) {
                childObjectRawWords = ((RawWordObject) childObject).RawWords;
            }
            else if (childObject is Word) {
                childObjectRawWords = ((Word) childObject).RawWords;
            }
            else {
                throw new RuntimeFailure("WordBindingPhrase passed something other than a word or raw word to bind.");
            }

            //	Create an action that has the desired effect
            WordBindingAction action = new WordBindingAction(childObjectRawWords, (Word) parentObject);

            //	Wrap the action in whatever punctuation was present and write the list of objects
            //	we want to substitute into our "value" field.
            value = new ProseObject[3];
            value[0] = M[0].value;		//	Initial punctuation
            value[1] = action;			//	Word binding action
            value[2] = M[4].value;		//	Terminal punctuation

            //	Call the super-class to do the substitution.
            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);
            value = null;
            return ret;
        }
예제 #3
0
        //
        //    Meant to match:
        //
        //    @break
        //
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            PatternMatcher match = successfulMatch;

            //	Extract the "arguments" from the PatternMatcher.
            List<PNode> M = match.Matching;			//	The pattern -> prose index from the match

            value = new ProseObject[1];
            //value[0] = new BreakPointObject("");
            value[0] = new BreakPointObject("# Breakpoint script - \n");

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);
            value = null;
            return ret;
        }
예제 #4
0
파일: ReadPhrase.cs 프로젝트: FizzyP/Prose
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            PatternMatcher match = successfulMatch;

            //	Extract the "arguments" from the PatternMatcher.
            List<PNode> M = match.Matching;			//	The pattern -> prose index from the match
            string sourceString = ((StringLiteralObject) M[2].value).literal;
            ProseAction action = new ReadAction(sourceString);

            value = new ProseObject[3];
            value[0] = M[0].value;
            value[1] = action;
            value[2] = M[3].value;

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);
            value = null;
            return ret;
        }
예제 #5
0
        //    Expects pattern:	contents of text file @string[file_name]
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            //	Extract the "arguments" from the PatternMatcher.
            List<PNode> M = successfulMatch.Matching;		//	The pattern -> prose index from the match
            string fileName = ((StringLiteralObject) M[4].value).literal;

            string source = System.IO.File.ReadAllText(fileName);

            //	Wrap the action in whatever punctuation was present and write the list of objects
            //	we want to substitute into our "value" field.
            value = new ProseObject[1];
            value[0] = new StringLiteralObject(source);
            //	Call the super-class to do the substitution.

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);
            value = null;
            return ret;
        }
예제 #6
0
        //	Clone the pattern matcher and reconfigure it in a new state based on a word.
        private PatternMatcher makeCopyWithStateFromAtWord(ProseObject atWord)
        {
            PatternMatcher newMatcher = new PatternMatcher(runtime);

            newMatcher.patternComponentNodes.AddRange(patternComponentNodes);
            newMatcher.numObjectsMatched = numObjectsMatched;

            if (currPatternObject != null)
            {
                newMatcher.currPatternObject = currPatternObject.clone();
            }


            if (atWord == runtime.@prose)
            {
                newMatcher.switchToState_MATCHING_PROSE();
                if (parentheticalStack != null)
                {
                    //newMatcher.parentheticalStack = new Stack<ProseObject>(parentheticalStack);
                    newMatcher.parentheticalStack = new Stack <ProseObject>();
                    ProseObject[] objs = parentheticalStack.ToArray();
                    for (int i = objs.Length - 1; i >= 0; i--)
                    {
                        newMatcher.parentheticalStack.Push(objs[i]);
                    }
                }
                newMatcher.inText = inText;
            }
            else if (atWord == runtime.@text)
            {
                newMatcher.switchToState_MATCHING_TEXT();
                newMatcher.textMatchingQQcount = textMatchingQQcount;
            }
            else if (atWord == runtime.@pattern)
            {
                newMatcher.switchToState_MATCHING_PATTERN();
            }
            else
            {
                newMatcher.switchToState_MATCHING_OBJECT();
            }

            return(newMatcher);
        }
예제 #7
0
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            PatternMatcher match = successfulMatch;

            //	Extract the "arguments" from the PatternMatcher.
            List<PNode> M = match.Matching;			//	The pattern -> prose index from the match
            string dllFileName = ((StringLiteralObject) M[4].value).literal;
            ProseObject newAssemblyWord = M[6].value;
            LoadAssemblyAction action = new LoadAssemblyAction(dllFileName, newAssemblyWord);

            value = new ProseObject[3];
            value[0] = M[0].value;
            value[1] = action;
            value[2] = M[7].value;

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);
            value = null;
            return ret;
        }
예제 #8
0
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            PatternMatcher match = successfulMatch;

            //	Extract the "arguments" from the PatternMatcher.
            List <PNode> M            = match.Matching;                 //	The pattern -> prose index from the match
            string       sourceString = ((StringLiteralObject)M[2].value).literal;
            ProseAction  action       = new ReadAction(sourceString);

            value    = new ProseObject[3];
            value[0] = M[0].value;
            value[1] = action;
            value[2] = M[3].value;

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);

            value = null;
            return(ret);
        }
        //	Expects pattern:	contents of text file @string[file_name]
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            //	Extract the "arguments" from the PatternMatcher.
            List <PNode> M        = successfulMatch.Matching;                   //	The pattern -> prose index from the match
            string       fileName = ((StringLiteralObject)M[4].value).literal;

            string source = System.IO.File.ReadAllText(fileName);

            //	Wrap the action in whatever punctuation was present and write the list of objects
            //	we want to substitute into our "value" field.
            value    = new ProseObject[1];
            value[0] = new StringLiteralObject(source);
            //	Call the super-class to do the substitution.

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);

            value = null;
            return(ret);
        }
예제 #10
0
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            PatternMatcher match = successfulMatch;

            //	Extract the "arguments" from the PatternMatcher.
            List <PNode>       M               = match.Matching;        //	The pattern -> prose index from the match
            string             dllFileName     = ((StringLiteralObject)M[4].value).literal;
            ProseObject        newAssemblyWord = M[6].value;
            LoadAssemblyAction action          = new LoadAssemblyAction(dllFileName, newAssemblyWord);

            value    = new ProseObject[3];
            value[0] = M[0].value;
            value[1] = action;
            value[2] = M[7].value;

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);

            value = null;
            return(ret);
        }
예제 #11
0
        //    Expects pattern:    , -> @prose -> ,
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            //	Extract the "arguments" from the PatternMatcher.
            List<PNode> M = successfulMatch.Matching;		//	The pattern -> prose index from the match
            //	Create an action that has the desired effect
            DebugOutputAction action = new DebugOutputAction("dbg", message);

            //	Wrap the action in whatever punctuation was present and write the list of objects
            //	we want to substitute into our "value" field.
            value = new ProseObject[5];
            value[0] = M[0].value;		//	Initial punctuation
            value[1] = action;			//	Word binding action
            value[2] = M[4].value;		//	Terminal punctuation
            value[3] = action;			//	Word binding action
            value[4] = M[4].value;		//	Terminal punctuation
            //	Call the super-class to do the substitution.

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);
            value = null;
            return ret;
        }
예제 #12
0
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            PatternMatcher match = successfulMatch;

            //	Extract the "arguments" from the PatternMatcher.
            List<PNode> M = match.Matching;			//	The pattern -> prose index from the match
            TypeNameWord typeNameWord = ((TypeNameWord) M[1].value);
            string methodName = ((StringLiteralObject) M[4].value).literal;
            RawWord[] newMethodWord;
            if (M[6].value is RawWordObject)	newMethodWord = ((RawWordObject) M[6].value).RawWords;
            else newMethodWord = ((Word) M[6].value).RawWords;
            BindMethodAction action = new BindMethodAction(typeNameWord, methodName, newMethodWord);

            value = new ProseObject[3];
            value[0] = M[0].value;
            value[1] = action;
            value[2] = M[7].value;

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);
            value = null;
            return ret;
        }
예제 #13
0
        //	Expects the pattern:
        //
        //	, word[parent] : word[child] ,
        //
        //	Replaces a "parent : child" expression with an action that effects the
        //	word creation/inheritance assertion.
        //override
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            //	Extract the "arguments" from the PatternMatcher.
            List <PNode> M            = successfulMatch.Matching;               //	The pattern -> prose index from the match
            ProseObject  parentObject = M[1].value;
            ProseObject  childObject  = M[3].value;

            //	The childObject must be either a word or raw-word.  Either way we just use the raw word
            //	data because it will result in looking up the correct word in the end anyway.
            RawWord[] childObjectRawWords;
            if (childObject is RawWordObject)
            {
                childObjectRawWords = ((RawWordObject)childObject).RawWords;
            }
            else if (childObject is Word)
            {
                childObjectRawWords = ((Word)childObject).RawWords;
            }
            else
            {
                throw new RuntimeFailure("WordBindingPhrase passed something other than a word or raw word to bind.");
            }

            //	Create an action that has the desired effect
            WordBindingAction action = new WordBindingAction(childObjectRawWords, (Word)parentObject);

            //	Wrap the action in whatever punctuation was present and write the list of objects
            //	we want to substitute into our "value" field.
            value    = new ProseObject[3];
            value[0] = M[0].value;                      //	Initial punctuation
            value[1] = action;                          //	Word binding action
            value[2] = M[4].value;                      //	Terminal punctuation

            //	Call the super-class to do the substitution.
            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);

            value = null;
            return(ret);
        }
예제 #14
0
        //	Compare matches against each other and throw out matchers which are "dominated"
        //	according to the inheritence system.
        private List <PatternMatcher> getStrongestMatchesUsingInheritence(List <PatternMatcher> matches)
        {
            List <PatternMatcher> betterMatches = new List <PatternMatcher>();
            int idx = 0;

            do
            {
                PatternMatcher m = matches[idx];
                betterMatches = filterMatchesUsingInheritenceAgainstOneMatcher(matches, m);

                //	If we didn't manage to shorten the list then we got back the exact same list.
                //	So, we have to look at the next spot in that list.
                if (betterMatches.Count == matches.Count)
                {
                    idx++;
                }

                matches = betterMatches;
            }while (matches.Count > 1 && matches.Count > idx);

            return(matches);
        }
예제 #15
0
        //	Expects pattern:    , -> @prose -> ,
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            //	Extract the "arguments" from the PatternMatcher.
            List <PNode> M = successfulMatch.Matching;                          //	The pattern -> prose index from the match
            //	Create an action that has the desired effect
            DebugOutputAction action = new DebugOutputAction("dbg", message);

            //	Wrap the action in whatever punctuation was present and write the list of objects
            //	we want to substitute into our "value" field.
            value    = new ProseObject[5];
            value[0] = M[0].value;                      //	Initial punctuation
            value[1] = action;                          //	Word binding action
            value[2] = M[4].value;                      //	Terminal punctuation
            value[3] = action;                          //	Word binding action
            value[4] = M[4].value;                      //	Terminal punctuation
            //	Call the super-class to do the substitution.

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);

            value = null;
            return(ret);
        }
예제 #16
0
        //    Clone the pattern matcher and reconfigure it in a new state based on a word.
        private PatternMatcher makeCopyWithStateFromAtWord(ProseObject atWord)
        {
            PatternMatcher newMatcher = new PatternMatcher(runtime);
            newMatcher.patternComponentNodes.AddRange(patternComponentNodes);
            newMatcher.numObjectsMatched = numObjectsMatched;

            if (currPatternObject != null)
                newMatcher.currPatternObject = currPatternObject.clone();

            if (atWord == runtime.@prose) {
                newMatcher.switchToState_MATCHING_PROSE();
                if (parentheticalStack != null) {
                    //newMatcher.parentheticalStack = new Stack<ProseObject>(parentheticalStack);
                    newMatcher.parentheticalStack = new Stack<ProseObject>();
                    ProseObject[] objs = parentheticalStack.ToArray();
                    for (int i=objs.Length - 1; i >= 0; i--)
                        newMatcher.parentheticalStack.Push(objs[i]);

                }
                newMatcher.inText = inText;
            }
            else if (atWord == runtime.@text) {
                newMatcher.switchToState_MATCHING_TEXT();
                newMatcher.textMatchingQQcount = textMatchingQQcount;
            }
            else if (atWord == runtime.@pattern) {
                newMatcher.switchToState_MATCHING_PATTERN();
            }
            else {
                newMatcher.switchToState_MATCHING_OBJECT();
            }

            return newMatcher;
        }
예제 #17
0
 public PatternMatcherException(string msg, PatternMatcher matcher) : base(msg)
 {
     patternMatcher = matcher;
 }
예제 #18
0
파일: REPL.cs 프로젝트: FizzyP/Prose
        public static void onMatcherFailure(ProseRuntime runtime, PatternMatcher match)
        {
            restoreConsoleColor();
            StringBuilder str = new StringBuilder();
            ProseObject[] partialPattern = match.AssociatedPattern;
            foreach(ProseObject po in partialPattern) {
                str.Append(po.getReadableString());
                str.Append(" ");
            }
            if (str.Length != 0)
                str.Remove(str.Length-1, 1);

            Console.WriteLine("match fail>     " + str.ToString());
        }
예제 #19
0
파일: REPL.cs 프로젝트: FizzyP/Prose
 public static void onMatch(ProseRuntime runtime, PatternMatcher match)
 {
     restoreConsoleColor();
     foreach (Phrase phrase in match.MatchedPhrases)
         Console.WriteLine("match>          " + phrase.getReadableString());
 }
예제 #20
0
        private List<PatternMatcher> getSuccessfulMatchesStartingAtPNode(PNode source)
        {
            PatternMatcher seedMatcher = new PatternMatcher(this);
            List<PatternMatcher> activeMatchers = new List<PatternMatcher>(64);
            activeMatchers.Add(seedMatcher);
            List<PatternMatcher> successfullMatches = new List<PatternMatcher>();

            //	Start out looking at the first node in the source.
            PNode sourceNode = source;

            //	As long as there are still active matchers...
            while(activeMatchers.Count != 0 && sourceNode != null)
            {
                sourceNode = debugFilterIncomingPNode(sourceNode);
                if (sourceNode == null)
                    break;

                //	If we run into left parenthesis, reduce and eliminate before continuing.
                while (sourceNode.value == LeftParenthesis)
                {
                    PNode leftParen = sourceNode;
                    //	Reduce the parenthetical
                    bool didReduce;
                    sourceNode = reduceParentheticalExpression(sourceNode, out didReduce, LeftParenthesis, RightParenthesis);
                    //	Some matchers may have retained a reference to the leftParen, so swap it for whatever is there now.
                    foreach (PatternMatcher matcher in activeMatchers) {
                        if (matcher.terminatorNode == leftParen)
                            matcher.terminatorNode = sourceNode;
                    }

                    //	Refilter the source node
                    sourceNode = debugFilterIncomingPNode(sourceNode);
                    if (sourceNode == null)
                        break;
                }

                //	Try to extend all of the active matchers.
                List<PatternMatcher> babyMatchers = new List<PatternMatcher>(256);
                foreach(PatternMatcher matcher in activeMatchers)
                {
                    //	Try to extend the given matcher and get all the resulting babies.
                    List<PatternMatcher> thisMatchersBabies = matcher.matchNextPNode(sourceNode);

                    int failCount = 0;	//	Count the baby matchers that arrive dead.
                    foreach (PatternMatcher babyMatcher in thisMatchersBabies) {
                        //	if the matcher has found a match, remember it.
                        if (babyMatcher.IsMatched)
                        {
                            //	Callback for successful match
                            if (OnMatch != null)
                                OnMatch(this, babyMatcher);

                            successfullMatches.Add(babyMatcher);
                            babyMatchers.Add(babyMatcher);
                            //							//	Rest the matcher so it can be can be continued
            //							babyMatcher.IsMatched = false;
                        }
                        else if (babyMatcher.IsntFailed)
                        {
                        //	Regardless, throw it back in the pot to see if it can be extended
                        //if (babyMatcher.IsntFailed)
                            babyMatchers.Add(babyMatcher);
                        }
                        else {
                            //	This baby matcher was stillborn
                            failCount++;
                        }
                    }

                    //	If the matcher produced no good children then that branch is "dead"
                    //	Only count it as a "fail" if it isn't a success itself.
                    if (	thisMatchersBabies.Count - failCount == 0
                        &&	!matcher.IsMatched)
                    {
                        if (OnMatcherFailure != null)
                            OnMatcherFailure(this, matcher);
                    }

                }

                //	After one generation, the baby matchers become the new active matchers.
                activeMatchers = babyMatchers;
                //	And now we're looking at the next object in the sequence
                sourceNode = sourceNode.next;
            }

            return successfullMatches;
        }
예제 #21
0
        bool firstMatcherDominatesSecond(PatternMatcher a, PatternMatcher b)
        {
            //	Compare their class word first

            //	Compare the associated patterns.

            //	Extract the patterns from a, b.
            ProseObject[] pa = a.AssociatedPattern;
            ProseObject[] pb = b.AssociatedPattern;

            for (int i=0; i < pa.Length; i++) {

                //	Most often they'll be the same and then
                if (pa[i] == pb[i])
                    continue;

                //	@prose is weaker than everything else
                if (pa[i] == @prose && pb[i] != @prose)
                    return false;
                else if (pa[i] != @prose && pb[i] == @prose)
                    continue;

                else if (pa[i] == @raw && pb[i] is Word)
                    return false;
                else if (pa[i] is Word && pb[i] == @raw)
                    continue;

                Word aword = (Word) pa[i];
                List<ProseObject> descendents = aword.getAllDescendents(this);
                //	If there even one piece of b's pattern doesn't descend from a's
                //	then a doesn't dominate.
                if (!descendents.Contains(pb[i]))
                    return false;
            }

            return true;
        }
예제 #22
0
        //    Evaluate a list of prose objects into a new list of prose objects.
        public PNode replaceWithValueAt(PNode evaluateMe, PatternMatcher match)
        {
            //	If the phrase only serves to delete the pattern...
            if (value.Length == 0)
            {
            //				PNode firstNodeAfterPattern = evaluateMe.forwardSeek(match.NumObjectsMatched);
                PNode firstNodeAfterPattern = match.terminatorNode;
                if (evaluateMe.prev != null)
                    evaluateMe.prev.next = firstNodeAfterPattern;
                firstNodeAfterPattern.prev = evaluateMe.prev;
                return firstNodeAfterPattern;
            }

            //	Make a node to write and hook it up the previous part of the list.
            PNode prevWriteHead = evaluateMe.prev;
            PNode firstNodeInNewList = new PNode();
            PNode writeHead = firstNodeInNewList;
            prevWriteHead.next = writeHead;

            foreach (ProseObject obj in value)
            {

                //	Write a value into it
                //	Argrefs get special treatment.
                if (obj is ArgRefObject)
                {
                    //	Look up the appropriate argument in "evaluate me" and substitute it.
                    int idx = ((ArgRefObject) obj).reffedArgIndex;
                    //ProseObject evaluated = evaluateMe.forwardSeek(index).value;

                    PNode subStart, subEnd;
                    subStart = match.getArgumentBounds(idx, out subEnd);

                    //TODO	This needs to support @prose, @text, and @string.
                    //writeHead.value = evaluated;
                    PNode readHead = subStart;
                    //writeHead.initWithPNode(subStart);
                    while (readHead != subEnd) {
                        //	Hook p into the output
                        if (prevWriteHead != null) {

                            prevWriteHead.next = writeHead;
                        }
                        writeHead.prev = prevWriteHead;
                        writeHead.initWithPNode(readHead);

                        //	Update
                        prevWriteHead = writeHead;
                        readHead = readHead.next;
                        //	Get a new node for the next cycle
                        writeHead = new PNode();
                    }

                }
                else {
                    //	Hook this node into the list
                    writeHead.prev = prevWriteHead;
                    if (prevWriteHead != null)
                        prevWriteHead.next = writeHead;

                    writeHead.value = obj;

                    //	Grab a new node
                    prevWriteHead = writeHead;
                    writeHead = new PNode();
                }
            }

            //	When we're done, tie the end of the output list back into the input list.
            //	Note: prevWriteHead is actually the last PNode we wrote.
            if (prevWriteHead != null) {
                prevWriteHead.next = match.terminatorNode;
                //prevWriteHead.next = evaluateMe.forwardSeek(match.NumObjectsMatched);
                if (match.terminatorNode != null)
                    match.terminatorNode.prev = prevWriteHead;
            }

            return firstNodeInNewList;
        }
예제 #23
0
        //    Returns 1 if a > b, -1 if a < b, 0 otherwise
        int compareMatchers(PatternMatcher a, PatternMatcher b)
        {
            //	These matches represent exactly the same thing.
            if (a.PhraseTrieNode == b.PhraseTrieNode) {
                return 0;
            }

            if (firstMatcherDominatesSecond(a,b)) {
                if (firstMatcherDominatesSecond(b, a))
                    return 0;
                else
                    return 1;
            }
            else {
                if (firstMatcherDominatesSecond(b,a))
                    return -1;
                else
                    return 0;
            }
        }
예제 #24
0
        List <PatternMatcher> while_MATCHING_PROSE_matchNextObject(PNode node)
        {
            ProseObject obj = node.value;

            //	Return this list of spawned matchers.
            List <PatternMatcher> babyMatchers = new List <PatternMatcher>();

            //	Possibly we can make this prose block longer (in addition to other options where we may leave it)
            bool canExtendThisProseBlock = false;
            //	If we want extend our prose block by adding a right parenthetical, remember to pop the left off the stack.
            bool shouldPopParentheticalStack = false;
            //	If we stay in this prose block, record if we are entering text or leaving text
            bool shouldToggleInText = false;
            //	Should we exit to a different mode?
            bool         shouldLeaveMatchingProse = false;
            MatcherState switchToThisState;


            //	Check for parentheticals
            //	No need to check for () because it's eliminated before we're ever called.
            if (obj == runtime.LeftCurlyBracket)
            {
                canExtendThisProseBlock = true;
                //	Do this in extend
                //parentheticalStack.Push(runtime.LeftCurlyBracket);
            }
            else if (obj == runtime.LeftSquareBracket)
            {
                canExtendThisProseBlock = true;
                //	Do this in extend
                //parentheticalStack.Push(runtime.LeftSquareBracket);
            }
            else if (obj == runtime.RightCurlyBracket)
            {
                ProseObject matchingParenthetical = tryPeekParenthetical();
                if (matchingParenthetical == null || matchingParenthetical != runtime.LeftCurlyBracket)
                {
                    throw new PatternMatcherException("Right curly bracket wihtout matching left curly bracket inside @prose block.", this);
                }
                //	At this point, we agree the curly bracket makes sense, so we pop it's counterpart off the stack.
                shouldPopParentheticalStack = true;
                canExtendThisProseBlock     = true;
            }
            else if (obj == runtime.RightSquareBracket)
            {
                ProseObject matchingParenthetical = tryPeekParenthetical();
                if (matchingParenthetical == null || matchingParenthetical != runtime.LeftSquareBracket)
                {
                    throw new PatternMatcherException("Right square bracket without matching left square bracket inside @prose block.", this);
                }
                //	At this point, we agree the square bracket makes sense, so we pop it's counterpart off the stack.
                shouldPopParentheticalStack = true;
                canExtendThisProseBlock     = true;
            }
            else if (obj == runtime.Quadquote)
            {
                //	In this case, we count that we are in a text block, but we don't "read it as text".  Instead, we just
                //	bundle the symbols in with our prose object and pass it along to be interpreted later.
                if (inText)
                {
                    ProseObject matchingParenthetical = tryPeekParenthetical();
                    if (matchingParenthetical == null || matchingParenthetical != runtime.Quadquote)
                    {
                        //	The "" didn't match up with a previous one!
                        throw new PatternMatcherException("Quadquote entagled with other parenthetical.", this);
                    }
                    else
                    {
                        canExtendThisProseBlock     = true;
                        shouldToggleInText          = true;                                     //	inText = false;
                        shouldPopParentheticalStack = true;                                     //	Pop off the left ""
                    }
                }
                else
                {
                    //	In this case, we treat this as an opening quadquote.
                    canExtendThisProseBlock = true;
                    parentheticalStack.Push(runtime.Quadquote);                                 //	Remember the left ""
                    shouldToggleInText = true;                                                  //	inText = true;
                }
            }

            //	When the parenthetical stack is empty, we are allowed to exit the prose block if
            //	we can match the next piece of the pattern.
            else if (parentheticalStack.Count == 0)
            {
//				if (obj == runtime.Period) {
//					//	A period ends a "prose" block unless it is protected by {} or [] or "" ""
//					//	The period does not appear in the block.  It is interpreted as ending the sentence.
//					//	So exit reading prose
//					shouldLeaveMatchingProse = true;
//					//switchToThisState = MatcherState.MATCHING_OBJECT;
//					//CURSOR
//				} else {
                //	Use inheritance to look for an exit!
                //	Look up words which would match if they were in a pattern.
                List <ProseObject> matchingPatternWords = getMatchingPatternWords(obj);
                //	Look these words up to see if actual patterns exist.
                canExtendThisProseBlock = (matchingPatternWords.Count != 0);
                foreach (ProseObject match in matchingPatternWords)
                {
                    //	If it's not a period and the attempt to extend @prose immediately failed,
                    //	then we continue matching @prose.  If the attempt didn't immediately fail then
                    //	the rules say we must leave @prose.
                    if (obj == runtime.Period)                     // && !babyMatcher.IsntFailed)
                    {
                        canExtendThisProseBlock = false;
                    }

                    if (match == runtime.@prose)
                    {
                        continue;                                               //	back to back @prose outlawed.
                    }
                    //	Look up the match
                    Trie <ProseObject, List <Phrase> > .Node matchNode = currNode.getChildNode(match);
                    if (matchNode == null)
                    {
                        continue;
                    }

                    //	If this pattern can be extended by leaving prose, then do it
                    //	Spawn a baby matcher to pursue this pattern
                    PatternMatcher babyMatcher = makeCopyWithStateFromAtWord(match);                            //	Clone ourselves
                    babyMatcher.switchToState_MATCHING_OBJECT();                                                //	Move babyMatcher into the generic state (can accept anything)
                    babyMatcher.while_MATCHING_OBJECT_extendWith(node, matchNode);                              //	Append the new node
                    babyMatchers.Add(babyMatcher);                                                              //	Eventually return this baby matcher

                    //	If it's possible to exit an @prose block, the matcher MUST
                    canExtendThisProseBlock = false;
                }
            }

            //	In this case the parenthetical stack is not empty and we have some symbol that
            //	isn't parenthetical (or "").
            else
            {
                //	Add it to this prose block
                canExtendThisProseBlock = true;
            }


            //
            //	Perform updates according to flags
            //
            if (shouldToggleInText)
            {
                inText = !inText;
            }
            if (shouldPopParentheticalStack)
            {
                parentheticalStack.Pop();
            }
            if (canExtendThisProseBlock)
            {
                //	Extend ourselves!
                //	NOTE: We don't change the node we're using!
                PatternMatcher babyMatcher = makeCopyWithStateFromAtWord(runtime.@prose);                       //	Clone ourselves
                babyMatcher.objectsInCurrentProseblock = objectsInCurrentProseblock;
                babyMatcher.while_MATCHING_PROSE_extendWith(node, currNode);
                babyMatchers.Add(babyMatcher);
            }
            else if (shouldLeaveMatchingProse)
            {
                throw new Exception("Failboat.");
//				PatternMatcher babyMatcher = makeCopyWithStateFromAtWord(obj);	//	Clone ourselves
//				//babyMatcher.switchToState_MATCHING_OBJECT();
//				babyMatcher.while_MATCHING_OBJECT_extendWith(node, );
//				babyMatchers.Add(babyMatcher);
            }

            return(babyMatchers);
        }
예제 #25
0
        //	Read a new object and maybe switch to reading prose, text, or pattern if necessary.
        List <PatternMatcher> while_MATCHING_OBJECT_matchNextObject(PNode node)
        {
            ProseObject obj = node.value;

            //	Some symbols get special treatment at the beginning or end of
            if (obj == runtime.Period ||
                obj == runtime.Semicolon &&
                currNode == patternTrie.Root)
            {
            }

            //	Get a list of words which, if they appeared in a pattern, would match with this one.
            List <ProseObject> matchingPatternWords = getMatchingPatternWords(obj);

            //
            //	For each matchingPatternWord, query the pattern tree to see if
            //	our pattern can be extended any further.
            //

            List <PatternMatcher> babyMatchers = new List <PatternMatcher>(16);

            bool foundAMatch = false;

            //ProseObject myExtensionObject = null;
            Trie <ProseObject, List <Phrase> > .Node myExtensionNode = null;
            foreach (ProseObject objMatch in matchingPatternWords)
            {
                ProseObject match = objMatch;



                //Word match = (Word) objMatch;
                //	Look up the node that would correspond to the pattern word that would match.
                Trie <ProseObject, List <Phrase> > .Node matchNode = currNode.getChildNode(match);
                //	If we can't find it, then there are no patterns with that matching word, so skip it
                if (matchNode == null)
                {
                    continue;
                }
                //	If we can find it, then we might need to make a new matcher
                //	Since ONE match has to be reserved for THIS, and the other matches spawn new matchers,
                //	we use "foundAMatch" to decide which to do.
//				if (foundAMatch)
//				{
                //	Spawn off a baby matcher and transform its state to represent the new possibility.
                PatternMatcher babyMatcher = this.makeCopyWithStateFromAtWord(match);
                babyMatcher.while_MATCHING_OBJECT_extendWith(node, matchNode);
                babyMatchers.Add(babyMatcher);                          //	List this baby matcher
                foundAMatch = true;
//				}
//				else {
//					//	Cache these two so we can use them later.
//					myExtensionObject = match;
//					myExtensionNode = matchNode;
//					foundAMatch = true;
//				}
            }

            //	If we found at least one, then we need to tweak ourselves and add ourselves to the babies.
//			if (foundAMatch) {
//				this.while_MATCHING_OBJECT_extendWith(node, myExtensionNode);
//				babyMatchers.Add(this);
//			}
//			else {
//				state = MatcherState.FAILED;
//			}

            if (!foundAMatch)
            {
                state = MatcherState.FAILED;
            }
            return(babyMatchers);
        }
예제 #26
0
        List <PatternMatcher> while_MATCHING_PATTERN_matchNextObject(PNode node)
        {
            List <PatternMatcher> babyMatchers = new List <PatternMatcher>();
            ProseObject           obj          = node.value;

            //	@Pattern won't match periods
            if (obj == runtime.Period)
            {
                return(babyMatchers);
            }

            //
            switch (bracketReaderCount)
            {
            case 0:
                //	Check to see if obj is -> :+ or :-
                if (obj == runtime.RightArrow ||
                    obj == runtime.ColonPlus ||
                    obj == runtime.ColonMinus)
                {
                    //	If so, then we have to leave matching.  See if anything is checking for this symbol
                    Trie <ProseObject, List <Phrase> > .Node childNode = currNode.getChildNode(obj);
                    if (childNode != null)
                    {
                        PatternMatcher babyMatcher = makeCopyWithStateFromAtWord(obj);                          //	Clone ourselves
                        babyMatcher.while_MATCHING_OBJECT_extendWith(node, childNode);
                        babyMatchers.Add(babyMatcher);
                    }
                }
                else if (obj == runtime.Period ||
                         !(obj is Word))
                {
                    return(babyMatchers);
                }
                else
                {
                    PatternMatcher babyMatcher = makeCopyWithStateFromAtWord(runtime.@pattern);
                    babyMatcher.while_MATCHING_PATTERN_extendWith(node, currNode);                      //	Use same node
                    if (babyMatcher.IsntFailed)
                    {
                        babyMatchers.Add(babyMatcher);
                    }
                }
                break;

            case 1:
            {
                //	In this case, just trust while_..._extendWith to do the right thing.
                PatternMatcher babyMatcher = makeCopyWithStateFromAtWord(runtime.@pattern);
                babyMatcher.bracketReaderCount = bracketReaderCount;
                babyMatcher.while_MATCHING_PATTERN_extendWith(node, currNode);                  //	Use same node
                if (babyMatcher.IsntFailed)
                {
                    babyMatchers.Add(babyMatcher);
                }
                break;
            }
            }

            return(babyMatchers);
        }
예제 #27
0
        private List <PatternMatcher> getSuccessfulMatchesStartingAtPNode(PNode source)
        {
            PatternMatcher        seedMatcher    = new PatternMatcher(this);
            List <PatternMatcher> activeMatchers = new List <PatternMatcher>(64);

            activeMatchers.Add(seedMatcher);
            List <PatternMatcher> successfullMatches = new List <PatternMatcher>();

            //	Start out looking at the first node in the source.
            PNode sourceNode = source;

            //	As long as there are still active matchers...
            while (activeMatchers.Count != 0 && sourceNode != null)
            {
                sourceNode = debugFilterIncomingPNode(sourceNode);
                if (sourceNode == null)
                {
                    break;
                }

                //	If we run into left parenthesis, reduce and eliminate before continuing.
                while (sourceNode.value == LeftParenthesis)
                {
                    PNode leftParen = sourceNode;
                    //	Reduce the parenthetical
                    bool didReduce;
                    sourceNode = reduceParentheticalExpression(sourceNode, out didReduce, LeftParenthesis, RightParenthesis);
                    //	Some matchers may have retained a reference to the leftParen, so swap it for whatever is there now.
                    foreach (PatternMatcher matcher in activeMatchers)
                    {
                        if (matcher.terminatorNode == leftParen)
                        {
                            matcher.terminatorNode = sourceNode;
                        }
                    }

                    //	Refilter the source node
                    sourceNode = debugFilterIncomingPNode(sourceNode);
                    if (sourceNode == null)
                    {
                        break;
                    }
                }


                //	Try to extend all of the active matchers.
                List <PatternMatcher> babyMatchers = new List <PatternMatcher>(256);
                foreach (PatternMatcher matcher in activeMatchers)
                {
                    //	Try to extend the given matcher and get all the resulting babies.
                    List <PatternMatcher> thisMatchersBabies = matcher.matchNextPNode(sourceNode);

                    int failCount = 0;                          //	Count the baby matchers that arrive dead.
                    foreach (PatternMatcher babyMatcher in thisMatchersBabies)
                    {
                        //	if the matcher has found a match, remember it.
                        if (babyMatcher.IsMatched)
                        {
                            //	Callback for successful match
                            if (OnMatch != null)
                            {
                                OnMatch(this, babyMatcher);
                            }

                            successfullMatches.Add(babyMatcher);
                            babyMatchers.Add(babyMatcher);
                            //							//	Rest the matcher so it can be can be continued
//							babyMatcher.IsMatched = false;
                        }
                        else if (babyMatcher.IsntFailed)
                        {
                            //	Regardless, throw it back in the pot to see if it can be extended
                            //if (babyMatcher.IsntFailed)
                            babyMatchers.Add(babyMatcher);
                        }
                        else
                        {
                            //	This baby matcher was stillborn
                            failCount++;
                        }
                    }

                    //	If the matcher produced no good children then that branch is "dead"
                    //	Only count it as a "fail" if it isn't a success itself.
                    if (thisMatchersBabies.Count - failCount == 0 &&
                        !matcher.IsMatched)
                    {
                        if (OnMatcherFailure != null)
                        {
                            OnMatcherFailure(this, matcher);
                        }
                    }
                }

                //	After one generation, the baby matchers become the new active matchers.
                activeMatchers = babyMatchers;
                //	And now we're looking at the next object in the sequence
                sourceNode = sourceNode.next;
            }

            return(successfullMatches);
        }
예제 #28
0
        //	Take a pass through the list and throw out everything that loses against m.
        private List <PatternMatcher> filterMatchesUsingInheritenceAgainstOneMatcher(List <PatternMatcher> matches, PatternMatcher m)
        {
            List <PatternMatcher> winners = new List <PatternMatcher>();

            foreach (PatternMatcher match in matches)
            {
                int res = compareMatchers(m, match);
                //	As long as it isn't a clear victory for m we keep match
                if (res != 1)
                {
                    winners.Add(match);
                }
            }

            return(winners);
        }
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            PatternMatcher match = successfulMatch;

            //	Create the phrase represented by the user's code
            //	Extract the pattern from the match
            ProseObject[] pattern  = match.CurrPatternObject.Pattern;
            ProseObject[] argNames = match.CurrPatternObject.elementNames.ToArray();
            //	Create a value[] array for the new phrase
            ProseObject[] pvalue = match.getArgumentAsProseAtIndex(5).ToArray();
            //	Go through and make substitutions for the arguments
            PatternObject po = match.CurrPatternObject;

            for (int i = 0; i < po.Length; i++)
            {
                ProseObject argName = po.elementNames[i];
                if (argName == null)
                {
                    continue;
                }

                //	If we actually have an argument name, then scan through
                //	the value array and replace instances of that variable name
                //	with ArgRefObjects.
                for (int j = 0; j < pvalue.Length; j++)
                {
                    if (pvalue[j] == argName)
                    {
                        //	Replace this object with a reference to the pattern.
                        pvalue[j] = new ArgRefObject(i);
                    }
                }
            }

            //	Follow rules regarding , ; .
            //	1.	When matching these on the beginning or end of a pattern, they automatically
            //		generate ArgRefObjects on the beginning/end of the corresponding value. This
            //		means punctuation never gets downgraded.
            //	2.	Shouldn't allow stronger punctuation on the inside than on the outside, but
            //		this is a little tougher to check.
            ProseRuntime runtime = successfulMatch.Runtime;

            if (pattern[0] == runtime.Comma || pattern[0] == runtime.Semicolon)
            {
                //	Add a ref to the beginning
                ProseObject[] newValue = new ProseObject[pvalue.Length + 1];
                Array.Copy(pvalue, 0, newValue, 1, pvalue.Length);
                newValue[0] = new ArgRefObject(0);
                pvalue      = newValue;
            }
            int patternEnd = pattern.Length - 1;

            if (pattern[patternEnd] == runtime.Comma || pattern[patternEnd] == runtime.Semicolon)
            {
                //	Add a ref to the beginning
                ProseObject[] newValue = new ProseObject[pvalue.Length + 1];
                Array.Copy(pvalue, 0, newValue, 0, pvalue.Length);
                newValue[pvalue.Length] = new ArgRefObject(patternEnd);
                pvalue = newValue;
            }



            //	Create a simple phrase from these ingredients
            SimplePhrase newPhrase = new SimplePhrase(match.Matching[1].value, pattern, argNames, pvalue);

            //	Extract the "arguments" from the PatternMatcher.
            List <PNode> M = successfulMatch.Matching;                          //	The pattern -> prose index from the match

            value    = new ProseObject[3];
            value[0] = M[0].value;
            value[1] = new ExclusivePhraseBindingAction(newPhrase);
            value[2] = M[6].value;

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);

            value = null;
            return(ret);
        }
예제 #30
0
        //    Take a pass through the list and throw out everything that loses against m.
        private List<PatternMatcher> filterMatchesUsingInheritenceAgainstOneMatcher(List<PatternMatcher> matches,  PatternMatcher m)
        {
            List<PatternMatcher> winners = new List<PatternMatcher>();

            foreach (PatternMatcher match in matches) {
                int res = compareMatchers(m, match);
                //	As long as it isn't a clear victory for m we keep match
                if (res != 1) {
                    winners.Add(match);
                }
            }

            return winners;
        }
예제 #31
0
 public virtual PNode evaluate(PNode evaluateMe, PatternMatcher match)
 {
     return(replaceWithValueAt(evaluateMe, match));
 }
예제 #32
0
 public virtual PNode evaluate(PNode evaluateMe, PatternMatcher match)
 {
     return replaceWithValueAt(evaluateMe, match);
 }
예제 #33
0
        //	Match must start at the beginning
        private PNode reduceSentenceFragmentStartingAtBeginning(PNode source, out bool didReduce)
        {
            //	Create a matcher
            //	While there are still "matchers in progress"
            //		Feed each PNode in the source to each matcher in progress.
            //		If the matcher indicats it is done then
            //			Ask for it's list of best matches.
            //			Add that list to the complete list of best matches.
            //			Remove the completed matcher from the list of matchers in progress.
            //		Otherwise,
            //			Add the list of child matchers it returns to the list of matchers in progress

            List <PatternMatcher> matches     = getSuccessfulMatchesStartingAtPNode(source);            //	Get the matches
            List <PatternMatcher> bestMatches = getStrongestMatchesFromMatchList(matches);              //	Select the winners

            //	Deal with ambiguity (too many matches)
            if (bestMatches.Count > 1 ||
                bestMatches.Count == 1 && bestMatches[0].MatchedPhrases.Count > 1)
            {
                didReduce = false;

                //	Make an ambiguity callback and throw an exception to bail out of this mess.
                if (OnAmbiguity != null)
                {
                    OnAmbiguity(this, source, bestMatches);
                    throw new RuntimeProseLanguageException("Sentence is ambiguous.", source);
                }
                else
                {
                    throw new RuntimeProseLanguageException("Sentence is ambiguous.", source);
                }
            }
            else if (bestMatches.Count == 0)
            {
                //	We couldn't reduce anything
                didReduce = false;
                return(source);
            }


            //	Apply the phrase
            PatternMatcher bestMatcher = bestMatches[0];
            Phrase         bestPhrase  = bestMatcher.MatchedPhrases[0];

            didReduce = true;

            //	Do any automatic casting necessary to make the arguments match the pattern.
            bestMatcher.autoCastArguments();

            if (BeforeReduction != null)
            {
                BeforeReduction(this, source);
            }

            //	REDUCE!
            PNode reducedSource = bestPhrase.evaluate(source, bestMatcher);

            if (AfterReduction != null)
            {
                AfterReduction(this, reducedSource);
            }

            return(reducedSource);
        }
예제 #34
0
        //	Evaluate a list of prose objects into a new list of prose objects.
        public PNode replaceWithValueAt(PNode evaluateMe, PatternMatcher match)
        {
            //	If the phrase only serves to delete the pattern...
            if (value.Length == 0)
            {
//				PNode firstNodeAfterPattern = evaluateMe.forwardSeek(match.NumObjectsMatched);
                PNode firstNodeAfterPattern = match.terminatorNode;
                if (evaluateMe.prev != null)
                {
                    evaluateMe.prev.next = firstNodeAfterPattern;
                }
                firstNodeAfterPattern.prev = evaluateMe.prev;
                return(firstNodeAfterPattern);
            }

            //	Make a node to write and hook it up the previous part of the list.
            PNode prevWriteHead      = evaluateMe.prev;
            PNode firstNodeInNewList = new PNode();
            PNode writeHead          = firstNodeInNewList;

            prevWriteHead.next = writeHead;

            foreach (ProseObject obj in value)
            {
                //	Write a value into it
                //	Argrefs get special treatment.
                if (obj is ArgRefObject)
                {
                    //	Look up the appropriate argument in "evaluate me" and substitute it.
                    int idx = ((ArgRefObject)obj).reffedArgIndex;
                    //ProseObject evaluated = evaluateMe.forwardSeek(index).value;


                    PNode subStart, subEnd;
                    subStart = match.getArgumentBounds(idx, out subEnd);


                    //TODO	This needs to support @prose, @text, and @string.
                    //writeHead.value = evaluated;
                    PNode readHead = subStart;
                    //writeHead.initWithPNode(subStart);
                    while (readHead != subEnd)
                    {
                        //	Hook p into the output
                        if (prevWriteHead != null)
                        {
                            prevWriteHead.next = writeHead;
                        }
                        writeHead.prev = prevWriteHead;
                        writeHead.initWithPNode(readHead);

                        //	Update
                        prevWriteHead = writeHead;
                        readHead      = readHead.next;
                        //	Get a new node for the next cycle
                        writeHead = new PNode();
                    }
                }
                else
                {
                    //	Hook this node into the list
                    writeHead.prev = prevWriteHead;
                    if (prevWriteHead != null)
                    {
                        prevWriteHead.next = writeHead;
                    }

                    writeHead.value = obj;

                    //	Grab a new node
                    prevWriteHead = writeHead;
                    writeHead     = new PNode();
                }
            }

            //	When we're done, tie the end of the output list back into the input list.
            //	Note: prevWriteHead is actually the last PNode we wrote.
            if (prevWriteHead != null)
            {
                prevWriteHead.next = match.terminatorNode;
                //prevWriteHead.next = evaluateMe.forwardSeek(match.NumObjectsMatched);
                if (match.terminatorNode != null)
                {
                    match.terminatorNode.prev = prevWriteHead;
                }
            }

            return(firstNodeInNewList);
        }
예제 #35
0
        public override PNode evaluate(PNode evaluateMe, PatternMatcher successfulMatch)
        {
            PatternMatcher match = successfulMatch;
            //	Create the phrase represented by the user's code
            //	Extract the pattern from the match
            ProseObject[] pattern = match.CurrPatternObject.Pattern;
            ProseObject[] argNames = match.CurrPatternObject.elementNames.ToArray();
            //	Create a value[] array for the new phrase
            ProseObject[] pvalue = match.getArgumentAsProseAtIndex(5).ToArray();
            //	Go through and make substitutions for the arguments
            PatternObject po = match.CurrPatternObject;
            for(int i=0; i < po.Length; i++) {
                ProseObject argName = po.elementNames[i];
                if (argName == null)
                    continue;

                //	If we actually have an argument name, then scan through
                //	the value array and replace instances of that variable name
                //	with ArgRefObjects.
                for(int j=0; j < pvalue.Length; j++) {
                    if (pvalue[j] == argName) {
                        //	Replace this object with a reference to the pattern.
                        pvalue[j] = new ArgRefObject(i);
                    }
                }
            }

            //	Follow rules regarding , ; .
            //	1.	When matching these on the beginning or end of a pattern, they automatically
            //		generate ArgRefObjects on the beginning/end of the corresponding value. This
            //		means punctuation never gets downgraded.
            //	2.	Shouldn't allow stronger punctuation on the inside than on the outside, but
            //		this is a little tougher to check.
            ProseRuntime runtime = successfulMatch.Runtime;
            if (pattern[0] == runtime.Comma || pattern[0] == runtime.Semicolon) {
                //	Add a ref to the beginning
                ProseObject[] newValue = new ProseObject[pvalue.Length + 1];
                Array.Copy(pvalue, 0, newValue, 1, pvalue.Length);
                newValue[0] = new ArgRefObject(0);
                pvalue = newValue;
            }
            int patternEnd = pattern.Length - 1;
            if (pattern[patternEnd] == runtime.Comma || pattern[patternEnd] == runtime.Semicolon) {
                //	Add a ref to the beginning
                ProseObject[] newValue = new ProseObject[pvalue.Length + 1];
                Array.Copy(pvalue, 0, newValue, 0, pvalue.Length);
                newValue[pvalue.Length] = new ArgRefObject(patternEnd);
                pvalue = newValue;
            }

            //	Create a simple phrase from these ingredients
            SimplePhrase newPhrase = new SimplePhrase(match.Matching[1].value, pattern, argNames, pvalue);

            //	Extract the "arguments" from the PatternMatcher.
            List<PNode> M = successfulMatch.Matching;		//	The pattern -> prose index from the match

            value = new ProseObject[3];
            value[0] = M[0].value;
            value[1] = new ExclusivePhraseBindingAction(newPhrase);
            value[2] = M[6].value;

            PNode ret = replaceWithValueAt(evaluateMe, successfulMatch);
            value = null;
            return ret;
        }
예제 #36
0
 public PatternMatcherException(string msg, PatternMatcher matcher)
     : base(msg)
 {
     patternMatcher = matcher;
 }