Merge: Stringify Bytes
authorJean Privat <jean@pryen.org>
Thu, 3 Dec 2015 20:59:29 +0000 (15:59 -0500)
committerJean Privat <jean@pryen.org>
Thu, 3 Dec 2015 20:59:29 +0000 (15:59 -0500)
This PR adds some String-like functions to Bytes, along with an abstraction for Byte-based patterns.

Also, a bug was found within `Bytes::is_empty` and `FlatText` is now public since there was no real rationale to keep it private

Pull-Request: #1860
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>

56 files changed:
contrib/benitlux/src/benitlux_daily.nit
contrib/nitiwiki/examples/default/config.ini
contrib/nitiwiki/examples/default/templates/header.html
contrib/nitiwiki/examples/nitiwiki/pages/section/other_section/first.md [new file with mode: 0644]
contrib/nitiwiki/examples/nitiwiki/pages/section/other_section/index.md [new file with mode: 0644]
contrib/nitiwiki/examples/nitiwiki/pages/section/other_section/second.md [new file with mode: 0644]
contrib/nitiwiki/examples/nitiwiki/templates/menu.html
contrib/nitiwiki/src/wiki_html.nit
contrib/nitiwiki/src/wiki_links.nit
contrib/nitrpg/src/achievements.nit
contrib/nitrpg/src/events.nit
contrib/nitrpg/src/game.nit
contrib/nitrpg/src/reactors.nit
contrib/nitrpg/src/statistics.nit
contrib/nitrpg/src/templates/templates_base.nit
lib/android/audio.nit
lib/console.nit
lib/core/bytes.nit
lib/core/collection/array.nit
lib/core/collection/circular_array.nit [new file with mode: 0644]
lib/core/collection/collection.nit
lib/core/collection/hash_collection.nit
lib/core/collection/list.nit
lib/core/text/abstract_text.nit
lib/github/api.nit
lib/github/events.nit
lib/libevent.nit
lib/markdown/markdown.nit
lib/mongodb/mongodb.nit
lib/mongodb/native_mongodb.nit
lib/nitcorn/log.nit [new file with mode: 0644]
lib/pthreads/concurrent_collections.nit
lib/pthreads/examples/threadpool_example.nit [new file with mode: 0644]
lib/pthreads/threadpool.nit [new file with mode: 0644]
src/astvalidation.nit
src/ffi/cpp.nit
src/modelize/modelize_property.nit
src/parser/nit.sablecc3xx
src/parser/tables_nit.c
src/rapid_type_analysis.nit
tests/base_prot_sig.nit
tests/bench_seq.nit [new file with mode: 0644]
tests/exec.skip
tests/sav/base_prot_sig_alt1.res
tests/sav/base_prot_sig_alt2.res
tests/sav/base_prot_sig_alt3.res
tests/sav/base_prot_sig_alt4.res
tests/sav/base_prot_sig_alt5.res
tests/sav/base_prot_sig_alt6.res
tests/sav/base_prot_sig_alt7.res
tests/sav/bench_seq.res [new file with mode: 0644]
tests/sav/nituml_args3.res
tests/sav/nituml_args4.res
tests/sav/test_new_native_alt1.res
tests/sav/test_seq.res
tests/test_seq.nit

index d242751..f9e8400 100644 (file)
@@ -89,9 +89,19 @@ class Benitlux
                # Get the web page
                var body = download_html_page
 
+               if opts.verbose.value > 1 then
+                       print " # Body"
+                       print body
+               end
+
                # Parse the Web page and get the available beers
                var beers = parse_beers_from_html(body)
 
+               if opts.verbose.value > 0 then
+                       print " # Beers"
+                       print beers
+               end
+
                var db = new DB.open(db_path)
 
                # Update the database with the beers of the day
@@ -112,6 +122,10 @@ class Benitlux
                # Set the email if desired
                if send_emails then
                        var subs = db.subscribers
+                       if opts.verbose.value > 0 then
+                               print " # Subscribers"
+                               print subs
+                       end
                        send_emails_to subs
                end
 
@@ -152,9 +166,14 @@ class Benitlux
                var of_interest = body.substring(start, finish-start)
                var lines = of_interest.strip_tags.to_clean_lines
 
+               if opts.verbose.value > 0 then
+                       print " # Lines"
+                       print lines
+               end
+
                var beers = new HashSet[Beer]
                for line in lines do
-                       var parts = line.split(" - ")
+                       var parts = line.split("- ")
                        if parts.length >= 2 then
                                beers.add new Beer(parts[0].trim, parts[1].trim)
                        end
@@ -202,16 +221,23 @@ redef class OptionContext
        # Shall we mail the mailing list?
        var send_emails = new OptionBool("Send emails to subscribers", "-e", "--email")
 
+       # Display more debug messages
+       var verbose = new OptionCount("Display extra debug messages", "-v")
+
        # Print the usage message
        var help = new OptionBool("Print this help message", "-h", "--help")
 
-       redef init do add_option(send_emails, help)
+       redef init do add_option(send_emails, verbose, help)
+end
+
+redef class Sys
+       # Command line options
+       var opts = new OptionContext
 end
 
 # Avoid executing when running tests
 if "NIT_TESTING".environ == "true" then exit 0
 
-var opts = new OptionContext
 opts.parse args
 if not opts.errors.is_empty or opts.help.value == true then
        print opts.errors.join("\n")
index 7917052..9ac9824 100644 (file)
@@ -1,4 +1,3 @@
 wiki.name=MyWiki
 wiki.desc=proudly powered by nit
 wiki.logo=assets/logo.png
-wiki.root_dir=/full/path/to/your/wiki/root/dir
index d86aac9..298f8ab 100644 (file)
@@ -1,5 +1,5 @@
 <header>
-    <a href="#"><img src="%ROOT_URL%/%LOGO%" alt="logo"/></a>
+    <a href="%ROOT_URL%/index.html"><img src="%ROOT_URL%/%LOGO%" alt="logo"/></a>
     <h2>%SUBTITLE%</h2>
     <h1>%TITLE%</h1>
 </header>
diff --git a/contrib/nitiwiki/examples/nitiwiki/pages/section/other_section/first.md b/contrib/nitiwiki/examples/nitiwiki/pages/section/other_section/first.md
new file mode 100644 (file)
index 0000000..c61423f
--- /dev/null
@@ -0,0 +1 @@
+first page
diff --git a/contrib/nitiwiki/examples/nitiwiki/pages/section/other_section/index.md b/contrib/nitiwiki/examples/nitiwiki/pages/section/other_section/index.md
new file mode 100644 (file)
index 0000000..0a918d5
--- /dev/null
@@ -0,0 +1,3 @@
+# A independant trail
+
+a [[trail: first]] and a [[trail: second]] page.
diff --git a/contrib/nitiwiki/examples/nitiwiki/pages/section/other_section/second.md b/contrib/nitiwiki/examples/nitiwiki/pages/section/other_section/second.md
new file mode 100644 (file)
index 0000000..ce04f0f
--- /dev/null
@@ -0,0 +1 @@
+a second page
index 1ff832e..ec20a0e 100644 (file)
@@ -8,7 +8,7 @@
                                <span class="icon-bar"></span>
                                <span class="icon-bar"></span>
                        </button>
-                       <a class="navbar-brand" href="%ROOT_URL%index.html">%TITLE%</a>
+                       <a class="navbar-brand" href="%ROOT_URL%/index.html">%TITLE%</a>
                </div>
                <!-- Collect the nav links, forms, and other content for toggling -->
                <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
index 05c06f9..ab79f09 100644 (file)
@@ -189,10 +189,7 @@ redef class WikiArticle
        fun load_template(template_file: String): TemplateString do
                var tpl = wiki.load_template(template_file)
                if tpl.has_macro("ROOT_URL") then
-                       var root_dir = href.dirname.relpath("")
-                       # Avoid issues if the macro is just followed by a `/` (as with url prefix)
-                       if root_dir == "" then root_dir = "."
-                       tpl.replace("ROOT_URL", root_dir)
+                       tpl.replace("ROOT_URL", root_href)
                end
                return tpl
        end
@@ -313,17 +310,21 @@ redef class WikiArticle
 
                var res = new Template
                res.add "<ul class=\"trail\">"
-               if pos > 0 then
-                       var target = flat[pos-1]
-                       res.add "<li>{target.a_from(self, "prev")}</li>"
-               end
                var parent = wiki.trails.parent(self)
+               # Up and prev are disabled on a root
                if parent != null then
+                       if pos > 0 then
+                               var target = flat[pos-1]
+                               res.add "<li>{target.a_from(self, "prev")}</li>"
+                       end
                        res.add "<li>{parent.a_from(self, "up")}</li>"
                end
                if pos < flat.length - 1 then
                        var target = flat[pos+1]
-                       res.add "<li>{target.a_from(self, "next")}</li>"
+                       # Only print the next if it is not a root
+                       if target.parent != null then
+                               res.add "<li>{target.a_from(self, "next")}</li>"
+                       end
                end
                res.add "</ul>"
 
index 03f21ca..c1785b2 100644 (file)
@@ -100,12 +100,23 @@ redef class WikiEntry
        # Relative path to `self` from the target root_url
        fun href: String do return breadcrumbs.join("/")
 
+       # Relative path to the directory `self` from the target root_url
+       fun dir_href: String do return href.dirname
+
+       # Relative path to the root url from `self`
+       fun root_href: String do
+               var root_dir = dir_href.relpath("")
+               # Avoid issues if used as a macro just followed by a `/` (as with url prefix)
+               if root_dir == "" then root_dir = "."
+               return root_dir
+       end
+
        # A relative `href` to `self` from the page `context`.
        #
        # Should be used to navigate between documents.
        fun href_from(context: WikiEntry): String
        do
-               var res = context.href.dirname.relpath(href)
+               var res = context.dir_href.relpath(href)
                return res
        end
 
@@ -174,6 +185,8 @@ redef class WikiSection
                end
                return new WikiSectionIndex(wiki, "index", self)
        end
+
+       redef fun dir_href do return href
 end
 
 redef class WikiArticle
@@ -212,6 +225,8 @@ class WikiSectionIndex
        redef fun title do return section.title
 
        redef fun href do return section.href
+
+       redef fun dir_href do return section.dir_href
 end
 
 # A MarkdownProcessor able to parse wiki links.
index 9b18a6b..5ce317a 100644 (file)
@@ -74,10 +74,15 @@ end
 class Achievement
        super GameEntity
 
-       redef var key is lazy do return "achievements" / id
 
        redef var game
 
+       redef var key is lazy do
+               var owner = self.owner
+               if owner == null then return id
+               return "{owner.key}-{id}"
+       end
+
        # Uniq ID for this achievement.
        var id: String
 
@@ -93,6 +98,9 @@ class Achievement
        # Is this achievement unlocked by somebody?
        var is_unlocked: Bool is lazy do return not load_events.is_empty
 
+       # Game entity this achievement is about.
+       var owner: nullable GameEntity = null
+
        # Init `self` from a `json` object.
        #
        # Used to load achievements from storage.
@@ -106,6 +114,8 @@ class Achievement
                json["name"] = name
                json["desc"] = desc
                json["reward"] = reward
+               json["game"] = game.key
+               if owner != null then json["owner"] = owner.key
                return json
        end
 end
@@ -346,7 +356,7 @@ abstract class PlayerXCommits
                if not event.action == "closed" then return
                if not event.pull.merged then return
                var player = event.pull.user.player(game)
-               if player.stats["commits"] == threshold then
+               if player.stats["commits"] >= threshold then
                        var a = new_achievement(game)
                        player.unlock_achievement(a, event)
                end
@@ -447,7 +457,7 @@ end
 class Player1KComments
        super PlayerXComments
 
-       redef var id = "player_1000__comments"
+       redef var id = "player_1000_comments"
        redef var name = "You sir, talk a lot!"
        redef var desc = "Comment 1000 times on issues."
        redef var reward = 1000
index d1ba25a..bd1ee58 100644 (file)
@@ -24,8 +24,10 @@ import game
 
 redef class GameEntity
 
-       # Saves `event` in `self`.
-       fun add_event(event: GameEvent) do event.save_in(self.key)
+       fun add_event(event: GameEvent) do
+               event.owner = self
+               event.save
+       end
 
        # List all events registered in this entity.
        #
@@ -61,10 +63,12 @@ end
 class GameEvent
        super GameEntity
 
-       redef var key is lazy do return "events" / internal_id
 
        redef var game
 
+       # Entity this event belongs to.
+       var owner: nullable GameEntity = null
+
        # String used to dissociate events in the display.
        var kind: String
 
@@ -76,6 +80,8 @@ class GameEvent
        # GameEvent uniq id used for storage.
        var internal_id: String is noinit
 
+       redef var key = internal_id is lazy
+
        # Date and time of the event.
        var time: ISODate is noinit, writable
 
@@ -100,6 +106,8 @@ class GameEvent
                json["kind"] = kind
                json["time"] = time.to_s
                json["data"] = data
+               json["game"] = game.key
+               if owner != null then json["owner"] = owner.key
                return json
        end
 end
index a109949..2924e46 100644 (file)
@@ -65,20 +65,20 @@ class Game
 
        redef fun game do return self
 
-       # Returns the repo `full_name`.
-       #
-       # Example: `"nitlang/nit"`
-       redef fun key do return repo.full_name
-
        # We need a `GithubAPI` client to load Github data.
        var api: GithubAPI
 
        # A game takes place in a `github::Repo`.
        var repo: Repo
 
+       # Game name
+       var name: String = repo.full_name is lazy
+
        # Directory where game data are stored.
        var game_dir: String is lazy do return "nitrpg_data" / repo.full_name
 
+       redef var key = name is lazy
+
        # Used for data storage.
        #
        # File are stored in `game_dir`.
@@ -92,6 +92,12 @@ class Game
        # Used to load entities from saved data.
        fun from_json(json: JsonObject) do end
 
+       redef fun to_json do
+               var json = super
+               json["name"] = name
+               return json
+       end
+
        # Create a player from a Github `User`.
        #
        # Or return the existing one from game data.
@@ -180,9 +186,6 @@ end
 class Player
        super GameEntity
 
-       # Key is based on player `name`.
-       redef var key is lazy do return "players" / name
-
        redef var game
 
        # FIXME contructor should be private
@@ -195,6 +198,8 @@ class Player
        # The name is also used to load the user data lazilly from Github API.
        var name: String
 
+       redef var key = name is lazy
+
        # Player amount of nitcoins.
        #
        # Nitcoins is the currency used in nitrpg.
@@ -218,6 +223,7 @@ class Player
 
        redef fun to_json do
                var json = super
+               json["game"] = game.key
                json["name"] = name
                json["nitcoins"] = nitcoins
                return json
index 7073c98..e2717f4 100644 (file)
@@ -58,7 +58,7 @@ redef class PullRequestEvent
 
        # Rewards player for opened pull requests.
        redef fun react_player_event(r, game) do
-               if action == "opened" then
+               if action == "opened" or action == "reopened" then
                        react_pull_open(r, game)
                else if action == "closed" then
                        react_pull_close(r, game)
@@ -95,14 +95,18 @@ redef class IssueCommentEvent
        # Rewards player for review comments.
        #
        # TODO only give nitcoins if reviewers < 2
+       # TODO give more points to first reviewer
        redef fun react_player_event(r, game) do
                if comment.is_ack then
                        react_player_review(r, game)
                end
        end
 
+       # TODO same player should not be authorized to review multiple times? How to handle rerols?
        private fun react_player_review(r: PlayerReactor, game: Game) do
+               if issue.state == "closed" then return
                var player = comment.user.player(game)
+               if issue.user == player.user then return
                player.nitcoins += r.nc_pull_review
                player.save
                var event = player_reward_event("pull_review", player, r.nc_pull_review)
index b7d3530..153b5cd 100644 (file)
@@ -79,49 +79,32 @@ class GameStatsManager
        # The GameEntity monitored by these statistics.
        var owner: GameEntity
 
-       redef var key = "stats"
+       # Current date to extract stats
+       private var date = new Tm.gmtime
 
        # Returns the `GameStats` instance for the overall statistics.
-       var overall: GameStats is lazy do
-               return load_stats_for("all")
-       end
+       var overall: GameStats = load_stats_for("all") is lazy
 
        # Returns the `GameStats` instance for the current year statistics.
-       var yearly: GameStats is lazy do
-               var date = new Tm.gmtime
-               var key = date.strftime("%Y")
-               return load_stats_for(key)
-       end
+       var yearly: GameStats = load_stats_for(date.strftime("%Y")) is lazy
 
        # Returns the `GameStats` instance for the current month statistics.
-       var monthly: GameStats is lazy do
-               var date = new Tm.gmtime
-               var key = date.strftime("%Y-%m")
-               return load_stats_for(key)
-       end
+       var monthly: GameStats = load_stats_for(date.strftime("%Y-%m")) is lazy
 
        # Returns the `GameStats` instance for the current day statistics.
-       var daily: GameStats is lazy do
-               var date = new Tm.gmtime
-               var key = date.strftime("%Y-%m-%d")
-               return load_stats_for(key)
-       end
+       var daily: GameStats = load_stats_for(date.strftime("%Y-%m-%d")) is lazy
 
        # Returns the `GameStats` instance for the current week statistics.
-       var weekly: GameStats is lazy do
-               var date = new Tm.gmtime
-               var key = date.strftime("%Y-W%U")
-               return load_stats_for(key)
-       end
+       var weekly: GameStats = load_stats_for(date.strftime("%Y-W%U")) is lazy
 
        # Load statistics for a `period` key.
        fun load_stats_for(period: String): GameStats do
                var key = owner.key / self.key / period
                if not game.store.has_key(key) then
-                       return new GameStats(game, period)
+                       return new GameStats(game, period, owner)
                end
                var json = game.store.load_object(key)
-               return new GameStats.from_json(game, period, json)
+               return new GameStats.from_json(game, period, owner, json)
        end
 
        redef fun [](key) do return overall[key]
@@ -168,19 +151,28 @@ class GameStats
 
        redef var game
 
-       # The pedriod these stats are about.
+       # The period these stats are about.
        var period: String
 
-       redef fun key do return period
+       # The game entity these stats are about.
+       var owner: GameEntity
+
+       redef var key = "{owner.key}-{period}" is lazy
 
        # Load `self` from saved data.
-       init from_json(game: Game, period: String, json: JsonObject) do
-               for k, v in json do self[k] = v.as(Int)
+       init from_json(game: Game, period: String, owner: GameEntity, json: JsonObject) do
+               var values = json.get_or_null("values")
+               if not values isa JsonObject then return
+               for k, v in values do self[k] = v.as(Int)
        end
 
        redef fun to_json do
-               var obj = new JsonObject
-               for k, v in self do obj[k] = v
+               var obj = super
+               obj["period"] = period
+               obj["owner"] = owner.key
+               var values = new JsonObject
+               values.recover_with(self)
+               obj["values"] = values
                return obj
        end
 
index 8b85a4d..a4f40d9 100644 (file)
@@ -34,9 +34,6 @@ redef class Game
 
        redef fun url do return "{root_url}/games" / key
 
-       # Displayed name.
-       fun name: String do return repo.full_name
-
        # Return a HTML link to this Game.
        fun link: String do return "<a href=\"{url}\">{name}</a>"
 end
index 9cc54d7..649a95d 100644 (file)
@@ -646,7 +646,7 @@ redef class App
        var default_soundpool: SoundPool is lazy do return new SoundPool
 
        # Get the native audio manager
-       fun audio_manager: NativeAudioManager import native_activity in "Java" `{
+       private fun audio_manager: NativeAudioManager import native_activity in "Java" `{
                return (AudioManager)App_native_activity(self).getSystemService(Context.AUDIO_SERVICE);
        `}
 
index 0020b7a..b8fe277 100644 (file)
@@ -337,3 +337,75 @@ redef class String
        # WARNING: SEE: `TermCharFormat`
        fun underline: String do return apply_format(normal.underline)
 end
+
+# A dynamic progressbar displayable in console.
+#
+# Example:
+# ~~~nitish
+# var max = 10
+# var current = 0
+# var pb = new TermProgress(max, current)
+#
+# pb.display
+# for i in [current + 1 .. max] do
+#      nanosleep(1, 0)
+#      pb.update(i)
+# end
+#
+# print "\ndone"
+# ~~~
+#
+# Progressbar can accept metadata to display a small amount of data.
+#
+# Example with metadata:
+# ~~~nitish
+# var pb = new TermProgress(10, 0)
+# for i in [0..10] do
+#      pb.update(i, "Step {i}")
+# end
+# ~~~
+class TermProgress
+
+       # Max value of the progress bar (business value).
+       var max_value: Int
+
+       # Current value of the progress bar (business value).
+       var current_value: Int
+
+       # Number of columns used to display the progress bar.
+       var max_columns = 70 is writable
+
+       # Get the current percent value.
+       fun current_percentage: Int do
+               return current_value * 100 / max_value
+       end
+
+       # Display the progress bar.
+       #
+       # `metadata`  can be used to pass a small amount of data to display after
+       # the progressbar.
+       fun display(metadata: nullable String) do
+               var percent = current_percentage
+               var p = current_value * max_columns / max_value
+               printn "\r{percent}% ["
+               for i in [1..max_columns] do
+                       if i < p then
+                               printn "="
+                       else if i == p then
+                               printn ">"
+                       else
+                               printn " "
+                       end
+               end
+               printn "]"
+               if metadata != null then printn " ({metadata})"
+       end
+
+       # Update and display the progresssbar.
+       #
+       # See `display`.
+       fun update(new_current: Int, metadata: nullable String) do
+               current_value = new_current
+               display(metadata)
+       end
+end
index 439a621..af5b61b 100644 (file)
@@ -288,6 +288,21 @@ class Bytes
                length += 1
        end
 
+       # Adds the UTF-8 representation of `c` to `self`
+       #
+       #     var b = new Bytes.empty
+       #     b.add_char('A')
+       #     b.add_char('ã‚­')
+       #     assert b.hexdigest == "41E382AD"
+       fun add_char(c: Char) do
+               if persisted then regen
+               var cln = c.u8char_len
+               var ln = length
+               enlarge(ln + cln)
+               items.set_char_at(length, c)
+               length += cln
+       end
+
        #     var b = new Bytes.empty
        #     b.append([104u8, 101u8, 108u8, 108u8, 111u8])
        #     assert b.to_s == "hello"
@@ -596,6 +611,57 @@ redef class Text
                end
                return new FlatString.with_infos(outns, ln * 2, 0, ln * 2 - 1)
        end
+
+       # Return a `Bytes` instance where Nit escape sequences are transformed.
+       #
+       #     assert "B\\n\\x41\\u0103D3".unescape_to_bytes.hexdigest == "420A41F0908F93"
+       fun unescape_to_bytes: Bytes do
+               var res = new Bytes.with_capacity(self.bytelen)
+               var was_slash = false
+               var i = 0
+               while i < length do
+                       var c = chars[i]
+                       if not was_slash then
+                               if c == '\\' then
+                                       was_slash = true
+                               else
+                                       res.add_char(c)
+                               end
+                               i += 1
+                               continue
+                       end
+                       was_slash = false
+                       if c == 'n' then
+                               res.add_char('\n')
+                       else if c == 'r' then
+                               res.add_char('\r')
+                       else if c == 't' then
+                               res.add_char('\t')
+                       else if c == '0' then
+                               res.add_char('\0')
+                       else if c == 'x' or c == 'X' then
+                               var hx = substring(i + 1, 2)
+                               if hx.is_hex then
+                                       res.add(hx.to_hex.to_b)
+                               else
+                                       res.add_char(c)
+                               end
+                               i += 2
+                       else if c == 'u' or c == 'U' then
+                               var hx = substring(i + 1, 6)
+                               if hx.is_hex then
+                                       res.add_char(hx.to_hex.code_point)
+                               else
+                                       res.add_char(c)
+                               end
+                               i += 6
+                       else
+                               res.add_char(c)
+                       end
+                       i += 1
+               end
+               return res
+       end
 end
 
 redef class FlatText
@@ -606,11 +672,23 @@ redef class FlatText
 end
 
 redef class NativeString
-       # Creates a new `Bytes` object from `self` with `strlen` as length
-       fun to_bytes: Bytes do
-               var len = cstring_length
+       # Creates a new `Bytes` object from `self` with `len` as length
+       #
+       # If `len` is null, strlen will determine the length of the Bytes
+       fun to_bytes(len: nullable Int): Bytes do
+               if len == null then len = cstring_length
                return new Bytes(self, len, len)
        end
+
+       # Creates a new `Bytes` object from a copy of `self` with `len` as length
+       #
+       # If `len` is null, strlen will determine the length of the Bytes
+       fun to_bytes_with_copy(len: nullable Int): Bytes do
+               if len == null then len = cstring_length
+               var nns = new NativeString(len)
+               copy_to(nns, len, 0, 0)
+               return new Bytes(nns, len, len)
+       end
 end
 
 # Joins an array of bytes `arr` separated by `sep`
index ce89435..d196333 100644 (file)
@@ -111,11 +111,18 @@ abstract class AbstractArrayRead[E]
        #     assert b      ==  [10, 20, 2, 3, 50]
        fun copy_to(start: Int, len: Int, dest: AbstractArray[E], new_start: Int)
        do
-               # TODO native one
-               var i = len
-               while i > 0 do
-                       i -= 1
-                       dest[new_start+i] = self[start+i]
+               if start < new_start then
+                       var i = len
+                       while i > 0 do
+                               i -= 1
+                               dest[new_start+i] = self[start+i]
+                       end
+               else
+                       var i = 0
+                       while i < len do
+                               dest[new_start+i] = self[start+i]
+                               i += 1
+                       end
                end
        end
 
@@ -130,7 +137,7 @@ abstract class AbstractArrayRead[E]
                end
        end
 
-       redef fun iterator: ArrayIterator[E] do
+       redef fun iterator: IndexedIterator[E] do
                var res = _free_iterator
                if res == null then return new ArrayIterator[E](self)
                res._index = 0
@@ -220,22 +227,18 @@ abstract class AbstractArray[E]
        do
                assert not_empty: not is_empty
                var r = first
-               var i = 1
-               var l = length
-               while i < l do
-                       self[i-1] = self[i]
-                       i += 1
-               end
-               _length = l - 1
+               var l = length-1
+               copy_to(1, l, self, 0)
+               _length = l
                return r
        end
 
        redef fun unshift(item)
        do
-               var i = length - 1
-               while i >= 0 do
-                       self[i+1] = self[i]
-                       i -= 1
+               var l = length
+               if l > 0 then
+                       enlarge(l + 1)
+                       copy_to(0, l, self, 1)
                end
                self[0] = item
        end
@@ -369,6 +372,32 @@ class Array[E]
                _length = nl
        end
 
+       redef fun copy_to(start, len, dest, new_start)
+       do
+               # Fast code when source and destination are two arrays
+
+               if not dest isa Array[E] then
+                       super
+                       return
+               end
+
+               # Enlarge dest if required
+               var dest_len = new_start + len
+               if dest_len > dest.length then
+                       dest.enlarge(dest_len)
+                       dest.length = dest_len
+               end
+
+               # Get underlying native arrays
+               var items = self.items
+               if items == null then return
+               var dest_items = dest.items
+               assert dest_items != null
+
+               # Native copy
+               items.memmove(start, len, dest_items, new_start)
+       end
+
        redef fun enlarge(cap)
        do
                var c = _capacity
@@ -653,7 +682,7 @@ private class ArraySetIterator[E]
 
        redef fun item: E do return _iter.item
 
-       var iter: ArrayIterator[E]
+       var iter: Iterator[E]
 end
 
 
@@ -962,6 +991,25 @@ universal NativeArray[E]
 
        # Copy `length` items to `dest`.
        fun copy_to(dest: NativeArray[E], length: Int) is intern
+
+       # Copy `length` items to `dest` starting from `dest`.
+       fun memmove(start: Int, length: Int, dest: NativeArray[E], dest_start: Int) do
+               # TODO native one
+               if start < dest_start then
+                       var i = length
+                       while i > 0 do
+                               i -= 1
+                               dest[dest_start+i] = self[start+i]
+                       end
+               else
+                       var i = 0
+                       while i < length do
+                               dest[dest_start+i] = self[start+i]
+                               i += 1
+                       end
+               end
+       end
+
        #fun =(o: NativeArray[E]): Bool is intern
        #fun !=(o: NativeArray[E]): Bool is intern
 end
diff --git a/lib/core/collection/circular_array.nit b/lib/core/collection/circular_array.nit
new file mode 100644 (file)
index 0000000..9419853
--- /dev/null
@@ -0,0 +1,258 @@
+# This file is part of NIT (http://www.nitlanguage.org).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Efficient data structure to access both end of the sequence.
+module circular_array
+
+import array
+
+# Efficient data structure to access both end of the sequence.
+#
+# A circular array offers efficient random access,
+# efficient manipulation for both ends of the structure (push, pop, ) and
+# automatic amortized growth.
+#
+# Therefore it can be used as is or as and efficient queue (FIFO/LIFO)
+class CircularArray[E]
+       super Sequence[E]
+
+       # The low-level storage of the items.
+       #
+       # Internally, there is two main configurations
+       #
+       # One part: from `head` to `tail` (inclusive)
+       #
+       # ~~~raw
+       # ...0123...
+       #    h  t
+       # ~~~
+       #
+       # Two parts: from `head` to `capacity-1`,
+       # then from `0` to `tail` (both inclusive)
+       # Test with `head > tail`
+       #
+       # ~~~raw
+       # 345....012
+       #   t    h
+       # ~~~
+       #
+       # For consistency, *length* and *index* are used in the context of the sequence (self) and
+       # *capacity* and *offset* are used in the context of the native array.
+       #
+       # Initially the native is not allocated, the first one is done with `enlarge`
+       private var native: NativeArray[E] is noautoinit
+
+       # The offset of the `first` item in `native`
+       private var head = 0
+
+       # The offset of the `last` item in `native`
+       private var tail: Int = -1
+
+       redef var length = 0
+
+       # Transform an index into an offset.
+       #
+       # The method takes care of the initial gap and the possible wrapping.
+       #
+       # REQUIRE: `0 <= index and index < length`
+       private fun offset(index: Int): Int
+       do
+               assert index >= 0
+               var head = self._head
+               var tail = self._tail
+               var offset = head + index
+
+               if head > tail then
+                       # Two parts
+                       var capacity = native.length
+                       if offset < capacity then
+                               return offset
+                       end
+                       offset -= capacity
+               end
+
+               assert offset <= tail
+               return offset
+       end
+
+       redef fun [](index) do return native[offset(index)]
+
+       redef fun []=(index, item) do
+               var l = length
+               if index == l then
+                       push(item)
+                       return
+               end
+               native[offset(index)] = item
+       end
+
+       redef fun push(item) do
+               var l = length + 1
+               enlarge(l)
+               length = l
+
+               var native = _native
+               var cap = native.length
+               var t = tail + 1
+               if t >= cap then t -= cap
+
+               native[t] = item
+               tail = t
+       end
+
+       redef fun add_all(items) do
+               enlarge length + items.length
+               super
+       end
+
+       redef fun pop do
+               var l = length - 1
+               assert l >= 0
+               length = l
+
+               var native = _native
+               var t = tail
+               var res = native[t]
+
+               t -= 1
+               if t < 0 then t += native.length
+               tail = t
+
+               return res
+       end
+
+       redef fun unshift(item) do
+               var l = length + 1
+               enlarge(l)
+               length = l
+
+               var native = _native
+               var h = head - 1
+               if h < 0 then h += native.length
+
+               native[h] = item
+               head = h
+       end
+
+       redef fun shift do
+               var l = length - 1
+               assert l >= 0
+               length = l
+
+               var native = _native
+               var h = head
+               var res = native[h]
+
+               h += 1
+               var cap = native.length
+               if h >= cap then h -= cap
+               head = h
+
+               return res
+       end
+
+       # Ensure at least a given capacity
+       #
+       # If the current capacity is enough, then no-op.
+       fun enlarge(capacity: Int)
+       do
+               # First allocation
+               if not isset _native then
+                       var new_c = 8
+                       while new_c < capacity do new_c *= 2
+                       native = new NativeArray[E](new_c)
+                       return
+               end
+
+               # Compute more capacity
+               var c = native.length
+               if capacity <= c then return
+               var new_c = c
+               while new_c < capacity do new_c *= 2
+
+               var new_native = new NativeArray[E](new_c)
+
+               # Reallocation: just realign the parts on 0
+               if head > tail then
+                       # Two parts
+                       native.memmove(head, c-head, new_native, 0)
+                       native.memmove(0, tail+1, new_native, c-head)
+               else
+                       # One part
+                       native.memmove(head, length, new_native, 0)
+               end
+               head = 0
+               tail = length - 1
+               native = new_native
+       end
+
+       redef fun insert(item, index)
+       do
+               # Special insertion at the end (is push)
+               if index >= length then
+                       assert index == length
+                       push(item)
+                       return
+               end
+               assert index >= 0
+
+               var new_len = length + 1
+
+               # TODO be more efficient:
+               # Here, we just allocate a new native and copy everything.
+
+               # Allocate a new native array
+               var c = native.length
+               while c < new_len do c *= 2
+               var new_native = new NativeArray[E](c)
+
+               # Copy everything
+               var i = 0
+               while i < index do
+                       new_native[i] = self[i]
+                       i += 1
+               end
+               new_native[index] = item
+               var l = length
+               while i < l do
+                       new_native[i+1] = self[i]
+                       i += 1
+               end
+
+               # Use the new native array
+               length = new_len
+               head = 0
+               tail = new_len - 1
+               native = new_native
+       end
+
+       redef fun clear do
+               length = 0
+               head = 0
+               tail = -1
+       end
+
+       redef fun iterator do return new CircularArrayIterator[E](self)
+end
+
+private class CircularArrayIterator[E]
+       super IndexedIterator[E]
+
+       var array: CircularArray[E]
+
+       redef var index = 0
+       redef fun is_ok do return index < array.length
+       redef fun item do return array[index]
+       redef fun next do index += 1
+end
index 0701cc7..2475b68 100644 (file)
@@ -16,6 +16,7 @@ module collection
 import range
 import list
 import array
+import circular_array
 import sorter
 import hash_collection
 import union_find
index 890ecd9..ac4a8a1 100644 (file)
@@ -238,7 +238,7 @@ class HashMap[K, V]
                end
        end
 
-       redef fun iterator: HashMapIterator[K, V] do return new HashMapIterator[K,V](self)
+       redef fun iterator do return new HashMapIterator[K,V](self)
 
        redef fun length do return _the_length
 
index 4aa3242..4516703 100644 (file)
@@ -42,17 +42,8 @@ class List[E]
        # O(1)
        redef fun is_empty do return _head == null
 
-       # O(n)
-       redef fun length
-       do
-               var l = 0
-               var t = _head
-               while t != null do
-                       l += 1
-                       t = t.next
-               end
-               return l
-       end
+       # O(1)
+       redef var length = 0
 
        # O(n)
        redef fun has(e) do return search_node_after(e, _head) != null
@@ -103,6 +94,7 @@ class List[E]
                        node.prev = _tail
                end
                _tail = node
+               length += 1
        end
 
        # O(1)
@@ -116,6 +108,7 @@ class List[E]
                        _head.prev = node
                end
                _head = node
+               length += 1
        end
 
        # O(n)
@@ -141,6 +134,7 @@ class List[E]
                        _tail.next.prev = _tail
                end
                _tail = l._tail
+               length += l.length
                l.clear
        end
 
@@ -157,6 +151,7 @@ class List[E]
                else
                        _tail.next = null
                end
+               length -= 1
                return node.item
        end
 
@@ -171,6 +166,7 @@ class List[E]
                else
                        _head.prev = null
                end
+               length -= 1
                return node.item
        end
 
@@ -233,6 +229,7 @@ class List[E]
        # Remove the node (ie. atach prev and next)
        private fun remove_node(node: ListNode[E])
        do
+               length -= 1
                if node.prev == null then
                        _head = node.next
                        if node.next == null then
@@ -251,6 +248,7 @@ class List[E]
 
        private fun insert_before(element: E, node: ListNode[E])
        do
+               length += 1
                var nnode = new ListNode[E](element)
                var prev = node.prev
                if prev == null then
index ef8a24b..76823e2 100644 (file)
@@ -68,7 +68,7 @@ abstract class Text
        fun substring(from: Int, count: Int): SELFTYPE is abstract
 
        # Iterates on the substrings of self if any
-       fun substrings: Iterator[FlatText] is abstract
+       private fun substrings: Iterator[FlatText] is abstract
 
        # Is the current Text empty (== "")
        #
index 7e7400c..18880ec 100644 (file)
@@ -732,6 +732,12 @@ class Issue
                super
        end
 
+       # Issue id.
+       fun id: Int do return json["id"].as(Int)
+
+       # Set issue id.
+       fun id=(id: Int) do json["id"] = id
+
        # Issue title.
        fun title: String do return json["title"].as(String)
 
@@ -814,10 +820,16 @@ class Issue
                        for obj in array do
                                if not obj isa JsonObject then continue
                                var id = obj["id"].as(Int)
-                               res.add(api.load_issue_comment(repo, id).as(not null))
+                               var comment = api.load_issue_comment(repo, id)
+                               if comment == null then continue
+                               res.add(comment)
                        end
                        page += 1
-                       array = api.get("{key}/comments?page={page}").as(JsonArray)
+                       var json = api.get("{key}/comments?page={page}")
+                       if not json isa JsonArray then
+                               return res
+                       end
+                       array = json
                end
                return res
        end
index df7c8c3..543a786 100644 (file)
@@ -38,6 +38,12 @@ class GithubEvent
                self.json = json
        end
 
+       # Event ID from Github.
+       fun id: String do return json["id"].as(String)
+
+       # Set id.
+       fun id=(id: String) do json["id"] = id
+
        # Action performed by the event.
        fun action: String do return json["action"].as(String)
 
index 9cbe38e..c01d417 100644 (file)
@@ -346,6 +346,10 @@ extern class ConnectionListener `{ struct evconnlistener * `}
 
                struct hostent *hostent = gethostbyname(address);
 
+               if (!hostent) {
+                       return NULL;
+               }
+
                memset(&sin, 0, sizeof(sin));
                sin.sin_family = hostent->h_addrtype;
                sin.sin_port = htons(port);
index b9e2f6a..7907409 100644 (file)
@@ -417,7 +417,7 @@ class MarkdownProcessor
                        end
                else if c == '_' then
                        if c1 == '_' then
-                               if c0 != ' ' or c2 != ' 'then
+                               if c0 != ' ' or c2 != ' ' then
                                        return new TokenStrongUnderscore(loc, pos, c)
                                else
                                        return new TokenEmUnderscore(loc, pos, c)
index 624dc8a..78cd75d 100644 (file)
@@ -55,16 +55,11 @@ in "C header" `{
 # * [Binary JSON spec](http://bsonspec.org/)
 # * [Libbson](http://api.mongodb.org/libbson/1.1.4/)#
 private class BSON
-       super Finalizable
+       super FinalizableOnce
 
        # Native instance pointer.
        var native: NativeBSON
 
-       # Is the native instance valid?
-       #
-       # This is set to false if the `native` is destroyed.
-       var is_alive = true
-
        # Returns a new BSON object initialized from the content of `json`.
        #
        # ~~~
@@ -95,7 +90,6 @@ private class BSON
        end
 
        redef fun to_s do
-               assert is_alive
                var ns = native.to_native_string
                var res = ns.to_s_with_copy
                ns.free # manual free of gc allocated NativeString
@@ -114,16 +108,15 @@ private class BSON
        # assert json["ELS"].as(JsonArray).is_empty
        # ~~~
        fun to_json: JsonObject do
-               assert is_alive
-               return to_s.parse_json.as(JsonObject)
-       end
-
-       redef fun finalize do
-               if is_alive then
-                       native.destroy
-                       is_alive = false
+               var json = to_s.parse_json
+               if json isa JsonParseError then
+                       print json.message
+                       sys.exit 1
                end
+               return json.as(JsonObject)
        end
+
+       redef fun finalize_once do native.destroy
 end
 
 redef class JsonObject
@@ -144,26 +137,14 @@ class MongoError
 
        private var native: BSONError
 
-       # Is the native instance valid?
-       #
-       # This is set to false if the `native` is destroyed.
-       private var is_alive = true
-
        # Logical domain within a library that created the error.
-       fun domain: Int do
-               assert is_alive
-               return native.domain
-       end
+       fun domain: Int do return native.domain
 
        # Domain specific error code.
-       fun code: Int do
-               assert is_alive
-               return native.code
-       end
+       fun code: Int do return native.code
 
        # Human readable error message.
        fun message: String do
-               assert is_alive
                var ns = native.message
                var res = ns.to_s_with_copy
                ns.free
@@ -211,21 +192,14 @@ end
 # assert client.server_uri == uri
 # ~~~
 class MongoClient
-       super Finalizable
+       super FinalizableOnce
 
        # Server URI.
        var server_uri: String
 
        private var native: NativeMongoClient is noinit
 
-       # Is the native instance valid?
-       #
-       # This is set to false if the `native` is destroyed.
-       private var is_alive = true
-
-       init do
-               native = new NativeMongoClient(server_uri.to_cstring)
-       end
+       init do native = new NativeMongoClient(server_uri.to_cstring)
 
        # Gets server data.
        #
@@ -236,7 +210,6 @@ class MongoClient
        # assert client.server_status["process"] == "mongod"
        # ~~~
        fun server_status: nullable JsonObject do
-               assert is_alive
                var nbson = native.server_status
                if nbson == null then return null
                var bson = new BSON(nbson)
@@ -253,7 +226,6 @@ class MongoClient
        # assert client.database_names.has("test")
        # ~~~
        fun database_names: Array[String] do
-               assert is_alive
                var res = new Array[String]
                var nas = native.database_names
                if nas == null then return res
@@ -278,25 +250,14 @@ class MongoClient
        # var client = new MongoClient("mongodb://localhost:27017/")
        # assert client.database("test").name == "test"
        # ~~~
-       fun database(name: String): MongoDb do
-               assert is_alive
-               return new MongoDb(self, name)
-       end
+       fun database(name: String): MongoDb do return new MongoDb(self, name)
 
        # Close the connexion and destroy the instance.
        #
        # The reference should not be used beyond this point!
-       fun close do
-               assert is_alive
-               finalize
-       end
+       fun close do finalize_once
 
-       redef fun finalize do
-               if is_alive then
-                       native.destroy
-                       is_alive = false
-               end
-       end
+       redef fun finalize_once do native.destroy
 
        # Last error raised by mongoc.
        fun last_error: nullable MongoError do
@@ -328,7 +289,7 @@ end
 # first document into a collection.
 # There is no need to create a database manually.
 class MongoDb
-       super Finalizable
+       super FinalizableOnce
 
        # `MongoClient` used to load this database.
        var client: MongoClient
@@ -338,14 +299,7 @@ class MongoDb
 
        private var native: NativeMongoDb is noinit
 
-       # Is the native instance valid?
-       #
-       # This is set to false if the `native` is destroyed.
-       private var is_alive = true
-
-       init do
-               native = new NativeMongoDb(client.native, name.to_cstring)
-       end
+       init do native = new NativeMongoDb(client.native, name.to_cstring)
 
        # Lists available collection names.
        #
@@ -358,7 +312,6 @@ class MongoDb
        # assert db.collection_names.has("test")
        # ~~~
        fun collection_names: Array[String] do
-               assert is_alive
                var res = new Array[String]
                var nas = native.collection_names
                if nas == null then return res
@@ -382,7 +335,6 @@ class MongoDb
        # assert col.name == "test"
        # ~~~
        fun collection(name: String): MongoCollection do
-               assert is_alive
                return new MongoCollection(self, name)
        end
 
@@ -394,23 +346,14 @@ class MongoDb
        # assert not db.has_collection("qwerty")
        # ~~~
        fun has_collection(name: String): Bool do
-               assert is_alive
                # TODO handle error
                return native.has_collection(name.to_cstring)
        end
 
        # Drop `self`, returns false if an error occured.
-       fun drop: Bool do
-               assert is_alive
-               return native.drop
-       end
+       fun drop: Bool do return native.drop
 
-       redef fun finalize do
-               if is_alive then
-                       native.destroy
-                       is_alive = false
-               end
-       end
+       redef fun finalize_once do native.destroy
 end
 
 # A Mongo collection.
@@ -419,7 +362,7 @@ end
 # the first document.
 # There is no need to create a database manually.
 class MongoCollection
-       super Finalizable
+       super FinalizableOnce
 
        # Database that collection belongs to.
        var database: MongoDb
@@ -429,11 +372,6 @@ class MongoCollection
 
        private var native: NativeMongoCollection is noinit
 
-       # Is the native instance valid?
-       #
-       # This is set to false if the `native` is destroyed.
-       private var is_alive = true
-
        # Loads a collection.
        #
        # Call `MongoDb::collection` instead.
@@ -471,7 +409,6 @@ class MongoCollection
        # assert doc.has_key("_id")
        # ~~~
        fun insert(doc: JsonObject): Bool do
-               assert is_alive
                var res = native.insert(doc.to_bson.native)
                if res then set_id(doc)
                return res
@@ -481,7 +418,6 @@ class MongoCollection
        #
        # See `insert`.
        fun insert_all(docs: Collection[JsonObject]): Bool do
-               assert is_alive
                var res = true
                for doc in docs do res = insert(doc) and res
                return res
@@ -511,9 +447,12 @@ class MongoCollection
        # assert doc["_id"] == id
        # ~~~
        fun save(doc: JsonObject): Bool do
-               assert is_alive
-               var res = native.save(doc.to_bson.native)
+               var bson = doc.to_bson
+               var nat = bson.native
+               var res = native.save(nat)
                if res then set_id(doc)
+               assert nat != self #FIXME used to avoid GC crashes
+               assert bson != self #FIXME used to avoid GC crashes
                return res
        end
 
@@ -529,7 +468,6 @@ class MongoCollection
        # assert col.remove(sel)
        # ~~~
        fun remove(selector: JsonObject): Bool do
-               assert is_alive
                return native.remove(selector.to_bson.native)
        end
 
@@ -537,7 +475,6 @@ class MongoCollection
        #
        # See `remove`.
        fun remove_all(selector: JsonObject): Bool do
-               assert is_alive
                return native.remove_all(selector.to_bson.native)
        end
 
@@ -555,7 +492,6 @@ class MongoCollection
        # assert col.update(sel, upd)
        # ~~~
        fun update(selector: JsonObject, update: JsonObject): Bool do
-               assert is_alive
                return native.update(
                        selector.to_bson.native,
                        update.to_bson.native)
@@ -582,12 +518,15 @@ class MongoCollection
        # assert col.count(query) > 0
        # ~~~
        fun count(query: JsonObject): Int do
-               assert is_alive
                return native.count(query.to_bson.native)
        end
 
        # Finds the first document that matches `query`.
        #
+       # Params:
+       # * `skip` number of documents to skip
+       # * `limit` number of documents to return
+       #
        # Returns `null` if an error occured. See `Sys::last_mongoc_error`.
        #
        # ~~~
@@ -598,19 +537,28 @@ class MongoCollection
        # var doc = col.find(query)
        # assert doc["foo"] == 10
        # ~~~
-       fun find(query: JsonObject): nullable JsonObject do
-               assert is_alive
+       fun find(query: JsonObject, skip, limit: nullable Int): nullable JsonObject do
                var q = new NativeBSON.from_json_string(query.to_json.to_cstring)
-               var c = native.find(q)
+               var s = skip or else 0
+               var l = limit or else 0
+               var c = native.find(q, s, l)
                q.destroy
                if c == null then return null
                var cursor = new MongoCursor(c)
-               if cursor.is_ok then return cursor.item
-               return null
+               if not cursor.is_ok then
+                       return null
+               end
+               var item = cursor.item
+               assert cursor != self
+               return item
        end
 
        # Finds all the documents matching the `query`.
        #
+       # Params:
+       # * `skip` number of documents to skip
+       # * `limit` number of documents to return
+       #
        # ~~~
        # var client = new MongoClient("mongodb://localhost:27017/")
        # var col = client.database("test").collection("test")
@@ -618,13 +566,17 @@ class MongoCollection
        # query["foo"] = 10
        # assert col.find_all(query).length > 0
        # ~~~
-       fun find_all(query: JsonObject): Array[JsonObject] do
-               assert is_alive
+       fun find_all(query: JsonObject, skip, limit: nullable Int): Array[JsonObject] do
+               var s = skip or else 0
+               var l = limit or else 0
                var res = new Array[JsonObject]
-               var c = native.find(query.to_bson.native)
+               var c = native.find(query.to_bson.native, s, l)
                if c == null then return res
                var cursor = new MongoCursor(c)
-               for item in cursor do res.add item
+               while cursor.is_ok do
+                       res.add cursor.item
+                       cursor.next
+               end
                return res
        end
 
@@ -638,17 +590,13 @@ class MongoCollection
        # assert col.stats["ns"] == "test.test"
        # ~~~
        fun stats: nullable JsonObject do
-               assert is_alive
                var bson = native.stats
                if bson == null then return null
                return new JsonObject.from_bson(new BSON(bson))
        end
 
        # Drops `self`, returns false if an error occured.
-       fun drop: Bool do
-               assert is_alive
-               return native.drop
-       end
+       fun drop: Bool do return native.drop
 
        # Moves `self` to another `database`.
        #
@@ -656,7 +604,6 @@ class MongoCollection
        # this collection after the move.
        # Additional operations will occur on moved collection.
        fun move(database: MongoDb): Bool do
-               assert is_alive
                self.database = database
                return native.rename(database.name.to_cstring, name.to_cstring)
        end
@@ -667,17 +614,11 @@ class MongoCollection
        # to continue using this collection after the rename.
        # Additional operations will occur on renamed collection.
        fun rename(name: String): Bool do
-               assert is_alive
                self.name = name
                return native.rename(database.name.to_cstring, name.to_cstring)
        end
 
-       redef fun finalize do
-               if is_alive then
-                       native.destroy
-                       is_alive = false
-               end
-       end
+       redef fun finalize_once do native.destroy
 end
 
 # A MongoDB query cursor.
@@ -685,37 +626,20 @@ end
 # It wraps up the wire protocol negotation required to initiate a query and
 # retreive an unknown number of documents.
 class MongoCursor
-       super Finalizable
+       super FinalizableOnce
        super Iterator[JsonObject]
 
        private var native: NativeMongoCursor
 
-       # Is the native instance valid?
-       #
-       # This is set to false if the `native` is destroyed.
-       private var is_alive = true
-
        init do next
 
-       redef fun is_ok do
-               assert is_alive
-               return native.more
-       end
+       redef var is_ok = true
 
-       redef fun next do
-               assert is_alive
-               native.next
-       end
+       redef fun next do is_ok = native.next
 
        redef fun item do
-               assert is_alive
                return new JsonObject.from_bson(new BSON(native.current))
        end
 
-       redef fun finalize do
-               if is_alive then
-                       native.destroy
-                       is_alive = false
-               end
-       end
+       redef fun finalize_once do native.destroy
 end
index d25a9ac..fb8b305 100644 (file)
@@ -421,11 +421,11 @@ extern class NativeMongoCollection `{ mongoc_collection_t * `}
        #
        # If you would like to specify options such as a sort order,
        # the query must be placed inside of `{"$query": {}}`.
-       fun find(query: NativeBSON): nullable NativeMongoCursor import
+       fun find(query: NativeBSON, skip, limit: Int): nullable NativeMongoCursor import
                NativeMongoCursor.as nullable, set_mongoc_error `{
                bson_error_t error;
                mongoc_cursor_t *cursor;
-               cursor = mongoc_collection_find(self, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
+               cursor = mongoc_collection_find(self, MONGOC_QUERY_NONE, skip, limit, 0, query, NULL, NULL);
                if (mongoc_cursor_error(cursor, &error)) {
                        NativeMongoCollection_set_mongoc_error(self, &error);
                        return null_NativeMongoCursor();
@@ -506,7 +506,12 @@ extern class NativeMongoCursor `{ mongoc_cursor_t* `}
        # Wrapper for `mongoc_cursor_current()`.
        #
        # Fetches the cursors current document or NULL if there has been an error.
-       fun current: NativeBSON `{ return (bson_t*) mongoc_cursor_current(self); `}
+       fun current: NativeBSON `{
+               // As said in documentation, BSON objects should not be freed manually.
+               bson_t* bson = (bson_t*) mongoc_cursor_current(self);
+               // Copy BSON so we can let the GC free it automatically.
+               return bson_copy(bson);
+       `}
 
        # Wrapper for `mongoc_cursor_next()`.
        #
@@ -519,11 +524,6 @@ extern class NativeMongoCursor `{ mongoc_cursor_t* `}
                return mongoc_cursor_next(self, &doc);
        `}
 
-       # Wrapper for `mongoc_cursor_more()`.
-       #
-       # This function shall indicate if there is more data to be read from the cursor.
-       fun more: Bool `{ return mongoc_cursor_more(self); `}
-
        # Wrapper for `mongoc_cursor_destroy()`.
        #
        # This instance should not be used beyond this point!
diff --git a/lib/nitcorn/log.nit b/lib/nitcorn/log.nit
new file mode 100644 (file)
index 0000000..c0d6d52
--- /dev/null
@@ -0,0 +1,59 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Services inserting a timestamp in all prints and to log each requests
+# Also keep track of the performances of the requests
+module log
+
+import reactor
+import realtime
+import performance_analysis
+
+redef class Action
+
+       redef fun prepare_respond_and_close(request, truncated_uri, http_server) do
+               if not log_nitcorn_actions then
+                       super
+                       return
+               end
+               print """{{{class_name}}} enter:
+uri="{{{truncated_uri}}}"
+query="{{{request.query_string}}}"
+body:{{{request.body.length}}} bytes"""
+               var clock = new Clock
+               super
+               var perf = sys.perfs[class_name]
+               perf.add(clock.lapse)
+               if perf.count % perfs_print_period == 0 then print "{class_name} perfs: {perf}:"
+               print "{class_name} return: uri={truncated_uri}"
+       end
+end
+
+redef fun print(object) do
+       var timestamp = new Tm.gmtime
+       super "{timestamp.year}/{timestamp.mon}/{timestamp.mday} "+
+       "{timestamp.hour}:{timestamp.min}:{timestamp.sec}: {object}"
+end
+
+redef fun print_error(object) do
+       var timestamp = new Tm.gmtime
+       super "{timestamp.year}/{timestamp.mon}/{timestamp.mday} "+
+       "{timestamp.hour}:{timestamp.min}:{timestamp.sec}: {object}"
+end
+
+# Should the actions be logged ?
+fun log_nitcorn_actions: Bool do return false
+
+# Number of actions executed before printing the perfs
+fun perfs_print_period: Int do return 20
index 6df0ea5..67e6765 100644 (file)
@@ -492,4 +492,11 @@ class ConcurrentList[E]
                real_collection.unshift(e)
                mutex.unlock
        end
+
+       redef fun push(e)
+       do
+               mutex.lock
+               real_collection.push(e)
+               mutex.unlock
+       end
 end
diff --git a/lib/pthreads/examples/threadpool_example.nit b/lib/pthreads/examples/threadpool_example.nit
new file mode 100644 (file)
index 0000000..f7fafd7
--- /dev/null
@@ -0,0 +1,42 @@
+# This file is part of NIT (http://www.nitlanguage.org).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Simple example using threadpool
+module threadpool_example
+
+import threadpool
+
+# Task printing "hello world" on standard output
+class HWTask
+       super Task
+
+       # Sleeping time
+       var sec: Int
+
+       # id
+       var id: Int
+       redef fun main do
+               print "Hello from {id}"
+               nanosleep(sec, 0)
+               print "World from {id}"
+       end
+end
+
+var tp = new ThreadPool
+for i in 100.times do
+       var t = new HWTask(2.rand, i)
+       tp.execute(t)
+end
+
+nanosleep(20,10)
diff --git a/lib/pthreads/threadpool.nit b/lib/pthreads/threadpool.nit
new file mode 100644 (file)
index 0000000..42931d3
--- /dev/null
@@ -0,0 +1,66 @@
+# This file is part of NIT (http://www.nitlanguage.org).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Introduces a minimal ThreadPool implementation using Tasks
+module threadpool
+
+intrude import pthreads
+import concurrent_collections
+
+# A simple ThreadPool implemented with an array
+class ThreadPool
+       private var queue = new ConcurrentList[Task].wrap(new List[Task])
+       private var mutex = new Mutex
+       private var cond = new NativePthreadCond
+
+       # Number of threads used
+       var nb_threads: Int is noinit
+
+       init do
+               for i in [0..nb_threads[ do
+                       var t = new PoolThread(queue, mutex, cond)
+                       t.start
+               end
+       end
+
+       private fun set_nb_threads(nb: nullable Int) is autoinit do nb_threads = nb or else 5
+
+       # Adds a Task into the queue
+       fun execute(task: Task) do
+               queue.push(task)
+               cond.signal
+       end
+end
+
+# A Thread running in a threadpool
+private class PoolThread
+       super Thread
+
+       var queue: ConcurrentList[Task]
+       var mutex: Mutex
+       var cond : NativePthreadCond
+
+       redef fun main do
+               loop
+                       var t: nullable Task = null
+                       mutex.lock
+                       if queue.is_empty then cond.wait(mutex.native.as(not null))
+                       if not queue.is_empty then
+                               t = queue.pop
+                       end
+                       mutex.unlock
+                       if t != null then t.main
+               end
+       end
+end
index 183b4b2..cf3da76 100644 (file)
@@ -24,7 +24,7 @@ class ASTValidationVisitor
        do
                node.accept_ast_validation(self)
        end
-       private var path = new List[ANode]
+       private var path = new CircularArray[ANode]
        private var seen = new HashSet[ANode]
 end
 
index 8bcd56c..13a6e92 100644 (file)
@@ -195,9 +195,9 @@ redef class NitniCallback
        fun compile_callback_to_cpp(mmodule: MModule, mainmodule: MModule) do end
 end
 
-fun cpp_call_context: CppCallContext do return once new CppCallContext
-fun to_cpp_call_context: ToCppCallContext do return once new ToCppCallContext
-fun from_cpp_call_context: FromCppCallContext do return once new FromCppCallContext
+private fun cpp_call_context: CppCallContext do return once new CppCallContext
+private fun to_cpp_call_context: ToCppCallContext do return once new ToCppCallContext
+private fun from_cpp_call_context: FromCppCallContext do return once new FromCppCallContext
 
 redef class MExplicitCall
        redef fun compile_callback_to_cpp(mmodule, mainmodule)
index cd50d4a..afd299f 100644 (file)
@@ -1060,7 +1060,7 @@ redef class AMethPropdef
                        end
                end
 
-               if mysignature.arity > 0 then
+               if nsig != null then
                        # Check parameters visibility
                        for i in [0..mysignature.arity[ do
                                var nt = nsig.n_params[i].n_type
index 694da7b..a485468 100644 (file)
@@ -91,6 +91,8 @@ extern_code_char
        ;
 extern_code_body = extern_code_char*;
 
+id = lowercase letter*;
+
 /*****************************************************************************/
 States
 /*****************************************************************************/
@@ -203,16 +205,16 @@ at='@';
 semi=';';
 
 classid = uppercase letter*;
-id = lowercase letter*;
+id = id;
 attrid = '_' lowercase letter*;
 
 integer = (number | hex_number | bin_number | oct_number) (('u' prec) | ('i' prec) |);
 float = digit* '.' digit+ | (digit+ | digit* '.' digit+) ('E'|'e') ('+'|'-'|) digit+;
-string = '"' str_body '"' | '"' '"' '"' long_str_body lsend1 | ''' ''' ''' long_sstr_body ''' ''' ''';
-start_string = '"' str_body '{' | '"' '"' '"' long_str_body lsend2;
+string = id? '"' str_body '"' id? | id? '"' '"' '"' long_str_body lsend1 | id? ''' ''' ''' long_sstr_body ''' ''' ''' id?;
+start_string = id? '"' str_body '{' | id? '"' '"' '"' long_str_body lsend2;
 mid_string = '}' str_body '{' | '}' '}' '}' long_str_body lsend2;
-end_string = '}' str_body '"' | '}' '}' '}' long_str_body lsend1;
-char = (''' [[any - '''] - '\'] ''') | (''' '\' any ''');
+end_string = '}' str_body '"' id? | '}' '}' '}' long_str_body lsend1 id? ;
+char = id? ((''' [[any - '''] - '\'] ''') | (''' '\' any ''')) id?;
 bad_string = ('"'|'}') str_body | '"' '"' '"' long_str_body | ''' ''' ''' long_sstr_body;
 bad_char = ''' '\'? any;
 
index c641dda..b7bebb6 100644 (file)
@@ -202,199 +202,202 @@ static const int lexer_goto_row33[] = {
        123, 123, 102
 };
 static const int lexer_goto_row34[] = {
-       10,
-       48, 57, 103,
-       65, 90, 104,
-       95, 95, 105,
-       97, 97, 106,
-       98, 98, 107,
-       99, 109, 106,
-       110, 110, 108,
-       111, 114, 106,
-       115, 115, 109,
-       116, 122, 106
+       12,
+       34, 34, 103,
+       39, 39, 104,
+       48, 57, 105,
+       65, 90, 106,
+       95, 95, 107,
+       97, 97, 108,
+       98, 98, 109,
+       99, 109, 108,
+       110, 110, 110,
+       111, 114, 108,
+       115, 115, 111,
+       116, 122, 108
 };
 static const int lexer_goto_row35[] = {
        4,
-       48, 95, -35,
-       97, 113, 106,
-       114, 114, 110,
-       115, 122, 106
+       34, 95, -35,
+       97, 113, 108,
+       114, 114, 112,
+       115, 122, 108
 };
 static const int lexer_goto_row36[] = {
        6,
-       48, 95, -35,
-       97, 107, 106,
-       108, 108, 111,
-       109, 110, 106,
-       111, 111, 112,
-       112, 122, 106
+       34, 95, -35,
+       97, 107, 108,
+       108, 108, 113,
+       109, 110, 108,
+       111, 111, 114,
+       112, 122, 108
 };
 static const int lexer_goto_row37[] = {
        4,
-       48, 95, -35,
-       97, 110, 106,
-       111, 111, 113,
-       112, 122, 106
+       34, 95, -35,
+       97, 110, 108,
+       111, 111, 115,
+       112, 122, 108
 };
 static const int lexer_goto_row38[] = {
        7,
-       48, 107, -37,
-       108, 108, 114,
-       109, 109, 106,
-       110, 110, 115,
-       111, 119, 106,
-       120, 120, 116,
-       121, 122, 106
+       34, 107, -37,
+       108, 108, 116,
+       109, 109, 108,
+       110, 110, 117,
+       111, 119, 108,
+       120, 120, 118,
+       121, 122, 108
 };
 static const int lexer_goto_row39[] = {
        7,
-       48, 95, -35,
-       97, 97, 117,
-       98, 110, 106,
-       111, 111, 118,
-       112, 116, 106,
-       117, 117, 119,
-       118, 122, 106
+       34, 95, -35,
+       97, 97, 119,
+       98, 110, 108,
+       111, 111, 120,
+       112, 116, 108,
+       117, 117, 121,
+       118, 122, 108
 };
 static const int lexer_goto_row40[] = {
        2,
-       48, 95, -35,
-       97, 122, 106
+       34, 95, -35,
+       97, 122, 108
 };
 static const int lexer_goto_row41[] = {
        9,
-       48, 95, -35,
-       97, 101, 106,
-       102, 102, 120,
-       103, 108, 106,
-       109, 109, 121,
-       110, 110, 122,
-       111, 114, 106,
-       115, 115, 123,
-       116, 122, 106
+       34, 95, -35,
+       97, 101, 108,
+       102, 102, 122,
+       103, 108, 108,
+       109, 109, 123,
+       110, 110, 124,
+       111, 114, 108,
+       115, 115, 125,
+       116, 122, 108
 };
 static const int lexer_goto_row42[] = {
        5,
-       48, 95, -35,
-       97, 97, 124,
-       98, 110, 106,
-       111, 111, 125,
-       112, 122, 106
+       34, 95, -35,
+       97, 97, 126,
+       98, 110, 108,
+       111, 111, 127,
+       112, 122, 108
 };
 static const int lexer_goto_row43[] = {
        3,
-       48, 110, -38,
-       111, 111, 126,
-       112, 122, 106
+       34, 110, -38,
+       111, 111, 128,
+       112, 122, 108
 };
 static const int lexer_goto_row44[] = {
        8,
-       48, 95, -35,
-       97, 100, 106,
-       101, 101, 127,
-       102, 110, 106,
-       111, 111, 128,
-       112, 116, 106,
-       117, 117, 129,
-       118, 122, 106
+       34, 95, -35,
+       97, 100, 108,
+       101, 101, 129,
+       102, 110, 108,
+       111, 111, 130,
+       112, 116, 108,
+       117, 117, 131,
+       118, 122, 108
 };
 static const int lexer_goto_row45[] = {
        6,
-       48, 95, -35,
-       97, 109, 106,
-       110, 110, 130,
-       111, 113, 106,
-       114, 114, 131,
-       115, 122, 106
+       34, 95, -35,
+       97, 109, 108,
+       110, 110, 132,
+       111, 113, 108,
+       114, 114, 133,
+       115, 122, 108
 };
 static const int lexer_goto_row46[] = {
        7,
-       48, 95, -35,
-       97, 97, 132,
-       98, 113, 106,
-       114, 114, 133,
-       115, 116, 106,
-       117, 117, 134,
-       118, 122, 106
+       34, 95, -35,
+       97, 97, 134,
+       98, 113, 108,
+       114, 114, 135,
+       115, 116, 108,
+       117, 117, 136,
+       118, 122, 108
 };
 static const int lexer_goto_row47[] = {
        3,
-       48, 100, -45,
-       101, 101, 135,
-       102, 122, 106
+       34, 100, -45,
+       101, 101, 137,
+       102, 122, 108
 };
 static const int lexer_goto_row48[] = {
        5,
-       48, 100, -45,
-       101, 101, 136,
-       102, 116, 106,
-       117, 117, 137,
-       118, 122, 106
+       34, 100, -45,
+       101, 101, 138,
+       102, 116, 108,
+       117, 117, 139,
+       118, 122, 108
 };
 static const int lexer_goto_row49[] = {
        8,
-       48, 95, -35,
-       97, 103, 106,
-       104, 104, 138,
-       105, 113, 106,
-       114, 114, 139,
-       115, 120, 106,
-       121, 121, 140,
-       122, 122, 106
+       34, 95, -35,
+       97, 103, 108,
+       104, 104, 140,
+       105, 113, 108,
+       114, 114, 141,
+       115, 120, 108,
+       121, 121, 142,
+       122, 122, 108
 };
 static const int lexer_goto_row50[] = {
        3,
-       48, 109, -46,
-       110, 110, 141,
-       111, 122, 106
+       34, 109, -46,
+       110, 110, 143,
+       111, 122, 108
 };
 static const int lexer_goto_row51[] = {
        3,
-       48, 95, -35,
-       97, 97, 142,
-       98, 122, 106
+       34, 95, -35,
+       97, 97, 144,
+       98, 122, 108
 };
 static const int lexer_goto_row52[] = {
        4,
-       48, 103, -50,
-       104, 104, 143,
-       105, 105, 144,
-       106, 122, 106
+       34, 103, -50,
+       104, 104, 145,
+       105, 105, 146,
+       106, 122, 108
 };
 static const int lexer_goto_row53[] = {
        1,
-       61, 61, 145
+       61, 61, 147
 };
 static const int lexer_goto_row54[] = {
        11,
-       0, 9, 146,
-       11, 12, 146,
-       14, 33, 146,
-       34, 34, 147,
-       35, 91, 146,
-       92, 92, 148,
-       93, 122, 146,
-       123, 123, 149,
-       124, 124, 146,
-       125, 125, 150,
-       126, 255, 146
+       0, 9, 148,
+       11, 12, 148,
+       14, 33, 148,
+       34, 34, 149,
+       35, 91, 148,
+       92, 92, 150,
+       93, 122, 148,
+       123, 123, 151,
+       124, 124, 148,
+       125, 125, 152,
+       126, 255, 148
 };
 static const int lexer_goto_row58[] = {
        3,
        0, 33, -8,
-       34, 34, 151,
+       34, 34, 153,
        35, 255, -8
 };
 static const int lexer_goto_row59[] = {
-       1,
-       34, 34, 152
+       2,
+       34, 34, 154,
+       97, 122, 155
 };
 static const int lexer_goto_row60[] = {
        3,
-       0, 9, 153,
-       11, 12, 153,
-       14, 255, 153
+       0, 9, 156,
+       11, 12, 156,
+       14, 255, 156
 };
 static const int lexer_goto_row62[] = {
        1,
@@ -402,29 +405,29 @@ static const int lexer_goto_row62[] = {
 };
 static const int lexer_goto_row64[] = {
        1,
-       10, 10, 154
+       10, 10, 157
 };
 static const int lexer_goto_row67[] = {
        1,
-       39, 39, 155
+       39, 39, 158
 };
 static const int lexer_goto_row68[] = {
        1,
-       39, 39, 156
+       39, 39, 159
 };
 static const int lexer_goto_row69[] = {
        3,
-       0, 9, 157,
-       11, 12, 157,
-       14, 255, 157
+       0, 9, 160,
+       11, 12, 160,
+       14, 255, 160
 };
 static const int lexer_goto_row70[] = {
        1,
-       61, 61, 158
+       61, 61, 161
 };
 static const int lexer_goto_row74[] = {
        1,
-       46, 46, 159
+       46, 46, 162
 };
 static const int lexer_goto_row75[] = {
        3,
@@ -442,31 +445,31 @@ static const int lexer_goto_row78[] = {
 };
 static const int lexer_goto_row79[] = {
        3,
-       48, 48, 160,
-       49, 49, 161,
-       95, 95, 162
+       48, 48, 163,
+       49, 49, 164,
+       95, 95, 165
 };
 static const int lexer_goto_row80[] = {
        3,
-       43, 43, 163,
-       45, 45, 164,
-       48, 57, 165
+       43, 43, 166,
+       45, 45, 167,
+       48, 57, 168
 };
 static const int lexer_goto_row81[] = {
        2,
-       48, 55, 166,
-       95, 95, 167
+       48, 55, 169,
+       95, 95, 170
 };
 static const int lexer_goto_row82[] = {
        4,
-       48, 57, 168,
-       65, 70, 169,
-       95, 95, 170,
-       97, 102, 171
+       48, 57, 171,
+       65, 70, 172,
+       95, 95, 173,
+       97, 102, 174
 };
 static const int lexer_goto_row83[] = {
        3,
-       48, 57, 172,
+       48, 57, 175,
        95, 95, 82,
        105, 117, -22
 };
@@ -480,9 +483,9 @@ static const int lexer_goto_row85[] = {
 };
 static const int lexer_goto_row86[] = {
        3,
-       49, 49, 173,
-       51, 51, 174,
-       56, 56, 175
+       49, 49, 176,
+       51, 51, 177,
+       56, 56, 178
 };
 static const int lexer_goto_row87[] = {
        1,
@@ -490,9 +493,9 @@ static const int lexer_goto_row87[] = {
 };
 static const int lexer_goto_row88[] = {
        3,
-       49, 49, 176,
-       51, 51, 177,
-       56, 56, 178
+       49, 49, 179,
+       51, 51, 180,
+       56, 56, 181
 };
 static const int lexer_goto_row89[] = {
        1,
@@ -500,15 +503,15 @@ static const int lexer_goto_row89[] = {
 };
 static const int lexer_goto_row91[] = {
        1,
-       61, 61, 179
+       61, 61, 182
 };
 static const int lexer_goto_row92[] = {
        1,
-       62, 62, 180
+       62, 62, 183
 };
 static const int lexer_goto_row95[] = {
        1,
-       61, 61, 181
+       61, 61, 184
 };
 static const int lexer_goto_row96[] = {
        1,
@@ -528,418 +531,447 @@ static const int lexer_goto_row99[] = {
 };
 static const int lexer_goto_row101[] = {
        1,
-       100, 100, 182
+       100, 100, 185
 };
 static const int lexer_goto_row102[] = {
        4,
-       48, 57, 183,
-       65, 90, 184,
-       95, 95, 185,
-       97, 122, 186
+       48, 57, 186,
+       65, 90, 187,
+       95, 95, 188,
+       97, 122, 189
 };
 static const int lexer_goto_row103[] = {
        5,
-       0, 91, 187,
-       92, 92, 188,
-       93, 95, 187,
-       96, 96, 189,
-       97, 255, 187
+       0, 91, 190,
+       92, 92, 191,
+       93, 95, 190,
+       96, 96, 192,
+       97, 255, 190
 };
 static const int lexer_goto_row104[] = {
-       1,
-       48, 122, -41
+       9,
+       0, 9, 193,
+       11, 12, 193,
+       14, 33, 193,
+       34, 34, 194,
+       35, 91, 193,
+       92, 92, 195,
+       93, 122, 193,
+       123, 123, 60,
+       124, 255, 193
 };
 static const int lexer_goto_row105[] = {
-       1,
-       48, 122, -41
+       7,
+       0, 9, 196,
+       11, 12, 196,
+       14, 38, 196,
+       39, 39, 197,
+       40, 91, 196,
+       92, 92, 198,
+       93, 255, 196
 };
 static const int lexer_goto_row106[] = {
        1,
-       48, 122, -41
+       34, 122, -41
 };
 static const int lexer_goto_row107[] = {
        1,
-       48, 122, -41
+       34, 122, -41
 };
 static const int lexer_goto_row108[] = {
-       5,
-       48, 110, -38,
-       111, 111, 190,
-       112, 114, 106,
-       115, 115, 191,
-       116, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row109[] = {
-       4,
-       48, 95, -35,
-       97, 99, 106,
-       100, 100, 192,
-       101, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row110[] = {
-       4,
-       48, 95, -35,
-       97, 114, 106,
-       115, 115, 193,
-       116, 122, 106
+       5,
+       34, 110, -38,
+       111, 111, 199,
+       112, 114, 108,
+       115, 115, 200,
+       116, 122, 108
 };
 static const int lexer_goto_row111[] = {
-       3,
-       48, 100, -45,
-       101, 101, 194,
-       102, 122, 106
+       4,
+       34, 95, -35,
+       97, 99, 108,
+       100, 100, 201,
+       101, 122, 108
 };
 static const int lexer_goto_row112[] = {
-       3,
-       48, 95, -35,
-       97, 97, 195,
-       98, 122, 106
+       4,
+       34, 95, -35,
+       97, 114, 108,
+       115, 115, 202,
+       116, 122, 108
 };
 static const int lexer_goto_row113[] = {
        3,
-       48, 109, -46,
-       110, 110, 196,
-       111, 122, 106
+       34, 100, -45,
+       101, 101, 203,
+       102, 122, 108
 };
 static const int lexer_goto_row114[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 95, -35,
+       97, 97, 204,
+       98, 122, 108
 };
 static const int lexer_goto_row115[] = {
        3,
-       48, 114, -111,
-       115, 115, 197,
-       116, 122, 106
+       34, 109, -46,
+       110, 110, 205,
+       111, 122, 108
 };
 static const int lexer_goto_row116[] = {
-       5,
-       48, 99, -110,
-       100, 100, 198,
-       101, 116, 106,
-       117, 117, 199,
-       118, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row117[] = {
-       4,
-       48, 95, -35,
-       97, 115, 106,
-       116, 116, 200,
-       117, 122, 106
+       3,
+       34, 114, -113,
+       115, 115, 206,
+       116, 122, 108
 };
 static const int lexer_goto_row118[] = {
-       3,
-       48, 107, -37,
-       108, 108, 201,
-       109, 122, 106
+       5,
+       34, 99, -112,
+       100, 100, 207,
+       101, 116, 108,
+       117, 117, 208,
+       118, 122, 108
 };
 static const int lexer_goto_row119[] = {
-       3,
-       48, 113, -36,
-       114, 114, 202,
-       115, 122, 106
+       4,
+       34, 95, -35,
+       97, 115, 108,
+       116, 116, 209,
+       117, 122, 108
 };
 static const int lexer_goto_row120[] = {
        3,
-       48, 109, -46,
-       110, 110, 203,
-       111, 122, 106
+       34, 107, -37,
+       108, 108, 210,
+       109, 122, 108
 };
 static const int lexer_goto_row121[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 113, -36,
+       114, 114, 211,
+       115, 122, 108
 };
 static const int lexer_goto_row122[] = {
-       4,
-       48, 95, -35,
-       97, 111, 106,
-       112, 112, 204,
-       113, 122, 106
+       3,
+       34, 109, -46,
+       110, 110, 212,
+       111, 122, 108
 };
 static const int lexer_goto_row123[] = {
-       6,
-       48, 95, -35,
-       97, 104, 106,
-       105, 105, 205,
-       106, 115, 106,
-       116, 116, 206,
-       117, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row124[] = {
-       5,
-       48, 95, -35,
-       97, 97, 207,
-       98, 114, 106,
-       115, 115, 208,
-       116, 122, 106
+       4,
+       34, 95, -35,
+       97, 111, 108,
+       112, 112, 213,
+       113, 122, 108
 };
 static const int lexer_goto_row125[] = {
-       3,
-       48, 97, -35,
-       98, 98, 209,
-       99, 122, 106
+       6,
+       34, 95, -35,
+       97, 104, 108,
+       105, 105, 214,
+       106, 115, 108,
+       116, 116, 215,
+       117, 122, 108
 };
 static const int lexer_goto_row126[] = {
-       3,
-       48, 110, -38,
-       111, 111, 210,
-       112, 122, 106
+       5,
+       34, 95, -35,
+       97, 97, 216,
+       98, 114, 108,
+       115, 115, 217,
+       116, 122, 108
 };
 static const int lexer_goto_row127[] = {
        3,
-       48, 99, -110,
-       100, 100, 211,
-       101, 122, 106
+       34, 97, -35,
+       98, 98, 218,
+       99, 122, 108
 };
 static const int lexer_goto_row128[] = {
-       4,
-       48, 95, -35,
-       97, 118, 106,
-       119, 119, 212,
-       120, 122, 106
+       3,
+       34, 110, -38,
+       111, 111, 219,
+       112, 122, 108
 };
 static const int lexer_goto_row129[] = {
        3,
-       48, 115, -118,
-       116, 116, 213,
-       117, 122, 106
+       34, 99, -112,
+       100, 100, 220,
+       101, 122, 108
 };
 static const int lexer_goto_row130[] = {
-       3,
-       48, 107, -37,
-       108, 108, 214,
-       109, 122, 106
+       4,
+       34, 95, -35,
+       97, 118, 108,
+       119, 119, 221,
+       120, 122, 108
 };
 static const int lexer_goto_row131[] = {
-       4,
-       48, 95, -35,
-       97, 98, 106,
-       99, 99, 215,
-       100, 122, 106
+       3,
+       34, 115, -120,
+       116, 116, 222,
+       117, 122, 108
 };
 static const int lexer_goto_row132[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 107, -37,
+       108, 108, 223,
+       109, 122, 108
 };
 static const int lexer_goto_row133[] = {
-       3,
-       48, 98, -132,
-       99, 99, 216,
-       100, 122, 106
+       4,
+       34, 95, -35,
+       97, 98, 108,
+       99, 99, 224,
+       100, 122, 108
 };
 static const int lexer_goto_row134[] = {
-       5,
-       48, 104, -124,
-       105, 105, 217,
-       106, 110, 106,
-       111, 111, 218,
-       112, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row135[] = {
        3,
-       48, 97, -35,
-       98, 98, 219,
-       99, 122, 106
+       34, 98, -134,
+       99, 99, 225,
+       100, 122, 108
 };
 static const int lexer_goto_row136[] = {
        5,
-       48, 99, -110,
-       100, 100, 220,
-       101, 115, 106,
-       116, 116, 221,
-       117, 122, 106
+       34, 104, -126,
+       105, 105, 226,
+       106, 110, 108,
+       111, 111, 227,
+       112, 122, 108
 };
 static const int lexer_goto_row137[] = {
        3,
-       48, 107, -37,
-       108, 108, 222,
-       109, 122, 106
+       34, 97, -35,
+       98, 98, 228,
+       99, 122, 108
 };
 static const int lexer_goto_row138[] = {
-       3,
-       48, 111, -123,
-       112, 112, 223,
-       113, 122, 106
+       5,
+       34, 99, -112,
+       100, 100, 229,
+       101, 115, 108,
+       116, 116, 230,
+       117, 122, 108
 };
 static const int lexer_goto_row139[] = {
        3,
-       48, 100, -45,
-       101, 101, 224,
-       102, 122, 106
+       34, 107, -37,
+       108, 108, 231,
+       109, 122, 108
 };
 static const int lexer_goto_row140[] = {
-       4,
-       48, 95, -35,
-       97, 116, 106,
-       117, 117, 225,
-       118, 122, 106
+       3,
+       34, 111, -125,
+       112, 112, 232,
+       113, 122, 108
 };
 static const int lexer_goto_row141[] = {
        3,
-       48, 111, -123,
-       112, 112, 226,
-       113, 122, 106
+       34, 100, -45,
+       101, 101, 233,
+       102, 122, 108
 };
 static const int lexer_goto_row142[] = {
-       3,
-       48, 104, -124,
-       105, 105, 227,
-       106, 122, 106
+       4,
+       34, 95, -35,
+       97, 116, 108,
+       117, 117, 234,
+       118, 122, 108
 };
 static const int lexer_goto_row143[] = {
        3,
-       48, 113, -36,
-       114, 114, 228,
-       115, 122, 106
+       34, 111, -125,
+       112, 112, 235,
+       113, 122, 108
 };
 static const int lexer_goto_row144[] = {
        3,
-       48, 104, -124,
-       105, 105, 229,
-       106, 122, 106
+       34, 104, -126,
+       105, 105, 236,
+       106, 122, 108
 };
 static const int lexer_goto_row145[] = {
        3,
-       48, 115, -118,
-       116, 116, 230,
-       117, 122, 106
+       34, 113, -36,
+       114, 114, 237,
+       115, 122, 108
+};
+static const int lexer_goto_row146[] = {
+       3,
+       34, 104, -126,
+       105, 105, 238,
+       106, 122, 108
 };
 static const int lexer_goto_row147[] = {
+       3,
+       34, 115, -120,
+       116, 116, 239,
+       117, 122, 108
+};
+static const int lexer_goto_row149[] = {
        2,
        0, 123, -55,
-       124, 255, 146
+       124, 255, 148
 };
-static const int lexer_goto_row149[] = {
-       3,
-       0, 9, 231,
-       11, 12, 231,
-       14, 255, 231
+static const int lexer_goto_row150[] = {
+       1,
+       97, 122, 240
 };
 static const int lexer_goto_row151[] = {
        3,
-       0, 124, -55,
-       125, 125, 232,
-       126, 255, 146
+       0, 9, 241,
+       11, 12, 241,
+       14, 255, 241
 };
 static const int lexer_goto_row153[] = {
-       11,
-       0, 9, 233,
-       10, 10, 234,
-       11, 12, 233,
-       13, 13, 235,
-       14, 33, 233,
-       34, 34, 236,
-       35, 91, 233,
-       92, 92, 237,
-       93, 122, 233,
-       123, 123, 238,
-       124, 255, 233
+       3,
+       0, 124, -55,
+       125, 125, 242,
+       126, 255, 148
 };
 static const int lexer_goto_row154[] = {
        1,
-       0, 255, -59
+       97, 122, 155
 };
-static const int lexer_goto_row157[] = {
-       9,
-       0, 9, 239,
-       10, 10, 240,
-       11, 12, 239,
-       13, 13, 241,
-       14, 38, 239,
-       39, 39, 242,
-       40, 91, 239,
-       92, 92, 243,
-       93, 255, 239
+static const int lexer_goto_row155[] = {
+       11,
+       0, 9, 243,
+       10, 10, 244,
+       11, 12, 243,
+       13, 13, 245,
+       14, 33, 243,
+       34, 34, 246,
+       35, 91, 243,
+       92, 92, 247,
+       93, 122, 243,
+       123, 123, 248,
+       124, 255, 243
+};
+static const int lexer_goto_row156[] = {
+       4,
+       48, 57, 249,
+       65, 90, 250,
+       95, 95, 251,
+       97, 122, 252
 };
-static const int lexer_goto_row158[] = {
+static const int lexer_goto_row157[] = {
        1,
-       39, 39, 244
-};
-static const int lexer_goto_row161[] = {
-       2,
-       48, 95, -80,
-       105, 117, -22
+       0, 255, -59
 };
-static const int lexer_goto_row162[] = {
+static const int lexer_goto_row159[] = {
        1,
-       48, 117, -162
+       97, 122, 253
+};
+static const int lexer_goto_row160[] = {
+       9,
+       0, 9, 254,
+       10, 10, 255,
+       11, 12, 254,
+       13, 13, 256,
+       14, 38, 254,
+       39, 39, 257,
+       40, 91, 254,
+       92, 92, 258,
+       93, 255, 254
 };
-static const int lexer_goto_row163[] = {
+static const int lexer_goto_row161[] = {
        1,
-       48, 117, -162
+       39, 39, 259
 };
 static const int lexer_goto_row164[] = {
-       1,
-       48, 57, 165
+       2,
+       48, 95, -80,
+       105, 117, -22
 };
 static const int lexer_goto_row165[] = {
        1,
-       48, 57, 165
+       48, 117, -165
 };
 static const int lexer_goto_row166[] = {
        1,
-       48, 57, 165
+       48, 117, -165
 };
 static const int lexer_goto_row167[] = {
-       2,
-       48, 95, -82,
-       105, 117, -22
+       1,
+       48, 57, 168
 };
 static const int lexer_goto_row168[] = {
        1,
-       48, 117, -168
+       48, 57, 168
 };
 static const int lexer_goto_row169[] = {
-       2,
-       48, 102, -83,
-       105, 117, -22
+       1,
+       48, 57, 168
 };
 static const int lexer_goto_row170[] = {
-       1,
-       48, 117, -170
+       2,
+       48, 95, -82,
+       105, 117, -22
 };
 static const int lexer_goto_row171[] = {
        1,
-       48, 117, -170
+       48, 117, -171
 };
 static const int lexer_goto_row172[] = {
-       1,
-       48, 117, -170
+       2,
+       48, 102, -83,
+       105, 117, -22
 };
 static const int lexer_goto_row173[] = {
        1,
-       48, 117, -84
+       48, 117, -173
 };
 static const int lexer_goto_row174[] = {
        1,
-       54, 54, 245
+       48, 117, -173
 };
 static const int lexer_goto_row175[] = {
        1,
-       50, 50, 246
+       48, 117, -173
 };
-static const int lexer_goto_row177[] = {
+static const int lexer_goto_row176[] = {
        1,
-       54, 54, 247
+       48, 117, -84
 };
-static const int lexer_goto_row178[] = {
+static const int lexer_goto_row177[] = {
        1,
-       50, 50, 248
+       54, 54, 260
 };
-static const int lexer_goto_row183[] = {
+static const int lexer_goto_row178[] = {
        1,
-       101, 101, 249
+       50, 50, 261
 };
-static const int lexer_goto_row184[] = {
+static const int lexer_goto_row180[] = {
        1,
-       48, 122, -103
+       54, 54, 262
 };
-static const int lexer_goto_row185[] = {
+static const int lexer_goto_row181[] = {
        1,
-       48, 122, -103
+       50, 50, 263
 };
 static const int lexer_goto_row186[] = {
        1,
-       48, 122, -103
+       101, 101, 264
 };
 static const int lexer_goto_row187[] = {
        1,
@@ -947,1095 +979,1484 @@ static const int lexer_goto_row187[] = {
 };
 static const int lexer_goto_row188[] = {
        1,
-       0, 255, -104
+       48, 122, -103
 };
 static const int lexer_goto_row189[] = {
        1,
-       0, 255, 250
+       48, 122, -103
 };
 static const int lexer_goto_row190[] = {
-       3,
-       0, 124, 251,
-       125, 125, 252,
-       126, 255, 251
+       1,
+       48, 122, -103
 };
 static const int lexer_goto_row191[] = {
-       3,
-       48, 113, -36,
-       114, 114, 253,
-       115, 122, 106
+       1,
+       0, 255, -104
 };
 static const int lexer_goto_row192[] = {
-       3,
-       48, 115, -118,
-       116, 116, 254,
-       117, 122, 106
+       1,
+       0, 255, 265
 };
 static const int lexer_goto_row193[] = {
-       1,
-       48, 122, -41
+       3,
+       0, 124, 266,
+       125, 125, 267,
+       126, 255, 266
 };
 static const int lexer_goto_row194[] = {
        3,
-       48, 100, -45,
-       101, 101, 255,
-       102, 122, 106
+       0, 33, -105,
+       34, 34, 153,
+       35, 255, -105
 };
 static const int lexer_goto_row195[] = {
-       3,
-       48, 95, -35,
-       97, 97, 256,
-       98, 122, 106
+       2,
+       34, 34, 268,
+       97, 122, 155
 };
 static const int lexer_goto_row196[] = {
        3,
-       48, 114, -111,
-       115, 115, 257,
-       116, 122, 106
+       0, 9, 269,
+       11, 12, 269,
+       14, 255, 269
 };
 static const int lexer_goto_row197[] = {
-       3,
-       48, 115, -118,
-       116, 116, 258,
-       117, 122, 106
+       1,
+       39, 39, 158
 };
 static const int lexer_goto_row198[] = {
-       3,
-       48, 100, -45,
-       101, 101, 259,
-       102, 122, 106
+       1,
+       39, 39, 270
 };
 static const int lexer_goto_row199[] = {
-       1,
-       48, 122, -41
+       3,
+       0, 9, 271,
+       11, 12, 271,
+       14, 255, 271
 };
 static const int lexer_goto_row200[] = {
-       4,
-       48, 95, -35,
-       97, 108, 106,
-       109, 109, 260,
-       110, 122, 106
+       3,
+       34, 113, -36,
+       114, 114, 272,
+       115, 122, 108
 };
 static const int lexer_goto_row201[] = {
        3,
-       48, 100, -45,
-       101, 101, 261,
-       102, 122, 106
+       34, 115, -120,
+       116, 116, 273,
+       117, 122, 108
 };
 static const int lexer_goto_row202[] = {
-       3,
-       48, 114, -111,
-       115, 115, 262,
-       116, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row203[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 100, -45,
+       101, 101, 274,
+       102, 122, 108
 };
 static const int lexer_goto_row204[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 95, -35,
+       97, 97, 275,
+       98, 122, 108
 };
 static const int lexer_goto_row205[] = {
-       5,
-       48, 107, -37,
-       108, 108, 263,
-       109, 110, 106,
-       111, 111, 264,
-       112, 122, 106
+       3,
+       34, 114, -113,
+       115, 115, 276,
+       116, 122, 108
 };
 static const int lexer_goto_row206[] = {
        3,
-       48, 115, -118,
-       116, 116, 265,
-       117, 122, 106
+       34, 115, -120,
+       116, 116, 277,
+       117, 122, 108
 };
 static const int lexer_goto_row207[] = {
-       5,
-       48, 100, -45,
-       101, 101, 266,
-       102, 113, 106,
-       114, 114, 267,
-       115, 122, 106
+       3,
+       34, 100, -45,
+       101, 101, 278,
+       102, 122, 108
 };
 static const int lexer_goto_row208[] = {
        1,
-       48, 122, -41
+       34, 122, -41
 };
 static const int lexer_goto_row209[] = {
-       3,
-       48, 100, -45,
-       101, 101, 268,
-       102, 122, 106
+       4,
+       34, 95, -35,
+       97, 108, 108,
+       109, 109, 279,
+       110, 122, 108
 };
 static const int lexer_goto_row210[] = {
        3,
-       48, 100, -45,
-       101, 101, 269,
-       102, 122, 106
+       34, 100, -45,
+       101, 101, 280,
+       102, 122, 108
 };
 static const int lexer_goto_row211[] = {
        3,
-       48, 111, -123,
-       112, 112, 270,
-       113, 122, 106
+       34, 114, -113,
+       115, 115, 281,
+       116, 122, 108
 };
 static const int lexer_goto_row212[] = {
-       3,
-       48, 116, -141,
-       117, 117, 271,
-       118, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row213[] = {
        1,
-       48, 122, -41
+       34, 122, -41
 };
 static const int lexer_goto_row214[] = {
-       1,
-       48, 122, -41
+       5,
+       34, 107, -37,
+       108, 108, 282,
+       109, 110, 108,
+       111, 111, 283,
+       112, 122, 108
 };
 static const int lexer_goto_row215[] = {
        3,
-       48, 107, -37,
-       108, 108, 272,
-       109, 122, 106
+       34, 115, -120,
+       116, 116, 284,
+       117, 122, 108
 };
 static const int lexer_goto_row216[] = {
-       3,
-       48, 100, -45,
-       101, 101, 273,
-       102, 122, 106
+       5,
+       34, 100, -45,
+       101, 101, 285,
+       102, 113, 108,
+       114, 114, 286,
+       115, 122, 108
 };
 static const int lexer_goto_row217[] = {
-       4,
-       48, 95, -35,
-       97, 106, 106,
-       107, 107, 274,
-       108, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row218[] = {
-       4,
-       48, 95, -35,
-       97, 117, 106,
-       118, 118, 275,
-       119, 122, 106
+       3,
+       34, 100, -45,
+       101, 101, 287,
+       102, 122, 108
 };
 static const int lexer_goto_row219[] = {
        3,
-       48, 115, -118,
-       116, 116, 276,
-       117, 122, 106
+       34, 100, -45,
+       101, 101, 288,
+       102, 122, 108
 };
 static const int lexer_goto_row220[] = {
        3,
-       48, 107, -37,
-       108, 108, 277,
-       109, 122, 106
+       34, 111, -125,
+       112, 112, 289,
+       113, 122, 108
 };
 static const int lexer_goto_row221[] = {
        3,
-       48, 100, -45,
-       101, 101, 278,
-       102, 122, 106
+       34, 116, -143,
+       117, 117, 290,
+       118, 122, 108
 };
 static const int lexer_goto_row222[] = {
-       3,
-       48, 116, -141,
-       117, 117, 279,
-       118, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row223[] = {
-       3,
-       48, 101, -42,
-       102, 102, 280,
-       103, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row224[] = {
        3,
-       48, 100, -45,
-       101, 101, 281,
-       102, 122, 106
+       34, 107, -37,
+       108, 108, 291,
+       109, 122, 108
 };
 static const int lexer_goto_row225[] = {
        3,
-       48, 109, -46,
-       110, 110, 282,
-       111, 122, 106
+       34, 100, -45,
+       101, 101, 292,
+       102, 122, 108
 };
 static const int lexer_goto_row226[] = {
-       3,
-       48, 100, -45,
-       101, 101, 283,
-       102, 122, 106
+       4,
+       34, 95, -35,
+       97, 106, 108,
+       107, 107, 293,
+       108, 122, 108
 };
 static const int lexer_goto_row227[] = {
-       3,
-       48, 100, -45,
-       101, 101, 284,
-       102, 122, 106
+       4,
+       34, 95, -35,
+       97, 117, 108,
+       118, 118, 294,
+       119, 122, 108
 };
 static const int lexer_goto_row228[] = {
        3,
-       48, 117, -219,
-       118, 118, 285,
-       119, 122, 106
+       34, 115, -120,
+       116, 116, 295,
+       117, 122, 108
 };
 static const int lexer_goto_row229[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 107, -37,
+       108, 108, 296,
+       109, 122, 108
 };
 static const int lexer_goto_row230[] = {
        3,
-       48, 107, -37,
-       108, 108, 286,
-       109, 122, 106
+       34, 100, -45,
+       101, 101, 297,
+       102, 122, 108
 };
 static const int lexer_goto_row231[] = {
        3,
-       48, 103, -50,
-       104, 104, 287,
-       105, 122, 106
+       34, 116, -143,
+       117, 117, 298,
+       118, 122, 108
 };
 static const int lexer_goto_row232[] = {
-       1,
-       0, 255, -148
+       3,
+       34, 101, -42,
+       102, 102, 299,
+       103, 122, 108
 };
 static const int lexer_goto_row233[] = {
-       11,
-       0, 9, 288,
-       10, 10, 289,
-       11, 12, 288,
-       13, 13, 290,
-       14, 33, 288,
-       34, 34, 291,
-       35, 91, 288,
-       92, 92, 292,
-       93, 122, 288,
-       123, 123, 293,
-       124, 255, 288
+       3,
+       34, 100, -45,
+       101, 101, 300,
+       102, 122, 108
 };
 static const int lexer_goto_row234[] = {
-       1,
-       0, 255, -154
+       3,
+       34, 109, -46,
+       110, 110, 301,
+       111, 122, 108
 };
 static const int lexer_goto_row235[] = {
-       1,
-       0, 255, -154
+       3,
+       34, 100, -45,
+       101, 101, 302,
+       102, 122, 108
 };
 static const int lexer_goto_row236[] = {
-       1,
-       0, 255, -154
+       3,
+       34, 100, -45,
+       101, 101, 303,
+       102, 122, 108
 };
 static const int lexer_goto_row237[] = {
-       5,
-       0, 33, -154,
-       34, 34, 294,
-       35, 122, -154,
-       123, 123, 295,
-       124, 255, 233
+       3,
+       34, 117, -228,
+       118, 118, 304,
+       119, 122, 108
 };
 static const int lexer_goto_row238[] = {
-       3,
-       0, 9, 296,
-       11, 12, 296,
-       14, 255, 296
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row239[] = {
-       5,
-       0, 33, -154,
-       34, 34, 297,
-       35, 122, -154,
-       123, 123, 298,
-       124, 255, 233
+       3,
+       34, 107, -37,
+       108, 108, 305,
+       109, 122, 108
 };
 static const int lexer_goto_row240[] = {
-       1,
-       0, 255, -158
+       3,
+       34, 103, -50,
+       104, 104, 306,
+       105, 122, 108
 };
 static const int lexer_goto_row241[] = {
-       1,
-       0, 255, -158
+       4,
+       48, 57, 307,
+       65, 90, 308,
+       95, 95, 309,
+       97, 122, 310
 };
 static const int lexer_goto_row242[] = {
        1,
-       0, 255, -158
+       0, 255, -150
 };
 static const int lexer_goto_row243[] = {
-       9,
-       0, 9, 299,
-       10, 10, 300,
-       11, 12, 299,
-       13, 13, 301,
-       14, 38, 299,
-       39, 39, 302,
-       40, 91, 299,
-       92, 92, 303,
-       93, 255, 299
+       11,
+       0, 9, 311,
+       10, 10, 312,
+       11, 12, 311,
+       13, 13, 313,
+       14, 33, 311,
+       34, 34, 314,
+       35, 91, 311,
+       92, 92, 315,
+       93, 122, 311,
+       123, 123, 316,
+       124, 255, 311
 };
 static const int lexer_goto_row244[] = {
+       1,
+       0, 255, -156
+};
+static const int lexer_goto_row245[] = {
+       1,
+       0, 255, -156
+};
+static const int lexer_goto_row246[] = {
+       1,
+       0, 255, -156
+};
+static const int lexer_goto_row247[] = {
+       5,
+       0, 33, -156,
+       34, 34, 317,
+       35, 122, -156,
+       123, 123, 318,
+       124, 255, 243
+};
+static const int lexer_goto_row248[] = {
        3,
-       0, 9, 304,
-       11, 12, 304,
-       14, 255, 304
+       0, 9, 319,
+       11, 12, 319,
+       14, 255, 319
+};
+static const int lexer_goto_row249[] = {
+       5,
+       0, 33, -156,
+       34, 34, 320,
+       35, 122, -156,
+       123, 123, 321,
+       124, 255, 243
 };
 static const int lexer_goto_row250[] = {
        1,
-       98, 98, 305
+       48, 122, -157
 };
 static const int lexer_goto_row251[] = {
        1,
-       0, 255, -104
+       48, 122, -157
 };
 static const int lexer_goto_row252[] = {
        1,
-       0, 255, -104
+       48, 122, -157
+};
+static const int lexer_goto_row253[] = {
+       1,
+       48, 122, -157
 };
 static const int lexer_goto_row254[] = {
-       3,
-       48, 115, -118,
-       116, 116, 306,
-       117, 122, 106
+       4,
+       48, 57, 322,
+       65, 90, 323,
+       95, 95, 324,
+       97, 122, 325
 };
 static const int lexer_goto_row255[] = {
-       3,
-       48, 113, -36,
-       114, 114, 307,
-       115, 122, 106
+       1,
+       0, 255, -161
 };
 static const int lexer_goto_row256[] = {
-       3,
-       48, 113, -36,
-       114, 114, 308,
-       115, 122, 106
+       1,
+       0, 255, -161
 };
 static const int lexer_goto_row257[] = {
-       3,
-       48, 106, -218,
-       107, 107, 309,
-       108, 122, 106
+       1,
+       0, 255, -161
 };
 static const int lexer_goto_row258[] = {
-       3,
-       48, 114, -111,
-       115, 115, 310,
-       116, 122, 106
+       9,
+       0, 9, 326,
+       10, 10, 327,
+       11, 12, 326,
+       13, 13, 328,
+       14, 38, 326,
+       39, 39, 329,
+       40, 91, 326,
+       92, 92, 330,
+       93, 255, 326
 };
 static const int lexer_goto_row259[] = {
        3,
-       48, 104, -124,
-       105, 105, 311,
-       106, 122, 106
+       0, 9, 331,
+       11, 12, 331,
+       14, 255, 331
 };
 static const int lexer_goto_row260[] = {
        1,
-       48, 122, -41
-};
-static const int lexer_goto_row261[] = {
-       1,
-       48, 122, -41
-};
-static const int lexer_goto_row262[] = {
-       3,
-       48, 113, -36,
-       114, 114, 312,
-       115, 122, 106
-};
-static const int lexer_goto_row263[] = {
-       3,
-       48, 100, -45,
-       101, 101, 313,
-       102, 122, 106
-};
-static const int lexer_goto_row264[] = {
-       3,
-       48, 104, -124,
-       105, 105, 314,
-       106, 122, 106
+       97, 122, 253
 };
 static const int lexer_goto_row265[] = {
-       3,
-       48, 113, -36,
-       114, 114, 315,
-       115, 122, 106
+       1,
+       98, 98, 332
 };
 static const int lexer_goto_row266[] = {
        1,
-       48, 122, -41
+       0, 255, -104
 };
 static const int lexer_goto_row267[] = {
-       3,
-       48, 113, -36,
-       114, 114, 316,
-       115, 122, 106
-};
-static const int lexer_goto_row268[] = {
-       3,
-       48, 116, -141,
-       117, 117, 317,
-       118, 122, 106
+       1,
+       0, 255, -104
 };
 static const int lexer_goto_row269[] = {
-       3,
-       48, 115, -118,
-       116, 116, 318,
-       117, 122, 106
+       11,
+       0, 9, 333,
+       10, 10, 334,
+       11, 12, 333,
+       13, 13, 335,
+       14, 33, 333,
+       34, 34, 336,
+       35, 91, 333,
+       92, 92, 337,
+       93, 122, 333,
+       123, 123, 338,
+       124, 255, 333
 };
 static const int lexer_goto_row270[] = {
-       3,
-       48, 107, -37,
-       108, 108, 319,
-       109, 122, 106
+       1,
+       0, 255, -195
 };
 static const int lexer_goto_row271[] = {
-       1,
-       48, 122, -41
+       9,
+       0, 9, 339,
+       10, 10, 340,
+       11, 12, 339,
+       13, 13, 341,
+       14, 38, 339,
+       39, 39, 342,
+       40, 91, 339,
+       92, 92, 343,
+       93, 255, 339
 };
 static const int lexer_goto_row272[] = {
-       3,
-       48, 107, -37,
-       108, 108, 320,
-       109, 122, 106
+       1,
+       39, 39, 259
 };
 static const int lexer_goto_row273[] = {
        3,
-       48, 95, -35,
-       97, 97, 321,
-       98, 122, 106
+       34, 115, -120,
+       116, 116, 344,
+       117, 122, 108
 };
 static const int lexer_goto_row274[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 113, -36,
+       114, 114, 345,
+       115, 122, 108
 };
 static const int lexer_goto_row275[] = {
        3,
-       48, 95, -35,
-       97, 97, 322,
-       98, 122, 106
+       34, 113, -36,
+       114, 114, 346,
+       115, 122, 108
 };
 static const int lexer_goto_row276[] = {
        3,
-       48, 95, -35,
-       97, 97, 323,
-       98, 122, 106
+       34, 106, -227,
+       107, 107, 347,
+       108, 122, 108
 };
 static const int lexer_goto_row277[] = {
        3,
-       48, 100, -45,
-       101, 101, 324,
-       102, 122, 106
+       34, 114, -113,
+       115, 115, 348,
+       116, 122, 108
 };
 static const int lexer_goto_row278[] = {
        3,
-       48, 104, -124,
-       105, 105, 325,
-       106, 122, 106
+       34, 104, -126,
+       105, 105, 349,
+       106, 122, 108
 };
 static const int lexer_goto_row279[] = {
-       3,
-       48, 101, -42,
-       102, 102, 326,
-       103, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row280[] = {
-       3,
-       48, 113, -36,
-       114, 114, 327,
-       115, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row281[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 113, -36,
+       114, 114, 350,
+       115, 122, 108
 };
 static const int lexer_goto_row282[] = {
        3,
-       48, 113, -36,
-       114, 114, 328,
-       115, 122, 106
+       34, 100, -45,
+       101, 101, 351,
+       102, 122, 108
 };
 static const int lexer_goto_row283[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 104, -126,
+       105, 105, 352,
+       106, 122, 108
 };
 static const int lexer_goto_row284[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 113, -36,
+       114, 114, 353,
+       115, 122, 108
 };
 static const int lexer_goto_row285[] = {
        1,
-       48, 122, -41
+       34, 122, -41
 };
 static const int lexer_goto_row286[] = {
        3,
-       48, 100, -45,
-       101, 101, 329,
-       102, 122, 106
+       34, 113, -36,
+       114, 114, 354,
+       115, 122, 108
 };
 static const int lexer_goto_row287[] = {
        3,
-       48, 100, -45,
-       101, 101, 330,
-       102, 122, 106
+       34, 116, -143,
+       117, 117, 355,
+       118, 122, 108
 };
 static const int lexer_goto_row288[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 115, -120,
+       116, 116, 356,
+       117, 122, 108
 };
 static const int lexer_goto_row289[] = {
-       1,
-       0, 255, -234
+       3,
+       34, 107, -37,
+       108, 108, 357,
+       109, 122, 108
 };
 static const int lexer_goto_row290[] = {
-       11,
-       0, 9, 331,
-       10, 10, 289,
-       11, 12, 331,
-       13, 13, 290,
-       14, 33, 331,
-       34, 34, 332,
-       35, 91, 331,
-       92, 92, 333,
-       93, 122, 331,
-       123, 123, 334,
-       124, 255, 331
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row291[] = {
-       1,
-       0, 255, -291
+       3,
+       34, 107, -37,
+       108, 108, 358,
+       109, 122, 108
 };
 static const int lexer_goto_row292[] = {
-       5,
-       0, 33, -291,
-       34, 34, 335,
-       35, 122, -291,
-       123, 123, 336,
-       124, 255, 331
+       3,
+       34, 95, -35,
+       97, 97, 359,
+       98, 122, 108
 };
 static const int lexer_goto_row293[] = {
-       3,
-       0, 9, 337,
-       11, 12, 337,
-       14, 255, 337
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row294[] = {
-       5,
-       0, 33, -291,
-       34, 34, 338,
-       35, 122, -291,
-       123, 123, 339,
-       124, 255, 331
+       3,
+       34, 95, -35,
+       97, 97, 360,
+       98, 122, 108
 };
 static const int lexer_goto_row295[] = {
        3,
-       0, 33, -154,
-       34, 34, 340,
-       35, 255, -238
+       34, 95, -35,
+       97, 97, 361,
+       98, 122, 108
 };
 static const int lexer_goto_row296[] = {
        3,
-       0, 122, -240,
-       123, 123, 341,
-       124, 255, 233
+       34, 100, -45,
+       101, 101, 362,
+       102, 122, 108
 };
 static const int lexer_goto_row297[] = {
-       1,
-       0, 255, -154
+       3,
+       34, 104, -126,
+       105, 105, 363,
+       106, 122, 108
 };
 static const int lexer_goto_row298[] = {
        3,
-       0, 33, -154,
-       34, 34, 342,
-       35, 255, -238
+       34, 101, -42,
+       102, 102, 364,
+       103, 122, 108
 };
 static const int lexer_goto_row299[] = {
        3,
-       0, 122, -240,
-       123, 123, 343,
-       124, 255, 233
+       34, 113, -36,
+       114, 114, 365,
+       115, 122, 108
 };
 static const int lexer_goto_row300[] = {
        1,
-       0, 255, -158
+       34, 122, -41
 };
 static const int lexer_goto_row301[] = {
-       1,
-       0, 255, -158
+       3,
+       34, 113, -36,
+       114, 114, 366,
+       115, 122, 108
 };
 static const int lexer_goto_row302[] = {
        1,
-       0, 255, -158
+       34, 122, -41
 };
 static const int lexer_goto_row303[] = {
-       9,
-       0, 9, 344,
-       10, 10, 345,
-       11, 12, 344,
-       13, 13, 346,
-       14, 38, 344,
-       39, 39, 347,
-       40, 91, 344,
-       92, 92, 348,
-       93, 255, 344
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row304[] = {
-       3,
-       0, 9, 349,
-       11, 12, 349,
-       14, 255, 349
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row305[] = {
-       1,
-       0, 255, -158
+       3,
+       34, 100, -45,
+       101, 101, 367,
+       102, 122, 108
 };
 static const int lexer_goto_row306[] = {
-       1,
-       117, 117, 350
+       3,
+       34, 100, -45,
+       101, 101, 368,
+       102, 122, 108
 };
 static const int lexer_goto_row307[] = {
        1,
-       48, 122, -41
+       34, 122, -41
 };
 static const int lexer_goto_row308[] = {
-       3,
-       48, 95, -35,
-       97, 97, 351,
-       98, 122, 106
+       1,
+       48, 122, -242
 };
 static const int lexer_goto_row309[] = {
-       3,
-       48, 115, -118,
-       116, 116, 352,
-       117, 122, 106
+       1,
+       48, 122, -242
 };
 static const int lexer_goto_row310[] = {
        1,
-       48, 122, -41
+       48, 122, -242
 };
 static const int lexer_goto_row311[] = {
        1,
-       48, 122, -41
+       48, 122, -242
 };
 static const int lexer_goto_row312[] = {
-       3,
-       48, 109, -46,
-       110, 110, 353,
-       111, 122, 106
+       1,
+       0, 255, -244
 };
 static const int lexer_goto_row313[] = {
-       3,
-       48, 109, -46,
-       110, 110, 354,
-       111, 122, 106
+       11,
+       0, 9, 369,
+       10, 10, 312,
+       11, 12, 369,
+       13, 13, 313,
+       14, 33, 369,
+       34, 34, 370,
+       35, 91, 369,
+       92, 92, 371,
+       93, 122, 369,
+       123, 123, 372,
+       124, 255, 369
 };
 static const int lexer_goto_row314[] = {
        1,
-       48, 122, -41
+       0, 255, -314
 };
 static const int lexer_goto_row315[] = {
-       3,
-       48, 100, -45,
-       101, 101, 355,
-       102, 122, 106
+       7,
+       0, 33, -314,
+       34, 34, 373,
+       35, 92, -314,
+       93, 96, 369,
+       97, 122, 374,
+       123, 123, 375,
+       124, 255, 369
 };
 static const int lexer_goto_row316[] = {
        3,
-       48, 115, -118,
-       116, 116, 356,
-       117, 122, 106
+       0, 9, 376,
+       11, 12, 376,
+       14, 255, 376
 };
 static const int lexer_goto_row317[] = {
-       3,
-       48, 101, -42,
-       102, 102, 357,
-       103, 122, 106
+       5,
+       0, 33, -314,
+       34, 34, 377,
+       35, 122, -314,
+       123, 123, 378,
+       124, 255, 369
 };
 static const int lexer_goto_row318[] = {
        3,
-       48, 99, -110,
-       100, 100, 358,
-       101, 122, 106
+       0, 33, -156,
+       34, 34, 379,
+       35, 255, -248
 };
 static const int lexer_goto_row319[] = {
-       1,
-       48, 122, -41
+       3,
+       0, 122, -250,
+       123, 123, 380,
+       124, 255, 243
 };
 static const int lexer_goto_row320[] = {
        1,
-       48, 122, -41
+       0, 255, -156
 };
 static const int lexer_goto_row321[] = {
        3,
-       48, 100, -45,
-       101, 101, 359,
-       102, 122, 106
+       0, 33, -156,
+       34, 34, 381,
+       35, 255, -248
 };
 static const int lexer_goto_row322[] = {
        3,
-       48, 97, -35,
-       98, 98, 360,
-       99, 122, 106
+       0, 122, -250,
+       123, 123, 382,
+       124, 255, 243
 };
 static const int lexer_goto_row323[] = {
-       4,
-       48, 95, -35,
-       97, 102, 106,
-       103, 103, 361,
-       104, 122, 106
+       1,
+       48, 122, -255
 };
 static const int lexer_goto_row324[] = {
-       3,
-       48, 115, -118,
-       116, 116, 362,
-       117, 122, 106
+       1,
+       48, 122, -255
 };
 static const int lexer_goto_row325[] = {
-       3,
-       48, 98, -132,
-       99, 99, 363,
-       100, 122, 106
+       1,
+       48, 122, -255
 };
 static const int lexer_goto_row326[] = {
-       3,
-       48, 98, -132,
-       99, 99, 364,
-       100, 122, 106
+       1,
+       48, 122, -255
 };
 static const int lexer_goto_row327[] = {
        1,
-       48, 122, -41
+       0, 255, -161
 };
 static const int lexer_goto_row328[] = {
-       3,
-       48, 109, -46,
-       110, 110, 365,
-       111, 122, 106
+       1,
+       0, 255, -161
 };
 static const int lexer_goto_row329[] = {
        1,
-       48, 122, -41
+       0, 255, -161
 };
 static const int lexer_goto_row330[] = {
-       3,
-       48, 113, -36,
-       114, 114, 366,
-       115, 122, 106
+       9,
+       0, 9, 383,
+       10, 10, 384,
+       11, 12, 383,
+       13, 13, 385,
+       14, 38, 383,
+       39, 39, 386,
+       40, 91, 383,
+       92, 92, 387,
+       93, 255, 383
 };
 static const int lexer_goto_row331[] = {
-       1,
-       48, 122, -41
+       3,
+       0, 9, 388,
+       11, 12, 388,
+       14, 255, 388
 };
 static const int lexer_goto_row332[] = {
        1,
-       0, 255, -291
+       0, 255, -161
 };
 static const int lexer_goto_row333[] = {
        1,
-       0, 255, -293
+       117, 117, 389
 };
 static const int lexer_goto_row334[] = {
-       3,
-       0, 9, 367,
-       11, 12, 367,
-       14, 255, 367
+       1,
+       0, 255, -270
 };
 static const int lexer_goto_row335[] = {
        1,
-       0, 255, -295
+       0, 255, -270
 };
 static const int lexer_goto_row336[] = {
-       3,
-       0, 33, -291,
-       34, 34, 368,
-       35, 255, -293
+       1,
+       0, 255, -270
 };
 static const int lexer_goto_row337[] = {
-       3,
-       0, 122, -295,
-       123, 123, 369,
-       124, 255, 331
+       5,
+       0, 33, -270,
+       34, 34, 390,
+       35, 122, -270,
+       123, 123, 391,
+       124, 255, 333
 };
 static const int lexer_goto_row338[] = {
-       1,
-       0, 255, -234
+       3,
+       0, 9, 392,
+       11, 12, 392,
+       14, 255, 392
 };
 static const int lexer_goto_row339[] = {
-       3,
-       0, 33, -291,
-       34, 34, 370,
-       35, 255, -293
+       5,
+       0, 33, -270,
+       34, 34, 393,
+       35, 122, -270,
+       123, 123, 394,
+       124, 255, 333
 };
 static const int lexer_goto_row340[] = {
-       3,
-       0, 122, -295,
-       123, 123, 371,
-       124, 255, 331
+       1,
+       0, 255, -272
 };
 static const int lexer_goto_row341[] = {
        1,
-       34, 34, 372
+       0, 255, -272
 };
 static const int lexer_goto_row342[] = {
        1,
-       0, 255, -300
+       0, 255, -272
 };
 static const int lexer_goto_row343[] = {
-       1,
-       0, 255, -296
+       9,
+       0, 9, 395,
+       10, 10, 396,
+       11, 12, 395,
+       13, 13, 397,
+       14, 38, 395,
+       39, 39, 398,
+       40, 91, 395,
+       92, 92, 399,
+       93, 255, 395
 };
 static const int lexer_goto_row344[] = {
-       1,
-       123, 123, 373
+       3,
+       0, 9, 400,
+       11, 12, 400,
+       14, 255, 400
 };
 static const int lexer_goto_row345[] = {
        1,
-       0, 255, -158
+       34, 122, -41
 };
 static const int lexer_goto_row346[] = {
-       1,
-       0, 255, -158
+       3,
+       34, 95, -35,
+       97, 97, 401,
+       98, 122, 108
 };
 static const int lexer_goto_row347[] = {
+       3,
+       34, 115, -120,
+       116, 116, 402,
+       117, 122, 108
+};
+static const int lexer_goto_row348[] = {
        1,
-       0, 255, -158
+       34, 122, -41
 };
 static const int lexer_goto_row349[] = {
-       3,
-       0, 9, 374,
-       11, 12, 374,
-       14, 255, 374
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row350[] = {
-       1,
-       0, 255, -158
+       3,
+       34, 109, -46,
+       110, 110, 403,
+       111, 122, 108
 };
 static const int lexer_goto_row351[] = {
-       1,
-       103, 103, 375
+       3,
+       34, 109, -46,
+       110, 110, 404,
+       111, 122, 108
 };
 static const int lexer_goto_row352[] = {
-       3,
-       48, 98, -132,
-       99, 99, 376,
-       100, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row353[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 100, -45,
+       101, 101, 405,
+       102, 122, 108
 };
 static const int lexer_goto_row354[] = {
        3,
-       48, 116, -141,
-       117, 117, 377,
-       118, 122, 106
+       34, 115, -120,
+       116, 116, 406,
+       117, 122, 108
 };
 static const int lexer_goto_row355[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 101, -42,
+       102, 102, 407,
+       103, 122, 108
 };
 static const int lexer_goto_row356[] = {
        3,
-       48, 114, -111,
-       115, 115, 378,
-       116, 122, 106
+       34, 99, -112,
+       100, 100, 408,
+       101, 122, 108
 };
 static const int lexer_goto_row357[] = {
        1,
-       48, 122, -41
+       34, 122, -41
 };
 static const int lexer_goto_row358[] = {
-       3,
-       48, 95, -35,
-       97, 97, 379,
-       98, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row359[] = {
        3,
-       48, 100, -45,
-       101, 101, 380,
-       102, 122, 106
+       34, 100, -45,
+       101, 101, 409,
+       102, 122, 108
 };
 static const int lexer_goto_row360[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 97, -35,
+       98, 98, 410,
+       99, 122, 108
 };
 static const int lexer_goto_row361[] = {
-       3,
-       48, 107, -37,
-       108, 108, 381,
-       109, 122, 106
+       4,
+       34, 95, -35,
+       97, 102, 108,
+       103, 103, 411,
+       104, 122, 108
 };
 static const int lexer_goto_row362[] = {
        3,
-       48, 100, -45,
-       101, 101, 382,
-       102, 122, 106
+       34, 115, -120,
+       116, 116, 412,
+       117, 122, 108
 };
 static const int lexer_goto_row363[] = {
        3,
-       48, 100, -45,
-       101, 101, 383,
-       102, 122, 106
+       34, 98, -134,
+       99, 99, 413,
+       100, 122, 108
 };
 static const int lexer_goto_row364[] = {
        3,
-       48, 115, -118,
-       116, 116, 384,
-       117, 122, 106
+       34, 98, -134,
+       99, 99, 414,
+       100, 122, 108
 };
 static const int lexer_goto_row365[] = {
        1,
-       48, 122, -41
+       34, 122, -41
 };
 static const int lexer_goto_row366[] = {
-       1,
-       48, 122, -41
+       3,
+       34, 109, -46,
+       110, 110, 415,
+       111, 122, 108
 };
 static const int lexer_goto_row367[] = {
-       3,
-       48, 114, -111,
-       115, 115, 385,
-       116, 122, 106
+       1,
+       34, 122, -41
 };
 static const int lexer_goto_row368[] = {
-       1,
-       0, 255, -291
+       3,
+       34, 113, -36,
+       114, 114, 416,
+       115, 122, 108
 };
 static const int lexer_goto_row369[] = {
        1,
-       34, 34, 386
+       34, 122, -41
 };
 static const int lexer_goto_row370[] = {
        1,
-       0, 255, -341
+       0, 255, -314
 };
 static const int lexer_goto_row371[] = {
-       1,
-       0, 255, -337
+       3,
+       0, 92, -316,
+       93, 122, 369,
+       123, 255, -316
 };
 static const int lexer_goto_row372[] = {
-       1,
-       123, 123, 387
+       3,
+       0, 9, 417,
+       11, 12, 417,
+       14, 255, 417
 };
 static const int lexer_goto_row373[] = {
        1,
-       34, 34, 372
+       0, 255, -318
 };
 static const int lexer_goto_row374[] = {
-       1,
-       123, 123, 373
+       3,
+       0, 33, -314,
+       34, 34, 418,
+       35, 255, -372
 };
 static const int lexer_goto_row375[] = {
-       1,
-       0, 255, -158
+       12,
+       0, 34, -314,
+       35, 47, 369,
+       48, 57, 419,
+       58, 64, 369,
+       65, 90, 420,
+       91, 91, 369,
+       92, 92, 371,
+       93, 94, 369,
+       95, 95, 421,
+       96, 96, 369,
+       97, 122, 422,
+       123, 255, -314
 };
 static const int lexer_goto_row376[] = {
-       1,
-       95, 95, 388
+       3,
+       0, 122, -318,
+       123, 123, 423,
+       124, 255, 369
 };
 static const int lexer_goto_row377[] = {
-       3,
-       48, 115, -118,
-       116, 116, 389,
-       117, 122, 106
+       1,
+       0, 255, -244
 };
 static const int lexer_goto_row378[] = {
        3,
-       48, 100, -45,
-       101, 101, 390,
-       102, 122, 106
+       0, 33, -314,
+       34, 34, 424,
+       35, 255, -372
 };
 static const int lexer_goto_row379[] = {
-       1,
-       48, 122, -41
+       3,
+       0, 122, -318,
+       123, 123, 425,
+       124, 255, 369
 };
 static const int lexer_goto_row380[] = {
-       3,
-       48, 98, -132,
-       99, 99, 391,
-       100, 122, 106
+       1,
+       34, 34, 426
 };
 static const int lexer_goto_row381[] = {
        1,
-       48, 122, -41
+       0, 255, -323
 };
 static const int lexer_goto_row382[] = {
-       3,
-       48, 100, -45,
-       101, 101, 392,
-       102, 122, 106
+       1,
+       0, 255, -319
 };
 static const int lexer_goto_row383[] = {
        1,
-       48, 122, -41
+       123, 123, 427
 };
 static const int lexer_goto_row384[] = {
        1,
-       48, 122, -41
+       0, 255, -161
 };
 static const int lexer_goto_row385[] = {
-       3,
-       48, 100, -45,
-       101, 101, 393,
-       102, 122, 106
+       1,
+       0, 255, -161
 };
 static const int lexer_goto_row386[] = {
-       3,
-       48, 95, -35,
-       97, 97, 394,
-       98, 122, 106
+       1,
+       0, 255, -161
 };
 static const int lexer_goto_row387[] = {
        1,
-       34, 34, 386
+       97, 122, 428
 };
 static const int lexer_goto_row388[] = {
-       1,
-       123, 123, 387
+       3,
+       0, 9, 429,
+       11, 12, 429,
+       14, 255, 429
 };
 static const int lexer_goto_row389[] = {
        1,
-       95, 95, 395
+       0, 255, -161
 };
 static const int lexer_goto_row390[] = {
        1,
-       48, 122, -41
+       103, 103, 430
 };
 static const int lexer_goto_row391[] = {
-       1,
-       48, 122, -41
+       3,
+       0, 33, -270,
+       34, 34, 379,
+       35, 255, -338
 };
 static const int lexer_goto_row392[] = {
        3,
-       48, 100, -45,
-       101, 101, 396,
-       102, 122, 106
+       0, 122, -340,
+       123, 123, 431,
+       124, 255, 333
 };
 static const int lexer_goto_row393[] = {
        1,
-       48, 122, -41
+       0, 255, -270
 };
 static const int lexer_goto_row394[] = {
        3,
-       48, 99, -110,
-       100, 100, 397,
-       101, 122, 106
+       0, 33, -270,
+       34, 34, 432,
+       35, 255, -338
 };
 static const int lexer_goto_row395[] = {
        3,
-       48, 107, -37,
-       108, 108, 398,
-       109, 122, 106
+       0, 122, -340,
+       123, 123, 382,
+       124, 255, 333
+};
+static const int lexer_goto_row396[] = {
+       1,
+       0, 255, -272
 };
 static const int lexer_goto_row397[] = {
        1,
-       48, 122, -41
+       0, 255, -272
 };
 static const int lexer_goto_row398[] = {
        1,
-       48, 122, -41
+       0, 255, -272
 };
 static const int lexer_goto_row399[] = {
+       9,
+       0, 9, 433,
+       10, 10, 434,
+       11, 12, 433,
+       13, 13, 435,
+       14, 38, 433,
+       39, 39, 386,
+       40, 91, 433,
+       92, 92, 436,
+       93, 255, 433
+};
+static const int lexer_goto_row400[] = {
+       3,
+       0, 9, 437,
+       11, 12, 437,
+       14, 255, 437
+};
+static const int lexer_goto_row401[] = {
+       1,
+       0, 255, -272
+};
+static const int lexer_goto_row402[] = {
+       3,
+       34, 98, -134,
+       99, 99, 438,
+       100, 122, 108
+};
+static const int lexer_goto_row403[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row404[] = {
+       3,
+       34, 116, -143,
+       117, 117, 439,
+       118, 122, 108
+};
+static const int lexer_goto_row405[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row406[] = {
+       3,
+       34, 114, -113,
+       115, 115, 440,
+       116, 122, 108
+};
+static const int lexer_goto_row407[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row408[] = {
+       3,
+       34, 95, -35,
+       97, 97, 441,
+       98, 122, 108
+};
+static const int lexer_goto_row409[] = {
+       3,
+       34, 100, -45,
+       101, 101, 442,
+       102, 122, 108
+};
+static const int lexer_goto_row410[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row411[] = {
+       3,
+       34, 107, -37,
+       108, 108, 443,
+       109, 122, 108
+};
+static const int lexer_goto_row412[] = {
+       3,
+       34, 100, -45,
+       101, 101, 444,
+       102, 122, 108
+};
+static const int lexer_goto_row413[] = {
+       3,
+       34, 100, -45,
+       101, 101, 445,
+       102, 122, 108
+};
+static const int lexer_goto_row414[] = {
+       3,
+       34, 115, -120,
+       116, 116, 446,
+       117, 122, 108
+};
+static const int lexer_goto_row415[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row416[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row417[] = {
+       3,
+       34, 114, -113,
+       115, 115, 447,
+       116, 122, 108
+};
+static const int lexer_goto_row418[] = {
+       1,
+       0, 255, -314
+};
+static const int lexer_goto_row419[] = {
+       2,
+       34, 34, 448,
+       97, 122, 449
+};
+static const int lexer_goto_row420[] = {
+       1,
+       0, 255, -376
+};
+static const int lexer_goto_row421[] = {
+       1,
+       0, 255, -376
+};
+static const int lexer_goto_row422[] = {
+       1,
+       0, 255, -376
+};
+static const int lexer_goto_row423[] = {
+       1,
+       0, 255, -376
+};
+static const int lexer_goto_row424[] = {
+       1,
+       0, 255, -380
+};
+static const int lexer_goto_row425[] = {
+       1,
+       0, 255, -375
+};
+static const int lexer_goto_row426[] = {
+       1,
+       123, 123, 450
+};
+static const int lexer_goto_row427[] = {
+       1,
+       34, 34, 426
+};
+static const int lexer_goto_row428[] = {
+       1,
+       123, 123, 427
+};
+static const int lexer_goto_row429[] = {
+       4,
+       48, 57, 451,
+       65, 90, 452,
+       95, 95, 453,
+       97, 122, 454
+};
+static const int lexer_goto_row430[] = {
+       1,
+       0, 255, -161
+};
+static const int lexer_goto_row431[] = {
+       1,
+       95, 95, 455
+};
+static const int lexer_goto_row432[] = {
+       1,
+       0, 255, -396
+};
+static const int lexer_goto_row433[] = {
+       1,
+       0, 255, -392
+};
+static const int lexer_goto_row434[] = {
+       1,
+       0, 255, -272
+};
+static const int lexer_goto_row435[] = {
+       1,
+       0, 255, -272
+};
+static const int lexer_goto_row436[] = {
+       1,
+       0, 255, -272
+};
+static const int lexer_goto_row437[] = {
+       3,
+       0, 9, 456,
+       11, 12, 456,
+       14, 255, 456
+};
+static const int lexer_goto_row438[] = {
+       1,
+       0, 255, -272
+};
+static const int lexer_goto_row439[] = {
+       3,
+       34, 115, -120,
+       116, 116, 457,
+       117, 122, 108
+};
+static const int lexer_goto_row440[] = {
+       3,
+       34, 100, -45,
+       101, 101, 458,
+       102, 122, 108
+};
+static const int lexer_goto_row441[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row442[] = {
+       3,
+       34, 98, -134,
+       99, 99, 459,
+       100, 122, 108
+};
+static const int lexer_goto_row443[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row444[] = {
+       3,
+       34, 100, -45,
+       101, 101, 460,
+       102, 122, 108
+};
+static const int lexer_goto_row445[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row446[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row447[] = {
+       3,
+       34, 100, -45,
+       101, 101, 461,
+       102, 122, 108
+};
+static const int lexer_goto_row448[] = {
+       3,
+       34, 95, -35,
+       97, 97, 462,
+       98, 122, 108
+};
+static const int lexer_goto_row449[] = {
+       1,
+       34, 122, -420
+};
+static const int lexer_goto_row450[] = {
+       4,
+       48, 57, 463,
+       65, 90, 464,
+       95, 95, 465,
+       97, 122, 466
+};
+static const int lexer_goto_row451[] = {
+       1,
+       123, 123, 450
+};
+static const int lexer_goto_row452[] = {
+       1,
+       48, 122, -430
+};
+static const int lexer_goto_row453[] = {
+       1,
+       48, 122, -430
+};
+static const int lexer_goto_row454[] = {
+       1,
+       48, 122, -430
+};
+static const int lexer_goto_row455[] = {
+       1,
+       48, 122, -430
+};
+static const int lexer_goto_row456[] = {
+       1,
+       95, 95, 467
+};
+static const int lexer_goto_row457[] = {
+       1,
+       0, 255, -272
+};
+static const int lexer_goto_row458[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row459[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row460[] = {
+       3,
+       34, 100, -45,
+       101, 101, 468,
+       102, 122, 108
+};
+static const int lexer_goto_row461[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row462[] = {
+       3,
+       34, 99, -112,
+       100, 100, 469,
+       101, 122, 108
+};
+static const int lexer_goto_row463[] = {
+       3,
+       34, 107, -37,
+       108, 108, 470,
+       109, 122, 108
+};
+static const int lexer_goto_row464[] = {
+       1,
+       48, 122, -451
+};
+static const int lexer_goto_row465[] = {
+       1,
+       48, 122, -451
+};
+static const int lexer_goto_row466[] = {
+       1,
+       48, 122, -451
+};
+static const int lexer_goto_row467[] = {
+       1,
+       48, 122, -451
+};
+static const int lexer_goto_row469[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row470[] = {
+       1,
+       34, 122, -41
+};
+static const int lexer_goto_row471[] = {
        1,
-       48, 122, -41
+       34, 122, -41
 };
 static const int lexer_goto_row_null[] = {0};
 const int* const lexer_goto_table[] = {
@@ -2184,24 +2605,24 @@ const int* const lexer_goto_table[] = {
        lexer_goto_row143,
        lexer_goto_row144,
        lexer_goto_row145,
-       lexer_goto_row_null,
+       lexer_goto_row146,
        lexer_goto_row147,
        lexer_goto_row_null,
        lexer_goto_row149,
-       lexer_goto_row_null,
+       lexer_goto_row150,
        lexer_goto_row151,
        lexer_goto_row_null,
        lexer_goto_row153,
        lexer_goto_row154,
-       lexer_goto_row_null,
-       lexer_goto_row_null,
+       lexer_goto_row155,
+       lexer_goto_row156,
        lexer_goto_row157,
-       lexer_goto_row158,
-       lexer_goto_row_null,
        lexer_goto_row_null,
+       lexer_goto_row159,
+       lexer_goto_row160,
        lexer_goto_row161,
-       lexer_goto_row162,
-       lexer_goto_row163,
+       lexer_goto_row_null,
+       lexer_goto_row_null,
        lexer_goto_row164,
        lexer_goto_row165,
        lexer_goto_row166,
@@ -2214,16 +2635,16 @@ const int* const lexer_goto_table[] = {
        lexer_goto_row173,
        lexer_goto_row174,
        lexer_goto_row175,
-       lexer_goto_row_null,
+       lexer_goto_row176,
        lexer_goto_row177,
        lexer_goto_row178,
        lexer_goto_row_null,
+       lexer_goto_row180,
+       lexer_goto_row181,
+       lexer_goto_row_null,
        lexer_goto_row_null,
        lexer_goto_row_null,
        lexer_goto_row_null,
-       lexer_goto_row183,
-       lexer_goto_row184,
-       lexer_goto_row185,
        lexer_goto_row186,
        lexer_goto_row187,
        lexer_goto_row188,
@@ -2283,15 +2704,15 @@ const int* const lexer_goto_table[] = {
        lexer_goto_row242,
        lexer_goto_row243,
        lexer_goto_row244,
-       lexer_goto_row_null,
-       lexer_goto_row_null,
-       lexer_goto_row_null,
-       lexer_goto_row_null,
-       lexer_goto_row_null,
+       lexer_goto_row245,
+       lexer_goto_row246,
+       lexer_goto_row247,
+       lexer_goto_row248,
+       lexer_goto_row249,
        lexer_goto_row250,
        lexer_goto_row251,
        lexer_goto_row252,
-       lexer_goto_row_null,
+       lexer_goto_row253,
        lexer_goto_row254,
        lexer_goto_row255,
        lexer_goto_row256,
@@ -2299,14 +2720,14 @@ const int* const lexer_goto_table[] = {
        lexer_goto_row258,
        lexer_goto_row259,
        lexer_goto_row260,
-       lexer_goto_row261,
-       lexer_goto_row262,
-       lexer_goto_row263,
-       lexer_goto_row264,
+       lexer_goto_row_null,
+       lexer_goto_row_null,
+       lexer_goto_row_null,
+       lexer_goto_row_null,
        lexer_goto_row265,
        lexer_goto_row266,
        lexer_goto_row267,
-       lexer_goto_row268,
+       lexer_goto_row_null,
        lexer_goto_row269,
        lexer_goto_row270,
        lexer_goto_row271,
@@ -2386,7 +2807,7 @@ const int* const lexer_goto_table[] = {
        lexer_goto_row345,
        lexer_goto_row346,
        lexer_goto_row347,
-       lexer_goto_row_null,
+       lexer_goto_row348,
        lexer_goto_row349,
        lexer_goto_row350,
        lexer_goto_row351,
@@ -2434,14 +2855,86 @@ const int* const lexer_goto_table[] = {
        lexer_goto_row393,
        lexer_goto_row394,
        lexer_goto_row395,
-       lexer_goto_row_null,
+       lexer_goto_row396,
        lexer_goto_row397,
        lexer_goto_row398,
-       lexer_goto_row399
+       lexer_goto_row399,
+       lexer_goto_row400,
+       lexer_goto_row401,
+       lexer_goto_row402,
+       lexer_goto_row403,
+       lexer_goto_row404,
+       lexer_goto_row405,
+       lexer_goto_row406,
+       lexer_goto_row407,
+       lexer_goto_row408,
+       lexer_goto_row409,
+       lexer_goto_row410,
+       lexer_goto_row411,
+       lexer_goto_row412,
+       lexer_goto_row413,
+       lexer_goto_row414,
+       lexer_goto_row415,
+       lexer_goto_row416,
+       lexer_goto_row417,
+       lexer_goto_row418,
+       lexer_goto_row419,
+       lexer_goto_row420,
+       lexer_goto_row421,
+       lexer_goto_row422,
+       lexer_goto_row423,
+       lexer_goto_row424,
+       lexer_goto_row425,
+       lexer_goto_row426,
+       lexer_goto_row427,
+       lexer_goto_row428,
+       lexer_goto_row429,
+       lexer_goto_row430,
+       lexer_goto_row431,
+       lexer_goto_row432,
+       lexer_goto_row433,
+       lexer_goto_row434,
+       lexer_goto_row435,
+       lexer_goto_row436,
+       lexer_goto_row437,
+       lexer_goto_row438,
+       lexer_goto_row439,
+       lexer_goto_row440,
+       lexer_goto_row441,
+       lexer_goto_row442,
+       lexer_goto_row443,
+       lexer_goto_row444,
+       lexer_goto_row445,
+       lexer_goto_row446,
+       lexer_goto_row447,
+       lexer_goto_row448,
+       lexer_goto_row449,
+       lexer_goto_row450,
+       lexer_goto_row451,
+       lexer_goto_row452,
+       lexer_goto_row453,
+       lexer_goto_row454,
+       lexer_goto_row455,
+       lexer_goto_row456,
+       lexer_goto_row457,
+       lexer_goto_row458,
+       lexer_goto_row459,
+       lexer_goto_row460,
+       lexer_goto_row461,
+       lexer_goto_row462,
+       lexer_goto_row463,
+       lexer_goto_row464,
+       lexer_goto_row465,
+       lexer_goto_row466,
+       lexer_goto_row467,
+       lexer_goto_row_null,
+       lexer_goto_row469,
+       lexer_goto_row470,
+       lexer_goto_row471
 };
 
 const int lexer_accept_table[] = {
-       -1,0,1,1,0,94,107,2,80,83,-1,53,54,77,75,57,76,74,79,100,100,58,96,87,60,90,95,97,55,56,82,-1,-1,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,81,107,84,1,86,107,102,-1,103,2,2,2,65,69,108,108,108,78,63,61,62,73,101,64,-1,100,-1,-1,-1,-1,100,-1,-1,-1,-1,-1,-1,59,89,88,85,91,92,97,97,97,97,68,-1,99,-1,98,98,98,98,98,98,47,98,98,98,16,98,98,98,98,98,98,23,98,29,15,98,98,98,98,98,98,98,31,98,98,98,98,98,98,98,98,98,98,98,98,98,67,107,105,-1,104,107,102,107,107,2,106,107,108,66,72,100,100,100,-1,-1,101,100,100,100,100,100,100,100,-1,-1,100,-1,-1,100,70,93,71,-1,99,99,99,99,-1,-1,-1,98,98,30,98,98,98,98,98,10,98,98,98,28,11,98,98,98,40,98,98,98,98,39,32,98,98,98,98,98,98,98,98,98,98,98,98,98,98,17,98,98,107,107,107,107,107,-1,-1,-1,107,107,107,-1,-1,106,100,100,100,100,-1,-1,-1,109,98,98,98,98,98,98,25,9,98,98,98,98,13,98,98,98,98,27,98,46,41,98,98,98,98,98,98,43,98,24,44,12,98,98,51,107,-1,-1,105,-1,104,-1,-1,107,-1,-1,107,107,107,-1,-1,107,-1,37,98,98,36,6,98,98,45,98,98,98,98,49,50,98,98,98,98,98,98,14,98,42,98,26,-1,-1,-1,-1,-1,-1,107,-1,-1,102,-1,-1,103,107,107,107,102,-1,107,-1,98,38,98,18,98,5,98,98,4,98,98,98,98,19,34,98,-1,105,-1,-1,104,102,103,107,-1,98,98,33,98,22,98,3,21,98,98,105,104,-1,7,35,98,48,98,98,52,8,20,9
+       -1,0,1,1,0,94,107,2,80,83,-1,53,54,77,75,57,76,74,79,100,100,58,96,87,60,90,95,97,55,56,82,-1,-1,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,81,107,84,1,86,107,102,-1,103,2,2,2,65,69,108,108,108,78,63,61,62,73,101,64,-1,100,-1,-1,-1,-1,100,-1,-1,-1,-1,-1,-1,59,89,88,85,91,92,97,97,97,97,68,-1,99,-1,-1,-1,98,98,98,98,98,98,47,98,98,98,16,98,98,98,98,98,98,23,98,29,15,98,98,98,98,98,98,98,31,98,98,98,98,98,98,98,98,98,98,98,98,98,67,107,105,-1,104,107,102,107,102,107,2,106,107,108,66,72,100,100,100,-1,-1,101,100,100,100,100,100,100,100,-1,-1,100,-1,-1,100,70,93,71,-1,99,99,99,99,-1,-1,-1,-1,102,-1,-1,-1,-1,98,98,30,98,98,98,98,98,10,98,98,98,28,11,98,98,98,40,98,98,98,98,39,32,98,98,98,98,98,98,98,98,98,98,98,98,98,98,17,98,98,105,107,107,107,107,107,-1,-1,-1,102,102,102,102,106,107,107,107,-1,-1,106,100,100,100,100,-1,-1,-1,109,-1,-1,-1,-1,98,98,98,98,98,98,25,9,98,98,98,98,13,98,98,98,98,27,98,46,41,98,98,98,98,98,98,43,98,24,44,12,98,98,51,105,105,105,105,107,-1,-1,105,-1,104,-1,-1,107,-1,-1,106,106,106,106,107,107,107,-1,-1,107,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,37,98,98,36,6,98,98,45,98,98,98,98,49,50,98,98,98,98,98,98,14,98,42,98,26,-1,-1,-1,-1,-1,105,-1,107,-1,-1,102,-1,-1,103,107,107,107,102,-1,107,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,98,38,98,18,98,5,98,98,4,98,98,98,98,19,34,98,-1,105,105,105,105,105,-1,-1,104,102,103,102,107,-1,-1,-1,-1,-1,-1,-1,-1,98,98,33,98,22,98,3,21,98,98,105,105,104,102,102,102,102,-1,-1,7,35,98,48,98,98,105,105,105,105,52,8,20,9
 };
 
 static int parser_action_row1[] = {
index a87a48f..9a6b117 100644 (file)
@@ -25,7 +25,7 @@ module rapid_type_analysis
 
 import semantize
 
-private import csv # for live_types_to_csv
+import csv # for live_types_to_csv
 private import ordered_tree # for live_methods_to_tree
 
 private import more_collections
index 22d361e..5c399c6 100644 (file)
@@ -18,6 +18,10 @@ class A
        protected fun proA(a: A) do end
        private fun priA(a: A) do end
 
+       fun pubA2: A do abort
+       protected fun proA2: A do abort
+       private fun priA2: A do abort
+
        var vpubA: nullable A is writable, noinit
        protected var vproA: nullable A is protected writable, noinit
        private var vpriA: nullable A is noinit
@@ -30,6 +34,10 @@ class A
        #alt2#protected fun proB(a: B) do end
        private fun priB(a: B) do end
 
+       #alt1#fun pubB2: B do abort
+       #alt2#protected fun proB2: B do abort
+       private fun priB2: B do abort
+
        #alt3#var vpubB: nullable B is writable, noinit
        #alt4#protected var vproB: nullable B is protected writable, noinit
        private var vpriB: nullable B is noinit
diff --git a/tests/bench_seq.nit b/tests/bench_seq.nit
new file mode 100644 (file)
index 0000000..8e83868
--- /dev/null
@@ -0,0 +1,42 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2005-2008 Jean Privat <jean@pryen.org>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import more_collections
+
+fun test_list(l: Sequence[Int], n: Int)
+do
+       for i in [0..n[ do l.push i
+       print "{l.length} {l.first} {l.last}"
+       for i in [0..n[ do l.unshift -i-1
+       print "{l.length} {l.first} {l.last}"
+       for i in [0..n[ do l.unshift l.pop
+       print "{l.length} {l.first} {l.last}"
+       for i in [0..n[ do l.push l.shift
+       print "{l.length} {l.first} {l.last}"
+       for i in [0..n[ do l[i] = l[n+i]
+       print "{l.length} {l.first} {l.last}"
+       for i in [0..n] do l.insert(i*10, i*2)
+       print "{l.length} {l.first} {l.last}"
+       print ""
+end
+
+var nb = 100
+if args.not_empty then nb = args.first.to_i
+
+test_list(new Array[Int], nb)
+test_list(new List[Int], nb)
+test_list(new UnrolledList[Int], nb)
+test_list(new CircularArray[Int], nb)
index c0428ae..4de2858 100644 (file)
@@ -7,3 +7,4 @@ langannot
 loops_infinite
 read_entire_file
 letter_frequency
+threadpool_example
index 6d747f4..30dc40c 100644 (file)
@@ -1 +1,2 @@
-alt/base_prot_sig_alt1.nit:29,14: Error: the public property `pubB` cannot contain the private type `B`.
+alt/base_prot_sig_alt1.nit:33,14: Error: the public property `pubB` cannot contain the private type `B`.
+alt/base_prot_sig_alt1.nit:37,13: Error: the public property `pubB2` cannot contain the private type `B`.
index e28956b..f31d97a 100644 (file)
@@ -1 +1,2 @@
-alt/base_prot_sig_alt2.nit:30,24: Error: the protected property `proB` cannot contain the private type `B`.
+alt/base_prot_sig_alt2.nit:34,24: Error: the protected property `proB` cannot contain the private type `B`.
+alt/base_prot_sig_alt2.nit:38,23: Error: the protected property `proB2` cannot contain the private type `B`.
index 6c32a28..aa019c0 100644 (file)
@@ -1,2 +1,2 @@
-alt/base_prot_sig_alt3.nit:33,13--22: Error: the public property `vpubB` cannot contain the private type `B`.
-alt/base_prot_sig_alt3.nit:33,13--22: Error: the public property `vpubB=` cannot contain the private type `B`.
+alt/base_prot_sig_alt3.nit:41,13--22: Error: the public property `vpubB` cannot contain the private type `B`.
+alt/base_prot_sig_alt3.nit:41,13--22: Error: the public property `vpubB=` cannot contain the private type `B`.
index 7a646cb..bb4255d 100644 (file)
@@ -1,2 +1,2 @@
-alt/base_prot_sig_alt4.nit:34,23--32: Error: the protected property `vproB` cannot contain the private type `B`.
-alt/base_prot_sig_alt4.nit:34,23--32: Error: the protected property `vproB=` cannot contain the private type `B`.
+alt/base_prot_sig_alt4.nit:42,23--32: Error: the protected property `vproB` cannot contain the private type `B`.
+alt/base_prot_sig_alt4.nit:42,23--32: Error: the protected property `vproB=` cannot contain the private type `B`.
index 01696e4..071db82 100644 (file)
@@ -1,2 +1,2 @@
-alt/base_prot_sig_alt5.nit:37,6--11: Error: the public property `vpubB2` cannot contain the private type `B`.
-alt/base_prot_sig_alt5.nit:37,6--11: Error: the public property `vpubB2=` cannot contain the private type `B`.
+alt/base_prot_sig_alt5.nit:45,6--11: Error: the public property `vpubB2` cannot contain the private type `B`.
+alt/base_prot_sig_alt5.nit:45,6--11: Error: the public property `vpubB2=` cannot contain the private type `B`.
index f129fb5..154d877 100644 (file)
@@ -1,2 +1,2 @@
-alt/base_prot_sig_alt6.nit:38,16--21: Error: the protected property `vproB2` cannot contain the private type `B`.
-alt/base_prot_sig_alt6.nit:38,16--21: Error: the protected property `vproB2=` cannot contain the private type `B`.
+alt/base_prot_sig_alt6.nit:46,16--21: Error: the protected property `vproB2` cannot contain the private type `B`.
+alt/base_prot_sig_alt6.nit:46,16--21: Error: the protected property `vproB2=` cannot contain the private type `B`.
index 1451e5f..786426c 100644 (file)
@@ -1,10 +1,10 @@
-alt/base_prot_sig_alt7.nit:46,2--10: Error: `private` is the only legal visibility for properties in a private class.
-alt/base_prot_sig_alt7.nit:50,2--10: Error: `private` is the only legal visibility for properties in a private class.
-alt/base_prot_sig_alt7.nit:50,37--45: Error: `private` is the only legal visibility for properties in a private class.
 alt/base_prot_sig_alt7.nit:54,2--10: Error: `private` is the only legal visibility for properties in a private class.
-alt/base_prot_sig_alt7.nit:54,34--42: Error: `private` is the only legal visibility for properties in a private class.
 alt/base_prot_sig_alt7.nit:58,2--10: Error: `private` is the only legal visibility for properties in a private class.
+alt/base_prot_sig_alt7.nit:58,37--45: Error: `private` is the only legal visibility for properties in a private class.
 alt/base_prot_sig_alt7.nit:62,2--10: Error: `private` is the only legal visibility for properties in a private class.
-alt/base_prot_sig_alt7.nit:62,37--45: Error: `private` is the only legal visibility for properties in a private class.
+alt/base_prot_sig_alt7.nit:62,34--42: Error: `private` is the only legal visibility for properties in a private class.
 alt/base_prot_sig_alt7.nit:66,2--10: Error: `private` is the only legal visibility for properties in a private class.
-alt/base_prot_sig_alt7.nit:66,34--42: Error: `private` is the only legal visibility for properties in a private class.
+alt/base_prot_sig_alt7.nit:70,2--10: Error: `private` is the only legal visibility for properties in a private class.
+alt/base_prot_sig_alt7.nit:70,37--45: Error: `private` is the only legal visibility for properties in a private class.
+alt/base_prot_sig_alt7.nit:74,2--10: Error: `private` is the only legal visibility for properties in a private class.
+alt/base_prot_sig_alt7.nit:74,34--42: Error: `private` is the only legal visibility for properties in a private class.
diff --git a/tests/sav/bench_seq.res b/tests/sav/bench_seq.res
new file mode 100644 (file)
index 0000000..d9c755c
--- /dev/null
@@ -0,0 +1,28 @@
+100 0 99
+200 -100 99
+200 0 -1
+200 -100 99
+200 0 99
+301 0 99
+
+100 0 99
+200 -100 99
+200 0 -1
+200 -100 99
+200 0 99
+301 0 99
+
+100 0 99
+200 -100 99
+200 0 -1
+200 -100 99
+200 0 99
+301 0 99
+
+100 0 99
+200 -100 99
+200 0 -1
+200 -100 99
+200 0 99
+301 0 99
+
index ec356da..9f86235 100644 (file)
@@ -78,7 +78,7 @@ Task [
 Object -> Task [dir=back arrowtail=open style=dashed];
 
 A [
- label = "{A|- _vpubA: nullable A\l- _vproA: nullable A\l- _vpriA: nullable A\l- _vpubA2: A\l- _vproA2: A\l- _vpriA2: A\l- _vpriB: nullable B\l- _vpriB2: B\l|+ pubA(a: A)\l# proA(a: A)\l- priA(a: A)\l+ vpubA(): nullable A\l+ vpubA=(vpubA: nullable A)\l# vproA(): nullable A\l# vproA=(vproA: nullable A)\l- vpriA(): nullable A\l- vpriA=(vpriA: nullable A)\l+ vpubA2(): A\l+ vpubA2=(vpubA2: A)\l# vproA2(): A\l# vproA2=(vproA2: A)\l- vpriA2(): A\l- vpriA2=(vpriA2: A)\l- priB(a: B)\l- vpriB(): nullable B\l- vpriB=(vpriB: nullable B)\l- vpriB2(): B\l- vpriB2=(vpriB2: B)\l}"
+ label = "{A|- _vpubA: nullable A\l- _vproA: nullable A\l- _vpriA: nullable A\l- _vpubA2: A\l- _vproA2: A\l- _vpriA2: A\l- _vpriB: nullable B\l- _vpriB2: B\l|+ pubA(a: A)\l# proA(a: A)\l- priA(a: A)\l+ pubA2(): A\l# proA2(): A\l- priA2(): A\l+ vpubA(): nullable A\l+ vpubA=(vpubA: nullable A)\l# vproA(): nullable A\l# vproA=(vproA: nullable A)\l- vpriA(): nullable A\l- vpriA=(vpriA: nullable A)\l+ vpubA2(): A\l+ vpubA2=(vpubA2: A)\l# vproA2(): A\l# vproA2=(vproA2: A)\l- vpriA2(): A\l- vpriA2=(vpriA2: A)\l- priB(a: B)\l- priB2(): B\l- vpriB(): nullable B\l- vpriB=(vpriB: nullable B)\l- vpriB2(): B\l- vpriB2=(vpriB2: B)\l}"
 ]
 Object -> A [dir=back arrowtail=open style=dashed];
 
index a87d928..c846cb7 100644 (file)
@@ -78,7 +78,7 @@ Task [
 Object -> Task [dir=back arrowtail=open style=dashed];
 
 A [
- label = "{A||+ pubA(a: A)\l+ vpubA(): nullable A\l+ vpubA=(vpubA: nullable A)\l+ vpubA2(): A\l+ vpubA2=(vpubA2: A)\l}"
+ label = "{A||+ pubA(a: A)\l+ pubA2(): A\l+ vpubA(): nullable A\l+ vpubA=(vpubA: nullable A)\l+ vpubA2(): A\l+ vpubA2=(vpubA2: A)\l}"
 ]
 Object -> A [dir=back arrowtail=open style=dashed];
 
index 458de3c..9e5ceab 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/core/collection/array.nit:960)
+Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/core/collection/array.nit:989)
 NativeString
 0x4e
 Nit
index 1de5fa0..c55a08b 100644 (file)
@@ -14,3 +14,7 @@ true
 true
 true
 
+true
+true
+true
+
index ff77897..40cfa68 100644 (file)
@@ -29,3 +29,4 @@ test_seq(new List[Int], new List[Int])
 test_seq(new Array[Int], new Array[Int])
 test_seq(new List[Int], new Array[Int])
 test_seq(new Array[Int], new List[Int])
+test_seq(new Array[Int], new CircularArray[Int])