Wiki

Ticket #86: tryCatchExpr1.patch

File tryCatchExpr1.patch, 10.2 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    var _what as Expr 
     1116    var _typeNode as ITypeProxy? 
     1117    var _excType as IType? 
     1118    var _getExpr as Expr 
     1119 
     1120    cue init(token as IToken, what as Expr, excTypeNode as ITypeProxy?, getExpr as Expr) 
     1121        base.init(token) 
     1122        _what = what 
     1123        _typeNode = excTypeNode 
     1124        _getExpr = getExpr 
     1125 
     1126    def addSubFields 
     1127        base.addSubFields 
     1128        .addField('what', _what) 
     1129        .addField('typeNode', _typeNode) 
     1130        .addField('getExpr', _getExpr) 
     1131 
     1132    get what from _what 
     1133    get typeNode from _typeNode 
     1134    get getExpr from _getExpr 
     1135     
     1136    def _bindImp 
     1137        # TODO revisit this when java backend based on java8 (supports closures) 
     1138        if 'java' in .compiler.backEnd.name  
     1139            if not _superNode inherits BinaryOpExpr or .binarySuperNode.op <> 'ASSIGN' 
     1140                msg = 'More complicated expressions cannot yet have code generated without side effects.' 
     1141                .throwError('Can only use a tryCatch expression as the simple target of an assignment (e.g "ID = try EXPR catch EXCEPTION get EXPR". [msg]') 
     1142         
     1143        base._bindImp 
     1144        _what.bindImp   
     1145        if _typeNode 
     1146            _typeNode.bindImp 
     1147            _excType = _typeNode.realType  
     1148            _excType.bindAll 
     1149 
     1150        _getExpr.bindImp 
     1151        _type = _getExpr.type to ! 
     1152     
    11101153class IdentifierExpr 
    11111154    is partial 
    11121155    inherits NameExpr 
  • Source/Cobra.Lang/Native.cs

     
    555555        return results; 
    556556    } 
    557557 
     558    // Support for TryCatchExpression  
     559    // Below is signature of closures containing the expressions  
     560    public delegate TOut TryCatchExpr<TOut>();  
     561     
     562    // TryCatchExpr - No exception specified  
     563    static public TOut RunTryCatchExpr<TOut>(TryCatchExpr<TOut> tryCatch, TryCatchExpr<TOut> tryGet) { 
     564            TOut r; 
     565            try {  
     566                r = tryCatch(); 
     567            } 
     568            catch {  
     569                r = tryGet(); 
     570            } 
     571            return r; 
     572    } 
    558573 
     574    // TryCatchExpr TExc exception specified  
     575    static public TOut RunTryCatchExpr<TOut, TExc>(TryCatchExpr<TOut> tryCatch, TryCatchExpr<TOut> tryGet)  
     576        where TExc : System.Exception { 
     577            TOut r; 
     578            try {  
     579                r = tryCatch(); 
     580            } 
     581            catch ( TExc ) {  
     582                r = tryGet(); 
     583            } 
     584            return r; 
     585    } 
     586 
     587 
    559588    /* Numeric forExpr - ints in, any type returned */         
    560589    static public List<TOut> For<TIn, TOut>(int start, int stop, int step, ForGet<int, TOut> forGet) { 
    561590        if ((step > 0 && start > stop) ||  
  • 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        sw.write('CobraLangInternal.CobraImp.RunTryCatchExpr<[_type.sharpRef]') 
     3321        if _excType 
     3322            sw.write(',') 
     3323            sw.write(_excType.sharpRef) 
     3324        sw.write('>(') 
     3325        # try-expr delegate 
     3326        sw.write('delegate() {\n') 
     3327        sw.indent 
     3328        sw.write('return (') 
     3329        .what.writeSharpDef(sw, false) 
     3330        sw.write(');\n') 
     3331        sw.dedent 
     3332        sw.write('}') 
     3333        sw.write(', ') 
     3334        # get-expr delegate 
     3335        sw.write('delegate() {\n') 
     3336        sw.indent 
     3337        sw.write('return (') 
     3338        _getExpr.writeSharpDef(sw, false)    
     3339        sw.write(');\n') 
     3340        sw.dedent 
     3341        sw.write('})') 
     3342         
    33173343 
    33183344class IdentifierExpr 
    33193345    is partial 
  • Source/CobraParser.cobra

     
    29412941                return .ifExpr 
    29422942            on 'FOR' 
    29432943                return .forExpr 
     2944            on 'TRY' 
     2945                return .tryCatchExpr 
    29442946            on 'OPEN_CALL' 
    29452947                return .callExpr 
    29462948            on 'OPEN_GENERIC' 
     
    31803182            getExpr = .expression 
    31813183        return ForExpr(token, nameExpr, what, stopExpr, stepExpr, whereExpr, getExpr) 
    31823184 
     3185    def tryCatchExpr as TryCatchExpr 
     3186        """ 
     3187        t = try ...  catch FormatException get 0  
     3188        grammar: try EXPR catch [<EXCEPTIONTYPE>] get EXPR 
     3189        """ 
     3190        token = .expect('TRY') 
     3191        what = .expression 
     3192        .expect('CATCH') 
     3193        if .peek.which <> 'GET' 
     3194            excType = .typeId 
     3195        .expect('GET') 
     3196        getExpr = .expression 
     3197        return TryCatchExpr(token, what, excType, getExpr) 
     3198         
    31833199    def identifierExpr as Expr 
    31843200        """ 
    31853201        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         
     2727        # codegen below is specific to tryCatch as target of an assignment 
     2728        assert _superNode inherits BinaryOpExpr and  .binarySuperNode.op == 'ASSIGN' 
     2729        sw.write('{') 
     2730        sw.write(_type.javaRef) 
     2731        sw.write(' r; try { r = ') 
     2732        .what.writeJavaDef(sw, false) 
     2733        sw.write(';} catch ') 
     2734        if _excType 
     2735            sw.write('(') 
     2736            sw.write(_excType.javaRef) 
     2737            sw.write(') ') 
     2738        sw.write('{ r =') 
     2739        _getExpr.writeJavaDef(sw, false)     
     2740        sw.write('; } ') 
     2741        lhs = .binarySuperNode.left 
     2742        lhs.writeJavaDef(sw, false)  
     2743        sw.write(' = r; }') 
     2744     
     2745        # with java8 try this again for any arbitrarily embedded trycatch expr by generating a closure and  
     2746        # immediately executing of it - otherwise some method type inference and auto sig lookup/generation.         
    27242747 
     2748 
    27252749class IdentifierExpr is partial 
    27262750 
    27272751    def writeJavaDef(sw as CurlyWriter, parens as bool) is override 
     
    33063330    var isJavaSetProperty = false 
    33073331     
    33083332    def _writeJavaDef(sw as CurlyWriter) is override 
     3333        # special case handling/trap for tryCatch within assignment 
     3334        if _right inherits TryCatchExpr # expand trycatch and do assignment within the expansion 
     3335            _right.writeJavaDef(sw)  
     3336            return   
     3337 
    33093338        # TODO: 
    33103339        # if trackLocal: 
    33113340        #   out.write('CobraLangInternal.CobraImp.SetLocal("%s", ' % .left.name) 
  • Tests/200-misc/272j-try-catch-expr.cobra

     
     1#.require. jvm 
     2# try catch in expression not an assignment 
     3class TryExpr 
     4    def main is shared 
     5         
     6        x = 0 
     7        x = 4 + try int.parse('123') catch FormatException get 0 - 2  # .error. target of an assignment 
     8        CobraCore.noOp(x) 
     9        assert x == 0 # should never get here 
  • 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 666 
     14        assert x == 666 
     15         
     16        x=0 
     17        val1 ='foo1' 
     18        x = try int.parse(val1) catch FormatException get 666 
     19        assert x == 666 
     20         
     21        # all exceptions 
     22        x = try int.parse(val1) catch get 667 
     23        assert x == 667 
     24         
  • 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         
  • Tests/200-misc/272-try-catch-expr.cobra

     
     1#.require. clr 
     2# try catch in expression not an assignment 
     3class TryExpr 
     4    def main is shared 
     5         
     6        x = 0 
     7        x = 4 + try int.parse('123') catch FormatException get 0 - 2  
     8        assert x == 127 
     9         
     10        v = '120' 
     11        worked = 5 + (try int.parse(v) catch FormatException get 0 - 2) == 125 
     12        assert worked 
     13         
     14        v = 'x120' 
     15        x = 112 
     16        worked = 5 + (try int.parse(v) catch FormatException get x - 2) == 115 
     17        assert worked 
     18         
     19         
     20        dflt = '---' 
     21        s1 = '00' + try String.format('{1:P}', 0.123)+ '00' catch get dflt + '00' 
     22        assert s1 == '00---00' 
     23