Changeset 3182
- Timestamp:
- 12/09/08 17:39:54 (12 months ago)
- Location:
- trunk/ProjectFortress
- Files:
-
- 19 modified
-
astgen/Fortress.ast (modified) (1 diff)
-
src/com/sun/fortress/compiler/desugarer/DottedMethodRewriteVisitor.java (modified) (2 diffs)
-
src/com/sun/fortress/compiler/desugarer/ObjectExpressionVisitor.java (modified) (4 diffs)
-
src/com/sun/fortress/compiler/desugarer/PreDisambiguationDesugaringVisitor.java (modified) (1 diff)
-
src/com/sun/fortress/compiler/desugarer/VarRefContainer.java (modified) (3 diffs)
-
src/com/sun/fortress/compiler/typechecker/TypeChecker.java (modified) (2 diffs)
-
src/com/sun/fortress/interpreter/evaluator/BuildEnvironments.java (modified) (1 diff)
-
src/com/sun/fortress/interpreter/evaluator/BuildNativeEnvironment.java (modified) (1 diff)
-
src/com/sun/fortress/interpreter/evaluator/Evaluator.java (modified) (8 diffs)
-
src/com/sun/fortress/interpreter/glue/NativeApp.java (modified) (3 diffs)
-
src/com/sun/fortress/interpreter/rewrite/DesugarerVisitor.java (modified) (6 diffs)
-
src/com/sun/fortress/nodes_util/DesugarerUtil.java (modified) (3 diffs)
-
src/com/sun/fortress/nodes_util/ExprFactory.java (modified) (5 diffs)
-
src/com/sun/fortress/parser/Expression.rats (modified) (1 diff)
-
src/com/sun/fortress/parser/templateparser/Gaps.rats (modified) (1 diff)
-
src/com/sun/fortress/parser_util/FortressUtil.java (modified) (1 diff)
-
src/com/sun/fortress/parser_util/precedence_resolver/ASTUtil.java (modified) (2 diffs)
-
src/com/sun/fortress/syntax_abstractions/phases/EllipsesJUTest.java (modified) (10 diffs)
-
src/com/sun/fortress/tools/FortressAstToConcrete.java (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ProjectFortress/astgen/Fortress.ast
r3178 r3182 914 914 * e.g.) myString.replace("foo", "few") 915 915 * e.g.) log log n 916 */ 917 abstract Juxt(FunctionalRef multiJuxt = ExprFactory.makeMultiJuxt(), 918 FunctionalRef infixJuxt = ExprFactory.makeInfixJuxt(), 919 List<Expr> exprs = new LinkedList<Expr>()); 920 /** 921 * juxtaposition with intervening whitespace 922 * e.g.) 3 5 923 */ 924 LooseJuxt(); 925 /** 926 * juxtaposition without intervening whitespace. If fnApp is true, 927 * then this juxtaposition should be type checked ONLY as a function 928 * application. This should be the case for desugarings only. 929 * e.g.) f(3+5) 930 */ 931 TightJuxt(boolean fnApp = false); 916 * 917 * loose juxtaposition 918 * juxtaposition with intervening whitespace 919 * e.g.) 3 5 920 * 921 * tight juxtaposition 922 * juxtaposition without intervening whitespace. If fnApp is true, 923 * then this juxtaposition should be type checked ONLY as a function 924 * application. This should be the case for desugarings only. 925 * e.g.) f(3+5) 926 */ 927 Juxt(FunctionalRef multiJuxt = ExprFactory.makeMultiJuxt(), 928 FunctionalRef infixJuxt = ExprFactory.makeInfixJuxt(), 929 List<Expr> exprs = new LinkedList<Expr>(), 930 boolean fnApp, boolean tight) implements OutAfterTypeChecking; 932 931 /** 933 932 * functional application -
trunk/ProjectFortress/src/com/sun/fortress/compiler/desugarer/DottedMethodRewriteVisitor.java
r3156 r3182 27 27 import com.sun.fortress.nodes.Expr; 28 28 import com.sun.fortress.nodes.FnRef; 29 import com.sun.fortress.nodes. LooseJuxt;29 import com.sun.fortress.nodes.Juxt; 30 30 import com.sun.fortress.nodes.MethodInvocation; 31 31 import com.sun.fortress.nodes.Node; 32 32 import com.sun.fortress.nodes.NodeUpdateVisitor; 33 33 import com.sun.fortress.nodes.ObjectDecl; 34 import com.sun.fortress.nodes.TightJuxt;35 34 import com.sun.fortress.nodes.VarRef; 36 35 import com.sun.fortress.nodes._RewriteFnApp; … … 59 58 60 59 @Override 61 public Node for LooseJuxt(LooseJuxt that) {60 public Node forJuxt(Juxt that) { 62 61 // FIXME: Not sure if I really need to recur on other things 63 62 List<Expr> exprs_result = recurOnListOfExpr(that.getExprs()); 64 65 63 Expr first = exprs_result.get(0); 66 64 if(first instanceof FnRef && methodRefs.contains(first)) { 67 65 FnRef fnRef = (FnRef) first; 68 MethodInvocation mi = makeMethodInvocationFrom( 69 fnRef, exprs_result.subList(1, exprs_result.size()) ); 66 MethodInvocation mi = makeMethodInvocationFrom(fnRef, exprs_result.subList(1, exprs_result.size()) ); 70 67 exprs_result = new LinkedList<Expr>(); 71 68 exprs_result.add(mi); 72 69 } 73 74 return forLooseJuxtOnly(that,that.getExprType(), that.getMultiJuxt(),75 that.getInfixJuxt(), exprs_result);70 return forJuxtOnly(that, 71 that.getExprType(), that.getMultiJuxt(), 72 that.getInfixJuxt(), exprs_result); 76 73 } 77 78 79 public Node forTightJuxt(TightJuxt that) {80 // FIXME: Not sure if I really need to recur on other things81 List<Expr> exprs_result = recurOnListOfExpr(that.getExprs());82 83 Expr first = exprs_result.get(0);84 if(first instanceof FnRef && methodRefs.contains(first)) {85 FnRef fnRef = (FnRef) first;86 MethodInvocation mi = makeMethodInvocationFrom(87 fnRef, exprs_result.subList(1, exprs_result.size()) );88 exprs_result = new LinkedList<Expr>();89 exprs_result.add(mi);90 }91 92 return forTightJuxtOnly(that, that.getExprType(), that.getMultiJuxt(),93 that.getInfixJuxt(), exprs_result);94 }95 96 74 97 75 public Node for_RewriteFnApp(_RewriteFnApp that) { -
trunk/ProjectFortress/src/com/sun/fortress/compiler/desugarer/ObjectExpressionVisitor.java
r3176 r3182 408 408 Pair<Id,Type> exitFnInfo = exitFnParamMap.get(exitKey); 409 409 if(exitFnInfo != null) { 410 List<Expr> exprs = new LinkedList<Expr>();411 410 Option<Expr> returnExpr = that.getReturnExpr(); 412 413 411 Id fnName = exitFnInfo.first(); 414 412 FnRef fnRef = ExprFactory.makeFnRef(fnName); 415 exprs.add(fnRef); 416 exprs.add( unwrapIfSomeElseAlternative(returnExpr, 417 ExprFactory.makeVoidLiteralExpr(span)) ); 418 419 return ExprFactory.makeTightJuxt(span, false, exprs); 413 Expr arg = unwrapIfSomeElseAlternative(returnExpr, 414 ExprFactory.makeVoidLiteralExpr(span)); 415 return ExprFactory.make_RewriteFnApp(fnRef, arg); 420 416 } else { 421 417 return that; … … 426 422 427 423 newObjectDecls.add(lifted); 428 TightJuxtcallToLifted = makeCallToLiftedObj(lifted, that, freeNames);424 Expr callToLifted = makeCallToLiftedObj(lifted, that, freeNames); 429 425 430 426 scopeStack.pop(); … … 435 431 436 432 437 private TightJuxtmakeCallToLiftedObj(ObjectDecl lifted,438 ObjectExpr objExpr,439 FreeNameCollection freeNames) {433 private Expr makeCallToLiftedObj(ObjectDecl lifted, 434 ObjectExpr objExpr, 435 FreeNameCollection freeNames) { 440 436 Span span = objExpr.getSpan(); 441 437 Id originalName = lifted.getName(); … … 460 456 List<Expr> exprs = makeArgsForCallToLiftedObj(objExpr, 461 457 freeNames, enclosingSelf); 462 exprs.add(0, fnRef); 463 464 TightJuxt callToConstructor = 465 ExprFactory.makeTightJuxt(span, objExpr.isParenthesized(), exprs); 466 467 return callToConstructor; 458 Expr arg = ExprFactory.makeTuple(exprs); 459 return ExprFactory.make_RewriteFnApp(fnRef, arg); 468 460 } 469 461 -
trunk/ProjectFortress/src/com/sun/fortress/compiler/desugarer/PreDisambiguationDesugaringVisitor.java
r3158 r3182 196 196 body = visitGenerators(span, gens, body); 197 197 Expr opexp = ExprFactory.makeOpExpr(span,op,staticArgs); 198 Expr res = newTightJuxt(span, false,199 Useful.list(BIGOP_NAME,200 ExprFactory.makeTuple(opexp,body)));198 Expr res = ExprFactory.makeTightJuxt(span, false, 199 Useful.list(BIGOP_NAME, 200 ExprFactory.makeTuple(opexp,body))); 201 201 return (Expr)recur(res); 202 202 } -
trunk/ProjectFortress/src/com/sun/fortress/compiler/desugarer/VarRefContainer.java
r3163 r3182 37 37 import com.sun.fortress.nodes.StaticArg; 38 38 import com.sun.fortress.nodes.StaticParam; 39 import com.sun.fortress.nodes.TightJuxt;40 39 import com.sun.fortress.nodes.TraitTypeWhere; 41 40 import com.sun.fortress.nodes.Type; … … 155 154 } 156 155 157 private TightJuxtmakeCallToContainerObj() {156 private Expr makeCallToContainerObj() { 158 157 List<IdOrOp> fns = new LinkedList<IdOrOp>(); 159 158 Span origSpan = origDeclNode.getSpan(); … … 163 162 containerDeclId(), fns, Collections.<StaticArg>emptyList() ); 164 163 165 List<Expr> exprs = new LinkedList<Expr>(); 166 exprs.add(fnRefToDecl); 167 exprs.add(origVar); 168 169 return( ExprFactory.makeTightJuxt(origSpan, false, exprs) ); 164 return( ExprFactory.make_RewriteFnApp(fnRefToDecl, origVar) ); 170 165 } 171 166 -
trunk/ProjectFortress/src/com/sun/fortress/compiler/typechecker/TypeChecker.java
r3176 r3182 2990 2990 2991 2991 @Override 2992 public TypeCheckerResult forLooseJuxtOnly(LooseJuxt that, Option<TypeCheckerResult> exprType_result, 2993 TypeCheckerResult multiJuxt_result, 2994 TypeCheckerResult infixJuxt_result, 2995 List<TypeCheckerResult> exprs_result) { 2996 // The implementation of this method is very similar to tight juxt except 2997 // the ordering of association is different. 2998 // Notice also that tightJuxt has to be recursive, but loose juxt is not, due to specification. 2999 3000 // Did any subexpressions fail to typecheck? 3001 for( TypeCheckerResult r : exprs_result ) { 3002 if( r.type().isNone()) 3003 return TypeCheckerResult.compose(that, subtypeChecker, exprs_result); 3004 } 3005 3006 if( that.getExprs().size() != exprs_result.size() ) { 3007 bug("Number of types don't match number of sub-expressions"); 3008 } 3009 // Specification describes chunks, which are elements group together. Chunking process goes first. 3010 List<Pair<TypeCheckerResult,Expr>> checked_chunks = new LinkedList<Pair<TypeCheckerResult,Expr>>(); 3011 { 3012 List<Pair<TypeCheckerResult,Expr>> cur_chunk = new LinkedList<Pair<TypeCheckerResult,Expr>>(); 3013 Iterator<Expr> expr_iter = that.getExprs().iterator(); 3014 boolean seen_non_fn = false; 3015 // First the loose juxtaposition is broken into nonempty chunks; wherever there is a non-function element followed 3016 // by a function element, the latter begins a new chunk. Thus a chunk consists of some number (possibly zero) of 3017 // functions followed by some number (possibly zero) of non-functions. 2992 public TypeCheckerResult forJuxt(Juxt that) { 2993 if ( that.isTight() ) { 2994 // Just create a MathPrimary 2995 Expr front = IterUtil.first(that.getExprs()); 2996 2997 // If this juxt is actually a fn app, then rewrite to a fn app. 2998 if (that.isFnApp()) { 2999 // Make sure it is just two exprs. 3000 if (that.getExprs().size() != 2) { 3001 bug(String.format("TightJuxt denoted as function application but has %d (!= 2) exprs.", 3002 that.getExprs().size())); 3003 } 3004 Expr arg = that.getExprs().get(1); 3005 _RewriteFnApp fnApp = new _RewriteFnApp(new Span(front.getSpan(), arg.getSpan()), 3006 front, arg); 3007 3008 // Simulate a TypeCheckerResult for the front, giving it a fresh arrow type. 3009 Type freshArrow = NodeFactory.makeArrowType(new Span(), 3010 NodeFactory.make_InferenceVarType(that.getSpan()), 3011 NodeFactory.make_InferenceVarType(that.getSpan())); 3012 TypeCheckerResult front_result = new TypeCheckerResult(front, freshArrow); 3013 3014 // Type check the other nodes and recur on the fn app. 3015 Option<TypeCheckerResult> exprType_result = this.recurOnOptionOfType(that.getExprType()); 3016 TypeCheckerResult arg_result = arg.accept(this); 3017 TypeCheckerResult fnApp_result = this.for_RewriteFnAppOnly(fnApp, 3018 exprType_result, 3019 front_result, 3020 arg_result); 3021 return TypeCheckerResult.compose(that, 3022 fnApp_result.type(), 3023 subtypeChecker, 3024 fnApp_result); 3025 } 3026 3027 Iterable<Expr> rest = IterUtil.skipFirst(that.getExprs()); 3028 List<MathItem> items = CollectUtil.makeList(IterUtil.map(rest, new Lambda<Expr,MathItem>(){ 3029 public MathItem value(Expr arg0) { 3030 if( arg0.isParenthesized() || arg0 instanceof TupleExpr || arg0 instanceof VoidLiteralExpr) 3031 return new ParenthesisDelimitedMI(arg0.getSpan(),arg0); 3032 else 3033 return new NonParenthesisDelimitedMI(arg0.getSpan(),arg0); 3034 }})); 3035 MathPrimary new_primary = new MathPrimary(that.getSpan(), 3036 that.isParenthesized(), 3037 that.getMultiJuxt(), 3038 that.getInfixJuxt(), 3039 front,items); 3040 return new_primary.accept(this); 3041 } else 3042 return super.forJuxt(that); 3043 } 3044 3045 @Override 3046 public TypeCheckerResult forJuxtOnly(Juxt that, Option<TypeCheckerResult> exprType_result, 3047 TypeCheckerResult multiJuxt_result, 3048 TypeCheckerResult infixJuxt_result, 3049 List<TypeCheckerResult> exprs_result) { 3050 if (! that.isTight() ) { 3051 // The implementation of this method is very similar to tight juxt except 3052 // the ordering of association is different. 3053 // Notice also that tightJuxt has to be recursive, but loose juxt is not, due to specification. 3054 3055 // Did any subexpressions fail to typecheck? 3018 3056 for( TypeCheckerResult r : exprs_result ) { 3019 boolean is_arrow = TypesUtil.isArrows(r.type().unwrap()); 3020 if( is_arrow && seen_non_fn ) { 3021 // finished last chunk 3022 Pair<TypeCheckerResult,Expr> checked_chunk = this.checkChunk(cur_chunk, that.getInfixJuxt()); 3023 checked_chunks.add(checked_chunk); 3024 cur_chunk.clear(); 3025 seen_non_fn = false; 3057 if( r.type().isNone()) 3058 return TypeCheckerResult.compose(that, subtypeChecker, exprs_result); 3059 } 3060 3061 if( that.getExprs().size() != exprs_result.size() ) { 3062 bug("Number of types don't match number of sub-expressions"); 3063 } 3064 // Specification describes chunks, which are elements group together. Chunking process goes first. 3065 List<Pair<TypeCheckerResult,Expr>> checked_chunks = new LinkedList<Pair<TypeCheckerResult,Expr>>(); 3066 { 3067 List<Pair<TypeCheckerResult,Expr>> cur_chunk = new LinkedList<Pair<TypeCheckerResult,Expr>>(); 3068 Iterator<Expr> expr_iter = that.getExprs().iterator(); 3069 boolean seen_non_fn = false; 3070 // First the loose juxtaposition is broken into nonempty chunks; wherever there is a non-function element followed 3071 // by a function element, the latter begins a new chunk. Thus a chunk consists of some number (possibly zero) of 3072 // functions followed by some number (possibly zero) of non-functions. 3073 for( TypeCheckerResult r : exprs_result ) { 3074 boolean is_arrow = TypesUtil.isArrows(r.type().unwrap()); 3075 if( is_arrow && seen_non_fn ) { 3076 // finished last chunk 3077 Pair<TypeCheckerResult,Expr> checked_chunk = this.checkChunk(cur_chunk, that.getInfixJuxt()); 3078 checked_chunks.add(checked_chunk); 3079 cur_chunk.clear(); 3080 seen_non_fn = false; 3081 } 3082 if( is_arrow ){ 3083 cur_chunk.add(Pair.make(r, expr_iter.next())); 3084 } 3085 else { 3086 seen_non_fn = true; 3087 cur_chunk.add(Pair.make(r, expr_iter.next())); 3088 } 3026 3089 } 3027 if( is_arrow ){ 3028 cur_chunk.add(Pair.make(r, expr_iter.next())); 3029 } 3030 else { 3031 seen_non_fn = true; 3032 cur_chunk.add(Pair.make(r, expr_iter.next())); 3090 // Last chunk needs to be checked, if there is one 3091 if( !cur_chunk.isEmpty() ) { 3092 checked_chunks.add(checkChunk(cur_chunk, that.getInfixJuxt())); 3033 3093 } 3034 3094 } 3035 // Last chunk needs to be checked, if there is one 3036 if( !cur_chunk.isEmpty() ) { 3037 checked_chunks.add(checkChunk(cur_chunk, that.getInfixJuxt())); 3095 // After chunking 3096 List<Expr> new_juxt_exprs = CollectUtil.makeList(IterUtil.pairSeconds(checked_chunks)); 3097 List<TypeCheckerResult> new_juxt_results = CollectUtil.makeList(IterUtil.pairFirsts(checked_chunks)); 3098 3099 if( checked_chunks.size() == 1 ) { 3100 Expr expr = IterUtil.first(new_juxt_exprs); 3101 TypeCheckerResult expr_result = expr.accept(this); // Is it bad to re-typecheck all args? 3102 return TypeCheckerResult.compose(expr_result.ast(), expr_result.type(), subtypeChecker, expr_result, 3103 TypeCheckerResult.compose(expr_result.ast(), subtypeChecker, new_juxt_results)); 3038 3104 } 3105 // (1) If any element that remains has type String, then it is a static error if any two adjacent elements are not of type String. 3106 // TODO: Separate pass? 3107 // (2) Treat the sequence that remains as a multifix application of the juxtaposition operator. The rules for multifix operators then apply: 3108 OpExpr multi_op_expr = new OpExpr(that.getSpan(), that.getMultiJuxt(), new_juxt_exprs); 3109 TypeCheckerResult multi_op_result = multi_op_expr.accept(this); 3110 if( multi_op_result.type().isSome() ) { 3111 return TypeCheckerResult.compose(multi_op_result.ast(), multi_op_result.type(), subtypeChecker, 3112 TypeCheckerResult.compose(multi_op_result.ast(), subtypeChecker, new_juxt_results)); 3113 } 3114 // if an applicable method cannot be found for the entire expression, then it is left-associated. 3115 Iterator<Expr> expr_iter = new_juxt_exprs.iterator(); 3116 Expr expr_1 = expr_iter.next(); // the fact that >= two items are here is guaranteed from above. 3117 Expr expr_2 = expr_iter.next(); 3118 OpExpr cur_op_expr = new OpExpr(new Span(expr_1.getSpan(),expr_2.getSpan()), that.getInfixJuxt(), Useful.list(expr_1,expr_2)); 3119 while( expr_iter.hasNext() ) { 3120 Expr next_expr = expr_iter.next(); 3121 cur_op_expr = new OpExpr(new Span(cur_op_expr.getSpan(),next_expr.getSpan()), that.getInfixJuxt(), Useful.list(cur_op_expr, next_expr)); 3122 } 3123 // typecheck this result instead 3124 TypeCheckerResult op_expr_result = cur_op_expr.accept(this); // Is it bad to re-typecheck all args? 3125 return TypeCheckerResult.compose(op_expr_result.ast(), op_expr_result.type(), subtypeChecker, op_expr_result, 3126 TypeCheckerResult.compose(op_expr_result.ast(), subtypeChecker, new_juxt_results)); 3127 } else { 3128 return super.forJuxtOnly(that, exprType_result, 3129 multiJuxt_result, infixJuxt_result, 3130 exprs_result); 3039 3131 } 3040 // After chunking 3041 List<Expr> new_juxt_exprs = CollectUtil.makeList(IterUtil.pairSeconds(checked_chunks)); 3042 List<TypeCheckerResult> new_juxt_results = CollectUtil.makeList(IterUtil.pairFirsts(checked_chunks)); 3043 3044 if( checked_chunks.size() == 1 ) { 3045 Expr expr = IterUtil.first(new_juxt_exprs); 3046 TypeCheckerResult expr_result = expr.accept(this); // Is it bad to re-typecheck all args? 3047 return TypeCheckerResult.compose(expr_result.ast(), expr_result.type(), subtypeChecker, expr_result, 3048 TypeCheckerResult.compose(expr_result.ast(), subtypeChecker, new_juxt_results)); 3049 } 3050 // (1) If any element that remains has type String, then it is a static error if any two adjacent elements are not of type String. 3051 // TODO: Separate pass? 3052 // (2) Treat the sequence that remains as a multifix application of the juxtaposition operator. The rules for multifix operators then apply: 3053 OpExpr multi_op_expr = new OpExpr(that.getSpan(), that.getMultiJuxt(), new_juxt_exprs); 3054 TypeCheckerResult multi_op_result = multi_op_expr.accept(this); 3055 if( multi_op_result.type().isSome() ) { 3056 return TypeCheckerResult.compose(multi_op_result.ast(), multi_op_result.type(), subtypeChecker, 3057 TypeCheckerResult.compose(multi_op_result.ast(), subtypeChecker, new_juxt_results)); 3058 } 3059 // if an applicable method cannot be found for the entire expression, then it is left-associated. 3060 Iterator<Expr> expr_iter = new_juxt_exprs.iterator(); 3061 Expr expr_1 = expr_iter.next(); // the fact that >= two items are here is guaranteed from above. 3062 Expr expr_2 = expr_iter.next(); 3063 OpExpr cur_op_expr = new OpExpr(new Span(expr_1.getSpan(),expr_2.getSpan()), that.getInfixJuxt(), Useful.list(expr_1,expr_2)); 3064 while( expr_iter.hasNext() ) { 3065 Expr next_expr = expr_iter.next(); 3066 cur_op_expr = new OpExpr(new Span(cur_op_expr.getSpan(),next_expr.getSpan()), that.getInfixJuxt(), Useful.list(cur_op_expr, next_expr)); 3067 } 3068 // typecheck this result instead 3069 TypeCheckerResult op_expr_result = cur_op_expr.accept(this); // Is it bad to re-typecheck all args? 3070 return TypeCheckerResult.compose(op_expr_result.ast(), op_expr_result.type(), subtypeChecker, op_expr_result, 3071 TypeCheckerResult.compose(op_expr_result.ast(), subtypeChecker, new_juxt_results)); 3072 } 3132 } 3073 3133 3074 3134 // Math primary, which is the more general case, is going to be called for both TightJuxt and MathPrimary … … 3887 3947 3888 3948 @Override 3889 public TypeCheckerResult forTightJuxt(TightJuxt that) {3890 // Just create a MathPrimary3891 Expr front = IterUtil.first(that.getExprs());3892 3893 // If this juxt is actually a fn app, then rewrite to a fn app.3894 if (that.isFnApp()) {3895 // Make sure it is just two exprs.3896 if (that.getExprs().size() != 2) {3897 bug(String.format("TightJuxt denoted as function application but has %d (!= 2) exprs.", that.getExprs().size()));3898 }3899 Expr arg = that.getExprs().get(1);3900 _RewriteFnApp fnApp = new _RewriteFnApp(new Span(front.getSpan(), arg.getSpan()),3901 front, arg);3902 3903 // Simulate a TypeCheckerResult for the front, giving it a fresh arrow type.3904 Type freshArrow = NodeFactory.makeArrowType(new Span(),3905 NodeFactory.make_InferenceVarType(that.getSpan()),3906 NodeFactory.make_InferenceVarType(that.getSpan()));3907 TypeCheckerResult front_result = new TypeCheckerResult(front, freshArrow);3908 3909 // Type check the other nodes and recur on the fn app.3910 Option<TypeCheckerResult> exprType_result = this.recurOnOptionOfType(that.getExprType());3911 TypeCheckerResult arg_result = arg.accept(this);3912 TypeCheckerResult fnApp_result = this.for_RewriteFnAppOnly(fnApp,3913 exprType_result,3914 front_result,3915 arg_result);3916 return TypeCheckerResult.compose(that,3917 fnApp_result.type(),3918 subtypeChecker,3919 fnApp_result);3920 }3921 3922 Iterable<Expr> rest = IterUtil.skipFirst(that.getExprs());3923 List<MathItem> items = CollectUtil.makeList(IterUtil.map(rest, new Lambda<Expr,MathItem>(){3924 public MathItem value(Expr arg0) {3925 if( arg0.isParenthesized() || arg0 instanceof TupleExpr || arg0 instanceof VoidLiteralExpr)3926 return new ParenthesisDelimitedMI(arg0.getSpan(),arg0);3927 else3928 return new NonParenthesisDelimitedMI(arg0.getSpan(),arg0);3929 }}));3930 MathPrimary new_primary = new MathPrimary(that.getSpan(),3931 that.isParenthesized(),3932 that.getMultiJuxt(),3933 that.getInfixJuxt(),3934 front,items);3935 return new_primary.accept(this);3936 }3937 3938 @Override3939 3949 public TypeCheckerResult forTraitDecl(final TraitDecl that) { 3940 3950 TypeChecker checker_with_sparams = this.extend(that.getStaticParams(), that.getWhereClause()); -
trunk/ProjectFortress/src/com/sun/fortress/interpreter/evaluator/BuildEnvironments.java
r3171 r3182 505 505 // Create a little expression to run the constructor. 506 506 Expr init = ExprFactory.makeTightJuxt(x.getSpan(), 507 ExprFactory.makeVarRef(x.getSpan(), WellKnownNames.obfuscatedSingletonConstructorName(fname, x), 0),508 ExprFactory.makeVoidLiteralExpr(x.getSpan()));507 ExprFactory.makeVarRef(x.getSpan(), WellKnownNames.obfuscatedSingletonConstructorName(fname, x), 0), 508 ExprFactory.makeVoidLiteralExpr(x.getSpan())); 509 509 FValue init_value = new LazilyEvaluatedCell(init, containing); 510 510 putValue(bindInto, fname, init_value); -
trunk/ProjectFortress/src/com/sun/fortress/interpreter/evaluator/BuildNativeEnvironment.java
r2969 r3182 160 160 161 161 // Create a little expression to run the constructor. 162 Expr init = ExprFactory.makeTightJuxt(x.getSpan(), ExprFactory163 .makeVarRef(x.getSpan(), WellKnownNames.obfuscatedSingletonConstructorName(fname, x), 0),164 ExprFactory.makeVoidLiteralExpr(x.getSpan()));162 Expr init = ExprFactory.makeTightJuxt(x.getSpan(), 163 ExprFactory.makeVarRef(x.getSpan(), WellKnownNames.obfuscatedSingletonConstructorName(fname, x), 0), 164 ExprFactory.makeVoidLiteralExpr(x.getSpan())); 165 165 FValue init_value = new LazilyEvaluatedCell(init, containing); 166 166 putValue(bindInto, fname, init_value); -
trunk/ProjectFortress/src/com/sun/fortress/interpreter/evaluator/Evaluator.java
r3166 r3182 108 108 import com.sun.fortress.nodes.Lhs; 109 109 import com.sun.fortress.nodes.Link; 110 import com.sun.fortress.nodes.LooseJuxt;111 110 import com.sun.fortress.nodes.MathItem; 112 111 import com.sun.fortress.nodes.MathPrimary; … … 127 126 import com.sun.fortress.nodes.SubscriptingMI; 128 127 import com.sun.fortress.nodes.Throw; 129 import com.sun.fortress.nodes.TightJuxt;130 128 import com.sun.fortress.nodes.Try; 131 129 import com.sun.fortress.nodes.TryAtomicExpr; … … 906 904 } 907 905 908 public FValue forLooseJuxt(LooseJuxt x) {909 return forJuxt(x);910 }911 906 public FValue forJuxt(Juxt x) { 907 if ( x.isTight() ) { 908 /** Assumes wrapped FnRefs have ids fields of length 1. */ 909 return forTightJuxt(x, false); 910 } else 911 return forJuxtCommon(x); 912 } 913 914 public FValue forJuxtCommon(Juxt x) { 912 915 // This is correct except for one minor detail: 913 916 // We should treat names from another scope as if they were functions. … … 920 923 bug(x,"empty juxtaposition"); 921 924 try { 922 // times = e.getValue("juxtaposition");925 // times = e.getValue("juxtaposition"); 923 926 times = e.getValueNull(x.getInfixJuxt()); 924 927 } catch (FortressException fe) { … … 1096 1099 "immediately followed by a non-expression " + 1097 1100 "element."); 1098 } else if (arg instanceof TightJuxt) { // f(x)! 1099 vargs = Useful.list(forTightJuxt((TightJuxt)arg, true)); 1101 } else if ( arg instanceof Juxt && 1102 ((Juxt)arg).isTight() ) { // f(x)! 1103 vargs = Useful.list(forTightJuxt((Juxt)arg, true)); 1100 1104 } else if (arg instanceof MathPrimary) { // f(x)^y! y[a](x)! 1101 1105 vargs = Useful.list(forMathPrimary((MathPrimary)arg, true)); … … 1390 1394 } 1391 1395 1392 /** Assumes wrapped FnRefs have ids fields of length 1. */ 1393 public FValue forTightJuxt(TightJuxt x) { 1394 return forTightJuxt(x, false); 1395 } 1396 1397 private FValue forTightJuxt(TightJuxt x, boolean isPostfix) { 1396 private FValue forTightJuxt(Juxt x, boolean isPostfix) { 1398 1397 List<Expr> exprs = x.getExprs(); 1399 1398 if (exprs.size() == 0) … … 1453 1452 // Please fix it if you know how to do it. -- Sukyoung 1454 1453 // Less of a hack now. -- David 1455 return forJuxt (x);1454 return forJuxtCommon(x); 1456 1455 } 1457 1456 } … … 1466 1465 * @throws ProgramError 1467 1466 */ 1468 private FValue juxtMemberSelection( TightJuxt x, FValue fobj, Id fld,1467 private FValue juxtMemberSelection(Juxt x, FValue fobj, Id fld, 1469 1468 List<Expr> exprs) throws ProgramError { 1470 1469 List<FValue> args = evalInvocationArgs(exprs); -
trunk/ProjectFortress/src/com/sun/fortress/interpreter/glue/NativeApp.java
r3123 r3182 36 36 import com.sun.fortress.nodes.Id; 37 37 import com.sun.fortress.nodes.IdOrOpOrAnonymousName; 38 import com.sun.fortress.nodes.Juxt; 38 39 import com.sun.fortress.nodes.MathItem; 39 40 import com.sun.fortress.nodes.MathPrimary; … … 41 42 import com.sun.fortress.nodes.StaticParam; 42 43 import com.sun.fortress.nodes.StringLiteralExpr; 43 import com.sun.fortress.nodes.TightJuxt;44 44 import com.sun.fortress.nodes.Type; 45 45 import com.sun.fortress.nodes.VarRef; … … 153 153 Expr fn; 154 154 Expr arg; 155 if (body instanceof TightJuxt) { 156 List<Expr> juxts = ((TightJuxt)body).getExprs(); 155 if ( body instanceof Juxt && 156 ((Juxt)body).isTight() ) { 157 List<Expr> juxts = ((Juxt)body).getExprs(); 157 158 if (juxts.size()!=2) return defn; 158 159 fn = juxts.get(0); -
trunk/ProjectFortress/src/com/sun/fortress/interpreter/rewrite/DesugarerVisitor.java
r3176 r3182 93 93 import com.sun.fortress.nodes.StaticParam; 94 94 import com.sun.fortress.nodes.TestDecl; 95 import com.sun.fortress.nodes.TightJuxt;96 95 import com.sun.fortress.nodes.BaseType; 97 96 import com.sun.fortress.nodes.TraitDecl; … … 775 774 } 776 775 @Override 777 public Node forTightJuxt(TightJuxt node) { 778 if (looksLikeMethodInvocation(node)) 779 return translateJuxtOfDotted(node); 780 else 781 return visitNode(node); 776 public Node forJuxt(Juxt node) { 777 if ( node.isTight() ) { 778 if (looksLikeMethodInvocation(node)) 779 return translateJuxtOfDotted(node); 780 else 781 return visitNode(node); 782 } else return visitNode(node); 782 783 } 783 784 @Override … … 1078 1079 args.add(bindsAndBody(g,w.getBody())); 1079 1080 Expr cond = 1080 new TightJuxt(g.getSpan(), false,1081 Useful.list(Q_WHILECOND_NAME,1082 ExprFactory.makeTuple(w.getSpan(),args)) );1081 ExprFactory.makeTightJuxt(g.getSpan(), 1082 Q_WHILECOND_NAME, 1083 ExprFactory.makeTuple(w.getSpan(),args)); 1083 1084 w = ExprFactory.makeWhile(w.getSpan(),cond); 1084 1085 } … … 1114 1115 List<Param> params = Collections.emptyList(); 1115 1116 FnExpr fnExpr = new FnExpr(sp, params, (Expr) rewrittenExpr); 1116 List<Expr> exprs = new ArrayList<Expr>(2); 1117 exprs.add(fn); 1118 1119 exprs.add(fnExpr); 1120 1121 TightJuxt juxt = new TightJuxt(s.getSpan(), false, exprs); 1122 1123 return visitNode(juxt); 1117 1118 return visitNode(ExprFactory.makeTightJuxt(s.getSpan(), fn, fnExpr)); 1124 1119 } 1125 1120 … … 1191 1186 args.add(bindsAndBody(g,c.getBody())); 1192 1187 if (elsePart != null) args.add(thunk(elsePart)); 1193 return new TightJuxt(c.getSpan(), false,1194 Useful.list(Q_COND_NAME,1195 ExprFactory.makeTuple(c.getSpan(),args)) );1188 return ExprFactory.makeTightJuxt(c.getSpan(), 1189 Q_COND_NAME, 1190 ExprFactory.makeTuple(c.getSpan(),args)); 1196 1191 } 1197 1192 // if expr then body else elsePart end is preserved … … 1218 1213 Expr loopSel = ExprFactory.makeFieldRef(g.getSpan(), 1219 1214 g.getInit(), LOOP_NAME); 1220 body = new TightJuxt(span, false, Useful.list(loopSel,loopBody));1215 body = ExprFactory.makeTightJuxt(span, loopSel,loopBody); 1221 1216 } 1222 1217 // System.out.println("Desugared to "+body.toStringVerbose()); -
trunk/ProjectFortress/src/com/sun/fortress/nodes_util/DesugarerUtil.java
r3123 r3182 134 134 if (i==0) { 135 135 /* Single generator as body, with no generator clauses. */ 136 body = new TightJuxt(span, false,137 Useful.list(GENERATE_NAME,138 ExprFactory.makeTuple(body,redVar,unitVar)));136 body = ExprFactory.makeTightJuxt(span, 137 GENERATE_NAME, 138 ExprFactory.makeTuple(body,redVar,unitVar)); 139 139 } else { 140 140 List<GeneratorClause> squozenGens = … … 162 162 // Wrap the body in parentheses (as a singleton tuple) so that it can be considered 163 163 // as the argument in a function application (denoted by the true argument). 164 body = newTightJuxt(body.getSpan(),165 false,166 Useful.list(unitVar, body),167 true);164 body = ExprFactory.makeTightJuxt(body.getSpan(), 165 false, 166 Useful.list(unitVar, body), 167 true); 168 168 for (i--; i>=0; i--) { 169 169 body = oneGenerator(gens.get(i), redVar, body); … … 273 273 Expr loopBody = bindsAndBody(g, body); 274 274 Expr params = ExprFactory.makeTuple(g.getInit(), reduction, loopBody); 275 return new TightJuxt(g.getSpan(), false, 276 Useful.list(GENERATE_NAME,params)); 275 return ExprFactory.makeTightJuxt(g.getSpan(), GENERATE_NAME, params); 277 276 } 278 277 } -
trunk/ProjectFortress/src/com/sun/fortress/nodes_util/ExprFactory.java
r3164 r3182 426 426 } 427 427 428 public static TightJuxt makeTightJuxt(Span span, Expr first, Expr second) { 429 return new TightJuxt(span, false, Useful.list(first, second)); 430 } 431 432 public static TightJuxt makeTightJuxt(Span span, boolean isParenthesized, List<Expr> exprs) { 433 return new TightJuxt(span, isParenthesized, Useful.immutableTrimmedList(exprs)); 434 } 435 436 public static TightJuxt makeTightJuxt(Span span, List<Expr> exprs, Boolean isParenthesized, FunctionalRef infixJuxt, FunctionalRef multiJuxt){ 437 return new TightJuxt(span, isParenthesized, multiJuxt, infixJuxt ,Useful.immutableTrimmedList(exprs)); 428 public static Juxt makeLooseJuxt(Span span, boolean isParenthesized, List<Expr> exprs) { 429 return new Juxt(span, isParenthesized, Useful.immutableTrimmedList(exprs), 430 false, false); 431 } 432 433 public static Juxt makeTightJuxt(Span span, Expr first, Expr second) { 434 return new Juxt(span, false, Option.<Type>none(), 435 Useful.list(first, second), false, true); 436 } 437 438 public static Juxt makeTightJuxt(Span span, boolean isParenthesized, List<Expr> exprs) { 439 return new Juxt(span, isParenthesized, Useful.immutableTrimmedList(exprs), 440 false, true); 441 } 442 443 public static Juxt makeTightJuxt(Span span, boolean isParenthesized, List<Expr> exprs, boolean isFnApp) { 444 return new Juxt(span, isParenthesized, Useful.immutableTrimmedList(exprs), 445 isFnApp, true); 446 } 447 448 public static Juxt makeTightJuxt(Span span, List<Expr> exprs, 449 Boolean isParenthesized, 450 FunctionalRef infixJuxt, 451 FunctionalRef multiJuxt){ 452 return new Juxt(span, isParenthesized, multiJuxt, infixJuxt, 453 Useful.immutableTrimmedList(exprs), 454 false, true); 438 455 } 439 456 … … 442 459 * with new exprs. 443 460 */ 444 public static TightJuxt makeTightJuxt(TightJuxt that, List<Expr> exprs) { 445 return new TightJuxt(that.getSpan(), that.isParenthesized(), 446 that.getMultiJuxt(), that.getInfixJuxt(), Useful.immutableTrimmedList(exprs)); 461 public static Juxt makeTightJuxt(Juxt that, List<Expr> exprs) { 462 return new Juxt(that.getSpan(), that.isParenthesized(), 463 that.getMultiJuxt(), that.getInfixJuxt(), 464 Useful.immutableTrimmedList(exprs), 465 that.isFnApp(), true); 447 466 } 448 467 … … 895 914 e.getArg()); 896 915 } 897 public Expr forLooseJuxt(LooseJuxt e) { 898 return new LooseJuxt(e.getSpan(), true, e.getExprs()); 899 } 900 public Expr forTightJuxt(TightJuxt e) { 901 return new TightJuxt(e.getSpan(), true, e.getExprs()); 916 public Expr forJuxt(Juxt e) { 917 return new Juxt(e.getSpan(), true, e.getExprType(), 918 e.getMultiJuxt(), e.getInfixJuxt(), 919 e.getExprs(), e.isFnApp(), e.isTight()); 902 920 } 903 921 public Expr forFnRef(FnRef e) { … … 985 1003 if (mi instanceof ExprMI) { 986 1004 Expr expr = ((ExprMI)mi).getExpr(); 987 return new TightJuxt(span, Useful.list(front, expr));1005 return makeTightJuxt(span, front, expr); 988 1006 } else if (mi instanceof ExponentiationMI) { 989 1007 ExponentiationMI expo = (ExponentiationMI)mi; … … 1038 1056 } 1039 1057 1040 public static TemplateGap LooseJuxt makeTemplateGapLooseJuxt(Span s, Id id, List<Id> params) {1041 return new TemplateGap LooseJuxt(s, id, params);1058 public static TemplateGapJuxt makeTemplateGapJuxt(Span s, Id id, List<Id> params) { 1059 return new TemplateGapJuxt(s, id, params); 1042 1060 } 1043 1061 -
trunk/ProjectFortress/src/com/sun/fortress/parser/Expression.rats
r3146 r3182 502 502 public Expr run(Expr base) { 503 503 List<Expr> exprs = FortressUtil.mkList(base, a1); 504 return newTightJuxt(FortressUtil.spanTwo(base, a1), false, exprs);504 return ExprFactory.makeTightJuxt(FortressUtil.spanTwo(base, a1), false, exprs); 505 505 }}; 506 506 }; -
trunk/ProjectFortress/src/com/sun/fortress/parser/templateparser/Gaps.rats
r3079 r3182 56 56 }; 57 57 58 LooseJuxt LooseJuxtGap =58 Juxt LooseJuxtGap = 59 59 <GAP> prefix "LooseJuxt" w a1:Id params:ParamList? w suffix 60 60 { if (params == null) params = new LinkedList<Id>(); 61 yyValue = ExprFactory.makeTemplateGap LooseJuxt(createSpan(yyStart,yyCount), a1, params);61 yyValue = ExprFactory.makeTemplateGapJuxt(createSpan(yyStart,yyCount), a1, params); 62 62 }; 63 63 -
trunk/ProjectFortress/src/com/sun/fortress/parser_util/FortressUtil.java
r3163 r3182 874 874 exprs = exprs.reverse(); 875 875 List<Expr> javaList = Useful.immutableTrimmedList(exprs); 876 return new TightJuxt(spanAll(javaList.toArray(new AbstractNode[0]), 877 javaList.size()), false, javaList); 876 return new Juxt(spanAll(javaList.toArray(new AbstractNode[0]), 877 javaList.size()), 878 false, javaList, false, true); 878 879 } 879 880 } -
trunk/ProjectFortress/src/com/sun/fortress/parser_util/precedence_resolver/ASTUtil.java
r3156 r3182 32 32 import com.sun.fortress.nodes.Expr; 33 33 import com.sun.fortress.nodes.Link; 34 import com.sun.fortress.nodes.LooseJuxt;35 34 import com.sun.fortress.nodes.IdOrOp; 36 35 import com.sun.fortress.nodes.Op; … … 144 143 } 145 144 }); 146 return newLooseJuxt(spanAll(exprs), false, _exprs.toJavaList());145 return ExprFactory.makeLooseJuxt(spanAll(exprs), false, _exprs.toJavaList()); 147 146 } 148 147 -
trunk/ProjectFortress/src/com/sun/fortress/syntax_abstractions/phases/EllipsesJUTest.java
r3071 r3182 22 22 import com.sun.fortress.nodes.*; 23 23 import com.sun.fortress.nodes_util.NodeFactory; 24 import com.sun.fortress.nodes_util.ExprFactory; 24 25 import com.sun.fortress.nodes_util.Span; 25 26 … … 30 31 31 32 static Span span = NodeFactory.makeSpan("EllipsesJUTest"); 32 33 33 34 private <T> List<T> mkList( T... e ){ 34 35 List<T> list = new ArrayList<T>(); … … 54 55 List<Expr> exprs = new ArrayList<Expr>(); 55 56 exprs.add( new _EllipsesExpr(new Span(), mkTemplate( "x" ) ) ); 56 original = new TightJuxt(new Span(), false, exprs);57 original = ExprFactory.makeTightJuxt(new Span(), false, exprs); 57 58 EllipsesEnvironment env = new EllipsesEnvironment(); 58 59 env.add( NodeFactory.makeId( "x" ), 1, mkList(new StringLiteralExpr(span, "hello" )) ); … … 63 64 List<Expr> exprs = new ArrayList<Expr>(); 64 65 exprs.add( new StringLiteralExpr(span, "hello" ) ); 65 expected = newTightJuxt( new Span(), false, exprs );66 expected = ExprFactory.makeTightJuxt( new Span(), false, exprs ); 66 67 } 67 68 … … 76 77 List<Expr> exprs = new ArrayList<Expr>(); 77 78 exprs.add( new _EllipsesExpr(new Span(), mkTemplate( "x" ) ) ); 78 original = new TightJuxt(new Span(), false, exprs);79 original = ExprFactory.makeTightJuxt(new Span(), false, exprs); 79 80 EllipsesEnvironment env = new EllipsesEnvironment(); 80 81 env.add( NodeFactory.makeId( "x" ), 1, mkList(new StringLiteralExpr(span, "hello" ), new StringLiteralExpr(span, "goodbye" ) ) ); … … 83 84 84 85 { 85 List<Expr> exprs = new ArrayList<Expr>(); 86 exprs.add( new StringLiteralExpr(span, "hello" ) ); 87 exprs.add( new StringLiteralExpr(span, "goodbye" ) ); 88 expected = new TightJuxt( new Span(), false, exprs ); 86 expected = ExprFactory.makeTightJuxt( new Span(), 87 new StringLiteralExpr(span, "hello" ), 88 new StringLiteralExpr(span, "goodbye" ) ); 89 89 } 90 90 … … 104 104 List<Expr> exprs = new ArrayList<Expr>(); 105 105 exprs.add( new _EllipsesExpr( new Span(), extra ) ); 106 original = newTightJuxt(new Span(), false, exprs );106 original = ExprFactory.makeTightJuxt(new Span(), false, exprs ); 107 107 EllipsesEnvironment env = new EllipsesEnvironment(); 108 108 env.add( NodeFactory.makeId( "x" ), 1, mkList( new StringLiteralExpr(span, "a"), new StringLiteralExpr(span, "b" ) ) ); … … 116 116 exprs.add( new Block(span, mkExprList( new StringLiteralExpr(span, "hi" ), 117 117 new StringLiteralExpr(span, "b" ) ) ) ); 118 expected = newTightJuxt(new Span(), false, exprs );118 expected = ExprFactory.makeTightJuxt(new Span(), false, exprs ); 119 119 } 120 120 … … 131 131 List<Expr> exprs = new ArrayList<Expr>(); 132 132 exprs.add( new StringLiteralExpr(span, "bar" ) ); 133 exprs.add( new _EllipsesExpr(new Span(), newTightJuxt(new Span(), false, extra ) ) );134 original = newTightJuxt(new Span(), false, exprs );133 exprs.add( new _EllipsesExpr(new Span(), ExprFactory.makeTightJuxt(new Span(), false, extra ) ) ); 134 original = ExprFactory.makeTightJuxt(new Span(), false, exprs ); 135 135 EllipsesEnvironment env = new EllipsesEnvironment(); 136 136 env.add( NodeFactory.makeId( "i" ), 0, new StringLiteralExpr(span, "a" ) ); … … 142 142 143 143 { 144 expected = newTightJuxt(new Span(), false,144 expected = ExprFactory.makeTightJuxt(new Span(), false, 145 145 mkExprList( new StringLiteralExpr(span, "bar" ), 146 new TightJuxt(new Span(), false,147 mkExprList(new StringLiteralExpr(span, "a"),148 new StringLiteralExpr(span, "1")) ),149 new TightJuxt(new Span(), false,150 mkExprList(new StringLiteralExpr(span, "a"),151 new StringLiteralExpr(span, "2")) ),152 new TightJuxt(new Span(), false,153 mkExprList(new StringLiteralExpr(span, "a"),154 new StringLiteralExpr(span, "3")))) );146 ExprFactory.makeTightJuxt(new Span(), 147 new StringLiteralExpr(span, "a"), 148 new StringLiteralExpr(span, "1")), 149 ExprFactory.makeTightJuxt(new Span(), 150 new StringLiteralExpr(span, "a"), 151 new StringLiteralExpr(span, "2")), 152 ExprFactory.makeTightJuxt(new Span(), 153 new StringLiteralExpr(span, "a"), 154 new StringLiteralExpr(span, "3")))); 155 155 } 156 156 157 157 assertEquals( actual, expected ); 158 158 } 159 159 160 160 } -
trunk/ProjectFortress/src/com/sun/fortress/tools/FortressAstToConcrete.java
r3176 r3182 1704 1704 } 1705 1705 1706 @Override public String forLooseJuxtOnly(LooseJuxt that, Option<String> exprType_result, 1707 String multiJuxt_result, 1708 String infixJuxt_result, 1709 List<String> exprs_result) { 1710 StringBuilder s = new StringBuilder(); 1711 1712 for ( String expr : exprs_result ){ 1713 s.append( expr ); 1714 s.append( " " ); 1715 } 1716 1717 return handleParen( s.toString(), 1718 that.isParenthesized() ); 1719 } 1720 1721 @Override public String forTightJuxtOnly(TightJuxt that, Option<String> exprType_result, 1722 String multiJuxt_result, 1723 String infixJuxt_result, 1724 List<String> exprs_result) { 1725 StringBuilder s = new StringBuilder(); 1726 1727 if ( exprs_result.isEmpty() ) 1728 return bug(that, "A tight juxtaposition expression should have " + 1729 "at least two subexpressions."); 1730 s.append(IterUtil.first(exprs_result)); 1731 for ( String expr : IterUtil.skipFirst(exprs_result) ){ 1732 s.append( inParentheses(expr) ); 1733 } 1734 1735 if ( that.isParenthesized() ) 1736 return "(" + s.toString() + ")"; 1737 else 1738 return s.toString(); 1706 @Override public String forJuxtOnly(Juxt that, Option<String> exprType_result, 1707 String multiJuxt_result, 1708 String infixJuxt_result, 1709 List<String> exprs_result) { 1710 StringBuilder s = new StringBuilder(); 1711 1712 if ( that.isTight() ) { 1713 if ( exprs_result.isEmpty() ) 1714 return bug(that, "A tight juxtaposition expression should have " + 1715 "at least two subexpressions."); 1716 s.append(IterUtil.first(exprs_result)); 1717 for ( String expr : IterUtil.skipFirst(exprs_result) ){ 1718 s.append( inParentheses(expr) ); 1719 } 1720 if ( that.isParenthesized() ) 1721 return "(" + s.toString() + ")"; 1722 else 1723 return s.toString(); 1724 } else { 1725 for ( String expr : exprs_result ){ 1726 s.append( expr ); 1727 s.append( " " ); 1728 } 1729 return handleParen( s.toString(), 1730 that.isParenthesized() ); 1731 } 1739 1732 } 1740 1733

