Manipulable AST

View: New views
15 Messages — Rating Filter:   Alert me  

Manipulable AST

by Matt Fowles :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

All~

On the path towards porting my current AST to Janino, I discovered the
need for StatementLists.

StatementLists provide a way to put a place holder statement
somewhere, and then fill it in later with only things that are needed.
 The big difference between this and a block is that it very
explicitly does not introduce a new scope, so that it can be used to
inject variables that will be visible.

This patch also adds `SimpleCompiler.cook(CompilationUnit)` which
allows the user to directly cook an AST that they have generated by
hand.

Both of these things are tested in the new `AstTests.java` that is
included in this test.

If you would like me to make any clean ups or sign any copyright
declarations before this work can be included in Janino, I would be
very happy to.

Enjoy,
Matt

[statementlist.patch]

==== Patch <statementlist> level 1
Source: 1adc4bfb-2c32-0410-81b9-bf0f0eac59bd:/janino-stmt-container:72685
Target: eb4544d6-894b-0410-9319-a9612837a279:/trunk/janino:332
        (http://svn.codehaus.org/janino)
Log:
 r72684@spiceweasel:  fowles | 2008-04-30 10:51:04 -0400
 creating a local branch for statement container work
 
 r72685@spiceweasel:  fowles | 2008-04-30 11:00:16 -0400
 Add support for StatementList and tests
 

=== tests/src/AstTests.java
==================================================================
--- tests/src/AstTests.java (revision 332)
+++ tests/src/AstTests.java (patch statementlist level 1)
@@ -0,0 +1,278 @@
+
+/*
+ * Janino - An embedded Java[TM] compiler
+ *
+ * Copyright (c) 2001-2007, Arno Unkrig
+ * All rights reserved.
+ *
+ * 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.
+ *    3. The name of the author may not be used to endorse or promote
+ *       products derived from this software without specific prior
+ *       written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.codehaus.janino.CompileException;
+import org.codehaus.janino.Java;
+import org.codehaus.janino.Location;
+import org.codehaus.janino.Mod;
+import org.codehaus.janino.SimpleCompiler;
+import org.codehaus.janino.Java.AmbiguousName;
+import org.codehaus.janino.Java.BasicType;
+import org.codehaus.janino.Java.Block;
+import org.codehaus.janino.Java.CompilationUnit;
+import org.codehaus.janino.Java.Literal;
+import org.codehaus.janino.Java.LocalVariableDeclarationStatement;
+import org.codehaus.janino.Java.MethodDeclarator;
+import org.codehaus.janino.Java.PackageMemberClassDeclaration;
+import org.codehaus.janino.Java.ReturnStatement;
+import org.codehaus.janino.Java.StatementList;
+import org.codehaus.janino.Java.Type;
+import org.codehaus.janino.Java.FunctionDeclarator.FormalParameter;
+import org.codehaus.janino.Parser.ParseException;
+import org.codehaus.janino.Scanner.ScanException;
+
+public class AstTests extends TestCase {
+
+    public static interface Evalable {
+        int eval(int a);
+    }
+    
+    public static Test suite() {
+        TestSuite s = new TestSuite(AstTests.class.getName());
+        s.addTest(new AstTests("testSimpleAst"));
+        s.addTest(new AstTests("testLocalVariable"));
+        s.addTest(new AstTests("testBlock"));
+        s.addTest(new AstTests("testStatementList"));
+        return s;
+    }
+
+    private static Object compileAndEval(CompilationUnit cu) throws CompileException,
+            ParseException, ScanException, IOException, ClassNotFoundException,
+            InstantiationException, IllegalAccessException,
+            NoSuchMethodException, InvocationTargetException {
+        SimpleCompiler compiler = new SimpleCompiler();
+        compiler.cook(cu);
+        
+        ClassLoader loader = compiler.getClassLoader();
+        
+        Class handMadeClass = loader.loadClass("HandMade");
+        
+        Object handMade = handMadeClass.newInstance();
+        Method calc = handMadeClass.getMethod("calculate", null);
+        Object res = calc.invoke(handMade, null);
+        return res;
+    }
+    
+    private static PackageMemberClassDeclaration createClass(CompilationUnit cu)
+            throws ParseException {
+        PackageMemberClassDeclaration clazz = new PackageMemberClassDeclaration(
+                getLocation(),
+                null,
+                Mod.PUBLIC,
+                "HandMade",
+                null,
+                new Type[]{}
+        );
+        cu.addPackageMemberTypeDeclaration(clazz);
+        return clazz;
+    };
+    
+    private static Type createDoubleType() {
+        return new BasicType(getLocation(), BasicType.DOUBLE);
+    }
+    
+    private static Literal createLiteral(double d) {
+        return new Literal( getLocation(), Double.valueOf(d) );
+    }
+    
+    
+    private static void createMethod(PackageMemberClassDeclaration clazz, Block body) {
+        MethodDeclarator method = new MethodDeclarator(
+                getLocation(),
+                null,
+                (short)(Mod.PUBLIC),
+                createDoubleType(),
+                "calculate",
+                new FormalParameter[0],
+                new Type[0],
+                body
+        );
+        clazz.addDeclaredMethod(method);
+    }
+    
+    private static LocalVariableDeclarationStatement createVarDecl(String name, double value) {
+        return new Java.LocalVariableDeclarationStatement(
+                getLocation(),
+                (short)0,
+                createDoubleType(),
+                new Java.VariableDeclarator[] {
+                    new Java.VariableDeclarator(
+                            getLocation(),
+                            name,
+                            0,
+                            createLiteral(value)
+                    )
+                }
+        );
+    }
+        
+
+    private static AmbiguousName createVariableRef(String name) {
+        return new Java.AmbiguousName(
+                getLocation(),
+                new String[] { name }
+        );
+    }
+    
+    /**
+     * "Clever" method to get a location from a stack trace
+     */
+    static private Location getLocation() {
+        Exception e = new Exception();
+        StackTraceElement ste = e.getStackTrace()[1];//we only care about our caller
+        return new Location(
+                ste.getFileName(),
+                (short)ste.getLineNumber(),
+                (short)0
+        );
+    }
+
+    public AstTests(String name) { super(name); }
+
+    public void testSimpleAst() throws Exception {
+        CompilationUnit cu = new CompilationUnit("AstTests.java");
+        
+        PackageMemberClassDeclaration clazz = createClass(cu);
+        
+        Block body = new Block(getLocation());
+        body.addStatement(
+                new ReturnStatement(
+                        getLocation(),
+                        createLiteral(3.0)
+                )
+        );
+        
+        createMethod(clazz, body);
+        
+        Object res = compileAndEval(cu);
+        assertEquals(Double.valueOf(3.0), res);
+    }
+    
+    public void testLocalVariable() throws Exception {
+        CompilationUnit cu = new CompilationUnit("AstTests.java");
+        
+        PackageMemberClassDeclaration clazz = createClass(cu);
+        
+        Block body = new Block(getLocation());
+        body.addStatement( createVarDecl("x", 2.0) );                        
+        body.addStatement(
+                new ReturnStatement(
+                        getLocation(),
+                        new Java.BinaryOperation(
+                                getLocation(),
+                                createVariableRef("x"),
+                                "*",
+                                createLiteral(3)
+                        )
+                )
+        );
+        
+        createMethod(clazz, body);
+        
+        Object res = compileAndEval(cu);
+        assertTrue(res instanceof Double);
+        assertEquals(Double.valueOf(6.0), res);
+    }
+
+    public void testBlock() throws Exception {
+        CompilationUnit cu = new CompilationUnit("AstTests.java");
+        
+        PackageMemberClassDeclaration clazz = createClass(cu);
+        
+        Block body = new Block(getLocation());
+        
+        Block sub = new Block(getLocation());
+        sub.addStatement( createVarDecl("x", 2.0) );                        
+        
+        body.addStatement(sub);
+        body.addStatement(
+                new ReturnStatement(
+                        getLocation(),
+                        new Java.BinaryOperation(
+                                getLocation(),
+                                createVariableRef("x"),
+                                "*",
+                                createLiteral(3)
+                        )
+                )
+        );
+        
+        createMethod(clazz, body);
+        
+        try {
+            compileAndEval(cu);
+            fail("Block must limit the scope of variables in it");
+        } catch(CompileException ex) {
+            assertTrue(ex.getMessage().endsWith("Expression \"x\" is not an rvalue"));
+        }
+    }
+
+    public void testStatementList() throws Exception {
+        CompilationUnit cu = new CompilationUnit("AstTests.java");
+        
+        PackageMemberClassDeclaration clazz = createClass(cu);
+        
+        Block body = new Block(getLocation());
+        
+        StatementList sub = new StatementList(getLocation());
+        sub.addStatement( createVarDecl("x", 3.0) );                        
+        body.addStatement(sub);
+        body.addStatement(
+                new ReturnStatement(
+                        getLocation(),
+                        new Java.BinaryOperation(
+                                getLocation(),
+                                createVariableRef("x"),
+                                "*",
+                                createLiteral(3)
+                        )
+                )
+        );
+        
+        createMethod(clazz, body);
+        
+        Object res = compileAndEval(cu);
+        assertTrue(res instanceof Double);
+        assertEquals(Double.valueOf(9.0), res);
+    }
+    
+}
=== tests/src/AllTests.java
==================================================================
--- tests/src/AllTests.java (revision 332)
+++ tests/src/AllTests.java (patch statementlist level 1)
@@ -82,5 +82,6 @@
         this.addTest(ReportedBugs.suite());
         this.addTest(SandboxTests.suite());
         this.addTest(EvaluatorTests.suite());
+        this.addTest(AstTests.suite());
     }
 }
=== src/org/codehaus/janino/UnitCompiler.java
==================================================================
--- src/org/codehaus/janino/UnitCompiler.java (revision 332)
+++ src/org/codehaus/janino/UnitCompiler.java (patch statementlist level 1)
@@ -5467,6 +5467,27 @@
         // 6.5.2.BL1.B1.B7 Package name
         return new Java.Package(location, identifier);
     }
+    
+    /**
+     * Check to see if a local variable was declared in this statement.  Possibly recursing into a StatementList, as needed.
+     * @param varName  The name of the variable to find
+     * @param stmt     The statement in question
+     * @return         A local variable definition if found.  null if not found
+     * @throws CompileException
+     */
+    private Java.LocalVariable findLocalVariableInStatement(Java.BlockStatement stmt, String varName) throws CompileException {
+        if (stmt instanceof Java.LocalVariableDeclarationStatement) {
+            return this.findLocalVariable((Java.LocalVariableDeclarationStatement)stmt, varName);
+        }
+        if (stmt instanceof Java.StatementList) {
+            Java.StatementList sl = (Java.StatementList)stmt;
+            for (Iterator it = sl.statements.iterator();;) {
+                Java.LocalVariable lv = findLocalVariableInStatement((Java.BlockStatement)it.next(), varName);
+                if (lv != null) return lv;
+            }
+        }
+        return null;
+    }
 
     /**
      * Find a local variable declared by the given <code>blockStatement</code> or any enclosing
@@ -5481,19 +5502,15 @@
             {
                 if (s instanceof Java.ForStatement) {
                     Java.BlockStatement optionalForInit = ((Java.ForStatement) s).optionalInit;
-                    if (optionalForInit instanceof Java.LocalVariableDeclarationStatement) {
-                        Java.LocalVariable lv = this.findLocalVariable((Java.LocalVariableDeclarationStatement) optionalForInit, name);
-                        if (lv != null) return lv;
-                    }
+                    Java.LocalVariable lv = this.findLocalVariableInStatement(optionalForInit, name);
+                    if (lv != null) return lv;
                 }
                 if (es instanceof Java.Block) {
                     Java.Block b = (Java.Block) es;
                     for (Iterator it = b.statements.iterator();;) {
                         Java.BlockStatement bs2 = (Java.BlockStatement) it.next();
-                        if (bs2 instanceof Java.LocalVariableDeclarationStatement) {
-                            Java.LocalVariable lv = this.findLocalVariable((Java.LocalVariableDeclarationStatement) bs2, name);
-                            if (lv != null) return lv;
-                        }
+                        Java.LocalVariable lv = this.findLocalVariableInStatement(bs2, name);
+                        if (lv != null) return lv;
                         if (bs2 == s) break;
                     }
                 }
@@ -5503,10 +5520,8 @@
                         Java.SwitchStatement.SwitchBlockStatementGroup sbgs = (Java.SwitchStatement.SwitchBlockStatementGroup) it2.next();
                         for (Iterator it = sbgs.blockStatements.iterator(); it.hasNext();) {
                             Java.BlockStatement bs2 = (Java.BlockStatement) it.next();
-                            if (bs2 instanceof Java.LocalVariableDeclarationStatement) {
-                                Java.LocalVariable lv = this.findLocalVariable((Java.LocalVariableDeclarationStatement) bs2, name);
-                                if (lv != null) return lv;
-                            }
+                            Java.LocalVariable lv = this.findLocalVariableInStatement(bs2, name);
+                            if (lv != null) return lv;
                             if (bs2 == s) break SBSGS;
                         }
                     }
=== src/org/codehaus/janino/Java.java
==================================================================
--- src/org/codehaus/janino/Java.java (revision 332)
+++ src/org/codehaus/janino/Java.java (patch statementlist level 1)
@@ -1230,7 +1230,56 @@
 
         public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitBlock(this); }
     }
+    
+    /**
+     * This is similar to a {@link Java.Block} except that it does not create a scope around it statements.
+     * It is useful for programmatically manipulating an AST
+     */
+    public final static class StatementList extends Statement {
+        public final List statements = new ArrayList(); // BlockStatement
 
+        public StatementList(Location location) {
+            super(location);
+        }
+
+        public void addStatement(BlockStatement statement) {
+            this.statements.add(statement);
+            statement.setEnclosingScope(this.getEnclosingScope());
+        }
+        
+        public void addStatements(
+            List statements // BlockStatement
+        ) {
+            Iterator stmtIter = statements.iterator();
+            while(stmtIter.hasNext()) {
+                addStatement((BlockStatement)stmtIter.next());
+            }
+        }
+        
+        public BlockStatement[] getStatements() {
+            return (BlockStatement[]) this.statements.toArray(new BlockStatement[this.statements.size()]);
+        }
+        
+        // set children to share this object's enclosing scope
+        public void setEnclosingScope(Scope enclosingScope) {
+            super.setEnclosingScope(enclosingScope);
+            Iterator stmtIter = this.statements.iterator();
+            while(stmtIter.hasNext()) {
+                BlockStatement stmt = (BlockStatement)stmtIter.next();
+                stmt.setEnclosingScope(enclosingScope);
+            }
+        }
+
+        // Compile time members.
+        public final void accept(Visitor.BlockStatementVisitor visitor) {
+            Iterator stmtIter = this.statements.iterator();
+            while(stmtIter.hasNext()) {
+                BlockStatement stmt = (BlockStatement)stmtIter.next();
+                stmt.accept(visitor);
+            }
+        }
+    }
+
     /**
      * Base class for statements that can be terminated abnormally with a
      * "break" statement.
=== src/org/codehaus/janino/SimpleCompiler.java
==================================================================
--- src/org/codehaus/janino/SimpleCompiler.java (revision 332)
+++ src/org/codehaus/janino/SimpleCompiler.java (patch statementlist level 1)
@@ -201,7 +201,7 @@
     public static final ClassLoader BOOT_CLASS_LOADER = new ClassLoader(null) {};
 
     /**
-     * Allowe references to the classes loaded through this parent class loader
+     * Allow references to the classes loaded through this parent class loader
      * (@see {@link #setParentClassLoader(ClassLoader)}), plus the extra
      * <code>auxiliaryClasses</code>.
      * <p>
@@ -233,7 +233,22 @@
             DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION
         );
     }
+    
+    /**
+     * Cook this compilation unit directly.
+     *  See {@link Cookable.cook}
+     */
+    public void cook(Java.CompilationUnit compilationUnit)
+    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
+        this.setUpClassLoaders();
 
+        // Compile the classes and load them.
+        this.compileToClassLoader(
+            compilationUnit,
+            DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION
+        );
+    }
+
     /**
      * Initializes {@link #classLoader} and {@link #iClassLoader} from the configured
      * {@link #parentClassLoader} and {@link #optionalAuxiliaryClasses}. These are needed by

==== BEGIN SVK PATCH BLOCK ====
Version: svk v2.0.2 (linux)

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
Zg==
==== END SVK PATCH BLOCK ====


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Re: Manipulable AST

by Matt Fowles :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

All~

The attached patch supersedes my last one and also include a test and
fix for the statement

return new byte[]{ (byte)1 };

which fails in `UnitCompiler.getType2` because of a missing case.

Once again, any pointers on things I can do to speed the inclusion of
patches into Janino would be greatly appreciated.

Matt

On Wed, Apr 30, 2008 at 11:13 AM, Matt Fowles <matt.fowles@...> wrote:

> All~
>
>  On the path towards porting my current AST to Janino, I discovered the
>  need for StatementLists.
>
>  StatementLists provide a way to put a place holder statement
>  somewhere, and then fill it in later with only things that are needed.
>   The big difference between this and a block is that it very
>  explicitly does not introduce a new scope, so that it can be used to
>  inject variables that will be visible.
>
>  This patch also adds `SimpleCompiler.cook(CompilationUnit)` which
>  allows the user to directly cook an AST that they have generated by
>  hand.
>
>  Both of these things are tested in the new `AstTests.java` that is
>  included in this test.
>
>  If you would like me to make any clean ups or sign any copyright
>  declarations before this work can be included in Janino, I would be
>  very happy to.
>
>  Enjoy,
>  Matt
>

[statementlist.patch]

==== Patch <statementlist> level 2
Source: 1adc4bfb-2c32-0410-81b9-bf0f0eac59bd:/janino-stmt-container:72835
Target: eb4544d6-894b-0410-9319-a9612837a279:/trunk/janino:332
        (http://svn.codehaus.org/janino)
Log:
 r72684@spiceweasel:  fowles | 2008-04-30 10:51:04 -0400
 creating a local branch for statement container work
 
 r72685@spiceweasel:  fowles | 2008-04-30 11:00:16 -0400
 Add support for StatementList and tests
 
 r72834@spiceweasel:  fowles | 2008-05-01 17:23:02 -0400
 comment out assertions since they are not valid in Java 1.2
 
 r72835@spiceweasel:  fowles | 2008-05-01 17:23:27 -0400
 Fix byte[] literals for ArrayInitiliazations
 

=== tests/src/AstTests.java
==================================================================
--- tests/src/AstTests.java (revision 332)
+++ tests/src/AstTests.java (patch statementlist level 2)
@@ -0,0 +1,323 @@
+
+/*
+ * Janino - An embedded Java[TM] compiler
+ *
+ * Copyright (c) 2001-2007, Arno Unkrig
+ * All rights reserved.
+ *
+ * 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.
+ *    3. The name of the author may not be used to endorse or promote
+ *       products derived from this software without specific prior
+ *       written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.codehaus.janino.CompileException;
+import org.codehaus.janino.Java;
+import org.codehaus.janino.Location;
+import org.codehaus.janino.Mod;
+import org.codehaus.janino.SimpleCompiler;
+import org.codehaus.janino.Java.AmbiguousName;
+import org.codehaus.janino.Java.ArrayType;
+import org.codehaus.janino.Java.BasicType;
+import org.codehaus.janino.Java.Block;
+import org.codehaus.janino.Java.CompilationUnit;
+import org.codehaus.janino.Java.Literal;
+import org.codehaus.janino.Java.LocalVariableDeclarationStatement;
+import org.codehaus.janino.Java.MethodDeclarator;
+import org.codehaus.janino.Java.PackageMemberClassDeclaration;
+import org.codehaus.janino.Java.ReturnStatement;
+import org.codehaus.janino.Java.StatementList;
+import org.codehaus.janino.Java.Type;
+import org.codehaus.janino.Java.FunctionDeclarator.FormalParameter;
+import org.codehaus.janino.Parser.ParseException;
+import org.codehaus.janino.Scanner.ScanException;
+
+public class AstTests extends TestCase {
+
+    public static interface Evalable {
+        int eval(int a);
+    }
+    
+    public static Test suite() {
+        TestSuite s = new TestSuite(AstTests.class.getName());
+        s.addTest(new AstTests("testSimpleAst"));
+        s.addTest(new AstTests("testLocalVariable"));
+        s.addTest(new AstTests("testBlock"));
+        s.addTest(new AstTests("testStatementList"));
+        s.addTest(new AstTests("testByteArrayLiteral"));
+        return s;
+    }
+
+    private static Object compileAndEval(CompilationUnit cu) throws CompileException,
+            ParseException, ScanException, IOException, ClassNotFoundException,
+            InstantiationException, IllegalAccessException,
+            NoSuchMethodException, InvocationTargetException {
+        SimpleCompiler compiler = new SimpleCompiler();
+        compiler.cook(cu);
+        
+        ClassLoader loader = compiler.getClassLoader();
+        
+        Class handMadeClass = loader.loadClass("HandMade");
+        
+        Object handMade = handMadeClass.newInstance();
+        Method calc = handMadeClass.getMethod("calculate", null);
+        Object res = calc.invoke(handMade, null);
+        return res;
+    }
+    
+    private static ArrayType createByteArrayType() {
+        return new Java.ArrayType(
+                new Java.BasicType(
+                        getLocation(),
+                        Java.BasicType.BYTE
+                )
+        );
+    };
+    
+    private static PackageMemberClassDeclaration createClass(CompilationUnit cu)
+            throws ParseException {
+        PackageMemberClassDeclaration clazz = new PackageMemberClassDeclaration(
+                getLocation(),
+                null,
+                Mod.PUBLIC,
+                "HandMade",
+                null,
+                new Type[]{}
+        );
+        cu.addPackageMemberTypeDeclaration(clazz);
+        return clazz;
+    }
+    
+    private static Type createDoubleType() {
+        return new BasicType(getLocation(), BasicType.DOUBLE);
+    }
+    
+    private static Literal createLiteral(double d) {
+        return createLiteral(Double.valueOf(d));
+    }
+    
+    
+    private static Literal createLiteral(Object o) {
+        return new Literal( getLocation(), o );
+    }
+    
+    private static void createMethod(PackageMemberClassDeclaration clazz, Block body, Type returnType) {
+        MethodDeclarator method = new MethodDeclarator(
+                getLocation(),
+                null,
+                (short)(Mod.PUBLIC),
+                returnType,
+                "calculate",
+                new FormalParameter[0],
+                new Type[0],
+                body
+        );
+        clazz.addDeclaredMethod(method);
+    }
+        
+
+    private static LocalVariableDeclarationStatement createVarDecl(String name, double value) {
+        return new Java.LocalVariableDeclarationStatement(
+                getLocation(),
+                (short)0,
+                createDoubleType(),
+                new Java.VariableDeclarator[] {
+                    new Java.VariableDeclarator(
+                            getLocation(),
+                            name,
+                            0,
+                            createLiteral(value)
+                    )
+                }
+        );
+    }
+    
+    private static AmbiguousName createVariableRef(String name) {
+        return new Java.AmbiguousName(
+                getLocation(),
+                new String[] { name }
+        );
+    }
+
+    /**
+     * "Clever" method to get a location from a stack trace
+     */
+    static private Location getLocation() {
+        Exception e = new Exception();
+        StackTraceElement ste = e.getStackTrace()[1];//we only care about our caller
+        return new Location(
+                ste.getFileName(),
+                (short)ste.getLineNumber(),
+                (short)0
+        );
+    }
+
+    public AstTests(String name) { super(name); }
+    
+    public void testBlock() throws Exception {
+        CompilationUnit cu = new CompilationUnit("AstTests.java");
+        
+        PackageMemberClassDeclaration clazz = createClass(cu);
+        
+        Block body = new Block(getLocation());
+        
+        Block sub = new Block(getLocation());
+        sub.addStatement( createVarDecl("x", 2.0) );                        
+        
+        body.addStatement(sub);
+        body.addStatement(
+                new ReturnStatement(
+                        getLocation(),
+                        new Java.BinaryOperation(
+                                getLocation(),
+                                createVariableRef("x"),
+                                "*",
+                                createLiteral(3)
+                        )
+                )
+        );
+        
+        createMethod(clazz, body, createDoubleType());
+        
+        try {
+            compileAndEval(cu);
+            fail("Block must limit the scope of variables in it");
+        } catch(CompileException ex) {
+            assertTrue(ex.getMessage().endsWith("Expression \"x\" is not an rvalue"));
+        }
+    }
+
+    public void testByteArrayLiteral() throws Exception {
+        CompilationUnit cu = new CompilationUnit("AstTests.java");
+        
+        PackageMemberClassDeclaration clazz = createClass(cu);
+        
+        Byte exp = Byte.valueOf((byte)1);
+        Block body = new Block(getLocation());
+        body.addStatement(
+                new ReturnStatement(
+                        getLocation(),
+                        new Java.NewInitializedArray(
+                                getLocation(),
+                                createByteArrayType(),
+                                new Java.ArrayInitializer(
+                                        getLocation(),
+                                        new Java.Rvalue[] {
+                                            createLiteral(exp)
+                                        }
+                                )
+                        )
+                )
+        );
+        
+        createMethod(clazz, body,
+                createByteArrayType()
+        );
+        
+        Object res = compileAndEval(cu);
+        assertEquals(exp.byteValue(), ((byte[])res)[0]);
+    }
+
+    public void testLocalVariable() throws Exception {
+        CompilationUnit cu = new CompilationUnit("AstTests.java");
+        
+        PackageMemberClassDeclaration clazz = createClass(cu);
+        
+        Block body = new Block(getLocation());
+        body.addStatement( createVarDecl("x", 2.0) );                        
+        body.addStatement(
+                new ReturnStatement(
+                        getLocation(),
+                        new Java.BinaryOperation(
+                                getLocation(),
+                                createVariableRef("x"),
+                                "*",
+                                createLiteral(3)
+                        )
+                )
+        );
+        
+        createMethod(clazz, body, createDoubleType());
+        
+        Object res = compileAndEval(cu);
+        assertTrue(res instanceof Double);
+        assertEquals(Double.valueOf(6.0), res);
+    }
+    
+    public void testSimpleAst() throws Exception {
+        CompilationUnit cu = new CompilationUnit("AstTests.java");
+        
+        PackageMemberClassDeclaration clazz = createClass(cu);
+        
+        Block body = new Block(getLocation());
+        body.addStatement(
+                new ReturnStatement(
+                        getLocation(),
+                        createLiteral(3.0)
+                )
+        );
+        
+        createMethod(clazz, body, createDoubleType());
+        
+        Object res = compileAndEval(cu);
+        assertEquals(Double.valueOf(3.0), res);
+    }
+
+    public void testStatementList() throws Exception {
+        CompilationUnit cu = new CompilationUnit("AstTests.java");
+        
+        PackageMemberClassDeclaration clazz = createClass(cu);
+        
+        Block body = new Block(getLocation());
+        
+        StatementList sub = new StatementList(getLocation());
+        sub.addStatement( createVarDecl("x", 3.0) );                        
+        body.addStatement(sub);
+        body.addStatement(
+                new ReturnStatement(
+                        getLocation(),
+                        new Java.BinaryOperation(
+                                getLocation(),
+                                createVariableRef("x"),
+                                "*",
+                                createLiteral(3)
+                        )
+                )
+        );
+        
+        createMethod(clazz, body, createDoubleType());
+        
+        Object res = compileAndEval(cu);
+        assertTrue(res instanceof Double);
+        assertEquals(Double.valueOf(9.0), res);
+    }
+}
=== tests/src/AllTests.java
==================================================================
--- tests/src/AllTests.java (revision 332)
+++ tests/src/AllTests.java (patch statementlist level 2)
@@ -82,5 +82,6 @@
         this.addTest(ReportedBugs.suite());
         this.addTest(SandboxTests.suite());
         this.addTest(EvaluatorTests.suite());
+        this.addTest(AstTests.suite());
     }
 }
=== src/org/codehaus/janino/UnitCompiler.java
==================================================================
--- src/org/codehaus/janino/UnitCompiler.java (revision 332)
+++ src/org/codehaus/janino/UnitCompiler.java (patch statementlist level 2)
@@ -4150,6 +4150,7 @@
         return this.getType(nia.arrayType);
     }
     private IClass getType2(Java.Literal l) {
+        if (l.value instanceof Byte     ) return IClass.BYTE;
         if (l.value instanceof Integer  ) return IClass.INT;
         if (l.value instanceof Long     ) return IClass.LONG;
         if (l.value instanceof Float    ) return IClass.FLOAT;
@@ -4162,6 +4163,7 @@
     }
     private IClass getType2(Java.ConstantValue cv) {
         IClass res = (
+            cv.constantValue instanceof Byte               ? IClass.BYTE    :
             cv.constantValue instanceof Integer            ? IClass.INT     :
             cv.constantValue instanceof Long               ? IClass.LONG    :
             cv.constantValue instanceof Float              ? IClass.FLOAT   :
@@ -5467,6 +5469,27 @@
         // 6.5.2.BL1.B1.B7 Package name
         return new Java.Package(location, identifier);
     }
+    
+    /**
+     * Check to see if a local variable was declared in this statement.  Possibly recursing into a StatementList, as needed.
+     * @param varName  The name of the variable to find
+     * @param stmt     The statement in question
+     * @return         A local variable definition if found.  null if not found
+     * @throws CompileException
+     */
+    private Java.LocalVariable findLocalVariableInStatement(Java.BlockStatement stmt, String varName) throws CompileException {
+        if (stmt instanceof Java.LocalVariableDeclarationStatement) {
+            return this.findLocalVariable((Java.LocalVariableDeclarationStatement)stmt, varName);
+        }
+        if (stmt instanceof Java.StatementList) {
+            Java.StatementList sl = (Java.StatementList)stmt;
+            for (Iterator it = sl.statements.iterator();;) {
+                Java.LocalVariable lv = findLocalVariableInStatement((Java.BlockStatement)it.next(), varName);
+                if (lv != null) return lv;
+            }
+        }
+        return null;
+    }
 
     /**
      * Find a local variable declared by the given <code>blockStatement</code> or any enclosing
@@ -5481,19 +5504,15 @@
             {
                 if (s instanceof Java.ForStatement) {
                     Java.BlockStatement optionalForInit = ((Java.ForStatement) s).optionalInit;
-                    if (optionalForInit instanceof Java.LocalVariableDeclarationStatement) {
-                        Java.LocalVariable lv = this.findLocalVariable((Java.LocalVariableDeclarationStatement) optionalForInit, name);
-                        if (lv != null) return lv;
-                    }
+                    Java.LocalVariable lv = this.findLocalVariableInStatement(optionalForInit, name);
+                    if (lv != null) return lv;
                 }
                 if (es instanceof Java.Block) {
                     Java.Block b = (Java.Block) es;
                     for (Iterator it = b.statements.iterator();;) {
                         Java.BlockStatement bs2 = (Java.BlockStatement) it.next();
-                        if (bs2 instanceof Java.LocalVariableDeclarationStatement) {
-                            Java.LocalVariable lv = this.findLocalVariable((Java.LocalVariableDeclarationStatement) bs2, name);
-                            if (lv != null) return lv;
-                        }
+                        Java.LocalVariable lv = this.findLocalVariableInStatement(bs2, name);
+                        if (lv != null) return lv;
                         if (bs2 == s) break;
                     }
                 }
@@ -5503,10 +5522,8 @@
                         Java.SwitchStatement.SwitchBlockStatementGroup sbgs = (Java.SwitchStatement.SwitchBlockStatementGroup) it2.next();
                         for (Iterator it = sbgs.blockStatements.iterator(); it.hasNext();) {
                             Java.BlockStatement bs2 = (Java.BlockStatement) it.next();
-                            if (bs2 instanceof Java.LocalVariableDeclarationStatement) {
-                                Java.LocalVariable lv = this.findLocalVariable((Java.LocalVariableDeclarationStatement) bs2, name);
-                                if (lv != null) return lv;
-                            }
+                            Java.LocalVariable lv = this.findLocalVariableInStatement(bs2, name);
+                            if (lv != null) return lv;
                             if (bs2 == s) break SBSGS;
                         }
                     }
=== src/org/codehaus/janino/Java.java
==================================================================
--- src/org/codehaus/janino/Java.java (revision 332)
+++ src/org/codehaus/janino/Java.java (patch statementlist level 2)
@@ -77,6 +77,7 @@
         private final Location location;
 
         protected Located(Location location) {
+            //assert location != null;
             this.location = location;
         }
 
@@ -1230,7 +1231,56 @@
 
         public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitBlock(this); }
     }
+    
+    /**
+     * This is similar to a {@link Java.Block} except that it does not create a scope around it statements.
+     * It is useful for programmatically manipulating an AST
+     */
+    public final static class StatementList extends Statement {
+        public final List statements = new ArrayList(); // BlockStatement
 
+        public StatementList(Location location) {
+            super(location);
+        }
+
+        public void addStatement(BlockStatement statement) {
+            this.statements.add(statement);
+            statement.setEnclosingScope(this.getEnclosingScope());
+        }
+        
+        public void addStatements(
+            List statements // BlockStatement
+        ) {
+            Iterator stmtIter = statements.iterator();
+            while(stmtIter.hasNext()) {
+                addStatement((BlockStatement)stmtIter.next());
+            }
+        }
+        
+        public BlockStatement[] getStatements() {
+            return (BlockStatement[]) this.statements.toArray(new BlockStatement[this.statements.size()]);
+        }
+        
+        // set children to share this object's enclosing scope
+        public void setEnclosingScope(Scope enclosingScope) {
+            super.setEnclosingScope(enclosingScope);
+            Iterator stmtIter = this.statements.iterator();
+            while(stmtIter.hasNext()) {
+                BlockStatement stmt = (BlockStatement)stmtIter.next();
+                stmt.setEnclosingScope(enclosingScope);
+            }
+        }
+
+        // Compile time members.
+        public final void accept(Visitor.BlockStatementVisitor visitor) {
+            Iterator stmtIter = this.statements.iterator();
+            while(stmtIter.hasNext()) {
+                BlockStatement stmt = (BlockStatement)stmtIter.next();
+                stmt.accept(visitor);
+            }
+        }
+    }
+
     /**
      * Base class for statements that can be terminated abnormally with a
      * "break" statement.
=== src/org/codehaus/janino/SimpleCompiler.java
==================================================================
--- src/org/codehaus/janino/SimpleCompiler.java (revision 332)
+++ src/org/codehaus/janino/SimpleCompiler.java (patch statementlist level 2)
@@ -201,7 +201,7 @@
     public static final ClassLoader BOOT_CLASS_LOADER = new ClassLoader(null) {};
 
     /**
-     * Allowe references to the classes loaded through this parent class loader
+     * Allow references to the classes loaded through this parent class loader
      * (@see {@link #setParentClassLoader(ClassLoader)}), plus the extra
      * <code>auxiliaryClasses</code>.
      * <p>
@@ -233,7 +233,22 @@
             DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION
         );
     }
+    
+    /**
+     * Cook this compilation unit directly.
+     *  See {@link Cookable.cook}
+     */
+    public void cook(Java.CompilationUnit compilationUnit)
+    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
+        this.setUpClassLoaders();
 
+        // Compile the classes and load them.
+        this.compileToClassLoader(
+            compilationUnit,
+            DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION
+        );
+    }
+
     /**
      * Initializes {@link #classLoader} and {@link #iClassLoader} from the configured
      * {@link #parentClassLoader} and {@link #optionalAuxiliaryClasses}. These are needed by

==== BEGIN SVK PATCH BLOCK ====
Version: svk v2.0.2 (linux)

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
==== END SVK PATCH BLOCK ====


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Re: Manipulable AST

by Matt Fowles :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

All~

Please ignore my current patch.  Further testing has revealed some
serious bugs with it.  I am working on a more complete version as we
speak.

Thanks,
Matt

On Thu, May 1, 2008 at 5:47 PM, Matt Fowles <matt.fowles@...> wrote:

> All~
>
>  The attached patch supersedes my last one and also include a test and
>  fix for the statement
>
>  return new byte[]{ (byte)1 };
>
>  which fails in `UnitCompiler.getType2` because of a missing case.
>
>  Once again, any pointers on things I can do to speed the inclusion of
>  patches into Janino would be greatly appreciated.
>
>  Matt
>
>
>
>  On Wed, Apr 30, 2008 at 11:13 AM, Matt Fowles <matt.fowles@...> wrote:
>  > All~
>  >
>  >  On the path towards porting my current AST to Janino, I discovered the
>  >  need for StatementLists.
>  >
>  >  StatementLists provide a way to put a place holder statement
>  >  somewhere, and then fill it in later with only things that are needed.
>  >   The big difference between this and a block is that it very
>  >  explicitly does not introduce a new scope, so that it can be used to
>  >  inject variables that will be visible.
>  >
>  >  This patch also adds `SimpleCompiler.cook(CompilationUnit)` which
>  >  allows the user to directly cook an AST that they have generated by
>  >  hand.
>  >
>  >  Both of these things are tested in the new `AstTests.java` that is
>  >  included in this test.
>  >
>  >  If you would like me to make any clean ups or sign any copyright
>  >  declarations before this work can be included in Janino, I would be
>  >  very happy to.
>  >
>  >  Enjoy,
>  >  Matt
>  >
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Manipulable AST

by Matt Fowles :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

All~

I am making very good progress targeting Janino's AST from my current
compiler.  The attached patch contains the total set of things I have
needed to add or fix so far.

Included in this patch is:

-  UnparseVisitor fix for precedence
  - a separate patch for just that bug is attached to the ticket
  - http://jira.codehaus.org/browse/JANINO-111

- Exposed the raw class data from SimpleCompiler
  - this allows my program to output .class or .jar files
  - tests for the raw class data

- improved support for Byte literals

- added class Java.StatementList
  - this allows code to be generated dynamically into an existing AST
(very necessary for my compiler)
  - update as necessary all the visitors for Java.StatementList
  - basic tests for Java.StatementList

- improved comments for Java.NewArray

Once again, any pointers on things I can do to speed the inclusion of
patches into Janino or to improve the patch in general are greatly appreciated.

Matt

On Tue, May 6, 2008 at 2:20 PM, Matt Fowles <matt.fowles@...> wrote:

> All~
>
>  Please ignore my current patch.  Further testing has revealed some
>  serious bugs with it.  I am working on a more complete version as we
>  speak.
>
>  Thanks,
>  Matt
>
>
>
>  On Thu, May 1, 2008 at 5:47 PM, Matt Fowles <matt.fowles@...> wrote:
>  > All~
>  >
>  >  The attached patch supersedes my last one and also include a test and
>  >  fix for the statement
>  >
>  >  return new byte[]{ (byte)1 };
>  >
>  >  which fails in `UnitCompiler.getType2` because of a missing case.
>  >
>  >  Once again, any pointers on things I can do to speed the inclusion of
>  >  patches into Janino would be greatly appreciated.
>  >
>  >  Matt
>  >
>  >
>  >
>  >  On Wed, Apr 30, 2008 at 11:13 AM, Matt Fowles <matt.fowles@...> wrote:
>  >  > All~
>  >  >
>  >  >  On the path towards porting my current AST to Janino, I discovered the
>  >  >  need for StatementLists.
>  >  >
>  >  >  StatementLists provide a way to put a place holder statement
>  >  >  somewhere, and then fill it in later with only things that are needed.
>  >  >   The big difference between this and a block is that it very
>  >  >  explicitly does not introduce a new scope, so that it can be used to
>  >  >  inject variables that will be visible.
>  >  >
>  >  >  This patch also adds `SimpleCompiler.cook(CompilationUnit)` which
>  >  >  allows the user to directly cook an AST that they have generated by
>  >  >  hand.
>  >  >
>  >  >  Both of these things are tested in the new `AstTests.java` that is
>  >  >  included in this test.
>  >  >
>  >  >  If you would like me to make any clean ups or sign any copyright
>  >  >  declarations before this work can be included in Janino, I would be
>  >  >  very happy to.
>  >  >
>  >  >  Enjoy,
>  >  >  Matt
>  >  >
>  >
>

[statementlist.patch]

==== Patch <statementlist> level 1
Source: 1adc4bfb-2c32-0410-81b9-bf0f0eac59bd:/janino-stmt-container:73185
Target: eb4544d6-894b-0410-9319-a9612837a279:/trunk/janino:338
        (http://svn.codehaus.org/janino)
Log:
 r72684@spiceweasel:  fowles | 2008-04-30 10:51:04 -0400
 creating a local branch for statement container work
 
 r72685@spiceweasel:  fowles | 2008-04-30 11:00:16 -0400
 Add support for StatementList and tests
 
 r72834@spiceweasel:  fowles | 2008-05-01 17:23:02 -0400
 comment out assertions since they are not valid in Java 1.2
 
 r72835@spiceweasel:  fowles | 2008-05-01 17:23:27 -0400
 Fix byte[] literals for ArrayInitiliazations
 
 r72849@spiceweasel:  fowles | 2008-05-01 22:49:37 -0400
 switch location null check to an IllegalArgumentException
 
 r72851@spiceweasel:  fowles | 2008-05-01 23:37:27 -0400
 Add a useful test
 
 r72852@spiceweasel:  fowles | 2008-05-01 23:45:48 -0400
 more tests
 
 r72853@spiceweasel:  fowles | 2008-05-02 00:17:46 -0400
 apparently some janino tests use null locations
 
 r72854@spiceweasel:  fowles | 2008-05-02 00:17:57 -0400
 found a way to make the test fail!
 
 r72915@spiceweasel:  fowles | 2008-05-02 16:00:07 -0400
 refactor a bunch of duplicate code
 
 r72916@spiceweasel:  fowles | 2008-05-02 16:25:08 -0400
 fix the problem with fully qualified names in this compilation unit
 
 r72941@spiceweasel:  fowles | 2008-05-02 16:37:33 -0400
 remove some debugging code
 
 r72942@spiceweasel:  fowles | 2008-05-02 23:55:16 -0400
 make test go three levels deep and clean up style
 
 r73062@spiceweasel:  fowles | 2008-05-05 17:23:33 -0400
 Fix a few small bugs with StatementLists
 
 r73063@spiceweasel:  fowles | 2008-05-05 17:35:48 -0400
 Fix a missing case for Byte literal
 
 r73064@spiceweasel:  fowles | 2008-05-05 17:35:58 -0400
 fix an indent
 
 r73065@spiceweasel:  fowles | 2008-05-05 17:38:47 -0400
 manually set the line encoding
 
 r73094@spiceweasel:  fowles | 2008-05-06 13:12:03 -0400
 Expose access to the underlying class data and write a test for it
 
 r73095@spiceweasel:  fowles | 2008-05-06 14:21:15 -0400
 make StatementList a more first class citizen and teach everyone how to deal with it.
 
 r73121@spiceweasel:  fowles | 2008-05-06 15:47:11 -0400
 Handle an unexpected null case more gracefully
 
 r73130@spiceweasel:  fowles | 2008-05-06 16:34:56 -0400
 add some javadoc
 
 r73135@spiceweasel:  fowles | 2008-05-06 18:28:17 -0400
 add suport for Operator precedence to UnparseVisitor and a basic test for it
 
 r73136@spiceweasel:  fowles | 2008-05-07 14:12:28 -0400
 add some tests for unparse and precedence
 fix a few bugs they found
 
 r73183@spiceweasel:  fowles | 2008-05-07 14:42:42 -0400
 remove a line ending change I made
 
 r73184@spiceweasel:  fowles | 2008-05-07 14:46:21 -0400
 somehow I messed up the line endings on this file
 
 r73185@spiceweasel:  fowles | 2008-05-07 14:50:45 -0400
 Fix some indenting I screwed up
 

=== tests/src/UnparseTests.java
==================================================================
--- tests/src/UnparseTests.java (revision 338)
+++ tests/src/UnparseTests.java (patch statementlist level 1)
@@ -0,0 +1,332 @@
+
+/*
+ * Janino - An embedded Java[TM] compiler
+ *
+ * Copyright (c) 2001-2007, Arno Unkrig
+ * All rights reserved.
+ *
+ * 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
+ * &nbs