cwal

Check-in [4f0d98c329]
Login

Check-in [4f0d98c329]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:s2 array.sort() now internally uses floating-point comparison so that sort routines which do things like (return 0.1-0.3) can DTRT. Prompted by a bug report files against mujs: https://github.com/ccxvii/mujs/issues/122
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4f0d98c3294778c603514c92c06af7a3fc368aab
User & Date: stephan 2019-12-20 17:43:30
Context
2019-12-20
17:49
Minor doc addition. check-in: f26d804fe8 user: stephan tags: trunk
17:43
s2 array.sort() now internally uses floating-point comparison so that sort routines which do things like (return 0.1-0.3) can DTRT. Prompted by a bug report files against mujs: https://github.com/ccxvii/mujs/issues/122 check-in: 4f0d98c329 user: stephan tags: trunk
17:35
s2: improved error reporting for invalid \Uxxxxxxxx sequence in a string literal, which previously fatally killed scripts with no error location info. It now triggers a syntax error, which catch{} is capable of downgrading to an exception, but that behaviour is arguable because this same error is, due to the shape of the API, indistinguishable from other invalid UTF8. check-in: e458b2a5fd user: stephan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to cwal.c.

9621
9622
9623
9624
9625
9626
9627
9628








9629
9630
9631
9632
9633
9634
9635
    ArrayFuncState * st = (ArrayFuncState *)state;
    cwal_value * rv = 0;
    int rc = 0;
    argv[0] = lhs ? lhs : cwal_value_undefined();
    argv[1] = rhs ? rhs : cwal_value_undefined();
    *errCode = cwal_function_call(st->f, st->self, &rv, 2, argv);
    cwal_value_ref(rv);
    if(!*errCode && rv) rc = cwal_value_get_integer(rv);








    cwal_value_unref(rv);
    return rc;
}

int cwal_array_sort_func( cwal_array * ar, cwal_value * self, cwal_function * cmp ){
    if(!ar || !cmp) return CWAL_RC_MISUSE;
    else if(CWAL_V_IS_VISITING_LIST(CWAL_VALPART(ar))) return CWAL_RC_IS_VISITING_LIST;







|
>
>
>
>
>
>
>
>







9621
9622
9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
    ArrayFuncState * st = (ArrayFuncState *)state;
    cwal_value * rv = 0;
    int rc = 0;
    argv[0] = lhs ? lhs : cwal_value_undefined();
    argv[1] = rhs ? rhs : cwal_value_undefined();
    *errCode = cwal_function_call(st->f, st->self, &rv, 2, argv);
    cwal_value_ref(rv);
    if(!*errCode && rv){
        /* We have to resolve this using doubles, not integers. See
           https://github.com/ccxvii/mujs/issues/122 for why. */
        cwal_double_t const d = cwal_value_get_double(rv);
        rc = (0.0==d) ? 0 : ((d<0) ? -1 : 1);
        /* There's a corner-case bug here, though: if rv is an
           integer value larger than cwal_double_t can represent, the
           results will very possibly be wrong. */           
    }
    cwal_value_unref(rv);
    return rc;
}

int cwal_array_sort_func( cwal_array * ar, cwal_value * self, cwal_function * cmp ){
    if(!ar || !cmp) return CWAL_RC_MISUSE;
    else if(CWAL_V_IS_VISITING_LIST(CWAL_VALPART(ar))) return CWAL_RC_IS_VISITING_LIST;

Changes to s2/unit/500-000-array.s2.

287
288
289
290
291
292
293













    a.sort(proc(l,r){
        assert !typeinfo(mayiteratelist a);
        return -l.compare(r);
    });
    assert 3 === a.0;
}



















>
>
>
>
>
>
>
>
>
>
>
>
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305

    a.sort(proc(l,r){
        assert !typeinfo(mayiteratelist a);
        return -l.compare(r);
    });
    assert 3 === a.0;
}

scope {
    /*
      Array comparison func must internally use floating point
      comparisons:
    */
    const l = [{a: 0.5}, {a: -0.1}, {a: 0.7}];
    l.sort(proc(x,y) {return x.a - y.a});
    assert 0.7===l.2.a;
    assert 0.5===l.1.a;
    assert -0.1===l.0.a;
}