A big set of loosely coupled but related changed on the annotations on attributes and methods.
Here is a summary of the changes on the user-side:
* No more special case for the kind of classes, so you can use `autoinit` in interfaces.
* Explicit annotation `autoinit` is understood on attributes and is the default on value-less concrete attribute.
* Abstract attributes are `noautoinit` by default, if `autoinit` is given, it is applied on the setter. This way abstract attributes are basically just a couple of getter-setter. close #1311
This way there is less special cases and behaviors. Still more work is required to finish #1322.
Pull-Request: #1433
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Romain Chanoir <chanoir.romain@courrier.uqam.ca>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
end
t.add """
<tr id="total">
- <th>Total</th>
+ <th>Total ({{{participants(db).length}}})</th>
"""
for i in answers(db) do
t.add """<th id="total{{{i.id}}}"><center>{{{i.count(db)}}}"""
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: 24 game
+# SEE: <http://rosettacode.org/wiki/24_game>
+
+redef class Char
+ fun is_op: Bool do return "-+/*".has(self)
+end
+
+# Get `numbers` and `operands` from string `operation` collect with `gets` in `main` function
+# Fill `numbers` and `operands` array with previous extraction
+fun exportation(operation: String, numbers: Array[Int], operands: Array[Char]) do
+ var previous_char: nullable Char = null
+ var number: nullable Int = null
+ var negative = false
+
+ for i in operation.length.times do
+ var current_char = operation[i]
+ var current_int = current_char.to_i
+
+ if (previous_char == null or previous_char.is_op) and current_char == '-' then
+ negative = true
+ continue
+ end
+
+ if current_char.is_digit then
+ if number == null then
+ number = current_int
+ else
+ number = number * 10 + current_int
+ end
+ end
+
+ if negative and (current_char.is_op or i == operation.length - 1) then
+ number = number - number * 2
+ negative = false
+ end
+
+ if (current_char.is_op or i == operation.length - 1) and number != null then
+ numbers.add(number)
+ number = null
+ end
+
+ if not negative and current_char.is_op then
+ operands.add(current_char)
+ end
+ previous_char = current_char
+ end
+ # Update `numbers` and `operands` array in main function with pointer
+end
+
+# Create random numbers between 1 to 9
+fun random: Array[Int] do
+ return [for i in 4.times do 1 + 9.rand]
+end
+
+# Make mathematical operation with `numbers` and `operands` and add the operation result into `random_numbers`
+fun calculation(random_numbers, numbers: Array[Int], operands: Array[Char]) do
+ var number = 0
+ var temp_numbers = numbers.clone
+
+ while temp_numbers.length > 1 do
+ var operand = operands.shift
+ var a = temp_numbers.shift
+ var b = temp_numbers.shift
+
+ if operand == '+' then number = a + b
+ if operand == '-' then number = a - b
+ if operand == '*' then number = a * b
+ if operand == '/' then number = a / b
+
+ temp_numbers.unshift(number)
+ end
+ if number != 0 then random_numbers.add(number)
+end
+
+# Check if used `numbers` exist in the `random_numbers` created
+fun numbers_exists(random_numbers, numbers: Array[Int]): Bool do
+ for number in numbers do
+ if not random_numbers.count(number) >= numbers.count(number) then return false
+ end
+ return true
+end
+
+# Remove `numbers` when they are used
+fun remove_numbers(random_numbers, numbers: Array[Int]) do
+ for number in numbers do random_numbers.remove(number)
+end
+
+# Check if the mathematical `operation` is valid
+fun check(operation: String): Bool do
+ var previous_char: nullable Char = null
+ var next_char: nullable Char = null
+ var next_1_char: nullable Char = null
+
+ for i in operation.length.times do
+ var current_char = operation[i]
+
+ if i + 1 < operation.length then
+ next_char = operation[i + 1]
+ if i + 2 < operation.length then
+ next_1_char = operation[i + 2]
+ else
+ next_1_char = null
+ end
+ else
+ next_char = null
+ end
+
+ if not current_char.is_op and not current_char.is_digit then return false
+ if next_char == null and current_char.is_op then return false
+
+ if previous_char == null then
+ if next_char == null or next_1_char == null then return false
+ if current_char == '-' and not next_char.is_digit then return false
+ if current_char != '-' and not current_char.is_digit then return false
+ else
+ if next_char != null then
+ if previous_char.is_digit and current_char.is_op and
+ not (next_char == '-' and next_1_char != null and
+ next_1_char.is_digit or next_char.is_digit) then
+ return false
+ end
+ end
+ end
+ previous_char = current_char
+ end
+ return true
+end
+
+var random_numbers = new Array[Int]
+var operation = ""
+
+random_numbers = random
+while not random_numbers.has(24) and random_numbers.length > 1 do
+ var numbers = new Array[Int]
+ var operands = new Array[Char]
+
+ print "numbers: " + random_numbers.join(", ")
+ operation = gets
+ if check(operation) then
+ exportation(operation, numbers, operands)
+ if numbers_exists(random_numbers, numbers) then
+ calculation(random_numbers, numbers, operands)
+ remove_numbers(random_numbers, numbers)
+ else
+ print "NUMBERS ERROR!"
+ end
+ else
+ print "STRING ERROR!"
+ end
+end
+
+if random_numbers.has(24) then print "CONGRATULATIONS" else print "YOU LOSE"
`}
# FIXME: Java's `char` are encoded on 16-bits whereas Nit's are on 8-bits.
fun put_char(key: JavaString, value: Char) in "Java" `{
- self.putChar(key, value);
+ self.putChar(key, (char)value);
`}
fun put_short(key: JavaString, value: Int) in "Java" `{
self.putShort(key, (short) value);
char[] java_array = new char[(int)Array_of_Char_length(value)];
for(int i=0; i < java_array.length; ++i)
- java_array[i] = Array_of_Char__index(value, i);
+ java_array[i] = (char)Array_of_Char__index(value, i);
self.putCharArray(key, java_array);
`}
return self.getByte(key, (byte) def_value);
`}
# FIXME: Java's `char` are encoded on 16-bits whereas Nit's are on 8-bits.
- fun get_char(key: JavaString): Char in "Java" `{ return self.getChar(key); `}
+ fun get_char(key: JavaString): Char in "Java" `{ return (int)self.getChar(key); `}
# FIXME: Java's `char` are encoded on 16-bits whereas Nit's are on 8-bits.
fun get_char_with_def_value(key: JavaString, def_value: Char): Char in "Java" `{
- return self.getChar(key, def_value);
+ return (int)self.getChar(key, (char)def_value);
`}
fun get_short(key: JavaString): Int in "Java" `{ return (short) self.getShort(key); `}
fun get_short_with_def_value(key: JavaString, def_value: Int): Int in "Java" `{
if (java_array == null) return nit_array;
for(int i=0; i < java_array.length; ++i)
- Array_of_Char_add(nit_array, java_array[i]);
+ Array_of_Char_add(nit_array, (int)java_array[i]);
return nit_array;
`}
`}
# FIXME: Java's `char` are encoded on 16-bits whereas Nit's are on 8-bits.
fun char_extra(name: JavaString, def_value: Char): Char in "Java" `{
- return self.getCharExtra(name, def_value);
+ return (int)self.getCharExtra(name, (char)def_value);
`}
fun char_sequence_array_extra(name: JavaString): Array[String]
import StringCopyArray, StringCopyArray.add, StringCopyArray.collection in "Java" `{
char[] java_array = new char[(int)Array_of_Char_length(value)];
for (int i=0; i < java_array.length; ++i)
- java_array[i] = Array_of_Char__index(value, i);
+ java_array[i] = (char)Array_of_Char__index(value, i);
return self.putExtra(name, java_array);
`}
#include <endian.h>
// Android compatibility
+ #ifndef be32toh
+ #define be32toh(val) betoh32(val)
+ #define le32toh(val) letoh32(val)
+ #endif
+
#ifndef be64toh
#define be64toh(val) betoh64(val)
- #endif
- #ifndef le64toh
#define le64toh(val) letoh64(val)
#endif
`}
super BinaryStream
# Read a single byte and return `true` if its value is different than 0
+ #
+ # Returns `false` when an error is pending (`last_error != null`).
fun read_bool: Bool do return read_byte != 0
# Get an `Array` of 8 `Bool` by reading a single byte
#
# To be used with `BinaryWriter::write_bits`.
+ #
+ # Returns an array of `false` when an error is pending (`last_error != null`).
fun read_bits: Array[Bool]
do
var int = read_byte
# Read a null terminated string
#
# To be used with `Writer::write_string`.
+ #
+ # Returns a truncated string when an error is pending (`last_error != null`).
fun read_string: String
do
var buf = new FlatBuffer
loop
var byte = read_byte
- if byte == 0x00 then return buf.to_s
+ if byte == null or byte == 0x00 then return buf.to_s
buf.chars.add byte.ascii
end
end
# Read the length as a 64 bits integer, then the content of the block
#
# To be used with `Writer::write_block`.
+ #
+ # Returns a truncated string when an error is pending (`last_error != null`).
fun read_block: String
do
var length = read_int64
#
# Using this format may result in a loss of precision as it uses less bits
# than Nit `Float`.
+ #
+ # Returns `0.0` when an error is pending (`last_error != null`).
fun read_float: Float
do
if last_error != null then return 0.0
`}
# Read a floating point on 64 bits and return it as a `Float`
+ #
+ # Returns `0.0` when an error is pending (`last_error != null`).
fun read_double: Float
do
if last_error != null then return 0.0
#
# Using this format may result in a loss of precision as the length of a
# Nit `Int` may be less than 64 bits on some platforms.
+ #
+ # Returns `0` when an error is pending (`last_error != null`).
fun read_int64: Int
do
if last_error != null then return 0
redef class NativeString
# Get `self` as a `CppString`
fun to_cpp_string(length: Int): CppString in "C++" `{
- return new std::string(self, length);
+ return new std::string(reinterpret_cast<char*>(self), length);
`}
end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Services to manipulate `Date`, `Time` and `DateTime`
+#
+# The services are split in 2 classes:
+#
+# * `Date` handles the year, month and day parts of the date.
+# * `Time` handles the time in hours, minutes and seconds.
+#
+# These are united in `DateTime` for a precise time in a precise day.
+#
+# ~~~
+# var now = new Time.now
+# var midnight = new Time(0, 0, 0)
+# assert now > midnight
+#
+# var nine_thirty = new Time(9, 30, 0)
+# var eleven_twenty = new Time(11, 20, 0)
+# assert eleven_twenty > nine_thirty
+#
+# var pi_day = new Date(2015, 03, 14)
+# var may_the_fourth = new Date(2015, 5, 4)
+# assert pi_day < may_the_fourth
+#
+# var now_t = new DateTime.now
+# var epoch = new DateTime(1970, 1, 1, 0, 0, 0)
+# assert now_t > epoch
+# ~~~
+#
+module date
+
+# A time of the day, composed of an `hour`, a `minute` and a `second` count
+class Time
+ super Comparable
+ redef type OTHER: Time
+
+ # The hour part of this time, between 0 and 23
+ var hour: Int
+
+ # The minute within the hour, between 0 and 59
+ var minute: Int
+
+ # The second within the minute, between 0 and 59
+ var second: Int
+
+ # Get the current time of the day
+ init now do
+ var tm = new Tm.localtime
+ hour = tm.hour
+ minute = tm.min
+ second = tm.sec
+ end
+
+ # Get the difference between two times in second
+ fun diff_time(other: Time): Int do
+ return (hour * 3600 + minute * 60 + second) -
+ (other.hour * 3600 + other.minute * 60 + other.second)
+ end
+
+ redef fun ==(d) do return d isa Time and time_eq(d)
+
+ redef fun <(d) do return self.diff_time(d) < 0
+
+ redef fun hash do return hour * 1024 + minute * 64 + second
+
+ private fun time_eq(other: Time): Bool
+ do
+ return hour * 3600 + minute * 60 + second ==
+ other.hour * 3600 + other.minute * 60 + other.second
+ end
+end
+
+# A date, composed by a `year`, a `month` and a `day`
+class Date
+ super Comparable
+ redef type OTHER: Date
+
+ # Year, ex: 1989
+ var year: Int
+
+ # Month as an integer, `1` for January, `2` for February, etc.
+ var month: Int
+
+ # Day of the month
+ var day: Int
+
+ # UTC time zone
+ #
+ # FIXME this value is not yet applied
+ var time_zone = "Z"
+
+ # The date of this day
+ init today do
+ var tm = new Tm.localtime
+ year = 1900 + tm.year
+ month = tm.mon + 1
+ day = tm.mday
+ end
+
+ # `self` formatted according to ISO 8601
+ redef fun to_s do return "{year}-{month}-{day}"
+
+ # Difference in days between `self` and `other`
+ fun diff_days(other: Date): Int
+ do
+ var y_out = year - other.year
+ y_out = y_out * 365
+ var m_out = month - other.month
+ m_out = m_out * 30 # FIXME
+ return day - other.day + m_out + y_out
+ end
+
+ # Difference in months between `self` and `other`
+ fun diff_months(other: Date): Int
+ do
+ var y_out = year - other.year
+ y_out = y_out * 12
+ return month - other.month + y_out
+ end
+
+ # Difference in years between `self` and `other`
+ fun diff_years(other: Date): Int do return year - other.year
+
+ redef fun ==(d) do return d isa Date and self.diff_days(d) == 0
+
+ redef fun hash do return year + month * 1024 + day * 2048
+
+ redef fun <(d) do return self.diff_days(d) < 0
+
+ # Is `self` is between the years of `a` and `b`?
+ private fun is_between_years(a, b: Date): Bool
+ do
+ return (a.year > year and b.year < year) or (b.year > year and a.year < year) or (a.year == year or b.year == year)
+ end
+
+ # Is `self` is between the months of `a` and `b`?
+ private fun is_between_months(a, b: Date) : Bool
+ do
+ if not self.is_between_years(a,b) then return false
+ return (a.month > month and b.month < month) or (b.month > month and a.month < month) or (a.month == month or b.month == month)
+ end
+
+ # Is `self` between `a` and `b`?
+ redef fun is_between(a, b)
+ do
+ if not self.is_between_months(a, b) then return false
+ return (a.day > day and b.day < day) or (b.day > day and a.day < day) or (a.day == day or b.day == day)
+ end
+end
+
+# A `Time` in a `Date`
+class DateTime
+ super Date
+ super Time
+ redef type OTHER: DateTime
+ autoinit year, month, day, hour, minute, second
+
+ # Get the current `DateTime`
+ init now
+ do
+ super
+ today
+ end
+
+ redef fun ==(other) do return other isa DateTime and diff_days(other) == 0 and time_eq(other)
+
+ redef fun to_s do return "{super} {hour}:{minute}:{second}{time_zone}"
+end
# The first power of `exp` greater or equal to `self`
private fun next_pow(exp: Int): Int
do
- var p = 0
+ var p = 1
while p < self do p = p*exp
return p
end
closed = true
return
end
- var hostname = socket.gethostbyname(host)
- addrin = new NativeSocketAddrIn.with_hostent(hostname, port)
+ var hostname = sys.gethostbyname(host.to_cstring)
+ if hostname.address_is_null then
+ # Error in name lookup
+ var err = sys.h_errno
+ last_error = new IOError(err.to_s)
+
+ closed = true
+ end_reached = true
+
+ return
+ end
+
+ addrin = new NativeSocketAddrIn.with_hostent(hostname, port)
address = addrin.address
init(addrin.port, hostname.h_name)
closed = not internal_connect
end_reached = closed
+ if closed then
+ # Connection failed
+ last_error = new IOError(errno.strerror)
+ end
end
# Creates a client socket, this is meant to be used by accept only
fun descriptor: Int `{ return *self; `}
- fun gethostbyname(n: String): NativeSocketHostent import String.to_cstring `{ return gethostbyname(String_to_cstring(n)); `}
-
fun connect(addrIn: NativeSocketAddrIn): Int `{
return connect(*self, (struct sockaddr*)addrIn, sizeof(*addrIn));
`}
return self | other;
`}
end
+
+redef class Sys
+ # Get network host entry
+ fun gethostbyname(name: NativeString): NativeSocketHostent `{
+ return gethostbyname(name);
+ `}
+
+ # Last error raised by `gethostbyname`
+ fun h_errno: HErrno `{ return h_errno; `}
+end
+
+# Error code of `Sys::h_errno`
+extern class HErrno `{ int `}
+ # The specified host is unknown
+ fun host_not_found: Bool `{ return self == HOST_NOT_FOUND; `}
+
+ # The requested name is valid but does not have an IP address
+ #
+ # Same as `no_data`.
+ fun no_address: Bool `{ return self == NO_ADDRESS; `}
+
+ # The requested name is valid byt does not have an IP address
+ #
+ # Same as `no_address`.
+ fun no_data: Bool `{ return self == NO_DATA; `}
+
+ # A nonrecoverable name server error occurred
+ fun no_recovery: Bool `{ return self == NO_RECOVERY; `}
+
+ # A temporary error occurred on an authoritative name server, try again later
+ fun try_again: Bool `{ return self == TRY_AGAIN; `}
+
+ redef fun to_s
+ do
+ if host_not_found then
+ return "The specified host is unknown"
+ else if no_address then
+ return "The requested name is valid but does not have an IP address"
+ else if no_recovery then
+ return "A nonrecoverable name server error occurred"
+ else if try_again then
+ return "A temporary error occurred on an authoritative name server, try again later"
+ else
+ # This may happen if another call was made to `gethostbyname`
+ # before we fetch the error code.
+ return "Unknown error on `gethostbyname`"
+ end
+ end
+end
return res
end
- # Simplify a file path by remove useless ".", removing "//", and resolving ".."
+ # Simplify a file path by remove useless `.`, removing `//`, and resolving `..`
#
- # * ".." are not resolved if they start the path
- # * starting "/" is not removed
- # * trailing "/" is removed
+ # * `..` are not resolved if they start the path
+ # * starting `.` is simplified unless the path is empty
+ # * starting `/` is not removed
+ # * trailing `/` is removed
#
# Note that the method only work on the string:
#
# assert "dir/..".simplify_path == "."
# assert "//absolute//path/".simplify_path == "/absolute/path"
# assert "//absolute//../".simplify_path == "/"
+ # assert "/".simplify_path == "/"
+ # assert "../".simplify_path == ".."
+ # assert "./".simplify_path == "."
+ # assert "././././././".simplify_path == "."
+ # assert "./../dir".simplify_path == "../dir"
+ # assert "./dir".simplify_path == "dir"
# ~~~
fun simplify_path: String
do
var a = self.split_with("/")
var a2 = new Array[String]
for x in a do
- if x == "." then continue
- if x == "" and not a2.is_empty then continue
+ if x == "." and not a2.is_empty then continue # skip `././`
+ if x == "" and not a2.is_empty then continue # skip `//`
if x == ".." and not a2.is_empty and a2.last != ".." then
- a2.pop
- continue
+ if a2.last == "." then # do not skip `./../`
+ a2.pop # reduce `./../` in `../`
+ else # reduce `dir/../` in `/`
+ a2.pop
+ continue
+ end
+ else if not a2.is_empty and a2.last == "." then
+ a2.pop # reduce `./dir` in `dir`
end
a2.push(x)
end
`--no-main`
: Do not generate main entry point.
-`--stacktrace`
-: Control the generation of stack traces.
+`--no-stacktrace`
+: The compiled program will not display stack traces on runtime errors.
+
+ Because stack traces rely on libunwind, this option might be useful in order to generate more portable binaries
+ since libunwind might be non available on the runtime system (or available with an ABI incompatible version).
+
+ The generated C is API-portable and can be reused, distributed and compiled on any supported system.
+ If the option `--no-stacktrace` is not used but the development files of the library `libunwind` are not available, then a warning will be displayed
+ and stack trace will be disabled.
+
+ Note that the `--no-stacktrace` option (or this absence) can be toggled manually in the generated Makefile (search `NO_STACKTRACE` in the Makefile).
+ Moreover, the environment variable `NIT_NO_STACK` (see bellow) can also be used at runtime to disable stack traces.
`--max-c-lines`
: Maximum number of lines in generated C files. Use 0 for unlimited.
* large: disable the GC and just allocate a large memory area to use for all instantiation.
* help: show the list of available options.
+`NIT_NO_STACK`
+: Runtime control of stack traces.
+
+ By default, stack traces are printed when a runtime errors occurs during the execution of a compiled program.
+ When setting this environment variable to a non empty value, such stack traces are disabled.
+
+ The environment variable is used when programs are executed, not when they are compiled.
+ Thus, you do not need to recompile programs in order to disable generated stack traces.
+
+ Note that stack traces require that, during the compilation, development files of the library `libunwind` are available.
+ If they are not available, then programs are compiled without any stack trace support.
+
+ To completely disable stack traces, see the option `--no-stacktrace`.
+
# SEE ALSO
The Nit language documentation and the source code of its tools and libraries may be downloaded from <http://nitlanguage.org>
# files to compile TODO check is appropriate
var files = new Array[String]
- # Add `c_function` as a `static` function local to this unit
+ # Add a `static` `c_function` to be strictly local to this unit
fun add_local_function(c_function: CFunction)
do
body_decl.add "static {c_function.signature};\n"
body_impl.add c_function.to_writer
end
- # Add `c_function` as a public function to this unit
+ # Add a public `c_function` accessible from outside this compilation unit
fun add_exported_function(c_function: CFunction)
do
- header_decl.add "{c_function.signature};\n"
+ body_decl.add "{c_function.signature};\n"
body_impl.add "\n"
body_impl.add c_function.to_writer
end
var opt_invocation_metrics = new OptionBool("Enable static and dynamic count of all method invocations", "--invocation-metrics")
# --isset-checks-metrics
var opt_isset_checks_metrics = new OptionBool("Enable static and dynamic count of isset checks before attributes access", "--isset-checks-metrics")
- # --stacktrace
- var opt_stacktrace = new OptionString("Control the generation of stack traces", "--stacktrace")
+ # --no-stacktrace
+ var opt_no_stacktrace = new OptionBool("Disable the generation of stack traces", "--no-stacktrace")
# --no-gcc-directives
var opt_no_gcc_directive = new OptionArray("Disable a advanced gcc directives for optimization", "--no-gcc-directive")
# --release
self.option_context.add_option(self.opt_output, self.opt_dir, self.opt_no_cc, self.opt_no_main, self.opt_make_flags, self.opt_compile_dir, self.opt_hardening)
self.option_context.add_option(self.opt_no_check_covariance, self.opt_no_check_attr_isset, self.opt_no_check_assert, self.opt_no_check_autocast, self.opt_no_check_null, self.opt_no_check_all)
self.option_context.add_option(self.opt_typing_test_metrics, self.opt_invocation_metrics, self.opt_isset_checks_metrics)
- self.option_context.add_option(self.opt_stacktrace)
+ self.option_context.add_option(self.opt_no_stacktrace)
self.option_context.add_option(self.opt_no_gcc_directive)
self.option_context.add_option(self.opt_release)
self.option_context.add_option(self.opt_max_c_lines, self.opt_group_c_files)
do
super
- var st = opt_stacktrace.value
- if st == "none" or st == "libunwind" or st == "nitstack" then
- # Fine, do nothing
- else if st == "auto" or st == null then
- # Default is nitstack
- opt_stacktrace.value = "nitstack"
- else
- print "Option Error: unknown value `{st}` for --stacktrace. Use `none`, `libunwind`, `nitstack` or `auto`."
- exit(1)
- end
-
if opt_output.value != null and opt_dir.value != null then
print "Option Error: cannot use both --dir and --output"
exit(1)
fun write_files(compile_dir: String, cfiles: Array[String])
do
var platform = compiler.target_platform
- if self.toolcontext.opt_stacktrace.value == "nitstack" and platform.supports_libunwind then compiler.build_c_to_nit_bindings
+ if platform.supports_libunwind then compiler.build_c_to_nit_bindings
var cc_opt_with_libgc = "-DWITH_LIBGC"
if not platform.supports_libgc then cc_opt_with_libgc = ""
makefile.write("CC = ccache cc\nCXX = ccache c++\nCFLAGS = -g -O2 -Wno-unused-value -Wno-switch -Wno-attributes\nCINCL =\nLDFLAGS ?= \nLDLIBS ?= -lm {linker_options.join(" ")}\n\n")
- var ost = toolcontext.opt_stacktrace.value
- if (ost == "libunwind" or ost == "nitstack") and platform.supports_libunwind then makefile.write("NEED_LIBUNWIND := YesPlease\n")
+ makefile.write "\n# SPECIAL CONFIGURATION FLAGS\n"
+ if platform.supports_libunwind then
+ if toolcontext.opt_no_stacktrace.value then
+ makefile.write "NO_STACKTRACE=True"
+ else
+ makefile.write "NO_STACKTRACE= # Set to `True` to enable"
+ end
+ end
# Dynamic adaptations
# While `platform` enable complex toolchains, they are statically applied
# For a dynamic adaptsation of the compilation, the generated Makefile should check and adapt things itself
+ makefile.write "\n\n"
# Check and adapt the targeted system
makefile.write("uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')\n")
- makefile.write("ifeq ($(uname_S),Darwin)\n")
- # remove -lunwind since it is already included on macosx
- makefile.write("\tNEED_LIBUNWIND :=\n")
- makefile.write("endif\n\n")
# Check and adapt for the compiler used
# clang need an additionnal `-Qunused-arguments`
makefile.write("clang_check := $(shell sh -c '$(CC) -v 2>&1 | grep -q clang; echo $$?')\nifeq ($(clang_check), 0)\n\tCFLAGS += -Qunused-arguments\nendif\n")
- makefile.write("ifdef NEED_LIBUNWIND\n\tLDLIBS += -lunwind\nendif\n")
+ if platform.supports_libunwind then
+ makefile.write """
+ifneq ($(NO_STACKTRACE), True)
+ # Check and include lib-unwind in a portable way
+ ifneq ($(uname_S),Darwin)
+ # already included on macosx, but need to get the correct flags in other supported platforms.
+ ifeq ($(shell pkg-config --exists 'libunwind'; echo $$?), 0)
+ LDLIBS += `pkg-config --libs libunwind`
+ CFLAGS += `pkg-config --cflags libunwind`
+ else
+ $(warning "[_] stack-traces disabled. Please install libunwind-dev.")
+ CFLAGS += -D NO_STACKTRACE
+ endif
+ endif
+else
+ # Stacktraces disabled
+ CFLAGS += -D NO_STACKTRACE
+endif
+
+"""
+ else
+ makefile.write("CFLAGS += -D NO_STACKTRACE\n\n")
+ end
makefile.write("all: {outpath}\n")
if outpath != real_outpath then
self.header.add_decl("#include <string.h>")
self.header.add_decl("#include <sys/types.h>\n")
self.header.add_decl("#include <unistd.h>\n")
+ self.header.add_decl("#include <stdint.h>\n")
self.header.add_decl("#include \"gc_chooser.h\"")
self.header.add_decl("#ifdef ANDROID")
self.header.add_decl(" #include <android/log.h>")
do
var v = self.new_visitor
v.add_decl("#include <signal.h>")
- var ost = modelbuilder.toolcontext.opt_stacktrace.value
var platform = target_platform
- if not platform.supports_libunwind then ost = "none"
-
var no_main = platform.no_main or modelbuilder.toolcontext.opt_no_main.value
- if ost == "nitstack" or ost == "libunwind" then
+ if platform.supports_libunwind then
+ v.add_decl("#ifndef NO_STACKTRACE")
v.add_decl("#define UNW_LOCAL_ONLY")
v.add_decl("#include <libunwind.h>")
- if ost == "nitstack" then
- v.add_decl("#include \"c_functions_hash.h\"")
- end
+ v.add_decl("#include \"c_functions_hash.h\"")
+ v.add_decl("#endif")
end
v.add_decl("int glob_argc;")
v.add_decl("char **glob_argv;")
end
v.add_decl("static void show_backtrace(void) \{")
- if ost == "nitstack" or ost == "libunwind" then
+ if platform.supports_libunwind then
+ v.add_decl("#ifndef NO_STACKTRACE")
v.add_decl("char* opt = getenv(\"NIT_NO_STACK\");")
v.add_decl("unw_cursor_t cursor;")
v.add_decl("if(opt==NULL)\{")
v.add_decl("PRINT_ERROR(\"-------------------------------------------------\\n\");")
v.add_decl("while (unw_step(&cursor) > 0) \{")
v.add_decl(" unw_get_proc_name(&cursor, procname, 100, &ip);")
- if ost == "nitstack" then
v.add_decl(" const char* recv = get_nit_name(procname, strlen(procname));")
v.add_decl(" if (recv != NULL)\{")
v.add_decl(" PRINT_ERROR(\"` %s\\n\", recv);")
v.add_decl(" \}else\{")
v.add_decl(" PRINT_ERROR(\"` %s\\n\", procname);")
v.add_decl(" \}")
- else
- v.add_decl(" PRINT_ERROR(\"` %s \\n\",procname);")
- end
v.add_decl("\}")
v.add_decl("PRINT_ERROR(\"-------------------------------------------------\\n\");")
v.add_decl("free(procname);")
v.add_decl("\}")
+ v.add_decl("#endif /* NO_STACKTRACE */")
end
v.add_decl("\}")
if nexpr == null then return
if nexpr.mtype == null and not nexpr.is_typed then
# Untyped expression.
- # Might mean dead code
- # So just return
+ # Might mean dead code or invalid code
+ # so aborts
+ add_abort("FATAL: bad statement executed.")
return
end
do
if nexpr.mtype == null then
# Untyped expression.
- # Might mean dead code
- # so return a placebo result
+ # Might mean dead code or invalid code.
+ # so aborts
+ add_abort("FATAL: bad expression executed.")
+ # and return a placebo result to please the C compiler
if mtype == null then mtype = compiler.mainmodule.object_type
return new_var(mtype)
end
else if mclass.name == "Bool" then
return "short int"
else if mclass.name == "Char" then
- return "char"
+ return "uint32_t"
else if mclass.name == "Float" then
return "double"
else if mclass.name == "Byte" then
return "unsigned char"
else if mclass.name == "NativeString" then
- return "char*"
+ return "unsigned char*"
else if mclass.name == "NativeArray" then
return "val*"
else
v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
return true
else if pname == "ascii" then
- v.ret(v.new_expr("{arguments[0]}", ret.as(not null)))
+ v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
return true
end
else if cname == "Char" then
if pname == "output" then
- v.add("printf(\"%c\", {arguments.first});")
+ v.add("printf(\"%c\", ((unsigned char){arguments.first}));")
return true
else if pname == "object_id" then
v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
v.ret(v.new_expr("{arguments[0]}-'0'", ret.as(not null)))
return true
else if pname == "ascii" then
- v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
+ v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
return true
end
else if cname == "Byte" then
end
else if cname == "NativeString" then
if pname == "[]" then
- v.ret(v.new_expr("{arguments[0]}[{arguments[1]}]", ret.as(not null)))
+ v.ret(v.new_expr("(uint32_t){arguments[0]}[{arguments[1]}]", ret.as(not null)))
return true
else if pname == "[]=" then
- v.add("{arguments[0]}[{arguments[1]}]={arguments[2]};")
+ v.add("{arguments[0]}[{arguments[1]}]=(unsigned char){arguments[2]};")
return true
else if pname == "copy_to" then
v.add("memmove({arguments[1]}+{arguments[4]},{arguments[0]}+{arguments[3]},{arguments[2]});")
v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
return true
else if pname == "new" then
- v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null)))
+ v.ret(v.new_expr("(unsigned char*)nit_alloc({arguments[1]})", ret.as(not null)))
return true
end
else if cname == "NativeArray" then
v.ret(v.new_expr("glob_sys", ret.as(not null)))
return true
else if pname == "calloc_string" then
- v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null)))
+ v.ret(v.new_expr("(unsigned char*)nit_alloc({arguments[1]})", ret.as(not null)))
return true
else if pname == "calloc_array" then
v.calloc_array(ret.as(not null), arguments)
ensure_compile_nitni_base(v)
nitni_ccu.header_c_types.add("#include \"{c_name}._ffi.h\"\n")
+ nitni_ccu.header_c_types.add("#include <stdint.h>\n")
nitni_ccu.header_c_types.add """
extern void nitni_global_ref_incr(void*);
extern void nitni_global_ref_decr(void*);
for cd in mmodule.mclassdefs do
for pd in cd.mpropdefs do
if not pd isa MMethodDef then continue
+ if pd.msignature == null then continue # Skip broken method
var rta = runtime_type_analysis
if modelbuilder.toolcontext.opt_skip_dead_methods.value and rta != null and not rta.live_methoddefs.has(pd) then continue
#print "compile {pd} @ {cd} @ {mmodule}"
if mtype.name == "Int" then
return self.new_expr("(long)({value})>>2", mtype)
else if mtype.name == "Char" then
- return self.new_expr("(char)((long)({value})>>2)", mtype)
+ return self.new_expr("(uint32_t)((long)({value})>>2)", mtype)
else if mtype.name == "Bool" then
return self.new_expr("(short int)((long)({value})>>2)", mtype)
else
private fun insert_compiler_options
do
cflags.add_one("", "-I $(JAVA_HOME)/include/ -I $(JAVA_HOME)/include/linux/")
- ldflags.add_one("", "-L $(JNI_LIB_PATH) -ljvm")
end
# Name of the generated Java class where to store all implementation methods of this module
if ftype isa ForeignJavaType then return ftype.java_type.
replace('/', ".").replace('$', ".").replace(' ', "").replace('\n',"")
if mclass.name == "Bool" then return "boolean"
- if mclass.name == "Char" then return "char"
+ if mclass.name == "Char" then return "int"
if mclass.name == "Int" then return "long"
if mclass.name == "Float" then return "double"
if mclass.name == "Byte" then return "byte"
var ftype = mclass.ftype
if ftype isa ForeignJavaType then return "jobject"
if mclass.name == "Bool" then return "jboolean"
- if mclass.name == "Char" then return "jchar"
+ if mclass.name == "Char" then return "jint"
if mclass.name == "Int" then return "jlong"
if mclass.name == "Float" then return "jdouble"
if mclass.name == "Byte" then return "jbyte"
return "L{jni_type};"
end
if mclass.name == "Bool" then return "Z"
- if mclass.name == "Char" then return "C"
+ if mclass.name == "Char" then return "I"
if mclass.name == "Int" then return "J"
if mclass.name == "Float" then return "D"
if mclass.name == "Byte" then return "B"
if ftype isa ForeignJavaType then return "Object"
if mclass.name == "Bool" then return "Boolean"
- if mclass.name == "Char" then return "Char"
+ if mclass.name == "Char" then return "Int"
if mclass.name == "Int" then return "Long"
if mclass.name == "Float" then return "Double"
if mclass.name == "Byte" then return "Byte"
var h_file = "{base_name}.h"
var guard = "{mmodule.c_name.to_upper}_NIT_H"
- write_header_to_file(mmodule, "{compdir}/{h_file}", new Array[String], guard)
+ write_header_to_file(mmodule, "{compdir}/{h_file}", ["<stdint.h>"], guard)
var c_file = "{base_name}.c"
- write_body_to_file(mmodule, "{compdir}/{c_file}", ["<stdlib.h>", "<stdio.h>", "\"{h_file}\""])
+ write_body_to_file(mmodule, "{compdir}/{c_file}", ["<stdlib.h>", "<stdio.h>", "<stdint.h>", "\"{h_file}\""])
files.add( "{compdir}/{c_file}" )
end
do
toolcontext.warning(node.hot_location, tag, msg)
end
+
+ # Issue a warning if `sub` is a standalone `do` block.
+ fun check_do_expr(sub: nullable AExpr)
+ do
+ if sub isa ADoExpr then
+ warning(sub, "useless-do", "Warning: superfluous `do` block.")
+ end
+ end
end
else
n_expr.warn_parentheses(v)
end
+ v.check_do_expr(n_block)
+ end
+end
+
+redef class ADoExpr
+ redef fun after_simple_misc(v)
+ do
+ v.check_do_expr(n_block)
+ end
+end
+
+redef class ALoopExpr
+ redef fun after_simple_misc(v)
+ do
+ v.check_do_expr(n_block)
end
end
redef fun after_simple_misc(v)
do
n_expr.warn_parentheses(v)
+ v.check_do_expr(n_block)
+ end
+end
+
+redef class AWithExpr
+ redef fun after_simple_misc(v)
+ do
+ v.check_do_expr(n_block)
end
end
end
var nit_dir = toolcontext.nit_dir
- var libname = "{nit_dir}/lib"
+ var libname = nit_dir/"lib"
+ if libname.file_exists then paths.add(libname)
+ libname = nit_dir/"contrib"
if libname.file_exists then paths.add(libname)
end
return res
end
+ # Fourth, try if the requested module is itself a group with a src
+ try_file = dirname + "/" + name + "/src/" + name + ".nit"
+ if try_file.file_exists then
+ var res = self.identify_file(try_file.simplify_path)
+ assert res != null
+ return res
+ end
+
c = c.parent
end
end
end
end
+ try_file = (dirname + "/" + name + "/src/" + name + ".nit").simplify_path
+ if try_file.file_exists then
+ if candidate == null then
+ candidate = try_file
+ else if candidate != try_file then
+ # try to disambiguate conflicting modules
+ var abs_candidate = module_absolute_path(candidate)
+ var abs_try_file = module_absolute_path(try_file)
+ if abs_candidate != abs_try_file then
+ toolcontext.error(location, "Error: conflicting module file for `{name}`: `{candidate}` `{try_file}`")
+ end
+ end
+ end
end
if candidate == null then return null
return identify_file(candidate)
# Regeneration of c_src from the current nitc
rm -r ../c_src
-./nitc nith.nit --stacktrace none --semi-global --compile-dir ../c_src --output ../c_src/nitg --no-cc
+./nitc nith.nit --semi-global --compile-dir ../c_src --output ../c_src/nitg --no-cc
# Remove old compilation flags
sed -i -e 's/OLDNITCOPT=.*/OLDNITCOPT=/' Makefile
# Representation of this type in C for the internal of the system
# Hides extern types.
- fun cname_blind: String is abstract
+ fun cname_blind: String do return "struct nitni_instance *"
# Representation of this type in mangled C
# Object -> Object
# Pointer -> Pointer
fun mangled_cname: String is abstract
- # Does this types has a primitive reprensentation
+ # Does this type have a primitive representation?
+ #
# type Object is_primitive? false
# type Pointer is_primitive? true
fun is_cprimitive: Bool is abstract
do
var name = mclass.name
if name == "Bool" then return "int"
- if name == "Char" then return "char"
+ if name == "Char" then return "uint32_t"
if name == "Float" then return "double"
if name == "Int" then return "long"
if name == "Byte" then return "unsigned char"
- if name == "NativeString" then return "char*"
+ if name == "NativeString" then return "unsigned char*"
if mclass.kind == extern_kind then
var ctype = mclass.ctype
assert ctype != null
redef fun cname_blind do
var name = mclass.name
if name == "Bool" then return "int"
- if name == "Char" then return "char"
+ if name == "Char" then return "uint32_t"
if name == "Float" then return "double"
if name == "Int" then return "long"
if name == "Byte" then return "unsigned char"
- if name == "NativeString" then return "char*"
+ if name == "NativeString" then return "unsigned char*"
if mclass.kind == extern_kind then return "void*"
- return "struct nitni_instance *"
+ return super
end
# Name of this type in C for normal classes (not extern and not primitive)
redef fun mangled_cname do return mclass.name
redef fun is_cprimitive do return mclass.kind == extern_kind or
- (once ["Bool", "Char", "Float", "Int", "NativeString"]).has(mclass.name)
+ (once ["Bool", "Char", "Float", "Int", "NativeString", "Byte"]).has(mclass.name)
end
redef class MNullableType
redef fun cname do return mangled_cname
- redef fun cname_blind do return "struct nitni_instance *"
redef fun mangled_cname do return "nullable_{mtype.mangled_cname}"
redef fun is_cprimitive do return false
end
redef class MVirtualType
- redef fun mangled_cname: String do return to_s
+ redef fun mangled_cname do return to_s
end
redef class MGenericType
hex_bytenum = ('0x' | '0X') hexdigit+ 'u8';
bin_bytenum = ('0b' | '0B') bindigit+ 'u8';
oct_bytenum = ('0o' | '0O') octdigit+ 'u8';
-float = digit* '.' digit+;
+float = digit* '.' digit+ | (digit+ | digit* '.' digit+) ('E'|'e') ('+'|'-'|) digit+;
string = '"' str_body '"' | '"' '"' '"' long_str_body lsend1 | ''' ''' ''' long_sstr_body ''' ''' ''';
start_string = '"' str_body '{' | '"' '"' '"' long_str_body lsend2;
mid_string = '}' str_body '{' | '}' '}' '}' long_str_body lsend2;
# May have disappeared in the AST
var next_token: nullable Token = null
+ # Is `self` a token discarded from the AST?
+ #
+ # Loose tokens are not present in the AST.
+ # It means they were identified by the lexer but were discarded by the parser.
+ # It also means that they are not visited or manipulated by AST-related functions.
+ #
+ # Each loose token is attached to the non-loose token that precedes or follows it.
+ # The rules are the following:
+ #
+ # * tokens that follow a non-loose token on a same line are attached to it.
+ # See `next_looses`.
+ # * other tokens, thus that precede a non-loose token on the same line or the next one,
+ # are attached to this one. See `prev_looses`.
+ #
+ # Loose tokens are mostly end of lines (`TEol`) and comments (`TComment`).
+ # Whitespace are ignored by the lexer, so they are not even considered as loose tokens.
+ # See `blank_before` to get the whitespace that separate tokens.
+ var is_loose = false
+
+ # Loose tokens that precede `self`.
+ #
+ # These tokens start the line or belong to a line with only loose tokens.
+ var prev_looses = new Array[Token] is lazy
+
+ # Loose tokens that follow `self`
+ #
+ # These tokens are on the same line than `self`.
+ var next_looses = new Array[Token] is lazy
+
# The verbatim blank text between `prev_token` and `self`
fun blank_before: String
do
var node1 = pop
assert node1 isa AModule
var node = new Start(node1, node2)
- (new ComputeProdLocationVisitor).enter_visit(node)
+ node2.parent = node
+ (new ComputeProdLocationVisitor(lexer.file.first_token)).enter_visit(node)
return node
else if action_type == 3 then # ERROR
# skip injected tokens
# Uses existing token locations to infer location of productions.
private class ComputeProdLocationVisitor
super Visitor
+
+ # The current (or starting) cursor on the token sequence used to collect loose tokens
+ var token: nullable Token
+
# Currently visited productions that need a first token
var need_first_prods = new Array[Prod]
# Already visited epsilon productions that waits something after them
var need_after_epsilons = new Array[Prod]
- # Location of the last visited token in the current production
- var last_location: nullable Location = null
+ # The last visited token in the current production
+ var last_token: nullable Token = null
redef fun visit(n: ANode)
do
if n isa Token then
+ # Skip injected tokens
if not isset n._location then return
+
+ # Collect loose tokens (not in the AST) and attach them to token in the AST
+ var cursor = token
+ if n != cursor then
+ var lt = last_token
+ # In order, we have the tokens:
+ # * `lt` the previous visited token in the AST (if any)
+ # * then `cursor` the loose tokens to attach
+ # * then `n` the current visited token in the AST
+
+ # In the following, we advance `cursor` to add them to `lt.next_looses` or to `n.prev_looses`.
+ if lt != null then
+ var ltl = lt.location.line_end
+ # floating tokens on the same line of a AST-token follows it
+ while cursor != null and cursor != n and ltl == cursor.location.line_start do
+ cursor.is_loose = true
+ lt.next_looses.add cursor
+ cursor = cursor.next_token
+ end
+ end
+ # other loose tokens precede the next AST-token
+ while cursor != null and cursor != n do
+ cursor.is_loose = true
+ n.prev_looses.add cursor
+ cursor = cursor.next_token
+ end
+ end
+ token = n.next_token
+
var loc = n._location
- _last_location = loc
+ _last_token = n
# Add a first token to productions that need one
if not _need_first_prods.is_empty then
var startl = n._first_location
if startl != null then
# Non-epsilon production
- var endl = _last_location
- assert endl != null
+ var endl = _last_token.location
if startl == endl then
n.location = startl
61, 61, 75
};
static const int lexer_goto_row20[] = {
- 9,
+ 11,
46, 46, 76,
48, 57, 20,
66, 66, 77,
- 79, 79, 78,
- 88, 88, 79,
- 98, 98, 80,
- 111, 111, 81,
- 117, 117, 82,
- 120, 120, 83
+ 69, 69, 78,
+ 79, 79, 79,
+ 88, 88, 80,
+ 98, 98, 81,
+ 101, 101, 82,
+ 111, 111, 83,
+ 117, 117, 84,
+ 120, 120, 85
};
static const int lexer_goto_row21[] = {
- 2,
+ 4,
46, 57, -21,
- 117, 117, 82
+ 69, 69, 78,
+ 101, 101, 82,
+ 117, 117, 84
};
static const int lexer_goto_row22[] = {
1,
- 58, 58, 84
+ 58, 58, 86
};
static const int lexer_goto_row24[] = {
2,
- 60, 60, 85,
- 61, 61, 86
+ 60, 60, 87,
+ 61, 61, 88
};
static const int lexer_goto_row25[] = {
1,
- 61, 61, 87
+ 61, 61, 89
};
static const int lexer_goto_row26[] = {
2,
- 61, 61, 88,
- 62, 62, 89
+ 61, 61, 90,
+ 62, 62, 91
};
static const int lexer_goto_row28[] = {
4,
- 48, 57, 90,
- 65, 90, 91,
- 95, 95, 92,
- 97, 122, 93
+ 48, 57, 92,
+ 65, 90, 93,
+ 95, 95, 94,
+ 97, 122, 95
};
static const int lexer_goto_row31[] = {
1,
- 61, 61, 94
+ 61, 61, 96
};
static const int lexer_goto_row32[] = {
2,
- 95, 95, 95,
- 97, 122, 96
+ 95, 95, 97,
+ 97, 122, 98
};
static const int lexer_goto_row33[] = {
1,
- 123, 123, 97
+ 123, 123, 99
};
static const int lexer_goto_row34[] = {
10,
- 48, 57, 98,
- 65, 90, 99,
- 95, 95, 100,
- 97, 97, 101,
- 98, 98, 102,
- 99, 109, 101,
- 110, 110, 103,
- 111, 114, 101,
- 115, 115, 104,
- 116, 122, 101
+ 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
};
static const int lexer_goto_row35[] = {
4,
48, 95, -35,
- 97, 113, 101,
- 114, 114, 105,
- 115, 122, 101
+ 97, 113, 103,
+ 114, 114, 107,
+ 115, 122, 103
};
static const int lexer_goto_row36[] = {
6,
48, 95, -35,
- 97, 107, 101,
- 108, 108, 106,
- 109, 110, 101,
- 111, 111, 107,
- 112, 122, 101
+ 97, 107, 103,
+ 108, 108, 108,
+ 109, 110, 103,
+ 111, 111, 109,
+ 112, 122, 103
};
static const int lexer_goto_row37[] = {
4,
48, 95, -35,
- 97, 110, 101,
- 111, 111, 108,
- 112, 122, 101
+ 97, 110, 103,
+ 111, 111, 110,
+ 112, 122, 103
};
static const int lexer_goto_row38[] = {
7,
48, 107, -37,
- 108, 108, 109,
- 109, 109, 101,
- 110, 110, 110,
- 111, 119, 101,
- 120, 120, 111,
- 121, 122, 101
+ 108, 108, 111,
+ 109, 109, 103,
+ 110, 110, 112,
+ 111, 119, 103,
+ 120, 120, 113,
+ 121, 122, 103
};
static const int lexer_goto_row39[] = {
7,
48, 95, -35,
- 97, 97, 112,
- 98, 110, 101,
- 111, 111, 113,
- 112, 116, 101,
- 117, 117, 114,
- 118, 122, 101
+ 97, 97, 114,
+ 98, 110, 103,
+ 111, 111, 115,
+ 112, 116, 103,
+ 117, 117, 116,
+ 118, 122, 103
};
static const int lexer_goto_row40[] = {
2,
48, 95, -35,
- 97, 122, 101
+ 97, 122, 103
};
static const int lexer_goto_row41[] = {
9,
48, 95, -35,
- 97, 101, 101,
- 102, 102, 115,
- 103, 108, 101,
- 109, 109, 116,
- 110, 110, 117,
- 111, 114, 101,
- 115, 115, 118,
- 116, 122, 101
+ 97, 101, 103,
+ 102, 102, 117,
+ 103, 108, 103,
+ 109, 109, 118,
+ 110, 110, 119,
+ 111, 114, 103,
+ 115, 115, 120,
+ 116, 122, 103
};
static const int lexer_goto_row42[] = {
5,
48, 95, -35,
- 97, 97, 119,
- 98, 110, 101,
- 111, 111, 120,
- 112, 122, 101
+ 97, 97, 121,
+ 98, 110, 103,
+ 111, 111, 122,
+ 112, 122, 103
};
static const int lexer_goto_row43[] = {
3,
48, 110, -38,
- 111, 111, 121,
- 112, 122, 101
+ 111, 111, 123,
+ 112, 122, 103
};
static const int lexer_goto_row44[] = {
8,
48, 95, -35,
- 97, 100, 101,
- 101, 101, 122,
- 102, 110, 101,
- 111, 111, 123,
- 112, 116, 101,
- 117, 117, 124,
- 118, 122, 101
+ 97, 100, 103,
+ 101, 101, 124,
+ 102, 110, 103,
+ 111, 111, 125,
+ 112, 116, 103,
+ 117, 117, 126,
+ 118, 122, 103
};
static const int lexer_goto_row45[] = {
6,
48, 95, -35,
- 97, 109, 101,
- 110, 110, 125,
- 111, 113, 101,
- 114, 114, 126,
- 115, 122, 101
+ 97, 109, 103,
+ 110, 110, 127,
+ 111, 113, 103,
+ 114, 114, 128,
+ 115, 122, 103
};
static const int lexer_goto_row46[] = {
7,
48, 95, -35,
- 97, 97, 127,
- 98, 113, 101,
- 114, 114, 128,
- 115, 116, 101,
- 117, 117, 129,
- 118, 122, 101
+ 97, 97, 129,
+ 98, 113, 103,
+ 114, 114, 130,
+ 115, 116, 103,
+ 117, 117, 131,
+ 118, 122, 103
};
static const int lexer_goto_row47[] = {
3,
48, 100, -45,
- 101, 101, 130,
- 102, 122, 101
+ 101, 101, 132,
+ 102, 122, 103
};
static const int lexer_goto_row48[] = {
5,
48, 100, -45,
- 101, 101, 131,
- 102, 116, 101,
- 117, 117, 132,
- 118, 122, 101
+ 101, 101, 133,
+ 102, 116, 103,
+ 117, 117, 134,
+ 118, 122, 103
};
static const int lexer_goto_row49[] = {
8,
48, 95, -35,
- 97, 103, 101,
- 104, 104, 133,
- 105, 113, 101,
- 114, 114, 134,
- 115, 120, 101,
- 121, 121, 135,
- 122, 122, 101
+ 97, 103, 103,
+ 104, 104, 135,
+ 105, 113, 103,
+ 114, 114, 136,
+ 115, 120, 103,
+ 121, 121, 137,
+ 122, 122, 103
};
static const int lexer_goto_row50[] = {
3,
48, 109, -46,
- 110, 110, 136,
- 111, 122, 101
+ 110, 110, 138,
+ 111, 122, 103
};
static const int lexer_goto_row51[] = {
3,
48, 95, -35,
- 97, 97, 137,
- 98, 122, 101
+ 97, 97, 139,
+ 98, 122, 103
};
static const int lexer_goto_row52[] = {
4,
48, 103, -50,
- 104, 104, 138,
- 105, 105, 139,
- 106, 122, 101
+ 104, 104, 140,
+ 105, 105, 141,
+ 106, 122, 103
};
static const int lexer_goto_row53[] = {
1,
- 61, 61, 140
+ 61, 61, 142
};
static const int lexer_goto_row54[] = {
11,
- 0, 9, 141,
- 11, 12, 141,
- 14, 33, 141,
- 34, 34, 142,
- 35, 91, 141,
- 92, 92, 143,
- 93, 122, 141,
- 123, 123, 144,
- 124, 124, 141,
- 125, 125, 145,
- 126, 255, 141
+ 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
};
static const int lexer_goto_row58[] = {
3,
0, 33, -8,
- 34, 34, 146,
+ 34, 34, 148,
35, 255, -8
};
static const int lexer_goto_row59[] = {
1,
- 34, 34, 147
+ 34, 34, 149
};
static const int lexer_goto_row60[] = {
3,
- 0, 9, 148,
- 11, 12, 148,
- 14, 255, 148
+ 0, 9, 150,
+ 11, 12, 150,
+ 14, 255, 150
};
static const int lexer_goto_row62[] = {
1,
};
static const int lexer_goto_row64[] = {
1,
- 10, 10, 149
+ 10, 10, 151
};
static const int lexer_goto_row67[] = {
1,
- 39, 39, 150
+ 39, 39, 152
};
static const int lexer_goto_row68[] = {
1,
- 39, 39, 151
+ 39, 39, 153
};
static const int lexer_goto_row69[] = {
3,
- 0, 9, 152,
- 11, 12, 152,
- 14, 255, 152
+ 0, 9, 154,
+ 11, 12, 154,
+ 14, 255, 154
};
static const int lexer_goto_row70[] = {
1,
- 61, 61, 153
+ 61, 61, 155
};
static const int lexer_goto_row74[] = {
1,
- 46, 46, 154
+ 46, 46, 156
};
static const int lexer_goto_row75[] = {
- 1,
- 48, 57, 74
+ 2,
+ 48, 57, 74,
+ 69, 101, -22
};
static const int lexer_goto_row77[] = {
1,
};
static const int lexer_goto_row78[] = {
3,
- 48, 48, 155,
- 49, 49, 156,
- 95, 95, 157
+ 48, 48, 157,
+ 49, 49, 158,
+ 95, 95, 159
};
static const int lexer_goto_row79[] = {
- 2,
- 48, 55, 158,
- 95, 95, 159
+ 3,
+ 43, 43, 160,
+ 45, 45, 161,
+ 48, 57, 162
};
static const int lexer_goto_row80[] = {
- 4,
- 48, 57, 160,
- 65, 70, 161,
- 95, 95, 162,
- 97, 102, 163
+ 2,
+ 48, 55, 163,
+ 95, 95, 164
};
static const int lexer_goto_row81[] = {
- 1,
- 48, 95, -79
+ 4,
+ 48, 57, 165,
+ 65, 70, 166,
+ 95, 95, 167,
+ 97, 102, 168
};
static const int lexer_goto_row82[] = {
1,
- 48, 95, -80
+ 48, 95, -79
};
static const int lexer_goto_row83[] = {
1,
- 56, 56, 164
+ 43, 57, -80
};
static const int lexer_goto_row84[] = {
1,
- 48, 102, -81
+ 48, 95, -81
};
-static const int lexer_goto_row86[] = {
+static const int lexer_goto_row85[] = {
1,
- 61, 61, 165
+ 56, 56, 169
};
-static const int lexer_goto_row87[] = {
+static const int lexer_goto_row86[] = {
1,
- 62, 62, 166
+ 48, 102, -82
};
-static const int lexer_goto_row90[] = {
+static const int lexer_goto_row88[] = {
1,
- 61, 61, 167
+ 61, 61, 170
};
-static const int lexer_goto_row91[] = {
+static const int lexer_goto_row89[] = {
1,
- 48, 122, -29
+ 62, 62, 171
};
static const int lexer_goto_row92[] = {
1,
- 48, 122, -29
+ 61, 61, 172
};
static const int lexer_goto_row93[] = {
1,
1,
48, 122, -29
};
+static const int lexer_goto_row95[] = {
+ 1,
+ 48, 122, -29
+};
static const int lexer_goto_row96[] = {
1,
- 100, 100, 168
+ 48, 122, -29
+};
+static const int lexer_goto_row98[] = {
+ 1,
+ 100, 100, 173
};
-static const int lexer_goto_row97[] = {
+static const int lexer_goto_row99[] = {
4,
- 48, 57, 169,
- 65, 90, 170,
- 95, 95, 171,
- 97, 122, 172
+ 48, 57, 174,
+ 65, 90, 175,
+ 95, 95, 176,
+ 97, 122, 177
};
-static const int lexer_goto_row98[] = {
+static const int lexer_goto_row100[] = {
5,
- 0, 91, 173,
- 92, 92, 174,
- 93, 95, 173,
- 96, 96, 175,
- 97, 255, 173
+ 0, 91, 178,
+ 92, 92, 179,
+ 93, 95, 178,
+ 96, 96, 180,
+ 97, 255, 178
};
-static const int lexer_goto_row99[] = {
+static const int lexer_goto_row101[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row100[] = {
+static const int lexer_goto_row102[] = {
1,
48, 122, -41
};
-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[] = {
5,
48, 110, -38,
- 111, 111, 176,
- 112, 114, 101,
- 115, 115, 177,
- 116, 122, 101
+ 111, 111, 181,
+ 112, 114, 103,
+ 115, 115, 182,
+ 116, 122, 103
};
-static const int lexer_goto_row104[] = {
+static const int lexer_goto_row106[] = {
4,
48, 95, -35,
- 97, 99, 101,
- 100, 100, 178,
- 101, 122, 101
+ 97, 99, 103,
+ 100, 100, 183,
+ 101, 122, 103
};
-static const int lexer_goto_row105[] = {
+static const int lexer_goto_row107[] = {
4,
48, 95, -35,
- 97, 114, 101,
- 115, 115, 179,
- 116, 122, 101
+ 97, 114, 103,
+ 115, 115, 184,
+ 116, 122, 103
};
-static const int lexer_goto_row106[] = {
+static const int lexer_goto_row108[] = {
3,
48, 100, -45,
- 101, 101, 180,
- 102, 122, 101
+ 101, 101, 185,
+ 102, 122, 103
};
-static const int lexer_goto_row107[] = {
+static const int lexer_goto_row109[] = {
3,
48, 95, -35,
- 97, 97, 181,
- 98, 122, 101
+ 97, 97, 186,
+ 98, 122, 103
};
-static const int lexer_goto_row108[] = {
+static const int lexer_goto_row110[] = {
3,
48, 109, -46,
- 110, 110, 182,
- 111, 122, 101
+ 110, 110, 187,
+ 111, 122, 103
};
-static const int lexer_goto_row109[] = {
+static const int lexer_goto_row111[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row110[] = {
+static const int lexer_goto_row112[] = {
3,
- 48, 114, -106,
- 115, 115, 183,
- 116, 122, 101
+ 48, 114, -108,
+ 115, 115, 188,
+ 116, 122, 103
};
-static const int lexer_goto_row111[] = {
+static const int lexer_goto_row113[] = {
5,
- 48, 99, -105,
- 100, 100, 184,
- 101, 116, 101,
- 117, 117, 185,
- 118, 122, 101
+ 48, 99, -107,
+ 100, 100, 189,
+ 101, 116, 103,
+ 117, 117, 190,
+ 118, 122, 103
};
-static const int lexer_goto_row112[] = {
+static const int lexer_goto_row114[] = {
4,
48, 95, -35,
- 97, 115, 101,
- 116, 116, 186,
- 117, 122, 101
+ 97, 115, 103,
+ 116, 116, 191,
+ 117, 122, 103
};
-static const int lexer_goto_row113[] = {
+static const int lexer_goto_row115[] = {
3,
48, 107, -37,
- 108, 108, 187,
- 109, 122, 101
+ 108, 108, 192,
+ 109, 122, 103
};
-static const int lexer_goto_row114[] = {
+static const int lexer_goto_row116[] = {
3,
48, 113, -36,
- 114, 114, 188,
- 115, 122, 101
+ 114, 114, 193,
+ 115, 122, 103
};
-static const int lexer_goto_row115[] = {
+static const int lexer_goto_row117[] = {
3,
48, 109, -46,
- 110, 110, 189,
- 111, 122, 101
+ 110, 110, 194,
+ 111, 122, 103
};
-static const int lexer_goto_row116[] = {
+static const int lexer_goto_row118[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row117[] = {
+static const int lexer_goto_row119[] = {
4,
48, 95, -35,
- 97, 111, 101,
- 112, 112, 190,
- 113, 122, 101
+ 97, 111, 103,
+ 112, 112, 195,
+ 113, 122, 103
};
-static const int lexer_goto_row118[] = {
+static const int lexer_goto_row120[] = {
6,
48, 95, -35,
- 97, 104, 101,
- 105, 105, 191,
- 106, 115, 101,
- 116, 116, 192,
- 117, 122, 101
+ 97, 104, 103,
+ 105, 105, 196,
+ 106, 115, 103,
+ 116, 116, 197,
+ 117, 122, 103
};
-static const int lexer_goto_row119[] = {
+static const int lexer_goto_row121[] = {
5,
48, 95, -35,
- 97, 97, 193,
- 98, 114, 101,
- 115, 115, 194,
- 116, 122, 101
+ 97, 97, 198,
+ 98, 114, 103,
+ 115, 115, 199,
+ 116, 122, 103
};
-static const int lexer_goto_row120[] = {
+static const int lexer_goto_row122[] = {
3,
48, 97, -35,
- 98, 98, 195,
- 99, 122, 101
+ 98, 98, 200,
+ 99, 122, 103
};
-static const int lexer_goto_row121[] = {
+static const int lexer_goto_row123[] = {
3,
48, 110, -38,
- 111, 111, 196,
- 112, 122, 101
+ 111, 111, 201,
+ 112, 122, 103
};
-static const int lexer_goto_row122[] = {
+static const int lexer_goto_row124[] = {
3,
- 48, 99, -105,
- 100, 100, 197,
- 101, 122, 101
+ 48, 99, -107,
+ 100, 100, 202,
+ 101, 122, 103
};
-static const int lexer_goto_row123[] = {
+static const int lexer_goto_row125[] = {
4,
48, 95, -35,
- 97, 118, 101,
- 119, 119, 198,
- 120, 122, 101
+ 97, 118, 103,
+ 119, 119, 203,
+ 120, 122, 103
};
-static const int lexer_goto_row124[] = {
+static const int lexer_goto_row126[] = {
3,
- 48, 115, -113,
- 116, 116, 199,
- 117, 122, 101
+ 48, 115, -115,
+ 116, 116, 204,
+ 117, 122, 103
};
-static const int lexer_goto_row125[] = {
+static const int lexer_goto_row127[] = {
3,
48, 107, -37,
- 108, 108, 200,
- 109, 122, 101
+ 108, 108, 205,
+ 109, 122, 103
};
-static const int lexer_goto_row126[] = {
+static const int lexer_goto_row128[] = {
4,
48, 95, -35,
- 97, 98, 101,
- 99, 99, 201,
- 100, 122, 101
+ 97, 98, 103,
+ 99, 99, 206,
+ 100, 122, 103
};
-static const int lexer_goto_row127[] = {
+static const int lexer_goto_row129[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row128[] = {
- 3,
- 48, 98, -127,
- 99, 99, 202,
- 100, 122, 101
-};
-static const int lexer_goto_row129[] = {
- 5,
- 48, 104, -119,
- 105, 105, 203,
- 106, 110, 101,
- 111, 111, 204,
- 112, 122, 101
-};
static const int lexer_goto_row130[] = {
3,
- 48, 97, -35,
- 98, 98, 205,
- 99, 122, 101
+ 48, 98, -129,
+ 99, 99, 207,
+ 100, 122, 103
};
static const int lexer_goto_row131[] = {
5,
- 48, 99, -105,
- 100, 100, 206,
- 101, 115, 101,
- 116, 116, 207,
- 117, 122, 101
+ 48, 104, -121,
+ 105, 105, 208,
+ 106, 110, 103,
+ 111, 111, 209,
+ 112, 122, 103
};
static const int lexer_goto_row132[] = {
3,
- 48, 107, -37,
- 108, 108, 208,
- 109, 122, 101
+ 48, 97, -35,
+ 98, 98, 210,
+ 99, 122, 103
};
static const int lexer_goto_row133[] = {
- 3,
- 48, 111, -118,
- 112, 112, 209,
- 113, 122, 101
+ 5,
+ 48, 99, -107,
+ 100, 100, 211,
+ 101, 115, 103,
+ 116, 116, 212,
+ 117, 122, 103
};
static const int lexer_goto_row134[] = {
3,
- 48, 100, -45,
- 101, 101, 210,
- 102, 122, 101
+ 48, 107, -37,
+ 108, 108, 213,
+ 109, 122, 103
};
static const int lexer_goto_row135[] = {
- 4,
- 48, 95, -35,
- 97, 116, 101,
- 117, 117, 211,
- 118, 122, 101
+ 3,
+ 48, 111, -120,
+ 112, 112, 214,
+ 113, 122, 103
};
static const int lexer_goto_row136[] = {
3,
- 48, 111, -118,
- 112, 112, 212,
- 113, 122, 101
+ 48, 100, -45,
+ 101, 101, 215,
+ 102, 122, 103
};
static const int lexer_goto_row137[] = {
- 3,
- 48, 104, -119,
- 105, 105, 213,
- 106, 122, 101
+ 4,
+ 48, 95, -35,
+ 97, 116, 103,
+ 117, 117, 216,
+ 118, 122, 103
};
static const int lexer_goto_row138[] = {
3,
- 48, 113, -36,
- 114, 114, 214,
- 115, 122, 101
+ 48, 111, -120,
+ 112, 112, 217,
+ 113, 122, 103
};
static const int lexer_goto_row139[] = {
3,
- 48, 104, -119,
- 105, 105, 215,
- 106, 122, 101
+ 48, 104, -121,
+ 105, 105, 218,
+ 106, 122, 103
};
static const int lexer_goto_row140[] = {
3,
- 48, 115, -113,
- 116, 116, 216,
- 117, 122, 101
+ 48, 113, -36,
+ 114, 114, 219,
+ 115, 122, 103
+};
+static const int lexer_goto_row141[] = {
+ 3,
+ 48, 104, -121,
+ 105, 105, 220,
+ 106, 122, 103
};
static const int lexer_goto_row142[] = {
+ 3,
+ 48, 115, -115,
+ 116, 116, 221,
+ 117, 122, 103
+};
+static const int lexer_goto_row144[] = {
2,
0, 123, -55,
- 124, 255, 141
+ 124, 255, 143
};
-static const int lexer_goto_row144[] = {
+static const int lexer_goto_row146[] = {
3,
- 0, 9, 217,
- 11, 12, 217,
- 14, 255, 217
+ 0, 9, 222,
+ 11, 12, 222,
+ 14, 255, 222
};
-static const int lexer_goto_row146[] = {
+static const int lexer_goto_row148[] = {
3,
0, 124, -55,
- 125, 125, 218,
- 126, 255, 141
+ 125, 125, 223,
+ 126, 255, 143
};
-static const int lexer_goto_row148[] = {
+static const int lexer_goto_row150[] = {
11,
- 0, 9, 219,
- 10, 10, 220,
- 11, 12, 219,
- 13, 13, 221,
- 14, 33, 219,
- 34, 34, 222,
- 35, 91, 219,
- 92, 92, 223,
- 93, 122, 219,
- 123, 123, 224,
- 124, 255, 219
-};
-static const int lexer_goto_row149[] = {
+ 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[] = {
1,
0, 255, -59
};
-static const int lexer_goto_row152[] = {
+static const int lexer_goto_row154[] = {
9,
- 0, 9, 225,
- 10, 10, 226,
- 11, 12, 225,
- 13, 13, 227,
- 14, 38, 225,
- 39, 39, 228,
- 40, 91, 225,
- 92, 92, 229,
- 93, 255, 225
+ 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
};
-static const int lexer_goto_row153[] = {
+static const int lexer_goto_row155[] = {
1,
- 39, 39, 230
+ 39, 39, 235
};
-static const int lexer_goto_row156[] = {
+static const int lexer_goto_row158[] = {
2,
48, 95, -79,
- 117, 117, 231
-};
-static const int lexer_goto_row157[] = {
- 1,
- 48, 117, -157
-};
-static const int lexer_goto_row158[] = {
- 1,
- 48, 117, -157
+ 117, 117, 236
};
static const int lexer_goto_row159[] = {
- 2,
- 48, 95, -80,
- 117, 117, 232
+ 1,
+ 48, 117, -159
};
static const int lexer_goto_row160[] = {
1,
- 48, 117, -160
+ 48, 117, -159
};
static const int lexer_goto_row161[] = {
- 2,
- 48, 102, -81,
- 117, 117, 233
+ 1,
+ 48, 57, 162
};
static const int lexer_goto_row162[] = {
1,
- 48, 117, -162
+ 48, 57, 162
};
static const int lexer_goto_row163[] = {
1,
- 48, 117, -162
+ 48, 57, 162
};
static const int lexer_goto_row164[] = {
- 1,
- 48, 117, -162
+ 2,
+ 48, 95, -81,
+ 117, 117, 237
};
-static const int lexer_goto_row169[] = {
+static const int lexer_goto_row165[] = {
1,
- 101, 101, 234
+ 48, 117, -165
};
-static const int lexer_goto_row170[] = {
- 1,
- 48, 122, -98
+static const int lexer_goto_row166[] = {
+ 2,
+ 48, 102, -82,
+ 117, 117, 238
};
-static const int lexer_goto_row171[] = {
+static const int lexer_goto_row167[] = {
1,
- 48, 122, -98
+ 48, 117, -167
};
-static const int lexer_goto_row172[] = {
+static const int lexer_goto_row168[] = {
1,
- 48, 122, -98
+ 48, 117, -167
};
-static const int lexer_goto_row173[] = {
+static const int lexer_goto_row169[] = {
1,
- 48, 122, -98
+ 48, 117, -167
};
static const int lexer_goto_row174[] = {
1,
- 0, 255, -99
+ 101, 101, 239
};
static const int lexer_goto_row175[] = {
1,
- 0, 255, 235
+ 48, 122, -100
};
static const int lexer_goto_row176[] = {
- 3,
- 0, 124, 236,
- 125, 125, 237,
- 126, 255, 236
+ 1,
+ 48, 122, -100
};
static const int lexer_goto_row177[] = {
- 3,
- 48, 113, -36,
- 114, 114, 238,
- 115, 122, 101
+ 1,
+ 48, 122, -100
};
static const int lexer_goto_row178[] = {
- 3,
- 48, 115, -113,
- 116, 116, 239,
- 117, 122, 101
+ 1,
+ 48, 122, -100
};
static const int lexer_goto_row179[] = {
1,
- 48, 122, -41
+ 0, 255, -101
};
static const int lexer_goto_row180[] = {
- 3,
- 48, 100, -45,
- 101, 101, 240,
- 102, 122, 101
+ 1,
+ 0, 255, 240
};
static const int lexer_goto_row181[] = {
3,
- 48, 95, -35,
- 97, 97, 241,
- 98, 122, 101
+ 0, 124, 241,
+ 125, 125, 242,
+ 126, 255, 241
};
static const int lexer_goto_row182[] = {
3,
- 48, 114, -106,
- 115, 115, 242,
- 116, 122, 101
+ 48, 113, -36,
+ 114, 114, 243,
+ 115, 122, 103
};
static const int lexer_goto_row183[] = {
3,
- 48, 115, -113,
- 116, 116, 243,
- 117, 122, 101
+ 48, 115, -115,
+ 116, 116, 244,
+ 117, 122, 103
};
static const int lexer_goto_row184[] = {
- 3,
- 48, 100, -45,
- 101, 101, 244,
- 102, 122, 101
-};
-static const int lexer_goto_row185[] = {
1,
48, 122, -41
};
+static const int lexer_goto_row185[] = {
+ 3,
+ 48, 100, -45,
+ 101, 101, 245,
+ 102, 122, 103
+};
static const int lexer_goto_row186[] = {
- 4,
+ 3,
48, 95, -35,
- 97, 108, 101,
- 109, 109, 245,
- 110, 122, 101
+ 97, 97, 246,
+ 98, 122, 103
};
static const int lexer_goto_row187[] = {
3,
- 48, 100, -45,
- 101, 101, 246,
- 102, 122, 101
+ 48, 114, -108,
+ 115, 115, 247,
+ 116, 122, 103
};
static const int lexer_goto_row188[] = {
3,
- 48, 114, -106,
- 115, 115, 247,
- 116, 122, 101
+ 48, 115, -115,
+ 116, 116, 248,
+ 117, 122, 103
};
static const int lexer_goto_row189[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 100, -45,
+ 101, 101, 249,
+ 102, 122, 103
};
static const int lexer_goto_row190[] = {
1,
48, 122, -41
};
static const int lexer_goto_row191[] = {
- 5,
- 48, 107, -37,
- 108, 108, 248,
- 109, 110, 101,
- 111, 111, 249,
- 112, 122, 101
+ 4,
+ 48, 95, -35,
+ 97, 108, 103,
+ 109, 109, 250,
+ 110, 122, 103
};
static const int lexer_goto_row192[] = {
3,
- 48, 115, -113,
- 116, 116, 250,
- 117, 122, 101
-};
-static const int lexer_goto_row193[] = {
- 5,
48, 100, -45,
101, 101, 251,
- 102, 113, 101,
- 114, 114, 252,
- 115, 122, 101
+ 102, 122, 103
+};
+static const int lexer_goto_row193[] = {
+ 3,
+ 48, 114, -108,
+ 115, 115, 252,
+ 116, 122, 103
};
static const int lexer_goto_row194[] = {
1,
48, 122, -41
};
static const int lexer_goto_row195[] = {
- 3,
- 48, 100, -45,
- 101, 101, 253,
- 102, 122, 101
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row196[] = {
- 3,
- 48, 100, -45,
- 101, 101, 254,
- 102, 122, 101
+ 5,
+ 48, 107, -37,
+ 108, 108, 253,
+ 109, 110, 103,
+ 111, 111, 254,
+ 112, 122, 103
};
static const int lexer_goto_row197[] = {
3,
- 48, 111, -118,
- 112, 112, 255,
- 113, 122, 101
+ 48, 115, -115,
+ 116, 116, 255,
+ 117, 122, 103
};
static const int lexer_goto_row198[] = {
- 3,
- 48, 116, -136,
- 117, 117, 256,
- 118, 122, 101
+ 5,
+ 48, 100, -45,
+ 101, 101, 256,
+ 102, 113, 103,
+ 114, 114, 257,
+ 115, 122, 103
};
static const int lexer_goto_row199[] = {
1,
48, 122, -41
};
static const int lexer_goto_row200[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 100, -45,
+ 101, 101, 258,
+ 102, 122, 103
};
static const int lexer_goto_row201[] = {
3,
- 48, 107, -37,
- 108, 108, 257,
- 109, 122, 101
+ 48, 100, -45,
+ 101, 101, 259,
+ 102, 122, 103
};
static const int lexer_goto_row202[] = {
3,
- 48, 100, -45,
- 101, 101, 258,
- 102, 122, 101
+ 48, 111, -120,
+ 112, 112, 260,
+ 113, 122, 103
};
static const int lexer_goto_row203[] = {
- 4,
- 48, 95, -35,
- 97, 106, 101,
- 107, 107, 259,
- 108, 122, 101
+ 3,
+ 48, 116, -138,
+ 117, 117, 261,
+ 118, 122, 103
};
static const int lexer_goto_row204[] = {
- 4,
- 48, 95, -35,
- 97, 117, 101,
- 118, 118, 260,
- 119, 122, 101
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row205[] = {
- 3,
- 48, 115, -113,
- 116, 116, 261,
- 117, 122, 101
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row206[] = {
3,
48, 107, -37,
108, 108, 262,
- 109, 122, 101
+ 109, 122, 103
};
static const int lexer_goto_row207[] = {
3,
48, 100, -45,
101, 101, 263,
- 102, 122, 101
+ 102, 122, 103
};
static const int lexer_goto_row208[] = {
- 3,
- 48, 116, -136,
- 117, 117, 264,
- 118, 122, 101
+ 4,
+ 48, 95, -35,
+ 97, 106, 103,
+ 107, 107, 264,
+ 108, 122, 103
};
static const int lexer_goto_row209[] = {
- 3,
- 48, 101, -42,
- 102, 102, 265,
- 103, 122, 101
+ 4,
+ 48, 95, -35,
+ 97, 117, 103,
+ 118, 118, 265,
+ 119, 122, 103
};
static const int lexer_goto_row210[] = {
3,
- 48, 100, -45,
- 101, 101, 266,
- 102, 122, 101
+ 48, 115, -115,
+ 116, 116, 266,
+ 117, 122, 103
};
static const int lexer_goto_row211[] = {
3,
- 48, 109, -46,
- 110, 110, 267,
- 111, 122, 101
+ 48, 107, -37,
+ 108, 108, 267,
+ 109, 122, 103
};
static const int lexer_goto_row212[] = {
3,
48, 100, -45,
101, 101, 268,
- 102, 122, 101
+ 102, 122, 103
};
static const int lexer_goto_row213[] = {
3,
- 48, 100, -45,
- 101, 101, 269,
- 102, 122, 101
+ 48, 116, -138,
+ 117, 117, 269,
+ 118, 122, 103
};
static const int lexer_goto_row214[] = {
3,
- 48, 117, -205,
- 118, 118, 270,
- 119, 122, 101
+ 48, 101, -42,
+ 102, 102, 270,
+ 103, 122, 103
};
static const int lexer_goto_row215[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 100, -45,
+ 101, 101, 271,
+ 102, 122, 103
};
static const int lexer_goto_row216[] = {
3,
- 48, 107, -37,
- 108, 108, 271,
- 109, 122, 101
+ 48, 109, -46,
+ 110, 110, 272,
+ 111, 122, 103
};
static const int lexer_goto_row217[] = {
3,
- 48, 103, -50,
- 104, 104, 272,
- 105, 122, 101
+ 48, 100, -45,
+ 101, 101, 273,
+ 102, 122, 103
};
static const int lexer_goto_row218[] = {
- 1,
- 0, 255, -143
+ 3,
+ 48, 100, -45,
+ 101, 101, 274,
+ 102, 122, 103
};
static const int lexer_goto_row219[] = {
- 11,
- 0, 9, 273,
- 10, 10, 274,
- 11, 12, 273,
- 13, 13, 275,
- 14, 33, 273,
- 34, 34, 276,
- 35, 91, 273,
- 92, 92, 277,
- 93, 122, 273,
- 123, 123, 278,
- 124, 255, 273
+ 3,
+ 48, 117, -210,
+ 118, 118, 275,
+ 119, 122, 103
};
static const int lexer_goto_row220[] = {
1,
- 0, 255, -149
+ 48, 122, -41
};
static const int lexer_goto_row221[] = {
- 1,
- 0, 255, -149
+ 3,
+ 48, 107, -37,
+ 108, 108, 276,
+ 109, 122, 103
};
static const int lexer_goto_row222[] = {
- 1,
- 0, 255, -149
+ 3,
+ 48, 103, -50,
+ 104, 104, 277,
+ 105, 122, 103
};
static const int lexer_goto_row223[] = {
- 5,
- 0, 33, -149,
- 34, 34, 279,
- 35, 122, -149,
- 123, 123, 280,
- 124, 255, 219
+ 1,
+ 0, 255, -145
};
static const int lexer_goto_row224[] = {
- 3,
- 0, 9, 281,
- 11, 12, 281,
- 14, 255, 281
+ 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
};
static const int lexer_goto_row225[] = {
- 5,
- 0, 33, -149,
- 34, 34, 282,
- 35, 122, -149,
- 123, 123, 283,
- 124, 255, 219
+ 1,
+ 0, 255, -151
};
static const int lexer_goto_row226[] = {
1,
- 0, 255, -153
+ 0, 255, -151
};
static const int lexer_goto_row227[] = {
1,
- 0, 255, -153
+ 0, 255, -151
};
static const int lexer_goto_row228[] = {
- 1,
- 0, 255, -153
+ 5,
+ 0, 33, -151,
+ 34, 34, 284,
+ 35, 122, -151,
+ 123, 123, 285,
+ 124, 255, 224
};
static const int lexer_goto_row229[] = {
- 9,
- 0, 9, 284,
- 10, 10, 285,
- 11, 12, 284,
- 13, 13, 286,
- 14, 38, 284,
- 39, 39, 287,
- 40, 91, 284,
- 92, 92, 288,
- 93, 255, 284
+ 3,
+ 0, 9, 286,
+ 11, 12, 286,
+ 14, 255, 286
};
static const int lexer_goto_row230[] = {
- 3,
- 0, 9, 289,
- 11, 12, 289,
- 14, 255, 289
+ 5,
+ 0, 33, -151,
+ 34, 34, 287,
+ 35, 122, -151,
+ 123, 123, 288,
+ 124, 255, 224
+};
+static const int lexer_goto_row231[] = {
+ 1,
+ 0, 255, -155
};
static const int lexer_goto_row232[] = {
1,
- 56, 56, 290
+ 0, 255, -155
};
static const int lexer_goto_row233[] = {
1,
- 56, 56, 291
+ 0, 255, -155
};
static const int lexer_goto_row234[] = {
- 1,
- 56, 56, 292
+ 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
};
static const int lexer_goto_row235[] = {
- 1,
- 98, 98, 293
+ 3,
+ 0, 9, 294,
+ 11, 12, 294,
+ 14, 255, 294
};
-static const int lexer_goto_row236[] = {
+static const int lexer_goto_row237[] = {
1,
- 0, 255, -99
+ 56, 56, 295
};
-static const int lexer_goto_row237[] = {
+static const int lexer_goto_row238[] = {
1,
- 0, 255, -99
+ 56, 56, 296
};
static const int lexer_goto_row239[] = {
- 3,
- 48, 115, -113,
- 116, 116, 294,
- 117, 122, 101
+ 1,
+ 56, 56, 297
};
static const int lexer_goto_row240[] = {
- 3,
- 48, 113, -36,
- 114, 114, 295,
- 115, 122, 101
+ 1,
+ 98, 98, 298
};
static const int lexer_goto_row241[] = {
- 3,
- 48, 113, -36,
- 114, 114, 296,
- 115, 122, 101
+ 1,
+ 0, 255, -101
};
static const int lexer_goto_row242[] = {
- 3,
- 48, 106, -204,
- 107, 107, 297,
- 108, 122, 101
-};
-static const int lexer_goto_row243[] = {
- 3,
- 48, 114, -106,
- 115, 115, 298,
- 116, 122, 101
+ 1,
+ 0, 255, -101
};
static const int lexer_goto_row244[] = {
3,
- 48, 104, -119,
- 105, 105, 299,
- 106, 122, 101
+ 48, 115, -115,
+ 116, 116, 299,
+ 117, 122, 103
};
static const int lexer_goto_row245[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 113, -36,
+ 114, 114, 300,
+ 115, 122, 103
};
static const int lexer_goto_row246[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 113, -36,
+ 114, 114, 301,
+ 115, 122, 103
};
static const int lexer_goto_row247[] = {
3,
- 48, 113, -36,
- 114, 114, 300,
- 115, 122, 101
+ 48, 106, -209,
+ 107, 107, 302,
+ 108, 122, 103
};
static const int lexer_goto_row248[] = {
3,
- 48, 100, -45,
- 101, 101, 301,
- 102, 122, 101
+ 48, 114, -108,
+ 115, 115, 303,
+ 116, 122, 103
};
static const int lexer_goto_row249[] = {
3,
- 48, 104, -119,
- 105, 105, 302,
- 106, 122, 101
+ 48, 104, -121,
+ 105, 105, 304,
+ 106, 122, 103
};
static const int lexer_goto_row250[] = {
- 3,
- 48, 113, -36,
- 114, 114, 303,
- 115, 122, 101
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row251[] = {
1,
static const int lexer_goto_row252[] = {
3,
48, 113, -36,
- 114, 114, 304,
- 115, 122, 101
+ 114, 114, 305,
+ 115, 122, 103
};
static const int lexer_goto_row253[] = {
3,
- 48, 116, -136,
- 117, 117, 305,
- 118, 122, 101
+ 48, 100, -45,
+ 101, 101, 306,
+ 102, 122, 103
};
static const int lexer_goto_row254[] = {
3,
- 48, 115, -113,
- 116, 116, 306,
- 117, 122, 101
+ 48, 104, -121,
+ 105, 105, 307,
+ 106, 122, 103
};
static const int lexer_goto_row255[] = {
3,
- 48, 107, -37,
- 108, 108, 307,
- 109, 122, 101
+ 48, 113, -36,
+ 114, 114, 308,
+ 115, 122, 103
};
static const int lexer_goto_row256[] = {
1,
};
static const int lexer_goto_row257[] = {
3,
- 48, 107, -37,
- 108, 108, 308,
- 109, 122, 101
+ 48, 113, -36,
+ 114, 114, 309,
+ 115, 122, 103
};
static const int lexer_goto_row258[] = {
3,
- 48, 95, -35,
- 97, 97, 309,
- 98, 122, 101
+ 48, 116, -138,
+ 117, 117, 310,
+ 118, 122, 103
};
static const int lexer_goto_row259[] = {
+ 3,
+ 48, 115, -115,
+ 116, 116, 311,
+ 117, 122, 103
+};
+static const int lexer_goto_row260[] = {
+ 3,
+ 48, 107, -37,
+ 108, 108, 312,
+ 109, 122, 103
+};
+static const int lexer_goto_row261[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row260[] = {
+static const int lexer_goto_row262[] = {
+ 3,
+ 48, 107, -37,
+ 108, 108, 313,
+ 109, 122, 103
+};
+static const int lexer_goto_row263[] = {
3,
48, 95, -35,
- 97, 97, 310,
- 98, 122, 101
+ 97, 97, 314,
+ 98, 122, 103
};
-static const int lexer_goto_row261[] = {
+static const int lexer_goto_row264[] = {
+ 1,
+ 48, 122, -41
+};
+static const int lexer_goto_row265[] = {
3,
48, 95, -35,
- 97, 97, 311,
- 98, 122, 101
+ 97, 97, 315,
+ 98, 122, 103
};
-static const int lexer_goto_row262[] = {
+static const int lexer_goto_row266[] = {
+ 3,
+ 48, 95, -35,
+ 97, 97, 316,
+ 98, 122, 103
+};
+static const int lexer_goto_row267[] = {
3,
48, 100, -45,
- 101, 101, 312,
- 102, 122, 101
+ 101, 101, 317,
+ 102, 122, 103
};
-static const int lexer_goto_row263[] = {
+static const int lexer_goto_row268[] = {
3,
- 48, 104, -119,
- 105, 105, 313,
- 106, 122, 101
+ 48, 104, -121,
+ 105, 105, 318,
+ 106, 122, 103
};
-static const int lexer_goto_row264[] = {
+static const int lexer_goto_row269[] = {
3,
48, 101, -42,
- 102, 102, 314,
- 103, 122, 101
+ 102, 102, 319,
+ 103, 122, 103
};
-static const int lexer_goto_row265[] = {
+static const int lexer_goto_row270[] = {
3,
48, 113, -36,
- 114, 114, 315,
- 115, 122, 101
+ 114, 114, 320,
+ 115, 122, 103
};
-static const int lexer_goto_row266[] = {
+static const int lexer_goto_row271[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row267[] = {
+static const int lexer_goto_row272[] = {
3,
48, 113, -36,
- 114, 114, 316,
- 115, 122, 101
+ 114, 114, 321,
+ 115, 122, 103
};
-static const int lexer_goto_row268[] = {
+static const int lexer_goto_row273[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row269[] = {
+static const int lexer_goto_row274[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row270[] = {
+static const int lexer_goto_row275[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row271[] = {
+static const int lexer_goto_row276[] = {
3,
48, 100, -45,
- 101, 101, 317,
- 102, 122, 101
+ 101, 101, 322,
+ 102, 122, 103
};
-static const int lexer_goto_row272[] = {
+static const int lexer_goto_row277[] = {
3,
48, 100, -45,
- 101, 101, 318,
- 102, 122, 101
+ 101, 101, 323,
+ 102, 122, 103
};
-static const int lexer_goto_row273[] = {
+static const int lexer_goto_row278[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row274[] = {
+static const int lexer_goto_row279[] = {
1,
- 0, 255, -220
+ 0, 255, -225
};
-static const int lexer_goto_row275[] = {
+static const int lexer_goto_row280[] = {
11,
- 0, 9, 319,
- 10, 10, 274,
- 11, 12, 319,
- 13, 13, 275,
- 14, 33, 319,
- 34, 34, 320,
- 35, 91, 319,
- 92, 92, 321,
- 93, 122, 319,
- 123, 123, 322,
- 124, 255, 319
+ 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
};
-static const int lexer_goto_row276[] = {
+static const int lexer_goto_row281[] = {
1,
- 0, 255, -276
+ 0, 255, -281
};
-static const int lexer_goto_row277[] = {
+static const int lexer_goto_row282[] = {
5,
- 0, 33, -276,
- 34, 34, 323,
- 35, 122, -276,
- 123, 123, 324,
- 124, 255, 319
+ 0, 33, -281,
+ 34, 34, 328,
+ 35, 122, -281,
+ 123, 123, 329,
+ 124, 255, 324
};
-static const int lexer_goto_row278[] = {
+static const int lexer_goto_row283[] = {
3,
- 0, 9, 325,
- 11, 12, 325,
- 14, 255, 325
+ 0, 9, 330,
+ 11, 12, 330,
+ 14, 255, 330
};
-static const int lexer_goto_row279[] = {
+static const int lexer_goto_row284[] = {
5,
- 0, 33, -276,
- 34, 34, 326,
- 35, 122, -276,
- 123, 123, 327,
- 124, 255, 319
+ 0, 33, -281,
+ 34, 34, 331,
+ 35, 122, -281,
+ 123, 123, 332,
+ 124, 255, 324
};
-static const int lexer_goto_row280[] = {
+static const int lexer_goto_row285[] = {
3,
- 0, 33, -149,
- 34, 34, 328,
- 35, 255, -224
+ 0, 33, -151,
+ 34, 34, 333,
+ 35, 255, -229
};
-static const int lexer_goto_row281[] = {
+static const int lexer_goto_row286[] = {
3,
- 0, 122, -226,
- 123, 123, 329,
- 124, 255, 219
+ 0, 122, -231,
+ 123, 123, 334,
+ 124, 255, 224
};
-static const int lexer_goto_row282[] = {
+static const int lexer_goto_row287[] = {
1,
- 0, 255, -149
+ 0, 255, -151
};
-static const int lexer_goto_row283[] = {
+static const int lexer_goto_row288[] = {
3,
- 0, 33, -149,
- 34, 34, 330,
- 35, 255, -224
+ 0, 33, -151,
+ 34, 34, 335,
+ 35, 255, -229
};
-static const int lexer_goto_row284[] = {
+static const int lexer_goto_row289[] = {
3,
- 0, 122, -226,
- 123, 123, 331,
- 124, 255, 219
+ 0, 122, -231,
+ 123, 123, 336,
+ 124, 255, 224
};
-static const int lexer_goto_row285[] = {
+static const int lexer_goto_row290[] = {
1,
- 0, 255, -153
+ 0, 255, -155
};
-static const int lexer_goto_row286[] = {
+static const int lexer_goto_row291[] = {
1,
- 0, 255, -153
+ 0, 255, -155
};
-static const int lexer_goto_row287[] = {
+static const int lexer_goto_row292[] = {
1,
- 0, 255, -153
+ 0, 255, -155
};
-static const int lexer_goto_row288[] = {
+static const int lexer_goto_row293[] = {
9,
- 0, 9, 332,
- 10, 10, 333,
- 11, 12, 332,
- 13, 13, 334,
- 14, 38, 332,
- 39, 39, 335,
- 40, 91, 332,
- 92, 92, 336,
- 93, 255, 332
-};
-static const int lexer_goto_row289[] = {
- 3,
0, 9, 337,
+ 10, 10, 338,
11, 12, 337,
- 14, 255, 337
+ 13, 13, 339,
+ 14, 38, 337,
+ 39, 39, 340,
+ 40, 91, 337,
+ 92, 92, 341,
+ 93, 255, 337
};
-static const int lexer_goto_row290[] = {
+static const int lexer_goto_row294[] = {
+ 3,
+ 0, 9, 342,
+ 11, 12, 342,
+ 14, 255, 342
+};
+static const int lexer_goto_row295[] = {
1,
- 0, 255, -153
+ 0, 255, -155
};
-static const int lexer_goto_row294[] = {
+static const int lexer_goto_row299[] = {
1,
- 117, 117, 338
+ 117, 117, 343
};
-static const int lexer_goto_row295[] = {
+static const int lexer_goto_row300[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row296[] = {
+static const int lexer_goto_row301[] = {
3,
48, 95, -35,
- 97, 97, 339,
- 98, 122, 101
+ 97, 97, 344,
+ 98, 122, 103
};
-static const int lexer_goto_row297[] = {
+static const int lexer_goto_row302[] = {
3,
- 48, 115, -113,
- 116, 116, 340,
- 117, 122, 101
+ 48, 115, -115,
+ 116, 116, 345,
+ 117, 122, 103
};
-static const int lexer_goto_row298[] = {
+static const int lexer_goto_row303[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row299[] = {
+static const int lexer_goto_row304[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row300[] = {
+static const int lexer_goto_row305[] = {
3,
48, 109, -46,
- 110, 110, 341,
- 111, 122, 101
+ 110, 110, 346,
+ 111, 122, 103
};
-static const int lexer_goto_row301[] = {
+static const int lexer_goto_row306[] = {
3,
48, 109, -46,
- 110, 110, 342,
- 111, 122, 101
+ 110, 110, 347,
+ 111, 122, 103
};
-static const int lexer_goto_row302[] = {
+static const int lexer_goto_row307[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row303[] = {
+static const int lexer_goto_row308[] = {
3,
48, 100, -45,
- 101, 101, 343,
- 102, 122, 101
+ 101, 101, 348,
+ 102, 122, 103
};
-static const int lexer_goto_row304[] = {
+static const int lexer_goto_row309[] = {
3,
- 48, 115, -113,
- 116, 116, 344,
- 117, 122, 101
+ 48, 115, -115,
+ 116, 116, 349,
+ 117, 122, 103
};
-static const int lexer_goto_row305[] = {
+static const int lexer_goto_row310[] = {
3,
48, 101, -42,
- 102, 102, 345,
- 103, 122, 101
+ 102, 102, 350,
+ 103, 122, 103
};
-static const int lexer_goto_row306[] = {
+static const int lexer_goto_row311[] = {
3,
- 48, 99, -105,
- 100, 100, 346,
- 101, 122, 101
+ 48, 99, -107,
+ 100, 100, 351,
+ 101, 122, 103
};
-static const int lexer_goto_row307[] = {
+static const int lexer_goto_row312[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row308[] = {
+static const int lexer_goto_row313[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row309[] = {
+static const int lexer_goto_row314[] = {
3,
48, 100, -45,
- 101, 101, 347,
- 102, 122, 101
+ 101, 101, 352,
+ 102, 122, 103
};
-static const int lexer_goto_row310[] = {
+static const int lexer_goto_row315[] = {
3,
48, 97, -35,
- 98, 98, 348,
- 99, 122, 101
+ 98, 98, 353,
+ 99, 122, 103
};
-static const int lexer_goto_row311[] = {
+static const int lexer_goto_row316[] = {
4,
48, 95, -35,
- 97, 102, 101,
- 103, 103, 349,
- 104, 122, 101
+ 97, 102, 103,
+ 103, 103, 354,
+ 104, 122, 103
};
-static const int lexer_goto_row312[] = {
+static const int lexer_goto_row317[] = {
3,
- 48, 115, -113,
- 116, 116, 350,
- 117, 122, 101
+ 48, 115, -115,
+ 116, 116, 355,
+ 117, 122, 103
};
-static const int lexer_goto_row313[] = {
+static const int lexer_goto_row318[] = {
3,
- 48, 98, -127,
- 99, 99, 351,
- 100, 122, 101
+ 48, 98, -129,
+ 99, 99, 356,
+ 100, 122, 103
};
-static const int lexer_goto_row314[] = {
+static const int lexer_goto_row319[] = {
3,
- 48, 98, -127,
- 99, 99, 352,
- 100, 122, 101
+ 48, 98, -129,
+ 99, 99, 357,
+ 100, 122, 103
};
-static const int lexer_goto_row315[] = {
+static const int lexer_goto_row320[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row316[] = {
+static const int lexer_goto_row321[] = {
3,
48, 109, -46,
- 110, 110, 353,
- 111, 122, 101
+ 110, 110, 358,
+ 111, 122, 103
};
-static const int lexer_goto_row317[] = {
+static const int lexer_goto_row322[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row318[] = {
+static const int lexer_goto_row323[] = {
3,
48, 113, -36,
- 114, 114, 354,
- 115, 122, 101
+ 114, 114, 359,
+ 115, 122, 103
};
-static const int lexer_goto_row319[] = {
+static const int lexer_goto_row324[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row320[] = {
- 1,
- 0, 255, -276
-};
-static const int lexer_goto_row321[] = {
- 1,
- 0, 255, -278
-};
-static const int lexer_goto_row322[] = {
- 3,
- 0, 9, 355,
- 11, 12, 355,
- 14, 255, 355
-};
-static const int lexer_goto_row323[] = {
- 1,
- 0, 255, -280
-};
-static const int lexer_goto_row324[] = {
- 3,
- 0, 33, -276,
- 34, 34, 356,
- 35, 255, -278
-};
static const int lexer_goto_row325[] = {
- 3,
- 0, 122, -280,
- 123, 123, 357,
- 124, 255, 319
+ 1,
+ 0, 255, -281
};
static const int lexer_goto_row326[] = {
1,
- 0, 255, -220
+ 0, 255, -283
};
static const int lexer_goto_row327[] = {
3,
- 0, 33, -276,
- 34, 34, 358,
- 35, 255, -278
+ 0, 9, 360,
+ 11, 12, 360,
+ 14, 255, 360
};
static const int lexer_goto_row328[] = {
- 3,
- 0, 122, -280,
- 123, 123, 359,
- 124, 255, 319
+ 1,
+ 0, 255, -285
};
static const int lexer_goto_row329[] = {
- 1,
- 34, 34, 360
+ 3,
+ 0, 33, -281,
+ 34, 34, 361,
+ 35, 255, -283
};
static const int lexer_goto_row330[] = {
- 1,
- 0, 255, -285
+ 3,
+ 0, 122, -285,
+ 123, 123, 362,
+ 124, 255, 324
};
static const int lexer_goto_row331[] = {
1,
- 0, 255, -281
+ 0, 255, -225
};
static const int lexer_goto_row332[] = {
- 1,
- 123, 123, 361
+ 3,
+ 0, 33, -281,
+ 34, 34, 363,
+ 35, 255, -283
};
static const int lexer_goto_row333[] = {
- 1,
- 0, 255, -153
+ 3,
+ 0, 122, -285,
+ 123, 123, 364,
+ 124, 255, 324
};
static const int lexer_goto_row334[] = {
1,
- 0, 255, -153
+ 34, 34, 365
};
static const int lexer_goto_row335[] = {
1,
- 0, 255, -153
+ 0, 255, -290
+};
+static const int lexer_goto_row336[] = {
+ 1,
+ 0, 255, -286
};
static const int lexer_goto_row337[] = {
- 3,
- 0, 9, 362,
- 11, 12, 362,
- 14, 255, 362
+ 1,
+ 123, 123, 366
};
static const int lexer_goto_row338[] = {
1,
- 0, 255, -153
+ 0, 255, -155
};
static const int lexer_goto_row339[] = {
1,
- 103, 103, 363
+ 0, 255, -155
};
static const int lexer_goto_row340[] = {
- 3,
- 48, 98, -127,
- 99, 99, 364,
- 100, 122, 101
-};
-static const int lexer_goto_row341[] = {
1,
- 48, 122, -41
+ 0, 255, -155
};
static const int lexer_goto_row342[] = {
3,
- 48, 116, -136,
- 117, 117, 365,
- 118, 122, 101
+ 0, 9, 367,
+ 11, 12, 367,
+ 14, 255, 367
};
static const int lexer_goto_row343[] = {
1,
- 48, 122, -41
+ 0, 255, -155
};
static const int lexer_goto_row344[] = {
- 3,
- 48, 114, -106,
- 115, 115, 366,
- 116, 122, 101
+ 1,
+ 103, 103, 368
};
static const int lexer_goto_row345[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 98, -129,
+ 99, 99, 369,
+ 100, 122, 103
};
static const int lexer_goto_row346[] = {
- 3,
- 48, 95, -35,
- 97, 97, 367,
- 98, 122, 101
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row347[] = {
3,
- 48, 100, -45,
- 101, 101, 368,
- 102, 122, 101
+ 48, 116, -138,
+ 117, 117, 370,
+ 118, 122, 103
};
static const int lexer_goto_row348[] = {
1,
};
static const int lexer_goto_row349[] = {
3,
- 48, 107, -37,
- 108, 108, 369,
- 109, 122, 101
+ 48, 114, -108,
+ 115, 115, 371,
+ 116, 122, 103
};
static const int lexer_goto_row350[] = {
- 3,
- 48, 100, -45,
- 101, 101, 370,
- 102, 122, 101
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row351[] = {
3,
- 48, 100, -45,
- 101, 101, 371,
- 102, 122, 101
+ 48, 95, -35,
+ 97, 97, 372,
+ 98, 122, 103
};
static const int lexer_goto_row352[] = {
3,
- 48, 115, -113,
- 116, 116, 372,
- 117, 122, 101
+ 48, 100, -45,
+ 101, 101, 373,
+ 102, 122, 103
};
static const int lexer_goto_row353[] = {
1,
48, 122, -41
};
static const int lexer_goto_row354[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 107, -37,
+ 108, 108, 374,
+ 109, 122, 103
};
static const int lexer_goto_row355[] = {
3,
- 48, 114, -106,
- 115, 115, 373,
- 116, 122, 101
+ 48, 100, -45,
+ 101, 101, 375,
+ 102, 122, 103
};
static const int lexer_goto_row356[] = {
- 1,
- 0, 255, -276
+ 3,
+ 48, 100, -45,
+ 101, 101, 376,
+ 102, 122, 103
};
static const int lexer_goto_row357[] = {
- 1,
- 34, 34, 374
+ 3,
+ 48, 115, -115,
+ 116, 116, 377,
+ 117, 122, 103
};
static const int lexer_goto_row358[] = {
1,
- 0, 255, -329
+ 48, 122, -41
};
static const int lexer_goto_row359[] = {
1,
- 0, 255, -325
+ 48, 122, -41
};
static const int lexer_goto_row360[] = {
- 1,
- 123, 123, 375
+ 3,
+ 48, 114, -108,
+ 115, 115, 378,
+ 116, 122, 103
};
static const int lexer_goto_row361[] = {
1,
- 34, 34, 360
+ 0, 255, -281
};
static const int lexer_goto_row362[] = {
1,
- 123, 123, 361
+ 34, 34, 379
};
static const int lexer_goto_row363[] = {
1,
- 0, 255, -153
+ 0, 255, -334
};
static const int lexer_goto_row364[] = {
1,
- 95, 95, 376
+ 0, 255, -330
};
static const int lexer_goto_row365[] = {
- 3,
- 48, 115, -113,
- 116, 116, 377,
- 117, 122, 101
+ 1,
+ 123, 123, 380
};
static const int lexer_goto_row366[] = {
- 3,
- 48, 100, -45,
- 101, 101, 378,
- 102, 122, 101
+ 1,
+ 34, 34, 365
};
static const int lexer_goto_row367[] = {
1,
- 48, 122, -41
+ 123, 123, 366
};
static const int lexer_goto_row368[] = {
- 3,
- 48, 98, -127,
- 99, 99, 379,
- 100, 122, 101
+ 1,
+ 0, 255, -155
};
static const int lexer_goto_row369[] = {
1,
- 48, 122, -41
+ 95, 95, 381
};
static const int lexer_goto_row370[] = {
3,
- 48, 100, -45,
- 101, 101, 380,
- 102, 122, 101
+ 48, 115, -115,
+ 116, 116, 382,
+ 117, 122, 103
};
static const int lexer_goto_row371[] = {
- 1,
- 48, 122, -41
+ 3,
+ 48, 100, -45,
+ 101, 101, 383,
+ 102, 122, 103
};
static const int lexer_goto_row372[] = {
1,
};
static const int lexer_goto_row373[] = {
3,
- 48, 100, -45,
- 101, 101, 381,
- 102, 122, 101
+ 48, 98, -129,
+ 99, 99, 384,
+ 100, 122, 103
};
static const int lexer_goto_row374[] = {
- 3,
- 48, 95, -35,
- 97, 97, 382,
- 98, 122, 101
+ 1,
+ 48, 122, -41
};
static const int lexer_goto_row375[] = {
- 1,
- 34, 34, 374
+ 3,
+ 48, 100, -45,
+ 101, 101, 385,
+ 102, 122, 103
};
static const int lexer_goto_row376[] = {
1,
- 123, 123, 375
+ 48, 122, -41
};
static const int lexer_goto_row377[] = {
1,
- 95, 95, 383
+ 48, 122, -41
};
static const int lexer_goto_row378[] = {
+ 3,
+ 48, 100, -45,
+ 101, 101, 386,
+ 102, 122, 103
+};
+static const int lexer_goto_row379[] = {
+ 3,
+ 48, 95, -35,
+ 97, 97, 387,
+ 98, 122, 103
+};
+static const int lexer_goto_row380[] = {
+ 1,
+ 34, 34, 379
+};
+static const int lexer_goto_row381[] = {
+ 1,
+ 123, 123, 380
+};
+static const int lexer_goto_row382[] = {
+ 1,
+ 95, 95, 388
+};
+static const int lexer_goto_row383[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row379[] = {
+static const int lexer_goto_row384[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row380[] = {
+static const int lexer_goto_row385[] = {
3,
48, 100, -45,
- 101, 101, 384,
- 102, 122, 101
+ 101, 101, 389,
+ 102, 122, 103
};
-static const int lexer_goto_row381[] = {
+static const int lexer_goto_row386[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row382[] = {
+static const int lexer_goto_row387[] = {
3,
- 48, 99, -105,
- 100, 100, 385,
- 101, 122, 101
+ 48, 99, -107,
+ 100, 100, 390,
+ 101, 122, 103
};
-static const int lexer_goto_row383[] = {
+static const int lexer_goto_row388[] = {
3,
48, 107, -37,
- 108, 108, 386,
- 109, 122, 101
+ 108, 108, 391,
+ 109, 122, 103
};
-static const int lexer_goto_row385[] = {
+static const int lexer_goto_row390[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row386[] = {
+static const int lexer_goto_row391[] = {
1,
48, 122, -41
};
-static const int lexer_goto_row387[] = {
+static const int lexer_goto_row392[] = {
1,
48, 122, -41
};
lexer_goto_row82,
lexer_goto_row83,
lexer_goto_row84,
- lexer_goto_row_null,
+ lexer_goto_row85,
lexer_goto_row86,
- lexer_goto_row87,
+ lexer_goto_row_null,
+ lexer_goto_row88,
+ lexer_goto_row89,
lexer_goto_row_null,
lexer_goto_row_null,
- lexer_goto_row90,
- lexer_goto_row91,
lexer_goto_row92,
lexer_goto_row93,
lexer_goto_row94,
- lexer_goto_row_null,
+ lexer_goto_row95,
lexer_goto_row96,
- lexer_goto_row97,
+ lexer_goto_row_null,
lexer_goto_row98,
lexer_goto_row99,
lexer_goto_row100,
lexer_goto_row138,
lexer_goto_row139,
lexer_goto_row140,
- lexer_goto_row_null,
+ lexer_goto_row141,
lexer_goto_row142,
lexer_goto_row_null,
lexer_goto_row144,
lexer_goto_row146,
lexer_goto_row_null,
lexer_goto_row148,
- lexer_goto_row149,
+ lexer_goto_row_null,
+ lexer_goto_row150,
+ lexer_goto_row151,
lexer_goto_row_null,
lexer_goto_row_null,
- lexer_goto_row152,
- lexer_goto_row153,
+ lexer_goto_row154,
+ lexer_goto_row155,
lexer_goto_row_null,
lexer_goto_row_null,
- lexer_goto_row156,
- lexer_goto_row157,
lexer_goto_row158,
lexer_goto_row159,
lexer_goto_row160,
lexer_goto_row162,
lexer_goto_row163,
lexer_goto_row164,
+ lexer_goto_row165,
+ lexer_goto_row166,
+ lexer_goto_row167,
+ lexer_goto_row168,
+ lexer_goto_row169,
lexer_goto_row_null,
lexer_goto_row_null,
lexer_goto_row_null,
lexer_goto_row_null,
- lexer_goto_row169,
- lexer_goto_row170,
- lexer_goto_row171,
- lexer_goto_row172,
- lexer_goto_row173,
lexer_goto_row174,
lexer_goto_row175,
lexer_goto_row176,
lexer_goto_row228,
lexer_goto_row229,
lexer_goto_row230,
- lexer_goto_row_null,
+ lexer_goto_row231,
lexer_goto_row232,
lexer_goto_row233,
lexer_goto_row234,
lexer_goto_row235,
- lexer_goto_row236,
- lexer_goto_row237,
lexer_goto_row_null,
+ lexer_goto_row237,
+ lexer_goto_row238,
lexer_goto_row239,
lexer_goto_row240,
lexer_goto_row241,
lexer_goto_row242,
- lexer_goto_row243,
+ lexer_goto_row_null,
lexer_goto_row244,
lexer_goto_row245,
lexer_goto_row246,
lexer_goto_row288,
lexer_goto_row289,
lexer_goto_row290,
+ lexer_goto_row291,
+ lexer_goto_row292,
+ lexer_goto_row293,
+ lexer_goto_row294,
+ lexer_goto_row295,
lexer_goto_row_null,
lexer_goto_row_null,
lexer_goto_row_null,
- lexer_goto_row294,
- lexer_goto_row295,
- lexer_goto_row296,
- lexer_goto_row297,
- lexer_goto_row298,
lexer_goto_row299,
lexer_goto_row300,
lexer_goto_row301,
lexer_goto_row333,
lexer_goto_row334,
lexer_goto_row335,
- lexer_goto_row_null,
+ lexer_goto_row336,
lexer_goto_row337,
lexer_goto_row338,
lexer_goto_row339,
lexer_goto_row340,
- lexer_goto_row341,
+ lexer_goto_row_null,
lexer_goto_row342,
lexer_goto_row343,
lexer_goto_row344,
lexer_goto_row381,
lexer_goto_row382,
lexer_goto_row383,
- lexer_goto_row_null,
+ lexer_goto_row384,
lexer_goto_row385,
lexer_goto_row386,
- lexer_goto_row387
+ lexer_goto_row387,
+ lexer_goto_row388,
+ lexer_goto_row_null,
+ lexer_goto_row390,
+ lexer_goto_row391,
+ lexer_goto_row392
};
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,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,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,-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
};
static int parser_action_row1[] = {
phase.process_nmodule(nmodule)
if errcount != self.error_count then
self.check_errors
- break
end
errcount = self.error_count
for nclassdef in nmodule.n_classdefs do
end
if errcount != self.error_count then
self.check_errors
- break
end
for na in vannot.annotations do
var p = na.parent
end
if errcount != self.error_count then
self.check_errors
- break
end
end
self.check_errors
while not todo.is_empty do
var mmethoddef = todo.shift
var mmeth = mmethoddef.mproperty
+ var msignature = mmethoddef.msignature
+ if msignature == null then continue # Skip broken method
+
#print "# visit {mmethoddef}"
var v = new RapidTypeVisitor(self, mmethoddef.mclassdef.bound_mtype, mmethoddef)
- var vararg_rank = mmethoddef.msignature.vararg_rank
+ var vararg_rank = msignature.vararg_rank
if vararg_rank > -1 then
var node = self.modelbuilder.mpropdef2node(mmethoddef)
- var elttype = mmethoddef.msignature.mparameters[vararg_rank].mtype
+ var elttype = msignature.mparameters[vararg_rank].mtype
#elttype = elttype.anchor_to(self.mainmodule, v.receiver)
var vararg = self.mainmodule.array_type(elttype)
v.add_type(vararg)
end
# TODO? new_msignature
- var sig = mmethoddef.msignature.as(not null)
+ var sig = msignature
var osig = mmeth.intro.msignature.as(not null)
for i in [0..sig.arity[ do
var origtype = osig.mparameters[i].mtype
continue
else if mmethoddef.constant_value != null then
# Make the return type live
- v.add_type(mmethoddef.msignature.return_mtype.as(MClassType))
+ v.add_type(msignature.return_mtype.as(MClassType))
continue
else if npropdef == null then
abort
if mmethoddef.is_intern or mmethoddef.is_extern then
# UGLY: We force the "instantation" of the concrete return type if any
- var ret = mmethoddef.msignature.return_mtype
+ var ret = msignature.return_mtype
if ret != null and ret isa MClassType and ret.mclass.kind != abstract_kind and ret.mclass.kind != interface_kind then
v.add_type(ret)
end
if not ot.can_resolve_for(t, t, mainmodule) then continue
var rt = ot.anchor_to(mainmodule, t)
if live_types.has(rt) then continue
+ if not check_depth(rt) then continue
#print "{ot}/{t} -> {rt}"
live_types.add(rt)
todo_types.add(rt)
- check_depth(rt)
end
end
#print "MType {live_types.length}: {live_types.join(", ")}"
#print "cast MType {live_cast_types.length}: {live_cast_types.join(", ")}"
end
- private fun check_depth(mtype: MClassType)
+ private fun check_depth(mtype: MClassType): Bool
do
var d = mtype.length
if d > 255 then
self.modelbuilder.toolcontext.fatal_error(null, "Fatal Error: limitation in the rapidtype analysis engine: a type depth of {d} is too important, the problematic type is `{mtype}`.")
+ return false
end
+ return true
end
fun add_new(recv: MClassType, mtype: MClassType)
redef fun visit(n)
do
- n.accept_rapid_type_visitor(self)
if n isa AExpr then
- var implicit_cast_to = n.implicit_cast_to
- if implicit_cast_to != null then self.add_cast_type(implicit_cast_to)
+ if n.mtype != null or n.is_typed then
+ n.accept_rapid_type_visitor(self)
+ var implicit_cast_to = n.implicit_cast_to
+ if implicit_cast_to != null then self.add_cast_type(implicit_cast_to)
+ end
+ else
+ n.accept_rapid_type_visitor(self)
end
# RTA does not enter in AAnnotations
# A local variable (including parameters, automatic variables and self)
class Variable
# The name of the variable (as used in the program)
- var name: String
+ var name: String is writable
# Alias of `name`
redef fun to_s do return self.name
# The declaration of the variable, if any
- var location: nullable Location = null
+ var location: nullable Location = null is writable
# Is the local variable not read and need a warning?
var warn_unread = false is writable
redef class AVarFormExpr
# The associated variable
- var variable: nullable Variable
+ var variable: nullable Variable is writable
end
redef class ACallFormExpr
redef class Variable
# The declared type of the variable
- var declared_type: nullable MType
+ var declared_type: nullable MType is writable
# Was the variable type-adapted?
# This is used to speedup type retrieval while it remains `false`
v.set_variable(self, variable, rettype)
- self.is_typed = true
+ self.is_typed = rettype != null
end
end
else
v.visit_expr(nexpr)
v.error(nexpr, "Error: `return` with value in a procedure.")
+ return
end
else if ret_type != null then
v.error(self, "Error: `return` without value in a function.")
+ return
end
self.is_typed = true
end
var mtype = self.attr_type
v.visit_expr_subtype(self.n_value, mtype)
- self.is_typed = true
+ self.is_typed = mtype != null
end
end
var mtype = self.attr_type
if mtype == null then return # Skip error
- self.resolve_reassignment(v, mtype, mtype)
+ var rettype = self.resolve_reassignment(v, mtype, mtype)
- self.is_typed = true
+ self.is_typed = rettype != null
end
end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2015 Julien Pagès <julien.pages@lirmm.fr>
+#
+# 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.
+
+# Single-Static Assignment algorithm from an AST
+module ssa
+
+import semantize
+import astbuilder
+
+# Represent a sequence of the program
+# A basic block is composed of several instructions without a jump
+class BasicBlock
+ # First instruction of the basic block
+ var first: ANode is noinit
+
+ # Last instruction of the basic block
+ var last: ANode is noinit
+
+ # Direct successors
+ var successors = new Array[BasicBlock]
+
+ # Direct predecessors
+ var predecessors = new Array[BasicBlock]
+
+ # Parts of AST that contain a read to a variable
+ var read_sites = new Array[AVarFormExpr]
+
+ # Parts of AST that contain a write to a variable
+ var write_sites = new Array[AVarFormExpr]
+
+ # Parts of AST that contain a variable access (read or write)
+ var variables_sites = new Array[AExpr]
+
+ # The iterated dominance frontier of this block
+ # i.e. the set of blocks this block dominate directly or indirectly
+ var dominance_frontier: Array[BasicBlock] = new Array[BasicBlock] is lazy
+
+ # Self is the old block to link to the new,
+ # The two blocks are not linked if the current ends with a `AReturnExpr` or `ABreakExpr`
+ # i.e. self is the predecessor of `successor`
+ # `successor` The successor block
+ fun link(successor: BasicBlock)
+ do
+ # Do not link the two blocks if the current block end with a return, break or continue
+ if last isa AReturnExpr or last isa ABreakExpr or last isa AContinueExpr then return
+
+ successors.add(successor)
+ successor.predecessors.add(self)
+ end
+
+ # Self is the old block to link to the new
+ # i.e. self is the predecessor of `successor`
+ # `successor` The successor block
+ fun link_special(successor: BasicBlock)
+ do
+ # Link the two blocks even if the current block ends with a return or a break
+ successors.add(successor)
+ successor.predecessors.add(self)
+ end
+
+ # Add the `block` to the dominance frontier of this block
+ fun add_df(block: BasicBlock)
+ do
+ dominance_frontier.add(block)
+
+ # Add this block recursively in super-blocks to compute the iterated
+ # dominance frontier
+ for successor in block.successors do
+ # If this successor has not already been add to the dominance frontier
+ if not dominance_frontier.has(successor) then
+ add_df(successor)
+ end
+ end
+ end
+
+ # Compute recursively the dominance frontier of self block and its successors
+ private fun compute_df
+ do
+ # Treat each block only one time
+ df_computed = true
+
+ for s in successors do
+ add_df(s)
+
+ if not s.df_computed then s.compute_df
+ end
+ end
+
+ # Used to handle recursions by treating only one time each block
+ var treated: Bool = false
+
+ # Used to dump the BasicBlock to dot
+ var treated_debug: Bool = false
+
+ # If true, the iterated dominance frontier of this block has been computed
+ var df_computed: Bool = false
+
+ # Indicate the BasicBlock is newly created and needs to be updated
+ var need_update: Bool = false
+
+ # Indicate if the variables renaming step has been made for this block
+ var is_renaming: Bool = false
+
+ # The variables that are accessed in this block
+ var variables = new Array[Variable] is lazy
+
+ # The PhiFunction this block contains at the beginning
+ var phi_functions = new Array[PhiFunction] is lazy
+end
+
+# Contain the currently analyzed propdef
+class SSA
+ # The currently analyzed APropdef
+ var propdef: APropdef
+
+ # The PhiFunction `current_propdef` contains
+ var phi_functions = new Array[PhiFunction]
+
+ # Recursively generate the basic blocks for this propdef
+ fun generate_basic_blocks
+ do
+ propdef.generate_basic_blocks(self)
+ end
+end
+
+redef class Variable
+ # The expressions of AST of this variable depends
+ var dep_exprs = new Array[AExpr]
+
+ # The blocks in which this variable is assigned
+ var assignment_blocks: Array[BasicBlock] = new Array[BasicBlock] is lazy
+
+ # Part of the program where this variable is read
+ var read_blocks: Array[BasicBlock] = new Array[BasicBlock] is lazy
+
+ # The stack of this variable, used for SSA renaming
+ var stack = new Array[Variable] is lazy
+
+ # The original Variable in case of renaming
+ var original_variable: nullable Variable = self
+
+ # If true, this variable is a parameter of a method
+ var parameter: Bool = false
+end
+
+# A PhiFunction is a kind of Variable used in SSA-construction,
+# it is placed at the beginning of a BasicBlock with many incoming blocks
+class PhiFunction
+ super Variable
+
+ # The dependences of this variable for SSA-Algorithm
+ var dependences = new Array[Couple[Variable, BasicBlock]]
+
+ # The position in the AST of the phi-function
+ var block: BasicBlock
+
+ # Set the dependences for the phi-function
+ # *`block` BasicBlock in which we go through the dominance-frontier
+ # *`v` The variable to looking for
+ fun add_dependences(block: BasicBlock, v: Variable)
+ do
+ # Look in which blocks of DF(block) `v` has been assigned
+ for b in block.predecessors do
+ if v.assignment_blocks.has(b) then
+ var dep = new Couple[Variable, BasicBlock](v, b)
+ dependences.add(dep)
+ end
+ end
+ end
+
+ # Print the PhiFunction with all its dependences
+ redef fun to_s: String
+ do
+ var s = ""
+ s += " dependences = [ "
+ for d in dependences do
+ s += d.first.to_s + " "
+ end
+ s += "]"
+
+ return s
+ end
+end
+
+redef class APropdef
+ # The variables contained in the body on this propdef
+ var variables: HashSet[Variable] = new HashSet[Variable] is lazy
+
+ # The first basic block of the code
+ var basic_block: nullable BasicBlock
+
+ # If true, the basic blocks where generated
+ var is_generated: Bool = false
+
+ # Generate all basic blocks for this code
+ fun generate_basic_blocks(ssa: SSA) is abstract
+
+ # Contain all AST-parts related to object mechanisms the propdef has:
+ # instantiation, method dispatch, attribute access, subtyping-test
+ var object_sites: Array[AExpr] = new Array[AExpr]
+
+ # Compute the three steps of SSA-algorithm
+ # `ssa` A new instance of SSA class initialized with `self`
+ fun compute_ssa(ssa: SSA)
+ do
+ if is_generated then return
+
+ # The first step is to generate the basic blocks
+ generate_basic_blocks(ssa)
+
+ # The propdef has no body (abstract)
+ if not is_generated then return
+
+ # Once basic blocks were generated, compute SSA algorithm
+ compute_phi(ssa)
+ rename_variables(ssa)
+ ssa_destruction(ssa)
+ end
+
+ # Compute the first phase of SSA algorithm: placing phi-functions
+ fun compute_phi(ssa: SSA)
+ do
+ var root_block = basic_block.as(not null)
+
+ # Compute the iterated dominance frontier of the graph of basic blocks
+ root_block.compute_df
+
+ # Places where a phi-function is added per variable
+ var phi_blocks = new HashMap[Variable, Array[BasicBlock]]
+
+ # For each variables in the propdef
+ for v in variables do
+ var phi_variables = new Array[BasicBlock]
+
+ var read_blocks = new Array[BasicBlock]
+ read_blocks.add_all(v.read_blocks)
+ read_blocks.add_all(v.assignment_blocks)
+
+ # While we have not treated each part accessing `v`
+ while not read_blocks.is_empty do
+ # Remove a block from the array
+ var block = read_blocks.shift
+
+ # For each block in the dominance frontier of `block`
+ for df in block.dominance_frontier do
+ # If we have not yet put a phi-function at the beginning of this block
+ if not phi_variables.has(df) then
+ phi_variables.add(df)
+
+ # Create a new phi-function and set its dependences
+ var phi = new PhiFunction("phi", df)
+ phi.add_dependences(df, v)
+ phi.block = df
+ phi.original_variable = phi
+ phi.declared_type = v.declared_type
+
+ # Indicate this phi-function is assigned in this block
+ phi.assignment_blocks.add(block)
+ ssa.phi_functions.add(phi)
+
+ # Add a phi-function at the beginning of df for variable v
+ df.phi_functions.add(phi)
+
+ if not v.read_blocks.has(df) or not v.assignment_blocks.has(df) then read_blocks.add(df)
+ end
+ end
+ end
+
+ # Add `phi-variables` to the global map
+ phi_blocks[v] = phi_variables
+ end
+ end
+
+ # Compute the second phase of SSA algorithm: renaming variables
+ # NOTE: `compute_phi` must has been called before
+ fun rename_variables(ssa: SSA)
+ do
+ # A counter for each variable
+ # The key is the variable, the value the number of assignment into the variable
+ var counter = new HashMap[Variable, Int]
+
+ for v in variables do
+ counter[v] = 0
+ v.stack.push(v)
+ end
+
+ for phi in ssa.phi_functions do counter[phi] = 0
+
+ # Launch the recursive renaming from the root block
+ rename(basic_block.as(not null), counter, ssa)
+ end
+
+ # Recursively rename each variable from `block`
+ # *`block` The starting basic block
+ # *`counter` The key is the variable, the value the number of assignment into the variable
+ fun rename(block: BasicBlock, counter: HashMap[Variable, Int], ssa: SSA)
+ do
+ if block.is_renaming then return
+
+ block.is_renaming = true
+
+ # For each phi-function of this block
+ for phi in block.phi_functions do
+ generate_name(phi, counter, block.first, ssa)
+
+ # Replace the phi into the block
+ block.phi_functions[block.phi_functions.index_of(phi)] = phi.original_variable.stack.last.as(PhiFunction)
+ end
+
+ # For each variable read in `block`
+ for vread in block.read_sites do
+ # Replace the old variable in AST
+ vread.variable = vread.variable.original_variable.stack.last
+ end
+
+ # For each variable write
+ for vwrite in block.write_sites do
+ generate_name(vwrite.variable.as(not null), counter, vwrite, ssa)
+
+ var new_version = vwrite.variable.original_variable.stack.last
+
+ # Set dependence of the new variable
+ if vwrite isa AVarReassignExpr then
+ new_version.dep_exprs.add(vwrite.n_value)
+ else if vwrite isa AVarAssignExpr then
+ new_version.dep_exprs.add(vwrite.n_value)
+ end
+
+ # Replace the old variable by the last created
+ vwrite.variable = new_version
+ end
+
+ # Rename occurrence of old names in phi-function
+ for successor in block.dominance_frontier do
+ for sphi in successor.phi_functions do
+ # Go over the couples in the phi dependences to rename variables
+ for couple in sphi.dependences do
+ if couple.second == block then
+ # Rename this variable
+ couple.first = couple.first.original_variable.stack.last
+ end
+ end
+ end
+ end
+
+ # Recurse in successor blocks
+ for successor in block.successors do
+ rename(successor, counter, ssa)
+ end
+
+ # Pop old names off the stack for each phi-function
+ for phi in block.phi_functions do
+ if not phi.stack.is_empty then phi.stack.pop
+ end
+ end
+
+ # Generate a new version of the variable `v` and return it
+ # *`v` The variable for which we generate a name
+ # *`counter` The key is the variable, the value the number of assignment into the variable
+ # *`expr` The AST node in which the assignment of v is made
+ # *`ssa` The instance of SSA
+ fun generate_name(v: Variable, counter: HashMap[Variable, Int], expr: ANode, ssa: SSA): Variable
+ do
+ var original_variable = v.original_variable.as(not null)
+
+ var i = counter[original_variable]
+
+ var new_version: Variable
+
+ # Create a new version of Variable
+ if original_variable isa PhiFunction then
+ var block = original_variable.block
+ new_version = new PhiFunction(original_variable.name + i.to_s, block)
+ new_version.dependences.add_all(original_variable.dependences)
+ ssa.phi_functions.add(new_version)
+ else
+ new_version = new Variable(original_variable.name + i.to_s)
+ new_version.declared_type = expr.as(AVarFormExpr).variable.declared_type
+ variables.add(new_version)
+ end
+
+ # Recopy the fields into the new version
+ new_version.location = expr.location
+ new_version.original_variable = original_variable
+
+ # Push a new version on the stack
+ original_variable.stack.add(new_version)
+ counter[v] = i + 1
+
+ return new_version
+ end
+
+ # Transform SSA-representation into an executable code (delete phi-functions)
+ # `ssa` Current instance of SSA
+ fun ssa_destruction(ssa: SSA)
+ do
+ var builder = new ASTBuilder(mpropdef.mclassdef.mmodule, mpropdef.mclassdef.bound_mtype)
+
+ # Iterate over all phi-functions
+ for phi in ssa.phi_functions do
+ for dep in phi.dependences do
+ # dep.second is the block where we need to create a varassign
+ var var_read = builder.make_var_read(dep.first, dep.first.declared_type.as(not null))
+ var nvar = builder.make_var_assign(dep.first, var_read)
+
+ var block = dep.second.last.parent
+
+ # This variable read must be add to a ABlockExpr
+ if block isa ABlockExpr then
+ block.add(nvar)
+ end
+
+ propagate_dependences(phi, phi.block)
+ ssa.propdef.variables.add(dep.first)
+ end
+ end
+ end
+
+ # Propagate the dependences of the phi-functions into following variables
+ # `phi` The PhiFunction
+ # `block` Current block where we propagate dependences
+ fun propagate_dependences(phi: PhiFunction, block: BasicBlock)
+ do
+ # Treat each block once
+ if block.treated then return
+
+ # For each variable access site in the block
+ for site in block.variables_sites do
+ if site isa AVarExpr then
+ # Propagate the dependences of the phi-function in variables after the phi
+ for dep in phi.dependences do
+ for expr in dep.first.dep_exprs do
+ if site.variable.dep_exprs.has(expr) then break
+
+ if dep.first.original_variable == site.variable.original_variable then
+ site.variable.dep_exprs.add(expr)
+ end
+ end
+ end
+ else
+ # The site is a variable write, we stop the propagation
+ return
+ end
+ end
+
+ block.treated = true
+
+ # If we do not meet a variable write, continue the propagation
+ for b in block.successors do propagate_dependences(phi, b)
+ end
+end
+
+redef class AAttrPropdef
+ redef fun generate_basic_blocks(ssa: SSA)
+ do
+ basic_block = new BasicBlock
+ basic_block.first = self
+ basic_block.last = self
+
+ # Add the self variable
+ if self.selfvariable != null then variables.add(selfvariable.as(not null))
+
+ # Recursively goes into the nodes
+ if n_block != null then
+ n_block.generate_basic_blocks(ssa, basic_block.as(not null))
+ is_generated = true
+ end
+ end
+end
+
+redef class AMethPropdef
+
+ # The return variable of the propdef
+ # Create an empty variable for the return of the method
+ # and treat returns like variable assignments
+ var returnvar: Variable = new Variable("returnvar")
+
+ redef fun generate_basic_blocks(ssa: SSA)
+ do
+ basic_block = new BasicBlock
+ basic_block.first = self
+ basic_block.last = self
+
+ # If the method has a signature
+ if n_signature != null then
+ for p in n_signature.n_params do
+ # Add parameters to the local variables
+ variables.add(p.variable.as(not null))
+ p.variable.parameter = true
+ end
+ end
+
+ # Add the return variable
+ variables.add(returnvar)
+
+ # Add the self variable
+ if self.selfvariable != null then variables.add(selfvariable.as(not null))
+
+ # Recursively goes into the nodes
+ if n_block != null then
+ n_block.generate_basic_blocks(ssa, basic_block.as(not null))
+ is_generated = true
+ end
+ end
+end
+
+# Utility class for dump basic block and SSA output to dot files
+class BlockDebug
+ # The output file
+ var file: FileWriter
+
+ # Dump all the hierarchy of BasicBlock from `block` to the leaves
+ fun dump(block: BasicBlock)
+ do
+ # Write the basic blocks hierarchy in output file
+ file.write("digraph basic_blocks\n\{\n")
+ var i = 0
+ file.write(print_block(block, i))
+ file.write("\n\}")
+
+ file.close
+ end
+
+ # Print all the block recursively from `block` to the leaves
+ # *`block` The root BasicBlock
+ # *`i` Used for the recursion
+ private fun print_block(block: BasicBlock, i: Int): String
+ do
+ # Precise the type and location of the begin and end of current block
+ var s = "block{block.hash.to_s} [shape=record, label="+"\"\{"
+ s += "block" + block.to_s.escape_to_dot
+ s += "|\{" + block.first.location.file.filename.to_s + block.first.location.line_start.to_s
+ s += " | " + block.first.to_s.escape_to_dot
+
+ # Print phi-functions if any
+ for phi in block.phi_functions do
+ s += " | " + phi.to_s.escape_to_dot + " "
+ end
+
+ s += "}|\{" + block.last.location.file.filename.to_s + block.last.location.line_start.to_s
+ s += " | " + block.last.to_s.escape_to_dot + "}}\"];"+ "\n"
+
+ i += 1
+ block.treated_debug = true
+
+ for b in block.successors do
+ # Print edges to successors
+ s += "block{block.hash.to_s} -> " + " block{b.hash.to_s};\n"
+
+ # Recursively print child blocks
+ if not b.treated_debug then s += print_block(b, i)
+ end
+
+ return s
+ end
+end
+
+redef class AExpr
+ # Generate recursively basic block for this expression
+ # *`ssa` An instance of the SSA class initialized with the enclosing `APropdef`
+ # *`old_block` A basic block not completely filled
+ # Return the last created block (the last block can be nested)
+ fun generate_basic_blocks(ssa: SSA, old_block: BasicBlock): BasicBlock
+ do
+ return old_block
+ end
+end
+
+redef class AVarFormExpr
+ # The original variable
+ var original_variable: nullable Variable = variable
+end
+
+redef class AVarExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.variable.as(not null).read_blocks.add(old_block)
+ old_block.variables.add(self.variable.as(not null))
+
+ self.variable.as(not null).original_variable = self.variable.as(not null)
+ # Save this read site in the block
+ old_block.read_sites.add(self)
+ old_block.variables_sites.add(self)
+
+ return old_block
+ end
+end
+
+redef class AVardeclExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ var decl = self.variable.as(not null)
+
+ # Add the corresponding variable to the enclosing mpropdef
+ ssa.propdef.variables.add(decl)
+
+ decl.original_variable = decl
+ decl.assignment_blocks.add(old_block)
+ old_block.variables.add(decl)
+
+ if self.n_expr != null then
+ self.variable.dep_exprs.add(self.n_expr.as(not null))
+ old_block = self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+
+ return old_block
+ end
+end
+
+redef class AVarAssignExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.variable.as(not null).assignment_blocks.add(old_block)
+ old_block.variables.add(self.variable.as(not null))
+ self.variable.as(not null).original_variable = self.variable.as(not null)
+
+ # Save this write site in the block
+ old_block.write_sites.add(self)
+ old_block.variables_sites.add(self)
+
+ ssa.propdef.variables.add(self.variable.as(not null))
+
+ return self.n_value.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AVarReassignExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.variable.as(not null).assignment_blocks.add(old_block)
+ old_block.variables.add(self.variable.as(not null))
+ self.variable.as(not null).original_variable = self.variable.as(not null)
+
+ # Save this write site in the block
+ old_block.write_sites.add(self)
+ old_block.variables_sites.add(self)
+
+ ssa.propdef.variables.add(self.variable.as(not null))
+ return self.n_value.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class ABreakExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ # Finish the old block
+ old_block.last = self
+
+ return old_block
+ end
+end
+
+redef class AContinueExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ return old_block
+ end
+end
+
+redef class AReturnExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ # The return just set the current block and stop the recursion
+ if self.n_expr != null then
+ old_block = self.n_expr.generate_basic_blocks(ssa, old_block)
+
+ # Store the return expression in the dependences of the dedicated returnvar
+ if ssa.propdef isa AMethPropdef then
+ ssa.propdef.as(AMethPropdef).returnvar.dep_exprs.add(n_expr.as(not null))
+ end
+ end
+
+ old_block.last = self
+
+ return old_block
+ end
+end
+
+redef class AAssertExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+
+ # The condition of the assert is the last expression of the previous block
+ old_block.last = self.n_expr
+
+ # The block if the assert fail
+ var block_false = new BasicBlock
+
+ if self.n_else != null then
+ block_false.first = self.n_else.as(not null)
+ block_false.last = self.n_else.as(not null)
+ self.n_else.generate_basic_blocks(ssa, block_false)
+ else
+ block_false.first = self
+ block_false.first = self
+ end
+
+ old_block.link(block_false)
+
+ # The block if the assert is true: the execution continue
+ var block_true = new BasicBlock
+ block_true.first = self
+ block_true.last = self
+
+ old_block.link(block_true)
+
+ return block_true
+ end
+end
+
+redef class AOrExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+ return self.n_expr2.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AImpliesExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+ return self.n_expr2.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AAndExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+ return self.n_expr2.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class ANotExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AOrElseExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+ return self.n_expr2.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AArrayExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ for nexpr in self.n_exprs do
+ old_block = nexpr.generate_basic_blocks(ssa, old_block)
+ end
+
+ return old_block
+ end
+end
+
+redef class ASuperstringExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ for nexpr in self.n_exprs do old_block = nexpr.generate_basic_blocks(ssa, old_block)
+
+ return old_block
+ end
+end
+
+redef class ACrangeExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+ return self.n_expr2.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AOrangeExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+ return self.n_expr2.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AIsaExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ ssa.propdef.object_sites.add(self)
+
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AAsCastExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ ssa.propdef.object_sites.add(self)
+
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AAsNotnullExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AParExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AOnceExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class ASendExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ # A call does not finish the current block,
+ # because we create intra-procedural basic blocks here
+
+ ssa.propdef.object_sites.add(self)
+
+ # Recursively goes into arguments to find variables if any
+ for e in self.raw_arguments do e.generate_basic_blocks(ssa, old_block)
+
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class ASendReassignFormExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+
+ ssa.propdef.object_sites.add(self)
+
+ # Recursively goes into arguments to find variables if any
+ for e in self.raw_arguments do e.generate_basic_blocks(ssa, old_block)
+
+ return self.n_value.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class ASuperExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ # Recursively goes into arguments to find variables if any
+ for arg in self.n_args.n_exprs do arg.generate_basic_blocks(ssa, old_block)
+
+ return old_block
+ end
+end
+
+redef class ANewExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ for e in self.n_args.n_exprs do e.generate_basic_blocks(ssa, old_block)
+
+ ssa.propdef.object_sites.add(self)
+
+ return old_block
+ end
+end
+
+redef class AAttrExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ ssa.propdef.object_sites.add(self)
+
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AAttrAssignExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ ssa.propdef.object_sites.add(self)
+
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AAttrReassignExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ ssa.propdef.object_sites.add(self)
+
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class AIssetAttrExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ return self.n_expr.generate_basic_blocks(ssa, old_block)
+ end
+end
+
+redef class ABlockExpr
+ # The block needs to know if a new block is created
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ var last_block = old_block
+ var current_block: BasicBlock
+
+ # Recursively continue in the body of the block
+ for i in [0..self.n_expr.length[ do
+ current_block = self.n_expr[i].generate_basic_blocks(ssa, last_block)
+
+ if current_block.need_update then
+ if i < (self.n_expr.length-1) then
+ # Current_block must be filled
+ current_block.first = self.n_expr[i+1]
+ current_block.last = self.n_expr[i+1]
+ current_block.need_update = false
+ else
+ # Put the current block at the end of the block
+ current_block.first = last_block.last
+ current_block.last = last_block.last
+ end
+ end
+
+ if not current_block.last isa AEscapeExpr or current_block.last isa AReturnExpr then
+ # Re-affected the last block
+ current_block.last = self.n_expr[i]
+ end
+
+ last_block = current_block
+ end
+
+ return last_block
+ end
+end
+
+redef class AIfExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ # Terminate the previous block
+ old_block.last = self
+
+ # We start two new blocks if the if has two branches
+ var block_then = new BasicBlock
+
+ # Visit the test of the if
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+
+ # Launch the recursion in two successors if they exist
+ if self.n_then != null then
+ old_block.link(block_then)
+
+ block_then.first = self.n_then.as(not null)
+ block_then.last = self.n_then.as(not null)
+ self.n_then.generate_basic_blocks(ssa, block_then)
+ end
+
+ var block_else = new BasicBlock
+
+ if self.n_else != null then
+ old_block.link(block_else)
+
+ block_else.first = self.n_else.as(not null)
+ block_else.last = self.n_else.as(not null)
+ self.n_else.generate_basic_blocks(ssa, block_else)
+ end
+
+ # Create a new BasicBlock to represent the two successor
+ # branches of the if
+ var new_block = new BasicBlock
+ new_block.first = self
+ new_block.last = self
+
+ if self.n_then != null then block_then.link(new_block)
+
+ # The new block needs to be filled by the caller
+ new_block.need_update = true
+
+ if block_else.predecessors.length != 0 then block_else.link(new_block)
+
+ return new_block
+ end
+end
+
+redef class AIfexprExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ # Terminate the previous block
+ old_block.last = self
+
+ # We start two new blocks if the if has two branches
+ var block_then = new BasicBlock
+
+ # Visit the test of the if
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+
+ # Launch the recursion in two successors if they exist
+ old_block.link(block_then)
+
+ block_then.first = self.n_then
+ block_then.last = self.n_then
+ self.n_then.generate_basic_blocks(ssa, block_then)
+
+ var block_else = new BasicBlock
+
+ old_block.link(block_else)
+
+ block_else.first = self.n_else
+ block_else.last = self.n_else
+ self.n_else.generate_basic_blocks(ssa, block_else)
+
+ # Create a new BasicBlock to represent the two successor
+ # branches of the if
+ var new_block = new BasicBlock
+ new_block.first = self
+ new_block.last = self
+
+ block_then.link(new_block)
+
+ # The new block needs to be filled by the caller
+ new_block.need_update = true
+
+ block_else.link(new_block)
+
+ return new_block
+ end
+end
+
+redef class ADoExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ old_block.last = self
+
+ # The beginning of the block is the first instruction
+ var block = new BasicBlock
+ block.first = self.n_block.as(not null)
+ block.last = self.n_block.as(not null)
+
+ old_block.link(block)
+ return self.n_block.generate_basic_blocks(ssa, block)
+ end
+end
+
+redef class AWhileExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ old_block.last = self
+
+ # The beginning of the block is the test of the while
+ var block = new BasicBlock
+ block.first = self.n_expr
+ block.last = self.n_block.as(not null)
+
+ old_block.link(block)
+
+ self.n_expr.generate_basic_blocks(ssa, old_block)
+ var inside_block = self.n_block.generate_basic_blocks(ssa, block)
+
+ # Link the inside of the block to the previous block
+ block.link_special(old_block)
+
+ # Create a new Block after the while
+ var new_block = new BasicBlock
+ new_block.need_update = true
+
+ old_block.link_special(new_block)
+
+ return new_block
+ end
+end
+
+redef class ALoopExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ old_block.last = self
+
+ # The beginning of the block is the first instruction
+ var block = new BasicBlock
+ block.first = self.n_block.as(not null)
+ block.last = self.n_block.as(not null)
+
+ old_block.link(block)
+ self.n_block.generate_basic_blocks(ssa, block)
+
+ return block
+ end
+end
+
+redef class AForExpr
+ redef fun generate_basic_blocks(ssa, old_block)
+ do
+ old_block.last = self
+
+ # The beginning of the block is the first instruction
+ var block = new BasicBlock
+ block.first = self.n_expr
+ block.last = self.n_block.as(not null)
+
+ # Visit the test of the if
+ self.n_expr.generate_basic_blocks(ssa, block)
+
+ # Collect the variables declared in the for
+ for v in variables do
+ ssa.propdef.variables.add(v)
+ end
+
+ old_block.link(block)
+
+ block.link(old_block)
+
+ var new_block = new BasicBlock
+ new_block.need_update = true
+
+ return new_block
+ end
+end
var nadd = v.builder.make_call(recv, na.push_callsite.as(not null), [self])
place.replace_with(nadd)
end
- super
+
+ visit_all(v)
+
+ if mtype == null and not is_typed then return # Skip broken
+
+ accept_transform_visitor(v)
end
redef fun replace_with(other)
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2015 Julien Pagès <julien.pages@lirmm.fr>
+#
+# 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.
+
+# The compilation module of the VirtualMachine
+module compilation
+
+import variables_numbering
+import ssa
+
+redef class VirtualMachine
+
+ # The currently analyzed APropdef
+ var current_propdef: APropdef
+
+ redef fun new_frame(node, mpropdef, args)
+ do
+ # Save the current propdef
+ if node isa APropdef then self.current_propdef = node
+
+ return super
+ end
+end
+
+redef class APropdef
+
+ redef fun compile(vm)
+ do
+ super
+
+ # A new instance of SSA to analyze the self propdef
+ var ssa = new SSA(self)
+
+ # Generate basic_blocks and compute SSA-algorithm for this propdef
+ compute_ssa(ssa)
+ end
+
+ # Redef to add the same position to a new version of a Variable than the original variable
+ redef fun generate_name(v, counter, expr, ssa)
+ do
+ var new_version = super
+
+ # All versions of a variable have the same position in the environment
+ new_version.position = v.original_variable.position
+
+ return new_version
+ end
+end
do
var f = new VmFrame(node, mpropdef, args)
- # If this Frame is for a method then number variables into the body of the method
- if node isa AMethPropdef then
- # Number the variables
- if not node.is_numbering then node.numbering_variables(self, mpropdef.as(MMethodDef))
-
- # Create an empty environment
- f.variables = new Array[Instance].filled_with(initialization_value, node.environment_size)
- end
-
- # If this Frame is for an attribute with a block then number the block
- if node isa AAttrPropdef then
- # Number the variables
- if not node.is_numbering then node.numbering_variables(self)
+ # If this Frame is for a method or an attribute block then number variables into the body of the method
+ if node isa APropdef then
+ # Compile the code (number its local variables)
+ if not node.is_compiled then node.compile(self)
# Create an empty environment
f.variables = new Array[Instance].filled_with(initialization_value, node.environment_size)
redef class Variable
# The position in the environment
- var position: Int
+ var position: Int is writable
end
# Implementation of a Frame with numbered variables
end
redef class APropdef
+ # Indicite if this propdef was compile
+ var is_compiled: Bool = false
+
# Indicate if the variables numbering has been done
private var is_numbering: Bool = false
# The size of the environment to create to call this method
private var environment_size: Int = 0
+
+ # Compile this propdef
+ # *`vm` The running instance of `VirtualMachine`
+ fun compile(vm: VirtualMachine)
+ do
+ # Number the variables
+ if not is_numbering then numbering_variables(vm)
+
+ is_compiled = true
+ end
+
+ # Numbering the variable inside the propdef
+ fun numbering_variables(vm: VirtualMachine) is abstract
end
redef class AMethPropdef
- # Assign a position in the environment to each local variable of `mpropdef`
- # *`v` The current VirtualMachine
- # *`mpropdef` The method to number
- private fun numbering_variables(v: VirtualMachine, mpropdef: MMethodDef)
+ # Assign a position in the environment to each local variable
+ # *`vm` The current VirtualMachine
+ redef fun numbering_variables(vm: VirtualMachine)
do
# The position in the environment
var position = 0
# Recursively go into the AST nodes to number all local variables
if n_block != null then
- position = v.numbering(self.n_block, position)
+ position = vm.numbering(self.n_block, position)
end
is_numbering = true
end
redef class AAttrPropdef
- # Assign a position in the environment to each local variable of `mpropdef`
- # *`v` The current VirtualMachine
- private fun numbering_variables(v: VirtualMachine)
+ # Assign a position in the environment to each local variable
+ # *`vm` The current VirtualMachine
+ redef fun numbering_variables(vm: VirtualMachine)
do
# The position in the environment
var position = 0
# Recursively go into the AST nodes to number all local variables
if n_block != null then
- position = v.numbering(self.n_block, position)
+ position = vm.numbering(self.n_block, position)
end
is_numbering = true
import virtual_machine
import vm_optimizations
import variables_numbering
+import compilation
--- /dev/null
+8/4
+8*2
+16+8
t2 = t2.next #alt2# t2 = null
end
#alt3#t2 = t2.next
+ #alt3#exit(0)
end
if i != null then
bar(i)
else
- break #alt4#
+ break #alt4# exit(0)
end
end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+class Foo
+ fun start do end
+ fun finish do end
+end
+fun foo: Foo do return new Foo
+
+do do
+ 1.output
+end
+while false do do
+ 2.output
+end
+if true then do
+ 3.output
+end else do
+ 4.output
+end
+for i in [0..1] do do
+ 5.output
+end
+with foo do do
+ 6.output
+end
+loop do
+ 7.output
+ return
+end
--- /dev/null
+numbers: 8, 4, 8, 8
+numbers: 8, 8, 2
+numbers: 8, 16
+CONGRATULATIONS
--- /dev/null
+base_do_block.nit:21,4--23,3: Warning: superfluous `do` block.
+base_do_block.nit:24,16--26,3: Warning: superfluous `do` block.
+base_do_block.nit:32,20--34,3: Warning: superfluous `do` block.
+base_do_block.nit:35,13--37,3: Warning: superfluous `do` block.
+base_do_block.nit:38,6--41,3: Warning: superfluous `do` block.
+1
+3
+5
+5
+6
+7
-alt/base_import_alt3.nit:1,8--21: Error: cannot find module `fail` from `project1`. Tried: ., ../lib/standard, ../lib/standard/collection, alt, ../lib.
+alt/base_import_alt3.nit:1,8--21: Error: cannot find module `fail` from `project1`. Tried: ., ../lib/standard, ../lib/standard/collection, alt, ../lib, ../contrib.
-error_mod_unk.nit:17,8--11: Error: cannot find module `dfgd` from `error_mod_unk`. Tried: ., ../lib/standard, ../lib/standard/collection, alt, ../lib.
+error_mod_unk.nit:17,8--11: Error: cannot find module `dfgd` from `error_mod_unk`. Tried: ., ../lib/standard, ../lib/standard/collection, alt, ../lib, ../contrib.
8:MPropDef
13:MAttributeDef
=properties=JsonObject(5):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["\u000e2\u00080\u0009cAnswer to the Ultimate Question of Life, the Universe, and Everything.","\u000e2\u00080\u0009c"],"is_intro":true}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["“Answer to the Ultimate Question of Life, the Universe, and Everything.","“"],"is_intro":true}
----
=to=Entity#0:
=labels=Array(4):
8:MPropDef
13:MAttributeDef
=properties=JsonObject(5):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["\u000e2\u00080\u0009cAnswer to the Ultimate Question of Life, the Universe, and Everything.","\u000e2\u00080\u0009c"],"is_intro":true}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["“Answer to the Ultimate Question of Life, the Universe, and Everything.","“"],"is_intro":true}
----
=to=Entity#0:
=labels=Array(4):
8:MPropDef
13:MAttributeDef
=properties=JsonObject(5):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["\u000e2\u00080\u0009cAnswer to the Ultimate Question of Life, the Universe, and Everything.","\u000e2\u00080\u0009c"],"is_intro":true}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["“Answer to the Ultimate Question of Life, the Universe, and Everything.","“"],"is_intro":true}
Edge
8:MPropDef
13:MAttributeDef
=properties=JsonObject(5):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["\u000e2\u00080\u0009cAnswer to the Ultimate Question of Life, the Universe, and Everything.","\u000e2\u00080\u0009c"],"is_intro":true}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["“Answer to the Ultimate Question of Life, the Universe, and Everything.","“"],"is_intro":true}
----
=to=Entity#0:
=labels=Array(4):
8:MPropDef
13:MAttributeDef
=properties=JsonObject(5):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["\u000e2\u00080\u0009cAnswer to the Ultimate Question of Life, the Universe, and Everything.","\u000e2\u00080\u0009c"],"is_intro":true}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["“Answer to the Ultimate Question of Life, the Universe, and Everything.","“"],"is_intro":true}
----
=to=Entity#0:
=labels=Array(4):
8:MPropDef
13:MAttributeDef
=properties=JsonObject(5):
-{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["\u000e2\u00080\u0009cAnswer to the Ultimate Question of Life, the Universe, and Everything.","\u000e2\u00080\u0009c"],"is_intro":true}
+{"location":"%SOURCE_DIRECTORY%\/org\/example\/foo\/C.java:25,1---1,1","visibility":"public","name":"THE_ANSWER","mdoc":["“Answer to the Ultimate Question of Life, the Universe, and Everything.","“"],"is_intro":true}
Edge
k
2234
12345.0
+0x12
hello world
12.346
12.3
12
+0.5
+0.000
+0.000003125
+3410.0
+400.0
+10.0
--- /dev/null
+test_keep_going.nit:15,11--14: Error: class `Fail` not found in module `test_keep_going`.
-../examples/nitcorn/src/xymus_net.nit:24,8--14: Error: cannot find module `tnitter` from `nitcorn`. Tried: alt, ../lib, ../examples/nitcorn.
-../examples/nitcorn/src/xymus_net.nit:25,8--26: Error: cannot find module `benitlux_controller` from `nitcorn`. Tried: alt, ../lib, ../examples/nitcorn.
-../examples/nitcorn/src/xymus_net.nit:26,8--29: Error: cannot find module `opportunity_controller` from `nitcorn`. Tried: alt, ../lib, ../examples/nitcorn.
+../examples/nitcorn/src/xymus_net.nit:25,8--26: Error: cannot find module `benitlux_controller` from `nitcorn`. Tried: alt, ../lib, ../contrib, ../examples/nitcorn.
+../examples/nitcorn/src/xymus_net.nit:26,8--29: Error: cannot find module `opportunity_controller` from `nitcorn`. Tried: alt, ../lib, ../contrib, ../examples/nitcorn.
# This file is part of NIT ( http://www.nitlanguage.org ).
#
-# Copyright 2011-2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# See the License for the specific language governing permissions and
# limitations under the License.
-fun opposite( v : Bool ) : Bool `{
+fun opposite(v: Bool): Bool `{
return v == 0;
`}
-fun plus_10( v : Char ) : Char `{
+
+fun plus_10(v: Char): Char `{
return v + 10;
`}
-fun plus_1000( v : Int ) : Int `{
+
+fun plus_1000(v: Int): Int `{
return v + 1000;
`}
-fun multiply_by_100( v : Float ) : Float `{
+
+fun multiply_by_100(v: Float): Float `{
return v * 100;
`}
-fun print_ns( s : NativeString ) `{
- printf( "%s\n", s );
+
+fun plus_0x10(v: Byte): Byte `{
+ return v + 0x10;
+`}
+
+fun print_ns(s: NativeString) `{
+ printf("%s\n", s);
`}
-print opposite( true )
-print opposite( false )
+print opposite(true)
+print opposite(false)
+
+print plus_10('a')
-print plus_10( 'a' )
+print plus_1000(1234)
-print plus_1000( 1234 )
+print multiply_by_100(123.45)
-print multiply_by_100( 123.45 )
+print plus_0x10(0x2u8)
-print_ns( "hello world".to_cstring )
+print_ns("hello world".to_cstring)
`}
fun print_a(str: String) import String.to_cstring in "C++" `{
- puts(String_to_cstring(str));
+ puts(reinterpret_cast<char*>(String_to_cstring(str)));
`}
print_a "Hello from `a`."
`}
fun print_b(str: String) import String.to_cstring in "C++" `{
- puts(String_to_cstring(str));
+ puts(reinterpret_cast<char*>(String_to_cstring(str)));
`}
print_a "Hello from `a`."
print(f.to_precision(3))
print(f.to_precision(1))
print(f.to_precision(0))
+f = 5.0e-1
+print(f)
+f = 3.125e-6
+print(f.to_precision(3))
+print(f.to_precision(9))
+f = 3.41e3
+print f
+f = 4e2
+print f
+f = .1e2
+print f
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+fun plop: Fail
+do
+ print 1
+end
+
+1.output
+if false then
+ plop
+end
+2.output
+if false then
+ fail
+end
+3.output
+if false then
+ var x = new Fail
+ x.output
+end
+4.output
+if false then
+ if 1 then abort
+end
+5.output
+if false then
+ abort
+ 999.output
+end
+6.output
+if false then
+ var a = new Sys.fail
+ a.output
+end
+7.output