Search code examples
genie

"Embedded statement cannot be declaration" error in Genie


It seems that is something out-of-date in Genie's website. Perhaps HashMaps are not supported anymore or their syntax has changed.

If one tries the examples from the old BarryK website:

uses
    Gee

init
    var d = new dict of string,string
    d["fruit"] = "apple"
    d["animal"] = "dog"
    d.set("plant","cactus")
    d.set("animal","hippopotomus") /*changes from 'dog'*/
    if d.contains("plant") == true do print "Key 'plant' is in dictionary"
    print "%s", d.get("animal")
    for o in d.keys do print o //old libgee use d.get_keys()
    for o in d.values do print o //old libgee use d.get_values()
    d.remove("animal")

One gets the error dicts.gs:7.36-7.40: error: syntax error, embedded statement cannot be declaration for the lines starting with:

  • if d.contains
  • for o in d.keys
  • for o in d.values

Furthermore, using the official Genie website there is no much success:

[indent=4]

uses
    Gee

init

    /* test dicts */
    var d = new dict of string,string

    /* add or change entries with following */
    d["Genie"] = "Great"
    d["Vala"] = "Rocks"


    /* access entires using d[key] */
    /* note that instead of "d.get_keys ()" it is "d.keys" in newer Versions of Gee */
    for s in d.get_keys ()
        print "%s => %s", s, d[s]

Generates the error: dicts.gs:18.14-18.23: error: The name `get_keys' does not exist in the context of `Gee.HashMap<string,string>' for line for s in d.get_keys ()

Am I missing something or is the site out of date?

Update For completness, I've been using Manjaro linux, my libgee package is version 0.18 and there is an extra error in compilation gee-0.8.vapi:664.4-664.13: warning: [Deprecated] is deprecated. Use [Version (deprecated = true, deprecated_since = "", replacement = "")]


Solution

  • The "embedded statement cannot be declaration" message is caused by using the do keyword instead of starting a new block. If you use:

    if d.contains("plant") == true
        print "Key 'plant' is in dictionary"
    

    This will compile. Alternatively you can change print from a statement to a function call and that will also compile:

    if d.contains("plant") == true do print( "Key 'plant' is in dictionary" )
    

    A working example, also updated for Gee version 0.8, would be:

    [indent=4]
    uses
        Gee
    
    init
        var d = new dict of string,string
        d["fruit"] = "apple"
        d["animal"] = "dog"
        d.set("plant","cactus")
        d.set("animal","hippopotomus") /*changes from 'dog'*/
        if d.has_key("plant") == true do print( "Key 'plant' is in dictionary" )
        print "%s", d.get("animal")
        for o in d.keys do print( o )
        for o in d.values do print( o )
        d.unset("animal")
    

    I wasn't aware of a difference between the print statement and the print function call, but you seem to have found one. I guess the parser is looking to do an action and an action should be a function call.

    For the example from the Genie tutorial you have missed the comment 'note that instead of "d.get_keys ()" it is "d.keys" in newer Versions of Gee'. Gee 0.8 is actually the newer version, so you should be using for s in d.keys. I have updated the tutorial to just show the newer version because Gee 0.8 has been around for a long time now. The working example is:

    [indent=4]
    uses
        Gee
    
    init
        /* test dicts */
        var d = new dict of string,string
    
        /* add or change entries with following */
        d["Genie"] = "Great"
        d["Vala"] = "Rocks"
    
        /* access entires using d[key] */
        for var s in d.keys
            print "%s => %s", s, d[s]
    

    The compiler warning about the [Deprecated] attribute being deprecated is because Vala 0.32 replaced it with the [Version] attribute and the Gee bindings have not been updated yet.