var str = file.to_path.read_all
var parser = new MarkdownProcessor
+parser.no_location = true
for i in [1..n] do
print parser.process(str)
end
#
# assert 3.is_prime
# assert not 1.is_prime
- # assert not 12.is_prime
+ # assert not 15.is_prime
fun is_prime: Bool
do
if self == 2 then
else if self <= 1 or self.is_even then
return false
end
- for i in [3..self.sqrt[ do
+ for i in [3..self.sqrt] do
if self % i == 0 then return false
end
return true
fun char_to_byte_index(index: Int): Int do
var dpos = index - _position
var b = _bytepos
+ var its = _items
- if dpos == 0 then return b
if dpos == 1 then
- b += _items.length_of_char_at(b)
+ if its[b] & 0x80u8 == 0x00u8 then
+ b += 1
+ else
+ b += its.length_of_char_at(b)
+ end
_bytepos = b
_position = index
return b
end
if dpos == -1 then
- b = _items.find_beginning_of_char_at(b - 1)
+ b = its.find_beginning_of_char_at(b - 1)
_bytepos = b
_position = index
return b
end
+ if dpos == 0 then return b
var ln = _length
var pos = _position
var delta_end = (ln - 1) - index
var delta_cache = (pos - index).abs
var min = delta_begin
- var its = _items
if delta_cache < min then min = delta_cache
if delta_end < min then min = delta_end
end
redef fun [](index) do
- assert index >= 0 and index < _length
+ var len = _length
+
+ # Statistically:
+ # * ~70% want the next char
+ # * ~23% want the previous
+ # * ~7% want the same char
+ #
+ # So it makes sense to shortcut early. And early is here.
+ var dpos = index - _position
+ var b = _bytepos
+ if dpos == 1 and index < len - 1 then
+ var its = _items
+ var c = its[b]
+ if c & 0x80u8 == 0x00u8 then
+ # We want the next, and current is easy.
+ # So next is easy to find!
+ b += 1
+ _position = index
+ _bytepos = b
+ # The rest will be done by `dpos==0` bellow.
+ dpos = 0
+ end
+ else if dpos == -1 and index > 1 then
+ var its = _items
+ var c = its[b-1]
+ if c & 0x80u8 == 0x00u8 then
+ # We want the previous, and it is easy.
+ b -= 1
+ dpos = 0
+ _position = index
+ _bytepos = b
+ return c.ascii
+ end
+ end
+ if dpos == 0 then
+ # We know what we want (+0 or +1) just get it now!
+ var its = _items
+ var c = its[b]
+ if c & 0x80u8 == 0x00u8 then return c.ascii
+ return items.char_at(b)
+ end
+
+ assert index >= 0 and index < len
return fetch_char_at(index)
end
#
# Very unsafe, make sure to have room for this char prior to calling this function.
private fun set_char_at(pos: Int, c: Char) do
+ if c.code_point < 128 then
+ self[pos] = c.code_point.to_b
+ return
+ end
var ln = c.u8char_len
native_set_char(pos, c, ln)
end
# ~~~
var ext_mode = true
+ # Disable attaching MDLocation to Tokens
+ #
+ # Locations are useful for some tools but they may
+ # cause an important time and space overhead.
+ #
+ # Default = `false`
+ var no_location = false is writable
+
init do self.emitter = new MarkdownEmitter(self)
# Process the mardown `input` string and return the processed output.
c2 = ' '
end
- var loc = new MDLocation(
- current_loc.line_start,
- current_loc.column_start + pos,
- current_loc.line_start,
- current_loc.column_start + pos)
+ var loc
+ if no_location then
+ loc = null
+ else
+ loc = new MDLocation(
+ current_loc.line_start,
+ current_loc.column_start + pos,
+ current_loc.line_start,
+ current_loc.column_start + pos)
+ end
if c == '*' then
if c1 == '*' then
end
# Append `c` to current buffer.
- fun addc(c: Char) do add c.to_s
+ fun addc(c: Char) do
+ current_buffer.add c
+ end
# Append a "\n" line break.
- fun addn do add "\n"
+ fun addn do addc '\n'
end
# A Link Reference.
abstract class Token
# Location of `self` in the original input.
- var location: MDLocation
+ var location: nullable MDLocation
# Position of `self` in input independant from lines.
var pos: Int
if c == '\\' and pos + 1 < length then
pos = escape(out, self[pos + 1], pos)
else
- var end_reached = false
- for n in nend do
- if c == n then
- end_reached = true
- break
- end
- end
- if end_reached then break
+ for n in nend do if c == n then break label
out.add c
end
pos += 1
- end
+ end label
if pos == length then return -1
return pos
end
redef fun token_at(input, pos) do
var token = super
if token isa TokenNone then return token
- var res = "{token.class_name} at {token.location}"
+ var res = "{token.class_name} at {token.location or else "?"}"
var exp = test_stack.shift
print ""
print "EXP {exp}"
else if node isa AClassdef then
# Automatic free init is always inlined since it is empty or contains only attribtes assigments
return true
+ else if node == null then
+ return true
else
abort
end
v.assign(v.frame.returnvar.as(not null), res)
else if mpropdef == mwritepropdef then
assert arguments.length == 2
- v.write_attribute(self.mpropdef.mproperty, arguments.first, arguments[1])
+ var recv = arguments.first
+ var arg = arguments[1]
+ if is_optional then
+ var value = v.new_var(self.mpropdef.static_mtype.as(not null))
+ v.add("if ({arg} == NULL) \{")
+ v.assign(value, evaluate_expr(v, recv))
+ v.add("\} else \{")
+ v.assign(value, arg)
+ v.add("\}")
+ arg = value
+ end
+ v.write_attribute(self.mpropdef.mproperty, arguments.first, arg)
if is_lazy then
var ret = self.mtype
var useiset = not ret.is_c_primitive and not ret isa MNullableType
noinit
readonly
writable
+optional
autoinit
noautoinit
lateinit
return evaluate_expr(v, recv, f)
else if mpropdef == mwritepropdef then
assert args.length == 2
- v.write_attribute(attr, recv, args[1])
+ var arg = args[1]
+ if is_optional and arg.mtype isa MNullType then
+ var f = v.new_frame(self, mpropdef, args)
+ arg = evaluate_expr(v, recv, f)
+ end
+ v.write_attribute(attr, recv, arg)
return null
else
abort
mreadpropdef.mproperty.is_autoinit = true
continue
end
- if npropdef.has_value then continue
- var paramname = mreadpropdef.mproperty.name
- var ret_type = msignature.return_mtype
- if ret_type == null then return
- var mparameter = new MParameter(paramname, ret_type, false)
- mparameters.add(mparameter)
+ if npropdef.has_value and not npropdef.is_optional then continue
var msetter = npropdef.mwritepropdef
if msetter == null then
# No setter, it is a readonly attribute, so just add it
+ var paramname = mreadpropdef.mproperty.name
+ var ret_type = msignature.return_mtype
+ if ret_type == null then return
+ var mparameter = new MParameter(paramname, ret_type, false)
+ mparameters.add(mparameter)
+
initializers.add(npropdef.mpropdef.mproperty)
npropdef.mpropdef.mproperty.is_autoinit = true
else
# Add the setter to the list
+ mparameters.add_all msetter.msignature.mparameters
initializers.add(msetter.mproperty)
msetter.mproperty.is_autoinit = true
end
# Is the node tagged lazy?
var is_lazy = false
+ # Is the node tagged optional?
+ var is_optional = false
+
# Has the node a default value?
# Could be through `n_expr` or `n_block`
var has_value = false
self.mlazypropdef = mlazypropdef
end
+ var atoptional = self.get_single_annotation("optional", modelbuilder)
+ if atoptional != null then
+ if not has_value then
+ modelbuilder.error(atoptional, "Error: `optional` attributes need a default value.")
+ end
+ is_optional = true
+ end
+
var atreadonly = self.get_single_annotation("readonly", modelbuilder)
if atreadonly != null then
if not has_value then
var mwritepropdef = self.mwritepropdef
if mwritepropdef != null then
+ var mwritetype = mtype
+ if is_optional then
+ mwritetype = mwritetype.as_nullable
+ end
var name: String
name = n_id2.text
- var mparameter = new MParameter(name, mtype, false)
+ var mparameter = new MParameter(name, mwritetype, false)
var msignature = new MSignature([mparameter], null)
mwritepropdef.msignature = msignature
end
end
return null # forward error
end
- self.error(nexpr, "Error: expected an expression.")
+ var more_message = null
+ var p = nexpr.parent
+ if p != null then more_message = p.bad_expr_message(nexpr)
+ if more_message == null then more_message = "" else more_message = " " + more_message
+ self.error(nexpr, "Error: expected an expression{more_message}.")
return null
end
redef class ANode
private fun accept_post_typing(v: TypeVisitor) do end
+
+ # An additional information message to explain the role of a child expression.
+ #
+ # The point of the method is to allow some kind of double dispatch so the parent
+ # choose how to describe its children.
+ private fun bad_expr_message(child: AExpr): nullable String do return null
end
redef class AAttrPropdef
# The property invoked by the send.
var callsite: nullable CallSite
+ redef fun bad_expr_message(child)
+ do
+ if child == self.n_expr then
+ return "to be the receiver of `{self.property_name}`"
+ end
+ return null
+ end
+
redef fun accept_typing(v)
do
var nrecv = self.n_expr
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+class A
+ var i: Int = 99 is optional
+
+ var o: Object = 999 is optional
+end
+
+var a = new A
+a.i.output
+a.o.output
+
+a.i = 1
+a.o = 10
+a.i.output
+a.o.output
+
+a.i = null
+a.o = null
+a.i.output
+a.o.output
+
+a = new A(2)
+a.i.output
+a.o.output
+
+a = new A(3, true)
+a.i.output
+a.o.output
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import core::kernel
+
+redef class Int
+ fun a: Int do return 10*self+self.abs
+end
+
+fun foo(a: Int): Int do
+ a.output
+ return a
+end
+fun bar(a: Int) do a.output
+
+foo 1.a
+foo(1.a)
+foo (1).a
+foo(1).a
+foo((1).a)
+
+'\n'.output
+
+bar 1.a
+bar(1.a)
+#alt1#bar (1).a
+#alt1#bar(1).a
+bar((1).a)
--- /dev/null
+99
+999
+1
+10
+99
+999
+2
+999
+3
+true
-alt/base_meth_call_alt1.nit:36,1--6: Error: expected an expression.
+alt/base_meth_call_alt1.nit:36,1--6: Error: expected an expression to be the receiver of `output`.
--- /dev/null
+11
+11
+1
+1
+11
+
+11
+11
+11
--- /dev/null
+alt/error_arg_alt1.nit:37,1--7: Error: expected an expression to be the receiver of `a`.
+alt/error_arg_alt1.nit:38,1--6: Error: expected an expression to be the receiver of `a`.
-RopeBuffer = 0
Calls to length, by type:
- FlatString = 23 (cache misses 5, 21.73%)
+ FlatString = 18 (cache misses 5, 27.77%)
Indexed accesses, by type:
- FlatString = 13
+ FlatString = 8
Calls to bytelen for each type:
FlatString = 61
Calls to position for each type:
- FlatString = 27
+ FlatString = 17
Calls to bytepos for each type:
- FlatString = 14
-Calls to first_byte on FlatString 216
+ FlatString = 9
+Calls to first_byte on FlatString 191
Calls to last_byte on FlatString 19
FlatStrings allocated with length 78 (86.813%)
Length of travel for index distribution:
-* null = 16 => occurences 80.0%, cumulative 80.0%
-* 1 = 14 => occurences 35.0%, cumulative 75.0%
+* null = 11 => occurences 73.333%, cumulative 73.333%
+* 1 = 8 => occurences 27.586%, cumulative 65.517%
Byte length of the FlatStrings created:
* null = 6 => occurences 4.444%, cumulative 4.444%
-* 1 = 21 => occurences 14.094%, cumulative 18.121%
-* 2 = 33 => occurences 20.245%, cumulative 36.81%
+* 1 = 24 => occurences 16.107%, cumulative 20.134%
+* 2 = 30 => occurences 18.405%, cumulative 36.81%
* 3 = 29 => occurences 16.292%, cumulative 50.0%
-* 4 = 9 => occurences 4.663%, cumulative 50.777%
-* 5 = 20 => occurences 9.615%, cumulative 56.731%
-* 6 = 21 => occurences 9.417%, cumulative 62.332%
+* 4 = 5 => occurences 2.591%, cumulative 48.705%
+* 5 = 20 => occurences 9.615%, cumulative 54.808%
+* 6 = 25 => occurences 11.211%, cumulative 62.332%
* 9 = 1 => occurences 0.42%, cumulative 58.824%
* 10 = 9 => occurences 3.557%, cumulative 58.893%
* 11 = 2 => occurences 0.746%, cumulative 56.343%
* 12 = 1 => occurences 0.355%, cumulative 53.901%
* 13 = 1 => occurences 0.339%, cumulative 51.864%
* 14 = 1 => occurences 0.325%, cumulative 50.0%
-* 15 = 5 => occurences 1.558%, cumulative 49.533%
-* 16 = 7 => occurences 2.083%, cumulative 49.405%
+* 15 = 7 => occurences 2.181%, cumulative 50.156%
+* 16 = 5 => occurences 1.488%, cumulative 49.405%
* 17 = 1 => occurences 0.285%, cumulative 47.578%
* 25 = 2 => occurences 0.549%, cumulative 46.429%
* 26 = 1 => occurences 0.265%, cumulative 44.974%
* 40 = 1 => occurences 0.207%, cumulative 37.19%
* 43 = 1 => occurences 0.201%, cumulative 36.419%
* 46 = 1 => occurences 0.196%, cumulative 35.686%
-* 48 = 1 => occurences 0.191%, cumulative 34.99%
-* 51 = 21 => occurences 3.918%, cumulative 38.06%
+* 51 = 20 => occurences 3.824%, cumulative 38.623%
+* 55 = 1 => occurences 0.186%, cumulative 37.732%
-RopeBuffer = 0
Calls to length, by type:
- FlatString = 23 (cache misses 5, 21.73%)
+ FlatString = 18 (cache misses 5, 27.77%)
Indexed accesses, by type:
- FlatString = 13
+ FlatString = 8
Calls to bytelen for each type:
FlatString = 61
Calls to position for each type:
- FlatString = 27
+ FlatString = 17
Calls to bytepos for each type:
- FlatString = 14
-Calls to first_byte on FlatString 216
+ FlatString = 9
+Calls to first_byte on FlatString 191
Calls to last_byte on FlatString 19
FlatStrings allocated with length 78 (86.813%)
Length of travel for index distribution:
-* 0 = 16 => occurences 80.0%, cumulative 80.0%
-* 1 = 14 => occurences 35.0%, cumulative 75.0%
+* 0 = 11 => occurences 73.333%, cumulative 73.333%
+* 1 = 8 => occurences 27.586%, cumulative 65.517%
Byte length of the FlatStrings created:
* 0 = 6 => occurences 4.478%, cumulative 4.478%
-* 1 = 21 => occurences 14.189%, cumulative 18.243%
-* 2 = 33 => occurences 20.37%, cumulative 37.037%
+* 1 = 24 => occurences 16.216%, cumulative 20.27%
+* 2 = 30 => occurences 18.519%, cumulative 37.037%
* 3 = 29 => occurences 16.384%, cumulative 50.282%
-* 4 = 7 => occurences 3.646%, cumulative 50.0%
-* 5 = 20 => occurences 9.662%, cumulative 56.039%
-* 6 = 21 => occurences 9.459%, cumulative 61.712%
-* 9 = 1 => occurences 0.422%, cumulative 58.228%
-* 10 = 9 => occurences 3.571%, cumulative 58.333%
-* 11 = 2 => occurences 0.749%, cumulative 55.805%
-* 12 = 1 => occurences 0.356%, cumulative 53.381%
-* 13 = 1 => occurences 0.34%, cumulative 51.361%
-* 14 = 1 => occurences 0.326%, cumulative 49.511%
-* 15 = 5 => occurences 1.563%, cumulative 49.063%
-* 16 = 7 => occurences 2.09%, cumulative 48.955%
-* 17 = 1 => occurences 0.286%, cumulative 47.143%
-* 25 = 2 => occurences 0.551%, cumulative 46.006%
-* 26 = 1 => occurences 0.265%, cumulative 44.562%
-* 31 = 2 => occurences 0.513%, cumulative 43.59%
-* 32 = 1 => occurences 0.248%, cumulative 42.327%
-* 33 = 1 => occurences 0.24%, cumulative 41.247%
-* 34 = 2 => occurences 0.465%, cumulative 40.465%
-* 35 = 1 => occurences 0.225%, cumulative 39.414%
-* 37 = 1 => occurences 0.219%, cumulative 38.512%
-* 39 = 1 => occurences 0.213%, cumulative 37.66%
-* 40 = 1 => occurences 0.207%, cumulative 36.853%
-* 43 = 1 => occurences 0.202%, cumulative 36.089%
-* 46 = 1 => occurences 0.196%, cumulative 35.363%
-* 48 = 3 => occurences 0.575%, cumulative 35.057%
+* 4 = 3 => occurences 1.563%, cumulative 47.917%
+* 5 = 20 => occurences 9.662%, cumulative 54.106%
+* 6 = 26 => occurences 11.712%, cumulative 62.162%
+* 9 = 1 => occurences 0.422%, cumulative 58.65%
+* 10 = 9 => occurences 3.571%, cumulative 58.73%
+* 11 = 2 => occurences 0.749%, cumulative 56.18%
+* 12 = 1 => occurences 0.356%, cumulative 53.737%
+* 13 = 1 => occurences 0.34%, cumulative 51.701%
+* 14 = 1 => occurences 0.326%, cumulative 49.837%
+* 15 = 7 => occurences 2.188%, cumulative 50.0%
+* 16 = 5 => occurences 1.493%, cumulative 49.254%
+* 17 = 1 => occurences 0.286%, cumulative 47.429%
+* 25 = 2 => occurences 0.551%, cumulative 46.281%
+* 26 = 1 => occurences 0.265%, cumulative 44.828%
+* 31 = 2 => occurences 0.513%, cumulative 43.846%
+* 32 = 1 => occurences 0.248%, cumulative 42.574%
+* 33 = 1 => occurences 0.24%, cumulative 41.487%
+* 34 = 2 => occurences 0.465%, cumulative 40.698%
+* 35 = 1 => occurences 0.225%, cumulative 39.64%
+* 37 = 1 => occurences 0.219%, cumulative 38.731%
+* 39 = 1 => occurences 0.213%, cumulative 37.872%
+* 40 = 1 => occurences 0.207%, cumulative 37.06%
+* 43 = 1 => occurences 0.202%, cumulative 36.29%
+* 46 = 1 => occurences 0.196%, cumulative 35.56%
+* 51 = 14 => occurences 2.682%, cumulative 37.356%
+* 52 = 5 => occurences 0.931%, cumulative 37.244%