Changeset 4300 for trunk/ProjectFortress
- Timestamp:
- 10/31/09 15:34:55 (3 weeks ago)
- Location:
- trunk/ProjectFortress
- Files:
-
- 1 added
- 2 removed
- 14 modified
- 1 moved
-
compiler_tests/SingleInheritance.fss (moved) (moved from trunk/ProjectFortress/long_term_not_working/inheritance/SingleInheritance.fss) (1 diff)
-
compiler_tests/SingleInheritance.test (added)
-
long_term_not_working/inheritance/SingleInheritanceInternal.fss (deleted)
-
long_term_not_working/inheritance/SingleInheritanceInternalNoSelf.fss (deleted)
-
src/com/sun/fortress/compiler/CompilerJUTest.scala (modified) (1 diff)
-
src/com/sun/fortress/compiler/NamingCzar.java (modified) (1 diff)
-
src/com/sun/fortress/compiler/codegen/CodeGen.java (modified) (35 diffs)
-
src/com/sun/fortress/compiler/codegen/SParallelismAnalyzer.scala (modified) (1 diff)
-
src/com/sun/fortress/compiler/desugarer/VarRefContainer.java (modified) (1 diff)
-
src/com/sun/fortress/interpreter/rewrite/DesugarerVisitor.java (modified) (1 diff)
-
src/com/sun/fortress/nodes_util/ExprFactory.java (modified) (2 diffs)
-
src/com/sun/fortress/nodes_util/NodeUtil.java (modified) (15 diffs)
-
src/com/sun/fortress/scala_src/typechecker/impls/Functionals.scala (modified) (4 diffs)
-
src/com/sun/fortress/scala_src/typechecker/impls/Operators.scala (modified) (7 diffs)
-
src/com/sun/fortress/scala_src/typechecker/staticenv/STypeEnv.scala (modified) (6 diffs)
-
src/com/sun/fortress/scala_src/useful/ASTGenHelper.scala (modified) (4 diffs)
-
src/com/sun/fortress/scala_src/useful/Lists.scala (modified) (2 diffs)
-
src/com/sun/fortress/scala_src/useful/STypesUtil.scala (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ProjectFortress/compiler_tests/SingleInheritance.fss
r4254 r4300 24 24 n():String = "O(" x.asString "," y.asString ").n " self.m("a","b") 25 25 p():String = "O(" x.asString "," y.asString ").p " m("e","f") 26 q():String = n() 26 27 end 27 28 28 29 run() = do 29 30 o = O(1,2) 31 println(o.m("c","d")) 30 32 println(o.n()) 31 33 println(o.p()) 32 println(o. m("c","d"))34 println(o.q()) 33 35 end -
trunk/ProjectFortress/src/com/sun/fortress/compiler/CompilerJUTest.scala
r3561 r4300 17 17 package com.sun.fortress.compiler 18 18 19 import _root_.java.util.Arrays20 import _root_.java.util.LinkedList21 19 import junit.framework.TestCase 22 20 import junit.framework.TestSuite -
trunk/ProjectFortress/src/com/sun/fortress/compiler/NamingCzar.java
r4262 r4300 895 895 } 896 896 public String forVarType (VarType t) { 897 // 897 // 898 898 String s = t.getName().getText(); 899 899 s = internalToDesc(s); -
trunk/ProjectFortress/src/com/sun/fortress/compiler/codegen/CodeGen.java
r4291 r4300 177 177 } 178 178 } 179 179 180 180 this.topLevelOverloads = 181 181 sizePartitionedOverloads(ci.functions()); … … 184 184 this.lexEnv = new BATree<String,VarCodeGen>(StringHashComparer.V); 185 185 this.env = env; 186 187 186 187 188 188 debug( "Compile: Compiling ", packageAndClassName ); 189 189 } … … 338 338 339 339 private VarCodeGen getLocalVarOrNull( IdOrOp nm ) { 340 debug("getLocalVar: " +nm);340 debug("getLocalVar: ", nm); 341 341 VarCodeGen r = lexEnv.get(idOrOpToString(nm)); 342 342 if (r != null) 343 debug("getLocalVar:" + nm + " VarCodeGen = " + r + " of class " +r.getClass());343 debug("getLocalVar:", nm, " VarCodeGen = ", r, " of class ", r.getClass()); 344 344 else 345 debug("getLocalVar:" + nm +" VarCodeGen = null");345 debug("getLocalVar:", nm, " VarCodeGen = null"); 346 346 return r; 347 347 } … … 352 352 353 353 String file = Naming.mangleFortressIdentifier(unmangled_file_name); 354 354 355 355 if (ProjectProperties.getBoolean("fortress.bytecode.verify", false)) 356 356 CheckClassAdapter.verify(new ClassReader(cw.toByteArray()), true, pw); … … 609 609 /* Need wrappers for the API, too. */ 610 610 generateUnambiguousWrappersForApi(); 611 611 612 612 // Must process top-level values next to make sure fields end up in scope. 613 613 for (Decl d : x.getDecls()) { … … 708 708 FnDecl y = x; 709 709 x = (FnDecl) x.accept(new GenericNumberer(xlation)); 710 710 711 711 // Get rewritten parts. 712 712 FnHeader header = x.getHeader(); … … 714 714 Type returnType = header.getReturnType().unwrap(); 715 715 Expr body = x.getBody().unwrap(); 716 716 717 717 String sig = 718 718 NamingCzar.jvmSignatureFor(NodeUtil.getParamType(x), … … 781 781 // methods. 782 782 String mname; 783 int n = params.size(); 783 784 if (selfIndex != NO_SELF) { 784 785 sig = Naming.removeNthSigParameter(sig, selfIndex+1); … … 786 787 } else { 787 788 mname = nonCollidingSingleName(name, sig); 789 n++; 788 790 } 789 791 … … 796 798 * for our primitive type story. 797 799 */ 798 799 800 800 801 // Dotted method; downcast self and … … 803 804 InstantiatingClassloader.forwardingMethod(cw, mname, ACC_PUBLIC, 0, 804 805 springBoardClass, mname, INVOKESTATIC, 805 sig, params.size(), true);806 sig, n, true); 806 807 } 807 808 … … 851 852 cg.generateActualMethodCode(modifiers, mname, sig, params, selfIndex, 852 853 inAMethod, body); 853 854 854 855 generateAllWrappersForFn(x, params, sig, modifiers, mname); 855 856 } … … 868 869 String mname) { 869 870 CodeGen cg = new CodeGen(this); 870 /* This code generates forwarding wrappers for 871 /* This code generates forwarding wrappers for 871 872 * the (local) unambiguous name of the function. 872 873 */ 873 874 874 875 // unambiguous within component 875 876 String wname = idOrOpToString(x.getUnambiguousName()); … … 898 899 function.getReturnType().unwrap(), 899 900 component.getName()); 900 901 901 902 String mname = idOrOpToString(function.name()); // entry.getKey(); 902 903 … … 919 920 if (0 == (Opcodes.ACC_STATIC & modifiers)) 920 921 return; 921 922 922 923 mv = cw.visitCGMethod(modifiers, wname, sig, null, null); 923 924 mv.visitCode(); … … 928 929 929 930 int i = 0; 930 931 931 932 for (Param p : params) { 932 933 // Type ty = p.getIdType().unwrap(); … … 936 937 937 938 mv.visitMethodInsn(Opcodes.INVOKESTATIC, packageAndClassName, mname, sig); 938 939 939 940 methodReturnAndFinish(); 940 941 } … … 1327 1328 sig, params.size(), true); 1328 1329 1329 1330 1330 1331 generateAllWrappersForFn(x, params, sig, modifiers, mname); 1331 1332 1332 1333 } 1333 1334 … … 1343 1344 1344 1345 /** 1346 * TODO: surely this is derivable from the arrow type, which maintains the selfParameterIndex? 1347 * Are those inconsistent with one another? 1345 1348 * @param params 1346 1349 * @return … … 1360 1363 1361 1364 public void forFnExpr(FnExpr x) { 1362 debug("forFnExpr " +x);1365 debug("forFnExpr ", x); 1363 1366 FnHeader header = x.getHeader(); 1364 1367 Expr body = x.getBody(); … … 1379 1382 String className = NamingCzar.gensymArrowClassName(Naming.deDot(thisApi().getText())); 1380 1383 1381 debug("forFnExpr className = " + className + " desc = " +desc);1384 debug("forFnExpr className = ", className, " desc = ", desc); 1382 1385 List<VarCodeGen> freeVars = getFreeVars(body); 1383 1386 cg.lexEnv = cg.createTaskLexEnvVariables(className, freeVars); … … 1512 1515 String arrow_type = NamingCzar.jvmTypeDesc(arrow, thisApi(), false); 1513 1516 String PCN = pc_and_m.getA() + "$" + 1514 1517 1515 1518 method_and_signature.getA() + 1516 1519 Naming.ENVELOPE + "$"+ // "ENVELOPE" … … 1530 1533 */ 1531 1534 public void forFunctionalRef(FunctionalRef x) { 1532 debug("forFunctionalRef " +x);1535 debug("forFunctionalRef ", x); 1533 1536 1534 1537 List<StaticArg> sargs = x.getStaticArgs(); … … 1539 1542 com.sun.fortress.nodes.Type arrow = exprType(x); 1540 1543 1541 debug("forFunctionalRef " + x + " arrow = " +arrow);1544 debug("forFunctionalRef ", x, " arrow = ", arrow); 1542 1545 1543 1546 Pair<String, String> calleeInfo = functionalRefToPackageClassAndMethod(x); … … 1554 1557 1555 1558 String arrow_type = NamingCzar.jvmTypeDesc(arrow, thisApi(), false); 1556 pkgClass = pkgClass + Naming.GEAR + "$" + 1559 pkgClass = pkgClass + Naming.GEAR + "$" + 1557 1560 calleeInfo.getB() + 1558 1561 decoration + … … 1789 1792 String [] superInterfaces = 1790 1793 NamingCzar.extendsClauseToInterfaces(extendsC, component.getName()); 1794 String abstractSuperclass; 1795 if (superInterfaces.length > 0) { 1796 abstractSuperclass = superInterfaces[0] + NamingCzar.springBoard; 1797 } else { 1798 abstractSuperclass = NamingCzar.internalObject; 1799 } 1791 1800 Id classId = NodeUtil.getName(x); 1792 1801 String classFile = … … 1844 1853 // classFile, null, NamingCzar.internalObject, new String[] { parent }); 1845 1854 cw.visit( Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER + Opcodes.ACC_FINAL, 1846 classFile, null, NamingCzar.internalObject, superInterfaces);1855 classFile, null, abstractSuperclass, superInterfaces); 1847 1856 1848 1857 if (!hasParameters) { … … 1854 1863 1855 1864 // Emit fields here, one per parameter. 1856 generateFieldsAndInitMethod(classFile, NamingCzar.internalObject, params);1865 generateFieldsAndInitMethod(classFile, abstractSuperclass, params); 1857 1866 1858 1867 if (!hasParameters) { … … 2214 2223 String classFile = NamingCzar.makeInnerClassName(packageAndClassName, 2215 2224 NodeUtil.getName(x).getText()); 2225 String abstractSuperclass; 2216 2226 traitOrObjectName = classFile; 2217 2227 if (classFile.equals("fortress/AnyType$Any")) { 2218 2228 superInterfaces = new String[0]; 2229 abstractSuperclass = NamingCzar.FValueType; 2230 } else { 2231 abstractSuperclass = superInterfaces[0] + NamingCzar.springBoard; 2219 2232 } 2220 2233 CodeGenClassWriter prev = cw; … … 2234 2247 // In general Springboard must not be directly instantiable. 2235 2248 cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, springBoardClass, 2236 null, NamingCzar.FValueType, new String[0]);2249 null, abstractSuperclass, new String[] { classFile } ); 2237 2250 debug("Start writing springboard class ", 2238 2251 springBoardClass); 2239 generateFieldsAndInitMethod(springBoardClass, NamingCzar.FValueType,2252 generateFieldsAndInitMethod(springBoardClass, abstractSuperclass, 2240 2253 Collections.<Param>emptyList()); 2241 2254 debug("Finished init method ", springBoardClass); … … 2288 2301 } 2289 2302 if (!oinit.isSome()) { 2290 debug("VarDecl " +v+" skipping abs var decl.");2303 debug("VarDecl ", v, " skipping abs var decl."); 2291 2304 return; 2292 2305 } … … 2300 2313 String classFile = NamingCzar.jvmTypeForToplevelDecl(var, packageAndClassName); 2301 2314 String tyDesc = NamingCzar.jvmTypeDesc(ty, thisApi()); 2302 debug("VarDeclPrePass " +var+" : "+ty+" = "+exp);2315 debug("VarDeclPrePass ", var, " : ", ty, " = ", exp); 2303 2316 new CodeGen(this).generateVarDeclInnerClass(v, classFile, tyDesc, exp); 2304 2317 … … 2342 2355 2343 2356 public void forMethodInvocation(MethodInvocation x) { 2357 debug("forMethodInvocation ", x, 2358 " obj = ", x.getObj(), 2359 " method = ", x.getMethod(), 2360 " static args = ", x.getStaticArgs(), 2361 " args = ", x.getArg()); 2344 2362 Id method = x.getMethod(); 2345 2363 Expr obj = x.getObj(); … … 2432 2450 public void for_RewriteFnApp(_RewriteFnApp x) { 2433 2451 debug("for_RewriteFnApp ", x, 2434 " args = ", x.getArgument(), " function = ", x.getFunction() +2435 " function class = " +x.getFunction());2452 " args = ", x.getArgument(), " function = ", x.getFunction(), 2453 " function class = ", x.getFunction()); 2436 2454 // This is a little weird. If a function takes no arguments the parser gives me a void literal expr 2437 2455 // however I don't want to be putting a void literal on the stack because it gets in the way. … … 2556 2574 if (cg != null) { 2557 2575 /* Need to check if the overloaded function happens to match 2558 * a name in an API that this component exports; if so, 2559 * generate a forwarding wrapper from the 2576 * a name in an API that this component exports; if so, 2577 * generate a forwarding wrapper from the 2560 2578 */ 2561 2579 } -
trunk/ProjectFortress/src/com/sun/fortress/compiler/codegen/SParallelismAnalyzer.scala
r3935 r4300 59 59 } 60 60 61 override def walk(x: Any) = { 62 x match { 63 case sop@SOpExpr(_, op, args) => { 61 override def walk(x: Any) = { 62 x match { 63 case sop@SOpExpr(_, op, args) => { 64 64 if (tallyArgs(args)) worthy += sop 65 65 walk(args) 66 66 } 67 case fnApp@S_RewriteFnApp(_, fun, STupleExpr(_, exprs, varargs, keywords, _)) => { 67 case fnApp@S_RewriteFnApp(_, fun, STupleExpr(_, exprs, varargs, keywords, _)) => { 68 68 if (tallyArgs(exprs)) worthy += fnApp 69 69 } 70 70 case _ => super.walk(x) 71 71 } 72 } 72 } 73 73 } -
trunk/ProjectFortress/src/com/sun/fortress/compiler/desugarer/VarRefContainer.java
r3716 r4300 49 49 import edu.rice.cs.plt.tuple.Option; 50 50 51 /** Generate object to hold hoisted mutable variables that are shared by 52 * an object expression and its enclosing context. 53 */ 51 54 public class VarRefContainer { 52 55 private VarRef origVar; -
trunk/ProjectFortress/src/com/sun/fortress/interpreter/rewrite/DesugarerVisitor.java
r4185 r4300 1031 1031 FnExpr fnExpr = ExprFactory.makeFnExpr(sp, params, (Expr) rewrittenExpr); 1032 1032 1033 return visitNode(ExprFactory.make TightJuxt(NodeUtil.getSpan(s), fn, fnExpr));1033 return visitNode(ExprFactory.make_RewriteFnApp(NodeUtil.getSpan(s), fn, fnExpr)); 1034 1034 } 1035 1035 -
trunk/ProjectFortress/src/com/sun/fortress/nodes_util/ExprFactory.java
r4296 r4300 467 467 ExprInfo info = NodeFactory.makeExprInfo(span, parenthesized, ty); 468 468 return new OpRef(info, staticArgs, lexicalDepth, name, names, 469 interp_overloadings, newOverloadings,470 overloadingType);469 interp_overloadings, newOverloadings, 470 overloadingType); 471 471 } 472 472 … … 1995 1995 1996 1996 //Span in_span, boolean in_parenthesized, Id in_obj, List<StaticArg> in_staticArgs 1997 public static Expr make_RewriteObjectRef(boolean parenthesized, Id in_obj) {1998 return make_RewriteObjectRef(parenthesized, in_obj, Collections.<StaticArg>emptyList());1999 }1997 public static Expr make_RewriteObjectRef(boolean parenthesized, Id in_obj) { 1998 return make_RewriteObjectRef(parenthesized, in_obj, Collections.<StaticArg>emptyList()); 1999 } 2000 2000 2001 2001 public static NonParenthesisDelimitedMI makeNonParenthesisDelimitedMI(Span span, -
trunk/ProjectFortress/src/com/sun/fortress/nodes_util/NodeUtil.java
r4280 r4300 58 58 59 59 public static boolean isKeyword(Id id) { 60 String name = id.getText();61 return ( ! name.equals("self") &&62 Fortress.FORTRESS_KEYWORDS.contains(name) );60 String name = id.getText(); 61 return ( ! name.equals("self") && 62 Fortress.FORTRESS_KEYWORDS.contains(name) ); 63 63 } 64 64 65 65 public static void log(BufferedWriter writer, Span span, String msg) { 66 try {67 if ( writer == null ) {68 String file = span.getFileName();69 writer = Useful.filenameToBufferedWriter( file + ".preparserError.log" );70 }71 writer.write( span + ":\n " + msg + "\n" );72 } catch (IOException error) {73 error("Writing to a log file for the parser failed!");74 }66 try { 67 if ( writer == null ) { 68 String file = span.getFileName(); 69 writer = Useful.filenameToBufferedWriter( file + ".preparserError.log" ); 70 } 71 writer.write( span + ":\n " + msg + "\n" ); 72 } catch (IOException error) { 73 error("Writing to a log file for the parser failed!"); 74 } 75 75 } 76 76 … … 84 84 85 85 public static Span spanTwo(Span s1, Span s2) { 86 return new Span(s1.getBegin(), s2.getEnd());86 return new Span(s1.getBegin(), s2.getEnd()); 87 87 } 88 88 89 89 public static Span spanTwo(ASTNode s1, ASTNode s2) { 90 return spanTwo(getSpan(s1), getSpan(s2));90 return spanTwo(getSpan(s1), getSpan(s2)); 91 91 } 92 92 93 93 public static Span spanTwo(Expr e1, Expr e2) { 94 return spanTwo(getSpan(e1), getSpan(e2));94 return spanTwo(getSpan(e1), getSpan(e2)); 95 95 } 96 96 … … 100 100 // | node :: rest -> join node.node_span (span_all rest) 101 101 public static Span spanAll(Object[] nodes, int size) { 102 if (size == 0)103 return bug("Cannot make a span from an empty list of nodes.");104 else { // size != 0105 return new Span(getSpan((ASTNode)Array.get(nodes,0)).getBegin(),106 getSpan((ASTNode)Array.get(nodes,size-1)).getEnd());107 }102 if (size == 0) 103 return bug("Cannot make a span from an empty list of nodes."); 104 else { // size != 0 105 return new Span(getSpan((ASTNode)Array.get(nodes,0)).getBegin(), 106 getSpan((ASTNode)Array.get(nodes,size-1)).getEnd()); 107 } 108 108 } 109 109 110 110 public static Span spanAll(Iterable<? extends ASTNode> nodes) { 111 if (IterUtil.isEmpty(nodes))112 return bug("Cannot make a span from an empty list of nodes.");113 else {114 return new Span(getSpan(IterUtil.first(nodes)).getBegin(),115 getSpan(IterUtil.last(nodes)).getEnd());116 }111 if (IterUtil.isEmpty(nodes)) 112 return bug("Cannot make a span from an empty list of nodes."); 113 else { 114 return new Span(getSpan(IterUtil.first(nodes)).getBegin(), 115 getSpan(IterUtil.last(nodes)).getEnd()); 116 } 117 117 } 118 118 119 119 public static Span spanAll(SourceLoc defaultLoc, Iterable<? extends ASTNode> nodes) { 120 if (IterUtil.isEmpty(nodes)) { return new Span(defaultLoc, defaultLoc); }121 else {122 return new Span(getSpan(IterUtil.first(nodes)).getBegin(),123 getSpan(IterUtil.last(nodes)).getEnd());124 }120 if (IterUtil.isEmpty(nodes)) { return new Span(defaultLoc, defaultLoc); } 121 else { 122 return new Span(getSpan(IterUtil.first(nodes)).getBegin(), 123 getSpan(IterUtil.last(nodes)).getEnd()); 124 } 125 125 } 126 126 … … 128 128 129 129 public static ASTNodeInfo getInfo(ASTNode n) { 130 return n.getInfo();130 return n.getInfo(); 131 131 } 132 132 133 133 public static Span getSpan(ASTNode n) { 134 return n.getInfo().getSpan();134 return n.getInfo().getSpan(); 135 135 } 136 136 137 137 public static boolean isTraitObjectDecl(ASTNode n) { 138 return (n instanceof TraitObjectDecl);138 return (n instanceof TraitObjectDecl); 139 139 } 140 140 … … 142 142 143 143 public static Span getSpan(Expr e) { 144 return e.getInfo().getSpan();144 return e.getInfo().getSpan(); 145 145 } 146 146 147 147 public static boolean isParenthesized(Expr e) { 148 return e.getInfo().isParenthesized();148 return e.getInfo().isParenthesized(); 149 149 } 150 150 151 151 public static Option<Type> getExprType(Expr e) { 152 return e.getInfo().getExprType();152 return e.getInfo().getExprType(); 153 153 } 154 154 … … 156 156 157 157 public static Span getSpan(Type t) { 158 return t.getInfo().getSpan();158 return t.getInfo().getSpan(); 159 159 } 160 160 161 161 public static boolean isParenthesized(Type t) { 162 return t.getInfo().isParenthesized();162 return t.getInfo().isParenthesized(); 163 163 } 164 164 165 165 public static List<StaticParam> getStaticParams(Type t) { 166 return t.getInfo().getStaticParams();166 return t.getInfo().getStaticParams(); 167 167 } 168 168 169 169 public static Option<WhereClause> getWhereClause(Type t) { 170 return t.getInfo().getWhereClause();170 return t.getInfo().getWhereClause(); 171 171 } 172 172 … … 174 174 175 175 public static Modifiers getMods(TraitObjectDecl t) { 176 return t.getHeader().getMods();176 return t.getHeader().getMods(); 177 177 } 178 178 179 179 public static Id getName(TraitObjectDecl t) { 180 return (Id)t.getHeader().getName();180 return (Id)t.getHeader().getName(); 181 181 } 182 182 183 183 public static List<Decl> getDecls(TraitObjectDecl t) { 184 return t.getHeader().getDecls();184 return t.getHeader().getDecls(); 185 185 } 186 186 187 187 public static List<StaticParam> getStaticParams(TraitObjectDecl t) { 188 return t.getHeader().getStaticParams();188 return t.getHeader().getStaticParams(); 189 189 } 190 190 … … 204 204 205 205 public static Option<WhereClause> getWhereClause(TraitObjectDecl o) { 206 return o.getHeader().getWhereClause();206 return o.getHeader().getWhereClause(); 207 207 } 208 208 209 209 public static List<TraitTypeWhere> getExtendsClause(TraitObjectDecl t) { 210 return t.getHeader().getExtendsClause();210 return t.getHeader().getExtendsClause(); 211 211 } 212 212 213 213 public static List<BaseType> getExcludesClause(TraitObjectDecl t) { 214 if ( t instanceof TraitDecl )215 return ((TraitDecl)t).getExcludesClause();216 else217 return bug("TraitDecl expected, but got " + t);214 if ( t instanceof TraitDecl ) 215 return ((TraitDecl)t).getExcludesClause(); 216 else 217 return bug("TraitDecl expected, but got " + t); 218 218 } 219 219 220 220 public static Option<List<NamedType>> getComprisesClause(TraitObjectDecl t) { 221 if ( t instanceof TraitDecl )222 return ((TraitDecl)t).getComprisesClause();223 else224 return bug("TraitDecl expected, but got " + t);221 if ( t instanceof TraitDecl ) 222 return ((TraitDecl)t).getComprisesClause(); 223 else 224 return bug("TraitDecl expected, but got " + t); 225 225 } 226 226 227 227 public static boolean isComprisesEllipses(TraitObjectDecl t) { 228 if ( t instanceof TraitDecl )229 return ((TraitDecl)t).isComprisesEllipses();230 else {231 bug("TraitDecl expected, but got " + t);232 return false;233 }228 if ( t instanceof TraitDecl ) 229 return ((TraitDecl)t).isComprisesEllipses(); 230 else { 231 bug("TraitDecl expected, but got " + t); 232 return false; 233 } 234 234 } 235 235 236 236 public static Option<List<Param>> getParams(TraitObjectDecl o) { 237 if ( o instanceof ObjectDecl )238 return ((ObjectDecl)o).getParams();239 else240 return bug("ObjectDecl expected, but got " + o);237 if ( o instanceof ObjectDecl ) 238 return ((ObjectDecl)o).getParams(); 239 else 240 return bug("ObjectDecl expected, but got " + o); 241 241 } 242 242 243 243 /* Getters for TraitDecl */ 244 244 public static List<BaseType> getExcludesClause(TraitDecl t) { 245 return t.getExcludesClause();245 return t.getExcludesClause(); 246 246 } 247 247 248 248 public static Option<List<NamedType>> getComprisesClause(TraitDecl t) { 249 return t.getComprisesClause();249 return t.getComprisesClause(); 250 250 } 251 251 252 252 /* Getters for ObjectDecl */ 253 253 public static Option<List<Param>> getParams(ObjectDecl o) { 254 return o.getParams();254 return o.getParams(); 255 255 } 256 256 257 257 public static Option<List<Type>> getThrowsClause(ObjectDecl o) { 258 return o.getHeader().getThrowsClause();258 return o.getHeader().getThrowsClause(); 259 259 } 260 260 261 261 public static Option<Contract> getContract(ObjectDecl o) { 262 return o.getHeader().getContract();262 return o.getHeader().getContract(); 263 263 } 264 264 265 265 public static List<Decl> getDecls(ObjectDecl o) { 266 return o.getHeader().getDecls();266 return o.getHeader().getDecls(); 267 267 } 268 268 269 269 public static List<TraitTypeWhere> getExtendsClause(ObjectDecl o) { 270 return o.getHeader().getExtendsClause();270 return o.getHeader().getExtendsClause(); 271 271 } 272 272 273 273 /* Getters for ObjectExpr */ 274 274 public static List<Decl> getDecls(ObjectExpr o) { 275 return o.getHeader().getDecls();275 return o.getHeader().getDecls(); 276 276 } 277 277 278 278 public static List<TraitTypeWhere> getExtendsClause(ObjectExpr o) { 279 return o.getHeader().getExtendsClause();279 return o.getHeader().getExtendsClause(); 280 280 } 281 281 282 282 /* Getters for FnDecl */ 283 283 public static Modifiers getMods(FnDecl f) { 284 return f.getHeader().getMods();284 return f.getHeader().getMods(); 285 285 } 286 286 287 287 public static IdOrOpOrAnonymousName getName(FnDecl f) { 288 return f.getHeader().getName();288 return f.getHeader().getName(); 289 289 } 290 290 291 291 public static List<StaticParam> getStaticParams(FnDecl f) { 292 return f.getHeader().getStaticParams();292 return f.getHeader().getStaticParams(); 293 293 } 294 294 295 295 public static Option<WhereClause> getWhereClause(FnDecl f) { 296 return f.getHeader().getWhereClause();296 return f.getHeader().getWhereClause(); 297 297 } 298 298 299 299 public static List<Param> getParams(FnDecl f) { 300 return f.getHeader().getParams();300 return f.getHeader().getParams(); 301 301 } 302 302 303 303 public static Type getParamType(Param p) { 304 if ( p.getIdType().isSome() )305 return p.getIdType().unwrap();306 else if ( p.getVarargsType().isSome() )307 return NodeFactory.makeVarargsType(getSpan(p),308 p.getVarargsType().unwrap());309 else310 return bug(getSpan(p) + "\n Type is not inferred.");304 if ( p.getIdType().isSome() ) 305 return p.getIdType().unwrap(); 306 else if ( p.getVarargsType().isSome() ) 307 return NodeFactory.makeVarargsType(getSpan(p), 308 p.getVarargsType().unwrap()); 309 else 310 return bug(getSpan(p) + "\n Type is not inferred."); 311 311 } 312 312 313 313 public static Type getParamType(List<Param> params, Span span) { 314 if ( params.isEmpty() ) return NodeFactory.makeVoidType(span);315 else if ( params.size() == 1 ) return getParamType(params.get(0));316 else { // if ( params.size() > 1 )317 List<Type> types = new ArrayList<Type>( params.size() );318 for ( Param p : params ) {319 types.add( getParamType(p) );320 }321 return NodeFactory.makeTupleType(span, types);322 }314 if ( params.isEmpty() ) return NodeFactory.makeVoidType(span); 315 else if ( params.size() == 1 ) return getParamType(params.get(0)); 316 else { // if ( params.size() > 1 ) 317 List<Type> types = new ArrayList<Type>( params.size() ); 318 for ( Param p : params ) { 319 types.add( getParamType(p) ); 320 } 321 return NodeFactory.makeTupleType(span, types); 322 } 323 323 } 324 324 325 325 public static Option<Type> getParamType(ObjectDecl o) { 326 if ( o.getParams().isSome() ) {327 return Option.<Type>some(getParamType(o.getParams().unwrap(), getSpan(o)));328 } else return Option.<Type>none();326 if ( o.getParams().isSome() ) { 327 return Option.<Type>some(getParamType(o.getParams().unwrap(), getSpan(o))); 328 } else return Option.<Type>none(); 329 329 } 330 330 331 331 public static Type getParamType(FnDecl f) { 332 return getParamType(getParams(f), getSpan(f));332 return getParamType(getParams(f), getSpan(f)); 333 333 } 334 334 335 335 public static Option<Type> getReturnType(FnDecl f) { 336 return f.getHeader().getReturnType();336 return f.getHeader().getReturnType(); 337 337 } 338 338 339 339 public static Option<List<Type>> getThrowsClause(FnDecl f) { 340 return f.getHeader().getThrowsClause();340 return f.getHeader().getThrowsClause(); 341 341 } 342 342 343 343 public static Option<Contract> getContract(FnDecl f) { 344 return f.getHeader().getContract();344 return f.getHeader().getContract(); 345 345 } 346 346 347 347 /* Getters for FnExpr */ 348 348 public static IdOrOpOrAnonymousName getName(FnExpr f) { 349 return f.getHeader().getName();349 return f.getHeader().getName(); 350 350 } 351 351 352 352 public static List<StaticParam> getStaticParams(FnExpr f) { 353 return f.getHeader().getStaticParams();353 return f.getHeader().getStaticParams(); 354 354 } 355 355 356 356 public static Option<WhereClause> getWhereClause(FnExpr f) { 357 return f.getHeader().getWhereClause();357 return f.getHeader().getWhereClause(); 358 358 } 359 359 360 360 public static List<Param> getParams(FnExpr f) { 361 return f.getHeader().getParams();361 return f.getHeader().getParams(); 362 362 } 363 363 364 364 public static Option<Type> getReturnType(FnExpr f) { 365 return f.getHeader().getReturnType();365 return f.getHeader().getReturnType(); 366 366 } 367 367 368 368 public static Option<List<Type>> getThrowsClause(FnExpr f) { 369 return f.getHeader().getThrowsClause();369 return f.getHeader().getThrowsClause(); 370 370 } 371 371 372 372 /* Getter for Generic */ 373 373 public static List<StaticParam> getStaticParams(Generic g) { 374 return g.getHeader().getStaticParams();374 return g.getHeader().getStaticParams(); 375 375 } 376 376 377 377 /* Getters for ObjectConstructor */ 378 378 public static Option<List<Param>> getParams(ObjectConstructor g) { 379 return g.getParams();379 return g.getParams(); 380 380 } 381 381 382 382 public static List<Decl> getDecls(ObjectConstructor g) { 383 return g.getHeader().getDecls();383 return g.getHeader().getDecls(); 384 384 } 385 385 386 386 public static List<TraitTypeWhere> getExtendsClause(ObjectConstructor g) { 387 return g.getHeader().getExtendsClause();387 return g.getHeader().getExtendsClause(); 388 388 } 389 389 390 390 /* Getters for Applicable */ 391 391 public static IdOrOpOrAnonymousName getName(Applicable a) { 392 return a.getHeader().getName();392 return a.getHeader().getName(); 393 393 } 394 394 395 395 public static List<StaticParam> getStaticParams(Applicable a) { 396 return a.getHeader().getStaticParams();396 return a.getHeader().getStaticParams(); 397 397 } 398 398 399 399 public static List<Param> getParams(Applicable a) { 400 return a.getHeader().getParams();400 return a.getHeader().getParams(); 401 401 } 402 402 403 403 public static Option<Type> getReturnType(Applicable a) { 404 return a.getHeader().getReturnType();404 return a.getHeader().getReturnType(); 405 405 } 406 406 407 407 public static Option<Type> getSelfType(ArrowType a) { 408 Option<MethodInfo> mi = a.getMethodInfo();409 if (mi.isNone()) return Option.<Type>none();410 return Option.some(mi.unwrap().getSelfType());408 Option<MethodInfo> mi = a.getMethodInfo(); 409 if (mi.isNone()) return Option.<Type>none(); 410 return Option.some(mi.unwrap().getSelfType()); 411 411 } 412 412 413 413 public static Option<Integer> getSelfPosition(ArrowType a) { 414 Option<MethodInfo> mi = a.getMethodInfo();415 if (mi.isNone()) return Option.<Integer>none();416 return Option.some(mi.unwrap().getSelfPosition());414 Option<MethodInfo> mi = a.getMethodInfo(); 415 if (mi.isNone()) return Option.<Integer>none(); 416 return Option.some(mi.unwrap().getSelfPosition()); 417 417 } 418 418 419 419 public static Option<WhereClause> getWhereClause(Applicable a) { 420 return a.getHeader().getWhereClause();420 return a.getHeader().getWhereClause(); 421 421 } 422 422 423 423 public static boolean isOpParam(StaticParam p) { 424 return p.getKind() instanceof KindOp;424 return p.getKind() instanceof KindOp; 425 425 } 426 426 427 427 public static boolean isTypeParam(StaticParam p) { 428 return p.getKind() instanceof KindType;428 return p.getKind() instanceof KindType; 429 429 } 430 430 431 431 public static boolean isIntParam(StaticParam p) { 432 return ( p.getKind() instanceof KindInt ||433 p.getKind() instanceof KindNat );432 return ( p.getKind() instanceof KindInt || 433 p.getKind() instanceof KindNat ); 434 434 } 435 435 436 436 public static boolean isNatParam(StaticParam p) { 437 return p.getKind() instanceof KindNat;437 return p.getKind() instanceof KindNat; 438 438 } 439 439 440 440 public static boolean isBoolParam(StaticParam p) { 441 return p.getKind() instanceof KindBool;441 return p.getKind() instanceof KindBool; 442 442 } 443 443 444 444 public static boolean isDimParam(StaticParam p) { 445 return p.getKind() instanceof KindDim;445 return p.getKind() instanceof KindDim; 446 446 } 447 447 448 448 public static boolean isUnitParam(StaticParam p) { 449 return p.getKind() instanceof KindUnit;449 return p.getKind() instanceof KindUnit; 450 450 } 451 451 452 452 public static List<_RewriteObjectExpr> getObjectExprs(Component comp) { 453 for ( Decl d : comp.getDecls() ) {454 if ( d instanceof _RewriteObjectExprDecl )455 return ((_RewriteObjectExprDecl)d).getObjectExprs();456 }457 return new ArrayList<_RewriteObjectExpr>();453 for ( Decl d : comp.getDecls() ) { 454 if ( d instanceof _RewriteObjectExprDecl ) 455 return ((_RewriteObjectExprDecl)d).getObjectExprs(); 456 } 457 return new ArrayList<_RewriteObjectExpr>(); 458 458 } 459 459 460 460 public static List<String> getFunctionalMethodNames(Component comp) { 461 for ( Decl d : comp.getDecls() ) {462 if ( d instanceof _RewriteFunctionalMethodDecl )463 return ((_RewriteFunctionalMethodDecl)d).getFunctionalMethodNames();464 }465 return new ArrayList<String>();461 for ( Decl d : comp.getDecls() ) { 462 if ( d instanceof _RewriteFunctionalMethodDecl ) 463 return ((_RewriteFunctionalMethodDecl)d).getFunctionalMethodNames(); 464 } 465 return new ArrayList<String>(); 466 466 } 467 467 468 468 private static boolean beginComment( String token ) { 469 return (token.length() >= 2 &&470 token.substring(0,2).equals("(*"));469 return (token.length() >= 2 && 470 token.substring(0,2).equals("(*")); 471 471 } 472 472 473 473 private static boolean endComment( String token ) { 474 return (token.length() >= 2 &&475 token.substring(token.length()-2,token.length()).equals("*)"));474 return (token.length() >= 2 && 475 token.substring(token.length()-2,token.length()).equals("*)")); 476 476 } 477 477 478 478 private static boolean lineComment( String token ) { 479 return (token.length() == 3 &&480 token.equals("(*)"));479 return (token.length() == 3 && 480 token.equals("(*)")); 481 481 } 482 482 483 483 private static boolean blankOrComment( String line ) { 484 if ( line.equals("") )485 return true;486 else {487 String[] split = line.split(" ");488 return beginComment(split[0]);489 }484 if ( line.equals("") ) 485 return true; 486 else { 487 String[] split = line.split(" "); 488 return beginComment(split[0]); 489 } 490 490 } 491 491 492 492 /* Getters for VarDecl */ 493 493 public static Modifiers getMods(BufferedWriter writer, VarDecl v) { 494 if ( v.getLhs().isEmpty() ) {495 log(writer, getSpan(v),496 "Variable declaration does not declare any: " + v);497 return Modifiers.None;498 } else499 return v.getLhs().get(0).getMods();494 if ( v.getLhs().isEmpty() ) { 495 log(writer, getSpan(v), 496 "Variable declaration does not declare any: " + v); 497 return Modifiers.None; 498 } else 499 return v.getLhs().get(0).getMods(); 500 500 } 501 501 502 502 /* Getters for LocalVarDecl */ 503 503 public static Modifiers getMods(BufferedWriter writer, LocalVarDecl v) { 504 if ( v.getLhs().isEmpty() ) {505 log(writer, getSpan(v),506 "Variable declaration does not declare any: " + v);507 return Modifiers.None;508 } else509 return v.getLhs().get(0).getMods();504 if ( v.getLhs().isEmpty() ) { 505 log(writer, getSpan(v), 506 "Variable declaration does not declare any: " + v); 507 return Modifiers.None; 508 } else 509 return v.getLhs().get(0).getMods(); 510 510 } 511 511 512 512 /* get the declared name of a component or api */ 513 513 public static APIName apiName( String path ) throws UserError, IOException { 514 String absolutePath = new File(path).getCanonicalPath();515 try {516 File file = new File(path).getCanonicalFile();517 String filename = new File(path).getName();518 try {519 filename = filename.substring(0, filename.length()-4);520 BufferedReader br = Useful.utf8BufferedFileReader(file);521 // skip comments and blank lines522 int lineNo = 0;523 int commentDepth = 0;524 String line = br.readLine(); lineNo++;525 while ( blankOrComment(line) || commentDepth != 0 ) {526 if ( line.equals("") ) {527 line = br.readLine(); lineNo++;528 } else {529 String[] split = line.split(" ");530 for ( String token : split ) {531 if ( lineComment(token) ) {532 line = "";533 break;534 } else if ( beginComment(token) ) {535 commentDepth++; line = "";536 } else if ( endComment(token) ) {537 commentDepth--; line = "";538 } else if ( commentDepth == 0 ) {539 line += token;540 line += " ";541 }542 }543 if ( commentDepth == 0 && ! line.equals("") ) break;544 else line = br.readLine(); lineNo++;545 }546 }547 br.close();548 // line is the first non-comment/non-blank line549 String[] split = line.split(" ");550 String name;551 if ( split[0].equals("component") || split[0].equals("api") ) {552 Span span = NodeFactory.makeSpan(absolutePath,553 lineNo, split[0].length()+2,554 split[0].length()+split[1].length()+1);555 name = split[1];556 if ( ! name.equals(filename) )557 return error(span,558 " Component/API names must match their enclosing file names." +559 "\n File name: " + absolutePath +560 "\n Component/API name: " + name);561 } else name = filename;562 return NodeFactory.makeAPIName(NodeFactory.parserSpan, name);563 } catch (NullPointerException ex) {564 return NodeFactory.makeAPIName(NodeFactory.parserSpan, filename);565 }566 } catch (FileNotFoundException ex) {567 throw new UserError("Cannot find file " + absolutePath);568 }514 String absolutePath = new File(path).getCanonicalPath(); 515 try { 516 File file = new File(path).getCanonicalFile(); 517 String filename = new File(path).getName(); 518 try { 519 filename = filename.substring(0, filename.length()-4); 520 BufferedReader br = Useful.utf8BufferedFileReader(file); 521 // skip comments and blank lines 522 int lineNo = 0; 523 int commentDepth = 0; 524 String line = br.readLine(); lineNo++; 525 while ( blankOrComment(line) || commentDepth != 0 ) { 526 if ( line.equals("") ) { 527 line = br.readLine(); lineNo++; 528 } else { 529 String[] split = line.split(" "); 530 for ( String token : split ) { 531 if ( lineComment(token) ) { 532 line = ""; 533 break; 534 } else if ( beginComment(token) ) { 535 commentDepth++; line = ""; 536 } else if ( endComment(token) ) { 537 commentDepth--; line = ""; 538 } else if ( commentDepth == 0 ) { 539 line += token; 540 line += " "; 541 } 542 } 543 if ( commentDepth == 0 && ! line.equals("") ) break; 544 else line = br.readLine(); lineNo++; 545 } 546 } 547 br.close(); 548 // line is the first non-comment/non-blank line 549 String[] split = line.split(" "); 550 String name; 551 if ( split[0].equals("component") || split[0].equals("api") ) { 552 Span span = NodeFactory.makeSpan(absolutePath, 553 lineNo, split[0].length()+2, 554 split[0].length()+split[1].length()+1); 555 name = split[1]; 556 if ( ! name.equals(filename) ) 557 return error(span, 558 " Component/API names must match their enclosing file names." + 559 "\n File name: " + absolutePath + 560 "\n Component/API name: " + name); 561 } else name = filename; 562 return NodeFactory.makeAPIName(NodeFactory.parserSpan, name); 563 } catch (NullPointerException ex) { 564 return NodeFactory.makeAPIName(NodeFactory.parserSpan, filename); 565 } 566 } catch (FileNotFoundException ex) { 567 throw new UserError("Cannot find file " + absolutePath); 568 } 569 569 } 570 570 571 571 public static Iterable<Id> getIds(final Id qName) { 572 return qName.getApiName().apply(new OptionVisitor<APIName, Iterable<Id>>() {573 public Iterable<Id> forSome(APIName apiName) {574 return IterUtil.compose(apiName.getIds(), qName);575 }576 public Iterable<Id> forNone() {577 return IterUtil.singleton(qName);578 }579 });572 return qName.getApiName().apply(new OptionVisitor<APIName, Iterable<Id>>() { 573 public Iterable<Id> forSome(APIName apiName) { 574 return IterUtil.compose(apiName.getIds(), qName); 575 } 576 public Iterable<Id> forNone() { 577 return IterUtil.singleton(qName); 578 } 579 }); 580 580 } 581 581 … … 587 587 */ 588 588 public static int selfParameterIndex(Applicable d) { 589 int i = 0;590 for (Param p : getParams(d)) {591 Id name = p.getName();592 if (WellKnownNames.defaultSelfName.equals(nameString(name))) {593 return i;594 }595 i++;596 }597 return -1;589 int i = 0; 590 for (Param p : getParams(d)) { 591 Id name = p.getName(); 592 if (WellKnownNames.defaultSelfName.equals(nameString(name))) { 593 return i; 594 } 595 i++; 596 } 597 return -1; 598 598 } 599 599 600 600 /* for Applicable ******************************************************/ 601 601 public static String nameAsMethod(Applicable app) { 602 String name = nameString(getName(app));603 int spi = selfParameterIndex(app);604 if (spi >= 0)605 return "rm$" + spi + "$" + name;606 else607 return name;602 String name = nameString(getName(app)); 603 int spi = selfParameterIndex(app); 604 if (spi >= 0) 605 return "rm$" + spi + "$" + name; 606 else 607 return name; 608 608 609 609 } 610 610 611 611 public static Option<Expr> getBody(Applicable def) { 612 if (def instanceof FnDecl) { return ((FnDecl)def).getBody(); }613 else if (def instanceof FnExpr) { return Option.some(((FnExpr)def).getBody()); }614 else { return Option.none(); }612 if (def instanceof FnDecl) { return ((FnDecl)def).getBody(); } 613 else if (def instanceof FnExpr) { return Option.some(((FnExpr)def).getBody()); } 614 else { return Option.none(); } 615 615 } 616 616 617 617 public static boolean hasVarargs(Type t) { 618 if ( isTupleType(t) )619 return hasVarargs((TupleType)t);620 else {621 bug("TupleType expected, but got " + t);622 return false;623 }618 if ( isTupleType(t) ) 619 return hasVarargs((TupleType)t); 620 else { 621 bug("TupleType expected, but got " + t); 622 return false; 623 } 624 624 } 625 625 626 626 public static boolean hasKeywords(Type t) { 627 if ( isTupleType(t) )628 return hasKeywords((TupleType)t);629 else {630 bug("TupleType expected, but got " + t);631 return false;632 }627 if ( isTupleType(t) ) 628 return hasKeywords((TupleType)t); 629 else { 630 bug("TupleType expected, but got " + t); 631 return false; 632 } 633 633 } 634 634 635 635 public static boolean hasVarargs(TupleType t) { 636 return t.getVarargs().isSome();636 return t.getVarargs().isSome(); 637 637 } 638 638 639 639 public static boolean hasKeywords(TupleType t) { 640 return ! t.getKeywords().isEmpty();640 return ! t.getKeywords().isEmpty(); 641 641 } 642 642 643 643 public static boolean isVarargsParam(Param p) { 644 return p.getVarargsType().isSome();644 return p.getVarargsType().isSome(); 645 645 } 646 646 647 647 public static boolean isKeywordParam(Param p) { 648 return p.getDefaultExpr().isSome();648 return p.getDefaultExpr().isSome(); 649 649 } 650 650 651 651 public static boolean isSingletonObject(VarRef v) { 652 return (! v.getStaticArgs().isEmpty());652 return (! v.getStaticArgs().isEmpty()); 653 653 } 654 654 655 655 public static boolean isGenericSingletonType(TraitType t) { 656 return (! t.getStaticParams().isEmpty());656 return (! t.getStaticParams().isEmpty()); 657 657 } 658 658 659 659 public static boolean isVoidType(Type t) { 660 if ( t instanceof TupleType ) {661 TupleType _t = (TupleType)t;662 return ( _t.getElements().isEmpty() &&663 _t.getVarargs().isNone() &&664 _t.getKeywords().isEmpty() );665 } else666 return false;660 if ( t instanceof TupleType ) { 661 TupleType _t = (TupleType)t; 662 return ( _t.getElements().isEmpty() && 663 _t.getVarargs().isNone() && 664 _t.getKeywords().isEmpty() ); 665 } else 666 return false; 667 667 } 668 668 669 669 public static boolean isTupleType(Type t) { 670 return ( t instanceof TupleType );670 return ( t instanceof TupleType ); 671 671 } 672 672 673 673 public static int getTupleTypeSize(Type t) { 674 if ( isTupleType(t) )675 return ((TupleType)t).getElements().size();676 else {677 bug("TupleType expected, but got " + t);678 return 0;679 }674 if ( isTupleType(t) ) 675 return ((TupleType)t).getElements().size(); 676 else { 677 bug("TupleType expected, but got " + t); 678 return 0; 679 } 680 680 } 681 681 682 682 public static Type getTupleTypeElem(Type t, int i) { 683 if ( isTupleType(t) )684 return ((TupleType)t).getElements().get(i);685 else686 return bug("TupleType expected, but got " + t);683 if ( isTupleType(t) ) 684 return ((TupleType)t).getElements().get(i); 685 else 686 return bug("TupleType expected, but got " + t); 687 687 } 688 688 689 689 public static boolean differentArity(TupleType first, TupleType second) { 690 return ( isVoidType(first) && ! isVoidType(second) ) ||691 ( isVoidType(second) && ! isVoidType(first) ) ||692 ( first.getVarargs().isNone() && second.getVarargs().isNone() &&693 first.getKeywords().isEmpty() && second.getKeywords().isEmpty() &&694 first.getElements().size() != second.getElements().size() );690 return ( isVoidType(first) && ! isVoidType(second) ) || 691 ( isVoidType(second) && ! isVoidType(first) ) || 692 ( first.getVarargs().isNone() && second.getVarargs().isNone() && 693 first.getKeywords().isEmpty() && second.getKeywords().isEmpty() && 694 first.getElements().size() != second.getElements().size() ); 695 695 } 696 696 697 697 /* for Param ***********************************************************/ 698 698 public static boolean isMultifix(List<Param> params) { 699 for (Param p : params) {700 if ( isVarargsParam(p) )701 return true;702 }703 return (params.size() > 2);699 for (Param p : params) { 700 if ( isVarargsParam(p) ) 701 return true; 702 } 703 return (params.size() > 2); 704 704 } 705 705 706 706 public static boolean isMutable(Param p) { 707 return p.getMods().isMutable();707 return p.getMods().isMutable(); 708 708 } 709 709 710 710 public final static NodeVisitor<String> nameSuffixGetter = 711 new NodeAbstractVisitor<String>() {712 @Override public String forAPIName(APIName n) {713 return n.getText();714 }715 public String forId(Id n) {716 return n.getText();717 }718 public String forOp(Op n) {719 if ( n.isEnclosing() )720 return n.getText();721 else return OprUtil.fixityDecorator(n.getFixity(), n.getText());722 }723 public String forAnonymousFnName(AnonymousFnName n) {724 return getSpan(n).toString();725 }711 new NodeAbstractVisitor<String>() { 712 @Override public String forAPIName(APIName n) { 713 return n.getText(); 714 } 715 public String forId(Id n) { 716 return n.getText(); 717 } 718 public String forOp(Op n) { 719 if ( n.isEnclosing() ) 720 return n.getText(); 721 else return OprUtil.fixityDecorator(n.getFixity(), n.getText()); 722 } 723 public String forAnonymousFnName(AnonymousFnName n) { 724 return getSpan(n).toString(); 725 } 726 726 }; 727 727 728 728 public static String nameSuffixString(AbstractNode n) { 729 return n.accept(nameSuffixGetter);729 return n.accept(nameSuffixGetter); 730 730 } 731 731 732 732 private final static NodeVisitor<String> nameGetter = 733 new NodeAbstractVisitor<String>() {734 735 @Override public String forAPIName(APIName n) {736 return n.getText();737 }738 @Override public String forIdOrOpOrAnonymousName(IdOrOpOrAnonymousName n) {739 return nameString(n);740 }741 public String forId(Id n) {742 final String last = n.getText();743 Option<APIName> odn = n.getApiName();744 return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last;745 }746 public String forOp(Op n) {747 if ( n.isEnclosing() ) {748 Option<APIName> odn = n.getApiName();749 String last = n.getText();750 return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last;751 } else {752 Option<APIName> odn = n.getApiName();753 String last = OprUtil.fixityDecorator(n.getFixity(), n.getText());754 return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last;755 }756 }757 public String forAnonymousFnName(AnonymousFnName n) {758 return getSpan(n).toString();759 }760 public String forConstructorFnName(ConstructorFnName n) {761 // TODO Auto-generated method stub762 return nameString(n);763 }733 new NodeAbstractVisitor<String>() { 734 735 @Override public String forAPIName(APIName n) { 736 return n.getText(); 737 } 738 @Override public String forIdOrOpOrAnonymousName(IdOrOpOrAnonymousName n) { 739 return nameString(n); 740 } 741 public String forId(Id n) { 742 final String last = n.getText(); 743 Option<APIName> odn = n.getApiName(); 744 return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 745 } 746 public String forOp(Op n) { 747 if ( n.isEnclosing() ) { 748 Option<APIName> odn = n.getApiName(); 749 String last = n.getText(); 750 return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 751 } else { 752 Option<APIName> odn = n.getApiName(); 753 String last = OprUtil.fixityDecorator(n.getFixity(), n.getText()); 754 return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 755 } 756 } 757 public String forAnonymousFnName(AnonymousFnName n) { 758 return getSpan(n).toString(); 759 } 760 public String forConstructorFnName(ConstructorFnName n) { 761 // TODO Auto-generated method stub 762 return nameString(n); 763 } 764 764 }; 765 765 766 766 public static Modifiers getMods(LValue f) { 767 return f.getMods();767 return f.getMods(); 768 768 } 769 769 770 770 /* nameString *************************************************************/ 771 771 public static String nameString(Name n) { 772 return n.accept(nameGetter);772 return n.accept(nameGetter); 773 773 } 774 774 775 775 public static String nameString(IdOrOpOrAnonymousName n) { 776 return n.accept(nameGetter);776 return n.accept(nameGetter); 777 777 } 778 778 779 779 public static String nameString(APIName n) { 780 return n.getText();780 return n.getText(); 781 781 // Iterable<String> ns = IterUtil.map(n.getIds(), IdToStringFn); 782 782 // return IterUtil.toString(ns, "", ".", ""); … … 784 784 785 785 public static String dirString(APIName n) { 786 Iterable<String> ns = IterUtil.map(n.getIds(), IdToStringFn);787 // NOT File.separator -- that is unnecessary and confusing.788 return IterUtil.toString(ns, "", "/", "");786 Iterable<String> ns = IterUtil.map(n.getIds(), IdToStringFn); 787 // NOT File.separator -- that is unnecessary and confusing. 788 return IterUtil.toString(ns, "", "/", ""); 789 789 } 790 790 791 791 public static String shortNameString(Id n) { 792 final String last = n.getText();793 Option<APIName> odn = n.getApiName();794 if (odn.isSome()) {795 APIName _odn = odn.unwrap();796 if (_odn.getText().equals(WellKnownNames.fortressBuiltin())797 || _odn.getText().equals(WellKnownNames.fortressLibrary())) {798 return last;799 } else {800 return nameString(odn.unwrap()) + "." + last;801 }802 } else {803 return last;804 }792 final String last = n.getText(); 793 Option<APIName> odn = n.getApiName(); 794 if (odn.isSome()) { 795 APIName _odn = odn.unwrap(); 796 if (_odn.getText().equals(WellKnownNames.fortressBuiltin()) 797 || _odn.getText().equals(WellKnownNames.fortressLibrary())) { 798 return last; 799 } else { 800 return nameString(odn.unwrap()) + "." + last; 801 } 802 } else { 803 return last; 804 } 805 805 } 806 806 807 807 public static String nameString(Id n) { 808 final String last = n.getText();809 Option<APIName> odn = n.getApiName();810 return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last;808 final String last = n.getText(); 809 Option<APIName> odn = n.getApiName(); 810 return odn.isSome() ? nameString(odn.unwrap()) + "." + last : last; 811 811 } 812 812 813 813 public static String nameString(Op n) { 814 if ( n.isEnclosing() )815 return n.getText();816 else return OprUtil.fixityDecorator(n.getFixity(), n.getText());814 if ( n.isEnclosing() ) 815 return n.getText(); 816 else return OprUtil.fixityDecorator(n.getFixity(), n.getText()); 817 817 } 818 818 public static String nameString(AnonymousFnName n) { 819 return getSpan(n).toString();819 return getSpan(n).toString(); 820 820 } 821 821 public static String nameString(ConstructorFnName n) { 822 // TODO Auto-generated method stub823 return stringName(n.getConstructor());822 // TODO Auto-generated method stub 823 return stringName(n.getConstructor()); 824 824 } 825 825 826 826 private static final Fn<Name, String> NameToStringFn = new Fn<Name, String>() { 827 public String apply(Name n) { return nameString(n); }827 public String apply(Name n) { return nameString(n); } 828 828 }; 829 829 830 830 public static String namesString(Iterable<? extends Name> names) { 831 return IterUtil.toString(IterUtil.map(names, NameToStringFn), "", ", ", "");831 return IterUtil.toString(IterUtil.map(names, NameToStringFn), "", ", ", ""); 832 832 } 833 833 834 834 /* getName *************************************************************/ 835 835 public static String getName(StaticParam param) { 836 if ( isOpParam(param) )837 return nameString(param.getName());838 else839 return param.getName().getText();836 if ( isOpParam(param) ) 837 return nameString(param.getName()); 838 else 839 return param.getName().getText(); 840 840 } 841 841 842 842 private final static NodeAbstractVisitor<String> stringNameVisitor = 843 new NodeAbstractVisitor<String>() {844 @Override845 public String forId(Id that) {846 return that.getText();847 }848 @Override849 public String forOp(Op that) {850 if ( that.isEnclosing() )851 return that.getText();852 else return OprUtil.fixityDecorator(that.getFixity(), that.getText());853 }854 @Override855 public String forDimDecl(DimDecl node) {856 return nameString(node.getDimId());857 }858 @Override859 public String forUnitDecl(UnitDecl node) {860 List<Id> ids = node.getUnits();861 if (ids.size() < 1)862 return bug("Unit declarations should have a name.");863 else return nameString(ids.get(0));864 }865 @Override866 public String forFnDecl(FnDecl node) {867 return nameString(getName(node));868 }869 @Override870 public String forIdOrOpOrAnonymousName(IdOrOpOrAnonymousName node) {871 return nameString(node);872 }873 @Override874 public String forObjectDecl(ObjectDecl node) {875 return getName(node).getText();876 }877 @Override878 public String for_RewriteObjectExpr(_RewriteObjectExpr node) {879 return node.getGenSymName();880 }881 @Override882 public String forTraitDecl(TraitDecl node) {883 return getName(node).getText();884 }885 @Override886 public String forTypeAlias(TypeAlias node) {887 return node.getName().getText();888 }889 @Override890 public String forOpRef(OpRef node) {891 return node.getOriginalName().accept(this);892 }893 @Override894 public String forVarRef(VarRef node) {895 return node.getVarId().accept(this);896 }897 898 @Override899 public String defaultCase(Node node) {900 return node.getClass().getSimpleName();901 }843 new NodeAbstractVisitor<String>() { 844 @Override 845 public String forId(Id that) { 846 return that.getText(); 847 } 848 @Override 849 public String forOp(Op that) { 850 if ( that.isEnclosing() ) 851 return that.getText(); 852 else return OprUtil.fixityDecorator(that.getFixity(), that.getText()); 853 } 854 @Override 855 public String forDimDecl(DimDecl node) { 856 return nameString(node.getDimId()); 857 } 858 @Override 859 public String forUnitDecl(UnitDecl node) { 860 List<Id> ids = node.getUnits(); 861 if (ids.size() < 1) 862 return bug("Unit declarations should have a name."); 863 else return nameString(ids.get(0)); 864 } 865 @Override 866 public String forFnDecl(FnDecl node) { 867 return nameString(getName(node)); 868 } 869 @Override 870 public String forIdOrOpOrAnonymousName(IdOrOpOrAnonymousName node) { 871 return nameString(node); 872 } 873 @Override 874 public String forObjectDecl(ObjectDecl node) { 875 return getName(node).getText(); 876 } 877 @Override 878 public String for_RewriteObjectExpr(_RewriteObjectExpr node) { 879 return node.getGenSymName(); 880 } 881 @Override 882 public String forTraitDecl(TraitDecl node) { 883 return getName(node).getText(); 884 } 885 @Override 886 public String forTypeAlias(TypeAlias node) { 887 return node.getName().getText(); 888 } 889 @Override 890 public String forOpRef(OpRef node) { 891 return node.getOriginalName().accept(this); 892 } 893 @Override 894 public String forVarRef(VarRef node) { 895 return node.getVarId().accept(this); 896 } 897 898 @Override 899 public String defaultCase(Node node) { 900 return node.getClass().getSimpleName(); 901 } 902 902 }; 903 903 … … 905 905 /* stringName **********************************************************/ 906 906 public static String stringName(Node the_node) { 907 return the_node.accept(stringNameVisitor);907 return the_node.accept(stringNameVisitor); 908 908 } 909 909 910 910 /* stringNames *********************************************************/ 911 911 public static IterableOnce<String> stringNames(LValue lv) { 912 return new UnitIterable<String>(lv.getName().getText());912 return new UnitIterable<String>(lv.getName().getText()); 913 913 } 914 914 915 915 public static IterableOnce<String> stringNames(Decl decl) { 916 return decl.accept(new NodeAbstractVisitor<IterableOnce<String>>() {917 public IterableOnce<String> forDimDecl(DimDecl d) {918 return new UnitIterable<String>(d.getDimId().getText());919 }920 public IterableOnce<String> forUnitDecl(UnitDecl d) {921 List<Id> ids = d.getUnits();922 if (ids.size() < 1)923 return bug("Unit declarations should have a name.");924 else return new UnitIterable<String>(nameString(ids.get(0)));925 }926 public IterableOnce<String> forFnExpr(FnExpr d) {927 return new UnitIterable<String>(nameString(d.getHeader().getName()));928 }929 public IterableOnce<String> forFnDecl(FnDecl d) {930 return new UnitIterable<String>(nameString(getName(d)));931 }932 public IterableOnce<String> forLetFn(LetFn d) {933 return new UnitIterable<String>(d.getClass().getSimpleName());934 }935 public IterableOnce<String> forLocalVarDecl(LocalVarDecl d) {936 return new IterableOnceForLValueList(d.getLhs());937 }938 public IterableOnce<String> forObjectDecl(ObjectDecl d) {939 return new UnitIterable<String>(getName(d).getText());940 }941 public IterableOnce<String> for_RewriteObjectExpr(_RewriteObjectExpr d) {942 return new UnitIterable<String>(d.getGenSymName());943 }944 public IterableOnce<String> forPropertyDecl(PropertyDecl d) {945 return d.getName().apply(new OptionVisitor<Id, IterableOnce<String>>() {946 public IterableOnce<String> forSome(Id name) {947 return new UnitIterable<String>(name.getText());948 }949 public IterableOnce<String> forNone() {950 return new UnitIterable<String>("_");951 }952 });953 }954 public IterableOnce<String> forTestDecl(TestDecl d) {955 return new UnitIterable<String>(d.getName().getText());956 }957 public IterableOnce<String> forTraitDecl(TraitDecl d) {958 return new UnitIterable<String>(getName(d).getText());959 }960 public IterableOnce<String> forTypeAlias(TypeAlias d) {961 return new UnitIterable<String>(d.getName().getText());962 }963 public IterableOnce<String> forVarDecl(VarDecl d) {964 return new IterableOnceForLValueList(d.getLhs());965 }966 public IterableOnce<String> forGrammarDecl(GrammarDecl d) {967 return new UnitIterable<String>(d.getName().getText());968 }969 public IterableOnce<String> for_RewriteFnOverloadDecl(_RewriteFnOverloadDecl d) {970 return new UnitIterable<String>(nameString(d.getName()));971 }972 });916 return decl.accept(new NodeAbstractVisitor<IterableOnce<String>>() { 917 public IterableOnce<String> forDimDecl(DimDecl d) { 918 return new UnitIterable<String>(d.getDimId().getText()); 919 } 920 public IterableOnce<String> forUnitDecl(UnitDecl d) { 921 List<Id> ids = d.getUnits(); 922 if (ids.size() < 1) 923 return bug("Unit declarations should have a name."); 924 else return new UnitIterable<String>(nameString(ids.get(0))); 925 } 926 public IterableOnce<String> forFnExpr(FnExpr d) { 927 return new UnitIterable<String>(nameString(d.getHeader().getName())); 928 } 929 public IterableOnce<String> forFnDecl(FnDecl d) { 930 return new UnitIterable<String>(nameString(getName(d))); 931 } 932 public IterableOnce<String> forLetFn(LetFn d) { 933 return new UnitIterable<String>(d.getClass().getSimpleName()); 934 } 935 public IterableOnce<String> forLocalVarDecl(LocalVarDecl d) { 936 return new IterableOnceForLValueList(d.getLhs()); 937 } 938 public IterableOnce<String> forObjectDecl(ObjectDecl d) { 939 return new UnitIterable<String>(getName(d).getText()); 940 } 941 public IterableOnce<String> for_RewriteObjectExpr(_RewriteObjectExpr d) { 942 return new UnitIterable<String>(d.getGenSymName()); 943 } 944 public IterableOnce<String> forPropertyDecl(PropertyDecl d) { 945 return d.getName().apply(new OptionVisitor<Id, IterableOnce<String>>() { 946 public IterableOnce<String> forSome(Id name) { 947 return new UnitIterable<String>(name.getText()); 948 } 949 public IterableOnce<String> forNone() { 950 return new UnitIterable<String>("_"); 951 } 952 }); 953 } 954 public IterableOnce<String> forTestDecl(TestDecl d) { 955 return new UnitIterable<String>(d.getName().getText()); 956 } 957 public IterableOnce<String> forTraitDecl(TraitDecl d) { 958 return new UnitIterable<String>(getName(d).getText()); 959 } 960 public IterableOnce<String> forTypeAlias(TypeAlias d) { 961 return new UnitIterable<String>(d.getName().getText()); 962 } 963 public IterableOnce<String> forVarDecl(VarDecl d) { 964 return new IterableOnceForLValueList(d.getLhs()); 965 } 966 public IterableOnce<String> forGrammarDecl(GrammarDecl d) { 967 return new UnitIterable<String>(d.getName().getText()); 968 } 969 public IterableOnce<String> for_RewriteFnOverloadDecl(_RewriteFnOverloadDecl d) { 970 return new UnitIterable<String>(nameString(d.getName())); 971 } 972 }); 973 973 } 974 974 975 975 /* dump ****************************************************************/ 976 976 public static String dump(AbstractNode n) { 977 try {978 StringBuffer sb = new StringBuffer();979 dump(sb, n);980 return sb.toString();981 } catch (Throwable ex) {982 return "Exception " + ex + " during dump";983 }977 try { 978 StringBuffer sb = new StringBuffer(); 979 dump(sb, n); 980 return sb.toString(); 981 } catch (Throwable ex) { 982 return "Exception " + ex + " during dump"; 983 } 984 984 } 985 985 … … 988 988 */ 989 989 public static void dump(Appendable appendable, AbstractNode n) throws IOException { 990 Printer p = new Printer(true, true, true);991 p.dump(n, appendable, 0);990 Printer p = new Printer(true, true, true); 991 p.dump(n, appendable, 0); 992 992 } 993 993 994 994 public static <T> T NYI(String s) { 995 return (T)bug("AST." + s + " NYI");995 return (T)bug("AST." + s + " NYI"); 996 996 } 997 997 998 998 /* Boolean functions for FnDecls. */ 999 999 public static boolean isGetter(FnDecl decl) { 1000 return getMods(decl).isGetter();1000 return getMods(decl).isGetter(); 1001 1001 } 1002 1002 1003 1003 public static boolean isSetter(FnDecl decl) { 1004 return getMods(decl).isSetter();1004 return getMods(decl).isSetter(); 1005 1005 } 1006 1006 1007 1007 public static boolean isOp(FnDecl decl) { 1008 return getName(decl) instanceof Op;1008 return getName(decl) instanceof Op; 1009 1009 } 1010 1010 1011 1011 /* for APIName ******************************************************/ 1012 1012 private static final Fn<Id, String> IdToStringFn = new Fn<Id, String>() { 1013 public String apply(Id x) {1014 return stringName(x);1015 }1013 public String apply(Id x) { 1014 return stringName(x); 1015 } 1016 1016 }; 1017 1017 1018 1018 public static List<String> toStrings(APIName n) { 1019 return Useful.applyToAll(n.getIds(), IdToStringFn);1019 return Useful.applyToAll(n.getIds(), IdToStringFn); 1020 1020 } 1021 1021 1022 1022 /* for TraitTypeWhere **************************************************/ 1023 1023 public static List<BaseType> getTypes(List<TraitTypeWhere> l) { 1024 List<BaseType> t = new ArrayList<BaseType>(l.size());1025 for (TraitTypeWhere tw : l) {1026 t.add(tw.getBaseType());1027 }1028 return t;1024 List<BaseType> t = new ArrayList<BaseType>(l.size()); 1025 for (TraitTypeWhere tw : l) { 1026 t.add(tw.getBaseType()); 1027 } 1028 return t; 1029 1029 } 1030 1030 1031 1031 /* for Type and StaticExpr **********************************************/ 1032 1032 public static void validTraitTypes(BufferedWriter writer, 1033 List<? extends BaseType> types) {1034 for (BaseType ty: types) {1035 if ( ty instanceof NamedType &&1036 validOp(((NamedType)ty).getName().getText()) )1037 log(writer, getSpan(ty), "Operator name, " +1038 ((NamedType)ty).getName().getText() +1039 ", is not a valid type name.");1040 }1033 List<? extends BaseType> types) { 1034 for (BaseType ty: types) { 1035 if ( ty instanceof NamedType && 1036 validOp(((NamedType)ty).getName().getText()) ) 1037 log(writer, getSpan(ty), "Operator name, " + 1038 ((NamedType)ty).getName().getText() + 1039 ", is not a valid type name."); 1040 } 1041 1041 } 1042 1042 1043 1043 public static void validTraitTypeWheres(BufferedWriter writer, 1044 List<TraitTypeWhere> types) {1045 for (TraitTypeWhere typ: types) {1046 BaseType ty = typ.getBaseType();1047 if ( ty instanceof NamedType &&1048 validOp(((NamedType)ty).getName().getText()) )1049 log(writer, getSpan(ty), "Operator name, " +1050 ((NamedType)ty).getName().getText() +1051 ", is not a valid type name.");1052 }1044 List<TraitTypeWhere> types) { 1045 for (TraitTypeWhere typ: types) { 1046 BaseType ty = typ.getBaseType(); 1047 if ( ty instanceof NamedType && 1048 validOp(((NamedType)ty).getName().getText()) ) 1049 log(writer, getSpan(ty), "Operator name, " + 1050 ((NamedType)ty).getName().getText() + 1051 ", is not a valid type name."); 1052 } 1053 1053 } 1054 1054 1055 1055 public static boolean isExponentiation(Type type) { 1056 return (type instanceof ArrayType ||1057 type instanceof MatrixType ||1058 type instanceof DimExponent);1056 return (type instanceof ArrayType || 1057 type instanceof MatrixType || 1058 type instanceof DimExponent); 1059 1059 } 1060 1060 public static boolean isExponentiation(IntExpr staticExpr) { 1061 return (staticExpr instanceof IntBinaryOp &&1062 ((IntBinaryOp)staticExpr).getOp().getText().equals("^"));1061 return (staticExpr instanceof IntBinaryOp && 1062 ((IntBinaryOp)staticExpr).getOp().getText().equals("^")); 1063 1063 } 1064 1064 1065 1065 public static String nameString(BoolRef vre) { 1066 return nameString(vre.getName());1066 return nameString(vre.getName()); 1067 1067 } 1068 1068 public static String nameString(IntRef vre) { 1069 return nameString(vre.getName());1069 return nameString(vre.getName()); 1070 1070 } 1071 1071 1072 1072 /* for Literals ********************************************************/ 1073 1073 public static boolean validRadix(BufferedWriter writer, 1074 Span span, String radix) {1075 String[] all = new String[]{"2","3","4","5","6","7","8","9","10",1076 "11","12","13","14","15","16"};1077 List<String> validRadix = new LinkedList<String>(java.util.Arrays.asList(all));1078 if (! validRadix.contains( radix )) {1079 log(writer, span, "Syntax Error: the radix of " +1080 "a numeral must be an integer from 2 to 16.");1081 return false;1082 } else return true;1074 Span span, String radix) { 1075 String[] all = new String[]{"2","3","4","5","6","7","8","9","10", 1076 "11","12","13","14","15","16"}; 1077 List<String> validRadix = new LinkedList<String>(java.util.Arrays.asList(all)); 1078 if (! validRadix.contains( radix )) { 1079 log(writer, span, "Syntax Error: the radix of " + 1080 "a numeral must be an integer from 2 to 16."); 1081 return false; 1082 } else return true; 1083 1083 } 1084 1084 1085 1085 public static boolean validIntLiteral(String numeral) { 1086 for (int index = 0; index < numeral.length(); index++) {1087 if (numeral.charAt(index) == '.')1088 return false;1089 }1090 return true;1086 for (int index = 0; index < numeral.length(); index++) { 1087 if (numeral.charAt(index) == '.') 1088 return false; 1089 } 1090 return true; 1091 1091 } 1092 1092 1093 1093 public static void validNumericLiteral(BufferedWriter writer, 1094 Span span, String numeral) {1095 int numberOfDots = 0;1096 for (int index = 0; index < numeral.length(); index++) {1097 char c = numeral.charAt(index);1098 if (Character.isLetter(c))1099 log(writer, span, "Syntax Error: a numeral contains " +1100 "letters and does not have a radix specifier.");1101 if (c == '.') numberOfDots++;1102 }1103 if (numberOfDots > 1)1104 log(writer, span, "Syntax Error: a numeral contains more " +1105 "than one `.' character.");1094 Span span, String numeral) { 1095 int numberOfDots = 0; 1096 for (int index = 0; index < numeral.length(); index++) { 1097 char c = numeral.charAt(index); 1098 if (Character.isLetter(c)) 1099 log(writer, span, "Syntax Error: a numeral contains " + 1100 "letters and does not have a radix specifier."); 1101 if (c == '.') numberOfDots++; 1102 } 1103 if (numberOfDots > 1) 1104 log(writer, span, "Syntax Error: a numeral contains more " + 1105 "than one `.' character."); 1106 1106 } 1107 1107 1108 1108 public static void validNumericLiteral(BufferedWriter writer, 1109 Span span, String numeral,1110 String radix) {1111 int radixNumber = radix2Number(radix);1112 if (radixNumber == -1)1113 log(writer, span, "Syntax Error: the radix of " +1114 "a numeral should be an integer from 2 to 16.");1115 boolean sawUpperCase = false;1116 boolean sawLowerCase = false;1117 boolean sawAb = false;1118 boolean sawXe = false;1119 int numberOfDots = 0;1120 for (int index = 0; index < numeral.length(); index++) {1121 char c = numeral.charAt(index);1122 if (c == '.') numberOfDots++;1123 if (Character.isUpperCase(c)) {1124 if (sawLowerCase)1125 log(writer, span, "Syntax Error: a numeral " +1126 "contains both uppercase and lowercase letters.");1127 else sawUpperCase = true;1128 } else if (Character.isLowerCase(c)) {1129 if (sawUpperCase)1130 log(writer, span, "Syntax Error: a numeral " +1131 "contains both uppercase and lowercase letters.");1132 else sawLowerCase = true;1133 }1134 if (radixNumber == 12) {1135 if (!validDigitOrLetterIn12(c)1136 && c != '.' && c != '\'' && c != '\u202F') {1109 Span span, String numeral, 1110 String radix) { 1111 int radixNumber = radix2Number(radix); 1112 if (radixNumber == -1) 1113 log(writer, span, "Syntax Error: the radix of " + 1114 "a numeral should be an integer from 2 to 16."); 1115 boolean sawUpperCase = false; 1116 boolean sawLowerCase = false; 1117 boolean sawAb = false; 1118 boolean sawXe = false; 1119 int numberOfDots = 0; 1120 for (int index = 0; index < numeral.length(); index++) { 1121 char c = numeral.charAt(index); 1122 if (c == '.') numberOfDots++; 1123 if (Character.isUpperCase(c)) { 1124 if (sawLowerCase) 1125 log(writer, span, "Syntax Error: a numeral " + 1126 "contains both uppercase and lowercase letters."); 1127 else sawUpperCase = true; 1128 } else if (Character.isLowerCase(c)) { 1129 if (sawUpperCase) 1130 log(writer, span, "Syntax Error: a numeral " + 1131 "contains both uppercase and lowercase letters."); 1132 else sawLowerCase = true; 1133 } 1134 if (radixNumber == 12) { 1135 if (!validDigitOrLetterIn12(c) 1136 && c != '.' && c != '\'' && c != '\u202F') { 1137 1137 log(writer, span, "Syntax Error: a numeral " + 1138 "has radix 12 and contains letters other " +1139 "than A, B, X, E, a, b, x or e.");1140 }1141 if (c == 'A' || c == 'a' || c == 'B' || c == 'b') {1142 if (sawXe)1143 log(writer, span, "Syntax Error: a numeral " +1144 "has radix 12 and contains at least one " +1145 "A, B, a or b and at least one X, E, x or e.");1146 else sawAb = true;1147 } else if (c == 'X' || c == 'x' || c == 'E' || c == 'e') {1148 if (sawAb)1149 log(writer, span, "Syntax Error: a numeral " +1150 "has radix 12 and contains at least one " +1151 "A, B, a or b and at least one X, E, x or e.");1152 else sawXe = true;1153 }1154 }1155 // The numeral has a radix other than 12.1156 else if (!validDigitOrLetter(c, radixNumber)1157 && c != '.' && c != '\'' && c != '\u202F') {1158 log(writer, span, "Syntax Error: a numeral has a radix " +1159 "specifier and contains a digit or letter that " +1160 "denotes a value greater than or equal to the " +1161 "numeral's radix.");1162 }1163 }1164 if (numberOfDots > 1)1165 log(writer, span, "Syntax Error: a numeral contains more " +1166 "than one `.' character.");1138 "has radix 12 and contains letters other " + 1139 "than A, B, X, E, a, b, x or e."); 1140 } 1141 if (c == 'A' || c == 'a' || c == 'B' || c == 'b') { 1142 if (sawXe) 1143 log(writer, span, "Syntax Error: a numeral " + 1144 "has radix 12 and contains at least one " + 1145 "A, B, a or b and at least one X, E, x or e."); 1146 else sawAb = true; 1147 } else if (c == 'X' || c == 'x' || c == 'E' || c == 'e') { 1148 if (sawAb) 1149 log(writer, span, "Syntax Error: a numeral " + 1150 "has radix 12 and contains at least one " + 1151 "A, B, a or b and at least one X, E, x or e."); 1152 else sawXe = true; 1153 } 1154 } 1155 // The numeral has a radix other than 12. 1156 else if (!validDigitOrLetter(c, radixNumber) 1157 && c != '.' && c != '\'' && c != '\u202F') { 1158 log(writer, span, "Syntax Error: a numeral has a radix " + 1159 "specifier and contains a digit or letter that " + 1160 "denotes a value greater than or equal to the " + 1161 "numeral's radix."); 1162 } 1163 } 1164 if (numberOfDots > 1) 1165 log(writer, span, "Syntax Error: a numeral contains more " + 1166 "than one `.' character."); 1167 1167 } 1168 1168 1169 1169 public static int radix2Number(String radix) { 1170 if (radix.equals("2") || radix.equals("TWO")) {1171 return 2;1172 } else if (radix.equals("3") || radix.equals("THREE")) {1173 return 3;1174 } else if (radix.equals("4") || radix.equals("FOUR")) {1175 return 4;1176 } else if (radix.equals("5") || radix.equals("FIVE")) {1177 return 5;1178 } else if (radix.equals("6") || radix.equals("SIX")) {1179 return 6;1180 } else if (radix.equals("7") || radix.equals("SEVEN")) {1181 return 7;1182 } else if (radix.equals("8") || radix.equals("EIGHT")) {1183 return 8;1184 } else if (radix.equals("9") || radix.equals("NINE")) {1185 return 9;1186 } else if (radix.equals("10") || radix.equals("TEN")) {1187 return 10;1188 } else if (radix.equals("11") || radix.equals("ELEVEN")) {1189 return 11;1190 } else if (radix.equals("12") || radix.equals("TWELVE")) {1191 return 12;1192 } else if (radix.equals("13") || radix.equals("THIRTEEN")) {1193 return 13;1194 } else if (radix.equals("14") || radix.equals("FOURTEEN")) {1195 return 14;1196 } else if (radix.equals("15") || radix.equals("FIFTEEN")) {1197 return 15;1198 } else if (radix.equals("16") || radix.equals("SIXTEEN")) {1199 return 16;1200 } else {1201 /* radix is not valid. */1202 return -1;1203 }1170 if (radix.equals("2") || radix.equals("TWO")) { 1171 return 2; 1172 } else if (radix.equals("3") || radix.equals("THREE")) { 1173 return 3; 1174 } else if (radix.equals("4") || radix.equals("FOUR")) { 1175 return 4; 1176 } else if (radix.equals("5") || radix.equals("FIVE")) { 1177 return 5; 1178 } else if (radix.equals("6") || radix.equals("SIX")) { 1179 return 6; 1180 } else if (radix.equals("7") || radix.equals("SEVEN")) { 1181 return 7; 1182 } else if (radix.equals("8") || radix.equals("EIGHT")) { 1183 return 8; 1184 } else if (radix.equals("9") || radix.equals("NINE")) { 1185 return 9; 1186 } else if (radix.equals("10") || radix.equals("TEN")) { 1187 return 10; 1188 } else if (radix.equals("11") || radix.equals("ELEVEN")) { 1189 return 11; 1190 } else if (radix.equals("12") || radix.equals("TWELVE")) { 1191 return 12; 1192 } else if (radix.equals("13") || radix.equals("THIRTEEN")) { 1193 return 13; 1194 } else if (radix.equals("14") || radix.equals("FOURTEEN")) { 1195 return 14; 1196 } else if (radix.equals("15") || radix.equals("FIFTEEN")) { 1197 return 15; 1198 } else if (radix.equals("16") || radix.equals("SIXTEEN")) { 1199 return 16; 1200 } else { 1201 /* radix is not valid. */ 1202 return -1; 1203 } 1204 1204 } 1205 1205 1206 1206 private static boolean validDigitOrLetterIn12(char c) { 1207 if (Character.isLetter(c)) {1208 switch (c) {1209 case 'A':1210 case 'a':1211 case 'B':1212 case 'b':1213 case 'X':1214 case 'x':1215 case 'E':1216 case 'e': { break; }1217 default: {1218 /* c is not valid in radix 12. */1219 return false;1220 }1221 }1222 }1223 return true;1207 if (Character.isLetter(c)) { 1208 switch (c) { 1209 case 'A': 1210 case 'a': 1211 case 'B': 1212 case 'b': 1213 case 'X': 1214 case 'x': 1215 case 'E': 1216 case 'e': { break; } 1217 default: { 1218 /* c is not valid in radix 12. */ 1219 return false; 1220 } 1221 } 1222 } 1223 return true; 1224 1224 } 1225 1225 1226 1226 // radix is not 12. 1227 1227 private static boolean validDigitOrLetter(char c, int radix) { 1228 if ((radix < 10 && Character.digit(c, radix) > -1) ||1229 (radix >= 10 && Character.isDigit(c)))1230 return true;1231 switch (c) {1232 case 'A':1233 case 'a': {1234 if (radix <= 10) return false;1235 break;1236 }1237 case 'B':1238 case 'b': {1239 if (radix <= 11) return false;1240 break;1241 }1242 case 'C':1243 case 'c': {1244 if (radix <= 12) return false;1245 break;1246 }1247 case 'D':1248 case 'd': {1249 if (radix <= 13) return false;1250 break;1251 }1252 case 'E':1253 case 'e': {1254 if (radix <= 14)1255 return false;1256 break;1257 }1258 case 'F':1259 case 'f': {1260 if (radix <= 15) return false;1261 break;1262 }1263 default: {1264 /* c is not valid in a numeral of the radix. */1265 return false;1266 }1267 }1268 return true;1228 if ((radix < 10 && Character.digit(c, radix) > -1) || 1229 (radix >= 10 && Character.isDigit(c))) 1230 return true; 1231 switch (c) { 1232 case 'A': 1233 case 'a': { 1234 if (radix <= 10) return false; 1235 break; 1236 } 1237 case 'B': 1238 case 'b': { 1239 if (radix <= 11) return false; 1240 break; 1241 } 1242 case 'C': 1243 case 'c': { 1244 if (radix <= 12) return false; 1245 break; 1246 } 1247 case 'D': 1248 case 'd': { 1249 if (radix <= 13) return false; 1250 break; 1251 } 1252 case 'E': 1253 case 'e': { 1254 if (radix <= 14) 1255 return false; 1256 break; 1257 } 1258 case 'F': 1259 case 'f': { 1260 if (radix <= 15) return false; 1261 break; 1262 } 1263 default: { 1264 /* c is not valid in a numeral of the radix. */ 1265 return false; 1266 } 1267 } 1268 return true; 1269 1269 } 1270 1270 1271 1271 public static void checkSubscriptedAssignment(BufferedWriter writer, Span span, 1272 FnHeaderFront fhf, FnHeaderClause fhc) {1273 if ( fhf.isSubscriptedAssignment && fhc.getReturnType().isSome() &&1274 ! isVoidType(fhc.getReturnType().unwrap()) )1275 log(writer, span,1276 "If a return type is given in a subscripted assignment operator declaration,\n it must be ().");1272 FnHeaderFront fhf, FnHeaderClause fhc) { 1273 if ( fhf.isSubscriptedAssignment && fhc.getReturnType().isSome() && 1274 ! isVoidType(fhc.getReturnType().unwrap()) ) 1275 log(writer, span, 1276 "If a return type is given in a subscripted assignment operator declaration,\n it must be ()."); 1277 1277 } 1278 1278 … … 1282 1282 */ 1283 1283 public static Modifiers checkModifiers(BufferedWriter writer, final Span span, 1284 List<Modifiers> mods) {1285 Modifiers res = Modifiers.None;1286 int index = 0;1287 for (Modifiers mod : mods) {1288 if ( mod.isAbstract() && index > 0 )1289 log(writer, span,1290 "Modifier " + mod + " should come first.");1291 if ( (mod.isGetter() || mod.isSetter()) &&1292 index != mods.size()-1 )1293 log(writer, span,1294 "Modifier " + mod + " should come last.");1295 if (res.containsAny(mod)) {1296 log(writer, span,1297 "Modifier " + mod + " must not occur multiple times.");1298 }1299 res = res.combine(mod);1300 index++;1301 }1302 return res;1284 List<Modifiers> mods) { 1285 Modifiers res = Modifiers.None; 1286 int index = 0; 1287 for (Modifiers mod : mods) { 1288 if ( mod.isAbstract() && index > 0 ) 1289 log(writer, span, 1290 "Modifier " + mod + " should come first."); 1291 if ( (mod.isGetter() || mod.isSetter()) && 1292 index != mods.size()-1 ) 1293 log(writer, span, 1294 "Modifier " + mod + " should come last."); 1295 if (res.containsAny(mod)) { 1296 log(writer, span, 1297 "Modifier " + mod + " must not occur multiple times."); 1298 } 1299 res = res.combine(mod); 1300 index++; 1301 } 1302 return res; 1303 1303 } 1304 1304 1305 1305 public static void checkNoWrapped(BufferedWriter writer, 1306 Option<List<Param>> optParams) {1307 if ( optParams.isSome() ) {1308 List<Param> params = optParams.unwrap();1309 for ( Param param : params ) {1310 if (param.getMods().isWrapped()) {1311 log(writer, getSpan(param),1312 "The modifier \"wrapped\" cannot " +1313 "appear in an API.");1314 }1315 }1316 }1306 Option<List<Param>> optParams) { 1307 if ( optParams.isSome() ) { 1308 List<Param> params = optParams.unwrap(); 1309 for ( Param param : params ) { 1310 if (param.getMods().isWrapped()) { 1311 log(writer, getSpan(param), 1312 "The modifier \"wrapped\" cannot " + 1313 "appear in an API."); 1314 } 1315 } 1316 } 1317 1317 } 1318 1318 1319 1319 /* true if there exists a self parameter in the parameter list of a given FnDecl */ 1320 1320 public static boolean isFunctionalMethod(FnDecl f) { 1321 for (Param p : getParams(f)) {1322 if (p.getName().getText().equals("self")) return true;1323 }1324 return false;1321 for (Param p : getParams(f)) { 1322 if (p.getName().getText().equals("self")) return true; 1323 } 1324 return false; 1325 1325 } 1326 1326 1327 1327 /* true if there exists a self parameter in a given parameter list */ 1328 1328 public static boolean isFunctionalMethod(List<Param> params) { 1329 for (Param p : params) {1330 if (p.getName().getText().equals("self")) return true;1331 }1332 return false;1329 for (Param p : params) { 1330 if (p.getName().getText().equals("self")) return true; 1331 } 1332 return false; 1333 1333 } 1334 1334 1335 1335 public static void validId(final BufferedWriter writer, Id name) { 1336 name.accept(new NodeDepthFirstVisitor_void(){1337 public void forIdOnly(Id id){1338 if (id.getText().equals("outcome"))1339 log(writer, getSpan(id),1340 "Invalid variable name: 'outcome' is a reserved word.");1341 }1342 1343 public void defaultTemplateGap(TemplateGap g){1344 /* nothing */1345 }1346 1347 public void for_EllipsesIdOnly(_EllipsesId e){1348 /* nothing */1349 }1350 });1336 name.accept(new NodeDepthFirstVisitor_void(){ 1337 public void forIdOnly(Id id){ 1338 if (id.getText().equals("outcome")) 1339 log(writer, getSpan(id), 1340 "Invalid variable name: 'outcome' is a reserved word."); 1341 } 1342 1343 public void defaultTemplateGap(TemplateGap g){ 1344 /* nothing */ 1345 } 1346 1347 public void for_EllipsesIdOnly(_EllipsesId e){ 1348 /* nothing */ 1349 } 1350 }); 1351 1351 } 1352 1352 1353 1353 public static void validId(BufferedWriter writer, List<? extends LValue> lvs) { 1354 for (LValue lv : lvs) {1355 validId(writer, lv.getName());
