working on jEdit plugin

cvs
Slava Pestov 2005-02-22 02:26:20 +00:00
parent c502ea889e
commit eb86c229e0
17 changed files with 219 additions and 133 deletions

View File

@ -3,18 +3,14 @@
- update plugin docs - update plugin docs
- word preview for remote words - word preview for remote words
- faster completion - faster completion
- [ [ dup call ] dup call ] infer hangs - [ [ dup call ] dup call ] infer hangs
- type inference fails with some assembler words; - type inference fails with some assembler words;
displaced, register and other predicates need to inherit from list displaced, register and other predicates need to inherit from list
not cons, and need stronger branch partial eval not cons, and need stronger branch partial eval
- print warning on null class - print warning on null class
- optimize away dispatch - optimize away dispatch
- code gc - code gc
- #jump-f #jump-f-label - #jump-f #jump-f-label
- extract word inside M:, C:, and structure browsing for these
- fix completion invoke in middle of word
- don't hardcode so many colors - don't hardcode so many colors
- ffi unicode strings: null char security hole - ffi unicode strings: null char security hole
- utf16 string boxing - utf16 string boxing

View File

@ -50,11 +50,11 @@ public class DefaultVocabularyLookup implements VocabularyLookup
/* comments */ /* comments */
FactorWord lineComment = define("syntax","!"); FactorWord lineComment = define("syntax","!");
lineComment.parsing = new LineComment(lineComment,false); lineComment.parsing = new LineComment(lineComment);
FactorWord stackComment = define("syntax","("); FactorWord stackComment = define("syntax","(");
stackComment.parsing = new StackComment(stackComment); stackComment.parsing = new StackComment(stackComment);
FactorWord docComment = define("syntax","#!"); FactorWord docComment = define("syntax","#!");
docComment.parsing = new LineComment(docComment,true); docComment.parsing = new LineComment(docComment);
/* strings */ /* strings */
FactorWord str = define("syntax","\""); FactorWord str = define("syntax","\"");
@ -91,7 +91,6 @@ public class DefaultVocabularyLookup implements VocabularyLookup
/* word defs */ /* word defs */
FactorWord def = define("syntax",":"); FactorWord def = define("syntax",":");
def.parsing = new Def(def); def.parsing = new Def(def);
def.docComment = true;
FactorWord ine = define("syntax",";"); FactorWord ine = define("syntax",";");
ine.parsing = new Ine(ine); ine.parsing = new Ine(ine);
FactorWord symbol = define("syntax","SYMBOL:"); FactorWord symbol = define("syntax","SYMBOL:");

View File

@ -0,0 +1,70 @@
/* :folding=explicit:collapseFolds=1: */
/*
* $Id$
*
* Copyright (C) 2005 Slava Pestov.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package factor;
public abstract class FactorArtifact
{
private String file;
private int line;
private int col;
public String getFile()
{
return file;
}
public void setFile(String file)
{
this.file = file;
}
public int getLine()
{
return line;
}
public void setLine(int line)
{
this.line = line;
}
public int getColumn()
{
return col;
}
public void setColumn(int column)
{
this.col = col;
}
public abstract String getShortString();
public abstract String getLongString();
}

View File

@ -53,7 +53,7 @@ public class FactorReader
private String in; private String in;
private int base = 10; private int base = 10;
private Cons definedWords; private Cons artifacts;
//{{{ getUnreadableString() method //{{{ getUnreadableString() method
public static String getUnreadableString(String str) public static String getUnreadableString(String str)
@ -254,10 +254,16 @@ public class FactorReader
return word; return word;
} //}}} } //}}}
//{{{ getDefinedWords() method //{{{ getArtifacts() method
public Cons getDefinedWords() public Cons getArtifacts()
{ {
return Cons.reverse(definedWords); return Cons.reverse(artifacts);
} //}}}
//{{{ addArtifact() method
public void addArtifact(FactorArtifact artifact)
{
artifacts = new Cons(artifact,artifacts);
} //}}} } //}}}
//{{{ nextWord() method //{{{ nextWord() method
@ -282,10 +288,10 @@ public class FactorReader
FactorWord w = intern((String)next,define); FactorWord w = intern((String)next,define);
if(define && w != null) if(define && w != null)
{ {
definedWords = new Cons(w,definedWords); artifacts = new Cons(w,artifacts);
w.line = line; w.setFile(scanner.getFileName());
w.col = col; w.setLine(line);
w.file = scanner.getFileName(); w.setColumn(col);
w.stackEffect = null; w.stackEffect = null;
w.documentation = null; w.documentation = null;
} }
@ -416,21 +422,6 @@ public class FactorReader
getCurrentState().setStackComment(comment); getCurrentState().setStackComment(comment);
} //}}} } //}}}
//{{{ addDocComment() method
public void addDocComment(String comment)
{
getCurrentState().addDocComment(comment);
} //}}}
//{{{ bar() method
/**
* Sets the current parser state's cdr to the given object.
*/
public void bar() throws FactorParseException
{
getCurrentState().bar();
} //}}}
//{{{ error() method //{{{ error() method
public void error(String msg) throws FactorParseException public void error(String msg) throws FactorParseException
{ {
@ -444,35 +435,21 @@ public class FactorReader
public FactorWord defining; public FactorWord defining;
public Cons first; public Cons first;
public Cons last; public Cons last;
private boolean bar;
private boolean docComment;
ParseState(FactorWord start, FactorWord defining) ParseState(FactorWord start, FactorWord defining)
{ {
docComment = start.docComment;
this.start = start; this.start = start;
this.defining = defining; this.defining = defining;
} }
void append(Object obj) throws FactorParseException void append(Object obj) throws FactorParseException
{ {
docComment = false; Cons next = new Cons(obj,null);
if(first == null)
if(bar) first = next;
{
if(last.cdr != null)
scanner.error("Only one token allowed after |");
last.cdr = obj;
}
else else
{ last.cdr = next;
Cons next = new Cons(obj,null); last = next;
if(first == null)
first = next;
else
last.cdr = next;
last = next;
}
} }
void setStackComment(String comment) void setStackComment(String comment)
@ -480,32 +457,5 @@ public class FactorReader
if(defining != null && defining.stackEffect == null) if(defining != null && defining.stackEffect == null)
defining.stackEffect = comment; defining.stackEffect = comment;
} }
void addDocComment(String comment)
{
if(defining != null && (docComment || alwaysDocComments))
{
if(defining.documentation == null)
defining.documentation = comment;
else
{
/* Its O(n^2). Big deal. */
defining.documentation = defining.documentation
.concat(comment);
}
}
}
void bar() throws FactorParseException
{
if(last.cdr != null)
{
// We already read [ a | b
// no more can be appended to this state.
scanner.error("Only one token allowed after |");
}
bar = true;
}
} //}}} } //}}}
} }

View File

@ -29,7 +29,9 @@
package factor; package factor;
public class FactorWord implements FactorExternalizable import factor.jedit.FactorWordRenderer;
public class FactorWord extends FactorArtifact implements FactorExternalizable
{ {
public String vocabulary; public String vocabulary;
public String name; public String name;
@ -46,18 +48,6 @@ public class FactorWord implements FactorExternalizable
*/ */
private FactorWord definer; private FactorWord definer;
/**
* Should the parser keep doc comments?
*/
public boolean docComment;
/**
* For text editor integration.
*/
public String file;
public int line;
public int col;
//{{{ FactorWord constructor //{{{ FactorWord constructor
public FactorWord(String vocabulary, String name) public FactorWord(String vocabulary, String name)
{ {
@ -85,4 +75,16 @@ public class FactorWord implements FactorExternalizable
{ {
this.definer = definer; this.definer = definer;
} //}}} } //}}}
//{{{ getShortString() method
public String getShortString()
{
return name;
} //}}}
//{{{ getLongString() method
public String getLongString()
{
return FactorWordRenderer.getWordHTMLString(this,false);
} //}}}
} }

View File

@ -0,0 +1,60 @@
/* :folding=explicit:collapseFolds=1: */
/*
* $Id$
*
* Copyright (C) 2005 Slava Pestov.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package factor;
import factor.jedit.FactorWordRenderer;
import org.gjt.sp.jedit.jEdit;
public class MethodArtifact extends FactorArtifact
implements FactorExternalizable
{
private FactorWord type;
private FactorWord generic;
//{{{ MethodArtifact constructor
public MethodArtifact(FactorWord type, FactorWord generic)
{
this.type = type;
this.generic = generic;
} //}}}
//{{{ getShortString() method
public String getShortString()
{
return type.name + " " + generic.name;
} //}}}
//{{{ getLongString() method
public String getLongString()
{
return jEdit.getProperty("factor.completion.method",
new String[] { type.name, generic.name });
} //}}}
}

View File

@ -29,7 +29,7 @@
package factor.jedit; package factor.jedit;
import factor.FactorWord; import factor.*;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.text.Position; import javax.swing.text.Position;
import org.gjt.sp.jedit.Buffer; import org.gjt.sp.jedit.Buffer;
@ -37,12 +37,12 @@ import sidekick.*;
public class FactorAsset extends Asset public class FactorAsset extends Asset
{ {
private FactorWord word; private FactorArtifact artifact;
public FactorAsset(FactorWord word, Position start) public FactorAsset(FactorArtifact artifact, Position start)
{ {
super(word.name); super(artifact.getShortString());
this.word = word; this.artifact = artifact;
this.start = start; this.start = start;
} }
@ -53,11 +53,11 @@ public class FactorAsset extends Asset
public String getShortString() public String getShortString()
{ {
return word.name; return artifact.getShortString();
} }
public String getLongString() public String getLongString()
{ {
return FactorWordRenderer.getWordHTMLString(word,false); return artifact.getLongString();
} }
} }

View File

@ -48,7 +48,7 @@ public abstract class FactorBufferProcessor
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
Cons words = (Cons)buffer.getProperty( Cons words = (Cons)buffer.getProperty(
FactorSideKickParser.WORDS_PROPERTY); FactorSideKickParser.ARTIFACTS_PROPERTY);
Cons wordCodeMap = null; Cons wordCodeMap = null;
while(words != null) while(words != null)
{ {

View File

@ -3,7 +3,7 @@
/* /*
* $Id$ * $Id$
* *
* Copyright (C) 2004 Slava Pestov. * Copyright (C) 2004, 2005 Slava Pestov.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -80,7 +80,7 @@ public class FactorPlugin extends EditPlugin
Buffer buffer = jEdit.getFirstBuffer(); Buffer buffer = jEdit.getFirstBuffer();
while(buffer != null) while(buffer != null)
{ {
buffer.setProperty(FactorSideKickParser.WORDS_PROPERTY,null); buffer.setProperty(FactorSideKickParser.ARTIFACTS_PROPERTY,null);
buffer = buffer.getNext(); buffer = buffer.getNext();
} }
} //}}} } //}}}
@ -681,6 +681,7 @@ public class FactorPlugin extends EditPlugin
buffer.indentLines(firstLine,lastLine); buffer.indentLines(firstLine,lastLine);
textArea.setSelectedText(newWord); textArea.setSelectedText(newWord);
buffer.indentLine(textArea.getCaretLine(),true);
} }
finally finally
{ {

View File

@ -60,6 +60,8 @@ mode.factor.sidekick.parser=factor
factor.completion.in=<font color="#a0a0a0">IN: {0}</font>\ factor.completion.in=<font color="#a0a0a0">IN: {0}</font>\
factor.completion.def={0} <b>{1}</b> factor.completion.def={0} <b>{1}</b>
factor.completion.stack={0} ( {1}) factor.completion.stack={0} ( {1})
factor.completion.method=<html>M: <b>{0} {1}</b>
factor.completion.constructor=<html>C: <b>{0}</b>
# Dialog boxes # Dialog boxes
factor.status.inserted-use=Using {0} factor.status.inserted-use=Using {0}

View File

@ -43,7 +43,7 @@ public class FactorSideKickParser extends SideKickParser
/** /**
* We store the file's parse tree in this property. * We store the file's parse tree in this property.
*/ */
public static String WORDS_PROPERTY = "factor-parsed"; public static String ARTIFACTS_PROPERTY = "factor-parsed";
private Map previewMap; private Map previewMap;
@ -98,7 +98,7 @@ public class FactorSideKickParser extends SideKickParser
public SideKickParsedData parse(Buffer buffer, public SideKickParsedData parse(Buffer buffer,
DefaultErrorSource errorSource) DefaultErrorSource errorSource)
{ {
Object words = buffer.getProperty(WORDS_PROPERTY); Object words = buffer.getProperty(ARTIFACTS_PROPERTY);
if(words instanceof Cons) if(words instanceof Cons)
forgetWords((Cons)words); forgetWords((Cons)words);
@ -135,7 +135,7 @@ public class FactorSideKickParser extends SideKickParser
d.in = r.getIn(); d.in = r.getIn();
d.use = r.getUse(); d.use = r.getUse();
addWordDefNodes(d,r.getDefinedWords(),buffer); addArtifactNodes(d,r.getArtifacts(),buffer);
} }
catch(FactorParseException pe) catch(FactorParseException pe)
{ {
@ -152,7 +152,7 @@ public class FactorSideKickParser extends SideKickParser
} }
if(r != null) if(r != null)
buffer.setProperty(WORDS_PROPERTY,r.getDefinedWords()); buffer.setProperty(ARTIFACTS_PROPERTY,r.getArtifacts());
return d; return d;
} //}}} } //}}}
@ -171,21 +171,24 @@ public class FactorSideKickParser extends SideKickParser
} }
} //}}} } //}}}
//{{{ addWordDefNodes() method //{{{ addArtifactNodes() method
private void addWordDefNodes(FactorParsedData d, Cons words, Buffer buffer) private void addArtifactNodes(FactorParsedData d, Cons artifacts, Buffer buffer)
{ {
FactorAsset last = null; FactorAsset last = null;
while(words != null) while(artifacts != null)
{ {
FactorWord word = (FactorWord)words.car; FactorArtifact artifact = (FactorArtifact)artifacts.car;
/* word lines are indexed from 1 */ /* artifact lines are indexed from 1 */
int startLine = Math.max(0,Math.min( int startLine = artifact.getLine();
startLine = Math.max(0,Math.min(
buffer.getLineCount() - 1, buffer.getLineCount() - 1,
word.line - 1)); startLine - 1));
int startLineLength = buffer.getLineLength(startLine); int startLineLength = buffer.getLineLength(startLine);
int startCol = Math.min(word.col,startLineLength);
int startCol = artifact.getColumn();
startCol = Math.min(startCol,startLineLength);
int start = buffer.getLineStartOffset(startLine) int start = buffer.getLineStartOffset(startLine)
+ startCol; + startCol;
@ -193,10 +196,10 @@ public class FactorSideKickParser extends SideKickParser
if(last != null) if(last != null)
last.end = buffer.createPosition(Math.max(0,start - 1)); last.end = buffer.createPosition(Math.max(0,start - 1));
last = new FactorAsset(word,buffer.createPosition(start)); last = new FactorAsset(artifact,buffer.createPosition(start));
d.root.add(new DefaultMutableTreeNode(last)); d.root.add(new DefaultMutableTreeNode(last));
words = words.next(); artifacts = artifacts.next();
} }
if(last != null) if(last != null)
@ -264,13 +267,13 @@ public class FactorSideKickParser extends SideKickParser
String text = buffer.getText(lineStart,caret - lineStart); String text = buffer.getText(lineStart,caret - lineStart);
/* Don't complete in the middle of a word */ /* Don't complete in the middle of a word */
int lineEnd = buffer.getLineEndOffset(caretLine) - 1; /* int lineEnd = buffer.getLineEndOffset(caretLine) - 1;
if(caret != lineEnd) if(caret != lineEnd)
{ {
String end = buffer.getText(caret,lineEnd - caret); String end = buffer.getText(caret,lineEnd - caret);
if(!isWhitespace(end.charAt(0))) if(!isWhitespace(end.charAt(0)))
return null; return null;
} } */
int wordStart = 0; int wordStart = 0;
for(int i = text.length() - 1; i >= 0; i--) for(int i = text.length() - 1; i >= 0; i--)

View File

@ -46,7 +46,7 @@ public class BeginConstructor extends FactorParsingDefinition
return; return;
reader.intern("<" + type + ">",true); reader.intern("<" + type + ">",true);
reader.addArtifact(new ConstructorArtifact(type));
reader.pushExclusiveState(word,type); reader.pushExclusiveState(word,type);
} }
} }

View File

@ -41,14 +41,24 @@ public class BeginMethod extends FactorParsingDefinition
public void eval(FactorReader reader) public void eval(FactorReader reader)
throws Exception throws Exception
{ {
// remember the position before the word name
FactorScanner scanner = reader.getScanner();
int line = scanner.getLineNumber();
int col = scanner.getColumnNumber();
FactorWord type = reader.nextWord(false); FactorWord type = reader.nextWord(false);
if(type == null) if(type == null)
return; return;
FactorWord newWord = reader.nextWord(false); FactorWord generic = reader.nextWord(false);
if(newWord == null) if(generic == null)
return; return;
reader.pushExclusiveState(word,newWord); MethodArtifact artifact = new MethodArtifact(type,generic);
artifact.setFile(scanner.getFileName());
artifact.setLine(line);
artifact.setColumn(col);
reader.addArtifact(artifact);
reader.pushExclusiveState(word,generic);
} }
} }

View File

@ -34,23 +34,18 @@ import java.io.IOException;
public class LineComment extends FactorParsingDefinition public class LineComment extends FactorParsingDefinition
{ {
public boolean doc;
//{{{ LineComment constructor //{{{ LineComment constructor
/** /**
* A new definition. * A new definition.
*/ */
public LineComment(FactorWord word, boolean doc) public LineComment(FactorWord word)
{ {
super(word); super(word);
this.doc = doc;
} //}}} } //}}}
public void eval(FactorReader reader) public void eval(FactorReader reader)
throws IOException, FactorParseException throws IOException, FactorParseException
{ {
String comment = reader.getScanner().readUntilEOL(); String comment = reader.getScanner().readUntilEOL();
if(doc)
reader.addDocComment(comment);
} }
} }

View File

@ -35,7 +35,7 @@ complement [
: complement-predicate ( complement -- list ) : complement-predicate ( complement -- list )
"predicate" word-property [ not ] append ; "predicate" word-property [ not ] append ;
: define-complement ( class predicate complement -- ) : define-complement ( class complement -- )
[ complement-predicate define-compound ] keep 2dup "complement" set-word-property
dupd "complement" set-word-property dupd complement-predicate "predicate" set-word-property
complement define-class ; complement define-class ;

View File

@ -23,12 +23,10 @@ USING: syntax generic kernel lists namespaces parser words ;
#! Syntax: BUILTIN: <class> <type#> <slots> ; #! Syntax: BUILTIN: <class> <type#> <slots> ;
CREATE scan-word [ builtin-class ] [ ] ; parsing CREATE scan-word [ builtin-class ] [ ] ; parsing
: COMPLEMENT: ( -- class predicate definition ) : COMPLEMENT: ( -- )
#! Followed by a class name, then a complemented class. #! Followed by a class name, then a complemented class.
CREATE CREATE
dup intern-symbol dup intern-symbol
dup predicate-word
[ dupd unit "predicate" set-word-property ] keep
scan-word define-complement ; parsing scan-word define-complement ; parsing
: UNION: ( -- class predicate definition ) : UNION: ( -- class predicate definition )

View File

@ -26,7 +26,7 @@ namespaces prettyprint stdio unparser vectors words ;
swap dup slip (each-object) swap dup slip (each-object)
] [ ] [
2drop 2drop
] ifte ; inline ] ifte ;
: each-object ( quot -- ) : each-object ( quot -- )
#! Applies the quotation to each object in the image. #! Applies the quotation to each object in the image.
@ -34,7 +34,7 @@ namespaces prettyprint stdio unparser vectors words ;
begin-scan (each-object) begin-scan (each-object)
] [ ] [
end-scan rethrow end-scan rethrow
] catch ; inline ] catch ;
: instances ( quot -- list ) : instances ( quot -- list )
#! Return a list of all object that return true when the #! Return a list of all object that return true when the