Nitrpg was down since last wednesday because of this. It's now back on track: http://nitlanguage.org/rpg/games/privat/nit
Since the listener didn't crash, no data were loss during the downtime.
Pull-Request: #1604
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Jean Privat <jean@pryen.org>
check: bin/jwrapper tests/wildcards.javap
mkdir -p tmp
+ bin/jwrapper -v -u stub -o tests/statics.nit tests/statics.javap
+ ../../bin/nitpick -q tests/statics.nit
+ bin/jwrapper -v -u comment -o tests/generics.nit tests/generics.javap
+ ../../bin/nitpick -q tests/generics.nit
bin/jwrapper -v -u comment -o tests/long.nit tests/long.javap
../../bin/nitpick -q tests/long.nit
bin/jwrapper -v -u comment -o tests/inits.nit tests/inits.javap
bin/jwrapper -v -u comment -o tests/wildcards.nit tests/wildcards.javap
../../bin/nitpick -q tests/wildcards.nit
make -C examples/queue/ check
+ make -C examples/java_api/ check
check-libs: bin/jwrapper
# This config dependent rule must be tweaked according to each system
-android.nit
-std.nit
+android_api.nit
+java_api.nit
tmp/
java_api.nit:
mkdir -p tmp
- ../../bin/jwrapper -v -u comment -o java_api.nit -r "^java" $(ANDROID_JAR)
+ ../../bin/jwrapper -vv -u comment -o java_api.nit -r "^(java|javax|junit|org)" $(ANDROID_JAR) -i ../../../../lib/java/collections.nit
+ echo "+ Disabled functions: `grep '#\s*fun' $@ | wc -l` / `grep '^\s*fun' $@ | wc -l`"
android_api.nit: java_api.nit
- ../../bin/jwrapper -v -u comment -o android_api.nit -r "^android" -i java_api.nit $(ANDROID_JAR)
- echo "+ Disabled functions: `grep '# fun' $@ | wc -l` / `grep '^ fun' $@ | wc -l`"
+ ../../bin/jwrapper -vv -u comment -o android_api.nit -r "^(android|com.android)" -i java_api.nit $(ANDROID_JAR) -i ../../../../lib/java/collections.nit
+ echo "+ Disabled functions: `grep '#\s*fun' $@ | wc -l` / `grep '^\s*fun' $@ | wc -l`"
# Insert an import between the 2 modules
sed -i -e "s/import java/import java\nimport java_api/" android_api.nit
--- /dev/null
+java_api.nit
+api_user
+api_user.res
+api_user.jar
+tmp/
--- /dev/null
+RT_JAR ?= /usr/lib/jvm/default-java/jre/lib/rt.jar
+
+all: api_user
+
+java_api.nit:
+ mkdir -p tmp
+ ../../bin/jwrapper -vv -u comment -o java_api.nit $(RT_JAR) \
+ -r "^java.(lang|util|io)" -i ../../../../lib/java/collections.nit
+ echo "+ Disabled functions: `grep '#\s*fun' $@ | wc -l` / `grep '^\s*fun' $@ | wc -l`"
+
+api_user: java_api.nit
+ # Using --semi-global makes it much faster
+ time -f "%E k:%S u:%U" ../../../../bin/nitc -v api_user.nit --semi-global
+
+check: api_user
+ ./api_user > api_user.res
+ diff api_user.sav api_user.res
+
+check-more-java:
+ mkdir -p tmp
+ ../../bin/jwrapper -vv -u comment -o java_api.nit $(RT_JAR) \
+ -r "^(java|org)" -i ../../../../lib/java/collections.nit
+ echo "+ Disabled functions: `grep '#\s*fun' $@ | wc -l` / `grep '^\s*fun' $@ | wc -l`"
+
+ # This may take a while...
+ time -f "%E k:%S u:%U" ../../../../bin/nitc -v api_user.nit --no-cc
+
+ # Don't compile the C only the Java
+ make -C nit_compile Nit_rt.class
+
+.PHONY: api_user java_api.nit
--- /dev/null
+# 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.
+
+import java_api
+
+# Get a Java string
+var str = java_lang_integer_to_string_int(5678)
+
+# Do some Java side printing
+var stdout = java_lang_system_out
+stdout.println_int 1234
+stdout.println_String str
+
+# Test a generic list
+var list = new Java_util_ArrayList
+
+print list.is_empty
+assert list.is_empty
+
+print list.size
+assert list.size == 0
+
+list.clear
--- /dev/null
+1234
+5678
+true
+0
# Nit test program
-user_test: queue.nit $(shell ../../../../bin/nitls -M user_test.nit) ../../../../bin/nitc
+user_test: queue.nit $(shell ../../../../bin/nitls -M user_test.nit) ../../../../bin/nitc ../../bin/jwrapper
CLASSPATH=`pwd` ../../../../bin/nitc user_test.nit
# Manually add our class file to the Jar for easy access
| {head:} full_class_name;
generic_identifier
- = full_class_name
- | wildcard;
+ = {class:} full_class_name
+ | {wildcard:} wildcard;
full_class_name
= {tail:} full_class_name separator class_name
file_out.write "\n"
for key, jclass in model.classes do
+ # Skip anonymous classes
+ if jclass.class_type.is_anonymous then continue
+
+ # Skip classes with an invalid name at the Java language level
+ if jclass.class_type.extern_equivalent.has("-") then continue
generate_class_header(jclass.class_type)
for id, signatures in jclass.methods do
- for signature in signatures do
+ for signature in signatures do if not signature.is_static then
generate_method(jclass, id, id, signature.return_type, signature.params)
file_out.write "\n"
end
for constructor in jclass.constructors do
var complex = jclass.constructors.length != 1 and constructor.params.not_empty
var base_name = if complex then "from" else ""
- var name = jclass.nit_name_for(base_name, constructor.params, complex)
+ var name = jclass.nit_name_for(base_name, constructor.params, complex, false)
generate_constructor(jclass, constructor, name)
end
# Attributes
- for id, java_type in jclass.attributes do
- generate_getter_setter(jclass, id, java_type)
+ for id, attribute in jclass.attributes do if not attribute.is_static then
+ generate_getter_setter(jclass, id, attribute)
end
+ # JNI services
+ generate_jni_services jclass.class_type
+
+ # Close the class
file_out.write "end\n\n"
+
+ # Static functions as top-level methods
+ var static_functions_prefix = jclass.class_type.extern_name.to_snake_case
+ for id, signatures in jclass.methods do
+ for signature in signatures do if signature.is_static then
+ var nit_id = static_functions_prefix + "_" + id
+ generate_method(jclass, id, nit_id, signature.return_type, signature.params, is_static=true)
+ file_out.write "\n"
+ end
+ end
+
+ # Static attributes as top-level getters and setters
+ for id, attribute in jclass.attributes do if attribute.is_static then
+ generate_getter_setter(jclass, id, attribute)
+ end
+
+ # Primitive arrays
+ for d in [1..opt_arrays.value] do
+ generate_primitive_array(jclass, d)
+ end
end
if stub_for_unknown_types then
private fun generate_class_header(jtype: JavaType)
do
var nit_type = model.java_to_nit_type(jtype)
- file_out.write "# Java class: {jtype.to_package_name}\n"
- file_out.write "extern class {nit_type} in \"Java\" `\{ {jtype.to_package_name} `\}\n"
+ file_out.write "# Java class: {jtype}\n"
+ file_out.write "extern class {nit_type} in \"Java\" `\{ {jtype.extern_equivalent} `\}\n"
file_out.write "\tsuper JavaObject\n\n"
end
do
var nit_type = jtype.extern_name
- file_out.write "extern class {nit_type} in \"Java\" `\{ {jtype.to_package_name} `\}\n"
+ file_out.write "extern class {nit_type} in \"Java\" `\{ {jtype.extern_equivalent} `\}\n"
file_out.write "\tsuper JavaObject\n\nend\n"
end
- private fun generate_method(java_class: JavaClass, jmethod_id, method_id: String,
- jreturn_type: JavaType, jparam_list: Array[JavaType])
+ private fun generate_method(java_class: JavaClass, java_method_id, method_id: String,
+ java_return_type: JavaType, java_params: Array[JavaType], is_static: nullable Bool)
do
- var java_params = ""
- var nit_params = ""
+ var java_args = new Array[String]
+ var nit_params = new Array[String]
var nit_id = "arg"
var nit_id_no = 0
- var nit_types = new Array[NitType]
- var comment = ""
+ var c = ""
# Parameters
- for i in [0..jparam_list.length[ do
- var jparam = jparam_list[i]
+ for jparam in java_params do
var nit_type = model.java_to_nit_type(jparam)
- if not nit_type.is_known and comment_unknown_types then comment = "#"
- if jparam.is_primitive_array then comment = "#"
+ if not nit_type.is_known and comment_unknown_types then c = "#"
+ if jparam.is_vararg then c = "#"
- var cast = jparam.param_cast
-
- nit_types.add(nit_type)
-
- if i == jparam_list.length - 1 then
- java_params += "{cast}{nit_id}{nit_id_no}"
- nit_params += "{nit_id}{nit_id_no}: {nit_type}"
- else
- java_params += "{cast}{nit_id}{nit_id_no}" + ", "
- nit_params += "{nit_id}{nit_id_no}: {nit_type}, "
- end
+ java_args.add "{jparam.param_cast}{nit_id}{nit_id_no}"
+ nit_params.add "{nit_id}{nit_id_no}: {nit_type}"
nit_id_no += 1
end
- # Method documentation
- var doc = "\t# Java implementation: {java_class}.{jmethod_id}\n"
-
# Method identifier
method_id = method_id.to_nit_method_name
- method_id = java_class.nit_name_for(method_id, jparam_list, java_class.methods[jmethod_id].length > 1)
+ method_id = java_class.nit_name_for(method_id, java_params, java_class.methods[java_method_id].length > 1, is_static == true)
+
+ # Build the signature
var nit_signature = new Array[String]
+ nit_signature.add "fun {method_id}"
+ if not java_params.is_empty then nit_signature.add "({nit_params.join(", ")})"
+
+ # Return value
+ var return_type = null
+ if not java_return_type.is_void then
+ return_type = model.java_to_nit_type(java_return_type)
- nit_signature.add "\tfun {method_id}"
+ if not return_type.is_known and comment_unknown_types then c = "#"
+ if java_return_type.is_vararg then c = "#"
- if not jparam_list.is_empty then
- nit_signature.add "({nit_params})"
+ nit_signature.add ": " + return_type.to_s
end
- var return_type = null
- if not jreturn_type.is_void then
- return_type = model.java_to_nit_type(jreturn_type)
+ # Build the call in Java
+ var java_call
+ if is_static == true then
+ java_call = java_class.class_type.package_name
+ else java_call = "self"
+ java_call += ".{java_method_id}({java_args.join(", ")})"
- if not return_type.is_known and comment_unknown_types then comment = "#"
- if jreturn_type.is_primitive_array then comment = "#"
+ if return_type != null then java_call = "return {java_return_type.return_cast}" + java_call
- nit_signature.add ": {return_type} "
- end
+ # Tabulation
+ var t = "\t"
+ if is_static == true then t = ""
+ var ct = c+t
- file_out.write doc
- file_out.write comment + nit_signature.join
-
- if comment == "#" then
- file_out.write " in \"Java\" `\{\n{comment}\t\tself.{jmethod_id}({java_params});\n{comment}\t`\}\n"
- # Methods with return type
- else if return_type != null then
- file_out.write " in \"Java\" `\{\n{comment}\t\treturn {jreturn_type.return_cast}self.{jmethod_id}({java_params});\n{comment}\t`\}\n"
- # Methods without return type
- else if jreturn_type.is_void then
- file_out.write " in \"Java\" `\{\n{comment}\t\tself.{jmethod_id}({java_params});\n{comment}\t`\}\n"
- # No copy
- else
- file_out.write " in \"Java\" `\{\n{comment}\t\tself.{jmethod_id}({java_params});\n{comment}\t`\}\n"
- end
+ # Write
+ file_out.write """
+{{{t}}}# Java implementation: {{{java_return_type}}} {{{java_class}}}.{{{java_method_id}}}({{{java_params.join(", ")}}})
+{{{ct}}}{{{nit_signature.join}}} in "Java" `{
+{{{ct}}} {{{java_call}}};
+{{{ct}}}`}
+"""
end
# Generate getter and setter to access an attribute, of field
- private fun generate_getter_setter(java_class: JavaClass, java_id: String, java_type: JavaType)
+ private fun generate_getter_setter(java_class: JavaClass, java_id: String,
+ attribute: JavaAttribute)
do
+ var java_type = attribute.java_type
var nit_type = model.java_to_nit_type(java_type)
- var nit_id = java_id.to_nit_method_name
- nit_id = java_class.nit_name_for(nit_id, [java_type], false)
+
+ var nit_id = java_id
+ if attribute.is_static then nit_id = java_class.class_type.extern_name.to_snake_case + "_" + nit_id
+ nit_id = nit_id.to_nit_method_name
+ nit_id = java_class.nit_name_for(nit_id, [java_type], false, attribute.is_static)
var c = ""
if not nit_type.is_known and comment_unknown_types then c = "#"
- if java_type.is_primitive_array then c = "#"
+ if java_type.is_vararg then c = "#"
+
+ var recv
+ if attribute.is_static then
+ recv = java_class.class_type.package_name
+ else recv = "self"
+
+ # Tabulation
+ var t = "\t"
+ if attribute.is_static then t = ""
+ var ct = c+t
file_out.write """
- # Java getter: {{{java_class}}}.{{{java_id}}}
-{{{c}}} fun {{{nit_id}}}: {{{nit_type}}} in "Java" `{
-{{{c}}} return self.{{{java_id}}};
-{{{c}}} `}
+{{{t}}}# Java getter: {{{java_class}}}.{{{java_id}}}
+{{{ct}}}fun {{{nit_id}}}: {{{nit_type}}} in "Java" `{
+{{{ct}}} return {{{recv}}}.{{{java_id}}};
+{{{ct}}}`}
- # Java setter: {{{java_class}}}.{{{java_id}}}
-{{{c}}} fun {{{nit_id}}}=(value: {{{nit_type}}}) in "Java" `{
-{{{c}}} self.{{{java_id}}} = value;
-{{{c}}} `}
+{{{t}}}# Java setter: {{{java_class}}}.{{{java_id}}}
+{{{ct}}}fun {{{nit_id}}}=(value: {{{nit_type}}}) in "Java" `{
+{{{ct}}} {{{recv}}}.{{{java_id}}} = value;
+{{{ct}}}`}
"""
end
param_id = param_id.successor(1)
if not nit_type.is_known and comment_unknown_types then c = "#"
- if java_type.is_primitive_array then c = "#"
+ if java_type.is_vararg then c = "#"
end
nit_params_s = "(" + nit_params.join(", ") + ")"
file_out.write """
# Java constructor: {{{java_class}}}
{{{c}}} new {{{name}}}{{{nit_params_s}}} in "Java" `{
-{{{c}}} return new {{{java_class}}}({{{java_params_s}}});
+{{{c}}} return new {{{java_class.class_type.package_name}}}({{{java_params_s}}});
{{{c}}} `}
"""
end
+
+ private fun generate_primitive_array(java_class: JavaClass, dimensions: Int)
+ do
+ var base_java_type = java_class.class_type
+ var java_type = base_java_type.clone
+ java_type.array_dimension = dimensions
+
+ var base_nit_type = model.java_to_nit_type(base_java_type)
+ var nit_type = model.java_to_nit_type(java_type)
+
+ file_out.write """
+# Java primitive array: {{{java_type}}}
+extern class {{{nit_type}}} in "Java" `{ {{{java_type.extern_equivalent}}} `}
+ super AbstractJavaArray[{{{base_nit_type}}}]
+
+ # Get a new array of the given `size`
+ new(size: Int) in "Java" `{ return new {{{base_java_type}}}[(int)size]; `}
+
+ redef fun [](i) in "Java" `{ return self[(int)i]; `}
+
+ redef fun []=(i, e) in "Java" `{ self[(int)i] = e; `}
+
+ redef fun length in "Java" `{ return self.length; `}
+
+"""
+ generate_jni_services(java_type)
+ file_out.write """
+end
+
+"""
+ end
+
+ # Generate JNI related services
+ #
+ # For now, mostly avoid issue #845, but more services could be generated as needed.
+ private fun generate_jni_services(java_type: JavaType)
+ do
+ var nit_type = model.java_to_nit_type(java_type)
+
+ file_out.write """
+ redef fun new_global_ref import sys, Sys.jni_env `{
+ Sys sys = {{{nit_type}}}_sys(self);
+ JNIEnv *env = Sys_jni_env(sys);
+ return (*env)->NewGlobalRef(env, self);
+ `}
+
+ redef fun pop_from_local_frame_with_env(jni_env) `{
+ return (*jni_env)->PopLocalFrame(jni_env, self);
+ `}
+"""
+ end
end
redef class Sys
"protected", "public", "return", "self", "super", "then", "true", "type", "var", "while",
# Top-level methods
- "class_name", "get_time", "hash", "is_same_type", "is_same_instance", "output",
+ "class_name", "get_time", "hash", "inspect", "inspect_head", "is_same_type",
+ "is_same_instance", "object_id", "output", "output_class_name", "sys", "to_s",
# Pointer or JavaObject methods
"free"])
+
+ # Name of methods used at the top-level
+ #
+ # Used by `JavaClass::nit_name_for` with static properties.
+ private var top_level_used_names = new HashSet[String]
end
redef class String
redef class JavaClass
# Property names used in this class
- private var used_name = new HashSet[String]
+ private var used_names = new HashSet[String]
# Get an available property name for the Java property with `name` and parameters
#
# If `use_parameters_name` then expect that there will be conflicts,
# so use the types of `parameters` to build the name.
- private fun nit_name_for(name: String, parameters: Array[JavaType], use_parameters_name: Bool): String
+ private fun nit_name_for(name: String, parameters: Array[JavaType], use_parameters_name: Bool, is_static: Bool): String
do
# Append the name of each parameter
if use_parameters_name then
end
end
+ # Set of property names, local or top-level
+ var used_names
+ if is_static then
+ used_names = sys.top_level_used_names
+ else used_names = self.used_names
+
# As a last resort, append numbers to the name
var base_name = name
var count = 1
- while used_name.has(name) do
+ while used_names.has(name) do
name = base_name + count.to_s
count += 1
end
- used_name.add name
+ used_names.add name
return name
end
end
redef class Nproperty_declaration_method
redef fun accept_visitor(v)
do
+ var is_static = false
+ var modifiers = n_modifier
+ if modifiers != null then is_static = modifiers.has_static
+
var id = n_identifier.text
var return_jtype = n_type.to_java_type
+ # Generic parameters
+ var n_params = n_generic_parameters
+ var generic_params
+ if n_params != null then
+ generic_params = n_params.n_parameters.to_a
+ else generic_params = new Array[JavaType]
+
# Collect parameters
var n_parameters = n_parameters
var params
params = n_parameters.to_a
else params = new Array[JavaType]
- var method = new JavaMethod(return_jtype, params)
+ var method = new JavaMethod(is_static, return_jtype, params, generic_params)
v.java_class.methods[id].add method
end
end
params = n_parameters.to_a
else params = new Array[JavaType]
- var method = new JavaConstructor(params)
+ # Generic parameters
+ var n_params = n_generic_parameters
+ var generic_params
+ if n_params != null then
+ generic_params = n_params.n_parameters.to_a
+ else generic_params = new Array[JavaType]
+
+ var method = new JavaConstructor(params, generic_params)
v.java_class.constructors.add method
end
end
var brackets = n_brackets
if brackets != null then jtype.array_dimension += brackets.children.length
- v.java_class.attributes[id] = jtype
+ var is_static = false
+ var modifiers = n_modifier
+ if modifiers != null then is_static = modifiers.has_static
+
+ v.java_class.attributes[id] = new JavaAttribute(is_static, jtype)
end
end
private fun to_java_type: JavaType
do
# By default, everything is bound by object
- # TODO use a more precise bound
var jtype = new JavaType
jtype.identifier.add_all(["java", "lang", "object"])
return jtype
end
end
+redef class Nbase_type_extends
+ redef fun to_java_type do return n_generic_identifier.to_java_type
+end
+
+redef class Nbase_type_super
+ redef fun to_java_type
+ do
+ var bounds = n_type_bound.to_a
+
+ # Java use more than one lower bound,
+ # it can't be translated statically to Nit,
+ # so we use the only the first one.
+ # This may cause problems on complex generic types,
+ # but these cases can be handled manually.
+ return bounds.first
+ end
+end
+
+redef class Ngeneric_identifier
+ private fun to_java_type: JavaType is abstract
+end
+
+redef class Ngeneric_identifier_class
+ redef fun to_java_type do return n_full_class_name.to_java_type
+end
+
+redef class Ngeneric_identifier_wildcard
+ redef fun to_java_type
+ do
+ var jtype = new JavaType
+ jtype.identifier.add_all(["java", "lang", "Object"])
+ return jtype
+ end
+end
+
redef class Nfull_class_name
# All the identifiers composing this class name
private fun to_a: Array[String] is abstract
return jtype
end
end
+
+redef class Nodes
+ private fun has_static: Bool
+ do
+ for modifier in depth do
+ if modifier isa NToken and modifier.text == "static" then return true
+ end
+
+ return false
+ end
+end
+
+redef class Ntype_bound
+ # Get the types composing this bound
+ private fun to_a: Array[JavaType] is abstract
+end
+
+redef class Ntype_bound_head
+ redef fun to_a do return [n_full_class_name.to_java_type]
+end
+
+redef class Ntype_bound_tail
+ redef fun to_a
+ do
+ var a = n_type_bound.to_a
+ a.add n_full_class_name.to_java_type
+ return a
+ end
+end
var opt_regex = new OptionString("Regex pattern to filter classes in Jar archives", "-r")
var opt_help = new OptionBool("Show this help message", "-h", "--help")
-opts.add_option(opt_output, opt_unknown, opt_extern_class_prefix, opt_libs, opt_regex, opt_cast_objects, opt_verbose, opt_help)
+opts.add_option(opt_output, opt_unknown, opt_extern_class_prefix, opt_libs, opt_regex, opt_cast_objects, opt_arrays, opt_verbose, opt_help)
opts.parse args
if opts.errors.not_empty or opts.rest.is_empty or opt_help.value then
visitor.enter_visit root_node
sys.perfs["core model"].add clock.lapse
+model.resolve_types
+sys.perfs["core resolve"].add clock.lapse
+
if opt_verbose.value > 0 then print "# Generating Nit code"
var use_comment = opt_unknown.value == 0
if opt_verbose.value > 1 then
print "# Performance Analysis:"
print sys.perfs
+
+ print "# {model.unknown_types.length} unknown types:"
+ var c = 0
+ for id, ntype in model.unknown_types do
+ print "* {id}"
+ c += 1
+ if c > 100 then
+ print "* ..."
+ break
+ end
+ end
end
import jtype_converter
class JavaType
+ super Cloneable
+
+ # Identifiers composing the namespace and class name
+ #
+ # An array of all the names that would be separated by `.`.
+ # Each name may contain `$`.
var identifier = new Array[String]
+
var generic_params: nullable Array[JavaType] = null
# Is this a void return type?
# Is this type a vararg?
var is_vararg = false is writable
+ # Is this type based on an anonymous class?
+ var is_anonymous: Bool is lazy do
+ for id in identifier do
+ for part in id.split("$") do
+ if part.chars.first.is_digit then return true
+ end
+ end
+ return false
+ end
+
# Has some generic type to be resolved (T extends foo => T is resolved to foo)
var has_unresolved_types = false
fun is_primitive_array: Bool do return array_dimension > 0
fun has_generic_params: Bool do return not generic_params == null
- fun full_id: String do return identifier.join(".")
- fun id: String do return identifier.last.replace("$", "")
fun return_cast: String do return converter.cast_as_return(self.id)
name = prefix + id
end
+ if is_primitive_array then
+ name += "_" + "Array" * array_dimension
+ end
+
name = name.replace("-", "_")
name = name.replace("$", "_")
return name
end
- redef fun to_s
- do
- var id = self.full_id
+ # Short name of the class, mangled to remove `$` (e.g. `Set`)
+ fun id: String do return identifier.last.replace("$", "")
+
+ # Full name of this class as used in an importation (e.g. `java.lang.Set`)
+ fun package_name: String do return identifier.join(".")
+
+ # Name of this class for the extern declaration in Nit (e.g. `java.lang.Set[]`)
+ fun extern_equivalent: String do return package_name + "[]" * array_dimension
+
+ # Full name of this class with arrays and generic values (e.g. `java.lang.Set<E>[]`)
+ redef fun to_s do
+ var id = self.package_name
if self.is_primitive_array then
id += "[]" * array_dimension
return id
end
- # To fully qualified package name
- # Cuts the primitive array `[]`
- fun to_package_name: String
+ # Get a copy of `self`
+ redef fun clone
do
- var str = self.to_s
- var len = str.length
-
- return str.substring(0, len - (2*array_dimension))
- end
-
- fun resolve_types(conversion_map: HashMap[String, Array[String]])
- do
- if identifier.length == 1 then
- var resolved_id = conversion_map.get_or_null(self.id)
- if resolved_id != null then self.identifier = new Array[String].from(resolved_id)
- end
-
- if self.has_generic_params then
- for params in generic_params do params.resolve_types(conversion_map)
- end
+ var jtype = new JavaType
+ jtype.identifier = identifier
+ jtype.generic_params = generic_params
+ jtype.is_void = is_void
+ jtype.is_vararg = is_vararg
+ jtype.array_dimension = array_dimension
+ return jtype
end
# Comparison based on fully qualified named
redef fun ==(other) do return other isa JavaType and
- self.full_id == other.full_id and
- self.is_primitive_array == other.is_primitive_array
+ self.package_name == other.package_name and
+ self.array_dimension == other.array_dimension
- redef fun hash do return self.full_id.hash
+ redef fun hash do return self.package_name.hash
end
class NitType
var class_type: JavaType
# Attributes of this class
- var attributes = new HashMap[String, JavaType]
+ var attributes = new HashMap[String, JavaAttribute]
# Methods of this class organized by their name
var methods = new MultiHashMap[String, JavaMethod]
var imports = new HashSet[NitModule]
redef fun to_s do return class_type.to_s
+
+ # Resolve the types in `other` in the context of this class
+ private fun resolve_types_of(other: JavaClass)
+ do
+ # Methods
+ for mid, method in other.methods do
+ for signature in method do
+ self.resolve(signature.return_type, signature.generic_params)
+ for param in signature.params do self.resolve(param, signature.generic_params)
+ end
+ end
+
+ # Constructors
+ for signature in other.constructors do
+ for param in signature.params do self.resolve(param, signature.generic_params)
+ end
+
+ # Attributes
+ for aid, attribute in other.attributes do
+ self.resolve attribute.java_type
+ end
+ end
+
+ # Resolve `java_type` in the context of this class
+ #
+ # Replace, in place, parameter types by their bound.
+ private fun resolve(java_type: JavaType, property_generic_params: nullable Array[JavaType])
+ do
+ # Skip types with a full package name
+ if java_type.identifier.length != 1 then return
+
+ # Skip primitive types
+ if converter.type_map.keys.has(java_type.id) then return
+
+ # Gather the generic parameters of the method, then the class
+ var params = new Array[JavaType]
+ if property_generic_params != null then params.add_all property_generic_params
+ var class_generic_params = class_type.generic_params
+ if class_generic_params != null then params.add_all class_generic_params
+
+ # Skip if there is not parameters usable to resolve
+ if params.is_empty then return
+
+ for param in params do
+ if param.identifier == java_type.identifier then
+ # Found a marching parameter type
+ # TODO use a more precise bound
+ java_type.identifier = ["java", "lang", "Object"]
+ return
+ end
+ end
+ end
end
# Model of all the Java class analyzed in one run
# Add a class in `classes`
fun add_class(jclass: JavaClass)
do
- var key = jclass.class_type.full_id
+ var key = jclass.class_type.package_name
classes[key] = jclass
end
# Unknown types, not already wrapped and not in this pass
- private var unknown_types = new HashMap[JavaType, NitType]
+ var unknown_types = new HashMap[JavaType, NitType]
# Wrapped types, or classes analyzed in this pass
- private var known_types = new HashMap[JavaType, NitType]
+ var known_types = new HashMap[JavaType, NitType]
# Get the `NitType` corresponding to the `JavaType`
#
end
# Is being wrapped in this pass?
- var key = jtype.full_id
+ var key = jtype.package_name
if classes.keys.has(key) then
- var nit_type = new NitType(jtype.extern_name)
- known_types[jtype] = nit_type
-
- return nit_type
+ if jtype.array_dimension <= opt_arrays.value then
+ var nit_type = new NitType(jtype.extern_name)
+ known_types[jtype] = nit_type
+ return nit_type
+ end
end
# Search in lib
- var nit_type = find_extern_class[jtype.full_id]
+ var nit_type = find_extern_class[jtype.extern_equivalent]
if nit_type != null then
known_types[jtype] = nit_type
return nit_type
unknown_types[jtype] = nit_type
return nit_type
end
+
+ # Resolve the types in methods and attributes of this class
+ fun resolve_types
+ do
+ for id, java_class in classes do
+ java_class.resolve_types_of java_class
+
+ # Ask nester classes for resolve too
+ var matches = id.search_all("$")
+ for match in matches do
+ var nester_name = id.substring(0, match.from)
+ if classes.keys.has(nester_name) then
+ var nester = classes[nester_name]
+ nester.resolve_types_of java_class
+ end
+ end
+ end
+ end
+end
+
+# A property to a Java class
+abstract class JavaProperty
+
+ # Is this property marked static?
+ var is_static: Bool
end
# A Java method, with its signature
class JavaMethod
+ super JavaProperty
+
# Type returned by the method
var return_type: JavaType
# Type of the arguments of the method
var params: Array[JavaType]
+
+ # Generic parameters of this method
+ var generic_params: Array[JavaType]
+end
+
+# An attribute in a Java class
+class JavaAttribute
+ super JavaProperty
+
+ # Type of the attribute
+ var java_type: JavaType
end
# A Java method, with its signature
class JavaConstructor
# Type of the parameters of this constructor
var params: Array[JavaType]
+
+ # Generic parameters of this constructor
+ var generic_params: Array[JavaType]
end
# A Nit module, use to import the referenced extern classes
redef class Sys
# Collection of Java classes already wrapped in the library
#
- # * The key is from `JavaType.full_id`.
+ # * The key uses `JavaType.to_s`.
# * The value is the corresponding `NitType`.
var find_extern_class: DefaultMap[String, nullable NitType] is lazy do
var map = new DefaultMap[String, nullable NitType](null)
grep.wait
# Sort out the modules, Nit class names and Java types
- var regex = """(.+):\\s*extern +class +([a-zA-Z0-9_]+) *in *"Java" *`\\{ *([a-zA-Z0-9.$/]+) *`\\}""".to_re
+ var regex = """(.+):\\s*extern +class +([a-zA-Z0-9_]+) *in *"Java" *`\\{(.+)`\\}""".to_re
for line in lines do
var matches = line.search_all(regex)
for match in matches do
var path = match[1].to_s
var nit_name = match[2].to_s
- var java_name = match[3].to_s
+ var java_name = match[3].to_s.trim
# Debug code
- # print "+ Found {nit_name}:{java_name} at {path}"
+ # print "+ Found {nit_name}: {java_name} at {path}"
var mod = modules.get_or_null(path)
if mod == null then
# Libraries to search for existing wrappers
var opt_libs = new OptionArray("Paths to libraries with wrappers of Java classes ('auto' to use the full Nit lib)", "-i")
+
+ # Generate the primitive array version of each class up to the given depth
+ var opt_arrays = new OptionInt("Depth of the primitive array for each wrapped class (default: 1)", 1, "-a")
end
redef class Text
--- /dev/null
+public abstract class android.os.asynctask<params, progress, result> {
+ public android.os.asynctask();
+ public final android.os.asynctask$status getstatus();
+ public final result get(long, java.util.concurrent.timeunit) throws java.lang.interruptedexception, java.util.concurrent.executionexception, java.util.concurrent.timeoutexception;
+ public final android.os.asynctask<params, progress, result> execute(params...);
+}
--- /dev/null
+public final class com.oracle.net.Sdp {
+ public static java.net.Socket openSocket() throws java.io.IOException;
+ public static java.net.ServerSocket openServerSocket() throws java.io.IOException;
+ public static java.nio.channels.SocketChannel openSocketChannel() throws java.io.IOException;
+ public static java.nio.channels.ServerSocketChannel openServerSocketChannel() throws java.io.IOException;
+}
+public class com.sun.activation.registries.LogSupport {
+ public static void log(java.lang.String);
+ public static void log(java.lang.String, java.lang.Throwable);
+ public static boolean isLoggable();
+}
+public class com.sun.activation.registries.MailcapTokenizer {
+ public static final int UNKNOWN_TOKEN;
+}
+public final class com.sun.beans.TypeResolver {
+ public com.sun.beans.TypeResolver();
+ public static java.lang.reflect.Type resolveInClass(java.lang.Class<?>, java.lang.reflect.Type);
+}
# XML tag used for pattern recognition
fun tag_title: String do return "title"
+ # XML tag of the link to act upon
+ fun tag_link: String do return "link"
+
+ # Are the feeds at `rss_source_urls` compressed?
+ var compressed: nullable Bool
+
# Action to apply on each selected RSS element
fun act_on(element: Element)
do
var elements = new HashSet[Element]
for rss_url in config.rss_source_urls do
var rss = rss_url.fetch_rss_content
+ if config.compressed == true then rss = rss.gunzip
elements.add_all rss.to_rss_elements
end
if sys.verbose then
print "\n# {matches.length} matching elements:"
- print matches.join("\n")
+ print "* " + matches.join("\n* ")
print "\n# Downloading..."
end
# Do not download a file that is not unique according to `unique_id`
if not element.is_unique_exception(config) then
# We make some exceptions
- if sys.verbose then print "File in log, skipping {element}"
+ if sys.verbose then print "- Skipping {element}"
continue
end
end
# Download element
- if sys.verbose then print "Acting on {element}"
+ if sys.verbose then print "+ Acting on {element}"
tool_config.act_on element
fun to_rss_elements: Array[Element]
do
var xml = to_xml
+ if xml isa XMLError then
+ print_error "RSS Parse Error: {xml.message}:{xml.location or else "null"}"
+ return new Array[Element]
+ end
var items = xml["rss"].first["channel"].first["item"]
var elements = new Array[Element]
for item in items do
var title = item[tool_config.tag_title].first.as(XMLStartTag).data
- var link = item["link"].first.as(XMLStartTag).data
+ var link = item[tool_config.tag_link].first.as(XMLStartTag).data
elements.add new Element(title, link)
end
if sys.verbose then
print "# Found elements:"
- print elements.join("\n")
+ print "* " + elements.join("\n* ")
end
return elements
end
+
+ # Expand the Lempel-Ziv encoded `self`
+ fun gunzip: String
+ do
+ var proc = new ProcessDuplex("gunzip", new Array[String]...)
+ var res = proc.write_and_read(self)
+ assert proc.status == 0 else print_error "gunzip failed: {proc.last_error or else "Unknown"}"
+ return res
+ end
end
# Implement this method in your module to configure this tool
# limitations under the License.
# Android audio services, wraps a part of android audio API
+# This module modifies the default behaviour of the audio loading:
+# It is first loaded from the `res/raw` folder.
+# The file extension is not needed for the `res/raw` loading part.
+# If it didn't work, it is loaded from the `assets` folder.
+# The file extension is needed for the `assets` loading part.
+#
+# `assets` contains the portable version of sounds, since the `res` folder exsists only in android projects.
#
# For this example, the sounds "test_sound" and "test_music" are located in the "assets/sounds" folder,
# they both have ".ogg" extension. "test_sound" is a short sound and "test_music" a music track
redef fun load do
if is_loaded then return
- var nam = app.asset_manager.open_fd(self.name)
- if nam.is_java_null then
- self.error = new Error("Failed to get file descriptor for " + self.name)
- var retval_resources = app.default_soundpool.load_name_rid(app.resource_manager, app.native_activity, self.name)
- if retval_resources == -1 then
- self.error = new Error("Failed to load" + self.name)
+ var retval_resources = app.default_soundpool.load_name_rid(app.resource_manager, app.native_activity, self.name.strip_extension)
+ if retval_resources == -1 then
+ self.error = new Error("failed to load" + self.name)
+ var nam = app.asset_manager.open_fd(self.name)
+ if nam.is_java_null then
+ self.error = new Error("Failed to get file descriptor for " + self.name)
else
- self.soundpool_id = retval_resources
- self.soundpool = app.default_soundpool
- self.error = null
- self.soundpool.error = null
+ var retval_assets = app.default_soundpool.load_asset_fd_rid(nam)
+ if retval_assets == -1 then
+ self.error = new Error("Failed to load" + self.name)
+ else
+ self.soundpool_id = retval_assets
+ self.soundpool = app.default_soundpool
+ self.error = null
+ self.soundpool.error = null
+ end
end
else
- var retval_assets = app.default_soundpool.load_asset_fd_rid(nam)
- if retval_assets == -1 then
- self.error = new Error("Failed to load" + self.name)
- else
- self.soundpool_id = retval_assets
- self.soundpool = app.default_soundpool
- self.error = null
- self.soundpool.error = null
- end
+ self.soundpool_id = retval_resources
+ self.soundpool = app.default_soundpool
+ self.error = null
+ self.soundpool.error = null
end
is_loaded = true
end
redef fun load do
if is_loaded then return
- var nam = app.asset_manager.open_fd(self.name)
- if nam.is_java_null then
- self.error = new Error("Failed to get file descriptor for " + self.name)
- var mp_sound_resources = app.default_mediaplayer.load_sound(app.resource_manager.raw_id(self.name), app.native_activity)
- if mp_sound_resources.error != null then
- self.error = mp_sound_resources.error
+ var mp_sound_resources = app.default_mediaplayer.load_sound(app.resource_manager.raw_id(self.name.strip_extension), app.native_activity)
+ if mp_sound_resources.error != null then
+ self.error = mp_sound_resources.error
+ var nam = app.asset_manager.open_fd(self.name)
+ if nam.is_java_null then
+ self.error = new Error("Failed to get file descriptor for " + self.name)
else
- self.media_player = app.default_mediaplayer
- self.error = null
- self.media_player.error = null
+ var mp_sound_assets = app.default_mediaplayer.data_source_fd(nam)
+ if mp_sound_assets.error != null then
+ self.error = mp_sound_assets.error
+ else
+ self.media_player = app.default_mediaplayer
+ self.error = null
+ self.media_player.error = null
+ end
end
else
- var mp_sound_assets = app.default_mediaplayer.data_source_fd(nam)
- if mp_sound_assets.error != null then
- self.error = mp_sound_assets.error
- else
- self.media_player = app.default_mediaplayer
- self.error = null
- self.media_player.error = null
- end
+ self.media_player = app.default_mediaplayer
+ self.error = null
+ self.media_player.error = null
end
is_loaded = true
end
# Retrieves a music with a media player in the `assets` folder using its name.
# Used to play long sounds or musics, can't play multiple sounds simultaneously
- redef fun load_music(path: String): Music do
+ redef fun load_music(path) do
var fd = asset_manager.open_fd(path)
if not fd.is_java_null then
return add_to_sounds(default_mediaplayer.data_source_fd(fd)).as(Music)
# limitations under the License.
# App audio abstraction
+# Default behaviour is loading the audio from the `assets` folder of the project with its name and extension
+# Platforms implementations can modify this comportement
#
# Once the application has started (after `App.setup`)
# use `App.load_sound` to get a sound
# Is this already loaded ?
protected var is_loaded = false is writable
- # load this playable audio
+ # Load this playable audio
fun load is abstract
# Plays the sound
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# This file is free software, which comes along with NIT. This software is
+# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. You can modify it is you want, provided this header
+# is kept unaltered, and a notification of the changes is added.
+# You are allowed to redistribute it and sell it, alone or is a part of
+# another product.
+
+# Simple XML validity checker using the `dom` module
+module checker
+
+import dom
+
+# Check arguments
+if args.length != 1 then
+ print_error "Usage: checker xml_file"
+ exit 2
+end
+
+var path = args.first
+if not path.file_exists then
+ print_error "Path '{path}' does not exist"
+ exit 3
+end
+
+# Read file
+var content = path.to_path.read_all
+
+# Parse XML
+var xml = content.to_xml
+
+# Check for errors
+if xml isa XMLError then
+ print_error "XML file at '{path}' is invalid:"
+ print_error xml.message
+ var loc = xml.location
+ if loc != null then print_error loc
+ exit 1
+else
+ print "XML file at '{path}' is valid"
+end
--- /dev/null
+# 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.
+
+# Supporting services for the FFI with Java
+#
+# This modules relies on `Sys::jvm`, `Sys::jni_env` and
+# `Sys::create_default_jvm` to get a handle on a JVM. You can adapt the
+# behavior of the FFI and services in this module by redefing
+# `Sys::create_default_jvm` and supply your own JVM object. You can manage
+# multiple java thread by switching the current environment in a redef
+# of `Sys::jni_env`, and multiple JVM using `Sys::jvm`.
+module base is
+ cflags "-I $(JAVA_HOME)/include/ -I $(JAVA_HOME)/include/linux/"
+ ldflags "-L $(JNI_LIB_PATH) -ljvm"
+ new_annotation extra_java_files
+end
+
+import jvm
+
+redef class Sys
+ private var jvm_cache: nullable JavaVM = null
+ private var jni_env_cache: nullable JniEnv = null
+
+ # Default Java Virtual Machine to use (will be instantiated using
+ # `create_default_jvm` if not already set)
+ fun jvm: JavaVM
+ do
+ if jvm_cache == null then create_default_jvm
+ return jvm_cache.as(not null)
+ end
+
+ # Sets the current default Java Virtual Machine (use with `jni_env=`)
+ fun jvm=(jvm: JavaVM) do jvm_cache = jvm
+
+ # Current main `JniEnv`
+ fun jni_env: JniEnv
+ do
+ if jni_env_cache == null then create_default_jvm
+ return jni_env_cache.as(not null)
+ end
+
+ # Sets the current default JNI env (use with `jvm=`)
+ fun jni_env=(jni_env: JniEnv) do jni_env_cache = jni_env
+
+ # Called by `jvm` and `jni_env` to instantiate a Java Virtual Machine.
+ # Used mostly for the FFI with Java.
+ protected fun create_default_jvm
+ do
+ var builder = new JavaVMBuilder
+
+ # By default, look for Java classes in a jar file the same directory as the executable
+ builder.options.add "-Djava.class.path={sys.program_name}.jar"
+
+ var jvm = builder.create_jvm
+ assert jvm != null else print "JVM creation failed"
+
+ self.jvm = jvm
+ self.jni_env = builder.jni_env.as(not null)
+ end
+
+ # Get a Java class by its name from the current `jni_env`
+ fun load_jclass(name: NativeString): JClass import jni_env `{
+ JNIEnv *nit_ffi_jni_env = Sys_jni_env(self);
+
+ // retrieve the implementation Java class
+ jclass java_class = (*nit_ffi_jni_env)->FindClass(nit_ffi_jni_env, name);
+ if (java_class == NULL) {
+ fprintf(stderr, "Nit FFI with Java error: failed to load class.\\n");
+ (*nit_ffi_jni_env)->ExceptionDescribe(nit_ffi_jni_env);
+ exit(1);
+ }
+
+ return java_class;
+ `}
+end
+
+# A standard Java string `java.lang.String`
+#
+# Converted to a Nit string using `to_s`, or to a C string with `to_cstring`.
+# Created using `String::to_java_string` or `NativeString::to_java_string`.
+extern class JavaString in "Java" `{ java.lang.String `}
+ super JavaObject
+
+ # Get the string from Java and copy it to Nit memory
+ fun to_cstring: NativeString import sys, Sys.jni_env `{
+ Sys sys = JavaString_sys(self);
+ JNIEnv *env = Sys_jni_env(sys);
+
+ // Get the data from Java
+ const char *java_cstr = (*env)->GetStringUTFChars(env, self, NULL);
+ jsize len = (*env)->GetStringUTFLength(env, self);
+
+ // Copy it in control of Nit
+ char *nit_cstr = (char*)malloc(len+1);
+ memcpy(nit_cstr, java_cstr, len);
+ nit_cstr[len] = '\0';
+
+ // Free JNI ref and return
+ (*env)->ReleaseStringUTFChars(env, self, java_cstr);
+ return nit_cstr;
+ `}
+
+ redef fun to_s do return to_cstring.to_s
+end
+
+redef class NativeString
+ # Get a Java string from this C string
+ #
+ # This instance is only valid until the next execution of Java code.
+ # You can use `new_local_ref` to keep it longer.
+ fun to_java_string: JavaString import sys, Sys.jni_env `{
+ Sys sys = JavaString_sys(self);
+ JNIEnv *env = Sys_jni_env(sys);
+ return (*env)->NewStringUTF(env, self);
+ `}
+end
+
+redef class Text
+ # Get `self` as a `JavaString`
+ fun to_java_string: JavaString do return to_cstring.to_java_string
+end
+
+redef extern class JavaObject
+
+ # Returns a global reference to the Java object behind this reference
+ #
+ # You must use a global reference when keeping a Java object
+ # across execution of Java code, per JNI specification.
+ fun new_global_ref: SELF import sys, Sys.jni_env `{
+ Sys sys = JavaObject_sys(self);
+ JNIEnv *env = Sys_jni_env(sys);
+ return (*env)->NewGlobalRef(env, self);
+ `}
+
+ # Delete this global reference
+ fun delete_global_ref import sys, Sys.jni_env `{
+ Sys sys = JavaObject_sys(self);
+ JNIEnv *env = Sys_jni_env(sys);
+ (*env)->DeleteGlobalRef(env, self);
+ `}
+
+ # Delete this local reference
+ fun delete_local_ref import sys, Sys.jni_env `{
+ Sys sys = JavaObject_sys(self);
+ JNIEnv *env = Sys_jni_env(sys);
+ (*env)->DeleteLocalRef(env, self);
+ `}
+
+ # Pops the current local reference frame and return a valid reference to self
+ #
+ # Similar to `JavaVM::pop_local_frame` but returns a value.
+ fun pop_from_local_frame: SELF
+ do
+ var jni_env = sys.jni_env
+ return pop_from_local_frame_with_env(jni_env)
+ end
+
+ # Java implementation of `pop_from_local_frame`
+ protected fun pop_from_local_frame_with_env(jni_env: JniEnv): SELF `{
+ return (*jni_env)->PopLocalFrame(jni_env, self);
+ `}
+
+ # Is `self` null in Java?
+ #
+ # Since Java type system doesn't have the same `nullable` concept as Nit's,
+ # the two systems are not directly compatible. Any Nit instances of
+ # `JavaObject` may hold a Java null.
+ #
+ # To benefit from the safer type system of Nit, it is recommended to check
+ # the return of all extern methods implemented in Java to ensure the value
+ # is not a Java null. In case it is, you should replace it by a normal Nit
+ # `null`.
+ fun is_java_null: Bool in "Java" `{ return self == null; `}
+
+ # `JavaString` representation of `self` using Java's `toString`
+ fun to_java_string: JavaString in "Java" `{ return self.toString(); `}
+
+ # Use Java's `toString` for any `JavaObject`
+ redef fun to_s
+ do
+ if is_java_null then return super
+ return to_java_string.to_s
+ end
+end
# ~~~
module collections
-import java
+import base
# Java primitive array
#
# This module is used by `android::assets_and_resources` and `android::audio`.
module io
-import java
+import base
in "Java" `{
import java.io.File;
# This file is part of NIT ( http://www.nitlanguage.org ).
#
-# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
# 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
# The module `jvm` gives more control over the JVM instances and wraps
# most of JNI functions. You can use it to further customize the behavior
# of your code.
-module java is
- cflags "-I $(JAVA_HOME)/include/ -I $(JAVA_HOME)/include/linux/"
- ldflags "-L $(JNI_LIB_PATH) -ljvm"
- new_annotation extra_java_files
-end
-
-import jvm
-
-redef class Sys
- private var jvm_cache: nullable JavaVM = null
- private var jni_env_cache: nullable JniEnv = null
-
- # Default Java Virtual Machine to use (will be instantiated using
- # `create_default_jvm` if not already set)
- fun jvm: JavaVM
- do
- if jvm_cache == null then create_default_jvm
- return jvm_cache.as(not null)
- end
-
- # Sets the current default Java Virtual Machine (use with `jni_env=`)
- fun jvm=(jvm: JavaVM) do jvm_cache = jvm
-
- # Current main `JniEnv`
- fun jni_env: JniEnv
- do
- if jni_env_cache == null then create_default_jvm
- return jni_env_cache.as(not null)
- end
-
- # Sets the current default JNI env (use with `jvm=`)
- fun jni_env=(jni_env: JniEnv) do jni_env_cache = jni_env
-
- # Called by `jvm` and `jni_env` to instantiate a Java Virtual Machine.
- # Used mostly for the FFI with Java.
- protected fun create_default_jvm
- do
- var builder = new JavaVMBuilder
-
- # By default, look for Java classes in a jar file the same directory as the executable
- builder.options.add "-Djava.class.path={sys.program_name}.jar"
-
- var jvm = builder.create_jvm
- assert jvm != null else print "JVM creation failed"
-
- self.jvm = jvm
- self.jni_env = builder.jni_env.as(not null)
- end
-
- # Get a Java class by its name from the current `jni_env`
- fun load_jclass(name: NativeString): JClass import jni_env `{
- JNIEnv *nit_ffi_jni_env = Sys_jni_env(self);
-
- // retrieve the implementation Java class
- jclass java_class = (*nit_ffi_jni_env)->FindClass(nit_ffi_jni_env, name);
- if (java_class == NULL) {
- fprintf(stderr, "Nit FFI with Java error: failed to load class.\\n");
- (*nit_ffi_jni_env)->ExceptionDescribe(nit_ffi_jni_env);
- exit(1);
- }
-
- return java_class;
- `}
-end
-
-# A standard Java string `java.lang.String`
-#
-# Converted to a Nit string using `to_s`, or to a C string with `to_cstring`.
-# Created using `String::to_java_string` or `NativeString::to_java_string`.
-extern class JavaString in "Java" `{ java.lang.String `}
- super JavaObject
-
- # Get the string from Java and copy it to Nit memory
- fun to_cstring: NativeString import sys, Sys.jni_env `{
- Sys sys = JavaString_sys(self);
- JNIEnv *env = Sys_jni_env(sys);
-
- // Get the data from Java
- const char *java_cstr = (*env)->GetStringUTFChars(env, self, NULL);
- jsize len = (*env)->GetStringUTFLength(env, self);
-
- // Copy it in control of Nit
- char *nit_cstr = (char*)malloc(len+1);
- memcpy(nit_cstr, java_cstr, len);
- nit_cstr[len] = '\0';
-
- // Free JNI ref and return
- (*env)->ReleaseStringUTFChars(env, self, java_cstr);
- return nit_cstr;
- `}
-
- redef fun to_s do return to_cstring.to_s
-end
-
-redef class NativeString
- # Get a Java string from this C string
- #
- # This instance is only valid until the next execution of Java code.
- # You can use `new_local_ref` to keep it longer.
- fun to_java_string: JavaString import sys, Sys.jni_env `{
- Sys sys = JavaString_sys(self);
- JNIEnv *env = Sys_jni_env(sys);
- return (*env)->NewStringUTF(env, self);
- `}
-end
-
-redef class Text
- # Get `self` as a `JavaString`
- fun to_java_string: JavaString do return to_cstring.to_java_string
-end
-
-redef extern class JavaObject
-
- # Returns a global reference to the Java object behind this reference
- #
- # You must use a global reference when keeping a Java object
- # across execution of Java code, per JNI specification.
- fun new_global_ref: SELF import sys, Sys.jni_env `{
- Sys sys = JavaObject_sys(self);
- JNIEnv *env = Sys_jni_env(sys);
- return (*env)->NewGlobalRef(env, self);
- `}
-
- # Delete this global reference
- fun delete_global_ref import sys, Sys.jni_env `{
- Sys sys = JavaObject_sys(self);
- JNIEnv *env = Sys_jni_env(sys);
- (*env)->DeleteGlobalRef(env, self);
- `}
-
- # Delete this local reference
- fun delete_local_ref import sys, Sys.jni_env `{
- Sys sys = JavaObject_sys(self);
- JNIEnv *env = Sys_jni_env(sys);
- (*env)->DeleteLocalRef(env, self);
- `}
-
- # Pops the current local reference frame and return a valid reference to self
- #
- # Similar to `JavaVM::pop_local_frame` but returns a value.
- fun pop_from_local_frame: SELF
- do
- var jni_env = sys.jni_env
- return pop_from_local_frame_with_env(jni_env)
- end
-
- private fun pop_from_local_frame_with_env(jni_env: JniEnv): SELF `{
- return (*jni_env)->PopLocalFrame(jni_env, self);
- `}
-
- # Is `self` null in Java?
- #
- # Since Java type system doesn't have the same `nullable` concept as Nit's,
- # the two systems are not directly compatible. Any Nit instances of
- # `JavaObject` may hold a Java null.
- #
- # To benefit from the safer type system of Nit, it is recommended to check
- # the return of all extern methods implemented in Java to ensure the value
- # is not a Java null. In case it is, you should replace it by a normal Nit
- # `null`.
- fun is_java_null: Bool in "Java" `{ return self == null; `}
-
- # `JavaString` representation of `self` using Java's `toString`
- fun to_java_string: JavaString in "Java" `{ return self.toString(); `}
+module java
- # Use Java's `toString` for any `JavaObject`
- redef fun to_s
- do
- if is_java_null then return super
- return to_java_string.to_s
- end
-end
+import base
+import collections
# assert x.is_empty == false
fun is_empty: Bool is abstract
+ # Alias for `not is_empty`.
+ #
+ # Some people prefer to have conditions grammatically easier to read.
+ #
+ # var map = new HashMap[String, Int]
+ # assert map.not_empty == false
+ # map["one"] = 1
+ # assert map.not_empty == true
+ fun not_empty: Bool do return not self.is_empty
+
# Number of items in the collection.
#
# var x = new HashMap[String, Int]
redef fun pipeflags do return 3
- redef fun execute
+ redef fun execute do super
+
+ # Write `input` to process and return its output
+ #
+ # Writing and reading are processed line by line,
+ # reading only when something is available.
+ #
+ # ~~~
+ # var proc = new ProcessDuplex("tr", "[:lower:]", "[:upper:]")
+ # assert proc.write_and_read("""
+ # Alice
+ # Bob
+ # """) == """
+ # ALICE
+ # BOB
+ # """
+ # ~~~
+ fun write_and_read(input: Text): String
do
- super
+ var read = new Buffer #new Array[String]
+
+ # Main loop, read and write line by line
+ var prev = 0
+ for delimiter in input.search_all('\n') do
+ write input.substring(prev, delimiter.after-prev)
+ prev = delimiter.after
+
+ while stream_in.poll_in do
+ read.append stream_in.read_line
+ end
+ end
+
+ # Write the last line
+ write input.substring_from(prev)
+ stream_out.close
+
+ # Read the rest, may be everything for some programs
+ read.append stream_in.read_all
+ stream_in.close
+
+ # Clean up
+ wait
+ return read.to_s
end
end
end_reached = true
end
end
+
+ redef fun poll_in
+ do
+ var res = native_poll_in(fd)
+ if res == -1 then
+ last_error = new IOError(errno.to_s)
+ return false
+ else return res > 0
+ end
+
+ private fun native_poll_in(fd: Int): Int `{
+ struct pollfd fds = {fd, POLLIN, 0};
+ return poll(&fds, 1, 0);
+ `}
end
# `Stream` that can write to a File
path = "/dev/stdin"
prepare_buffer(1)
end
-
- redef fun poll_in `{
- struct pollfd fd = {0, POLLIN, 0};
- int res = poll(&fd, 1, 0);
- if (res == -1) {
- perror("Error poll stdin");
- exit(EXIT_FAILURE);
- }
- return res > 0;
- `}
end
# Standard output stream.
# var i = new StringReader(txt)
# assert i.read_all == txt
# ~~~
- fun read_all: String do return read_all_bytes.to_s
+ fun read_all: String do
+ var s = read_all_bytes
+ var slen = s.length
+ if slen == 0 then return ""
+ var rets = ""
+ var pos = 0
+ var sits = s.items
+ var remsp = slen
+ while pos < slen do
+ # The 129 size was decided more or less arbitrarily
+ # It will require some more benchmarking to compute
+ # if this is the best size or not
+ var chunksz = 129
+ if chunksz > remsp then
+ rets += new FlatString.with_infos(sits, remsp, pos, pos + remsp - 1)
+ break
+ end
+ var st = sits.find_beginning_of_char_at(pos + chunksz - 1)
+ var bytelen = st - pos
+ rets += new FlatString.with_infos(sits, bytelen, pos, st - 1)
+ pos = st
+ remsp -= bytelen
+ end
+ if rets isa Concat then return rets.balance
+ return rets
+ end
# Read all the stream until the eof.
#
# assert "abcd".has_suffix("bcd") == true
fun has_suffix(suffix: String): Bool do return has_substring(suffix, length - suffix.length)
- # If `self` contains only digits, return the corresponding integer
+ # Returns a copy of `self` minus all occurences of `c`
+ #
+ # assert "__init__".remove_all('_') == "init"
+ fun remove_all(c: Char): String do
+ var b = new Buffer
+ for i in chars do if i != c then b.add i
+ return b.to_s
+ end
+
+ # Is `self` a well-formed Integer (i.e. parsable via `to_i`)
+ #
+ # assert "123".is_int
+ # assert "0b1011".is_int
+ # assert not "0x_".is_int
+ # assert not "0xGE".is_int
+ fun is_int: Bool do
+ var s = remove_all('_')
+ var pos = 0
+ while s[pos] == '-' do
+ pos += 1
+ end
+ s = s.substring_from(pos)
+ var rets = s.strip_numhead
+ if rets == "" then return false
+ var hd = get_numhead
+ if hd == "0x" or hd == "0X" then return rets.is_hex
+ if hd == "0b" or hd == "0B" then return rets.is_bin
+ if hd == "0o" or hd == "0O" then return rets.is_oct
+ return hd.is_dec
+ end
+
+ # Removes the numeric head of `self` if present
+ #
+ # intrude import standard::text::abstract_text
+ # assert "0xFFEF".strip_numhead == "FFEF"
+ # assert "0o7364".strip_numhead == "7364"
+ # assert "0b01001".strip_numhead == "01001"
+ # assert "98".strip_numhead == "98"
+ private fun strip_numhead: Text do
+ if get_numhead != "" then return substring_from(2)
+ return self
+ end
+
+ # Gets the numeric head of `self` if present
+ # Returns "" otherwise
+ #
+ # intrude import standard::text::abstract_text
+ # assert "0xFEFF".get_numhead == "0x"
+ # assert "0b01001".get_numhead == "0b"
+ # assert "0o872".get_numhead == "0o"
+ # assert "98".get_numhead == ""
+ private fun get_numhead: Text do
+ if self.length < 2 then return ""
+ var c = self[0]
+ if c != '0' then return ""
+ c = self[1]
+ if c == 'x' or c == 'b' or c == 'o' or
+ c == 'X' or c == 'B' or c == 'O' then return substring(0, 2)
+ return ""
+ end
+
+ # Returns `self` as the corresponding integer
#
# assert "123".to_i == 123
# assert "-1".to_i == -1
+ # assert "0x64".to_i == 100
+ # assert "0b1100_0011".to_i== 195
+ # assert "--12".to_i == 12
+ #
+ # REQUIRE: `self`.`is_int`
fun to_i: Int
do
- # Shortcut
- return to_s.to_cstring.atoi
+ assert self.is_int
+ var s = remove_all('_')
+ var val = 0
+ var neg = false
+ var pos = 0
+ while s[pos] == '-' do
+ neg = not neg
+ pos += 1
+ end
+ s = s.substring_from(pos)
+ if s.length >= 2 then
+ var s1 = s[1]
+ if s1 == 'x' or s1 == 'X' then
+ val = s.substring_from(2).to_hex
+ else if s1 == 'o' or s1 == 'O' then
+ val = s.substring_from(2).to_oct
+ else if s1 == 'b' or s1 == 'B' then
+ val = s.substring_from(2).to_bin
+ else if s1.is_numeric then
+ val = s.to_dec
+ end
+ else
+ val = s.to_dec
+ end
+ return if neg then -val else val
end
# If `self` contains a float, return the corresponding float
# assert "101101".to_bin == 45
fun to_bin: Int do return a_to(2)
+ # If `self` contains only digits '0' .. '9', return the corresponding integer.
+ #
+ # assert "108".to_dec == 108
+ fun to_dec: Int do return a_to(10)
+
# If `self` contains only digits and letters, return the corresponding integer in a given base
#
# assert "120".a_to(3) == 15
return true
end
+ # Returns `true` if the string contains only Binary digits
+ #
+ # assert "1101100".is_bin == true
+ # assert "1101020".is_bin == false
+ fun is_bin: Bool do
+ for i in chars do if i != '0' and i != '1' then return false
+ return true
+ end
+
+ # Returns `true` if the string contains only Octal digits
+ #
+ # assert "213453".is_oct == true
+ # assert "781".is_oct == false
+ fun is_oct: Bool do
+ for i in chars do if i < '0' or i > '7' then return false
+ return true
+ end
+
+ # Returns `true` if the string contains only Decimal digits
+ #
+ # assert "10839".is_dec == true
+ # assert "164F".is_dec == false
+ fun is_dec: Bool do
+ for i in chars do if i < '0' or i > '9' then return false
+ return true
+ end
+
# Are all letters in `self` upper-case ?
#
# assert "HELLO WORLD".is_upper == true
redef fun empty do return ""
+ # Cache for the latest accessed FlatString in `self`
+ var flat_cache: String = ""
+
+ # Position of the beginning of `flat_cache` in `self`
+ var flat_last_pos_start: Int = -1
+
redef var to_cstring is lazy do
var len = bytelen
var ns = new NativeString(len + 1)
end
redef fun [](i) do
- var llen = left.length
- if i >= llen then return right[i - llen]
- return left[i]
+ if flat_last_pos_start != -1 then
+ var fsp = i - flat_last_pos_start
+ if fsp >= 0 and fsp < flat_cache.length then return flat_cache[fsp]
+ end
+ var s: String = self
+ var st = i
+ loop
+ if s isa FlatString then break
+ s = s.as(Concat)
+ var lft = s.left
+ var llen = lft.length
+ if i >= llen then
+ s = s.right
+ i -= llen
+ else
+ s = s.left
+ end
+ end
+ flat_last_pos_start = st - i
+ flat_cache = s
+ return s[i]
end
redef fun substring(from, len) do
st = 0
end
end
+
+ # Returns a balanced version of `self`
+ fun balance: String do
+ var children = new Array[String]
+ var rnod: String
+ var iter: nullable RopeCharIteratorPiece = new RopeCharIteratorPiece(self, false, false, null)
+ loop
+ if iter == null then break
+ rnod = iter.node
+ if not rnod isa Concat then
+ children.push rnod
+ iter = iter.prev
+ continue
+ end
+ if not iter.ldone then
+ iter.ldone = true
+ iter = new RopeCharIteratorPiece(rnod.left, false, false, iter)
+ else if not iter.rdone then
+ iter.rdone = true
+ iter = new RopeCharIteratorPiece(rnod.right, false, false, iter)
+ else
+ iter = iter.prev
+ end
+
+ end
+ return recurse_balance(children, children.length)
+ end
+
+ fun recurse_balance(nodes: Array[String], len: Int): String do
+ var finpos = 0
+ var stpos = 0
+ while stpos < len do
+ if len - stpos > 1 then
+ nodes[finpos] = new Concat(nodes[stpos], nodes[stpos + 1])
+ stpos += 2
+ else
+ nodes[finpos] = nodes[stpos]
+ stpos += 1
+ end
+ finpos += 1
+ end
+ if finpos == 1 then return nodes[0]
+ return recurse_balance(nodes, finpos)
+ end
end
# Mutable `Rope`, optimized for concatenation operations
redef fun enlarge(i) do end
redef fun to_s do
- dump_buffer
+ persist_buffer
+ written = true
return str
end
syn match NITExprSubstLong "\\." contained
syn match NITExprSubstLong "{*\zs{{{\([^}]\|\n\)*}}}\ze}*" contained
-" Numbers and ASCII Codes
-syn match NITNumber "\<\(\d\+\.\d\+\|\d\+\)\>"
+" Numbers
+syn match NITNumber "\<\([0-9_]\+\|0[bB][01_]\+\|0[oO][0-7_]\+\|0[xX][0-9a-fA-F_]\+\)\([iu]\(8\|16\|32\)\)\?\>"
+syn match NITNumber "\<[0-9_]\+\.[0-9_]\+\>"
" Identifiers
syn match NITClass "\<\u\w*"
end
end
-redef class Text
- private fun remove_underscores: Text do
- var b = new FlatBuffer
- for i in chars do
- if i == '_' then continue
- b.add i
- end
- return b
- end
-end
-
redef class AIntExpr
# The value of the literal int once computed.
var value: nullable Int
-end
-redef class ADecIntExpr
redef fun accept_literal(v)
do
- value = self.n_number.text.to_i
+ if not text.is_int then
+ v.toolcontext.error(hot_location, "Error: invalid literal `{text}`")
+ return
+ end
+ value = text.to_i
end
+
+ private fun text: String is abstract
+end
+
+redef class ADecIntExpr
+ redef fun text do return self.n_number.text
end
redef class AHexIntExpr
- redef fun accept_literal(v)
- do
- var s = self.n_hex_number.text.substring_from(2).remove_underscores
- if s.is_empty then
- v.toolcontext.error(location, "Error: invalid hexadecimal literal")
- return
- end
- value = s.to_hex
- end
+ redef fun text do return self.n_hex_number.text
end
redef class ABinIntExpr
- redef fun accept_literal(v)
- do
- var s = self.n_bin_number.text.substring_from(2).remove_underscores
- if s.is_empty then
- v.toolcontext.error(location, "Error: invalid binary literal")
- return
- end
- value = s.to_bin
- end
+ redef fun text do return self.n_bin_number.text
end
redef class AOctIntExpr
- redef fun accept_literal(v)
- do
- var s = self.n_oct_number.text.substring_from(2).remove_underscores
- if s.is_empty then
- v.toolcontext.error(location, "Error: invalid octal literal")
- return
- end
- value = s.to_oct
- end
+ redef fun text do return self.n_oct_number.text
end
redef class AByteExpr
# The value of the literal int once computed.
var value: nullable Byte
-end
-redef class ADecByteExpr
redef fun accept_literal(v)
do
- var t = self.n_bytenum.text
- value = t.substring(0, t.length - 2).to_i.to_b
+ var s = text.substring(0, text.length - 2)
+ if not s.is_int then
+ v.toolcontext.error(hot_location, "Error: invalid byte literal `{text}`")
+ return
+ end
+ value = s.to_i.to_b
end
+
+ private fun text: String is abstract
+end
+
+redef class ADecByteExpr
+ redef fun text do return self.n_bytenum.text
end
redef class AHexByteExpr
- redef fun accept_literal(v)
- do
- var t = self.n_hex_bytenum.text
- var s = t.substring(2, t.length - 4).remove_underscores
- if s.is_empty then
- v.toolcontext.error(location, "Error: invalid hexadecimal literal")
- return
- end
- value = s.to_hex.to_b
- end
+ redef fun text do return self.n_hex_bytenum.text
end
redef class ABinByteExpr
- redef fun accept_literal(v)
- do
- var t = self.n_bin_bytenum.text
- var s = t.substring(2, t.length - 4).remove_underscores
- if s.is_empty then
- v.toolcontext.error(location, "Error: invalid binary literal")
- return
- end
- value = s.to_bin.to_b
- end
+ redef fun text do return self.n_bin_bytenum.text
end
redef class AOctByteExpr
- redef fun accept_literal(v)
- do
- var t = self.n_oct_bytenum.text
- var s = t.substring(2, t.length - 4).remove_underscores
- if s.is_empty then
- v.toolcontext.error(location, "Error: invalid octal literal")
- return
- end
- value = s.to_oct.to_b
- end
+ redef fun text do return self.n_oct_bytenum.text
end
redef class AFloatExpr
id = lowercase letter*;
attrid = '_' lowercase letter*;
-number = digit+;
+number = digit (digit | '_')*;
hex_number = ('0x' | '0X') hexdigit+;
bin_number = ('0b' | '0B') bindigit+;
oct_number = ('0o' | '0O') octdigit+;
-bytenum = digit+ 'u8';
+bytenum = digit (digit | '_')* 'u8';
hex_bytenum = ('0x' | '0X') hexdigit+ 'u8';
bin_bytenum = ('0b' | '0B') bindigit+ 'u8';
oct_bytenum = ('0o' | '0O') octdigit+ 'u8';
61, 61, 75
};
static const int lexer_goto_row20[] = {
- 11,
+ 12,
46, 46, 76,
- 48, 57, 20,
- 66, 66, 77,
- 69, 69, 78,
- 79, 79, 79,
- 88, 88, 80,
- 98, 98, 81,
- 101, 101, 82,
- 111, 111, 83,
- 117, 117, 84,
- 120, 120, 85
+ 48, 57, 77,
+ 66, 66, 78,
+ 69, 69, 79,
+ 79, 79, 80,
+ 88, 88, 81,
+ 95, 95, 82,
+ 98, 98, 83,
+ 101, 101, 84,
+ 111, 111, 85,
+ 117, 117, 86,
+ 120, 120, 87
};
static const int lexer_goto_row21[] = {
- 4,
+ 5,
46, 57, -21,
- 69, 69, 78,
- 101, 101, 82,
- 117, 117, 84
+ 69, 69, 79,
+ 95, 95, 82,
+ 101, 101, 84,
+ 117, 117, 86
};
static const int lexer_goto_row22[] = {
1,
- 58, 58, 86
+ 58, 58, 88
};
static const int lexer_goto_row24[] = {
2,
- 60, 60, 87,
- 61, 61, 88
+ 60, 60, 89,
+ 61, 61, 90
};
static const int lexer_goto_row25[] = {
1,
- 61, 61, 89
+ 61, 61, 91
};
static const int lexer_goto_row26[] = {
2,
- 61, 61, 90,
- 62, 62, 91
+ 61, 61, 92,
+ 62, 62, 93
};
static const int lexer_goto_row28[] = {
4,
- 48, 57, 92,
- 65, 90, 93,
- 95, 95, 94,
- 97, 122, 95
+ 48, 57, 94,
+ 65, 90, 95,
+ 95, 95, 96,
+ 97, 122, 97
};
static const int lexer_goto_row31[] = {
1,
- 61, 61, 96
+ 61, 61, 98
};
static const int lexer_goto_row32[] = {
2,
- 95, 95, 97,
- 97, 122, 98
+ 95, 95, 99,
+ 97, 122, 100
};
static const int lexer_goto_row33[] = {
1,
- 123, 123, 99
+ 123, 123, 101
};
static const int lexer_goto_row34[] = {
10,
- 48, 57, 100,
- 65, 90, 101,
- 95, 95, 102,
- 97, 97, 103,
- 98, 98, 104,
- 99, 109, 103,
- 110, 110, 105,
- 111, 114, 103,
- 115, 115, 106,
- 116, 122, 103
+ 48, 57, 102,
+ 65, 90, 103,
+ 95, 95, 104,
+ 97, 97, 105,
+ 98, 98, 106,
+ 99, 109, 105,
+ 110, 110, 107,
+ 111, 114, 105,
+ 115, 115, 108,
+ 116, 122, 105
};
static const int lexer_goto_row35[] = {
4,
48, 95, -35,
- 97, 113, 103,
- 114, 114, 107,
- 115, 122, 103
+ 97, 113, 105,
+ 114, 114, 109,
+ 115, 122, 105
};
static const int lexer_goto_row36[] = {
6,
48, 95, -35,
- 97, 107, 103,
- 108, 108, 108,
- 109, 110, 103,
- 111, 111, 109,
- 112, 122, 103
+ 97, 107, 105,
+ 108, 108, 110,
+ 109, 110, 105,
+ 111, 111, 111,
+ 112, 122, 105
};
static const int lexer_goto_row37[] = {
4,
48, 95, -35,
- 97, 110, 103,
- 111, 111, 110,
- 112, 122, 103
+ 97, 110, 105,
+ 111, 111, 112,
+ 112, 122, 105
};
static const int lexer_goto_row38[] = {
7,
48, 107, -37,
- 108, 108, 111,
- 109, 109, 103,
- 110, 110, 112,
- 111, 119, 103,
- 120, 120, 113,
- 121, 122, 103
+ 108, 108, 113,
+ 109, 109, 105,
+ 110, 110, 114,
+ 111, 119, 105,
+ 120, 120, 115,
+ 121, 122, 105
};
static const int lexer_goto_row39[] = {
7,
48, 95, -35,
- 97, 97, 114,
- 98, 110, 103,
- 111, 111, 115,
- 112, 116, 103,
- 117, 117, 116,
- 118, 122, 103
+ 97, 97, 116,
+ 98, 110, 105,
+ 111, 111, 117,
+ 112, 116, 105,
+ 117, 117, 118,
+ 118, 122, 105
};
static const int lexer_goto_row40[] = {
2,
48, 95, -35,
- 97, 122, 103
+ 97, 122, 105
};
static const int lexer_goto_row41[] = {
9,
48, 95, -35,
- 97, 101, 103,
- 102, 102, 117,
- 103, 108, 103,
- 109, 109, 118,
- 110, 110, 119,
- 111, 114, 103,
- 115, 115, 120,
- 116, 122, 103
+ 97, 101, 105,
+ 102, 102, 119,
+ 103, 108, 105,
+ 109, 109, 120,
+ 110, 110, 121,
+ 111, 114, 105,
+ 115, 115, 122,
+ 116, 122, 105
};
static const int lexer_goto_row42[] = {
5,
48, 95, -35,
- 97, 97, 121,
- 98, 110, 103,
- 111, 111, 122,
- 112, 122, 103
+ 97, 97, 123,
+ 98, 110, 105,
+ 111, 111, 124,
+ 112, 122, 105
};
static const int lexer_goto_row43[] = {
3,
48, 110, -38,
- 111, 111, 123,
- 112, 122, 103
+ 111, 111, 125,
+ 112, 122, 105
};
static const int lexer_goto_row44[] = {
8,
48, 95, -35,
- 97, 100, 103,
- 101, 101, 124,
- 102, 110, 103,
- 111, 111, 125,
- 112, 116, 103,
- 117, 117, 126,
- 118, 122, 103
+ 97, 100, 105,
+ 101, 101, 126,
+ 102, 110, 105,
+ 111, 111, 127,
+ 112, 116, 105,
+ 117, 117, 128,
+ 118, 122, 105
};
static const int lexer_goto_row45[] = {
6,
48, 95, -35,
- 97, 109, 103,
- 110, 110, 127,
- 111, 113, 103,
- 114, 114, 128,
- 115, 122, 103
+ 97, 109, 105,
+ 110, 110, 129,
+ 111, 113, 105,
+ 114, 114, 130,
+ 115, 122, 105
};
static const int lexer_goto_row46[] = {
7,
48, 95, -35,
- 97, 97, 129,
- 98, 113, 103,
- 114, 114, 130,
- 115, 116, 103,
- 117, 117, 131,
- 118, 122, 103
+ 97, 97, 131,
+ 98, 113, 105,
+ 114, 114, 132,
+ 115, 116, 105,
+ 117, 117, 133,
+ 118, 122, 105
};
static const int lexer_goto_row47[] = {
3,
48, 100, -45,
- 101, 101, 132,
- 102, 122, 103
+ 101, 101, 134,
+ 102, 122, 105
};
static const int lexer_goto_row48[] = {
5,
48, 100, -45,
- 101, 101, 133,
- 102, 116, 103,
- 117, 117, 134,
- 118, 122, 103
+ 101, 101, 135,
+ 102, 116, 105,
+ 117, 117, 136,
+ 118, 122, 105
};
static const int lexer_goto_row49[] = {
8,
48, 95, -35,
- 97, 103, 103,
- 104, 104, 135,
- 105, 113, 103,
- 114, 114, 136,
- 115, 120, 103,
- 121, 121, 137,
- 122, 122, 103
+ 97, 103, 105,
+ 104, 104, 137,
+ 105, 113, 105,
+ 114, 114, 138,
+ 115, 120, 105,
+ 121, 121, 139,
+ 122, 122, 105
};
static const int lexer_goto_row50[] = {
3,
48, 109, -46,
- 110, 110, 138,
- 111, 122, 103
+ 110, 110, 140,
+ 111, 122, 105
};
static const int lexer_goto_row51[] = {
3,
48, 95, -35,
- 97, 97, 139,
- 98, 122, 103
+ 97, 97, 141,
+ 98, 122, 105
};
static const int lexer_goto_row52[] = {
4,
48, 103, -50,
- 104, 104, 140,
- 105, 105, 141,
- 106, 122, 103
+ 104, 104, 142,
+ 105, 105, 143,
+ 106, 122, 105
};
static const int lexer_goto_row53[] = {
1,
- 61, 61, 142
+ 61, 61, 144
};
static const int lexer_goto_row54[] = {
11,
- 0, 9, 143,
- 11, 12, 143,
- 14, 33, 143,
- 34, 34, 144,
- 35, 91, 143,
- 92, 92, 145,
- 93, 122, 143,
- 123, 123, 146,
- 124, 124, 143,
- 125, 125, 147,
- 126, 255, 143
+ 0, 9, 145,
+ 11, 12, 145,
+ 14, 33, 145,
+ 34, 34, 146,
+ 35, 91, 145,
+ 92, 92, 147,
+ 93, 122, 145,
+ 123, 123, 148,
+ 124, 124, 145,
+ 125, 125, 149,
+ 126, 255, 145
};
static const int lexer_goto_row58[] = {
3,
0, 33, -8,
- 34, 34, 148,
+ 34, 34, 150,
35, 255, -8
};
static const int lexer_goto_row59[] = {
1,
- 34, 34, 149
+ 34, 34, 151
};
static const int lexer_goto_row60[] = {
3,
- 0, 9, 150,
- 11, 12, 150,
- 14, 255, 150
+ 0, 9, 152,
+ 11, 12, 152,
+ 14, 255, 152
};
static const int lexer_goto_row62[] = {
1,
};
static const int lexer_goto_row64[] = {
1,
- 10, 10, 151
+ 10, 10, 153
};
static const int lexer_goto_row67[] = {
1,
- 39, 39, 152
+ 39, 39, 154
};
static const int lexer_goto_row68[] = {
1,
- 39, 39, 153
+ 39, 39, 155
};
static const int lexer_goto_row69[] = {
3,
- 0, 9, 154,
- 11, 12, 154,
- 14, 255, 154
+ 0, 9, 156,
+ 11, 12, 156,
+ 14, 255, 156
};
static const int lexer_goto_row70[] = {
1,
- 61, 61, 155
+ 61, 61, 157
};
static const int lexer_goto_row74[] = {
1,
- 46, 46, 156
+ 46, 46, 158
};
static const int lexer_goto_row75[] = {
- 2,
+ 3,
48, 57, 74,
- 69, 101, -22
+ 69, 69, 79,
+ 101, 101, 84
};
static const int lexer_goto_row77[] = {
1,
48, 57, 74
};
static const int lexer_goto_row78[] = {
- 3,
- 48, 48, 157,
- 49, 49, 158,
- 95, 95, 159
+ 1,
+ 46, 117, -22
};
static const int lexer_goto_row79[] = {
3,
- 43, 43, 160,
- 45, 45, 161,
- 48, 57, 162
+ 48, 48, 159,
+ 49, 49, 160,
+ 95, 95, 161
};
static const int lexer_goto_row80[] = {
- 2,
- 48, 55, 163,
- 95, 95, 164
+ 3,
+ 43, 43, 162,
+ 45, 45, 163,
+ 48, 57, 164
};
static const int lexer_goto_row81[] = {
- 4,
- 48, 57, 165,
- 65, 70, 166,
- 95, 95, 167,
- 97, 102, 168
+ 2,
+ 48, 55, 165,
+ 95, 95, 166
};
static const int lexer_goto_row82[] = {
- 1,
- 48, 95, -79
+ 4,
+ 48, 57, 167,
+ 65, 70, 168,
+ 95, 95, 169,
+ 97, 102, 170
};
static const int lexer_goto_row83[] = {
- 1,
- 43, 57, -80
+ 3,
+ 48, 57, 171,
+ 95, 95, 82,
+ 117, 117, 86
};
static const int lexer_goto_row84[] = {
1,
- 48, 95, -81
+ 48, 95, -80
};
static const int lexer_goto_row85[] = {
1,
- 56, 56, 169
+ 43, 57, -81
};
static const int lexer_goto_row86[] = {
1,
- 48, 102, -82
+ 48, 95, -82
};
-static const int lexer_goto_row88[] = {
+static const int lexer_goto_row87[] = {
1,
- 61, 61, 170
+ 56, 56, 172
};
-static const int lexer_goto_row89[] = {
+static const int lexer_goto_row88[] = {
1,
- 62, 62, 171
+ 48, 102, -83
};
-static const int lexer_goto_row92[] = {
+static const int lexer_goto_row90[] = {
1,
- 61, 61, 172
+ 61, 61, 173
};
-static const int lexer_goto_row93[] = {
+static const int lexer_goto_row91[] = {
1,
- 48, 122, -29
+ 62, 62, 174
};
static const int lexer_goto_row94[] = {
1,
- 48, 122, -29
+ 61, 61, 175
};
static const int lexer_goto_row95[] = {
1,
1,
48, 122, -29
};
+static const int lexer_goto_row97[] = {
+ 1,
+ 48, 122, -29
+};
static const int lexer_goto_row98[] = {
1,
- 100, 100, 173
+ 48, 122, -29
};
-static const int lexer_goto_row99[] = {
+static const int lexer_goto_row100[] = {
+ 1,
+ 100, 100, 176
+};
+static const int lexer_goto_row101[] = {
4,
- 48, 57, 174,
- 65, 90, 175,
- 95, 95, 176,
- 97, 122, 177
+ 48, 57, 177,
+ 65, 90, 178,
+ 95, 95, 179,
+ 97, 122, 180
};
-static const int lexer_goto_row100[] = {
+static const int lexer_goto_row102[] = {
5,
- 0, 91, 178,
- 92, 92, 179,
- 93, 95, 178,
- 96, 96, 180,
- 97, 255, 178
+ 0, 91, 181,
+ 92, 92, 182,
+ 93, 95, 181,
+ 96, 96, 183,
+ 97, 255, 181
};
-static const int lexer_goto_row101[] = {
+static const int lexer_goto_row103[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row102[] = {
+static const int lexer_goto_row104[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row103[] = {
+static const int lexer_goto_row105[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row104[] = {
+static const int lexer_goto_row106[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row105[] = {
+static const int lexer_goto_row107[] = {
5,
48, 110, -38,
- 111, 111, 181,
- 112, 114, 103,
- 115, 115, 182,
- 116, 122, 103
+ 111, 111, 184,
+ 112, 114, 105,
+ 115, 115, 185,
+ 116, 122, 105
};
-static const int lexer_goto_row106[] = {
+static const int lexer_goto_row108[] = {
4,
48, 95, -35,
- 97, 99, 103,
- 100, 100, 183,
- 101, 122, 103
+ 97, 99, 105,
+ 100, 100, 186,
+ 101, 122, 105
};
-static const int lexer_goto_row107[] = {
+static const int lexer_goto_row109[] = {
4,
48, 95, -35,
- 97, 114, 103,
- 115, 115, 184,
- 116, 122, 103
+ 97, 114, 105,
+ 115, 115, 187,
+ 116, 122, 105
};
-static const int lexer_goto_row108[] = {
+static const int lexer_goto_row110[] = {
3,
48, 100, -45,
- 101, 101, 185,
- 102, 122, 103
+ 101, 101, 188,
+ 102, 122, 105
};
-static const int lexer_goto_row109[] = {
+static const int lexer_goto_row111[] = {
3,
48, 95, -35,
- 97, 97, 186,
- 98, 122, 103
+ 97, 97, 189,
+ 98, 122, 105
};
-static const int lexer_goto_row110[] = {
+static const int lexer_goto_row112[] = {
3,
48, 109, -46,
- 110, 110, 187,
- 111, 122, 103
+ 110, 110, 190,
+ 111, 122, 105
};
-static const int lexer_goto_row111[] = {
+static const int lexer_goto_row113[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row112[] = {
+static const int lexer_goto_row114[] = {
3,
- 48, 114, -108,
- 115, 115, 188,
- 116, 122, 103
+ 48, 114, -110,
+ 115, 115, 191,
+ 116, 122, 105
};
-static const int lexer_goto_row113[] = {
+static const int lexer_goto_row115[] = {
5,
- 48, 99, -107,
- 100, 100, 189,
- 101, 116, 103,
- 117, 117, 190,
- 118, 122, 103
+ 48, 99, -109,
+ 100, 100, 192,
+ 101, 116, 105,
+ 117, 117, 193,
+ 118, 122, 105
};
-static const int lexer_goto_row114[] = {
+static const int lexer_goto_row116[] = {
4,
48, 95, -35,
- 97, 115, 103,
- 116, 116, 191,
- 117, 122, 103
+ 97, 115, 105,
+ 116, 116, 194,
+ 117, 122, 105
};
-static const int lexer_goto_row115[] = {
+static const int lexer_goto_row117[] = {
3,
48, 107, -37,
- 108, 108, 192,
- 109, 122, 103
+ 108, 108, 195,
+ 109, 122, 105
};
-static const int lexer_goto_row116[] = {
+static const int lexer_goto_row118[] = {
3,
48, 113, -36,
- 114, 114, 193,
- 115, 122, 103
+ 114, 114, 196,
+ 115, 122, 105
};
-static const int lexer_goto_row117[] = {
+static const int lexer_goto_row119[] = {
3,
48, 109, -46,
- 110, 110, 194,
- 111, 122, 103
+ 110, 110, 197,
+ 111, 122, 105
};
-static const int lexer_goto_row118[] = {
+static const int lexer_goto_row120[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row119[] = {
+static const int lexer_goto_row121[] = {
4,
48, 95, -35,
- 97, 111, 103,
- 112, 112, 195,
- 113, 122, 103
+ 97, 111, 105,
+ 112, 112, 198,
+ 113, 122, 105
};
-static const int lexer_goto_row120[] = {
+static const int lexer_goto_row122[] = {
6,
48, 95, -35,
- 97, 104, 103,
- 105, 105, 196,
- 106, 115, 103,
- 116, 116, 197,
- 117, 122, 103
+ 97, 104, 105,
+ 105, 105, 199,
+ 106, 115, 105,
+ 116, 116, 200,
+ 117, 122, 105
};
-static const int lexer_goto_row121[] = {
+static const int lexer_goto_row123[] = {
5,
48, 95, -35,
- 97, 97, 198,
- 98, 114, 103,
- 115, 115, 199,
- 116, 122, 103
+ 97, 97, 201,
+ 98, 114, 105,
+ 115, 115, 202,
+ 116, 122, 105
};
-static const int lexer_goto_row122[] = {
+static const int lexer_goto_row124[] = {
3,
48, 97, -35,
- 98, 98, 200,
- 99, 122, 103
+ 98, 98, 203,
+ 99, 122, 105
};
-static const int lexer_goto_row123[] = {
+static const int lexer_goto_row125[] = {
3,
48, 110, -38,
- 111, 111, 201,
- 112, 122, 103
+ 111, 111, 204,
+ 112, 122, 105
};
-static const int lexer_goto_row124[] = {
+static const int lexer_goto_row126[] = {
3,
- 48, 99, -107,
- 100, 100, 202,
- 101, 122, 103
+ 48, 99, -109,
+ 100, 100, 205,
+ 101, 122, 105
};
-static const int lexer_goto_row125[] = {
+static const int lexer_goto_row127[] = {
4,
48, 95, -35,
- 97, 118, 103,
- 119, 119, 203,
- 120, 122, 103
+ 97, 118, 105,
+ 119, 119, 206,
+ 120, 122, 105
};
-static const int lexer_goto_row126[] = {
+static const int lexer_goto_row128[] = {
3,
- 48, 115, -115,
- 116, 116, 204,
- 117, 122, 103
+ 48, 115, -117,
+ 116, 116, 207,
+ 117, 122, 105
};
-static const int lexer_goto_row127[] = {
+static const int lexer_goto_row129[] = {
3,
48, 107, -37,
- 108, 108, 205,
- 109, 122, 103
+ 108, 108, 208,
+ 109, 122, 105
};
-static const int lexer_goto_row128[] = {
+static const int lexer_goto_row130[] = {
4,
48, 95, -35,
- 97, 98, 103,
- 99, 99, 206,
- 100, 122, 103
+ 97, 98, 105,
+ 99, 99, 209,
+ 100, 122, 105
};
-static const int lexer_goto_row129[] = {
+static const int lexer_goto_row131[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row130[] = {
- 3,
- 48, 98, -129,
- 99, 99, 207,
- 100, 122, 103
-};
-static const int lexer_goto_row131[] = {
- 5,
- 48, 104, -121,
- 105, 105, 208,
- 106, 110, 103,
- 111, 111, 209,
- 112, 122, 103
-};
static const int lexer_goto_row132[] = {
3,
- 48, 97, -35,
- 98, 98, 210,
- 99, 122, 103
+ 48, 98, -131,
+ 99, 99, 210,
+ 100, 122, 105
};
static const int lexer_goto_row133[] = {
5,
- 48, 99, -107,
- 100, 100, 211,
- 101, 115, 103,
- 116, 116, 212,
- 117, 122, 103
+ 48, 104, -123,
+ 105, 105, 211,
+ 106, 110, 105,
+ 111, 111, 212,
+ 112, 122, 105
};
static const int lexer_goto_row134[] = {
3,
- 48, 107, -37,
- 108, 108, 213,
- 109, 122, 103
+ 48, 97, -35,
+ 98, 98, 213,
+ 99, 122, 105
};
static const int lexer_goto_row135[] = {
- 3,
- 48, 111, -120,
- 112, 112, 214,
- 113, 122, 103
+ 5,
+ 48, 99, -109,
+ 100, 100, 214,
+ 101, 115, 105,
+ 116, 116, 215,
+ 117, 122, 105
};
static const int lexer_goto_row136[] = {
3,
- 48, 100, -45,
- 101, 101, 215,
- 102, 122, 103
+ 48, 107, -37,
+ 108, 108, 216,
+ 109, 122, 105
};
static const int lexer_goto_row137[] = {
- 4,
- 48, 95, -35,
- 97, 116, 103,
- 117, 117, 216,
- 118, 122, 103
+ 3,
+ 48, 111, -122,
+ 112, 112, 217,
+ 113, 122, 105
};
static const int lexer_goto_row138[] = {
3,
- 48, 111, -120,
- 112, 112, 217,
- 113, 122, 103
+ 48, 100, -45,
+ 101, 101, 218,
+ 102, 122, 105
};
static const int lexer_goto_row139[] = {
- 3,
- 48, 104, -121,
- 105, 105, 218,
- 106, 122, 103
+ 4,
+ 48, 95, -35,
+ 97, 116, 105,
+ 117, 117, 219,
+ 118, 122, 105
};
static const int lexer_goto_row140[] = {
3,
- 48, 113, -36,
- 114, 114, 219,
- 115, 122, 103
+ 48, 111, -122,
+ 112, 112, 220,
+ 113, 122, 105
};
static const int lexer_goto_row141[] = {
3,
- 48, 104, -121,
- 105, 105, 220,
- 106, 122, 103
+ 48, 104, -123,
+ 105, 105, 221,
+ 106, 122, 105
};
static const int lexer_goto_row142[] = {
3,
- 48, 115, -115,
- 116, 116, 221,
- 117, 122, 103
+ 48, 113, -36,
+ 114, 114, 222,
+ 115, 122, 105
+};
+static const int lexer_goto_row143[] = {
+ 3,
+ 48, 104, -123,
+ 105, 105, 223,
+ 106, 122, 105
};
static const int lexer_goto_row144[] = {
+ 3,
+ 48, 115, -117,
+ 116, 116, 224,
+ 117, 122, 105
+};
+static const int lexer_goto_row146[] = {
2,
0, 123, -55,
- 124, 255, 143
+ 124, 255, 145
};
-static const int lexer_goto_row146[] = {
+static const int lexer_goto_row148[] = {
3,
- 0, 9, 222,
- 11, 12, 222,
- 14, 255, 222
+ 0, 9, 225,
+ 11, 12, 225,
+ 14, 255, 225
};
-static const int lexer_goto_row148[] = {
+static const int lexer_goto_row150[] = {
3,
0, 124, -55,
- 125, 125, 223,
- 126, 255, 143
+ 125, 125, 226,
+ 126, 255, 145
};
-static const int lexer_goto_row150[] = {
+static const int lexer_goto_row152[] = {
11,
- 0, 9, 224,
- 10, 10, 225,
- 11, 12, 224,
- 13, 13, 226,
- 14, 33, 224,
- 34, 34, 227,
- 35, 91, 224,
- 92, 92, 228,
- 93, 122, 224,
- 123, 123, 229,
- 124, 255, 224
-};
-static const int lexer_goto_row151[] = {
+ 0, 9, 227,
+ 10, 10, 228,
+ 11, 12, 227,
+ 13, 13, 229,
+ 14, 33, 227,
+ 34, 34, 230,
+ 35, 91, 227,
+ 92, 92, 231,
+ 93, 122, 227,
+ 123, 123, 232,
+ 124, 255, 227
+};
+static const int lexer_goto_row153[] = {
1,
0, 255, -59
};
-static const int lexer_goto_row154[] = {
+static const int lexer_goto_row156[] = {
9,
- 0, 9, 230,
- 10, 10, 231,
- 11, 12, 230,
- 13, 13, 232,
- 14, 38, 230,
- 39, 39, 233,
- 40, 91, 230,
- 92, 92, 234,
- 93, 255, 230
+ 0, 9, 233,
+ 10, 10, 234,
+ 11, 12, 233,
+ 13, 13, 235,
+ 14, 38, 233,
+ 39, 39, 236,
+ 40, 91, 233,
+ 92, 92, 237,
+ 93, 255, 233
};
-static const int lexer_goto_row155[] = {
+static const int lexer_goto_row157[] = {
1,
- 39, 39, 235
-};
-static const int lexer_goto_row158[] = {
- 2,
- 48, 95, -79,
- 117, 117, 236
-};
-static const int lexer_goto_row159[] = {
- 1,
- 48, 117, -159
+ 39, 39, 238
};
static const int lexer_goto_row160[] = {
- 1,
- 48, 117, -159
+ 2,
+ 48, 95, -80,
+ 117, 117, 239
};
static const int lexer_goto_row161[] = {
1,
- 48, 57, 162
+ 48, 117, -161
};
static const int lexer_goto_row162[] = {
1,
- 48, 57, 162
+ 48, 117, -161
};
static const int lexer_goto_row163[] = {
1,
- 48, 57, 162
+ 48, 57, 164
};
static const int lexer_goto_row164[] = {
- 2,
- 48, 95, -81,
- 117, 117, 237
+ 1,
+ 48, 57, 164
};
static const int lexer_goto_row165[] = {
1,
- 48, 117, -165
+ 48, 57, 164
};
static const int lexer_goto_row166[] = {
2,
- 48, 102, -82,
- 117, 117, 238
+ 48, 95, -82,
+ 117, 117, 240
};
static const int lexer_goto_row167[] = {
1,
48, 117, -167
};
static const int lexer_goto_row168[] = {
- 1,
- 48, 117, -167
+ 2,
+ 48, 102, -83,
+ 117, 117, 241
};
static const int lexer_goto_row169[] = {
1,
- 48, 117, -167
+ 48, 117, -169
};
-static const int lexer_goto_row174[] = {
+static const int lexer_goto_row170[] = {
1,
- 101, 101, 239
+ 48, 117, -169
};
-static const int lexer_goto_row175[] = {
+static const int lexer_goto_row171[] = {
1,
- 48, 122, -100
+ 48, 117, -169
};
-static const int lexer_goto_row176[] = {
+static const int lexer_goto_row172[] = {
1,
- 48, 122, -100
+ 48, 117, -84
};
static const int lexer_goto_row177[] = {
1,
- 48, 122, -100
+ 101, 101, 242
};
static const int lexer_goto_row178[] = {
1,
- 48, 122, -100
+ 48, 122, -102
};
static const int lexer_goto_row179[] = {
1,
- 0, 255, -101
+ 48, 122, -102
};
static const int lexer_goto_row180[] = {
1,
- 0, 255, 240
+ 48, 122, -102
};
static const int lexer_goto_row181[] = {
- 3,
- 0, 124, 241,
- 125, 125, 242,
- 126, 255, 241
+ 1,
+ 48, 122, -102
};
static const int lexer_goto_row182[] = {
+ 1,
+ 0, 255, -103
+};
+static const int lexer_goto_row183[] = {
+ 1,
+ 0, 255, 243
+};
+static const int lexer_goto_row184[] = {
+ 3,
+ 0, 124, 244,
+ 125, 125, 245,
+ 126, 255, 244
+};
+static const int lexer_goto_row185[] = {
3,
48, 113, -36,
- 114, 114, 243,
- 115, 122, 103
+ 114, 114, 246,
+ 115, 122, 105
};
-static const int lexer_goto_row183[] = {
+static const int lexer_goto_row186[] = {
3,
- 48, 115, -115,
- 116, 116, 244,
- 117, 122, 103
+ 48, 115, -117,
+ 116, 116, 247,
+ 117, 122, 105
};
-static const int lexer_goto_row184[] = {
+static const int lexer_goto_row187[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row185[] = {
+static const int lexer_goto_row188[] = {
3,
48, 100, -45,
- 101, 101, 245,
- 102, 122, 103
+ 101, 101, 248,
+ 102, 122, 105
};
-static const int lexer_goto_row186[] = {
+static const int lexer_goto_row189[] = {
3,
48, 95, -35,
- 97, 97, 246,
- 98, 122, 103
+ 97, 97, 249,
+ 98, 122, 105
};
-static const int lexer_goto_row187[] = {
+static const int lexer_goto_row190[] = {
3,
- 48, 114, -108,
- 115, 115, 247,
- 116, 122, 103
+ 48, 114, -110,
+ 115, 115, 250,
+ 116, 122, 105
};
-static const int lexer_goto_row188[] = {
+static const int lexer_goto_row191[] = {
3,
- 48, 115, -115,
- 116, 116, 248,
- 117, 122, 103
+ 48, 115, -117,
+ 116, 116, 251,
+ 117, 122, 105
};
-static const int lexer_goto_row189[] = {
+static const int lexer_goto_row192[] = {
3,
48, 100, -45,
- 101, 101, 249,
- 102, 122, 103
+ 101, 101, 252,
+ 102, 122, 105
};
-static const int lexer_goto_row190[] = {
+static const int lexer_goto_row193[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row191[] = {
+static const int lexer_goto_row194[] = {
4,
48, 95, -35,
- 97, 108, 103,
- 109, 109, 250,
- 110, 122, 103
+ 97, 108, 105,
+ 109, 109, 253,
+ 110, 122, 105
};
-static const int lexer_goto_row192[] = {
+static const int lexer_goto_row195[] = {
3,
48, 100, -45,
- 101, 101, 251,
- 102, 122, 103
+ 101, 101, 254,
+ 102, 122, 105
};
-static const int lexer_goto_row193[] = {
+static const int lexer_goto_row196[] = {
3,
- 48, 114, -108,
- 115, 115, 252,
- 116, 122, 103
+ 48, 114, -110,
+ 115, 115, 255,
+ 116, 122, 105
};
-static const int lexer_goto_row194[] = {
+static const int lexer_goto_row197[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row195[] = {
+static const int lexer_goto_row198[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row196[] = {
+static const int lexer_goto_row199[] = {
5,
48, 107, -37,
- 108, 108, 253,
- 109, 110, 103,
- 111, 111, 254,
- 112, 122, 103
+ 108, 108, 256,
+ 109, 110, 105,
+ 111, 111, 257,
+ 112, 122, 105
};
-static const int lexer_goto_row197[] = {
+static const int lexer_goto_row200[] = {
3,
- 48, 115, -115,
- 116, 116, 255,
- 117, 122, 103
+ 48, 115, -117,
+ 116, 116, 258,
+ 117, 122, 105
};
-static const int lexer_goto_row198[] = {
+static const int lexer_goto_row201[] = {
5,
48, 100, -45,
- 101, 101, 256,
- 102, 113, 103,
- 114, 114, 257,
- 115, 122, 103
+ 101, 101, 259,
+ 102, 113, 105,
+ 114, 114, 260,
+ 115, 122, 105
};
-static const int lexer_goto_row199[] = {
+static const int lexer_goto_row202[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row200[] = {
+static const int lexer_goto_row203[] = {
3,
48, 100, -45,
- 101, 101, 258,
- 102, 122, 103
+ 101, 101, 261,
+ 102, 122, 105
};
-static const int lexer_goto_row201[] = {
+static const int lexer_goto_row204[] = {
3,
48, 100, -45,
- 101, 101, 259,
- 102, 122, 103
+ 101, 101, 262,
+ 102, 122, 105
};
-static const int lexer_goto_row202[] = {
+static const int lexer_goto_row205[] = {
3,
- 48, 111, -120,
- 112, 112, 260,
- 113, 122, 103
+ 48, 111, -122,
+ 112, 112, 263,
+ 113, 122, 105
};
-static const int lexer_goto_row203[] = {
+static const int lexer_goto_row206[] = {
3,
- 48, 116, -138,
- 117, 117, 261,
- 118, 122, 103
+ 48, 116, -140,
+ 117, 117, 264,
+ 118, 122, 105
};
-static const int lexer_goto_row204[] = {
+static const int lexer_goto_row207[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row205[] = {
+static const int lexer_goto_row208[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row206[] = {
+static const int lexer_goto_row209[] = {
3,
48, 107, -37,
- 108, 108, 262,
- 109, 122, 103
+ 108, 108, 265,
+ 109, 122, 105
};
-static const int lexer_goto_row207[] = {
+static const int lexer_goto_row210[] = {
3,
48, 100, -45,
- 101, 101, 263,
- 102, 122, 103
+ 101, 101, 266,
+ 102, 122, 105
};
-static const int lexer_goto_row208[] = {
+static const int lexer_goto_row211[] = {
4,
48, 95, -35,
- 97, 106, 103,
- 107, 107, 264,
- 108, 122, 103
+ 97, 106, 105,
+ 107, 107, 267,
+ 108, 122, 105
};
-static const int lexer_goto_row209[] = {
+static const int lexer_goto_row212[] = {
4,
48, 95, -35,
- 97, 117, 103,
- 118, 118, 265,
- 119, 122, 103
-};
-static const int lexer_goto_row210[] = {
- 3,
- 48, 115, -115,
- 116, 116, 266,
- 117, 122, 103
-};
-static const int lexer_goto_row211[] = {
- 3,
- 48, 107, -37,
- 108, 108, 267,
- 109, 122, 103
-};
-static const int lexer_goto_row212[] = {
- 3,
- 48, 100, -45,
- 101, 101, 268,
- 102, 122, 103
+ 97, 117, 105,
+ 118, 118, 268,
+ 119, 122, 105
};
static const int lexer_goto_row213[] = {
3,
- 48, 116, -138,
- 117, 117, 269,
- 118, 122, 103
+ 48, 115, -117,
+ 116, 116, 269,
+ 117, 122, 105
};
static const int lexer_goto_row214[] = {
3,
- 48, 101, -42,
- 102, 102, 270,
- 103, 122, 103
+ 48, 107, -37,
+ 108, 108, 270,
+ 109, 122, 105
};
static const int lexer_goto_row215[] = {
3,
48, 100, -45,
101, 101, 271,
- 102, 122, 103
+ 102, 122, 105
};
static const int lexer_goto_row216[] = {
3,
- 48, 109, -46,
- 110, 110, 272,
- 111, 122, 103
+ 48, 116, -140,
+ 117, 117, 272,
+ 118, 122, 105
};
static const int lexer_goto_row217[] = {
3,
- 48, 100, -45,
- 101, 101, 273,
- 102, 122, 103
+ 48, 101, -42,
+ 102, 102, 273,
+ 103, 122, 105
};
static const int lexer_goto_row218[] = {
3,
48, 100, -45,
101, 101, 274,
- 102, 122, 103
+ 102, 122, 105
};
static const int lexer_goto_row219[] = {
3,
- 48, 117, -210,
- 118, 118, 275,
- 119, 122, 103
+ 48, 109, -46,
+ 110, 110, 275,
+ 111, 122, 105
};
static const int lexer_goto_row220[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 100, -45,
+ 101, 101, 276,
+ 102, 122, 105
};
static const int lexer_goto_row221[] = {
3,
- 48, 107, -37,
- 108, 108, 276,
- 109, 122, 103
+ 48, 100, -45,
+ 101, 101, 277,
+ 102, 122, 105
};
static const int lexer_goto_row222[] = {
3,
- 48, 103, -50,
- 104, 104, 277,
- 105, 122, 103
+ 48, 117, -213,
+ 118, 118, 278,
+ 119, 122, 105
};
static const int lexer_goto_row223[] = {
1,
- 0, 255, -145
+ 48, 122, -41
};
static const int lexer_goto_row224[] = {
- 11,
- 0, 9, 278,
- 10, 10, 279,
- 11, 12, 278,
- 13, 13, 280,
- 14, 33, 278,
- 34, 34, 281,
- 35, 91, 278,
- 92, 92, 282,
- 93, 122, 278,
- 123, 123, 283,
- 124, 255, 278
+ 3,
+ 48, 107, -37,
+ 108, 108, 279,
+ 109, 122, 105
};
static const int lexer_goto_row225[] = {
- 1,
- 0, 255, -151
+ 3,
+ 48, 103, -50,
+ 104, 104, 280,
+ 105, 122, 105
};
static const int lexer_goto_row226[] = {
1,
- 0, 255, -151
+ 0, 255, -147
};
static const int lexer_goto_row227[] = {
- 1,
- 0, 255, -151
+ 11,
+ 0, 9, 281,
+ 10, 10, 282,
+ 11, 12, 281,
+ 13, 13, 283,
+ 14, 33, 281,
+ 34, 34, 284,
+ 35, 91, 281,
+ 92, 92, 285,
+ 93, 122, 281,
+ 123, 123, 286,
+ 124, 255, 281
};
static const int lexer_goto_row228[] = {
- 5,
- 0, 33, -151,
- 34, 34, 284,
- 35, 122, -151,
- 123, 123, 285,
- 124, 255, 224
+ 1,
+ 0, 255, -153
};
static const int lexer_goto_row229[] = {
- 3,
- 0, 9, 286,
- 11, 12, 286,
- 14, 255, 286
+ 1,
+ 0, 255, -153
};
static const int lexer_goto_row230[] = {
+ 1,
+ 0, 255, -153
+};
+static const int lexer_goto_row231[] = {
5,
- 0, 33, -151,
+ 0, 33, -153,
34, 34, 287,
- 35, 122, -151,
+ 35, 122, -153,
123, 123, 288,
- 124, 255, 224
-};
-static const int lexer_goto_row231[] = {
- 1,
- 0, 255, -155
+ 124, 255, 227
};
static const int lexer_goto_row232[] = {
- 1,
- 0, 255, -155
+ 3,
+ 0, 9, 289,
+ 11, 12, 289,
+ 14, 255, 289
};
static const int lexer_goto_row233[] = {
- 1,
- 0, 255, -155
+ 5,
+ 0, 33, -153,
+ 34, 34, 290,
+ 35, 122, -153,
+ 123, 123, 291,
+ 124, 255, 227
};
static const int lexer_goto_row234[] = {
- 9,
- 0, 9, 289,
- 10, 10, 290,
- 11, 12, 289,
- 13, 13, 291,
- 14, 38, 289,
- 39, 39, 292,
- 40, 91, 289,
- 92, 92, 293,
- 93, 255, 289
+ 1,
+ 0, 255, -157
};
static const int lexer_goto_row235[] = {
- 3,
- 0, 9, 294,
- 11, 12, 294,
- 14, 255, 294
-};
-static const int lexer_goto_row237[] = {
1,
- 56, 56, 295
+ 0, 255, -157
};
-static const int lexer_goto_row238[] = {
+static const int lexer_goto_row236[] = {
1,
- 56, 56, 296
+ 0, 255, -157
};
-static const int lexer_goto_row239[] = {
- 1,
- 56, 56, 297
+static const int lexer_goto_row237[] = {
+ 9,
+ 0, 9, 292,
+ 10, 10, 293,
+ 11, 12, 292,
+ 13, 13, 294,
+ 14, 38, 292,
+ 39, 39, 295,
+ 40, 91, 292,
+ 92, 92, 296,
+ 93, 255, 292
+};
+static const int lexer_goto_row238[] = {
+ 3,
+ 0, 9, 297,
+ 11, 12, 297,
+ 14, 255, 297
};
static const int lexer_goto_row240[] = {
1,
- 98, 98, 298
+ 56, 56, 298
};
static const int lexer_goto_row241[] = {
1,
- 0, 255, -101
+ 56, 56, 299
};
static const int lexer_goto_row242[] = {
1,
- 0, 255, -101
+ 56, 56, 300
+};
+static const int lexer_goto_row243[] = {
+ 1,
+ 98, 98, 301
};
static const int lexer_goto_row244[] = {
- 3,
- 48, 115, -115,
- 116, 116, 299,
- 117, 122, 103
+ 1,
+ 0, 255, -103
};
static const int lexer_goto_row245[] = {
- 3,
- 48, 113, -36,
- 114, 114, 300,
- 115, 122, 103
-};
-static const int lexer_goto_row246[] = {
- 3,
- 48, 113, -36,
- 114, 114, 301,
- 115, 122, 103
+ 1,
+ 0, 255, -103
};
static const int lexer_goto_row247[] = {
3,
- 48, 106, -209,
- 107, 107, 302,
- 108, 122, 103
+ 48, 115, -117,
+ 116, 116, 302,
+ 117, 122, 105
};
static const int lexer_goto_row248[] = {
3,
- 48, 114, -108,
- 115, 115, 303,
- 116, 122, 103
+ 48, 113, -36,
+ 114, 114, 303,
+ 115, 122, 105
};
static const int lexer_goto_row249[] = {
3,
- 48, 104, -121,
- 105, 105, 304,
- 106, 122, 103
+ 48, 113, -36,
+ 114, 114, 304,
+ 115, 122, 105
};
static const int lexer_goto_row250[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 106, -212,
+ 107, 107, 305,
+ 108, 122, 105
};
static const int lexer_goto_row251[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 114, -110,
+ 115, 115, 306,
+ 116, 122, 105
};
static const int lexer_goto_row252[] = {
3,
- 48, 113, -36,
- 114, 114, 305,
- 115, 122, 103
+ 48, 104, -123,
+ 105, 105, 307,
+ 106, 122, 105
};
static const int lexer_goto_row253[] = {
- 3,
- 48, 100, -45,
- 101, 101, 306,
- 102, 122, 103
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row254[] = {
- 3,
- 48, 104, -121,
- 105, 105, 307,
- 106, 122, 103
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row255[] = {
3,
48, 113, -36,
114, 114, 308,
- 115, 122, 103
+ 115, 122, 105
};
static const int lexer_goto_row256[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 100, -45,
+ 101, 101, 309,
+ 102, 122, 105
};
static const int lexer_goto_row257[] = {
3,
- 48, 113, -36,
- 114, 114, 309,
- 115, 122, 103
+ 48, 104, -123,
+ 105, 105, 310,
+ 106, 122, 105
};
static const int lexer_goto_row258[] = {
3,
- 48, 116, -138,
- 117, 117, 310,
- 118, 122, 103
+ 48, 113, -36,
+ 114, 114, 311,
+ 115, 122, 105
};
static const int lexer_goto_row259[] = {
- 3,
- 48, 115, -115,
- 116, 116, 311,
- 117, 122, 103
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row260[] = {
3,
- 48, 107, -37,
- 108, 108, 312,
- 109, 122, 103
+ 48, 113, -36,
+ 114, 114, 312,
+ 115, 122, 105
};
static const int lexer_goto_row261[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 116, -140,
+ 117, 117, 313,
+ 118, 122, 105
};
static const int lexer_goto_row262[] = {
3,
- 48, 107, -37,
- 108, 108, 313,
- 109, 122, 103
+ 48, 115, -117,
+ 116, 116, 314,
+ 117, 122, 105
};
static const int lexer_goto_row263[] = {
3,
- 48, 95, -35,
- 97, 97, 314,
- 98, 122, 103
+ 48, 107, -37,
+ 108, 108, 315,
+ 109, 122, 105
};
static const int lexer_goto_row264[] = {
1,
};
static const int lexer_goto_row265[] = {
3,
- 48, 95, -35,
- 97, 97, 315,
- 98, 122, 103
+ 48, 107, -37,
+ 108, 108, 316,
+ 109, 122, 105
};
static const int lexer_goto_row266[] = {
3,
48, 95, -35,
- 97, 97, 316,
- 98, 122, 103
+ 97, 97, 317,
+ 98, 122, 105
};
static const int lexer_goto_row267[] = {
- 3,
- 48, 100, -45,
- 101, 101, 317,
- 102, 122, 103
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row268[] = {
3,
- 48, 104, -121,
- 105, 105, 318,
- 106, 122, 103
+ 48, 95, -35,
+ 97, 97, 318,
+ 98, 122, 105
};
static const int lexer_goto_row269[] = {
3,
- 48, 101, -42,
- 102, 102, 319,
- 103, 122, 103
+ 48, 95, -35,
+ 97, 97, 319,
+ 98, 122, 105
};
static const int lexer_goto_row270[] = {
3,
- 48, 113, -36,
- 114, 114, 320,
- 115, 122, 103
+ 48, 100, -45,
+ 101, 101, 320,
+ 102, 122, 105
};
static const int lexer_goto_row271[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 104, -123,
+ 105, 105, 321,
+ 106, 122, 105
};
static const int lexer_goto_row272[] = {
3,
- 48, 113, -36,
- 114, 114, 321,
- 115, 122, 103
+ 48, 101, -42,
+ 102, 102, 322,
+ 103, 122, 105
};
static const int lexer_goto_row273[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 113, -36,
+ 114, 114, 323,
+ 115, 122, 105
};
static const int lexer_goto_row274[] = {
1,
48, 122, -41
};
static const int lexer_goto_row275[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 113, -36,
+ 114, 114, 324,
+ 115, 122, 105
};
static const int lexer_goto_row276[] = {
- 3,
- 48, 100, -45,
- 101, 101, 322,
- 102, 122, 103
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row277[] = {
- 3,
- 48, 100, -45,
- 101, 101, 323,
- 102, 122, 103
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row278[] = {
1,
48, 122, -41
};
static const int lexer_goto_row279[] = {
- 1,
- 0, 255, -225
+ 3,
+ 48, 100, -45,
+ 101, 101, 325,
+ 102, 122, 105
};
static const int lexer_goto_row280[] = {
- 11,
- 0, 9, 324,
- 10, 10, 279,
- 11, 12, 324,
- 13, 13, 280,
- 14, 33, 324,
- 34, 34, 325,
- 35, 91, 324,
- 92, 92, 326,
- 93, 122, 324,
- 123, 123, 327,
- 124, 255, 324
+ 3,
+ 48, 100, -45,
+ 101, 101, 326,
+ 102, 122, 105
};
static const int lexer_goto_row281[] = {
1,
- 0, 255, -281
+ 48, 122, -41
};
static const int lexer_goto_row282[] = {
- 5,
- 0, 33, -281,
- 34, 34, 328,
- 35, 122, -281,
- 123, 123, 329,
- 124, 255, 324
+ 1,
+ 0, 255, -228
};
static const int lexer_goto_row283[] = {
- 3,
- 0, 9, 330,
- 11, 12, 330,
- 14, 255, 330
+ 11,
+ 0, 9, 327,
+ 10, 10, 282,
+ 11, 12, 327,
+ 13, 13, 283,
+ 14, 33, 327,
+ 34, 34, 328,
+ 35, 91, 327,
+ 92, 92, 329,
+ 93, 122, 327,
+ 123, 123, 330,
+ 124, 255, 327
};
static const int lexer_goto_row284[] = {
+ 1,
+ 0, 255, -284
+};
+static const int lexer_goto_row285[] = {
5,
- 0, 33, -281,
+ 0, 33, -284,
34, 34, 331,
- 35, 122, -281,
+ 35, 122, -284,
123, 123, 332,
- 124, 255, 324
-};
-static const int lexer_goto_row285[] = {
- 3,
- 0, 33, -151,
- 34, 34, 333,
- 35, 255, -229
+ 124, 255, 327
};
static const int lexer_goto_row286[] = {
3,
- 0, 122, -231,
- 123, 123, 334,
- 124, 255, 224
+ 0, 9, 333,
+ 11, 12, 333,
+ 14, 255, 333
};
static const int lexer_goto_row287[] = {
- 1,
- 0, 255, -151
+ 5,
+ 0, 33, -284,
+ 34, 34, 334,
+ 35, 122, -284,
+ 123, 123, 335,
+ 124, 255, 327
};
static const int lexer_goto_row288[] = {
3,
- 0, 33, -151,
- 34, 34, 335,
- 35, 255, -229
+ 0, 33, -153,
+ 34, 34, 336,
+ 35, 255, -232
};
static const int lexer_goto_row289[] = {
3,
- 0, 122, -231,
- 123, 123, 336,
- 124, 255, 224
+ 0, 122, -234,
+ 123, 123, 337,
+ 124, 255, 227
};
static const int lexer_goto_row290[] = {
1,
- 0, 255, -155
+ 0, 255, -153
};
static const int lexer_goto_row291[] = {
- 1,
- 0, 255, -155
+ 3,
+ 0, 33, -153,
+ 34, 34, 338,
+ 35, 255, -232
};
static const int lexer_goto_row292[] = {
- 1,
- 0, 255, -155
+ 3,
+ 0, 122, -234,
+ 123, 123, 339,
+ 124, 255, 227
};
static const int lexer_goto_row293[] = {
- 9,
- 0, 9, 337,
- 10, 10, 338,
- 11, 12, 337,
- 13, 13, 339,
- 14, 38, 337,
- 39, 39, 340,
- 40, 91, 337,
- 92, 92, 341,
- 93, 255, 337
+ 1,
+ 0, 255, -157
};
static const int lexer_goto_row294[] = {
- 3,
- 0, 9, 342,
- 11, 12, 342,
- 14, 255, 342
+ 1,
+ 0, 255, -157
};
static const int lexer_goto_row295[] = {
1,
- 0, 255, -155
+ 0, 255, -157
+};
+static const int lexer_goto_row296[] = {
+ 9,
+ 0, 9, 340,
+ 10, 10, 341,
+ 11, 12, 340,
+ 13, 13, 342,
+ 14, 38, 340,
+ 39, 39, 343,
+ 40, 91, 340,
+ 92, 92, 344,
+ 93, 255, 340
+};
+static const int lexer_goto_row297[] = {
+ 3,
+ 0, 9, 345,
+ 11, 12, 345,
+ 14, 255, 345
+};
+static const int lexer_goto_row298[] = {
+ 1,
+ 0, 255, -157
};
-static const int lexer_goto_row299[] = {
+static const int lexer_goto_row302[] = {
1,
- 117, 117, 343
+ 117, 117, 346
};
-static const int lexer_goto_row300[] = {
+static const int lexer_goto_row303[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row301[] = {
+static const int lexer_goto_row304[] = {
3,
48, 95, -35,
- 97, 97, 344,
- 98, 122, 103
+ 97, 97, 347,
+ 98, 122, 105
};
-static const int lexer_goto_row302[] = {
+static const int lexer_goto_row305[] = {
3,
- 48, 115, -115,
- 116, 116, 345,
- 117, 122, 103
+ 48, 115, -117,
+ 116, 116, 348,
+ 117, 122, 105
};
-static const int lexer_goto_row303[] = {
+static const int lexer_goto_row306[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row304[] = {
+static const int lexer_goto_row307[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row305[] = {
+static const int lexer_goto_row308[] = {
3,
48, 109, -46,
- 110, 110, 346,
- 111, 122, 103
+ 110, 110, 349,
+ 111, 122, 105
};
-static const int lexer_goto_row306[] = {
+static const int lexer_goto_row309[] = {
3,
48, 109, -46,
- 110, 110, 347,
- 111, 122, 103
+ 110, 110, 350,
+ 111, 122, 105
};
-static const int lexer_goto_row307[] = {
+static const int lexer_goto_row310[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row308[] = {
+static const int lexer_goto_row311[] = {
3,
48, 100, -45,
- 101, 101, 348,
- 102, 122, 103
+ 101, 101, 351,
+ 102, 122, 105
};
-static const int lexer_goto_row309[] = {
+static const int lexer_goto_row312[] = {
3,
- 48, 115, -115,
- 116, 116, 349,
- 117, 122, 103
+ 48, 115, -117,
+ 116, 116, 352,
+ 117, 122, 105
};
-static const int lexer_goto_row310[] = {
+static const int lexer_goto_row313[] = {
3,
48, 101, -42,
- 102, 102, 350,
- 103, 122, 103
+ 102, 102, 353,
+ 103, 122, 105
};
-static const int lexer_goto_row311[] = {
+static const int lexer_goto_row314[] = {
3,
- 48, 99, -107,
- 100, 100, 351,
- 101, 122, 103
+ 48, 99, -109,
+ 100, 100, 354,
+ 101, 122, 105
};
-static const int lexer_goto_row312[] = {
+static const int lexer_goto_row315[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row313[] = {
+static const int lexer_goto_row316[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row314[] = {
+static const int lexer_goto_row317[] = {
3,
48, 100, -45,
- 101, 101, 352,
- 102, 122, 103
+ 101, 101, 355,
+ 102, 122, 105
};
-static const int lexer_goto_row315[] = {
+static const int lexer_goto_row318[] = {
3,
48, 97, -35,
- 98, 98, 353,
- 99, 122, 103
+ 98, 98, 356,
+ 99, 122, 105
};
-static const int lexer_goto_row316[] = {
+static const int lexer_goto_row319[] = {
4,
48, 95, -35,
- 97, 102, 103,
- 103, 103, 354,
- 104, 122, 103
+ 97, 102, 105,
+ 103, 103, 357,
+ 104, 122, 105
};
-static const int lexer_goto_row317[] = {
+static const int lexer_goto_row320[] = {
3,
- 48, 115, -115,
- 116, 116, 355,
- 117, 122, 103
+ 48, 115, -117,
+ 116, 116, 358,
+ 117, 122, 105
};
-static const int lexer_goto_row318[] = {
+static const int lexer_goto_row321[] = {
3,
- 48, 98, -129,
- 99, 99, 356,
- 100, 122, 103
+ 48, 98, -131,
+ 99, 99, 359,
+ 100, 122, 105
};
-static const int lexer_goto_row319[] = {
+static const int lexer_goto_row322[] = {
3,
- 48, 98, -129,
- 99, 99, 357,
- 100, 122, 103
+ 48, 98, -131,
+ 99, 99, 360,
+ 100, 122, 105
};
-static const int lexer_goto_row320[] = {
+static const int lexer_goto_row323[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row321[] = {
+static const int lexer_goto_row324[] = {
3,
48, 109, -46,
- 110, 110, 358,
- 111, 122, 103
+ 110, 110, 361,
+ 111, 122, 105
};
-static const int lexer_goto_row322[] = {
+static const int lexer_goto_row325[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row323[] = {
+static const int lexer_goto_row326[] = {
3,
48, 113, -36,
- 114, 114, 359,
- 115, 122, 103
+ 114, 114, 362,
+ 115, 122, 105
};
-static const int lexer_goto_row324[] = {
+static const int lexer_goto_row327[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row325[] = {
- 1,
- 0, 255, -281
-};
-static const int lexer_goto_row326[] = {
- 1,
- 0, 255, -283
-};
-static const int lexer_goto_row327[] = {
- 3,
- 0, 9, 360,
- 11, 12, 360,
- 14, 255, 360
-};
static const int lexer_goto_row328[] = {
1,
- 0, 255, -285
+ 0, 255, -284
};
static const int lexer_goto_row329[] = {
- 3,
- 0, 33, -281,
- 34, 34, 361,
- 35, 255, -283
+ 1,
+ 0, 255, -286
};
static const int lexer_goto_row330[] = {
3,
- 0, 122, -285,
- 123, 123, 362,
- 124, 255, 324
+ 0, 9, 363,
+ 11, 12, 363,
+ 14, 255, 363
};
static const int lexer_goto_row331[] = {
1,
- 0, 255, -225
+ 0, 255, -288
};
static const int lexer_goto_row332[] = {
3,
- 0, 33, -281,
- 34, 34, 363,
- 35, 255, -283
+ 0, 33, -284,
+ 34, 34, 364,
+ 35, 255, -286
};
static const int lexer_goto_row333[] = {
3,
- 0, 122, -285,
- 123, 123, 364,
- 124, 255, 324
+ 0, 122, -288,
+ 123, 123, 365,
+ 124, 255, 327
};
static const int lexer_goto_row334[] = {
1,
- 34, 34, 365
+ 0, 255, -228
};
static const int lexer_goto_row335[] = {
- 1,
- 0, 255, -290
+ 3,
+ 0, 33, -284,
+ 34, 34, 366,
+ 35, 255, -286
};
static const int lexer_goto_row336[] = {
- 1,
- 0, 255, -286
+ 3,
+ 0, 122, -288,
+ 123, 123, 367,
+ 124, 255, 327
};
static const int lexer_goto_row337[] = {
1,
- 123, 123, 366
+ 34, 34, 368
};
static const int lexer_goto_row338[] = {
1,
- 0, 255, -155
+ 0, 255, -293
};
static const int lexer_goto_row339[] = {
1,
- 0, 255, -155
+ 0, 255, -289
};
static const int lexer_goto_row340[] = {
1,
- 0, 255, -155
+ 123, 123, 369
};
-static const int lexer_goto_row342[] = {
- 3,
- 0, 9, 367,
- 11, 12, 367,
- 14, 255, 367
+static const int lexer_goto_row341[] = {
+ 1,
+ 0, 255, -157
};
-static const int lexer_goto_row343[] = {
+static const int lexer_goto_row342[] = {
1,
- 0, 255, -155
+ 0, 255, -157
};
-static const int lexer_goto_row344[] = {
+static const int lexer_goto_row343[] = {
1,
- 103, 103, 368
+ 0, 255, -157
};
static const int lexer_goto_row345[] = {
3,
- 48, 98, -129,
- 99, 99, 369,
- 100, 122, 103
+ 0, 9, 370,
+ 11, 12, 370,
+ 14, 255, 370
};
static const int lexer_goto_row346[] = {
1,
- 48, 122, -41
+ 0, 255, -157
};
static const int lexer_goto_row347[] = {
- 3,
- 48, 116, -138,
- 117, 117, 370,
- 118, 122, 103
+ 1,
+ 103, 103, 371
};
static const int lexer_goto_row348[] = {
+ 3,
+ 48, 98, -131,
+ 99, 99, 372,
+ 100, 122, 105
+};
+static const int lexer_goto_row349[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row349[] = {
+static const int lexer_goto_row350[] = {
3,
- 48, 114, -108,
- 115, 115, 371,
- 116, 122, 103
+ 48, 116, -140,
+ 117, 117, 373,
+ 118, 122, 105
};
-static const int lexer_goto_row350[] = {
+static const int lexer_goto_row351[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row351[] = {
- 3,
- 48, 95, -35,
- 97, 97, 372,
- 98, 122, 103
-};
static const int lexer_goto_row352[] = {
3,
- 48, 100, -45,
- 101, 101, 373,
- 102, 122, 103
+ 48, 114, -110,
+ 115, 115, 374,
+ 116, 122, 105
};
static const int lexer_goto_row353[] = {
1,
};
static const int lexer_goto_row354[] = {
3,
- 48, 107, -37,
- 108, 108, 374,
- 109, 122, 103
+ 48, 95, -35,
+ 97, 97, 375,
+ 98, 122, 105
};
static const int lexer_goto_row355[] = {
3,
48, 100, -45,
- 101, 101, 375,
- 102, 122, 103
+ 101, 101, 376,
+ 102, 122, 105
};
static const int lexer_goto_row356[] = {
- 3,
- 48, 100, -45,
- 101, 101, 376,
- 102, 122, 103
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row357[] = {
3,
- 48, 115, -115,
- 116, 116, 377,
- 117, 122, 103
+ 48, 107, -37,
+ 108, 108, 377,
+ 109, 122, 105
};
static const int lexer_goto_row358[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 100, -45,
+ 101, 101, 378,
+ 102, 122, 105
};
static const int lexer_goto_row359[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 100, -45,
+ 101, 101, 379,
+ 102, 122, 105
};
static const int lexer_goto_row360[] = {
3,
- 48, 114, -108,
- 115, 115, 378,
- 116, 122, 103
+ 48, 115, -117,
+ 116, 116, 380,
+ 117, 122, 105
};
static const int lexer_goto_row361[] = {
1,
- 0, 255, -281
+ 48, 122, -41
};
static const int lexer_goto_row362[] = {
1,
- 34, 34, 379
+ 48, 122, -41
};
static const int lexer_goto_row363[] = {
- 1,
- 0, 255, -334
+ 3,
+ 48, 114, -110,
+ 115, 115, 381,
+ 116, 122, 105
};
static const int lexer_goto_row364[] = {
1,
- 0, 255, -330
+ 0, 255, -284
};
static const int lexer_goto_row365[] = {
1,
- 123, 123, 380
+ 34, 34, 382
};
static const int lexer_goto_row366[] = {
1,
- 34, 34, 365
+ 0, 255, -337
};
static const int lexer_goto_row367[] = {
1,
- 123, 123, 366
+ 0, 255, -333
};
static const int lexer_goto_row368[] = {
1,
- 0, 255, -155
+ 123, 123, 383
};
static const int lexer_goto_row369[] = {
1,
- 95, 95, 381
+ 34, 34, 368
};
static const int lexer_goto_row370[] = {
- 3,
- 48, 115, -115,
- 116, 116, 382,
- 117, 122, 103
+ 1,
+ 123, 123, 369
};
static const int lexer_goto_row371[] = {
- 3,
- 48, 100, -45,
- 101, 101, 383,
- 102, 122, 103
+ 1,
+ 0, 255, -157
};
static const int lexer_goto_row372[] = {
1,
- 48, 122, -41
+ 95, 95, 384
};
static const int lexer_goto_row373[] = {
3,
- 48, 98, -129,
- 99, 99, 384,
- 100, 122, 103
+ 48, 115, -117,
+ 116, 116, 385,
+ 117, 122, 105
};
static const int lexer_goto_row374[] = {
- 1,
- 48, 122, -41
-};
-static const int lexer_goto_row375[] = {
3,
48, 100, -45,
- 101, 101, 385,
- 102, 122, 103
+ 101, 101, 386,
+ 102, 122, 105
};
-static const int lexer_goto_row376[] = {
+static const int lexer_goto_row375[] = {
1,
48, 122, -41
};
+static const int lexer_goto_row376[] = {
+ 3,
+ 48, 98, -131,
+ 99, 99, 387,
+ 100, 122, 105
+};
static const int lexer_goto_row377[] = {
1,
48, 122, -41
static const int lexer_goto_row378[] = {
3,
48, 100, -45,
- 101, 101, 386,
- 102, 122, 103
+ 101, 101, 388,
+ 102, 122, 105
};
static const int lexer_goto_row379[] = {
- 3,
- 48, 95, -35,
- 97, 97, 387,
- 98, 122, 103
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row380[] = {
1,
- 34, 34, 379
+ 48, 122, -41
};
static const int lexer_goto_row381[] = {
- 1,
- 123, 123, 380
+ 3,
+ 48, 100, -45,
+ 101, 101, 389,
+ 102, 122, 105
};
static const int lexer_goto_row382[] = {
- 1,
- 95, 95, 388
+ 3,
+ 48, 95, -35,
+ 97, 97, 390,
+ 98, 122, 105
};
static const int lexer_goto_row383[] = {
1,
- 48, 122, -41
+ 34, 34, 382
};
static const int lexer_goto_row384[] = {
1,
- 48, 122, -41
+ 123, 123, 383
};
static const int lexer_goto_row385[] = {
- 3,
- 48, 100, -45,
- 101, 101, 389,
- 102, 122, 103
+ 1,
+ 95, 95, 391
};
static const int lexer_goto_row386[] = {
1,
48, 122, -41
};
static const int lexer_goto_row387[] = {
- 3,
- 48, 99, -107,
- 100, 100, 390,
- 101, 122, 103
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row388[] = {
3,
- 48, 107, -37,
- 108, 108, 391,
- 109, 122, 103
+ 48, 100, -45,
+ 101, 101, 392,
+ 102, 122, 105
};
-static const int lexer_goto_row390[] = {
+static const int lexer_goto_row389[] = {
1,
48, 122, -41
};
+static const int lexer_goto_row390[] = {
+ 3,
+ 48, 99, -109,
+ 100, 100, 393,
+ 101, 122, 105
+};
static const int lexer_goto_row391[] = {
+ 3,
+ 48, 107, -37,
+ 108, 108, 394,
+ 109, 122, 105
+};
+static const int lexer_goto_row393[] = {
+ 1,
+ 48, 122, -41
+};
+static const int lexer_goto_row394[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row392[] = {
+static const int lexer_goto_row395[] = {
1,
48, 122, -41
};
lexer_goto_row84,
lexer_goto_row85,
lexer_goto_row86,
- lexer_goto_row_null,
+ lexer_goto_row87,
lexer_goto_row88,
- lexer_goto_row89,
+ lexer_goto_row_null,
+ lexer_goto_row90,
+ lexer_goto_row91,
lexer_goto_row_null,
lexer_goto_row_null,
- lexer_goto_row92,
- lexer_goto_row93,
lexer_goto_row94,
lexer_goto_row95,
lexer_goto_row96,
- lexer_goto_row_null,
+ lexer_goto_row97,
lexer_goto_row98,
- lexer_goto_row99,
+ lexer_goto_row_null,
lexer_goto_row100,
lexer_goto_row101,
lexer_goto_row102,
lexer_goto_row140,
lexer_goto_row141,
lexer_goto_row142,
- lexer_goto_row_null,
+ lexer_goto_row143,
lexer_goto_row144,
lexer_goto_row_null,
lexer_goto_row146,
lexer_goto_row148,
lexer_goto_row_null,
lexer_goto_row150,
- lexer_goto_row151,
+ lexer_goto_row_null,
+ lexer_goto_row152,
+ lexer_goto_row153,
lexer_goto_row_null,
lexer_goto_row_null,
- lexer_goto_row154,
- lexer_goto_row155,
+ lexer_goto_row156,
+ lexer_goto_row157,
lexer_goto_row_null,
lexer_goto_row_null,
- lexer_goto_row158,
- lexer_goto_row159,
lexer_goto_row160,
lexer_goto_row161,
lexer_goto_row162,
lexer_goto_row167,
lexer_goto_row168,
lexer_goto_row169,
+ lexer_goto_row170,
+ lexer_goto_row171,
+ lexer_goto_row172,
lexer_goto_row_null,
lexer_goto_row_null,
lexer_goto_row_null,
lexer_goto_row_null,
- lexer_goto_row174,
- lexer_goto_row175,
- lexer_goto_row176,
lexer_goto_row177,
lexer_goto_row178,
lexer_goto_row179,
lexer_goto_row233,
lexer_goto_row234,
lexer_goto_row235,
- lexer_goto_row_null,
+ lexer_goto_row236,
lexer_goto_row237,
lexer_goto_row238,
- lexer_goto_row239,
+ lexer_goto_row_null,
lexer_goto_row240,
lexer_goto_row241,
lexer_goto_row242,
- lexer_goto_row_null,
+ lexer_goto_row243,
lexer_goto_row244,
lexer_goto_row245,
- lexer_goto_row246,
+ lexer_goto_row_null,
lexer_goto_row247,
lexer_goto_row248,
lexer_goto_row249,
lexer_goto_row293,
lexer_goto_row294,
lexer_goto_row295,
+ lexer_goto_row296,
+ lexer_goto_row297,
+ lexer_goto_row298,
lexer_goto_row_null,
lexer_goto_row_null,
lexer_goto_row_null,
- lexer_goto_row299,
- lexer_goto_row300,
- lexer_goto_row301,
lexer_goto_row302,
lexer_goto_row303,
lexer_goto_row304,
lexer_goto_row338,
lexer_goto_row339,
lexer_goto_row340,
- lexer_goto_row_null,
+ lexer_goto_row341,
lexer_goto_row342,
lexer_goto_row343,
- lexer_goto_row344,
+ lexer_goto_row_null,
lexer_goto_row345,
lexer_goto_row346,
lexer_goto_row347,
lexer_goto_row386,
lexer_goto_row387,
lexer_goto_row388,
- lexer_goto_row_null,
+ lexer_goto_row389,
lexer_goto_row390,
lexer_goto_row391,
- lexer_goto_row392
+ lexer_goto_row_null,
+ lexer_goto_row393,
+ lexer_goto_row394,
+ lexer_goto_row395
};
const int lexer_accept_table[] = {
- -1,0,1,1,0,94,114,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,114,84,1,86,114,109,-1,110,2,2,2,65,69,115,115,115,78,63,61,62,73,108,64,-1,-1,-1,-1,-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,114,112,-1,111,114,109,114,114,2,113,114,115,66,72,102,102,102,-1,-1,108,103,103,101,101,101,101,104,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,114,114,114,114,114,-1,-1,-1,114,114,114,-1,-1,113,-1,-1,-1,-1,-1,-1,116,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,114,-1,-1,112,-1,111,-1,-1,114,-1,-1,114,114,114,-1,-1,114,106,107,105,-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,114,-1,-1,109,-1,-1,110,114,114,114,109,-1,114,-1,98,38,98,18,98,5,98,98,4,98,98,98,98,19,34,98,-1,112,-1,-1,111,109,110,114,-1,98,98,33,98,22,98,3,21,98,98,112,111,-1,7,35,98,48,98,98,52,8,20,9
+ -1,0,1,1,0,94,114,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,114,84,1,86,114,109,-1,110,2,2,2,65,69,115,115,115,78,63,61,62,73,108,64,-1,100,-1,-1,-1,-1,100,-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,114,112,-1,111,114,109,114,114,2,113,114,115,66,72,102,102,102,-1,-1,108,103,103,101,101,101,101,100,104,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,114,114,114,114,114,-1,-1,-1,114,114,114,-1,-1,113,-1,-1,-1,-1,-1,-1,116,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,114,-1,-1,112,-1,111,-1,-1,114,-1,-1,114,114,114,-1,-1,114,106,107,105,-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,114,-1,-1,109,-1,-1,110,114,114,114,109,-1,114,-1,98,38,98,18,98,5,98,98,4,98,98,98,98,19,34,98,-1,112,-1,-1,111,109,110,114,-1,98,98,33,98,22,98,3,21,98,98,112,111,-1,7,35,98,48,98,98,52,8,20,9
};
static int parser_action_row1[] = {
assert 0b1001 == 0x09
assert 0o715 == 0x1CD
-assert 461 == 0o715
+assert 46_1 == 0o715
assert 0b111001101 == 0o715
-assert 256 == 0x100
-assert 0o400 == 256
+assert 2_56 == 0x100
+assert 0o400 == 2_56
assert 0b1_1100_1101 == 0o715
assert 0b1_1100_1101 == 0x1_CD
assert 0b1000_1001 == 0x89
assert 0b1000_1001u8 == 0x89u8
assert 0o151u8 == 0b0110_1001u8
assert 0x69u8 == 0o151u8
+assert 12_125 == 0x2F5D
+assert 0o27_535 == 1212_5
+assert 2_55u8 == 0xFFu8
first_letter_last_letter
fibonacci_word
shootout_nsieve
+test_ropebuffer
first_letter_last_letter
fibonacci_word
shootout_nsieve
+test_ropebuffer
-base_error_literal.nit:17,9--11: Error: invalid binary literal
-base_error_literal.nit:18,9--11: Error: invalid hexadecimal literal
-base_error_literal.nit:19,9--11: Error: invalid octal literal
+base_error_literal.nit:17,9--11: Error: invalid literal `0b_`
+base_error_literal.nit:18,9--11: Error: invalid literal `0x_`
+base_error_literal.nit:19,9--11: Error: invalid literal `0o_`
--- /dev/null
+Usage: checker xml_file
-../lib/standard/stream.nit:426,6--17: Documentation warning: Undocumented property `buffer_reset`
+../lib/standard/stream.nit:451,6--17: Documentation warning: Undocumented property `buffer_reset`
test_advice_repeated_types.nit:36,15--20: Warning: useless type repetition on redefined attribute `_a`
test_advice_repeated_types.nit:37,18--20: Warning: useless type repetition on parameter `b1` for redefined method `b`
test_advice_repeated_types.nit:38,18--20: Warning: useless type repetition on parameter `c1` for redefined method `c`
--- /dev/null
+# 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.
+
+var rb = new RopeBuffer
+
+for i in [0 .. 1000000[ do
+ rb.add 'S'
+ var s = rb.to_s
+end