# Additional program directories (contrib and examples) that are buildable
PROGS=$(dir $(wildcard examples/*/Makefile contrib/*/Makefile))
-all: tools
+all: tools man
+ @echo ""
+ @echo "Congratulations! Nit was succesfully compiled."
+ @echo "To configure your shell environment, execute the following command:"
+ @echo " source misc/nit_env.sh install"
# Compile all programs in $PROGS
full: all
$ bin/nitc examples/hello_world.nit
$ ./hello_world
-You can put the `bin/` directory in your PATH
+You can source `misc/nit_env.sh` to setup your environment like PATH, MANPATH and bash completion.
+To have your environment automatically configured at login, just source it with `install` as argument.
-Using bash completion with Nit tools:
-
- $ echo source /absolute/path/to/misc/bash_completion/nit >> ~/.bash_completion
- $ source ~/.bash_completion
+ $ . misc/nit_env.sh install
More information: <http://www.nitlanguage.org>
# See the License for the specific language governing permissions and
# limitations under the License.
-# Linex version of the shoot program
+# Linux version of the shoot program
module shoot_linux
import shoot
fun show_dot is abstract
end
-# Node used in Tree implementation
-# nodes are used to store values
-# * `E`: type of value
-class TreeNode[K: Comparable, E]
+# Abstract node structure used in `Tree` implementation
+#
+# Nodes are defined recursively each node (except the root one) pointing to a parent.
+# Nodes can be used to store data with the `TreeNode::value` attribute.
+#
+# Formal parameters:
+# * `K`: key type (a `Comparable` one so nodes can be sorted by their keys)
+# * `E`: value type (to store your data)
+abstract class TreeNode[K: Comparable, E]
+ super Comparable
# TreeNode type
type N: TreeNode[K, E]
# `value` stored in the node
var value: E
- # Direct parent of this node (null if the node is root)
+ # Direct parent of this node (`null` if the node is root)
+ #
+ # See `Tree::root`.
var parent: nullable N = null is writable
+ # Depth in tree (length of the path from `self` to `root`)
+ fun depth: Int do
+ var node = parent
+ var i = 0
+ while node != null do
+ node = node.parent
+ i += 1
+ end
+ return i
+ end
+
redef fun to_s do return "\{{value or else ""}\}"
# Return dot representation of this node
- # Used for debugging by `AbstractTree::show_dot`
+ #
+ # See `Tree::show_dot`.
fun to_dot: String do
var res = new FlatBuffer
res.append "\"{self}\";\n"
if parent != null then res.append "\"{parent.as(not null)}\" -> \"{self}\"[dir=back];\n"
return res.to_s
end
-end
+ redef type OTHER: N
+
+ # Nodes equality is done on `value` equality
+ #
+ # Redefine this method to change the default behavior.
+ redef fun ==(o) do
+ if not o isa N then return false
+ return self.value == o.value
+ end
+
+ # Nodes ordering is based on the `key`
+ redef fun <(o) do return self.key < o.key
+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.
+
+# Source this script inside a bash or sh session to setup:
+#
+# * PATH
+# * MANPATH
+# * bash_completion
+#
+# If `install` is given as an argument, then the script sourcing is automatically inserted in the `.profile`.
+
+# Final function that sets up the shell environment.
+__nit_env() {
+ #echo "Install in $1:"
+
+ local str="$1/bin"
+ echo "$PATH" | grep -q "$str" || export PATH="$str:$PATH"
+ str="$1/share/bin"
+ echo "$MANPATH" | grep -q "$str" || export MANPATH="$str:$MANPATH"
+
+ if [ -n "$BASH" -a -n "$PS1" ]; then
+ . "$1/misc/bash_completion/nit"
+ fi
+
+}
+
+# Fast setup when invoked from .profile (see `install` at the end)
+#
+# Because [d]ash does not support argument to source (`.`),
+# we pass the root dir as a local environment variable.
+if [ -n "$NIT_DIR" ]; then
+ __nit_env "$NIT_DIR"
+ return 2> /dev/null # `return` fails if invoked as is; i.e. not trough source (`.`)
+ exit
+fi
+
+# Guess the nit root directory and return it in `dirname`.
+__nit_env_guess() {
+ dirname=$NIT_DIR
+ [ -f "$dirname/src/nitc.nit" ] && return 0
+
+ dirname=$PWD
+ [ -f "$dirname/src/nitc.nit" ] && return 0
+
+ if [ -n "$BASH_SOURCE" ]; then
+ dirname=`dirname "$BASH_SOURCE"`/..
+ [ -f "$dirname/src/nitc.nit" ] && return 0
+ fi
+
+ dirname=`dirname "$0"`/..
+ [ -f "$dirname/src/nitc.nit" ] && return 0
+
+ echo "Cannot find the Nit root directory. Run the script from the Nit root directory."
+ return 1
+}
+
+# Main method of the script.
+#
+# A function is used so that `return` have a sane effect
+__nit_env_main() {
+ local install
+ local dirname
+
+ # Install required?
+ if [ "$1" = "install" ]; then
+ install=true
+ shift
+ fi
+
+ # Get the root directory
+ case "$#" in
+ 1)
+ # Get it from the argument
+ dirname=$1
+ if [ ! -f "$dirname/src/nitc.nit" ]; then
+ if [ -d "$dirname/" ]; then
+ echo "$dirname: not a Nit root directory"
+ else
+ echo "$dirname: not a directory"
+ fi
+ return 1
+ fi
+ ;;
+ 0)
+ # Guess it
+ __nit_env_guess || return 1
+ ;;
+ *) echo "usage: source nit_env.sh [install] [path/to/nitdir]"
+ return 1
+ ;;
+ esac
+
+ # Get a canonical path
+ local ret=`pwd`
+ cd $dirname > /dev/null
+ local fulldir=`pwd`
+ cd "$ret"
+
+ # Check misuse
+ if [ -n "$BASH" -a "$0" = "$BASH_SOURCE" ]; then
+ echo "nit_env.sh should be sourced not executed as is. E.g. run with 'source ./nit_env.sh'"
+ fi
+
+ # Setup the environment
+ __nit_env "$fulldir"
+
+ # Register in the .profile if required
+ if [ -n "$install" ]; then
+ local ne="$fulldir/misc/nit_env.sh"
+ local str="test -r \"$ne\" && NIT_DIR=\"$fulldir\" . \"$ne\""
+ grep -q "$str" "$HOME/.profile" || echo "$str" >> "$HOME/.profile"
+ fi
+}
+
+__nit_env_main "$@"
fun can_inline(v: VISITOR): Bool
do
if is_abstract then return true
+ if constant_value != null then return true
var modelbuilder = v.compiler.modelbuilder
var node = modelbuilder.mpropdef2node(self)
if node isa APropdef then
end
#print "4.is {sub} a {sup}? <- no more resolution"
- assert sub isa MClassType else print "{sub} <? {sub}" # It is the only remaining type
-
- # A unfixed formal type can only accept itself
- if sup isa MFormalType then
- return false
+ if sub isa MBottomType then
+ return true
end
- if sup isa MNullType then
- # `sup` accepts only null
+ assert sub isa MClassType else print "{sub} <? {sub}" # It is the only remaining type
+
+ # Handle sup-type when the sub-type is class-based (other cases must have be identified before).
+ if sup isa MFormalType or sup isa MNullType or sup isa MBottomType then
+ # These types are not super-types of Class-based types.
return false
end
- assert sup isa MClassType # It is the only remaining type
+ assert sup isa MClassType else print "got {sup} {sub.inspect}" # It is the only remaining type
# Now both are MClassType, we need to dig
# The result is returned exactly as declared in the "type" property (verbatim).
# So it could be another formal type.
#
- # In case of conflict, the method aborts.
+ # In case of conflicts or inconsistencies in the model, the method returns a `MBottomType`.
fun lookup_bound(mmodule: MModule, resolved_receiver: MType): MType do return self
# Resolve the formal type to its simplest equivalent form.
#
# By default, return self.
# See the redefinitions for specific behavior in each kind of type.
+ #
+ # In case of conflicts or inconsistencies in the model, the method returns a `MBottomType`.
fun lookup_fixed(mmodule: MModule, resolved_receiver: MType): MType do return self
# Can the type be resolved?
redef fun lookup_bound(mmodule: MModule, resolved_receiver: MType): MType
do
- return lookup_single_definition(mmodule, resolved_receiver).bound.as(not null)
+ return lookup_single_definition(mmodule, resolved_receiver).bound or else new MBottomType(model)
end
private fun lookup_single_definition(mmodule: MModule, resolved_receiver: MType): MVirtualTypeDef
assert resolved_receiver isa MClassType # It is the only remaining type
var prop = lookup_single_definition(mmodule, resolved_receiver)
- var res = prop.bound.as(not null)
+ var res = prop.bound
+ if res == null then return new MBottomType(model)
# Recursively lookup the fixed result
res = res.lookup_fixed(mmodule, resolved_receiver)
if not check_virtual_types_circularity(npropdef, mpropdef.mproperty, mclassdef.bound_mtype, mclassdef.mmodule) then
# Invalidate the bound
mpropdef.is_broken = true
- mpropdef.bound = mclassdef.mmodule.model.null_type
+ mpropdef.bound = new MBottomType(mclassdef.mmodule.model)
end
end
for npropdef in nclassdef2.n_propdefs do
# nothing, always visible
else if mtype isa MNullType then
# nothing to do.
+ else if mtype isa MBottomType then
+ # nothing to do.
else
node.debug "Unexpected type {mtype}"
abort
var vt = t.mproperty
# Because `vt` is possibly unchecked, we have to do the bound-lookup manually
var defs = vt.lookup_definitions(mmodule, recv)
- # TODO something to manage correctly bound conflicts
- assert not defs.is_empty
+ if defs.is_empty then return false
nexts = new Array[MType]
for d in defs do
var next = defs.first.bound
modelbuilder.warning(n_id, "bad-type-name", "Warning: lowercase in the virtual type `{name}`.")
break
end
- if not self.check_redef_keyword(modelbuilder, mclassdef, self.n_kwredef, false, mprop) then return
else
- if not self.check_redef_keyword(modelbuilder, mclassdef, self.n_kwredef, true, mprop) then return
assert mprop isa MVirtualTypeProp
check_redef_property_visibility(modelbuilder, self.n_visibility, mprop)
end
- mclassdef.mprop2npropdef[mprop] = self
var mpropdef = new MVirtualTypeDef(mclassdef, mprop, self.location)
self.mpropdef = mpropdef
- modelbuilder.mpropdef2npropdef[mpropdef] = self
if mpropdef.is_intro then
modelbuilder.toolcontext.info("{mpropdef} introduces new type {mprop.full_name}", 4)
else
modelbuilder.toolcontext.info("{mpropdef} redefines type {mprop.full_name}", 4)
end
+ if not self.check_redef_keyword(modelbuilder, mclassdef, self.n_kwredef, not mpropdef.is_intro, mprop) then
+ mpropdef.is_broken =true
+ end
+ mclassdef.mprop2npropdef[mprop] = self
+ modelbuilder.mpropdef2npropdef[mpropdef] = self
set_doc(mpropdef, modelbuilder)
var atfixed = get_single_annotation("fixed", modelbuilder)
# Check redefinitions
for p in mpropdef.mproperty.lookup_super_definitions(mmodule, anchor) do
var supbound = p.bound
- if supbound == null then break # broken super bound, skip error
+ if supbound == null or supbound isa MBottomType or p.is_broken then break # broken super bound, skip error
if p.is_fixed then
modelbuilder.error(self, "Redef Error: virtual type `{mpropdef.mproperty}` is fixed in super-class `{p.mclassdef.mclass}`.")
break
--- /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
+
+class G[E: Object]
+end
+
+class A
+ redef type N1: A
+ redef type N2: FAIL
+ fun foo1: G[N1] do return new G[N1]
+ fun foo2: G[N2] do return new G[N2]
+end
+
+var a = new A
+a.foo1
+a.foo2
base_simple_import.nit base_simple.nit --dir out/ ; out/base_simple ; out/base_simple_import
test_define.nit -D text=hello -D num=42 -D flag --dir out/ ; out/test_define
--log --log-dir $WRITE test_prog -o out/test_prog.bin
+test_define.nit --semi-global -D text=hello -D num=42 -D flag --dir out/ ; out/test_define
--- /dev/null
+error_redef_vt.nit:21,2--17: Error: no property `A::N1` is inherited. Remove the `redef` keyword to define a new property.
+error_redef_vt.nit:22,17--20: Error: class `FAIL` not found in module `error_redef_vt`.
+error_redef_vt.nit:22,2--20: Error: no property `A::N2` is inherited. Remove the `redef` keyword to define a new property.
alt/error_virtual_type2_alt1.nit:22,2--24,14: Error: circularity of virtual type definition: GT -> T <-> T.
alt/error_virtual_type2_alt1.nit:25,2--10: Error: circularity of virtual type definition: T <-> T.
-alt/error_virtual_type2_alt1.nit:38,23: Redef Error: expected `Comparable` for return type; got `T`.
-alt/error_virtual_type2_alt1.nit:40,17--27: Redef Error: expected `null` bound type; got `G[Discrete]`.
-alt/error_virtual_type2_alt1.nit:42,23: Redef Error: expected `Comparable` for return type; got `T`.
alt/error_virtual_type2_alt2.nit:22,2--24,14: Error: circularity of virtual type definition: GT -> T <-> nullable T.
alt/error_virtual_type2_alt2.nit:25,2--26,19: Error: circularity of virtual type definition: T <-> nullable T.
-alt/error_virtual_type2_alt2.nit:38,23: Redef Error: expected `Comparable` for return type; got `T`.
-alt/error_virtual_type2_alt2.nit:40,17--27: Redef Error: expected `null` bound type; got `G[Discrete]`.
-alt/error_virtual_type2_alt2.nit:42,23: Redef Error: expected `Comparable` for return type; got `T`.
alt/error_virtual_type2_alt3.nit:22,2--24,14: Error: circularity of virtual type definition: GT -> G[T] <-> T.
alt/error_virtual_type2_alt3.nit:25,2--27,13: Error: circularity of virtual type definition: T <-> G[T].
-alt/error_virtual_type2_alt3.nit:38,23: Redef Error: expected `Comparable` for return type; got `T`.
-alt/error_virtual_type2_alt3.nit:40,17--27: Redef Error: expected `null` bound type; got `G[Discrete]`.
-alt/error_virtual_type2_alt3.nit:42,23: Redef Error: expected `Comparable` for return type; got `T`.
alt/error_virtual_type2_alt4.nit:29,10--13: Error: class `FAIL` not found in module `error_virtual_type2_alt4`.
-alt/error_virtual_type2_alt4.nit:38,23: Redef Error: expected `Comparable` for return type; got `T`.
-alt/error_virtual_type2_alt4.nit:40,17--27: Redef Error: expected `null` bound type; got `G[Discrete]`.
-alt/error_virtual_type2_alt4.nit:42,23: Redef Error: expected `Comparable` for return type; got `T`.
alt/error_virtual_type2_alt5.nit:22,2--24,14: Error: circularity of virtual type definition: GT -> T <-> U.
alt/error_virtual_type2_alt5.nit:25,2--30,10: Error: circularity of virtual type definition: T <-> U.
-alt/error_virtual_type2_alt5.nit:38,23: Redef Error: expected `Comparable` for return type; got `T`.
-alt/error_virtual_type2_alt5.nit:40,17--27: Redef Error: expected `null` bound type; got `G[Discrete]`.
-alt/error_virtual_type2_alt5.nit:42,23: Redef Error: expected `Comparable` for return type; got `T`.
alt/error_virtual_type2_alt6.nit:40,17--27: Redef Error: expected `G[T]` bound type; got `G[Discrete]`.
+alt/error_virtual_type2_alt6.nit:41,17--23: Redef Error: expected `G[T]` bound type; got `G[Bool]`.
alt/error_virtual_type2_alt6.nit:41,2--23: Error: a property `GT` is already defined in class `B` at line 39.
-alt/error_virtual_type_alt3.nit:25,12: Type Error: expected `Object`, got `T`.
alt/error_virtual_type_alt3.nit:22,2--25,13: Error: circularity of virtual type definition: T <-> G[T].
--- /dev/null
+hello
+42
+true