Wiki

Ticket #86: tryCatchExpr.patch

File tryCatchExpr.patch, 8.4 KB (added by hopscc, 13 years ago)
  • Source/Expr.cobra

     
    11071107        return if(_what.type inherits AnyIntType, _what.type, _what.type.innerType) 
    11081108 
    11091109 
     1110class 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     
    11101154class IdentifierExpr 
    11111155    is partial 
    11121156    inherits NameExpr 
  • Source/BackEndClr/SharpGenerator.cobra

     
    33143314            sw.dedent 
    33153315            sw.write('})') 
    33163316 
     3317             
     3318class 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.         
    33173340 
    33183341class IdentifierExpr 
    33193342    is partial 
     
    41444167class AssignExpr is partial 
    41454168 
    41464169    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             
    41474175        .writeSharpDefWithRight(sw, true) 
    41484176 
    41494177    def writeSharpDefWithRight(sw as CurlyWriter, right as bool) 
  • Source/CobraParser.cobra

     
    29392942                return .ifExpr 
    29402943            on 'FOR' 
    29412944                return .forExpr 
     2945            on 'TRY' 
     2946                return .tryCatchExpr 
    29422947            on 'OPEN_CALL' 
    29432948                return .callExpr 
    29442949            on 'OPEN_GENERIC' 
     
    31783183            getExpr = .expression 
    31793184        return ForExpr(token, nameExpr, what, stopExpr, stepExpr, whereExpr, getExpr) 
    31803185 
     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         
    31813200    def identifierExpr as Expr 
    31823201        """ 
    31833202        Can return an IdentifierExpr or an AsExpr if the user says "i as int", for example. 
  • Source/BackEndJvm/JavaGenerator.cobra

     
    27212721    # TODO 
    27222722    pass 
    27232723 
     2724class 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.         
    27242746 
     2747 
    27252748class IdentifierExpr is partial 
    27262749 
    27272750    def writeJavaDef(sw as CurlyWriter, parens as bool) is override 
     
    33063329    var isJavaSetProperty = false 
    33073330     
    33083331    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 
    33093337        # TODO: 
    33103338        # if trackLocal: 
    33113339        #   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 
     2class 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

     
     1class 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

     
     1class 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