[Nice-commit] Nice/src/bossa/syntax VarScope.java,1.16,1.17 SuperExp.java,1.5,1.6 NiceClass.java,1.4
Brought to you by:
bonniot
Update of /cvsroot/nice/Nice/src/bossa/syntax
In directory sc8-pr-cvs1:/tmp/cvs-serv18316/src/bossa/syntax
Modified Files:
VarScope.java SuperExp.java NiceClass.java Module.java
MethodDeclaration.java MethodBodyDefinition.java
JavaMethod.java ClassDefinition.java
Log Message:
Allow implementations of native methods to dispatch on all their arguments.
Index: VarScope.java
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/VarScope.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** VarScope.java 26 Sep 2002 16:21:39 -0000 1.16
--- VarScope.java 18 Apr 2003 14:50:20 -0000 1.17
***************
*** 22,26 ****
@author Daniel Bonniot (d.b...@ma...)
*/
! final class VarScope
{
public VarScope(VarScope outer)
--- 22,26 ----
@author Daniel Bonniot (d.b...@ma...)
*/
! public final class VarScope
{
public VarScope(VarScope outer)
Index: SuperExp.java
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/SuperExp.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** SuperExp.java 17 Sep 2002 16:30:56 -0000 1.5
--- SuperExp.java 18 Apr 2003 14:50:20 -0000 1.6
***************
*** 41,56 ****
MethodDeclaration decl = currentMethod.getDeclaration();
gnu.expr.Expression code;
! if (decl instanceof NiceMethod)
! superAlternative = getSuper((NiceMethod) decl);
! else
! getSuper((JavaMethod) decl);
}
MethodBodyDefinition currentMethod;
Alternative superAlternative = null;
- MethodBodyDefinition superImplementation = null;
Method superMethod = null;
! private Alternative getSuper(NiceMethod decl)
{
Alternative superAlt = null;
--- 41,52 ----
MethodDeclaration decl = currentMethod.getDeclaration();
gnu.expr.Expression code;
! superAlternative = getSuper(decl);
}
MethodBodyDefinition currentMethod;
Alternative superAlternative = null;
Method superMethod = null;
! private Alternative getSuper(MethodDeclaration decl)
{
Alternative superAlt = null;
***************
*** 78,115 ****
}
! if (superAlt == null)
! throw User.error(this, "There is no super implementation to call");
! return superAlt;
}
private void getSuper(JavaMethod decl)
{
- for (java.util.Iterator i = decl.getImplementations();
- i.hasNext();)
- {
- MethodBodyDefinition impl = (MethodBodyDefinition) i.next();
- if (leq(impl, currentMethod))
- continue;
-
- if (superImplementation == null || leq(impl, superImplementation))
- superImplementation = impl;
- }
-
- Method thisMethod = decl.reflectMethod;
Type firstArg = nice.tools.code.Types.get(currentMethod.firstArgument());
if (! (firstArg instanceof ClassType))
throw User.error(this, "The first argument of this method is not a class");
! ClassType superClass = ((ClassType) firstArg).getSuperclass();
! if (superClass != null)
! {
! superMethod = superClass.getMethod(thisMethod.getName(), thisMethod.getParameterTypes());
! if (superMethod != null)
! return;
! }
throw User.error(this, "There is no super implementation to call");
}
private boolean leq(MethodBodyDefinition a, MethodBodyDefinition b)
{
--- 74,112 ----
}
! if (superAlt != null)
! return superAlt;
! if (decl instanceof JavaMethod)
! {
! getSuper((JavaMethod) decl);
! return null;
! }
! else
! throw User.error(this, "There is no super implementation to call");
}
private void getSuper(JavaMethod decl)
{
Type firstArg = nice.tools.code.Types.get(currentMethod.firstArgument());
if (! (firstArg instanceof ClassType))
throw User.error(this, "The first argument of this method is not a class");
! superMethod = getImplementationAbove(decl, (ClassType) firstArg);
! if (superMethod != null)
! return;
throw User.error(this, "There is no super implementation to call");
}
+ public static Method getImplementationAbove(JavaMethod decl, ClassType firstArg)
+ {
+ Method thisMethod = decl.reflectMethod;
+ ClassType superClass = firstArg.getSuperclass();
+ if (superClass == null)
+ return null;
+
+ return superClass.getMethod(thisMethod.getName(),
+ thisMethod.getParameterTypes());
+ }
+
private boolean leq(MethodBodyDefinition a, MethodBodyDefinition b)
{
***************
*** 137,158 ****
else
{
! TypeConstructor superTC;
! if (superImplementation != null)
! superTC = superImplementation.firstArgument();
! else
{
! superTC = findTCforClass
! (currentMethod.firstArgument(), superMethod.getDeclaringClass());
! if (superTC == null)
! {
! // This probably means that super comes from a special
! // class that is not in the Nice hierarchy, like
! // java.lang.Object (because of variances).
! // Our safe bet is to assert that the argument is
! // above Object
! superTC = JavaClasses.object
! (currentMethod.firstArgument().variance.arity());
! }
}
--- 134,151 ----
else
{
! TypeConstructor superTC = findTCforClass
! (currentMethod.firstArgument(),
! superMethod.getDeclaringClass());
!
! if (superTC == null)
{
! // This probably means that super comes from a special
! // class that is not in the Nice hierarchy, like
! // java.lang.Object (because of variances).
! // Our safe bet is to assert that the argument is
! // above Object
! superTC = JavaClasses.object
! (currentMethod.firstArgument().variance.arity());
}
***************
*** 212,216 ****
// It does not matter which method is called (the super method or
// the base method), a call to super is emited.
! code = new QuoteExp(PrimProcedure.specialCall(superMethod));
return new gnu.expr.ApplyExp(code, currentMethod.compiledArguments());
--- 205,210 ----
// It does not matter which method is called (the super method or
// the base method), a call to super is emited.
! code = ((NiceClass) ClassDefinition.get(currentMethod.firstArgument()).implementation).
! callSuperMethod(superMethod);
return new gnu.expr.ApplyExp(code, currentMethod.compiledArguments());
Index: NiceClass.java
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/NiceClass.java,v
retrieving revision 1.41
retrieving revision 1.42
diff -C2 -d -r1.41 -r1.42
*** NiceClass.java 23 Feb 2003 11:04:22 -0000 1.41
--- NiceClass.java 18 Apr 2003 14:50:21 -0000 1.42
***************
*** 270,281 ****
private void prepareCodeGeneration()
{
! // The module will lookup the existing class if it is already compiled
! // and call createClassExp if not.
! classe = definition.module.getClassExp(this);
}
! gnu.expr.ClassExp classe;
!
! public gnu.expr.ClassExp createClassExp()
{
gnu.expr.ClassExp classe = new gnu.expr.ClassExp();
--- 270,284 ----
private void prepareCodeGeneration()
{
! /*
! We always generate a new ClassExp object, even for classes from
! already compiled packages. The reason is that we might need to
! add methods for the multiple dispatch of java methods in the class
! (and maybe for adding fields, or optimizing the dispatch of Nice
! methods in the future).
! */
! classe = createClassExp();
}
! private gnu.expr.ClassExp createClassExp()
{
gnu.expr.ClassExp classe = new gnu.expr.ClassExp();
***************
*** 288,292 ****
}
! gnu.expr.ClassExp getClassExp()
{
return classe;
--- 291,297 ----
}
! gnu.expr.ClassExp classe;
!
! public gnu.expr.ClassExp getClassExp()
{
return classe;
***************
*** 507,513 ****
/** This native method is redefined for this Nice class. */
! void addJavaMethod(gnu.expr.LambdaExp method)
{
! classe.addMethod(method);
}
--- 512,549 ----
/** This native method is redefined for this Nice class. */
! public gnu.expr.Expression addJavaMethod(gnu.expr.LambdaExp method)
{
! return classe.addMethod(method);
! }
!
! public gnu.expr.LambdaExp createJavaMethod(String name,
! gnu.bytecode.Method likeMethod,
! gnu.expr.Expression[] params)
! {
! gnu.expr.LambdaExp lambda =
! Gen.createMemberMethod
! (name,
! getClassExp().getType(),
! likeMethod.getParameterTypes(),
! likeMethod.getReturnType(),
! params);
! return lambda;
! }
!
! /**
! Returns an expression to call a super method from outside a class method.
!
! This is needed because the JVM restricts call to a specific implementation
! to occur inside a method of the same class. So this generates a stub class
! method that calls the desired super method, and return a reference to this
! stub.
! */
! gnu.expr.Expression callSuperMethod(gnu.bytecode.Method superMethod)
! {
! gnu.expr.Expression[] params = new gnu.expr.Expression[superMethod.getParameterTypes().length + 1];
! gnu.expr.LambdaExp lambda = createJavaMethod("$super$" + superMethod.getName(), superMethod, params);
! Gen.setMethodBody(lambda,
! new gnu.expr.ApplyExp(new gnu.expr.QuoteExp(gnu.expr.PrimProcedure.specialCall(superMethod)), params));
! return addJavaMethod(lambda);
}
Index: Module.java
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/Module.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** Module.java 17 Jun 2002 21:33:11 -0000 1.12
--- Module.java 18 Apr 2003 14:50:23 -0000 1.13
***************
*** 33,37 ****
gnu.expr.Expression getDispatchMethod(NiceMethod def);
gnu.expr.Expression lookupPackageMethod(String methodName, String type);
- gnu.expr.ClassExp getClassExp(NiceClass def);
gnu.expr.ReferenceExp addMethod(gnu.expr.LambdaExp method,
boolean packageMethod);
--- 33,36 ----
Index: MethodDeclaration.java
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/MethodDeclaration.java,v
retrieving revision 1.37
retrieving revision 1.38
diff -C2 -d -r1.37 -r1.38
*** MethodDeclaration.java 23 Mar 2003 23:03:03 -0000 1.37
--- MethodDeclaration.java 18 Apr 2003 14:50:23 -0000 1.38
***************
*** 237,241 ****
MethodDeclaration.Symbol getSymbol() { return symbol; }
! class Symbol extends FunSymbol
{
Symbol(LocatedString name, bossa.syntax.Constraint constraint,
--- 237,241 ----
MethodDeclaration.Symbol getSymbol() { return symbol; }
! public class Symbol extends FunSymbol
{
Symbol(LocatedString name, bossa.syntax.Constraint constraint,
***************
*** 271,275 ****
}
! MethodDeclaration getDefinition()
{
return MethodDeclaration.this;
--- 271,275 ----
}
! public MethodDeclaration getDefinition()
{
return MethodDeclaration.this;
***************
*** 300,303 ****
--- 300,309 ----
* Code generation
****************************************************************/
+
+ /** @return a string that uniquely represents this method */
+ public String getFullName()
+ {
+ return "NONE";
+ }
private gnu.expr.Expression code;
Index: MethodBodyDefinition.java
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/MethodBodyDefinition.java,v
retrieving revision 1.115
retrieving revision 1.116
diff -C2 -d -r1.115 -r1.116
*** MethodBodyDefinition.java 1 Apr 2003 20:25:01 -0000 1.115
--- MethodBodyDefinition.java 18 Apr 2003 14:50:23 -0000 1.116
***************
*** 136,156 ****
this.declaration = d;
- // Overriding a mono-method can currently not dispatch on other args
if (d instanceof JavaMethod)
! {
! for (int i = 1; i < formals.length; i++)
! if (!(formals[i].atAny()))
! User.error(this, this + " is a native method. Dispatch can only occur on the first argument");
!
! ((JavaMethod) d).addImplementation(this);
! }
! else if (d instanceof NiceMethod)
! // Register this alternative for the link test
! alternative = new bossa.link.SourceAlternative(this);
! else
User.error(this, "Implementations can only be made for methods, but " +
d.getName() + " is a function.\nIt was defined at:\n" +
d.location());
if (d.isMain())
User.warning(this, "This syntax for the main function is deprecated.\nPlease use instead the following:\n\nvoid main(String[] args)\n{\n ...\n}");
--- 136,149 ----
this.declaration = d;
if (d instanceof JavaMethod)
! ((JavaMethod) d).registerForDispatch();
! else if (! (d instanceof NiceMethod))
User.error(this, "Implementations can only be made for methods, but " +
d.getName() + " is a function.\nIt was defined at:\n" +
d.location());
+ // Register this alternative for the link test
+ alternative = new bossa.link.SourceAlternative(this);
+
if (d.isMain())
User.warning(this, "This syntax for the main function is deprecated.\nPlease use instead the following:\n\nvoid main(String[] args)\n{\n ...\n}");
***************
*** 476,485 ****
{
if (ref == null)
! {
! if (declaration instanceof NiceMethod)
! ref = compile((NiceMethod) declaration);
! else
! compile((JavaMethod) declaration);
! }
return ref;
--- 469,473 ----
{
if (ref == null)
! ref = createRef();
return ref;
***************
*** 495,499 ****
}
! private gnu.expr.ReferenceExp compile (NiceMethod definition)
{
createMethod(name.toString(), false);
--- 483,487 ----
}
! private gnu.expr.ReferenceExp createRef ()
{
createMethod(name.toString(), false);
***************
*** 501,505 ****
compiledMethod.addBytecodeAttribute
! (new MiscAttr("definition", definition.getFullName().getBytes()));
compiledMethod.addBytecodeAttribute
(new MiscAttr("patterns",
--- 489,493 ----
compiledMethod.addBytecodeAttribute
! (new MiscAttr("definition", declaration.getFullName().getBytes()));
compiledMethod.addBytecodeAttribute
(new MiscAttr("patterns",
***************
*** 512,535 ****
{
return formals[0].tc;
- }
-
- NiceClass declaringClass()
- {
- ClassDefinition def = ClassDefinition.get(firstArgument());
-
- if (def == null || ! (def.implementation instanceof NiceClass))
- throw User.error(this, declaration + " is a native method.\n" +
- "It can not be overriden because " + formals[0].tc +
- " is not a class defined in Nice");
-
- return (NiceClass) def.implementation;
- }
-
- private void compile (JavaMethod declaration)
- {
- createMethod(declaration.getName().toString(), true);
-
- // Compile as a method in the class of the first argument
- declaringClass().addJavaMethod(compiledMethod);
}
--- 500,503 ----
Index: JavaMethod.java
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/JavaMethod.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -C2 -d -r1.24 -r1.25
*** JavaMethod.java 10 Dec 2002 19:10:52 -0000 1.24
--- JavaMethod.java 18 Apr 2003 14:50:24 -0000 1.25
***************
*** 28,32 ****
@author Daniel Bonniot (d.b...@ma...)
*/
! class JavaMethod extends MethodDeclaration
{
JavaMethod(LocatedString name, Constraint constraint,
--- 28,32 ----
@author Daniel Bonniot (d.b...@ma...)
*/
! public class JavaMethod extends MethodDeclaration
{
JavaMethod(LocatedString name, Constraint constraint,
***************
*** 72,75 ****
--- 72,88 ----
****************************************************************/
+ public static final String fullNamePrefix = "JAVA:";
+
+ /** @return a string that uniquely represents this method */
+ public String getFullName()
+ {
+ return fullNamePrefix + name + ':' + getType();
+ }
+
+ public final LambdaExp getLambda()
+ {
+ return nice.tools.code.Gen.dereference(getCode());
+ }
+
Method reflectMethod;
***************
*** 98,111 ****
****************************************************************/
! Iterator getImplementations()
! {
! return implementations.iterator();
! }
!
! private LinkedList implementations = new LinkedList();
! void addImplementation(MethodBodyDefinition impl)
{
! implementations.add(impl);
}
}
--- 111,123 ----
****************************************************************/
! private boolean registered;
! public void registerForDispatch()
{
! if (registered)
! return;
!
! bossa.link.Dispatch.register(this);
! registered = true;
}
}
Index: ClassDefinition.java
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/ClassDefinition.java,v
retrieving revision 1.87
retrieving revision 1.88
diff -C2 -d -r1.87 -r1.88
*** ClassDefinition.java 19 Feb 2003 18:33:54 -0000 1.87
--- ClassDefinition.java 18 Apr 2003 14:50:24 -0000 1.88
***************
*** 445,449 ****
public static void reset() { tcToClassDef = new HashMap(); }
! static final ClassDefinition get(TypeConstructor tc)
{
return (ClassDefinition) tcToClassDef.get(tc);
--- 445,449 ----
public static void reset() { tcToClassDef = new HashMap(); }
! public static final ClassDefinition get(TypeConstructor tc)
{
return (ClassDefinition) tcToClassDef.get(tc);
***************
*** 665,668 ****
--- 665,673 ----
ClassImplementation implementation;
+
+ public ClassImplementation getImplementation()
+ {
+ return implementation;
+ }
}
|