Ticket #86: tryCatchExpr.patch
File tryCatchExpr.patch, 8.4 KB (added by hopscc, 13 years ago) |
---|
-
Source/Expr.cobra
1107 1107 return if(_what.type inherits AnyIntType, _what.type, _what.type.innerType) 1108 1108 1109 1109 1110 class TryCatchExpr inherits Expr is partial 1111 """ 1112 Like try/catch statement but returns the value of the try-ed expression or a default expression on Exception 1113 Limited to a single expression in both try and get clauses 1114 1115 Currently restricted to use only when it is the target of an assignment. 1116 """ 1117 var _what as Expr 1118 var _typeNode as ITypeProxy? 1119 var _excType as IType? 1120 var _getExpr as Expr 1121 1122 cue init(token as IToken, what as Expr, excTypeNode as ITypeProxy?, getExpr as Expr) 1123 base.init(token) 1124 _what = what 1125 _typeNode = excTypeNode 1126 _getExpr = getExpr 1127 1128 def addSubFields 1129 base.addSubFields 1130 .addField('what', _what) 1131 .addField('typeNode', _typeNode) 1132 .addField('getExpr', _getExpr) 1133 1134 get what from _what 1135 get typeNode from _typeNode 1136 get getExpr from _getExpr 1137 1138 def _bindImp 1139 # TODO revisit this when move from being based on .Net 2 or cobra supports (anon) method type inference 1140 if not _superNode inherits BinaryOpExpr or .binarySuperNode.op <> 'ASSIGN' 1141 msg = 'More complicated expressions cannot have code generated without side effects.' 1142 .throwError('Can only use a tryCatch expression as the simple target of an assignment (e.g "ID = try EXPR catch EXCEPTION get EXPR". [msg]') 1143 1144 base._bindImp 1145 _what.bindImp 1146 if _typeNode 1147 _typeNode.bindImp 1148 _excType = _typeNode.realType 1149 _excType.bindAll 1150 1151 _getExpr.bindImp 1152 _type = _getExpr.type to ! 1153 1110 1154 class IdentifierExpr 1111 1155 is partial 1112 1156 inherits NameExpr -
Source/BackEndClr/SharpGenerator.cobra
3314 3314 sw.dedent 3315 3315 sw.write('})') 3316 3316 3317 3318 class TryCatchExpr is partial 3319 def writeSharpDef(sw as CurlyWriter, parens as bool) is override 3320 # codegen below is specific to tryCatch as target of an assignment 3321 assert _superNode inherits BinaryOpExpr and .binarySuperNode.op == 'ASSIGN' 3322 sw.write('{') 3323 sw.write(_type.sharpRef) 3324 sw.write(' r; try { r = ') 3325 .what.writeSharpDef(sw, false) 3326 sw.write(';} catch ') 3327 if _excType 3328 sw.write('(') 3329 sw.write(_excType.sharpRef) 3330 sw.write(') ') 3331 sw.write('{ r =') 3332 _getExpr.writeSharpDef(sw, false) 3333 sw.write('; } ') 3334 lhs = .binarySuperNode.left 3335 lhs.writeSharpDef(sw, false) 3336 sw.write(' = r; }') 3337 3338 # later try this again for an arbitrarily embedded expr using a generated closure and 3339 # some method type inference and auto sig lookup/generation. 3317 3340 3318 3341 class IdentifierExpr 3319 3342 is partial … … 4144 4167 class AssignExpr is partial 4145 4168 4146 4169 def _writeSharpDef(sw as CurlyWriter) is override 4170 # special case handling/trap for tryCatch within assignment 4171 if _right inherits TryCatchExpr # expand trycatch and do assignment within the expansion 4172 _right.writeSharpDef(sw) 4173 return 4174 4147 4175 .writeSharpDefWithRight(sw, true) 4148 4176 4149 4177 def writeSharpDefWithRight(sw as CurlyWriter, right as bool) -
Source/CobraParser.cobra
2939 2942 return .ifExpr 2940 2943 on 'FOR' 2941 2944 return .forExpr 2945 on 'TRY' 2946 return .tryCatchExpr 2942 2947 on 'OPEN_CALL' 2943 2948 return .callExpr 2944 2949 on 'OPEN_GENERIC' … … 3178 3183 getExpr = .expression 3179 3184 return ForExpr(token, nameExpr, what, stopExpr, stepExpr, whereExpr, getExpr) 3180 3185 3186 def tryCatchExpr as TryCatchExpr 3187 """ 3188 t = try ... catch FormatException get 0 3189 grammar: try EXPR catch [<EXCEPTIONTYPE>] get EXPR 3190 """ 3191 token = .expect('TRY') 3192 what = .expression 3193 .expect('CATCH') 3194 if .peek.which <> 'GET' 3195 excType = .typeId 3196 .expect('GET') 3197 getExpr = .expression 3198 return TryCatchExpr(token, what, excType, getExpr) 3199 3181 3200 def identifierExpr as Expr 3182 3201 """ 3183 3202 Can return an IdentifierExpr or an AsExpr if the user says "i as int", for example. -
Source/BackEndJvm/JavaGenerator.cobra
2721 2721 # TODO 2722 2722 pass 2723 2723 2724 class TryCatchExpr is partial 2725 def writeJavaDef(sw as CurlyWriter, parens as bool) is override 2726 # codegen below is specific to tryCatch as target of an assignment 2727 assert _superNode inherits BinaryOpExpr and .binarySuperNode.op == 'ASSIGN' 2728 sw.write('{') 2729 sw.write(_type.javaRef) 2730 sw.write(' r; try { r = ') 2731 .what.writeJavaDef(sw, false) 2732 sw.write(';} catch ') 2733 if _excType 2734 sw.write('(') 2735 sw.write(_excType.javaRef) 2736 sw.write(') ') 2737 sw.write('{ r =') 2738 _getExpr.writeJavaDef(sw, false) 2739 sw.write('; } ') 2740 lhs = .binarySuperNode.left 2741 lhs.writeJavaDef(sw, false) 2742 sw.write(' = r; }') 2743 2744 # with java8 try this again for any arbitrarily embedded trycatch expr by generating a closure and 2745 # immediately executing of it - otherwise some method type inference and auto sig lookup/generation. 2724 2746 2747 2725 2748 class IdentifierExpr is partial 2726 2749 2727 2750 def writeJavaDef(sw as CurlyWriter, parens as bool) is override … … 3306 3329 var isJavaSetProperty = false 3307 3330 3308 3331 def _writeJavaDef(sw as CurlyWriter) is override 3332 # special case handling/trap for tryCatch within assignment 3333 if _right inherits TryCatchExpr # expand trycatch and do assignment within the expansion 3334 _right.writeJavaDef(sw) 3335 return 3336 3309 3337 # TODO: 3310 3338 # if trackLocal: 3311 3339 # out.write('CobraLangInternal.CobraImp.SetLocal("%s", ' % .left.name) -
Tests/200-misc/270-try-catch-expr-restrict.cobra
1 # Fail because not simple assignment to tryCatch expr 2 class TryExpr 3 def main is shared 4 5 x = 0 6 x = 4 + try int.parse('123') catch FormatException get 0 - 2 # .error. target of an assignment 7 CobraCore.noOp(x) -
Tests/200-misc/270-try-catch-expr.cobra
1 class TryExpr 2 def main is shared 3 4 x = 0 5 x = try int.parse('123') catch FormatException get 0 6 assert x == 123 7 8 val ='11213' 9 x = try int.parse(val) catch FormatException get 0 10 assert x == 11213 11 12 val1 ='foo' 13 x = try int.parse(val1) catch FormatException get 0 14 assert x == 0 15 16 17 -
Tests/200-misc/271-try-catch-expr.cobra
1 class TryExpr 2 var val as int 3 4 def main 5 6 x = 0 7 x = try int.parse('123') catch get 0 8 assert x == 123 9 10 # type inference 11 y = try int.parse('x123') catch get 0 12 assert y == 0 13 14 # get expr not literal 15 x = 666 16 y = try int.parse('123') catch get x 17 assert y == 123 18 19 y = try int.parse('123x') catch get x-6 20 assert y == 660 21 22 x = try int.parse(nil) catch get 0 23 assert x == 0 24 25 x = try int.parse(nil) catch ArgumentNullException get 0 26 assert x == 0 27 28 expect ArgumentNullException 29 x = try int.parse(nil) catch FormatException get 0 30 31 32 .val = try int.parse('9909') catch get 0 33 assert .val == 9909 34 35 te2 = TryExpr() 36 assert te2.val == 0 37 te2.val = try int.parse('100') catch get 0 38 assert te2.val == 100 39 40 41 dflt = '---' 42 s0 = try String.format('{0:P}', 0.123) catch get dflt 43 assert s0 == '12.30 %' 44 s1 = try String.format('{1:P}', 0.123) catch FormatException get dflt 45 assert s1 == dflt 46 47 s1 = try String.format('{1:XP}', 0.123) catch FormatException get dflt 48 assert s1 == dflt 49