[Swift-commit] r2996 - in trunk: . docs resources src/org/griphyn/vdl/engine tests/language-behaviour

noreply at svn.ci.uchicago.edu noreply at svn.ci.uchicago.edu
Fri Jul 3 12:30:34 CDT 2009


Author: benc
Date: 2009-07-03 12:30:34 -0500 (Fri, 03 Jul 2009)
New Revision: 2996

Added:
   trunk/tests/language-behaviour/106-import.swift
   trunk/tests/language-behaviour/testimport.swift
Modified:
   trunk/CHANGES.txt
   trunk/docs/userguide.xml
   trunk/resources/swiftscript.g
   trunk/resources/swiftscript.stg
   trunk/resources/swiftscript.xsd
   trunk/src/org/griphyn/vdl/engine/Karajan.java
Log:
import directive to import swiftscript code from other files

Modified: trunk/CHANGES.txt
===================================================================
--- trunk/CHANGES.txt	2009-07-03 09:27:55 UTC (rev 2995)
+++ trunk/CHANGES.txt	2009-07-03 17:30:34 UTC (rev 2996)
@@ -1,3 +1,7 @@
+(07/03/09)
+*** New import keyword which allows other SwiftScript source files to be
+    imported.
+
 (07/01/09)
 *** New writeData procedure which writes data structures to files in the same
     format as used by readData.

Modified: trunk/docs/userguide.xml
===================================================================
--- trunk/docs/userguide.xml	2009-07-03 09:27:55 UTC (rev 2995)
+++ trunk/docs/userguide.xml	2009-07-03 17:30:34 UTC (rev 2996)
@@ -806,6 +806,37 @@
 		</para>
 	</section>
 
+	<section id="imports"><title>Imports</title>
+		<para>
+The <literal>import</literal> directive can be used to import definitions from
+another SwiftScript file.
+		</para>
+		<para>
+For example, a SwiftScript program might contain this:
+			<programlisting>
+import defs;
+file f;
+			</programlisting>
+which would import the content of <filename>defs.swift</filename> in the
+current directory:
+			<programlisting>
+type file;
+			</programlisting>
+		</para>
+		<para>
+Imported files are read from the current working directory.
+		</para>
+		<para>
+There is no requirement that a module is imported only once. If a module
+is imported multiple times, for example in different files, then Swift will
+only process the imports once.
+		</para>
+		<para>
+Imports may contain anything that is valid in a SwiftScript program,
+including code that causes remote execution.
+		</para>
+	</section>
+
 </section>
 		<section id="mappers">
 		<title>Mappers</title>

Modified: trunk/resources/swiftscript.g
===================================================================
--- trunk/resources/swiftscript.g	2009-07-03 09:27:55 UTC (rev 2995)
+++ trunk/resources/swiftscript.g	2009-07-03 17:30:34 UTC (rev 2996)
@@ -61,6 +61,7 @@
 program returns [StringTemplate code=template("program")]
     :
     (nsdecl[code])*        //namespace declaration
+    (importStatement[code])*
     (topLevelStatement[code])*
     EOF
     ;
@@ -76,6 +77,14 @@
     }
     ;
 
+importStatement [StringTemplate code]
+    : "import" name:ID SEMI {
+        StringTemplate i = template("import");
+        i.setAttribute("target", name.getText());
+        code.setAttribute("imports", i);
+    }
+    ;
+
 typedecl [StringTemplate code]
 {StringTemplate r=template("typeDef");
  StringTemplate t=null;}

Modified: trunk/resources/swiftscript.stg
===================================================================
--- trunk/resources/swiftscript.stg	2009-07-03 09:27:55 UTC (rev 2995)
+++ trunk/resources/swiftscript.stg	2009-07-03 17:30:34 UTC (rev 2996)
@@ -1,12 +1,17 @@
 group XDTM;
 
-program(namespaces,targetNS,functions,types,statements,sourcelocation) ::= <<
+program(namespaces,targetNS,functions,types,statements,imports,sourcelocation) ::= <<
 <program xmlns=$defaultNS()$
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xs="http://www.w3.org/2001/XMLSchema"$if(!namespaces)$>
      $else$
 
      $namespaces;separator="\n"$>$endif$
+  $if(imports)$
+  <imports>
+    $imports;separator="\n"$
+  </imports>
+  $endif$
   $if(types)$  
   <types>
      $types;separator="\n"$   
@@ -27,6 +32,10 @@
 $if(prefix)$xmlns:$prefix$="$uri$"$else$targetNamespace="$uri$"$endif$
 >>
 
+import(target,sourcelocation) ::= <<
+<import>$target$</import>
+>>
+
 typeDef(name,type,members,sourcelocation) ::= <<
 $if(type)$
    	<type>

Modified: trunk/resources/swiftscript.xsd
===================================================================
--- trunk/resources/swiftscript.xsd	2009-07-03 09:27:55 UTC (rev 2995)
+++ trunk/resources/swiftscript.xsd	2009-07-03 17:30:34 UTC (rev 2996)
@@ -13,6 +13,8 @@
   <xs:element name="program">
     <xs:complexType>
       <xs:sequence>
+        <xs:element minOccurs="0" ref="imports"/>
+
         <xs:element minOccurs="0" ref="types"/>
 
         <xs:element maxOccurs="unbounded" minOccurs="0" name="procedure"
@@ -55,6 +57,14 @@
       </xs:sequence>
     </xs:complexType>
   </xs:element>
+
+  <xs:element name="imports">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="import" maxOccurs="unbounded" minOccurs="0" type="xs:string" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
   
   <xs:complexType name="Procedure">
     <xs:annotation>

Modified: trunk/src/org/griphyn/vdl/engine/Karajan.java
===================================================================
--- trunk/src/org/griphyn/vdl/engine/Karajan.java	2009-07-03 09:27:55 UTC (rev 2995)
+++ trunk/src/org/griphyn/vdl/engine/Karajan.java	2009-07-03 17:30:34 UTC (rev 2996)
@@ -1,14 +1,20 @@
 package org.griphyn.vdl.engine;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintStream;
 import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import javax.xml.namespace.QName;
 
@@ -29,6 +35,7 @@
 import org.globus.swift.language.Variable.Mapping.Param;
 import org.globus.swift.language.If.Else;
 import org.globus.swift.language.If.Then;
+import org.globus.swift.language.ImportsDocument.Imports;
 import org.globus.swift.language.ProgramDocument.Program;
 import org.globus.swift.language.Switch.Case;
 import org.globus.swift.language.Switch.Default;
@@ -36,6 +43,8 @@
 import org.globus.swift.language.TypesDocument.Types.Type;
 import org.griphyn.vdl.karajan.Loader;
 import org.griphyn.vdl.karajan.CompilationException;
+import org.griphyn.vdl.toolkit.VDLt2VDLx;
+import org.griphyn.vdl.toolkit.VDLt2VDLx.ParsingException;
 import org.safehaus.uuid.UUIDGenerator;
 import org.w3c.dom.Node;
 
@@ -49,9 +58,11 @@
 	Map floatInternMap = new HashMap();
 	Map proceduresMap = new HashMap();
 	Map functionsMap = new HashMap();
+	Map typesMap = new HashMap();
+
+	LinkedList importList = new LinkedList();
+	Set importedNames = new HashSet();
 	
-	Types types = null;
-	
 	int internedIDCounter = 17000;
 
 	/** an arbitrary statement identifier. Start at some high number to
@@ -139,19 +150,53 @@
 		return m_templates.getInstanceOf(name);
 	}
 
-	public StringTemplate program(Program prog) throws CompilationException {
-		VariableScope scope = new VariableScope(this, null);
-		scope.bodyTemplate = template("program");
+	private void processImports(Program prog) throws CompilationException {
 
-		scope.bodyTemplate.setAttribute("buildversion",Loader.buildVersion);
+		Imports imports = prog.getImports();
+		if(imports!=null) {
+			logger.debug("Processing SwiftScript imports");
+// process imports in reverse order
+			for(int i = imports.sizeOfImportArray() - 1 ;  i >=0 ; i--) {
+				String moduleToImport = imports.getImportArray(i);
+				logger.debug("Importing module "+moduleToImport);
+				if(!importedNames.contains(moduleToImport)) {
 
-		types = prog.getTypes();
+					// TODO PATH/PERL5LIB-style path handling
+					String swiftfilename = "./"+moduleToImport+".swift";
+					String xmlfilename = "./"+moduleToImport+".xml";
+
+
+					try {
+        	    				VDLt2VDLx.compile(new FileInputStream(swiftfilename),new PrintStream(new FileOutputStream(xmlfilename)));
+						logger.debug("Compiled. Now reading in compiled XML for "+moduleToImport);
+						Program importedProgram = parseProgramXML(xmlfilename).getProgram();
+						logger.debug("Read in compiled XML for "+moduleToImport);
+						importList.addFirst(importedProgram);
+						importedNames.add(moduleToImport);
+						logger.debug("Added "+moduleToImport+" to import list. Processing imports from that.");
+						processImports(importedProgram);
+					} catch(Exception e) {
+						throw new CompilationException("When processing import "+moduleToImport, e);
+					}
+				} else {
+					logger.debug("Skipping repeated import of "+moduleToImport);
+				}
+			}
+		}
+	}
+
+	private void processTypes(Program prog, VariableScope scope) throws CompilationException {
+	Types types = prog.getTypes();
 		if (types != null) {
 			for (int i = 0; i < types.sizeOfTypeArray(); i++) {
 				Type theType = types.getTypeArray(i);
 				String typeName = theType.getTypename();
 				String typeAlias = theType.getTypealias();
-											
+
+				logger.debug("Processing type "+typeName);
+
+				typesMap.put(typeName, theType);
+
 				StringTemplate st = template("typeDef");
 				st.setAttribute("name", typeName);
 				if (typeAlias != null && !typeAlias.equals("") && !typeAlias.equals("string")) {
@@ -172,9 +217,10 @@
 				scope.bodyTemplate.setAttribute("types", st);
 			}
 		}
-		
-		statementsForSymbols(prog, scope);
+	}
 
+	private void processProcedures(Program prog, VariableScope scope) throws CompilationException {
+
 		// Keep track of declared procedures
 		for (int i = 0; i < prog.sizeOfProcedureArray(); i++) {
 			Procedure proc = prog.getProcedureArray(i);
@@ -189,8 +235,40 @@
 			procedure(proc, scope);
 		}
 
-		statements(prog, scope);
+	}
 
+
+	public StringTemplate program(Program prog) throws CompilationException {
+		VariableScope scope = new VariableScope(this, null);
+		scope.bodyTemplate = template("program");
+
+		scope.bodyTemplate.setAttribute("buildversion",Loader.buildVersion);
+
+		importList.addFirst(prog);
+		processImports(prog);
+
+		Iterator it;
+
+		it=importList.iterator();
+		while(it.hasNext()) {
+			processTypes((Program)it.next(), scope);
+		}
+	
+		it=importList.iterator();
+		while(it.hasNext()) {
+			statementsForSymbols((Program)it.next(), scope);
+		}
+
+		it=importList.iterator();
+		while(it.hasNext()) {
+			processProcedures((Program)it.next(), scope);
+		}
+
+		it=importList.iterator();
+		while(it.hasNext()) {
+			statements((Program)it.next(), scope);
+		}
+
 		generateInternedConstants(scope.bodyTemplate);
 
 		return scope.bodyTemplate;
@@ -341,14 +419,7 @@
 			type = type.substring(0, type.length() - 2);		
 		if (!type.equals("int") && !type.equals("float") && !type.equals("string") 
 				&& !type.equals("boolean") && !type.equals("external")) {
-			boolean typeDefined = false;
-			if (types != null) {
-				for (int i = 0; i < types.sizeOfTypeArray(); i++)
-					if (types.getTypeArray(i).getTypename().equals(type)) {
-						typeDefined = true;
-						break;
-					}
-			}
+			boolean typeDefined = typesMap.containsKey(type);
 			if (!typeDefined)
 				throw new CompilationException("Type " + type + " is not defined.");
 		}
@@ -402,7 +473,8 @@
 			|| child instanceof Switch
 			|| child instanceof Procedure
 			|| child instanceof Types
-			|| child instanceof FormalParameter) {
+			|| child instanceof FormalParameter
+			|| child instanceof Imports) {
 			// ignore these - they're expected but we don't need to
 			// do anything for them here
 		} else {
@@ -432,7 +504,8 @@
 			switchStat((Switch) child, scope);
 		} else if (child instanceof Procedure
 			|| child instanceof Types
-			|| child instanceof FormalParameter) {
+			|| child instanceof FormalParameter
+			|| child instanceof Imports) {
 			// ignore these - they're expected but we don't need to
 			// do anything for them here
 		} else {
@@ -1073,21 +1146,19 @@
 
 			String actualType = null;					
 			// TODO this should be a map lookup of some kind?
-			for (int i = 0; i < types.sizeOfTypeArray(); i++) {
-				if (types.getTypeArray(i).getTypename().equals(parentType)) {
-					TypeStructure ts = types.getTypeArray(i).getTypestructure();
-					int j = 0;
-					for (j = 0; j < ts.sizeOfMemberArray(); j++)			
-						if (ts.getMemberArray(j).getMembername().equals(sm.getMemberName())) {
-							actualType = ts.getMemberArray(j).getMembertype();
-							break;
-						}					
-					if (j == ts.sizeOfMemberArray())
-						throw new CompilationException("No member " + sm.getMemberName() 
-								+ " in structure " + parentType);					
+
+			Type t = (Type)typesMap.get(parentType);
+
+			TypeStructure ts = t.getTypestructure();
+			int j = 0;
+			for (j = 0; j < ts.sizeOfMemberArray(); j++) {
+				if (ts.getMemberArray(j).getMembername().equals(sm.getMemberName())) 	{
+					actualType = ts.getMemberArray(j).getMembertype();
 					break;
 				}
-			}			
+			if (j == ts.sizeOfMemberArray())
+				throw new CompilationException("No member " + sm.getMemberName() + " in structure " + parentType);					
+			}
 			if (actualType == null) {
 				throw new CompilationException("Type " + parentType + " is not defined.");
 			}

Added: trunk/tests/language-behaviour/106-import.swift
===================================================================
--- trunk/tests/language-behaviour/106-import.swift	                        (rev 0)
+++ trunk/tests/language-behaviour/106-import.swift	2009-07-03 17:30:34 UTC (rev 2996)
@@ -0,0 +1,6 @@
+import testimport;
+
+file f;
+
+int i = 6;
+

Added: trunk/tests/language-behaviour/testimport.swift
===================================================================
--- trunk/tests/language-behaviour/testimport.swift	                        (rev 0)
+++ trunk/tests/language-behaviour/testimport.swift	2009-07-03 17:30:34 UTC (rev 2996)
@@ -0,0 +1,4 @@
+import testimport2;
+
+type file;
+




More information about the Swift-commit mailing list