From: Jean Privat Date: Mon, 3 Aug 2015 18:35:20 +0000 (-0400) Subject: Merge: nitrpg: fix crash when the Reviews/Work requests return nothing X-Git-Tag: v0.7.8~106^2~3 X-Git-Url: http://nitlanguage.org?hp=093d586020acc76ea56550f8c389b36b997591d8 Merge: nitrpg: fix crash when the Reviews/Work requests return nothing 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 Reviewed-by: Jean Privat --- diff --git a/VERSION b/VERSION index 378c127..b977a66 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v0.7.6 +v0.7.7 diff --git a/contrib/jwrapper/Makefile b/contrib/jwrapper/Makefile index 4a52abf..d8d05e0 100644 --- a/contrib/jwrapper/Makefile +++ b/contrib/jwrapper/Makefile @@ -20,6 +20,10 @@ clean: 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 @@ -31,6 +35,7 @@ check: bin/jwrapper tests/wildcards.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 diff --git a/contrib/jwrapper/examples/android_api/.gitignore b/contrib/jwrapper/examples/android_api/.gitignore index 6e83ff1..2f2c039 100644 --- a/contrib/jwrapper/examples/android_api/.gitignore +++ b/contrib/jwrapper/examples/android_api/.gitignore @@ -1,3 +1,3 @@ -android.nit -std.nit +android_api.nit +java_api.nit tmp/ diff --git a/contrib/jwrapper/examples/android_api/Makefile b/contrib/jwrapper/examples/android_api/Makefile index e26ba9c..e01cb00 100644 --- a/contrib/jwrapper/examples/android_api/Makefile +++ b/contrib/jwrapper/examples/android_api/Makefile @@ -4,11 +4,12 @@ all: android_api.nit 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 diff --git a/contrib/jwrapper/examples/java_api/.gitignore b/contrib/jwrapper/examples/java_api/.gitignore new file mode 100644 index 0000000..f2f6834 --- /dev/null +++ b/contrib/jwrapper/examples/java_api/.gitignore @@ -0,0 +1,5 @@ +java_api.nit +api_user +api_user.res +api_user.jar +tmp/ diff --git a/contrib/jwrapper/examples/java_api/Makefile b/contrib/jwrapper/examples/java_api/Makefile new file mode 100644 index 0000000..a98f013 --- /dev/null +++ b/contrib/jwrapper/examples/java_api/Makefile @@ -0,0 +1,31 @@ +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 diff --git a/contrib/jwrapper/examples/java_api/api_user.nit b/contrib/jwrapper/examples/java_api/api_user.nit new file mode 100644 index 0000000..b0f5a0c --- /dev/null +++ b/contrib/jwrapper/examples/java_api/api_user.nit @@ -0,0 +1,34 @@ +# 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 diff --git a/contrib/jwrapper/examples/java_api/api_user.sav b/contrib/jwrapper/examples/java_api/api_user.sav new file mode 100644 index 0000000..86d17d1 --- /dev/null +++ b/contrib/jwrapper/examples/java_api/api_user.sav @@ -0,0 +1,4 @@ +1234 +5678 +true +0 diff --git a/contrib/jwrapper/examples/queue/Makefile b/contrib/jwrapper/examples/queue/Makefile index a07438c..fc9a0ae 100644 --- a/contrib/jwrapper/examples/queue/Makefile +++ b/contrib/jwrapper/examples/queue/Makefile @@ -1,5 +1,5 @@ # 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 diff --git a/contrib/jwrapper/grammar/javap.sablecc b/contrib/jwrapper/grammar/javap.sablecc index dc46557..718a446 100644 --- a/contrib/jwrapper/grammar/javap.sablecc +++ b/contrib/jwrapper/grammar/javap.sablecc @@ -44,8 +44,8 @@ type_bound | {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 diff --git a/contrib/jwrapper/src/code_generator.nit b/contrib/jwrapper/src/code_generator.nit index 5e3d770..eed951a 100644 --- a/contrib/jwrapper/src/code_generator.nit +++ b/contrib/jwrapper/src/code_generator.nit @@ -66,11 +66,16 @@ class CodeGenerator 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 @@ -80,17 +85,41 @@ class CodeGenerator 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 @@ -123,8 +152,8 @@ class CodeGenerator 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 @@ -132,105 +161,111 @@ class CodeGenerator 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 @@ -255,7 +290,7 @@ class CodeGenerator 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(", ") + ")" @@ -265,11 +300,62 @@ class CodeGenerator 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 @@ -283,10 +369,16 @@ 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 @@ -317,13 +409,13 @@ end 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 @@ -332,15 +424,21 @@ redef class JavaClass 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 diff --git a/contrib/jwrapper/src/javap_visitor.nit b/contrib/jwrapper/src/javap_visitor.nit index c3e5f98..fe81c88 100644 --- a/contrib/jwrapper/src/javap_visitor.nit +++ b/contrib/jwrapper/src/javap_visitor.nit @@ -80,9 +80,20 @@ 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 @@ -90,7 +101,7 @@ redef class Nproperty_declaration_method 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 @@ -106,7 +117,14 @@ redef class Nproperty_declaration_constructor 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 @@ -122,7 +140,11 @@ redef class Nproperty_declaration_attribute 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 @@ -153,7 +175,6 @@ redef class Nbase_type 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 @@ -189,6 +210,41 @@ redef class Nbase_type_void 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 @@ -257,3 +313,32 @@ redef class Nparameter 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 diff --git a/contrib/jwrapper/src/jwrapper.nit b/contrib/jwrapper/src/jwrapper.nit index 04878da..0a84fa9 100644 --- a/contrib/jwrapper/src/jwrapper.nit +++ b/contrib/jwrapper/src/jwrapper.nit @@ -44,7 +44,7 @@ var opt_output = new OptionString("Output file", "-o") 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 @@ -192,6 +192,9 @@ var visitor = new JavaVisitor(model) 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 @@ -203,4 +206,15 @@ sys.perfs["code generator"].add clock.lapse 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 diff --git a/contrib/jwrapper/src/model.nit b/contrib/jwrapper/src/model.nit index 8d6da40..50d54f1 100644 --- a/contrib/jwrapper/src/model.nit +++ b/contrib/jwrapper/src/model.nit @@ -24,7 +24,14 @@ import opts 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? @@ -33,6 +40,16 @@ class JavaType # 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 @@ -42,8 +59,6 @@ class JavaType 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) @@ -80,14 +95,27 @@ class JavaType 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[]`) + redef fun to_s do + var id = self.package_name if self.is_primitive_array then id += "[]" * array_dimension @@ -99,34 +127,24 @@ class JavaType 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 @@ -148,7 +166,7 @@ class JavaClass 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] @@ -160,6 +178,58 @@ class JavaClass 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 @@ -171,15 +241,15 @@ class JavaModel # 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` # @@ -203,16 +273,17 @@ class JavaModel 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 @@ -224,21 +295,62 @@ class JavaModel 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 @@ -257,7 +369,7 @@ end 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) @@ -290,16 +402,16 @@ redef class Sys 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 @@ -322,6 +434,9 @@ redef class Sys # 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 diff --git a/contrib/jwrapper/tests/generics.javap b/contrib/jwrapper/tests/generics.javap new file mode 100644 index 0000000..0753c90 --- /dev/null +++ b/contrib/jwrapper/tests/generics.javap @@ -0,0 +1,6 @@ +public abstract class android.os.asynctask { + 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 execute(params...); +} diff --git a/contrib/jwrapper/tests/statics.javap b/contrib/jwrapper/tests/statics.javap new file mode 100644 index 0000000..a10cc75 --- /dev/null +++ b/contrib/jwrapper/tests/statics.javap @@ -0,0 +1,18 @@ +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); +} diff --git a/contrib/rss_downloader/src/rss_downloader.nit b/contrib/rss_downloader/src/rss_downloader.nit index 323a84e..b5c884b 100644 --- a/contrib/rss_downloader/src/rss_downloader.nit +++ b/contrib/rss_downloader/src/rss_downloader.nit @@ -52,6 +52,12 @@ class Config # 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 @@ -131,6 +137,7 @@ class Downloader 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 @@ -144,7 +151,7 @@ class Downloader if sys.verbose then print "\n# {matches.length} matching elements:" - print matches.join("\n") + print "* " + matches.join("\n* ") print "\n# Downloading..." end @@ -155,13 +162,13 @@ class Downloader # 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 @@ -256,23 +263,36 @@ redef class Text 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 diff --git a/lib/android/audio.nit b/lib/android/audio.nit index 7dd2767..6cec4e1 100644 --- a/lib/android/audio.nit +++ b/lib/android/audio.nit @@ -15,6 +15,13 @@ # 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 @@ -503,28 +510,28 @@ redef class Sound 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 @@ -567,26 +574,26 @@ redef class Music 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 @@ -649,7 +656,7 @@ redef class App # 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) diff --git a/lib/app/audio.nit b/lib/app/audio.nit index 51c0c12..759ed81 100644 --- a/lib/app/audio.nit +++ b/lib/app/audio.nit @@ -15,6 +15,8 @@ # 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 @@ -41,7 +43,7 @@ abstract class PlayableAudio # 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 diff --git a/lib/dom/examples/checker.nit b/lib/dom/examples/checker.nit new file mode 100644 index 0000000..cc3b341 --- /dev/null +++ b/lib/dom/examples/checker.nit @@ -0,0 +1,43 @@ +# 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 diff --git a/lib/java/base.nit b/lib/java/base.nit new file mode 100644 index 0000000..0db04a4 --- /dev/null +++ b/lib/java/base.nit @@ -0,0 +1,195 @@ +# 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 diff --git a/lib/java/collections.nit b/lib/java/collections.nit index 0c24718..097158f 100644 --- a/lib/java/collections.nit +++ b/lib/java/collections.nit @@ -28,7 +28,7 @@ # ~~~ module collections -import java +import base # Java primitive array # diff --git a/lib/java/io.nit b/lib/java/io.nit index 6731c85..40d3f02 100644 --- a/lib/java/io.nit +++ b/lib/java/io.nit @@ -19,7 +19,7 @@ # This module is used by `android::assets_and_resources` and `android::audio`. module io -import java +import base in "Java" `{ import java.io.File; diff --git a/lib/java/java.nit b/lib/java/java.nit index 04e8743..116f40d 100644 --- a/lib/java/java.nit +++ b/lib/java/java.nit @@ -1,7 +1,5 @@ # This file is part of NIT ( http://www.nitlanguage.org ). # -# Copyright 2014 Alexis Laferrière -# # 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 @@ -26,175 +24,7 @@ # 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 diff --git a/lib/standard/collection/abstract_collection.nit b/lib/standard/collection/abstract_collection.nit index 39938bd..5192797 100644 --- a/lib/standard/collection/abstract_collection.nit +++ b/lib/standard/collection/abstract_collection.nit @@ -534,6 +534,16 @@ interface MapRead[K, V] # 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] diff --git a/lib/standard/exec.nit b/lib/standard/exec.nit index 517edf3..3e0d97a 100644 --- a/lib/standard/exec.nit +++ b/lib/standard/exec.nit @@ -272,9 +272,49 @@ class ProcessDuplex 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 diff --git a/lib/standard/file.nit b/lib/standard/file.nit index 849b4e7..e5fc85b 100644 --- a/lib/standard/file.nit +++ b/lib/standard/file.nit @@ -176,6 +176,20 @@ class FileReader 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 @@ -305,16 +319,6 @@ class Stdin 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. diff --git a/lib/standard/stream.nit b/lib/standard/stream.nit index 7218514..ce6e9b3 100644 --- a/lib/standard/stream.nit +++ b/lib/standard/stream.nit @@ -166,7 +166,32 @@ abstract class Reader # 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. # diff --git a/lib/standard/text/abstract_text.nit b/lib/standard/text/abstract_text.nit index 97191d2..cf0d1dc 100644 --- a/lib/standard/text/abstract_text.nit +++ b/lib/standard/text/abstract_text.nit @@ -231,14 +231,103 @@ abstract class Text # 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 @@ -267,6 +356,11 @@ abstract class Text # 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 @@ -335,6 +429,33 @@ abstract class Text 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 diff --git a/lib/standard/text/ropes.nit b/lib/standard/text/ropes.nit index 018217e..08611b7 100644 --- a/lib/standard/text/ropes.nit +++ b/lib/standard/text/ropes.nit @@ -82,6 +82,12 @@ private class Concat 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) @@ -119,9 +125,27 @@ private class Concat 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 @@ -180,6 +204,50 @@ private class Concat 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 @@ -449,7 +517,8 @@ class RopeBuffer redef fun enlarge(i) do end redef fun to_s do - dump_buffer + persist_buffer + written = true return str end diff --git a/misc/vim/syntax/nit.vim b/misc/vim/syntax/nit.vim index 9c3ede7..2930d81 100644 --- a/misc/vim/syntax/nit.vim +++ b/misc/vim/syntax/nit.vim @@ -36,8 +36,9 @@ syn match NITExprSubst "{\([^}]\|\n\)*}" contained 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*" diff --git a/src/literal.nit b/src/literal.nit index eb04e7a..541f752 100644 --- a/src/literal.nit +++ b/src/literal.nit @@ -74,115 +74,69 @@ redef class AExpr 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 diff --git a/src/parser/nit.sablecc3xx b/src/parser/nit.sablecc3xx index 592cc42..3904c1f 100644 --- a/src/parser/nit.sablecc3xx +++ b/src/parser/nit.sablecc3xx @@ -199,11 +199,11 @@ classid = uppercase letter*; 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'; diff --git a/src/parser/tables_nit.c b/src/parser/tables_nit.c index 4fd03ae..23c4d85 100644 --- a/src/parser/tables_nit.c +++ b/src/parser/tables_nit.c @@ -140,258 +140,260 @@ static const int lexer_goto_row19[] = { 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, @@ -399,102 +401,105 @@ static const int lexer_goto_row62[] = { }; 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, @@ -504,873 +509,869 @@ static const int lexer_goto_row96[] = { 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, @@ -1378,450 +1379,450 @@ static const int lexer_goto_row264[] = { }; 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, @@ -1829,114 +1830,116 @@ static const int lexer_goto_row353[] = { }; 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 @@ -1944,66 +1947,80 @@ static const int lexer_goto_row377[] = { 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 }; @@ -2095,19 +2112,19 @@ const int* const lexer_goto_table[] = { 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, @@ -2151,7 +2168,7 @@ const int* const lexer_goto_table[] = { 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, @@ -2159,15 +2176,15 @@ const int* const lexer_goto_table[] = { 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, @@ -2178,13 +2195,13 @@ const int* const lexer_goto_table[] = { 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, @@ -2244,17 +2261,17 @@ const int* const lexer_goto_table[] = { 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, @@ -2304,12 +2321,12 @@ const int* const lexer_goto_table[] = { 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, @@ -2349,10 +2366,10 @@ const int* const lexer_goto_table[] = { 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, @@ -2397,14 +2414,17 @@ const int* const lexer_goto_table[] = { 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[] = { diff --git a/tests/base_test_bases.nit b/tests/base_test_bases.nit index b21c85e..8a1bb4c 100644 --- a/tests/base_test_bases.nit +++ b/tests/base_test_bases.nit @@ -16,13 +16,16 @@ import standard::kernel 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 diff --git a/tests/niti.skip b/tests/niti.skip index 9718dc3..ad78ced 100644 --- a/tests/niti.skip +++ b/tests/niti.skip @@ -29,3 +29,4 @@ input first_letter_last_letter fibonacci_word shootout_nsieve +test_ropebuffer diff --git a/tests/nitvm.skip b/tests/nitvm.skip index 9718dc3..ad78ced 100644 --- a/tests/nitvm.skip +++ b/tests/nitvm.skip @@ -29,3 +29,4 @@ input first_letter_last_letter fibonacci_word shootout_nsieve +test_ropebuffer diff --git a/tests/sav/base_error_literal.res b/tests/sav/base_error_literal.res index a74724b..a376c79 100644 --- a/tests/sav/base_error_literal.res +++ b/tests/sav/base_error_literal.res @@ -1,3 +1,3 @@ -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_` diff --git a/tests/sav/checker.res b/tests/sav/checker.res new file mode 100644 index 0000000..e6fde82 --- /dev/null +++ b/tests/sav/checker.res @@ -0,0 +1 @@ +Usage: checker xml_file diff --git a/tests/sav/nitpick_args1.res b/tests/sav/nitpick_args1.res index 8e55697..f9e2cbb 100644 --- a/tests/sav/nitpick_args1.res +++ b/tests/sav/nitpick_args1.res @@ -1,4 +1,4 @@ -../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` diff --git a/tests/test_ropebuffer.nit b/tests/test_ropebuffer.nit new file mode 100644 index 0000000..aa21a5e --- /dev/null +++ b/tests/test_ropebuffer.nit @@ -0,0 +1,20 @@ +# 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