Skip to content

Commit 5096f41

Browse files
committed
BIG changes- parser is integrating nicely
1 parent 3ce2b46 commit 5096f41

File tree

12 files changed

+386
-199
lines changed

12 files changed

+386
-199
lines changed

BUILD.md

Lines changed: 0 additions & 33 deletions
This file was deleted.

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@ Check build.xml for building instructions.
1616
Done:
1717
- Basic functionality- running python code
1818
- Basic indentation & highlighting
19-
- Basic preprocessor
19+
- Preprocessor
2020

2121
Currently working on:
22-
- Proper parser for the preprocessor
22+
- Library imports and sketch exports
2323

2424
Future work:
25-
- Library imports and sketch exports
2625
- Better autoindent & syntax highlighting
2726
- REPL for live coding
2827

build.xml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<!-- Note: now compiles two separate jars- one for python mode, and one that's a wrapper for the processing core that can run python files -->
55

66
<!-- You'll want to change these to compile. -->
7-
<property name="processing.base" location="C:\Dev\processing-2.0.1-windows64\processing-2.0.1" /> <!-- The directory that you unpacked Processing into. -->
7+
<property name="processing.base" location="C:\Dev\processing-2.0.2-windows64\processing-2.0.2" /> <!-- The directory that you unpacked Processing into. -->
88
<property name="processing.sketchfolder" location="C:\Dev\Processing" /> <!-- Your sketchbook folder. -->
99
<property name="java.target.bootclasspath" location="C:\Program Files\Java\jdk1.6.0_38\jre\lib\rt.jar" /> <!-- If you're using a newer jdk -->
1010

@@ -72,8 +72,6 @@
7272
<target name="generate" depends="get" unless="gen.present">
7373
<mkdir dir="${gen}" />
7474
<java jar="tool/antlr-4.1-complete.jar" fork="true">
75-
<arg value="-no-listener" />
76-
<arg value="-visitor" />
7775
<arg value="-lib" />
7876
<arg value="${basedir}/${src}/${preproc.path}" />
7977
<arg value="-o" />
@@ -116,7 +114,7 @@
116114
<mkdir dir="${bundle}/mode" />
117115

118116
<!-- make mode jar -->
119-
<jar jarfile="${bundle}/mode/${lib.name}.jar" basedir="build" includes="${lib.path}/*.class"/>
117+
<jar jarfile="${bundle}/mode/${lib.name}.jar" basedir="build" includes="${lib.path}/*.class ${preproc.path}/*.class"/>
120118
<!-- make wrapper jar -->
121119
<jar jarfile="${bundle}/mode/${wrap.name}.jar" basedir="build" includes="${wrap.path}/*"/> <!-- include *.py -->
122120

@@ -161,7 +159,7 @@
161159
<delete dir="${dist}" />
162160
</target>
163161

164-
<target name="cleangen" >
162+
<target name="cleangen" depends="clean" >
165163
<delete dir="${gen}" />
166164
</target>
167165

release/PythonMode.zip

155 KB
Binary file not shown.

src/info/sansgills/mode/python/PythonBuild.java

Lines changed: 65 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.File;
44
import java.io.PrintWriter;
5+
import java.util.Set;
56
import java.util.regex.Matcher;
67
import java.util.regex.Pattern;
78

@@ -10,18 +11,26 @@
1011
import processing.app.Sketch;
1112
import processing.app.SketchCode;
1213

14+
import info.sansgills.mode.python.preproc.*;
15+
16+
import org.antlr.v4.runtime.ANTLRInputStream;
17+
import org.antlr.v4.runtime.CommonTokenStream;
18+
import org.antlr.v4.runtime.tree.ParseTree;
19+
import org.antlr.v4.runtime.tree.ParseTreeWalker;
20+
21+
1322

1423
/**
1524
*
1625
* Class to handle the building of python files.
17-
* Given that python runs as an interpreter, all this does is handle preprocessing.
26+
* Given that python runs as an interpreter, all this does is handle preprocessing
27+
* and write to an output file.
1828
*
1929
* See BUILD.md for notes.
2030
*
2131
*/
2232

2333
public class PythonBuild {
24-
2534
Sketch sketch;
2635
String resultProgram;
2736

@@ -30,6 +39,8 @@ public class PythonBuild {
3039
File binFolder;
3140
File outFile;
3241

42+
String classPath, pythonLibs, javaLibs;
43+
3344
//build tracking
3445
private int buildnumber;
3546
private static int buildstotal = 0;
@@ -69,62 +80,60 @@ public void build() throws Exception{
6980
+ sketch.getName().toLowerCase()
7081
+ ".py");
7182
outFile.createNewFile();
72-
83+
7384

7485
PrintWriter writer = new PrintWriter(outFile);
7586
writer.print(resultProgram);
7687
writer.close();
7788
}
7889

7990

80-
81-
//Things we don't need to reload every build
82-
//Some regexes
83-
//A hack, but much less work than a full parser, and we don't need to do very much
84-
private static Pattern getSpecial; //replace mousePressed / keyPressed /frameRate with getmousePressed, etc.
85-
private static Pattern instanceVars; //replace 'mouseX' with __applet__.mouseX, etc.
86-
private static Pattern findSetup, indent; //for static-mode sketches
87-
88-
static{
89-
getSpecial = Pattern.compile("(?<!def\\s{1,1000})(mousePressed|keyPressed|frameRate)(?![0-9a-zA-Z_])(?!\\s{0,1000}\\()");
90-
instanceVars = Pattern.compile("(mouseX|mouseY|pmouseX|pmouseY|mouseButton|"
91-
+"keyCode|key|pixels|width|height|displayWidth|displayHeight|focused|frameCount)(?![0-9a-zA-Z_])");
92-
findSetup = Pattern.compile("^def\\s+setup\\s*\\(\\s*\\)\\s*:", Pattern.MULTILINE);
93-
indent = Pattern.compile("\r?\n");
94-
}
95-
96-
97-
9891
/*
9992
* Turn .pde into valid python
93+
*
94+
* Now with antlr!
10095
*/
10196
private String preprocess(StringBuilder program){
97+
if(Pattern.matches("\\s*", program)){
98+
return "def setup():\n\tpass\n\n"; //empty sketch; TODO fix hack
99+
}
102100
try{
103-
String temp;
101+
PyPdeLexer lexer = new PyPdeLexer(new ANTLRInputStream(program.toString()));
102+
CommonTokenStream tokens = new CommonTokenStream(lexer);
103+
PyPdeParser parser = new PyPdeParser(tokens);
104+
ParseTree tree = parser.script();
105+
PyPdeConverter converter = new PyPdeConverter(tokens);
106+
ParseTreeWalker walker = new ParseTreeWalker();
107+
walker.walk(converter, tree);
104108

105-
Matcher regex = getSpecial.matcher(program);
109+
String result = converter.getText();
106110

107-
temp = regex.replaceAll("get$1()");
111+
String[] libraries = converter.getLibraries();
108112

109-
regex = instanceVars.matcher(temp);
113+
Set<String> knownPythonLibraries = PythonMode.getPythonLibraries();
110114

111-
temp = regex.replaceAll("__applet__.$1");
115+
pythonLibs = "";
116+
javaLibs = "";
112117

113-
regex = findSetup.matcher(temp);
114-
115-
if(!regex.find()){
116-
//no setup function; static mode sketch
117-
//TODO handle bad indentation
118-
program = new StringBuilder(temp);
119-
program.append("\nnoLoop()\n"); //no need to call draw()
120-
program.insert(0, "def setup():\n"); //put the whole function in setup()
121-
122-
regex = indent.matcher(program);
123-
124-
temp = regex.replaceAll("\n\t"); //indent everything a level! (except the first line)
118+
for(String lib : libraries){
119+
if(knownPythonLibraries.contains(lib)){
120+
//it's a python library; for now, I'm only handling ones built into jython, so no need to do anything
121+
}else{
122+
//normal java library; we can use the normal library infrastructure
123+
int dot = lib.lastIndexOf('.');
124+
String entry = (dot == -1) ? lib : lib.substring(0, dot);
125+
Library library = mode.getLibrary(entry);
126+
javaLibs += library.getJarPath() + System.getProperty("path.separator");
127+
}
125128
}
126129

127-
return temp;
130+
if(pythonLibs.equals("")){
131+
pythonLibs = null;
132+
}
133+
if(javaLibs.equals("")){
134+
javaLibs = null;
135+
}
136+
return result;
128137

129138
}catch(Exception e){
130139
System.err.println("Preprocessing failed.");
@@ -133,13 +142,20 @@ private String preprocess(StringBuilder program){
133142
}
134143
}
135144

145+
public String getJavaLibraries(){
146+
return javaLibs;
147+
}
148+
public boolean hasJavaLibraries(){
149+
return javaLibs != null;
150+
}
136151

137152

138-
139-
140-
141-
142-
153+
public String getPythonLibraries(){
154+
return pythonLibs;
155+
}
156+
public boolean hasPythonLibraries(){
157+
return pythonLibs != null;
158+
}
143159

144160
/*
145161
* The output code string
@@ -164,35 +180,13 @@ public int getBuildNumber(){
164180

165181
/*
166182
* Classes used to run the build.
167-
*
168-
* TODO build during preprocess
169183
*/
170184
public String getClassPath() {
171-
//the Processing classpath
172-
String cp = mode.getCoreLibrary().getClassPath();
173-
174-
// From JavaMode.java:
175-
// Finally, add the regular Java CLASSPATH. This contains everything
176-
// imported by the PDE itself (core.jar, pde.jar, quaqua.jar) which may
177-
// in fact be more of a problem.
178-
String javaClassPath = System.getProperty("java.class.path");
179-
// Remove quotes if any.. A messy (and frequent) Windows problem
180-
if (javaClassPath.startsWith("\"") && javaClassPath.endsWith("\"")) {
181-
javaClassPath = javaClassPath.substring(1,
182-
javaClassPath.length() - 1);
183-
}
184-
cp += File.pathSeparator + javaClassPath;
185-
186-
//The .jars for this mode; Jython and wrapper, primarily
187-
String jythonModeLib = Base.getSketchbookModesFolder().getAbsolutePath()
188-
+ File.separator
189-
+ "PythonMode"
190-
+ File.separator
191-
+ "mode";
192-
cp += Base.contentsToClassPath(new File(jythonModeLib));
193-
194-
195-
return cp; // TODO libraries?
185+
return classPath; //computed during preprocessing
186+
}
187+
188+
public String getName() {
189+
return sketch.getName();
196190
}
197191

198192
/*
@@ -201,18 +195,4 @@ public String getClassPath() {
201195
public String getJavaLibraryPath(){
202196
return "";
203197
}
204-
205-
/*
206-
* The PApplet subclass to extract from the code
207-
*/
208-
public String getClassName(){
209-
return "Placeholder"; //TODO implement naming scheme
210-
}
211-
212-
/*
213-
* The name of the output object
214-
*/
215-
public String getObjName(){
216-
return "applet"; // TODO
217-
}
218198
}

src/info/sansgills/mode/python/PythonKeyListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public boolean keyPressed(KeyEvent event){
9797
private static Pattern incIndent = Pattern.compile(":( |\\t)*(#.*)?$"); //TODO fix; breaks on strings (":#"\n) and so on
9898

9999
String getIndent(int cursor, String text){
100-
if(cursor == 1) return "\n";
100+
if(cursor <= 1) return "\n";
101101

102102
int lineStart, lineEnd;
103103
int i;

0 commit comments

Comments
 (0)