001: /*
002: * @(#)DefaultFunctionSerializer.java 1.2 05/06/21
003: *
004: * Copyright (c) 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.lang;
010:
011: import java.io.*;
012: import java.util.*;
013: import pnuts.lang.*;
014: import pnuts.compiler.Compiler;
015: import org.pnuts.lang.*;
016:
017: class DefaultFunctionSerializer implements Runtime.FunctionSerializer {
018:
019: public void serialize(PnutsFunction pnutsFunction,
020: ObjectOutputStream s) throws IOException {
021: Function[] functions = pnutsFunction.functions;
022: s.writeUTF(pnutsFunction.pkg.getName());
023: int n = functions.length;
024: s.writeInt(n);
025: for (int i = 0; i < n; i++) {
026: Function f = functions[i];
027: SimpleNode node = null;
028: if (f != null) {
029: node = f.node;
030: if (node != null) { // the function was written in Pnuts
031: s.writeObject(f);
032: } else { // the function was written in Java
033: node = f.getNode();
034: if (node != null) {
035: s.writeObject(node); // nodes was deserialized properly
036: } else {
037: s.writeObject(f.unparse(null)); // nodes was reconstracted from the script
038: }
039: f.writeAttributes(s);
040: }
041: } else {
042: s.writeObject(null);
043: }
044: }
045: }
046:
047: public void deserialize(PnutsFunction pnutsFunction,
048: ObjectInputStream s) throws IOException,
049: ClassNotFoundException {
050: String pkgName = s.readUTF();
051: Context threadContext = Runtime.getThreadContext();
052: int n = s.readInt();
053: Function[] functions = new Function[n];
054: pnutsFunction.functions = functions;
055: boolean[] compile = new boolean[n];
056: boolean compileString = false;
057: boolean compileNode = false;
058: StringBuffer sbuf = new StringBuffer();
059: List nodes = new ArrayList();
060: Package pkg = null;
061:
062: for (int i = 0; i < n; i++) {
063: Object f = s.readObject();
064: if (f instanceof Function) { // AST interpreter
065: functions[i] = (Function) f;
066: } else if (f instanceof SimpleNode) {
067: SimpleNode ss = new SimpleNode(
068: PnutsParserTreeConstants.JJTSTARTSET);
069: SimpleNode node = (SimpleNode) f;
070: Function func = new Function();
071: functions[i] = func;
072: compile[i] = true;
073: compileNode = true;
074: func.node = node.jjtGetChild(1);
075: func.readAttributes(s);
076: func.setPackage(Package.find(func.pkgName,
077: threadContext));
078: NodeUtil.setPackage(func.pkgName, ss);
079: String[] imports = func.importEnv.list();
080: for (int j = 0; j < imports.length; j++) {
081: NodeUtil.addImportNode(imports[j], ss);
082: }
083: NodeUtil.addFunction(node, ss);
084: nodes.add(ss);
085:
086: } else if (f instanceof String) {
087: String unparsed = (String) f;
088: try {
089: Function func = new Function();
090: func.readAttributes(s);
091: func.setPackage(Package.find(func.pkgName,
092: threadContext));
093: sbuf.append("package(\"");
094: sbuf.append(func.pkgName);
095: sbuf.append("\")\n");
096: String[] imports = func.importEnv.list();
097: for (int j = 0; j < imports.length; j++) {
098: sbuf.append("import " + imports[j] + "\n");
099: }
100: sbuf.append((String) f);
101: sbuf.append("\n");
102: PnutsParser parser = Pnuts
103: .getParser(new StringReader(unparsed));
104: SimpleNode node = parser.FunctionStatement(null);
105: func.node = node.jjtGetChild(1);
106: func.function = pnutsFunction;
107: functions[i] = func;
108: compile[i] = true;
109: compileString = true;
110: } catch (ParseException pe) {
111: pe.printStackTrace();
112: }
113: }
114: }
115: pnutsFunction.pkg = Package.find(pkgName, threadContext);
116: Compiler compiler = null;
117: if (compileString || compileNode) {
118: compiler = new pnuts.compiler.Compiler();
119: pkg = new Package(null, null);
120: }
121: if (compileString) {
122: Context c2 = (threadContext != null) ? (Context) threadContext
123: .clone()
124: : new Context();
125: c2.setCurrentPackage(pkg);
126: Pnuts compiled = compiler.compile(sbuf.toString(), c2);
127: PnutsFunction pf = (PnutsFunction) compiled.run(c2);
128: pf.pkg = Package.find(pkgName, threadContext);
129: for (int i = 0; i < functions.length; i++) {
130: Function f = functions[i];
131: if (f != null && compile[i]) {
132: Function f2 = pf.functions[i];
133: f2.moduleList = f.moduleList;
134: f2.config = f.config;
135: Package p = Package.getPackage(f.pkg.getName(), c2);
136: for (Enumeration e = f.pkg.bindings(); e
137: .hasMoreElements();) {
138: Binding binding = (Binding) e.nextElement();
139: p.set(binding.getName(), binding.get());
140: }
141: f2.pkg = p;
142: f2.pkgName = f.pkgName;
143: f2.file = null;
144: functions[i] = f2;
145: }
146: }
147: }
148: if (compileNode) {
149: Context c2 = (threadContext != null) ? (Context) threadContext
150: .clone()
151: : new Context();
152: if (pkg != null) {
153: c2.setCurrentPackage(pkg);
154: }
155: for (int j = 0, sz = nodes.size(); j < sz; j++) {
156: SimpleNode ss = (SimpleNode) nodes.get(j);
157:
158: Pnuts compiled = compiler.compile(new P(ss), c2);
159: PnutsFunction pf = (PnutsFunction) compiled.run(c2);
160: for (int i = 0; i < pf.functions.length; i++) {
161: Function f = functions[i];
162: if (f != null && compile[i]) {
163: Function f2 = pf.functions[i];
164: if (f2 == null) {
165: continue;
166: }
167: f2.moduleList = f.moduleList;
168: f2.config = f.config;
169: f2.pkg = f.pkg;
170: f2.pkgName = f.pkgName;
171: f2.file = f.file;
172: functions[i] = f2;
173: }
174: }
175: }
176: }
177: }
178:
179: static class P extends Pnuts {
180: public P(SimpleNode ss) {
181: this.startNodes = ss;
182: }
183: }
184: }
|