// Copyright (c) Corporation for National Research Initiatives package org.python.compiler; import java.io.*; import java.util.*; import org.python.parser.*; import org.python.parser.ast.*; import org.python.core.Py; import org.python.core.PyException; class PyIntegerConstant extends Constant implements ClassConstants { int value; public PyIntegerConstant(int value) { this.value = value; } public void get(Code c) throws IOException { c.getstatic(module.classfile.name, name, $pyInteger); } public void put(Code c) throws IOException { module.classfile.addField(name, $pyInteger, access); c.iconst(value); int mref_newInteger = c.pool.Methodref( "org/python/core/Py", "newInteger", "(I)" + $pyInteger); c.invokestatic(mref_newInteger); c.putstatic(module.classfile.name, name, $pyInteger); } public int hashCode() { return value; } public boolean equals(Object o) { if (o instanceof PyIntegerConstant) return ((PyIntegerConstant)o).value == value; else return false; } } class PyFloatConstant extends Constant implements ClassConstants { double value; public PyFloatConstant(double value) { this.value = value; } public void get(Code c) throws IOException { c.getstatic(module.classfile.name, name, $pyFloat); } public void put(Code c) throws IOException { module.classfile.addField(name, $pyFloat, access); c.ldc(c.pool.Double(value)); int mref_newFloat = c.pool.Methodref("org/python/core/Py", "newFloat", "(D)" + $pyFloat); c.invokestatic(mref_newFloat); c.putstatic(module.classfile.name, name, $pyFloat); } public int hashCode() { return (int)value; } public boolean equals(Object o) { if (o instanceof PyFloatConstant) return ((PyFloatConstant)o).value == value; else return false; } } class PyComplexConstant extends Constant implements ClassConstants { double value; public PyComplexConstant(double value) { this.value = value; } public void get(Code c) throws IOException { c.getstatic(module.classfile.name, name, $pyComplex); } public void put(Code c) throws IOException { module.classfile.addField(name, $pyComplex, access); c.ldc(c.pool.Double(value)); int mref_newImaginary = c.pool.Methodref( "org/python/core/Py", "newImaginary", "(D)" + $pyComplex); c.invokestatic(mref_newImaginary); c.putstatic(module.classfile.name, name, $pyComplex); } public int hashCode() { return (int)value; } public boolean equals(Object o) { if (o instanceof PyComplexConstant) return ((PyComplexConstant)o).value == value; else return false; } } class PyStringConstant extends Constant implements ClassConstants { String value; public PyStringConstant(String value) { this.value = value; } public void get(Code c) throws IOException { c.getstatic(module.classfile.name, name, $pyStr); } public void put(Code c) throws IOException { module.classfile.addField(name, $pyStr, access); c.ldc(value); int mref_newString = c.pool.Methodref( "org/python/core/Py", "newString", "(" + $str + ")" + $pyStr); c.invokestatic(mref_newString); c.putstatic(module.classfile.name, name, $pyStr); } public int hashCode() { return value.hashCode(); } public boolean equals(Object o) { if (o instanceof PyStringConstant) return ((PyStringConstant)o).value.equals(value); else return false; } } class PyLongConstant extends Constant implements ClassConstants { String value; public PyLongConstant(String value) { this.value = value; } public void get(Code c) throws IOException { c.getstatic(module.classfile.name, name, $pyLong); } public void put(Code c) throws IOException { module.classfile.addField(name, $pyLong, access); c.ldc(value); int mref_newLong = c.pool.Methodref( "org/python/core/Py", "newLong", "(" + $str + ")" + $pyLong); c.invokestatic(mref_newLong); c.putstatic(module.classfile.name, name, $pyLong); } public int hashCode() { return value.hashCode(); } public boolean equals(Object o) { if (o instanceof PyLongConstant) return ((PyLongConstant)o).value.equals(value); else return false; } } class PyCodeConstant extends Constant implements ClassConstants { public String co_name; public int argcount; public String[] names; public int id; public int co_firstlineno; public boolean arglist, keywordlist; String fname; // for nested scopes public String[] cellvars; public String[] freevars; public int jy_npurecell; public int moreflags; public PyCodeConstant() { ; } public void get(Code c) throws IOException { c.getstatic(module.classfile.name, name, $pyCode); } public void put(Code c) throws IOException { module.classfile.addField(name, $pyCode, access); c.iconst(argcount); //Make all names if (names != null) { CodeCompiler.makeStrings(c, names, names.length); } else { // classdef CodeCompiler.makeStrings(c, null, 0); } c.ldc(((PyStringConstant)module.filename).value); c.ldc(co_name); c.iconst(co_firstlineno); c.iconst(arglist ? 1 : 0); c.iconst(keywordlist ? 1 : 0); int mref_self = c.pool.Fieldref(module.classfile.name, "self", "L"+module.classfile.name+";"); c.getstatic(mref_self); //c.aconst_null(); c.iconst(id); if (cellvars != null) CodeCompiler.makeStrings(c, cellvars, cellvars.length); else c.aconst_null(); if (freevars != null) CodeCompiler.makeStrings(c, freevars, freevars.length); else c.aconst_null(); c.iconst(jy_npurecell); c.iconst(moreflags); int mref_newCode = c.pool.Methodref( "org/python/core/Py", "newCode", "(I" + $strArr + $str + $str + "IZZ" + $pyFuncTbl + "I" + $strArr + $strArr + "II)" + $pyCode); c.invokestatic(mref_newCode); //c.aconst_null(); c.putstatic(module.classfile.name, name, $pyCode); } } public class Module implements ClassConstants, CompilationContext { ClassFile classfile; Constant filename; String sfilename; public Constant mainCode; public boolean linenumbers; public boolean setFile=true; Future futures; Hashtable scopes; public Module(String name, String filename, boolean linenumbers) { this.linenumbers = linenumbers; classfile = new ClassFile(name, "org/python/core/PyFunctionTable", ClassFile.SYNCHRONIZED | ClassFile.PUBLIC); constants = new Hashtable(); sfilename = filename; if (filename != null) this.filename = PyString(filename); else this.filename = null; codes = new Vector(); futures = new Future(); scopes = new Hashtable(); } public Module(String name) { this(name, name+".py", true); } // This block of code handles the pool of Python Constants Hashtable constants; private Constant findConstant(Constant c) { Constant ret = (Constant)constants.get(c); if (ret != null) return ret; ret = c; c.module = this; //More sophisticated name mappings might be nice c.name = "_"+constants.size(); constants.put(ret, ret); return ret; } public Constant PyInteger(int value) { return findConstant(new PyIntegerConstant(value)); } public Constant PyFloat(double value) { return findConstant(new PyFloatConstant(value)); } public Constant PyComplex(double value) { return findConstant(new PyComplexConstant(value)); } public Constant PyString(String value) { return findConstant(new PyStringConstant(value)); } public Constant PyLong(String value) { return findConstant(new PyLongConstant(value)); } /*public PyCodeConstant PyCode(SimpleNode tree, String name, ArgListCompiler ac, boolean fast_locals, boolean class_body) throws Exception { return PyCode(tree, name, ac, fast_locals, class_body, false, 0); } public PyCodeConstant PyCode(SimpleNode tree, String name, ArgListCompiler ac, boolean fast_locals, boolean class_body, int firstlineno) throws Exception { return PyCode(tree, name, ac, fast_locals, class_body, false, firstlineno); } public PyCodeConstant PyCode(SimpleNode tree, String name, ArgListCompiler ac, boolean fast_locals, boolean class_body, boolean printResults) throws Exception { return PyCode(tree, name, ac, fast_locals, class_body, printResults, 0); }*/ Vector codes; private boolean isJavaIdentifier(String s) { char[] chars = s.toCharArray(); if (chars.length == 0) return false; if (!Character.isJavaIdentifierStart(chars[0])) return false; for(int i=1; i 0) { ac.appendInitCode((Suite) tree); } if (scope != null) { int nparamcell = scope.jy_paramcells.size(); if (nparamcell > 0) { if (to_cell == 0) { to_cell = classfile.pool.Methodref("org/python/core/PyFrame", "to_cell","(II)V"); } Hashtable tbl = scope.tbl; Vector paramcells = scope.jy_paramcells; for (int i = 0; i < nparamcell; i++) { c.aload(1); SymInfo syminf = (SymInfo)tbl.get(paramcells.elementAt(i)); c.iconst(syminf.locals_index); c.iconst(syminf.env_index); c.invokevirtual(to_cell); } } } compiler.parse(tree, c, fast_locals, className, classBody, scope, cflags); if (scope.generator) { genswitch.setPosition(); c.aload(1); if (compiler.f_lasti == 0) { compiler.f_lasti = c.pool.Fieldref( "org/python/core/PyFrame", "f_lasti", "I"); } c.getfield(compiler.f_lasti); Label[] yields = new Label[compiler.yields.size()+1]; yields[0] = start; for (int i = 1; i < yields.length; i++) { yields[i] = (Label) compiler.yields.elementAt(i-1); } c.tableswitch(start, 0, yields); // XXX: Generate an error } // !classdef only if (!classBody) code.names = toNameAr(compiler.names,false); if (scope != null) { code.cellvars = toNameAr(scope.cellvars,true); code.freevars = toNameAr(scope.freevars,true); code.jy_npurecell = scope.jy_npurecell; } if (compiler.optimizeGlobals) { code.moreflags |= org.python.core.PyTableCode.CO_OPTIMIZED; } if (compiler.my_scope.generator) { code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR; } if (cflags != null && cflags.generator_allowed) { code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR_ALLOWED; } code.module = this; code.name = code.fname; return code; } //This block of code writes out the various standard methods public void addInit() throws IOException { Code c = classfile.addMethod("", "()V", ClassFile.PUBLIC); c.aload(0); c.invokespecial(c.pool.Methodref("org/python/core/PyFunctionTable", "", "()V")); c.return_(); } public void addRunnable() throws IOException { Code c = classfile.addMethod("getMain", "()" + $pyCode, ClassFile.PUBLIC); mainCode.get(c); c.areturn(); } public void addMain() throws IOException { Code c = classfile.addMethod("main", "(" + $str + ")V", ClassFile.PUBLIC | ClassFile.STATIC); int mref_self = c.pool.Fieldref(classfile.name, "self", "L"+classfile.name+";"); c.getstatic(mref_self); c.aload(0); c.invokestatic(c.pool.Methodref( "org/python/core/Py", "do_main", "(" + $pyRunnable + $strArr + ")V")); c.return_(); } public void addConstants() throws IOException { Code c = classfile.addMethod("", "()V", ClassFile.STATIC); classfile.addField("self", "L"+classfile.name+";", ClassFile.STATIC|ClassFile.FINAL); c.new_(c.pool.Class(classfile.name)); c.dup(); c.invokespecial(c.pool.Methodref(classfile.name, "", "()V")); c.putstatic(c.pool.Fieldref(classfile.name, "self", "L"+classfile.name+";")); Enumeration e = constants.elements(); while (e.hasMoreElements()) { Constant constant = (Constant)e.nextElement(); constant.put(c); } for(int i=0; i