Array/String slicing

11 views
Skip to first unread message

Paul Nema

unread,
Dec 22, 2011, 4:03:38 PM12/22/11
to FalconPL


Working on extending string slicing, then array slicing.
For example:
a='string'
b = a[2:5]

My main question is how do I get access to the "2:5"
In classstring.cpp you have:
    296 void ClassString::op_getIndex( VMContext* ctx, void* self ) const
    297 {
    298    Item *index, *stritem;
    299    ctx->operands( stritem, index );
    300 
    301    String& str = *static_cast<String*>(self);
    302 
    303    if (index->isOrdinal())

index is of type Item.
If user states: a[3]
index->content.base.bits.type is set to FLC_ITEM_INT (real value = 2)

if the user states: a[1:3]
index->content.base.bits.type is set to FLC_ITEM_USER (real value = 8)

So I know if the user enters 3 or 1:3, but how do I get access to "1:3"

Thanks

Giancarlo Niccolai

unread,
Dec 22, 2011, 7:09:47 PM12/22/11
to falc...@googlegroups.com
In the new engine...

User items are a pair of a class and an instance.

They can be accessed via asClass() and asInst(), or simply via asClassInst(). This latter function checks the type of the item and if it's a deep (user) item, it will fills the class and instance parameters you pass.

The method forceClassInst will return a class and an instance for ANY item; flat items have a standard class stored in the engine (I.e. ClassInteger or ClassBool or even ClassNil) and you'll receive that if the item you apply forceClassInst to.

Classes with a special meaning to the language (as ClassInteger, ClassString, ClassRange) have a typeID member returning a positive integer (the value for typeID at script level). So you can check for the item you get in op_getProperty to be a range accessing its class and checking if the class typeID is FLC_CLASS_ID_RANGE.

If the class is ClassRange, then your instance can be static cast to a Range*.

Gian


Inviato da iPad
--
You received this message because you are subscribed to the Google Groups "FalconPL" group.
To post to this group, send email to falc...@googlegroups.com.
To unsubscribe from this group, send email to falconpl+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/falconpl?hl=en.

Paul Nema

unread,
Dec 23, 2011, 8:20:41 PM12/23/11
to falc...@googlegroups.com
Thanks, working on it now.

Some FYI for future work.  The survival guide states this is valid for arrays so I assume the same is true for strings?

Welcome to Falcon.
>>> a='asdfgh'
"asdfgh"
>>> a[:]
 CP0153 at (interactive):2:4: Error in expression syntax
 CP0001 at (interactive):2:6: Generic syntax error
>>> 

OmniMancer stated we just need to make the new engine aware of this is valid

Thanks

Giancarlo Niccolai

unread,
Dec 23, 2011, 8:55:11 PM12/23/11
to falc...@googlegroups.com
On 24/12/2011 02:20, Paul Nema wrote:
> Thanks, working on it now.
>
> Some FYI for future work. The survival guide states this is valid for
> arrays so I assume the same is true for strings?
>
> Welcome to Falcon.
> >>> a='asdfgh'
> "asdfgh"
> >>> a[:]
> CP0153 at (interactive):2:4: Error in expression syntax
> CP0001 at (interactive):2:6: Generic syntax error
> >>>
>


Yep. the parser is brand new, and hand-made. If any incongruence is
found, unless there is a very good reason to change it, it should be
made 100% backward compatible.

In other words, since you're at it you may have a try at fixing it. All
the grammar is in engine)/sp/source_parser.cpp

Gian.

Paul Nema

unread,
Dec 24, 2011, 2:57:05 PM12/24/11
to falc...@googlegroups.com

Ok cool, I'll take care of this by adding the grammar to support backward compatibility.

Thanks

Paul Nema

unread,
Dec 27, 2011, 7:02:32 PM12/27/11
to falc...@googlegroups.com

Updated the array handling for strings. Using the Survival Guide array examples for test cases here is the result. Let me know if this is correct (it matches the what I see in the survival guide). Note: the general rule implemented is:

a='abcefg'

example: a[start:end]

if start or end are negative their position in the array is used. a[-5:4] converted to values = [1:4] giving the values of ('bce')

if start is less than end (I.E. [2:4], [-4:-1]) result is in order of the string

if start is greater than end (I.E. [4:2], [-1:-3] which converts to ィ [5:3]) result is in reverse order.

 

Here are the test cases:

pnema@1-LX-D620:~/Projects/build$ bin/falcon -i

Welcome to Falcon.

>>> a='abcefg'

"abcefg"

>>> a[2:4]

"ce"

>>> a[2:]

"cefg"

>>> a[0:3]

"abc"

>>> a[0:]

"abcefg"

>>> a[:] // This will be fixed soon in sourceparser.cpp

CP0153 at (interactive):6:4: Error in expression syntax

CP0001 at (interactive):6:6: Generic syntax error

>>> a[-2:-1]

"f"

>>> a[-4:]

"cefg"

>>> a[-1:]

"g"

>>> a[3:0]

"ecba"

>>> a[4:2]

"fec"

>>> a[-1:4]

"gf"

>>> a[-1:0]

"gfecba"

>>>

Paul Nema

unread,
Dec 27, 2011, 7:04:35 PM12/27/11
to falc...@googlegroups.com

Not sure how place the result of a range array request onto the stack.

With string arrays, I created a new string, added the value in question and call VMContext->stackResult.

VMContext* ctx;

...stuff

String *s = new String();

c stuff

ctx->stackResult( 2, s->garbage() );

what class do I use for actual arrays?

Vmcontext.h defines stakcResult as: inline void stackResult( int count, const Item& result )

ClassArray is not derived from Item or has a method that returns an Item. So what is the correct way generate an array and place it onto the stack.

Does one create a new ItemArray? And place that on the stack using method elements()? This does not seem to work?

Code sample

VMContext* ctx;

...stuff

ItemArray *returnArray = new ItemArray( abs( (start - end) + 1 ) );

...stuff

loop:

returnArray->append( array[cnt] )

stuff...

ctx->stackResult( 2, *(returnArray->elements()) );

pnema@1-LX-D620:~/Projects/build$ !b

bin/falcon -i

Welcome to Falcon.

>>> a=[1,2,3,4]

[1, 2, 3, 4]

>>> a[0:]

1

>>>

a[0:] should return [1,2,3,4]

Paul Nema

unread,
Dec 27, 2011, 7:05:32 PM12/27/11
to falc...@googlegroups.com

Need some help understanding the how to add a production rule for array ranges.

I looked at the code but don't fully understand it.

I'm looking to add the patterns and rule for an array range matching the pattern of [:]

So added the following:

end of parser_arraydecl.h

void apply_array_entry_range0( const Rule&, Parser& p );

 

sourceparser.h

Parsing::Rule r_array_entry_range0;

 

sourceparser.cpp

575 ArrayEntry << ( r_array_entry_range0 << "array_entry_range0" << apply_array_entry_range0.

576 << T_Colon << T_CloseSquare );

Is the above pattern correct? ( << T_Colon << T_CloseSquare ) to match [:]

 

parser_arraydecl.cpp

473 void apply_array_entry_range0( const Rule&, Parser& p )

474 {

475 // << T_Colon << T_CloseSquare

476 makeRange( p, 2,

477 0,

478 0,

479 0

480 );

481 }

Not sure what makeRange is doing? I assume 0's are passed as there are no expressions.

 
Sorry if above format is messed up but I think its understandable 

Giancarlo Niccolai

unread,
Dec 28, 2011, 4:27:48 AM12/28/11
to falc...@googlegroups.com
On 28/12/2011 01:04, Paul Nema wrote:
>
> Not sure how place the result of a range array request onto the stack.
>
> With string arrays, I created a new string, added the value in
> question and call VMContext->stackResult.
>
> VMContext* ctx;
>
> ...stuff
>
> String *s = new String();
>
> c stuff
>
> ctx->stackResult( 2, s->garbage() );
>
> what class do I use for actual arrays?
>

String::garbage() it's just a shortcut (which I don't even like too
much) for FALCON_GC_STORE macro applied to strings.

It should be:
ctx->stackResult( 2, FALCON_GC_STORE( coll, clsArray, theArray) );

where coll and clsArray are the Engine::instance()->collector() and
Engine::instance()->classArray() (or arrayClass()). You can create
static variables in the function so that this data is queried just once,
or put them as fields in the owning class, or ... well do anything you
like to keep them around.


The rest seems ok.

Gian.

Giancarlo Niccolai

unread,
Dec 28, 2011, 4:29:04 AM12/28/11
to falc...@googlegroups.com
On 28/12/2011 01:05, Paul Nema wrote:
>
> Need some help understanding the how to add a production rule for
> array ranges.
>
> I looked at the code but don't fully understand it.
>
> I'm looking to add the patterns and rule for an array range matching
> the pattern of [:]
>
> So added the following:
>
>
<rip>

It seems more or less correct. If it works, I'd say it's ok.

Gian.

Reply all
Reply to author
Forward
0 new messages