示例#1
0
文件: Shell.cs 项目: mbrezu/synpl
 public Shell(IAbstractEditor editor)
 {
     _editor = editor;
     _editor.TextChanged += HandleTextChanged;
     _text = new TextWithChanges(_editor);
     _selectedTreeStack = new CowList<ParseTree>();
     _chordBuffer = new Queue<Synpl.EditorAbstraction.Key>();
     _structureModeAction = "m";
     _inStructureMode = false;
 }
示例#2
0
 public void Setup()
 {
     _cowList1 = new CowList<int>();
     _cowList1.Add(3);
     _cowList1.Add(4);
     _cowList1.Add(2);
     List<string> storage = new List<string>();
     storage.Add("Ana");
     storage.Add("are");
     storage.Add("mere");
     storage.Add(".");
     _cowList2 = new CowList<string>(storage);
 }
示例#3
0
 public ParseTreeList(int startPosition, 
                       int endPosition, 
                       CowList<ParseTree> members,
                       Synpl.Core.Parser parser,
                       ParseTree parent,
                       TextWithChanges text)
     : base(startPosition,
            endPosition,
            members,
            parser,
            parent,
            text,
            "() (list)")
 {
 }
示例#4
0
文件: ParseTree.cs 项目: mbrezu/synpl
 public ParseTree(int startPosition, 
                  int endPosition, 
                  CowList<ParseTree> subTrees, 
                  Parser parser,
                  ParseTree parent,
                  TextWithChanges text,
                  string label)
 {
     _startPosition = startPosition;
     _endPosition = endPosition;
     _subTrees = subTrees;
     _parser = parser;
     _parent = parent;
     _text = text;
     _label = label;
     foreach (ParseTree node in _subTrees)
     {
         node._parent = this;
     }
 }
示例#5
0
 public static void ParseGlobal(CowList<Token> tokens, 
                               TextWithChanges text,
                               out ParseTree parseTree,
                               out CowList<Token> remainingTokens)
 {
     CowList<ParseTree> trees = new CowList<ParseTree>();
     remainingTokens = tokens;
     while (remainingTokens.Count > 0)
     {
         ParseTree tree;
         ParseLocal(remainingTokens, text, out tree, out remainingTokens);
         trees.Add(tree);
     }
     if (trees.Count == 0)
     {
         throw new ParseException("No tokens in stream.");
     }
     parseTree = new ParseTreeList(tokens[0].StartPosition,
                                   trees.Last.EndPosition,
                                   trees,
                                   SexpParser.GetInstance(ParseType.Global),
                                   null,
                                   text);
 }
示例#6
0
 public void TestEquals()
 {
     CowList<int> equalList = new CowList<int>();
     equalList.Add(3);
     equalList.Add(4);
     equalList.Add(2);
     Assert.AreEqual(equalList, _cowList1);
 }
示例#7
0
文件: ParseTree.cs 项目: mbrezu/synpl
 private ParseTree Reparse(CowList<CharWithPosition> code)
 {
     CowList<Token> tokens = _parser.TokenizerFunc(code);
     ParseTree reparsedSelf;
     CowList<Token> tokensRest;
     _parser.ParserFunc(tokens, _text, out reparsedSelf, out tokensRest);
     if (tokensRest.Count > 0)
     {
         throw new ParseException("Extra tokens in stream.");
     }
     int index = GetIndexInParent();
     if (index != -1)
     {
         _parent.SubTrees[index] = reparsedSelf;
         reparsedSelf._parent = _parent;
         _parent = null;
     }
     reparsedSelf.AdjustCoordinates(this);
     return reparsedSelf.GetRoot();
 }
示例#8
0
文件: ParseTree.cs 项目: mbrezu/synpl
 public ParseTree GetNodeAtPath(CowList<int> path)
 {
     if (path.Count == 0)
     {
         return this;
     }
     int head = path[0];
     if (head >= 0 && head < _subTrees.Count)
     {
         return _subTrees[head].GetNodeAtPath(path.Tail);
     }
     return null;
 }
示例#9
0
文件: Shell.cs 项目: mbrezu/synpl
 // Restores a position saved by GetEditorPositionAsPath
 private void SetEditorPositionFromPath(CowList<int> path, int offset)
 {
     if (path == null || _parseTree == null)
     {
         return;
     }
     ParseTree currentNode = _parseTree.GetNodeAtPath(path);
     if (currentNode != null)
     {
         _editor.CursorOffset = currentNode.StartPosition + offset;
     }
 }
示例#10
0
 public void RemoveSliceWithChanges(int start, int end, bool sendToEditor)
 {
     if (_editor != null && sendToEditor)
     {
         _editor.DeleteText(start, end - start, true);
     }
     int oldStart = ConvertActualPositionToOld(start);
     int oldEnd = ConvertActualPositionToOld(end, true);
     CowList<TextChange> newChanges = new CowList<TextChange>();
     foreach (TextChange change in _changes)
     {
         if (change.Position < oldStart) {
             newChanges.Add(change);
         }
     }
     int offset = -(oldEnd - oldStart);
     foreach (TextChange change in _changes)
     {
         if (change.Position >= oldEnd) {
             newChanges.Add(change.Moved(offset));
         }
     }
     _changes = newChanges;
     _text = _text.Remove(oldStart, oldEnd - oldStart);
 }
示例#11
0
 public void InsertSliceWithChanges(int position, TextWithChanges slice, bool sendToEditor)
 {
     if (_editor != null && sendToEditor)
     {
         CowList<CharWithPosition> sliceText = slice.GetCurrentSlice(0, slice.GetActualLength());
         StringBuilder sb = new StringBuilder();
         foreach (CharWithPosition cwp in sliceText)
         {
             sb.Append(cwp.Char);
         }
         _editor.InsertText(position, sb.ToString(), true);
     }
     int oldPosition = ConvertActualPositionToOld(position);
     CowList<TextChange> newChanges = new CowList<TextChange>();
     // Select changes before the insert position.
     int i;
     for (i = 0; i < _changes.Count; i++)
     {
         if (_changes[i].Position < oldPosition)
         {
             newChanges.Add(_changes[i]);
         }
         else
         {
             break;
         }
     }
     // Add changes from the inserted slice.
     foreach (TextChange change in slice._changes)
     {
         newChanges.Add(change.Moved(oldPosition));
     }
     // Add changes that were after the insert position.
     for (; i < _changes.Count; i++)
     {
         newChanges.Add(_changes[i].Moved(slice._text.Length));
     }
     _changes = newChanges;
     _text = _text.Substring(0, oldPosition) + slice._text + _text.Substring(oldPosition);
 }
示例#12
0
 public CowList<CharWithPosition> GetOldSlice(int start, int end)
 {
     int oldStart = ConvertActualPositionToOld(start);
     int oldEnd = ConvertActualPositionToOld(end, true);
     CowList<TextChange> relevantChanges = new CowList<TextChange>();
     foreach (TextChange change in _changes)
     {
         if (change.IsBetween(oldStart, oldEnd)) {
             relevantChanges.Add(change);
         }
     }
     CowList<CharWithPosition> result = new CowList<CharWithPosition>();
     int k = 0;
     int runningIndex = start;
     for (int i = oldStart; i < oldEnd && i < _text.Length; i++)
     {
         bool isDeletion = false;
         if (k < relevantChanges.Count)
         {
             if (relevantChanges[k].Position == i) {
                 if (relevantChanges[k].IsDeletion)
                 {
                     isDeletion = true;
                     k++;
                 }
                 else
                 {
                     runningIndex += 1;
                     k++;
                     continue;
                 }
             }
         }
         result.Add(new CharWithPosition(runningIndex, _text[i]));
         if (!isDeletion)
         {
             runningIndex += 1;
         }
     }
     return result;
 }
示例#13
0
 public CowList<CharWithPosition> GetCurrentSlice(int start, int end)
 {
     int oldStart = ConvertActualPositionToOld(start);
     int oldEnd = ConvertActualPositionToOld(end, true);
     CowList<TextChange> deletes = new CowList<TextChange>();
     foreach (TextChange change in _changes)
     {
         if (change.IsDeletion && change.IsBetween(oldStart, oldEnd))
         {
             deletes.Add(change);
         }
     }
     CowList<CharWithPosition> result = new CowList<CharWithPosition>();
     int k = 0;
     int runningIndex = start;
     for (int i = oldStart; i < oldEnd && i < _text.Length; i++)
     {
         if (k < deletes.Count)
         {
             if (deletes[k].Position == i)
             {
                 k ++;
                 continue;
             }
         }
         result.Add(new CharWithPosition(runningIndex, _text[i]));
         runningIndex++;
     }
     return result;
 }
示例#14
0
 // TODO: Add unit test.
 public CowList<int> GetChangesActualPositionsBetween(int start, int end)
 {
     CowList<int> result = new CowList<int>();
     int offset = 0;
     foreach (TextChange tc in _changes)
     {
         if (tc.IsDeletion)
         {
             offset --;
         }
         if (tc.Position + offset > end)
         {
             break;
         }
         if (tc.Position + offset >= start)
         {
             result.Add(tc.Position + offset);
         }
     }
     return result;
 }
示例#15
0
 public void TestConstructorLiteral()
 {
     CowList<int> literal = new CowList<int>(3, 4, 2);
     Assert.AreEqual(_cowList1, literal);
 }
示例#16
0
 public void SetText(string text)
 {
     _changes = new CowList<TextChange>();
     _text = text;
 }
示例#17
0
 private static CowList<ParseTree> MakeList(ParseTree item)
 {
     CowList<ParseTree> result = new CowList<ParseTree>();
     result.Add(item);
     return result;
 }
示例#18
0
        public void ValidateSlice(int start, int end)
        {
            int oldStart = ConvertActualPositionToOld(start);
            int oldEnd = ConvertActualPositionToOld(end, true);

            CowList<TextChange> changesBefore = new CowList<TextChange>();
            foreach (TextChange change in _changes)
            {
                if (change.Position < oldStart) {
                    changesBefore.Add(change);
                }
            }

            CowList<TextChange> deletesBetween = new CowList<TextChange>();
            foreach (TextChange change in _changes)
            {
                if (change.IsDeletion && change.IsBetween(oldStart, oldEnd))
                {
                    deletesBetween.Add(change);
                }
            }

            int offset = - deletesBetween.Count;
            CowList<TextChange> changesAfter = new CowList<TextChange>();
            foreach (TextChange change in _changes)
            {
                if (change.Position >= oldEnd)
                {
                    changesAfter.Add(change.Moved(offset));
                }
            }
            _changes = changesBefore;
            _changes.AddRange(changesAfter);

            int runningOffset = 0;
            foreach (TextChange delete in deletesBetween)
            {
                int pos = delete.Position + runningOffset;
                _text = _text.Remove(pos, 1);
                runningOffset -= 1;
            }
        }
示例#19
0
文件: Shell.cs 项目: mbrezu/synpl
 // This function is used to save the current position of the cursor in a
 // way that's restorable after a pretty print or transform.
 // It stores the path to the node the cursor is on, along with the offset of the
 // cursor position relative to the start position of that node.
 //
 // Obviously, this works only for transformations that rearrange text, not for transformations
 // that change the parse tree structure. Transformations of the tree structure must be re-applied
 // on the <path> vector before calling SetEditorPositionAsPath.
 private void GetEditorPositionAsPath(out CowList<int> path, out int offset)
 {
     path = null;
     offset = 0;
     if (_parseTree == null)
     {
         return;
     }
     CowList<ParseTree> pathToPosition = _parseTree.GetPathForPosition(_editor.CursorOffset);
     if (pathToPosition.Count == 0)
     {
         return;
     }
     ParseTree currentTree = pathToPosition.Last;
     path = currentTree.GetPath();
     offset = _editor.CursorOffset - currentTree.StartPosition;
 }
示例#20
0
 public TextWithChanges()
 {
     _changes = new CowList<TextChange>();
     _text = String.Empty;
 }
示例#21
0
文件: Shell.cs 项目: mbrezu/synpl
 private void UpdateSelection(ParseTree newRoot, CowList<int> path)
 {
     if (newRoot != null)
     {
         _selectedTreeStack.Clear();
         _parseTree = newRoot;
         _selectedTreeStack.Add(_parseTree.GetNodeAtPath(path));
         SelectInEditor();
     }
 }
示例#22
0
 public TextWithChanges(IAbstractEditor editor)
 {
     _changes = new CowList<TextChange>();
     _editor = editor;
     _text = _editor.GetText(0, _editor.Length);
 }
示例#23
0
文件: ParseTree.cs 项目: mbrezu/synpl
 public CowList<ParseTree> GetPathForPosition(int position)
 {
     if (!Contains(position)) {
         return new CowList<ParseTree>();
     }
     CowList<ParseTree> result = new CowList<ParseTree>();
     result.Add(this);
     foreach (ParseTree subTree in _subTrees)
     {
         if (position < subTree.StartPosition)
         {
             break;
         }
         if (subTree.Contains(position))
         {
             result.AddRange(subTree.GetPathForPosition(position));
             break;
         }
     }
     return result;
 }
示例#24
0
 public static void ParseLocal(CowList<Token> tokens, 
                               TextWithChanges text,
                               out ParseTree parseTree,
                               out CowList<Token> remainingTokens)
 {
     if (tokens.Count == 0)
     {
         throw new ParseException("No tokens in stream.");
     }
     switch ((TokenTypes)tokens[0].Kind)
     {
     case TokenTypes.Quote:
         ParseTree quotedTree;
         ParseLocal(tokens.Tail,
                    text,
                    out quotedTree,
                    out remainingTokens);
         parseTree = new ParseTreeQuote(tokens[0].StartPosition,
                                        quotedTree.EndPosition,
                                        quotedTree,
                                        SexpParser.GetInstance(ParseType.Sexp),
                                        null,
                                        text);
         return;
     case TokenTypes.OpenParen:
         CowList<ParseTree> members = new CowList<ParseTree>();
         CowList<Token> iterTokens = tokens.Tail;
         while (iterTokens.Count > 0
                && (TokenTypes)iterTokens[0].Kind != TokenTypes.CloseParen)
         {
             ParseTree member;
             CowList<Token> nextIterTokens;
             ParseLocal(iterTokens, text, out member, out nextIterTokens);
             iterTokens = nextIterTokens;
             members.Add(member);
         }
         if (iterTokens.Count == 0)
         {
             throw new ParseException("No tokens left in stream, expected a ')'.");
         }
         remainingTokens = iterTokens.Tail;
         parseTree = new ParseTreeList(tokens[0].StartPosition,
                                       iterTokens[0].EndPosition,
                                       members,
                                       SexpParser.GetInstance(ParseType.Sexp),
                                       null,
                                       text);
         return;
     case TokenTypes.CloseParen:
         throw new ParseException("Unexpected ')'.");
     case TokenTypes.Atom:
         remainingTokens = tokens.Tail;
         parseTree = new ParseTreeAtom(tokens[0].StartPosition,
                                       tokens[0].EndPosition,
                                       tokens[0].Content,
                                       SexpParser.GetInstance(ParseType.Sexp),
                                       null,
                                       text);
         return;
     default:
         throw new ParseException(String.Format("Unknown token '{0}'.",
                                                tokens[0].ToString()));
     }
 }
示例#25
0
文件: ParseTree.cs 项目: mbrezu/synpl
 private static string CharListToString(CowList<CharWithPosition> chars)
 {
     StringBuilder sb = new StringBuilder();
     foreach (CharWithPosition ch in chars)
     {
         sb.Append(ch.Char);
     }
     return sb.ToString();
 }
示例#26
0
 public static CowList<Token> Tokenize(CowList<CharWithPosition> text)
 {
     CowList<Token> result = new CowList<Token>();
     for (int pos = 0; pos < text.Count;)
     {
         CharWithPosition ch = text[pos];
         if (ch.Char =='(')
         {
             result.Add(new Token((int)TokenTypes.OpenParen, "(", ch.Position, ch.Position + 1));
             pos ++;
         }
         else if (ch.Char == ')')
         {
             result.Add(new Token((int)TokenTypes.CloseParen, ")", ch.Position, ch.Position + 1));
             pos++;
         }
         else if (Char.IsWhiteSpace(ch.Char))
         {
             while (pos < text.Count && Char.IsWhiteSpace(text[pos].Char))
             {
                 pos ++;
             }
         }
         else if (ch.Char == '\'')
         {
             result.Add(new Token((int)TokenTypes.Quote, "'", ch.Position, ch.Position + 1));
             pos ++;
         }
         else if (ch.Char == ';')
         {
             while (pos < text.Count && text[pos].Char != '\n')
             {
                 pos++;
             }
         }
         else
         {
             StringBuilder sb = new StringBuilder();
             int startPos = ch.Position;
             int endPos = startPos;
             while (pos < text.Count
                    && !Char.IsWhiteSpace(text[pos].Char)
                    && text[pos].Char != '('
                    && text[pos].Char != ')'
                    && text[pos].Char != '\'')
             {
                 sb.Append(text[pos].Char);
                 endPos = text[pos].Position + 1;
                 pos ++;
             }
             result.Add(new Token((int)TokenTypes.Atom, sb.ToString(), startPos, endPos));
         }
     }
     return result;
 }
示例#27
0
文件: ParseTree.cs 项目: mbrezu/synpl
 private ParseTree TryReparse(CowList<CharWithPosition> code)
 {
     ParseTree result = null;
     try
     {
         result = Reparse(code);
     }
     catch (ParseException)
     {
         return null;
     }
     return result;
 }
示例#28
0
 public void TestGetCurrentSlice()
 {
     SetupText();
     CowList<CharWithPosition> slice0 = _textWc.GetCurrentSlice(0, 20);
     CowList<CharWithPosition> expected = 
         new CowList<CharWithPosition>() { 
         new CharWithPosition(0, 'A'),
         new CharWithPosition(1, 'n'),
         new CharWithPosition(2, 'a'),
         new CharWithPosition(3, ' '),
         new CharWithPosition(4, 'b'),
         new CharWithPosition(5, 'c'),
         new CharWithPosition(6, 'e'),
         new CharWithPosition(7, ' '),
         new CharWithPosition(8, 'm'),
         new CharWithPosition(9, 'e'),
         new CharWithPosition(10, 'r'),
         new CharWithPosition(11, 'e'),
         new CharWithPosition(12, '.')
     };
     Assert.AreEqual(expected, slice0);
 }