2005-08-25 23:06:28 +02:00
|
|
|
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
|
|
|
|
|
|
/*
|
|
|
|
PdePreprocessor - wrapper for default ANTLR-generated parser
|
2005-09-25 16:11:32 +02:00
|
|
|
Part of the Wiring project - http://wiring.org.co
|
2005-08-25 23:06:28 +02:00
|
|
|
|
2005-09-25 16:11:32 +02:00
|
|
|
Copyright (c) 2004-05 Hernando Barragan
|
|
|
|
|
|
|
|
Processing version Copyright (c) 2004-05 Ben Fry and Casey Reas
|
2005-08-25 23:06:28 +02:00
|
|
|
Copyright (c) 2001-04 Massachusetts Institute of Technology
|
|
|
|
|
|
|
|
ANTLR-generated parser and several supporting classes written
|
|
|
|
by Dan Mosedale via funding from the Interaction Institute IVREA.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software Foundation,
|
|
|
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
package processing.app.preproc;
|
|
|
|
|
|
|
|
import processing.app.*;
|
|
|
|
//import processing.core.*;
|
|
|
|
|
|
|
|
import java.io.*;
|
|
|
|
|
|
|
|
import antlr.*;
|
|
|
|
import antlr.collections.*;
|
|
|
|
import antlr.collections.impl.*;
|
|
|
|
|
|
|
|
import com.oroinc.text.regex.*;
|
|
|
|
|
|
|
|
|
|
|
|
public class PdePreprocessor {
|
|
|
|
|
|
|
|
static final int JDK11 = 0;
|
|
|
|
static final int JDK13 = 1;
|
|
|
|
static final int JDK14 = 2;
|
|
|
|
|
|
|
|
static String defaultImports[][] = new String[3][];
|
|
|
|
|
|
|
|
// these ones have the .* at the end, since a class name
|
|
|
|
// might be at the end instead of .* whcih would make trouble
|
|
|
|
// other classes using this can lop of the . and anything after
|
|
|
|
// it to produce a package name consistently.
|
|
|
|
public String extraImports[];
|
|
|
|
|
|
|
|
// imports just from the code folder, treated differently
|
|
|
|
// than the others, since the imports are auto-generated.
|
|
|
|
public String codeFolderImports[];
|
|
|
|
|
|
|
|
static public final int STATIC = 0; // formerly BEGINNER
|
|
|
|
static public final int ACTIVE = 1; // formerly INTERMEDIATE
|
|
|
|
static public final int JAVA = 2; // formerly ADVANCED
|
|
|
|
// static to make it easier for the antlr preproc to get at it
|
|
|
|
static public int programType = -1;
|
|
|
|
|
|
|
|
Reader programReader;
|
|
|
|
String buildPath;
|
|
|
|
|
|
|
|
// used for calling the ASTFactory to get the root node
|
|
|
|
private static final int ROOT_ID = 0;
|
2005-09-25 16:11:32 +02:00
|
|
|
|
|
|
|
// stores number of built user-defined function prototypes
|
|
|
|
public int prototypeCount = 0;
|
2005-08-25 23:06:28 +02:00
|
|
|
|
2006-03-26 21:12:53 +02:00
|
|
|
// stores number of included library headers written
|
|
|
|
public int headerCount = 0;
|
|
|
|
|
2005-08-25 23:06:28 +02:00
|
|
|
/**
|
|
|
|
* These may change in-between (if the prefs panel adds this option)
|
|
|
|
* so grab them here on construction.
|
|
|
|
*/
|
|
|
|
public PdePreprocessor() {
|
2005-09-25 16:11:32 +02:00
|
|
|
/* defaultImports[JDK11] =
|
2005-08-25 23:06:28 +02:00
|
|
|
Base.split(Preferences.get("preproc.imports.jdk11"), ',');
|
|
|
|
defaultImports[JDK13] =
|
|
|
|
Base.split(Preferences.get("preproc.imports.jdk13"), ',');
|
|
|
|
defaultImports[JDK14] =
|
|
|
|
Base.split(Preferences.get("preproc.imports.jdk14"), ',');
|
2005-09-25 16:11:32 +02:00
|
|
|
*/ }
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used by PdeEmitter.dumpHiddenTokens()
|
|
|
|
*/
|
2005-09-25 16:11:32 +02:00
|
|
|
//public static TokenStreamCopyingHiddenTokenFilter filter;
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* preprocesses a pde file and write out a java file
|
|
|
|
* @return the classname of the exported Java
|
|
|
|
*/
|
|
|
|
//public String write(String program, String buildPath, String name,
|
|
|
|
// String extraImports[]) throws java.lang.Exception {
|
|
|
|
public String write(String program, String buildPath,
|
2007-01-12 18:58:39 +01:00
|
|
|
String name, String codeFolderPackages[],
|
|
|
|
Target target)
|
2005-08-25 23:06:28 +02:00
|
|
|
throws java.lang.Exception {
|
|
|
|
// if the program ends with no CR or LF an OutOfMemoryError will happen.
|
|
|
|
// not gonna track down the bug now, so here's a hack for it:
|
|
|
|
if ((program.length() > 0) &&
|
|
|
|
program.charAt(program.length()-1) != '\n') {
|
|
|
|
program += "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Preferences.getBoolean("preproc.substitute_unicode")) {
|
|
|
|
// check for non-ascii chars (these will be/must be in unicode format)
|
|
|
|
char p[] = program.toCharArray();
|
|
|
|
int unicodeCount = 0;
|
|
|
|
for (int i = 0; i < p.length; i++) {
|
|
|
|
if (p[i] > 127) unicodeCount++;
|
|
|
|
}
|
|
|
|
// if non-ascii chars are in there, convert to unicode escapes
|
|
|
|
if (unicodeCount != 0) {
|
|
|
|
// add unicodeCount * 5.. replacing each unicode char
|
|
|
|
// with six digit uXXXX sequence (xxxx is in hex)
|
|
|
|
// (except for nbsp chars which will be a replaced with a space)
|
|
|
|
int index = 0;
|
|
|
|
char p2[] = new char[p.length + unicodeCount*5];
|
|
|
|
for (int i = 0; i < p.length; i++) {
|
|
|
|
if (p[i] < 128) {
|
|
|
|
p2[index++] = p[i];
|
|
|
|
|
|
|
|
} else if (p[i] == 160) { // unicode for non-breaking space
|
|
|
|
p2[index++] = ' ';
|
|
|
|
|
|
|
|
} else {
|
|
|
|
int c = p[i];
|
|
|
|
p2[index++] = '\\';
|
|
|
|
p2[index++] = 'u';
|
|
|
|
char str[] = Integer.toHexString(c).toCharArray();
|
|
|
|
// add leading zeros, so that the length is 4
|
|
|
|
//for (int i = 0; i < 4 - str.length; i++) p2[index++] = '0';
|
|
|
|
for (int m = 0; m < 4 - str.length; m++) p2[index++] = '0';
|
|
|
|
System.arraycopy(str, 0, p2, index, str.length);
|
|
|
|
index += str.length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
program = new String(p2, 0, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if this guy has his own imports, need to remove them
|
|
|
|
// just in case it's not an advanced mode sketch
|
|
|
|
PatternMatcher matcher = new Perl5Matcher();
|
|
|
|
PatternCompiler compiler = new Perl5Compiler();
|
|
|
|
//String mess = "^\\s*(import\\s+\\S+\\s*;)";
|
2006-03-27 00:16:55 +02:00
|
|
|
//String mess = "^\\s*(import\\s+)(\\S+)(\\s*;)";
|
|
|
|
String mess = "^\\s*(#include\\s+[<\"])(\\S+)([\">]\\s*)";
|
2005-08-25 23:06:28 +02:00
|
|
|
java.util.Vector imports = new java.util.Vector();
|
|
|
|
|
|
|
|
Pattern pattern = null;
|
|
|
|
try {
|
|
|
|
pattern = compiler.compile(mess);
|
|
|
|
} catch (MalformedPatternException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
PatternMatcherInput input = new PatternMatcherInput(program);
|
|
|
|
if (!matcher.contains(input, pattern)) break;
|
|
|
|
|
|
|
|
MatchResult result = matcher.getMatch();
|
|
|
|
String piece1 = result.group(1).toString();
|
2006-03-27 00:16:55 +02:00
|
|
|
String piece2 = result.group(2).toString(); // the header file name w/o quotes
|
2005-08-25 23:06:28 +02:00
|
|
|
String piece3 = result.group(3).toString();
|
|
|
|
String piece = piece1 + piece2 + piece3;
|
|
|
|
int len = piece.length();
|
|
|
|
|
|
|
|
//imports.add(piece);
|
|
|
|
imports.add(piece2);
|
|
|
|
int idx = program.indexOf(piece);
|
|
|
|
// just remove altogether?
|
|
|
|
program = program.substring(0, idx) + program.substring(idx + len);
|
|
|
|
|
|
|
|
//System.out.println("removing " + piece);
|
|
|
|
|
|
|
|
} while (true);
|
2006-03-27 00:16:55 +02:00
|
|
|
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
extraImports = new String[imports.size()];
|
|
|
|
imports.copyInto(extraImports);
|
|
|
|
|
|
|
|
// if using opengl, add it to the special imports
|
|
|
|
/*
|
|
|
|
if (Preferences.get("renderer").equals("opengl")) {
|
|
|
|
extraImports = new String[imports.size() + 1];
|
|
|
|
imports.copyInto(extraImports);
|
|
|
|
extraImports[extraImports.length - 1] = "processing.opengl.*";
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
if (codeFolderPackages != null) {
|
|
|
|
extraImports = new String[importsCount + codeFolderPackages.length];
|
|
|
|
imports.copyInto(extraImports);
|
|
|
|
for (int i = 0; i < codeFolderPackages.length; i++) {
|
|
|
|
extraImports[importsCount + i] = codeFolderPackages[i] + ".*";
|
|
|
|
}
|
|
|
|
codeFolderImports = null;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (codeFolderPackages != null) {
|
|
|
|
codeFolderImports = new String[codeFolderPackages.length];
|
|
|
|
for (int i = 0; i < codeFolderPackages.length; i++) {
|
|
|
|
codeFolderImports[i] = codeFolderPackages[i] + ".*";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
codeFolderImports = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// do this after the program gets re-combobulated
|
|
|
|
this.programReader = new StringReader(program);
|
|
|
|
this.buildPath = buildPath;
|
2005-09-25 16:11:32 +02:00
|
|
|
|
|
|
|
// create function prototypes
|
|
|
|
mess = "^(\\w+)\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*{";
|
|
|
|
pattern = null;
|
|
|
|
try {
|
|
|
|
pattern = compiler.compile(mess);
|
|
|
|
} catch (MalformedPatternException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
PatternMatcherInput input = new PatternMatcherInput(program);
|
|
|
|
MatchResult result;
|
|
|
|
String returntype, functioname, parameterlist, prototype;
|
|
|
|
java.util.LinkedList prototypes = new java.util.LinkedList();
|
|
|
|
//System.out.println("prototypes:");
|
2006-03-26 21:12:53 +02:00
|
|
|
while(matcher.contains(input, pattern)){
|
|
|
|
result = matcher.getMatch();
|
|
|
|
//System.out.println(result);
|
|
|
|
returntype = result.group(1).toString();
|
|
|
|
functioname = result.group(2).toString();
|
|
|
|
parameterlist = result.group(3).toString().replace('\n', ' ');
|
|
|
|
prototype = returntype + " " + functioname + "(" + parameterlist + ");";
|
|
|
|
if(0 == functioname.compareTo("setup")){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(0 == functioname.compareTo("loop")){
|
|
|
|
continue;
|
2005-09-25 16:11:32 +02:00
|
|
|
}
|
2006-03-26 21:12:53 +02:00
|
|
|
prototypes.add(prototype);
|
|
|
|
//System.out.println(prototype);
|
|
|
|
}
|
2005-09-25 16:11:32 +02:00
|
|
|
// store # of prototypes so that line number reporting can be adjusted
|
|
|
|
prototypeCount = prototypes.size();
|
|
|
|
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
// create a lexer with the stream reader, and tell it to handle
|
|
|
|
// hidden tokens (eg whitespace, comments) since we want to pass these
|
|
|
|
// through so that the line numbers when the compiler reports errors
|
|
|
|
// match those that will be highlighted in the PDE IDE
|
|
|
|
//
|
2006-03-26 21:12:53 +02:00
|
|
|
//System.out.println(program);
|
2005-09-25 16:11:32 +02:00
|
|
|
WLexer lexer = new WLexer(programReader);
|
|
|
|
//lexer.setTokenObjectClass("antlr.CommonHiddenStreamToken");
|
|
|
|
lexer.setTokenObjectClass("processing.app.preproc.CToken");
|
|
|
|
lexer.initialize();
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
// create the filter for hidden tokens and specify which tokens to
|
|
|
|
// hide and which to copy to the hidden text
|
|
|
|
//
|
2005-09-25 16:11:32 +02:00
|
|
|
/*filter = new TokenStreamCopyingHiddenTokenFilter(lexer);
|
|
|
|
filter.hide(WParser.CPPComment);
|
|
|
|
filter.hide(WParser.Comment);
|
|
|
|
filter.hide(WParser.Whitespace);
|
|
|
|
filter.copy(WParser.SEMI);
|
|
|
|
filter.copy(WParser.LPAREN);
|
|
|
|
filter.copy(WParser.RPAREN);
|
|
|
|
filter.copy(WParser.LCURLY);
|
|
|
|
filter.copy(WParser.RCURLY);
|
|
|
|
filter.copy(WParser.COMMA);
|
|
|
|
filter.copy(WParser.RBRACK);
|
|
|
|
filter.copy(WParser.LBRACK);
|
|
|
|
filter.copy(WParser.COLON);
|
|
|
|
*/
|
2005-08-25 23:06:28 +02:00
|
|
|
// create a parser and set what sort of AST should be generated
|
|
|
|
//
|
2005-09-25 16:11:32 +02:00
|
|
|
//PdeRecognizer parser = new PdeRecognizer(filter);
|
|
|
|
WParser parser = new WParser(lexer);
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
// use our extended AST class
|
|
|
|
//
|
2005-09-25 16:11:32 +02:00
|
|
|
//parser.setASTNodeClass("antlr.ExtendedCommonASTWithHiddenTokens");
|
|
|
|
parser.setASTNodeType(TNode.class.getName());
|
|
|
|
TNode.setTokenVocabulary("processing.app.preproc.WTokenTypes");
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
// start parsing at the compilationUnit non-terminal
|
|
|
|
//
|
2005-09-25 16:11:32 +02:00
|
|
|
//parser.pdeProgram();
|
2006-02-24 16:52:58 +01:00
|
|
|
//parser.translationUnit();
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
// set up the AST for traversal by PdeEmitter
|
|
|
|
//
|
|
|
|
ASTFactory factory = new ASTFactory();
|
|
|
|
AST parserAST = parser.getAST();
|
|
|
|
AST rootNode = factory.create(ROOT_ID, "AST ROOT");
|
|
|
|
rootNode.setFirstChild(parserAST);
|
|
|
|
|
|
|
|
// unclear if this actually works, but it's worth a shot
|
|
|
|
//
|
|
|
|
//((CommonAST)parserAST).setVerboseStringConversion(
|
|
|
|
// true, parser.getTokenNames());
|
|
|
|
// (made to use the static version because of jikes 1.22 warning)
|
|
|
|
CommonAST.setVerboseStringConversion(true, parser.getTokenNames());
|
|
|
|
|
|
|
|
// if this is an advanced program, the classname is already defined.
|
|
|
|
//
|
|
|
|
if (programType == JAVA) {
|
|
|
|
name = getFirstClassName(parserAST);
|
|
|
|
}
|
|
|
|
|
|
|
|
// if 'null' was passed in for the name, but this isn't
|
|
|
|
// a 'java' mode class, then there's a problem, so punt.
|
|
|
|
//
|
|
|
|
if (name == null) return null;
|
|
|
|
|
|
|
|
// output the code
|
|
|
|
//
|
2005-09-25 16:11:32 +02:00
|
|
|
WEmitter emitter = new WEmitter(lexer.getPreprocessorInfoChannel());
|
2006-02-24 16:52:58 +01:00
|
|
|
File streamFile = new File(buildPath, name + ".cpp");
|
2005-08-25 23:06:28 +02:00
|
|
|
PrintStream stream = new PrintStream(new FileOutputStream(streamFile));
|
|
|
|
|
|
|
|
//writeHeader(stream, extraImports, name);
|
2005-09-25 16:11:32 +02:00
|
|
|
writeHeader(stream, name, prototypes);
|
2006-02-24 16:52:58 +01:00
|
|
|
//added to write the pde code to the cpp file
|
|
|
|
writeProgram(stream, name, program);
|
2005-09-25 16:11:32 +02:00
|
|
|
emitter.setASTNodeType(TNode.class.getName());
|
2005-08-25 23:06:28 +02:00
|
|
|
emitter.setOut(stream);
|
2006-02-24 16:52:58 +01:00
|
|
|
//emitter.printDeclarations(rootNode);
|
2005-09-25 16:11:32 +02:00
|
|
|
//emitter.print(rootNode);
|
2006-02-24 16:52:58 +01:00
|
|
|
//emitter.translationUnit(parser.getAST());
|
2005-08-25 23:06:28 +02:00
|
|
|
|
2007-01-12 18:58:39 +01:00
|
|
|
writeFooter(stream, target);
|
2005-08-25 23:06:28 +02:00
|
|
|
stream.close();
|
|
|
|
|
|
|
|
// if desired, serialize the parse tree to an XML file. can
|
|
|
|
// be viewed usefully with Mozilla or IE
|
|
|
|
|
|
|
|
if (Preferences.getBoolean("preproc.output_parse_tree")) {
|
|
|
|
|
|
|
|
stream = new PrintStream(new FileOutputStream("parseTree.xml"));
|
|
|
|
stream.println("<?xml version=\"1.0\"?>");
|
|
|
|
stream.println("<document>");
|
|
|
|
OutputStreamWriter writer = new OutputStreamWriter(stream);
|
|
|
|
if (parserAST != null) {
|
|
|
|
((CommonAST)parserAST).xmlSerialize(writer);
|
|
|
|
}
|
|
|
|
writer.flush();
|
|
|
|
stream.println("</document>");
|
|
|
|
writer.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2006-02-24 16:52:58 +01:00
|
|
|
// Write the pde program to the cpp file
|
|
|
|
void writeProgram(PrintStream out, String className, String program) {
|
|
|
|
out.print(program);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-25 23:06:28 +02:00
|
|
|
/**
|
|
|
|
* Write any required header material (eg imports, class decl stuff)
|
|
|
|
*
|
|
|
|
* @param out PrintStream to write it to.
|
|
|
|
* @param exporting Is this being exported from PDE?
|
|
|
|
* @param name Name of the class being created.
|
|
|
|
*/
|
2006-03-27 00:16:55 +02:00
|
|
|
void writeHeader(PrintStream out, String className, java.util.LinkedList prototypes)
|
|
|
|
throws IOException {
|
2005-09-25 16:11:32 +02:00
|
|
|
out.print("#include \"WProgram.h\"\n");
|
2006-03-27 00:16:55 +02:00
|
|
|
/* Arduino doesn't automatically use all available libraries.
|
2006-03-26 21:12:53 +02:00
|
|
|
// print library headers
|
|
|
|
LibraryManager libraryManager = new LibraryManager();
|
|
|
|
String[] headerFiles = libraryManager.getHeaderFiles();
|
|
|
|
for(int i = 0; i < headerFiles.length; ++i){
|
|
|
|
out.print("#include \"" + headerFiles[i] + "\"\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
// record number of header lines written for error line adjustment
|
|
|
|
headerCount = headerFiles.length;
|
2006-03-27 00:16:55 +02:00
|
|
|
*/
|
2005-09-25 16:11:32 +02:00
|
|
|
// print user defined prototypes
|
|
|
|
while(0 < prototypes.size()){
|
|
|
|
out.print(prototypes.removeFirst() + "\n");
|
|
|
|
}
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
// emit emports that are needed for classes from the code folder
|
|
|
|
if (extraImports != null) {
|
|
|
|
for (int i = 0; i < extraImports.length; i++) {
|
2005-09-25 16:11:32 +02:00
|
|
|
out.print("#include \"" + extraImports[i] + "\"\n");
|
2005-08-25 23:06:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (codeFolderImports != null) {
|
|
|
|
for (int i = 0; i < codeFolderImports.length; i++) {
|
|
|
|
out.print("import " + codeFolderImports[i] + "; ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// emit standard imports (read from pde.properties)
|
|
|
|
// for each language level that's being used.
|
2005-09-25 16:11:32 +02:00
|
|
|
/* String jdkVersionStr = Preferences.get("preproc.jdk_version");
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
int jdkVersion = JDK11; // default
|
|
|
|
if (jdkVersionStr.equals("1.3")) { jdkVersion = JDK13; };
|
|
|
|
if (jdkVersionStr.equals("1.4")) { jdkVersion = JDK14; };
|
|
|
|
|
|
|
|
for (int i = 0; i <= jdkVersion; i++) {
|
|
|
|
for (int j = 0; j < defaultImports[i].length; j++) {
|
|
|
|
out.print("import " + defaultImports[i][j] + ".*; ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//boolean opengl = Preferences.get("renderer").equals("opengl");
|
|
|
|
//if (opengl) {
|
|
|
|
//out.println("import processing.opengl.*; ");
|
|
|
|
//}
|
2005-09-25 16:11:32 +02:00
|
|
|
*/
|
|
|
|
/* if (programType < JAVA) {
|
2005-08-25 23:06:28 +02:00
|
|
|
// open the class definition
|
|
|
|
out.print("public class " + className + " extends ");
|
|
|
|
//if (opengl) {
|
|
|
|
//out.print("PAppletGL");
|
|
|
|
//} else {
|
|
|
|
out.print("PApplet");
|
|
|
|
//}
|
|
|
|
out.print(" {");
|
|
|
|
|
|
|
|
if (programType == STATIC) {
|
|
|
|
// now that size() and background() can go inside of draw()
|
|
|
|
// actually, use setup(), because when running externally
|
|
|
|
// the applet size needs to be set before the window is drawn,
|
|
|
|
// meaning that after setup() things need to be ducky.
|
|
|
|
//out.print("public void draw() {");
|
|
|
|
out.print("public void setup() {");
|
|
|
|
}
|
|
|
|
}
|
2005-09-25 16:11:32 +02:00
|
|
|
*/ }
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Write any necessary closing text.
|
|
|
|
*
|
|
|
|
* @param out PrintStream to write it to.
|
|
|
|
*/
|
2007-01-12 18:58:39 +01:00
|
|
|
void writeFooter(PrintStream out, Target target) throws java.lang.Exception {
|
|
|
|
// Open the file main.cxx and copy its entire contents to the bottom of the
|
|
|
|
// generated sketch .cpp file...
|
2005-08-25 23:06:28 +02:00
|
|
|
|
2007-01-12 18:58:39 +01:00
|
|
|
String mainFileName = target.getPath() + File.separator + "main.cxx";
|
|
|
|
FileReader reader = null;
|
|
|
|
reader = new FileReader(mainFileName);
|
|
|
|
|
|
|
|
LineNumberReader mainfile = new LineNumberReader(reader);
|
2005-08-25 23:06:28 +02:00
|
|
|
|
2007-01-12 18:58:39 +01:00
|
|
|
String line;
|
|
|
|
while ((line = mainfile.readLine()) != null) {
|
|
|
|
out.print(line + "\n");
|
2005-08-25 23:06:28 +02:00
|
|
|
}
|
2007-01-12 18:58:39 +01:00
|
|
|
|
|
|
|
mainfile.close();
|
|
|
|
}
|
2005-08-25 23:06:28 +02:00
|
|
|
|
|
|
|
|
|
|
|
static String advClassName = "";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find the first CLASS_DEF node in the tree, and return the name of the
|
|
|
|
* class in question.
|
|
|
|
*
|
|
|
|
* XXXdmose right now, we're using a little hack to the grammar to get
|
|
|
|
* this info. In fact, we should be descending the AST passed in.
|
|
|
|
*/
|
|
|
|
String getFirstClassName(AST ast) {
|
|
|
|
|
|
|
|
String t = advClassName;
|
|
|
|
advClassName = "";
|
|
|
|
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|