// 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; }
private void while_MATCHING_PROSE_extendWith(PNode node, Trie <ProseObject, List <Phrase> > .Node patternNode) { this.numObjectsMatched++; this.currNode = patternNode; this.objectsInCurrentProseblock++; ProseObject obj = node.value; if (obj == runtime.LeftCurlyBracket) { parentheticalStack.Push(runtime.LeftCurlyBracket); } else if (obj == runtime.LeftSquareBracket) { parentheticalStack.Push(runtime.LeftSquareBracket); } // The first time this is called is from outside fo while_MATCHING_PROSE_matchNext else if (obj == runtime.Quadquote && objectsInCurrentProseblock == 1) { // In this case, we treat this as an opening quadquote. parentheticalStack.Push(runtime.Quadquote); // Remember the left "" inText = true; //shouldToggleInText = true; // inText = true; } // ...we don't really do anything. The beginning of the @prose block was already noted // If there's something here, then we are a match if (currNode.Value != null && currNode.Value.Count != 0) { //isMatched = true; becomeMatched(node.next); } }
public SimplePhrase(ProseObject phraseClass, ProseObject[] pattern, ProseObject[] argNames, ProseObject[] value) { this.phraseClass = phraseClass; this.pattern = (ProseObject[]) pattern.Clone(); this.argNames = (ProseObject[]) argNames.Clone (); this.value = (ProseObject[]) value.Clone(); }
// 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; }
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); }
// 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); }
public void read(List <ProseObject> source, int startIdx, int endIdx, ProseClient who) { // Convert source into a linked list structure. PNode head = new PNode(); PNode initPeriod = new PNode(Period); head.next = initPeriod; initPeriod.prev = head; PNode prev = initPeriod; for (int i = startIdx; i < endIdx; i++) { ProseObject obj = source[i]; PNode p = new PNode(obj); p.prev = prev; prev.next = p; // Update prev = p; } PNode termPeriod = new PNode(Period); prev.next = termPeriod; termPeriod.prev = prev; // Read the new format starting with the initial period. read(head); }
public static PNode new_PNodeList(ProseObject[] objs, out PNode lastNode) { // Create a first object. if (objs.Length == 0) { lastNode = null; return null; } PNode firstNode = new PNode(); firstNode.value = objs[0]; firstNode.prev = null; if (objs.Length == 1) { firstNode.next = null; lastNode = firstNode; return firstNode; } PNode prevNode = firstNode; PNode currNode = null; for (int i=2; i < objs.Length; i++) { currNode = new PNode(); prevNode.next = currNode; currNode.prev = prevNode; currNode.value = objs[i]; prevNode = currNode; } currNode.next = null; lastNode = currNode; return firstNode; }
public PNode(ProseObject[] objs) { debugData = null; this.prev = null; if (objs.Length == 0) { this.value = null; this.next = null; return; } if (objs.Length == 1) { this.value = objs[0]; this.next = null; return; } PNode prevNode = this; PNode currNode = null; for (int i=2; i < objs.Length; i++) { currNode = new PNode(); prevNode.next = currNode; currNode.prev = prevNode; currNode.value = objs[i]; prevNode = currNode; } currNode.next = null; return; }
public SimplePhrase(ProseObject phraseClass, ProseObject[] pattern, ProseObject[] argNames, ProseObject[] value) { this.phraseClass = phraseClass; this.pattern = (ProseObject[])pattern.Clone(); this.argNames = (ProseObject[])argNames.Clone(); this.value = (ProseObject[])value.Clone(); }
public PNode(ProseObject[] objs) { debugData = null; this.prev = null; if (objs.Length == 0) { this.value = null; this.next = null; return; } if (objs.Length == 1) { this.value = objs[0]; this.next = null; return; } PNode prevNode = this; PNode currNode = null; for (int i = 2; i < objs.Length; i++) { currNode = new PNode(); prevNode.next = currNode; currNode.prev = prevNode; currNode.value = objs[i]; prevNode = currNode; } currNode.next = null; return; }
// Take a single pattern matcher and actually add the next object and node to it // If the pattern object involves @prose, @text, or @pattern then switch to those states. // This is only called while MATCHING_OBJECT. The @prose, @text, @pattern matching algorithms // do their extensions internally. // private void while_MATCHING_OBJECT_extendWith(ProseObject matchedObject, Trie<ProseObject, List<Phrase>>.Node patternNode) private void while_MATCHING_OBJECT_extendWith(PNode node, Trie <ProseObject, List <Phrase> > .Node patternNode) { // Depending on the contents of patternNode we may need to change state. // If // If we do change state, then re-match ProseObject key = patternNode.getKey(); if (key == runtime.@prose) { // Either this node matches directly with a word in the pattern, or it's the first node in // a match of @prose, @text, @pattern. Either way, it goes in the patternComponentNodes. patternComponentNodes.Add(node); // this.currNode = patternNode; //this.numObjectsMatched++; switchToState_MATCHING_PROSE(); while_MATCHING_PROSE_extendWith(node, patternNode); if (currNode.Value != null && currNode.Value.Count != 0) { becomeMatched(node.next); } } else if (key == runtime.@text) { switchToState_MATCHING_TEXT(); } else if (key == runtime.@pattern) { switchToState_MATCHING_PATTERN(); while_MATCHING_PATTERN_extendWith(node, patternNode); } // A text expression masquerading as a string. else if (key == runtime.@string && node.value == runtime.Quadquote) { switchToState_MATCHING_TEXT(); while_MATCHING_TEXT_extendWith(node, patternNode); } else { // Either this node matches directly with a word in the pattern, or it's the first node in // a match of @prose, @text, @pattern. Either way, it goes in the patternComponentNodes. patternComponentNodes.Add(node); this.currNode = patternNode; this.numObjectsMatched++; // If there's something to match at this node, and we're not entering a // fancy matcher state. Then, having a value at this patternNode is the same // thing as saying, there's a phrase out there that matches US. So we're a match. if (state == MatcherState.MATCHING_OBJECT && patternNode.Value != null && patternNode.Value.Count != 0) { //isMatched = true; becomeMatched(node.next); } } }
public LoadAssemblyAction(string assemblyFileName, ProseObject rawWord) { dllName = assemblyFileName; this.rawWord = rawWord; if (rawWord is RawWordObject) rawWords = ((RawWordObject) rawWord).RawWords; else if (rawWord is Word) rawWords = ((Word) rawWord).RawWords; else throw new Exception("Assembly handles must be words or raw words."); }
// Read a text expression and reduce it to a string // textStart = opening "", textEnd = object after closing "" public string parseTextExpressionIntoString(PNode textStart, PNode textEnd) { StringBuilder str = new StringBuilder(); int prevObjSpaceRequest = 0; int thisObjSpaceRequest = 0; for (PNode node = textStart.next; node != null && node.next != textEnd; node = node.next) { ProseObject obj = node.value; // WARNING: MUST COME FIRST BECAUSE IT MAY CHANGE THE VALUE OF node // Left square bracket opens an inline prose expression that must be evaluated if (obj == LeftSquareBracket) { bool didReduce; node = reduceParentheticalExpression(node, out didReduce, LeftSquareBracket, RightSquareBracket); obj = node.value; } // String literals substitute their contents directly if (obj is StringLiteralObject) { str.Append(((StringLiteralObject)obj).literal); thisObjSpaceRequest = -1; } else { if (prevObjSpaceRequest != -1) { str.Append(" "); } str.Append(obj.getReadableString()); thisObjSpaceRequest = 1; } // if (prevObjSpaceRequest != -1 && thisObjSpaceRequest != -1) // str.Append(" "); // Update prevObjSpaceRequest = thisObjSpaceRequest; } if (str[str.Length - 1] == ' ') { str.Remove(str.Length - 1, 1); } return(str.ToString()); }
// // 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; }
List <PatternMatcher> while_MATCHING_TEXT_matchNextObject(PNode node) { ProseObject obj = node.value; List <PatternMatcher> babyMatchers = new List <PatternMatcher>(); // Extend ourselves! // NOTE: We don't change the node we're using! PatternMatcher babyMatcher = makeCopyWithStateFromAtWord(runtime.@text); // Clone ourselves babyMatcher.while_MATCHING_TEXT_extendWith(node, currNode); babyMatchers.Add(babyMatcher); return(babyMatchers); }
// // 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); }
public LoadAssemblyAction(string assemblyFileName, ProseObject rawWord) { dllName = assemblyFileName; this.rawWord = rawWord; if (rawWord is RawWordObject) { rawWords = ((RawWordObject)rawWord).RawWords; } else if (rawWord is Word) { rawWords = ((Word)rawWord).RawWords; } else { throw new Exception("Assembly handles must be words or raw words."); } }
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; }
// 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); }
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; }
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); }
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); }
// 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; }
public string getValueDescriptionString() { // If the value hasn't been determined, look up a static description instead. if (value == null) { return(getStaticValueDescriptionString()); } StringBuilder str = new StringBuilder(); for (int i = 0; i < value.Length; i++) { if (value[i] is ArgRefObject) { int argIdx = ((ArgRefObject)value[i]).reffedArgIndex; ProseObject argName = argNames[argIdx]; if (argName != null) { str.Append(argName.getReadableString()); } else { str.Append(pattern[argIdx].getReadableString()); } } else { str.Append(value[i].getReadableString()); } str.Append(" "); } if (value.Length > 0) { str.Remove(str.Length - 1, 1); } return(str.ToString()); }
// 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); }
// 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); }
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; }
// Take the current pattern matcher, attempt to extend the match by one object. // Return the list of child matchers spawned. //public List<PatternMatcher> matchNextObject(ProseObject nextObject) public List <PatternMatcher> matchNextPNode(PNode nextNode) { ProseObject obj = nextNode.value; // Create a list of ProseObjects that, if they appeared in a pattern, would match with obj. // For each such object, query the pattern tree to see if our pattern can be extended any further. // If it can be extended further // for each such extension (except the first) // Clone this patternMatcher and then advance that matcher to represent the extension. // Add the new matcher to the output children list // for the first such extension: // Modify this matcher toe represent the extension. // If it can't be extended further // isComplete = true; // You're NEVER allowed to match parenthesis if (obj == runtime.LeftParenthesis || obj == runtime.RightParenthesis) { throw new RuntimeFailure("getListOfMatchingPatternObjects received parenthesis."); } switch (state) { case MatcherState.MATCHING_OBJECT: return(while_MATCHING_OBJECT_matchNextObject(nextNode)); case MatcherState.MATCHING_PROSE: return(while_MATCHING_PROSE_matchNextObject(nextNode)); case MatcherState.MATCHING_TEXT: return(while_MATCHING_TEXT_matchNextObject(nextNode)); case MatcherState.MATCHING_PATTERN: return(while_MATCHING_PATTERN_matchNextObject(nextNode)); } return(null); }
public string getReadableString() { StringBuilder s = new StringBuilder(40); for (int i = 0; i < patternElements.Count; i++) { s.Append(patternElements[i].getReadableString()); ProseObject eltName = elementNames[i]; if (eltName != null) { s.Append("["); s.Append(eltName.getReadableString()); s.Append("]"); } s.Append(" "); } // Throw out the extra space at the end if (patternElements.Count > 0) { s.Remove(s.Length - 1, 1); } return(s.ToString()); }
// // The constructor expects a pattern like: // // , existing_word : word_or_raw_word , // // Possibly we will use different punctuation so, we allow the possibility of creating an // instance of this phrase with a differnet pattern. // public WordBindingPhrase(ProseObject phraseClass, ProseObject[] pattern) : base(phraseClass, pattern) { }
public PNode(ProseObject obj) { next = prev = null; value = obj; debugData = null; }
public DebugOutputPhrase(string message, ProseObject phraseClass, ProseObject[] pattern) : base(phraseClass, pattern) { this.message = message; }
public ReadPhrase(ProseObject phraseClass, ProseObject[] phrasePattern) : base(phraseClass, phrasePattern) { }
private PNode reduceParentheticalExpression(PNode source, out bool didReduce, ProseObject leftParentheticalObject, ProseObject rightParentheticalObject) { // Find the ending parenthesis PNode rightParen = source; for (int parenDepthCount = 0; true; rightParen = rightParen.next) { if (rightParen.value == leftParentheticalObject) { parenDepthCount++; continue; } if (rightParen.value == rightParentheticalObject) { parenDepthCount--; if (parenDepthCount == 0) // We've found the closing right parenthesis { break; } } } while (rightParen.value != rightParentheticalObject) { rightParen = rightParen.next; } // Unhook the ending parenthesis from the expression we want to reduce. rightParen.prev.next = null; // Reduce the expression (starting AFTER the left paren) bool didReduceParenthetical; PNode reducedExpression; callDepth++; try { reducedExpression = reduceSentenceFragment(source.next, out didReduceParenthetical); } finally { callDepth--; } //We splice it in in two ways depending on whether it reduces to anything or not if (reducedExpression == null) { // If we get nothing back, cut out the parenthesis and continue source.prev.next = rightParen.next; if (rightParen.next != null) { rightParen.next.prev = source.prev; } reducedExpression = rightParen.next; // The first thing after the paren is what we look at next. } else { // If we get something back, splice it in // Cut out the left paren if (source.prev != null) { source.prev.next = reducedExpression; } reducedExpression.prev = source.prev; // Hook the end of the expression back into the original source (skipping right paren) // First find the new end PNode reducedExprEnd = reducedExpression; while (reducedExprEnd.next != null) { reducedExprEnd = reducedExprEnd.next; } reducedExprEnd.next = rightParen.next; if (rightParen.next != null) { rightParen.next.prev = reducedExprEnd; } } didReduce = didReduceParenthetical; return(reducedExpression); }
// Create a phrase which binds phrases. The phrase itself uses phraseClass and // phrasePattern. The phrase to be bound is entirely described by the PatternMatcher. public ExclusivePhraseBindingPhrase(ProseObject phraseClass, ProseObject[] phrasePattern) : base(phraseClass, phrasePattern) { }
public ApplyMethodPhrase(ProseObject phraseClass, ProseObject[] phrasePattern) : base(phraseClass, phrasePattern) { }
public BindMethodPhrase(ProseObject phraseClass, ProseObject[] phrasePattern) : base(phraseClass, phrasePattern) { }
// This is reserved for subclasses who want to set value[] themselves and call // replaceWithValueAt in their own evaluate methods. public SimplePhrase(ProseObject phraseClass, ProseObject[] pattern) { this.phraseClass = phraseClass; this.pattern = (ProseObject[]) pattern.Clone(); this.value = null; }
public BindAssemblyPhrase(ProseObject phraseClass, ProseObject[] phrasePattern) : base(phraseClass, phrasePattern) { }
public void initWithPNode(PNode node) { this.value = node.value; this.debugData = node.debugData; }
public PNode(PNode copyMe) { value = copyMe.value; debugData = copyMe.debugData; }
// Add an element without a name public void putPatternElement(ProseObject element) { patternElements.Add (element); elementNames.Add(null); }
public ContentsOfTextFilePhrase(ProseObject phraseClass, ProseObject[] phrasePattern) : base(phraseClass, phrasePattern) { }
public BreakPointPhrase(ProseObject phraseClass, ProseObject[] phrasePattern) : base(phraseClass, phrasePattern) { }
public void addProseObject(ProseObject obj) { body.Add(obj); }
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); }
// Put an a new element into the pattern. If it has an argument name, put that name, otherwise second arg = null. public void putPatternElement(ProseObject element, ProseObject name) { patternElements.Add(element); elementNames.Add (name); }
private bool proseObjectEndsSentence(ProseObject p) { return (p == this.PERIOD); }
private bool proseObjectEndsSentence(ProseObject p) { return(p == this.PERIOD); }
private PNode reduceParentheticalExpression(PNode source, out bool didReduce, ProseObject leftParentheticalObject, ProseObject rightParentheticalObject) { // Find the ending parenthesis PNode rightParen = source; for (int parenDepthCount = 0; true; rightParen = rightParen.next) { if (rightParen.value == leftParentheticalObject) { parenDepthCount++; continue; } if (rightParen.value == rightParentheticalObject) { parenDepthCount--; if (parenDepthCount == 0) // We've found the closing right parenthesis break; } } while (rightParen.value != rightParentheticalObject) { rightParen= rightParen.next; } // Unhook the ending parenthesis from the expression we want to reduce. rightParen.prev.next = null; // Reduce the expression (starting AFTER the left paren) bool didReduceParenthetical; PNode reducedExpression; callDepth++; try { reducedExpression= reduceSentenceFragment(source.next, out didReduceParenthetical); } finally { callDepth--; } //We splice it in in two ways depending on whether it reduces to anything or not if (reducedExpression == null) { // If we get nothing back, cut out the parenthesis and continue source.prev.next = rightParen.next; if (rightParen.next != null) rightParen.next.prev = source.prev; reducedExpression = rightParen.next; // The first thing after the paren is what we look at next. } else { // If we get something back, splice it in // Cut out the left paren if (source.prev != null) source.prev.next = reducedExpression; reducedExpression.prev = source.prev; // Hook the end of the expression back into the original source (skipping right paren) // First find the new end PNode reducedExprEnd = reducedExpression; while (reducedExprEnd.next != null) reducedExprEnd = reducedExprEnd.next; reducedExprEnd.next = rightParen.next; if (rightParen.next != null) rightParen.next.prev = reducedExprEnd; } didReduce = didReduceParenthetical; return reducedExpression; }
// Overwrite the name written for the previous element public void replaceLastPutElementNameWith(ProseObject newName) { elementNames[elementNames.Count - 1] = newName; }
public static void constructInitialPatternTrie(ProseRuntime runtime) { ProseScope scope = runtime.GlobalScope; Trie<ProseObject, List<Phrase>> patternTrie = scope.PatternTree; // // Pattern Creation Pattern // // The only pattern we need to "force" into the system is the pattern for making patterns: // word[phrase_class] : @pattern[pattern] -> @prose[value] . // Phrase phrasePhrase = new SimplePhrase(runtime.Word_phrase, // new ProseObject[] { runtime.Word_word, //patternTrie.putObjectString( #region Word binding phrases // , word : @raw , { ProseObject[] commaDelimitedBindWordsPattern = new ProseObject[] {runtime.Comma, runtime.Word_word, runtime.Colon, runtime.@raw, runtime.Comma}; WordBindingPhrase bindWords_commaDelimited = new WordBindingPhrase( runtime.Word_phrase, commaDelimitedBindWordsPattern ); scope.addPhrase(bindWords_commaDelimited); } // , word +: @raw , { ProseObject[] commaDelimitedBindWordsPattern = new ProseObject[] {runtime.Comma, runtime.Word_word, runtime.PlusColon, runtime.@raw, runtime.Comma}; WordBindingPhrase bindWords_commaDelimited = new WordBindingPhrase( runtime.Word_phrase, commaDelimitedBindWordsPattern ); scope.addPhrase(bindWords_commaDelimited); } // , word <- @raw , { ProseObject[] commaDelimitedBindWordsPattern = new ProseObject[] {runtime.Comma, runtime.Word_word, runtime.LeftArrow, runtime.@raw, runtime.Comma}; ExclusiveWordBindingPhrase exclusiveBindWords_commaDelimited = new ExclusiveWordBindingPhrase( runtime.Word_phrase, commaDelimitedBindWordsPattern ); scope.addPhrase(exclusiveBindWords_commaDelimited); } #endregion #region Phrase creation phrases // Comma delimited exclusive phrase creation // , word[class]: @pattern -> @prose[value] , { ProseObject[] phrasePattern = new ProseObject[] {runtime.Comma, runtime.Word_word, runtime.Colon, runtime.@pattern, runtime.RightArrow, runtime.@prose, runtime.Comma}; ExclusivePhraseBindingPhrase phrasePhrase = new ExclusivePhraseBindingPhrase(runtime.Word_phrase, phrasePattern); scope.addPhrase(phrasePhrase); } // Semicolon delimited exclusive phrase creation // ; word[class]: @pattern -> @prose[value] ; { ProseObject[] phrasePattern = new ProseObject[] {runtime.Semicolon, runtime.Word_word, runtime.Colon, runtime.@pattern, runtime.RightArrow, runtime.@prose, runtime.Semicolon}; ExclusivePhraseBindingPhrase phrasePhrase = new ExclusivePhraseBindingPhrase(runtime.Word_phrase, phrasePattern); scope.addPhrase(phrasePhrase); } // Period delimited exclusive phrase creation // . word[class]: @pattern -> @prose[value] . { ProseObject[] phrasePattern = new ProseObject[] {runtime.Period, runtime.Word_word, runtime.Colon, runtime.@pattern, runtime.RightArrow, runtime.@prose, runtime.Period}; ExclusivePhraseBindingPhrase phrasePhrase = new ExclusivePhraseBindingPhrase(runtime.Word_phrase, phrasePattern); scope.addPhrase(phrasePhrase); } #endregion #region Reading // , read @string[x] , { ProseObject[] p = new ProseObject[] {runtime.Comma, runtime.word("read"), runtime.word("@string"), runtime.Comma}; Phrase readPhrase = new ReadPhrase(runtime.Word_phrase, p); scope.addPhrase(readPhrase); } // contents of text file @string[file_name] { ProseObject[] p = new ProseObject[] {runtime.word("contents"), runtime.word("of"), runtime.word("text"), runtime.word("file"), runtime.word("@string")}; Phrase readFilePhrase = new ContentsOfTextFilePhrase(runtime.Word_phrase, p); scope.addPhrase(readFilePhrase); } runtime.read("phrase: , read file @string[path] , -> , read contents of text file path ,", runtime.GlobalClient); #endregion #region Foreign Function Interface // Load an assembly and bind it to a name // , load assembly : @string[file_name] <- @raw[new_assembly_word] , { ProseObject[] p = new ProseObject[] {runtime.Comma, runtime.word("load"), runtime.word("assembly"), runtime.Colon, runtime.@string, runtime.LeftArrow, runtime.@raw, runtime.Comma}; BindAssemblyPhrase asmPhrase = new BindAssemblyPhrase(runtime.Word_phrase, p); scope.addPhrase(asmPhrase); } // Load a type and bind it to a name // , @assembly[asm_name] type : @string[type_name] <- @raw[new_type_word] , { ProseObject[] p = new ProseObject[] {runtime.Comma, runtime.word("@assembly"), runtime.word("type"), runtime.Colon, runtime.@string, runtime.LeftArrow, runtime.@raw, runtime.Comma}; BindTypePhrase typePhrase = new BindTypePhrase(runtime.Word_phrase, p); scope.addPhrase(typePhrase); } // Load a method and bind it to a name // , @type[type_name] method : @string[method_name] <- @raw[new_method_word] , { ProseObject[] p = new ProseObject[] {runtime.Comma, runtime.word("@type"), runtime.word("method"), runtime.Colon, runtime.@string, runtime.LeftArrow, runtime.@raw, runtime.Comma}; BindMethodPhrase methodPhrase = new BindMethodPhrase(runtime.Word_phrase, p); scope.addPhrase(methodPhrase); } // Apply a method to some arguments to produce an action // , @method[method_name] @prose[args] , { ProseObject[] p = new ProseObject[] {runtime.Comma, runtime.word("@method"), runtime.@prose, runtime.Comma}; Phrase applyMethodPhrase = new ApplyMethodPhrase(runtime.Word_phrase, p); scope.addPhrase(applyMethodPhrase); } // Apply a method with no arguments to produce an action // , @method[method_name] , { ProseObject[] p = new ProseObject[] {runtime.Comma, runtime.word("@method"), runtime.Comma}; Phrase applyMethodPhrase = new ApplyMethodPhrase(runtime.Word_phrase, p); scope.addPhrase(applyMethodPhrase); } #endregion // Add a breakpoint { ProseObject[] p = new ProseObject[] {runtime.@break}; Phrase addBreakpointPhrase = new BreakPointPhrase(runtime.Word_phrase, p); scope.addPhrase(addBreakpointPhrase); } #region Debugger #endregion #region Experimental // , -> @pattern -> , { ProseObject[] test = new ProseObject[] {runtime.Comma, runtime.RightArrow, runtime.@pattern, runtime.RightArrow, runtime.Comma}; DebugOutputPhrase dbg = new DebugOutputPhrase("Carlybou", runtime.Word_phrase, test); scope.addPhrase(dbg); } #endregion }
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; }