Page 1 of 1

Incorrect behaviour with StringMaker inside IEnumerator

PostPosted: Wed Jun 24, 2015 3:51 pm
by Ourous
There seems to be incorrect behaviour in StringMaker.makeString when it is called from an IEnumerator that resolves inside a call to StringMaker.makeString. StringMaker._level is being set one-too-high during the calls from inside the IEnumerator, as it is being treated as an IEnumerable by the StringMaker.

Demonstrated here:
class Demo

def main

print .x
print .x.toList


def x as String*

print CobraImp._printStringMaker.level
print c'x'
print [1, 2, 3, 4].join('')

yield ''


Output:
Code: Select all
1
c'x'
'1234'
['']
0
x
1234
['']


EDITED OUT:

I originally had a proposed fix for this, but I've since realized it only covered some cases. When/if I can find a proper way to address this I will reply here.

Re: Incorrect behaviour with StringMaker inside IEnumerator

PostPosted: Thu Jun 25, 2015 12:33 am
by Charles
Yeah I've seen this problem and also had trouble formulating a fix.

Re: Incorrect behaviour with StringMaker inside IEnumerator

PostPosted: Thu Jun 25, 2015 12:50 am
by Ourous
Found a fix for it. As well as .makeString counting String as an IEnumerable and incrementing _level, which is fixed too.

--removed, see below--

Re: Incorrect behaviour with StringMaker inside IEnumerator

PostPosted: Sun Nov 15, 2015 9:20 pm
by Ourous
StringMaker_fix_for_IEnumerator_V2.patch
(2.07 KiB) Downloaded 1343 times


Replacement for the patch. Fixes a cast exception that it introduced and adds tests.

Re: Incorrect behaviour with StringMaker inside IEnumerator

PostPosted: Mon Nov 30, 2015 12:40 am
by Charles
This is applied with a minor test case correction so that it passes on both .NET and Mono.

Thanks.

Re: Incorrect behaviour with StringMaker inside IEnumerator

PostPosted: Wed Dec 09, 2015 5:37 pm
by james
Hi. Will this fix be available in the latest download? Thanks :)

Re: Incorrect behaviour with StringMaker inside IEnumerator

PostPosted: Tue Dec 15, 2015 1:35 pm
by Ourous
The fix is applied to the latest revision (3119) if you install from source using a subversion client. It won't be in the 0.9.6 download file.

Re: Incorrect behaviour with StringMaker inside IEnumerator

PostPosted: Wed Dec 16, 2015 2:34 am
by thriwkin
How to install the latest version of the compiler from source?
See here: http://cobra-language.com/trac/cobra/wiki/HowToInstallFromSource


@ Ourous

Yes, the latest changeset (http://cobra-language.com/trac/cobra/changeset/3119)
does "fix" something:
- now the print statement can print an iterator that produces 1 element,
even if both, the iterator and the print statement, use the same instance of PrintStringMaker.

But what happens when the iterator produces more than 1 element?
Look at this example:

class Demo
def m1 as String*
"""
This is the iterator of the testcase, which was added to Cobra svn:3119.
It "enumerates" 1 item only.
"""
yield ['a', 'b', 'c'].join('')

def m3 as String*
"""
This is the same iterator, but it produces 3 items, instead of 1 only.
"""
yield ['a', 'b', 'c'].join('')
yield ['a', 'b', 'c'].join('')
yield ['a', 'b', 'c'].join('')

def main
print .m1
print .m3


The expected/correct output of print .m3 is:
- ['abc', 'abc', 'abc']
The actual output is
- in Cobra svn:3118: [''a''b''c'', ''a''b''c'', ''a''b''c''] -- all items wrong
- in Cobra svn:3119: ['abc', ''a''b''c'', ''a''b''c''] -- the first item is correct!

Ourous, you are right, it is the `_level` in `StringMaker.enumerableToString`:
it must be 0 when the `IEnumerator.moveNext` method of the iterator is executed -- but always, not just for the first item.

Re: Incorrect behaviour with StringMaker inside IEnumerator

PostPosted: Wed Dec 30, 2015 3:44 pm
by Ourous
Ah damn I made a poor assumption - I figured that it resolved the entire enumerator into an enumerable when the first run through the for was executed. I'll get to work on this.

EDIT: Done

StringMaker_fix_for_IEnumerator_fix.patch
(393 Bytes) Downloaded 1221 times