src/*.dat
src/*.gnu
src/*.bin
-src/nitg_0
+src/nitc_0
c_src/*.o
c_src/*.cksum
benchmarks/ Script to bench the compilers
bin/ The Nit tools
bin/nitc The Nit compiler
- bin/nitg The new Nit compiler
bin/nit The Nit interpreter
bin/nitdoc The Nit autodoc
c_src/ C code of nitc (needed to bootstrap)
*.png
*.xml
index.html
-nitg
+nitc
local title=$1
shift
if test -n "$fast"; then
- run_command "$@" ../src/nitg.nit -o "nitg.$title.bin"
- bench_command "nitg-g" "nitg --global ../src/test_parser.nit" "./nitg.$title.bin" -v --global --no-cc ../src/test_parser.nit
+ run_command "$@" ../src/nitc.nit -o "nitc.$title.bin"
+ bench_command "nitc-g" "nitc --global ../src/test_parser.nit" "./nitc.$title.bin" -v --global --no-cc ../src/test_parser.nit
run_command "$@" ../src/nit.nit -o "nit.$title.bin"
bench_command "nit" "nit ../src/test_parser.nit ../src/location.nit" "./nit.$title.bin" -v ../src/test_parser.nit -- -n ../src/location.nit
run_command "$@" ../examples/shoot/src/shoot_logic.nit -o "shoot.$title.bin"
run_command "$@" ../tests/bench_bintree_gen.nit -o "bintrees.$title.bin"
bench_command "bintrees" "bench_bintree_gen 16" "./bintrees.$title.bin" 16
else
- run_command "$@" ../src/nitg.nit -o "nitg.$title.bin"
- bench_command "nitg-g" "nitg --global --no-cc ../src/nitls.nit" "./nitg.$title.bin" -v --global --no-cc ../src/nitls.nit
- bench_command "nitg-s" "nitg --separate ../src/nitg.nit" "./nitg.$title.bin" -v --no-cc --separate ../src/nitg.nit
+ run_command "$@" ../src/nitc.nit -o "nitc.$title.bin"
+ bench_command "nitc-g" "nitc --global --no-cc ../src/nitls.nit" "./nitc.$title.bin" -v --global --no-cc ../src/nitls.nit
+ bench_command "nitc-s" "nitc --separate ../src/nitc.nit" "./nitc.$title.bin" -v --no-cc --separate ../src/nitc.nit
run_command "$@" ../src/nit.nit -o "nit.$title.bin"
bench_command "nit" "nit ../src/test_parser.nit ../src/nitls.nit" "./nit.$title.bin" -v ../src/test_parser.nit -- -n ../src/nitls.nit
run_command "$@" ../src/nitdoc.nit -o "nitdoc.$title.bin"
## COMPILE ENGINES
-# get the bootstrapped nitg
-cp ../bin/nitg .
+# get the bootstrapped nitc
+cp ../bin/nitc .
## EFFECTIVE BENCHS ##
{
name="$FUNCNAME"
skip_test "$name" && return
- prepare_res "$name-nitg.dat" "nitg-g" "Various steps of nitg --global"
- bench_command "parse" "" ./nitg --global --only-parse ../src/nitg.nit
- bench_command "metamodel" "" ./nitg --global --only-metamodel ../src/nitg.nit
- bench_command "generate c" "" ./nitg --global --no-cc ../src/nitg.nit
- bench_command "full" "" ./nitg --global ../src/nitg.nit -o "nitg_nitg.bin"
-
- prepare_res "$name-nitg-s.dat" "nitg-s" "Various steps of nitg --separate"
- bench_command "parse" "" ./nitg --separate --only-parse ../src/nitg.nit
- bench_command "metamodel" "" ./nitg --separate --only-metamodel ../src/nitg.nit
- bench_command "generate c" "" ./nitg --separate --no-cc ../src/nitg.nit
- bench_command "full" "" ./nitg --separate ../src/nitg.nit -o "nitg_nitg-e.bin"
-
- prepare_res "$name-nitg-e.dat" "nitg-e" "Various steps of nitg --erasure"
- bench_command "parse" "" ./nitg --erasure --only-parse ../src/nitg.nit
- bench_command "metamodel" "" ./nitg --erasure --only-metamodel ../src/nitg.nit
- bench_command "generate c" "" ./nitg --erasure --no-cc ../src/nitg.nit
- bench_command "full" "" ./nitg --erasure ../src/nitg.nit -o "nitg_nitg-e.bin"
+ prepare_res "$name-nitc.dat" "nitc-g" "Various steps of nitc --global"
+ bench_command "parse" "" ./nitc --global --only-parse ../src/nitc.nit
+ bench_command "metamodel" "" ./nitc --global --only-metamodel ../src/nitc.nit
+ bench_command "generate c" "" ./nitc --global --no-cc ../src/nitc.nit
+ bench_command "full" "" ./nitc --global ../src/nitc.nit -o "nitc_nitc.bin"
+
+ prepare_res "$name-nitc-s.dat" "nitc-s" "Various steps of nitc --separate"
+ bench_command "parse" "" ./nitc --separate --only-parse ../src/nitc.nit
+ bench_command "metamodel" "" ./nitc --separate --only-metamodel ../src/nitc.nit
+ bench_command "generate c" "" ./nitc --separate --no-cc ../src/nitc.nit
+ bench_command "full" "" ./nitc --separate ../src/nitc.nit -o "nitc_nitc-e.bin"
+
+ prepare_res "$name-nitc-e.dat" "nitc-e" "Various steps of nitc --erasure"
+ bench_command "parse" "" ./nitc --erasure --only-parse ../src/nitc.nit
+ bench_command "metamodel" "" ./nitc --erasure --only-metamodel ../src/nitc.nit
+ bench_command "generate c" "" ./nitc --erasure --no-cc ../src/nitc.nit
+ bench_command "full" "" ./nitc --erasure ../src/nitc.nit -o "nitc_nitc-e.bin"
plot "$name.gnu"
}
bench_steps
# $#: options to compare
-function bench_nitg-g_options()
+function bench_nitc-g_options()
{
tag=$1
shift
name="$FUNCNAME-$tag"
skip_test "$name" && return
- prepare_res "$name.dat" "no options" "nitg-g without options"
- run_compiler "nitg-g" ./nitg --global
+ prepare_res "$name.dat" "no options" "nitc-g without options"
+ run_compiler "nitc-g" ./nitc --global
if test "$1" = NOALL; then
shift
elif test -n "$2"; then
- prepare_res "$name-all.dat" "all" "nitg-g with all options $@"
- run_compiler "nitg-g-$tag" ./nitg --global $@
+ prepare_res "$name-all.dat" "all" "nitc-g with all options $@"
+ run_compiler "nitc-g-$tag" ./nitc --global $@
fi
for opt in "$@"; do
ot=${opt// /+}
- prepare_res "$name$ot.dat" "$opt" "nitg-g with option $opt"
- run_compiler "nitg-g$ot" ./nitg --global $opt
+ prepare_res "$name$ot.dat" "$opt" "nitc-g with option $opt"
+ run_compiler "nitc-g$ot" ./nitc --global $opt
done
plot "$name.gnu"
}
-bench_nitg-g_options "slower" --hardening --no-shortcut-range
-bench_nitg-g_options "nocheck" --no-check-null --no-check-autocast --no-check-attr-isset --no-check-covariance --no-check-assert
+bench_nitc-g_options "slower" --hardening --no-shortcut-range
+bench_nitc-g_options "nocheck" --no-check-null --no-check-autocast --no-check-attr-isset --no-check-covariance --no-check-assert
-function bench_nitg-s_options()
+function bench_nitc-s_options()
{
tag=$1
shift
name="$FUNCNAME-$tag"
skip_test "$name" && return
- prepare_res "$name.dat" "no options" "nitg-s without options"
- run_compiler "nitg-s" ./nitg --separate
+ prepare_res "$name.dat" "no options" "nitc-s without options"
+ run_compiler "nitc-s" ./nitc --separate
if test "$1" = NOALL; then
shift
elif test -n "$2"; then
- prepare_res "$name-all.dat" "all" "nitg-s with all options $@"
- run_compiler "nitg-s-$tag" ./nitg --separate $@
+ prepare_res "$name-all.dat" "all" "nitc-s with all options $@"
+ run_compiler "nitc-s-$tag" ./nitc --separate $@
fi
for opt in "$@"; do
ot=${opt// /+}
- prepare_res "$name-$ot.dat" "$opt" "nitg-s with option $opt"
- run_compiler "nitg-s$ot" ./nitg --separate $opt
+ prepare_res "$name-$ot.dat" "$opt" "nitc-s with option $opt"
+ run_compiler "nitc-s$ot" ./nitc --separate $opt
done
plot "$name.gnu"
}
-bench_nitg-s_options "slower" --hardening --no-shortcut-equal --no-union-attribute --no-shortcut-range --no-inline-intern "--no-gcc-directive likely --no-gcc-directive noreturn"
-bench_nitg-s_options "nocheck" --no-check-null --no-check-autocast --no-check-attr-isset --no-check-covariance --no-check-assert
-bench_nitg-s_options "faster" --skip-dead-methods --inline-coloring-numbers --inline-some-methods --direct-call-monomorph "--inline-some-methods --direct-call-monomorph" ""
+bench_nitc-s_options "slower" --hardening --no-shortcut-equal --no-union-attribute --no-shortcut-range --no-inline-intern "--no-gcc-directive likely --no-gcc-directive noreturn"
+bench_nitc-s_options "nocheck" --no-check-null --no-check-autocast --no-check-attr-isset --no-check-covariance --no-check-assert
+bench_nitc-s_options "faster" --skip-dead-methods --inline-coloring-numbers --inline-some-methods --direct-call-monomorph "--inline-some-methods --direct-call-monomorph" ""
-function bench_nitg-e_options()
+function bench_nitc-e_options()
{
tag=$1
shift
name="$FUNCNAME-$tag"
skip_test "$name" && return
- prepare_res "$name.dat" "no options" "nitg-e without options"
- run_compiler "nitg-e" ./nitg --erasure
+ prepare_res "$name.dat" "no options" "nitc-e without options"
+ run_compiler "nitc-e" ./nitc --erasure
if test "$1" = NOALL; then
shift
elif test -n "$2"; then
- prepare_res "$name-all.dat" "all" "nitg-e with all options $@"
- run_compiler "nitg-e-$tag" ./nitg --erasure $@
+ prepare_res "$name-all.dat" "all" "nitc-e with all options $@"
+ run_compiler "nitc-e-$tag" ./nitc --erasure $@
fi
for opt in "$@"; do
ot=${opt// /+}
- prepare_res "$name$ot.dat" "$opt" "nitg-e with option $opt"
- run_compiler "nitg-e$ot" ./nitg --erasure $opt
+ prepare_res "$name$ot.dat" "$opt" "nitc-e with option $opt"
+ run_compiler "nitc-e$ot" ./nitc --erasure $opt
done
plot "$name.gnu"
}
-bench_nitg-e_options "slower" --hardening --no-shortcut-equal --no-union-attribute --no-shortcut-range --no-inline-intern
-bench_nitg-e_options "nocheck" --no-check-null --no-check-autocast --no-check-attr-isset --no-check-covariance --no-check-assert --no-check-erasure-cast
-bench_nitg-e_options "faster" --skip-dead-methods --inline-coloring-numbers --inline-some-methods --direct-call-monomorph --rta
+bench_nitc-e_options "slower" --hardening --no-shortcut-equal --no-union-attribute --no-shortcut-range --no-inline-intern
+bench_nitc-e_options "nocheck" --no-check-null --no-check-autocast --no-check-attr-isset --no-check-covariance --no-check-assert --no-check-erasure-cast
+bench_nitc-e_options "faster" --skip-dead-methods --inline-coloring-numbers --inline-some-methods --direct-call-monomorph --rta
function bench_engines()
{
name="$FUNCNAME"
skip_test "$name" && return
- prepare_res "$name-nitg-s.dat" "nitg-s" "nitg with --separate"
- run_compiler "nitg-s" ./nitg --separate
- prepare_res "$name-nitg-e.dat" "nitg-e" "nitg with --erasure"
- run_compiler "nitg-e" ./nitg --erasure
- prepare_res "$name-nitg-sg.dat" "nitg-sg" "nitg with --separate --semi-global"
- run_compiler "nitg-sg" ./nitg --separate --semi-global
- prepare_res "$name-nitg-eg.dat" "nitg-eg" "nitg with --erasure --semi-global"
- run_compiler "nitg-eg" ./nitg --erasure --semi-global
- prepare_res "$name-nitg-egt.dat" "nitg-egt" "nitg with --erasure --semi-global --rta"
- run_compiler "nitg-egt" ./nitg --erasure --semi-global --rta
- prepare_res "$name-nitg-g.dat" "nitg-g" "nitg with --global"
- run_compiler "nitg-g" ./nitg --global
+ prepare_res "$name-nitc-s.dat" "nitc-s" "nitc with --separate"
+ run_compiler "nitc-s" ./nitc --separate
+ prepare_res "$name-nitc-e.dat" "nitc-e" "nitc with --erasure"
+ run_compiler "nitc-e" ./nitc --erasure
+ prepare_res "$name-nitc-sg.dat" "nitc-sg" "nitc with --separate --semi-global"
+ run_compiler "nitc-sg" ./nitc --separate --semi-global
+ prepare_res "$name-nitc-eg.dat" "nitc-eg" "nitc with --erasure --semi-global"
+ run_compiler "nitc-eg" ./nitc --erasure --semi-global
+ prepare_res "$name-nitc-egt.dat" "nitc-egt" "nitc with --erasure --semi-global --rta"
+ run_compiler "nitc-egt" ./nitc --erasure --semi-global --rta
+ prepare_res "$name-nitc-g.dat" "nitc-g" "nitc with --global"
+ run_compiler "nitc-g" ./nitc --global
plot "$name.gnu"
}
bench_engines
-function bench_nitg-e_gc()
+function bench_nitc-e_gc()
{
name="$FUNCNAME"
skip_test "$name" && return
- prepare_res "$name-nitg-e.dat" "nitg-e" "nitg with --erasure"
- run_compiler "nitg-e" ./nitg --erasure
- prepare_res "$name-nitg-e-malloc.dat" "nitg-e-malloc" "nitg with --erasure and malloc"
- NIT_GC_OPTION="malloc" run_compiler "nitg-e-malloc" ./nitg --erasure
- prepare_res "$name-nitg-e-large.dat" "nitg-e-large" "nitg with --erasure and large"
- NIT_GC_OPTION="large" run_compiler "nitg-e-large" ./nitg --erasure
+ prepare_res "$name-nitc-e.dat" "nitc-e" "nitc with --erasure"
+ run_compiler "nitc-e" ./nitc --erasure
+ prepare_res "$name-nitc-e-malloc.dat" "nitc-e-malloc" "nitc with --erasure and malloc"
+ NIT_GC_OPTION="malloc" run_compiler "nitc-e-malloc" ./nitc --erasure
+ prepare_res "$name-nitc-e-large.dat" "nitc-e-large" "nitc with --erasure and large"
+ NIT_GC_OPTION="large" run_compiler "nitc-e-large" ./nitc --erasure
plot "$name.gnu"
}
-bench_nitg-e_gc
+bench_nitc-e_gc
-function bench_cc_nitg-e()
+function bench_cc_nitc-e()
{
name="$FUNCNAME"
skip_test "$name" && return
for o in "gcc0:CC=\"ccache gcc\" CFLAGS=-O0" "cl0:CC=\"ccache clang\" CFLAGS=-O0" "gccs:CC=\"ccache gcc\" CFLAGS=-Os" "cls:CC=\"ccache clang\" CFLAGS=-Os" "gcc2:CC=\"ccache gcc\" CFLAGS=-O2" "cl2:CC=\"ccache clang\" CFLAGS=-O2" "gcc3:CC=\"ccache gcc\" CFLAGS=-O3" "cl3:CC=\"ccache clang\" CFLAGS=-O3"; do
f=`echo "$o" | cut -f1 -d:`
o=`echo "$o" | cut -f2 -d:`
- prepare_res "$name-nitg-e-$f.dat" "nitg-e-$f" "nitg with --erasure --make-flags $o"
- run_compiler "nitg-e-$f" ./nitg --erasure --make-flags "$o"
+ prepare_res "$name-nitc-e-$f.dat" "nitc-e-$f" "nitc with --erasure --make-flags $o"
+ run_compiler "nitc-e-$f" ./nitc --erasure --make-flags "$o"
done
plot "$name.gnu"
}
-bench_cc_nitg-e
+bench_cc_nitc-e
function bench_policy()
{
name="$FUNCNAME"
skip_test "$name" && return
- prepare_res "$name-nitg-s.dat" "nitg-s" "nitg with --separate"
- run_compiler "nitg-s" ./nitg --separate
- prepare_res "$name-nitg-e.dat" "nitg-e" "nitg with --erasure"
- run_compiler "nitg-e" ./nitg --erasure
- prepare_res "$name-nitg-su.dat" "nitg-su" "nitg with --separate --no-check-covariance"
- run_compiler "nitg-su" ./nitg --separate --no-check-covariance
- prepare_res "$name-nitg-eu.dat" "nitg-eu" "nitg with --erasure --no-check-covariance --no-check-erasure-cast"
- run_compiler "nitg-eu" ./nitg --erasure --no-check-covariance --no-check-erasure-cast
+ prepare_res "$name-nitc-s.dat" "nitc-s" "nitc with --separate"
+ run_compiler "nitc-s" ./nitc --separate
+ prepare_res "$name-nitc-e.dat" "nitc-e" "nitc with --erasure"
+ run_compiler "nitc-e" ./nitc --erasure
+ prepare_res "$name-nitc-su.dat" "nitc-su" "nitc with --separate --no-check-covariance"
+ run_compiler "nitc-su" ./nitc --separate --no-check-covariance
+ prepare_res "$name-nitc-eu.dat" "nitc-eu" "nitc with --erasure --no-check-covariance --no-check-erasure-cast"
+ run_compiler "nitc-eu" ./nitc --erasure --no-check-covariance --no-check-erasure-cast
plot "$name.gnu"
}
bench_policy
name="$FUNCNAME"
skip_test "$name" && return
prepare_res "$name-nitc.dat" "nitc" "nitc no options"
- run_compiler "nitc" ./nitg --separate
+ run_compiler "nitc" ./nitc --separate
prepare_res "$name-nitc-ni.dat" "nitc-ni" "nitc --no-check-attr-isset"
- run_compiler "nitc" ./nitg --separate --no-check-attr-isset
+ run_compiler "nitc" ./nitc --separate --no-check-attr-isset
prepare_res "$name-nitc-nu.dat" "nitc-nu" "nitc --no-union-attribute"
- run_compiler "nitc" ./nitg --separate --no-union-attribute
+ run_compiler "nitc" ./nitc --separate --no-union-attribute
prepare_res "$name-nitc-nu-ni.dat" "nitc-nu-ni" "nitc --no-union-attribute --no-check-attr-isset"
- run_compiler "nitc" ./nitg --separate --no-union-attribute --no-check-attr-isset
+ run_compiler "nitc" ./nitc --separate --no-union-attribute --no-check-attr-isset
plot "$name.gnu"
}
bench_nullables
{
name="$FUNCNAME"
skip_test "$name" && return
- prepare_res "$name-nitg-g.dat" "nitg-g" "nitg --global"
- for i in ../examples/hello_world.nit ../src/test_parser.nit ../src/nitg.nit; do
- bench_command `basename "$i" .nit` "" ./nitg --global "$i" --no-cc
+ prepare_res "$name-nitc-g.dat" "nitc-g" "nitc --global"
+ for i in ../examples/hello_world.nit ../src/test_parser.nit ../src/nitc.nit; do
+ bench_command `basename "$i" .nit` "" ./nitc --global "$i" --no-cc
done
- prepare_res "$name-nitg-s.dat" "nitg-s" "nitg --separate"
- for i in ../examples/hello_world.nit ../src/test_parser.nit ../src/nitg.nit; do
- bench_command `basename "$i" .nit` "" ./nitg --separate "$i" --no-cc
+ prepare_res "$name-nitc-s.dat" "nitc-s" "nitc --separate"
+ for i in ../examples/hello_world.nit ../src/test_parser.nit ../src/nitc.nit; do
+ bench_command `basename "$i" .nit` "" ./nitc --separate "$i" --no-cc
done
- prepare_res "$name-nitg-e.dat" "nitg-e" "nitg --erasure"
- for i in ../examples/hello_world.nit ../src/test_parser.nit ../src/nitg.nit; do
- bench_command `basename "$i" .nit` "" ./nitg --erasure "$i" --no-cc
+ prepare_res "$name-nitc-e.dat" "nitc-e" "nitc --erasure"
+ for i in ../examples/hello_world.nit ../src/test_parser.nit ../src/nitc.nit; do
+ bench_command `basename "$i" .nit` "" ./nitc --erasure "$i" --no-cc
done
plot "$name.gnu"
}
cd ../src
test -f ./nitc_3 || ./ncall.sh -O
cd ../benchmarks
-test -f ./nitg || ../src/nitc_3 ../src/nitg.nit -O -v
+test -f ./nitc || ../src/nitc_3 ../src/nitc.nit -O -v
## EFFECTIVE BENCHS ##
s=20
seq="2 4 8"
for b in $seq; do
- run_command ./nitg languages/$name.nit -o $basedir/$name.bin
+ run_command ./nitc languages/$name.nit -o $basedir/$name.bin
run_command $basedir/$name.bin $basedir "${t}_$b" "$b"
done
done
nitdir="${basedir}/nit"
- prepare_res $nitdir/$name-nitg.dat "nitg" "nitg"
+ prepare_res $nitdir/$name-nitc.dat "nitc" "nitc"
for b in $seq; do
- run_command ./nitg $nitdir/${t}_$b.nit --global -o "$nitdir/${t}_$b.nitg.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- bench_command "$b" "" "$nitdir/${t}_$b.nitg.bin" $s
+ run_command ./nitc $nitdir/${t}_$b.nit --global -o "$nitdir/${t}_$b.nitc.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ bench_command "$b" "" "$nitdir/${t}_$b.nitc.bin" $s
done
- prepare_res $nitdir/$name-nitg-s.dat "nitg-s" "nitg-s"
+ prepare_res $nitdir/$name-nitc-s.dat "nitc-s" "nitc-s"
for b in $seq; do
- run_command ./nitg $nitdir/${t}_$b.nit --separate -o "$nitdir/${t}_$b.nitg-s.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- bench_command "$b" "" "$nitdir/${t}_$b.nitg-s.bin" $s
+ run_command ./nitc $nitdir/${t}_$b.nit --separate -o "$nitdir/${t}_$b.nitc-s.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ bench_command "$b" "" "$nitdir/${t}_$b.nitc-s.bin" $s
done
<<XXX
- prepare_res $nitdir/$name-nitg-su.dat "nitg-su" "nitg-su"
+ prepare_res $nitdir/$name-nitc-su.dat "nitc-su" "nitc-su"
for b in $seq; do
- run_command ./nitg $nitdir/${t}_$b.nit --separate --no-check-covariance -o "$nitdir/${t}_$b.nitg-su.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- bench_command "$b" "" "$nitdir/${t}_$b.nitg-su.bin" $s
+ run_command ./nitc $nitdir/${t}_$b.nit --separate --no-check-covariance -o "$nitdir/${t}_$b.nitc-su.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ bench_command "$b" "" "$nitdir/${t}_$b.nitc-su.bin" $s
done
- prepare_res $nitdir/$name-nitg-e.dat "nitg-e" "nitg-e"
+ prepare_res $nitdir/$name-nitc-e.dat "nitc-e" "nitc-e"
for b in $seq; do
- run_command ./nitg $nitdir/${t}_$b.nit --erasure -o "$nitdir/${t}_$b.nitg-e.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- bench_command "$b" "" "$nitdir/${t}_$b.nitg-e.bin" $s
+ run_command ./nitc $nitdir/${t}_$b.nit --erasure -o "$nitdir/${t}_$b.nitc-e.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ bench_command "$b" "" "$nitdir/${t}_$b.nitc-e.bin" $s
done
- prepare_res $nitdir/$name-nitg-eu.dat "nitg-eu" "nitg-eu"
+ prepare_res $nitdir/$name-nitc-eu.dat "nitc-eu" "nitc-eu"
for b in $seq; do
- run_command ./nitg $nitdir/${t}_$b.nit --erasure --no-check-covariance --no-check-erasure-cast -o "$nitdir/${t}_$b.nitg-eu.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- bench_command "$b" "" "$nitdir/${t}_$b.nitg-eu.bin" $s
+ run_command ./nitc $nitdir/${t}_$b.nit --erasure --no-check-covariance --no-check-erasure-cast -o "$nitdir/${t}_$b.nitc-eu.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ bench_command "$b" "" "$nitdir/${t}_$b.nitc-eu.bin" $s
done
XXX
echo "*** Benching Array.to_s performance ***"
fi
- ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res arr_tos_ropes.out arr_tos_ropes ropes
if $verbose; then
bench_command $i ropes$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res arr_tos_buf_ropes.out arr_tos_buf_ropes buffered_ropes
if $verbose; then
bench_command $i buf_ropes$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res arr_tos_flat.out arr_tos_flat flatstring
if $verbose; then
bench_command $i flatstring$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_buffer.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_buffer.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res arr_tos_buf.out arr_tos_buf flatbuffer
if $verbose; then
bench_command $i flatbuffer$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_manual.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_manual.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res arr_tos_man.out arr_tos_man memmove
if $verbose; then
bench_command $i memmove$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_man_buf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_man_buf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res arr_tos_man_buf.out arr_tos_man_buf flatbuf_with_capacity
if $verbose; then
bench_command $i flatbuf_with_capacity$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_rope_buf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_rope_buf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res arr_tos_rope_buf.out arr_tos_rope_buf ropebuf
if $verbose; then
function bench_concat()
{
- ../bin/nitg --global ./strings/chain_concat.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- ../bin/nitg --global ./strings/utf_chain_concat.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/chain_concat.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/utf_chain_concat.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
if $verbose; then
echo "*** Benching concat performance ***"
bench_command $i flatstr_utf8_noindex$i ./utf_chain_concat -m flatstr_utf8_noindex --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/chain_concat.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/chain_concat.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res concat_ropes.out concat_ropes ropes
if $verbose; then
bench_command $i ropes$i ./chain_concat -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/chain_concat.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/chain_concat.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res concat_buf_ropes.out concat_buf_ropes buffered_ropes
if $verbose; then
bench_command $i buf_ropes$i ./chain_concat -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/chain_cct_ropebuf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/chain_cct_ropebuf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res cct_buf_ropes.out cct_buf_ropes cctbuf_ropes
if $verbose; then
echo "*** Benching iteration performance ***"
fi
- ../bin/nitg --global ./strings/iteration_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- ../bin/nitg --global ./strings/utf_iteration_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/iteration_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/utf_iteration_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res iter_flat_iter.out iter_flat_iter flatstring_iter
if $verbose; then
bench_command $i flatstr_index_utf8_noindex$i ./utf_iteration_bench -m flatstr_utf8_noindex --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/iteration_bench.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/iteration_bench.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res iter_ropes_iter.out iter_ropes_iter ropes_iter
if $verbose; then
bench_command $i ropes_index$i ./iteration_bench -m flatstr --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/iteration_bench.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/iteration_bench.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res iter_buf_ropes_iter.out iter_buf_ropes_iter buf_ropes_iter
if $verbose; then
echo "*** Benching substring performance ***"
fi
- ../bin/nitg --global ./strings/substr_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
- ../bin/nitg --global ./strings/utf_substr_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/substr_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/utf_substr_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res substr_flat.out substr_flat flatstring
if $verbose; then
bench_command $i flatstring_utf8_noindex$i ./utf_substr_bench -m flatstr_utf8_noindex --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/substr_bench.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/substr_bench.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res substr_ropes.out substr_ropes ropes
if $verbose; then
bench_command $i ropes$i ./substr_bench -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
done
- ../bin/nitg --global ./strings/substr_bench.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+ ../bin/nitc --global ./strings/substr_bench.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
prepare_res substr_buf_ropes.out substr_buf_ropes buf_ropes
if $verbose; then
+++ /dev/null
-#!/bin/bash
-dir=`dirname "$BASH_SOURCE"`
-exec "$dir/nitg" "$@"
--- /dev/null
+#!/bin/bash
+self=`readlink /proc/$$/fd/255`
+dir=`dirname "$self"`
+exec "$dir/nitc" "$@"
server:
mkdir -p bin/
- ../../bin/nitg --dir bin/ src/benitlux_daily.nit src/benitlux_web.nit
+ ../../bin/nitc --dir bin/ src/benitlux_daily.nit src/benitlux_web.nit
src/benitlux_serial.nit:
../../bin/nitserial -o $@ src/benitlux_web.nit
var content = new Array[String]
# New beers
- var new_beers_name = new Array[String]
for beer in self.new_beers do
content.add "+ {beer.name}: {beer.desc}"
end
Example:
~~~
-nitg ./brainfuck.nit
+nitc ./brainfuck.nit
./brainfuck ./examples/hello.bf
~~~
linux:
mkdir -p bin
- ../../bin/nitg -o bin/friendz src/friendz_linux.nit
+ ../../bin/nitc -o bin/friendz src/friendz_linux.nit
android:
mkdir -p bin
- ../../bin/nitg -o bin/friendz.apk src/friendz_android.nit
+ ../../bin/nitc -o bin/friendz.apk src/friendz_android.nit
doc:
mkdir -p doc
var textx: Int
redef fun draw(ctx) do
- var x = self.x
if self.toggleable then
var w
if self.toggled or not self.enabled then w = 6 else w = 7
var min = 1
var kind = 0
- var tile: nullable Tile = null
-
for x in [0..grid.width[ do
for y in [0..grid.height[ do
var t = grid.grid[x][y]
var l = fs.length
if l == 0 then continue
- tile = t
if n == 0 then
if min == 1 or start.length > l then
start = fs
# Query the Github PR API to perform a merge
module github_merge
-import github_api
+import github::github_curl
import template
redef class Object
var x = curl.get_and_check("https://api.github.com/repos/privat/nit/issues?labels=ok_will_merge")
for y in x.json_as_a do
var number = y.json_as_map["number"].as(Int)
- var pr = curl.getpr(number)
+ curl.getpr(number)
end
else
# With a arg, merge the PR
default:
mkdir -p bin
- ../../bin/nitg -o bin/github_search_for_jni src/github_search_for_jni.nit
+ ../../bin/nitc -o bin/github_search_for_jni src/github_search_for_jni.nit
# Script to scan Github for repositories possibly using JNI.
module github_search_for_jni
-import github_api
+import github::github_curl
# The proprieties introduced by this redef are to be used only on a JSON object
# representing a Github repository.
bins:
mkdir -p bin
- ../../bin/nitg --dir bin src/svg_to_png_and_nit.nit src/svg_to_icons.nit
+ ../../bin/nitc --dir bin src/svg_to_png_and_nit.nit src/svg_to_icons.nit
tests: test-dino test-app
linux:
mkdir -p bin
- ../../../../bin/nitg -o bin/s2pn src/s2pn_linux.nit
+ ../../../../bin/nitc -o bin/s2pn src/s2pn_linux.nit
android:
mkdir -p bin
- ../../../../bin/nitg -o bin/s2pn.apk src/s2pn_android.nit
+ ../../../../bin/nitc -o bin/s2pn.apk src/s2pn_android.nit
images:
mkdir -p assets/images
mkdir -p bin
make -C ../nitcc
../nitcc/src/nitcc ./grammar/javap.sablecc
- ../../bin/nitg ./src/jwrapper.nit -o ./bin/jwrapper
+ ../../bin/nitc ./src/jwrapper.nit -o ./bin/jwrapper
mv *.nit ./src/
mkdir -p gen
mv javap* ./gen/
var jarray_id = "java_array"
var loop_ = create_loop(java_type, nit_type, true, jarray_id, narray_id)
var imports = create_imports(nit_type, true)
- var jtype = java_type.to_s
var jinstanciation = create_array_instance(java_type, nit_type, jarray_id)
var return_str = ""
# See the License for the specific language governing permissions and
# limitations under the License.
-NITG=../../bin/nitg
+NITG=../../bin/nitc
NITG_FLAGS=--dir bin
NEO4J_DIR=/var/lib/neo4j
OLD_PWD=${PWD}
## Installation
-Ensure that you have a working version of `nitg` in `../../bin` then run `make`
+Ensure that you have a working version of `nitc` in `../../bin` then run `make`
in the present directory. The executable will be then generated at
`bin/neo_doxygen`.
To compile and run the tester:
- nitg file_test_parser.nit
+ nitc file_test_parser.nit
./file_test_parser an_input_file_to_parse
## Examples and regression tests
-NITC=../../../bin/nitg
+NITC=../../../bin/nitc
all: nitcc calc minilang
all:
mkdir -p bin/
- ../../bin/nitg src/nitester.nit -o bin/nitester
+ ../../bin/nitc src/nitester.nit -o bin/nitester
# Controller rank is always 0
var controller_rank: Rank = 0.rank
+ # Rank on this processor
+ fun rank: Rank is abstract
+
# Where to store data for transfer between nodes
#
# Require: `buffer.length % 4 == 0`
# Tag of a new task packet of size `tasks_per_packet`
var task_tag: Tag = 0.tag
- # Tag to return a set of `Result` throught `buffer`
+ # Tag to return a set of `Result` thought `buffer`
var result_tag: Tag = 1.tag
# Tag to notify `Worker` when to quit
# Run the main logic of this node
fun run is abstract
- # Engines targetted by this execution
+ # Hash or name of the branch to test
+ var branch_hash: String is noinit
+
+ # Engines targeted by this execution
var engines: Array[String] is noinit
# All known engines, used to detect errors in `engines`
fun read_cli_options
do
var opt_ctx = new OptionContext
+ var opt_hash = new OptionString(
+ "Branch to test",
+ "--hash", "-h")
+ opt_hash.mandatory = true
var opt_engines = new OptionString(
"Engines to test, separated with commas ({all_engines.join(", ")} or all)",
"--engine", "-e")
"Clean up all nitester files (and do not run tests)",
"--cleanup", "-C")
- opt_ctx.add_option(opt_engines, opt_help, opt_verbose, opt_cleanup)
+ opt_ctx.add_option(opt_hash, opt_engines, opt_help, opt_verbose, opt_cleanup)
opt_ctx.parse args
# --help?
if rest.is_empty then opt_ctx.usage_error "This tool needs at least one test_program.nit"
test_programs = rest
+ # hash
+ branch_hash = opt_hash.value.as(not null)
+
# gather and check engines
var engines_str = opt_engines.value
var engines
# All tasks to be performed
var tasks = new Array[Task]
- # Gather and registar all tasks
+ # Gather and register all tasks
fun create_tasks
do
+ # At this point we are in our local nit
+ var skip_path = "tests/turing.skip"
+ var skip
+ if skip_path.file_exists then
+ var skip_file = new IFStream.open(skip_path)
+ skip = skip_file.read_lines
+ skip_file.close
+ else
+ skip = new Array[String]
+ end
+
for prog in test_programs do for engine in engines do
+
+ # Is is blacklisted?
+ for s in skip do if not s.is_empty and prog.has(s) then
+ if verbose > 0 and rank == 0 then print "Skipping test '{prog}' because of '{s}' in turing.skip"
+ continue label
+ end
+
tasks.add new Task(engine, prog)
- end
+ end label
end
end
class Controller
super Processor
+ redef fun rank do return controller_rank
+
# Id as `Int` of the next task to distribute
var next_task_id = 0
super Processor
# The `Rank` of `self`
- var rank: Rank
+ redef var rank: Rank
# Compilation directory
var comp_dir = "/dev/shm/nit_compile{rank}" is lazy
- # Output file directory
- var out_dir = "/dev/shm/nit_out{rank}" is lazy
-
# Directory to store the xml files produced for Jenkins
var xml_dir = "~/jenkins_xml/"
var tests_sh_out = "/dev/shm/nit_local_out{rank}" is lazy
# Source Nit repository, must be already updated and `make` before execution
- var nit_source_dir = "~/nit"
+ var local_nit = "/dev/shm/nit{rank}" is lazy
+
+ # Remote Nit repository (actually the local source)
+ var remote_nit = "~/nit/"
# Compiled `Regex` to detect the argument of an execution
var re_arg: Regex = "arg [0-9]+".to_re
fun setup
do
if verbose > 0 then sys.system "hostname"
+
+ if local_nit.file_exists then local_nit.rmdir
+
+ exec_and_check "git clone {remote_nit} {local_nit}"
+ local_nit.chdir
+ exec_and_check "git config remote.origin.fetch +refs/remotes/origin/pr/*:refs/remotes/origin/pr/*"
+ exec_and_check "git fetch origin --quiet"
+ exec_and_check "git checkout {branch_hash}"
+ exec_and_check "cp {remote_nit}/bin/nitg bin/"
+ exec_and_check "src/git-gen-version.sh"
+ exec_and_check "bin/nitg --dir bin/ src/nit.nit src/nitvm.nit"
+ end
+
+ private fun exec_and_check(cmd: String)
+ do
+ if verbose > 0 then
+ print "+ {cmd}"
+ var res = sys.system(cmd)
+ assert res == 0 else print "Command '{cmd}' failed."
+ end
end
# Clean up the testing environment
fun cleanup
do
if comp_dir.file_exists then comp_dir.rmdir
- if out_dir.file_exists then out_dir.rmdir
if tests_sh_out.file_exists then tests_sh_out.file_delete
+ if local_nit.file_exists then local_nit.file_delete
end
# Single C `int` to hold the next task id received from the `Controller`
if task_id >= tasks.length then break
var task = tasks[task_id]
+ "tests".chdir
+
# Command line to execute test
- var cmd = "XMLDIR={xml_dir} ERRLIST={out_dir}/errlist TMPDIR={out_dir} " +
+ var cmd = "XMLDIR={xml_dir} " +
"CCACHE_DIR={ccache_dir} CCACHE_TEMPDIR={ccache_dir} CCACHE_BASEDIR={comp_dir} " +
- "./tests.sh --compdir {comp_dir} --outdir {out_dir} " +
- " --node --engine {task.engine} {task.test_program} > {tests_sh_out}"
+ "./tests.sh --node --engine {task.engine} {task.test_program} > {tests_sh_out}"
# Execute test
sys.system cmd
while not pipe.eof do
var file = pipe.read_line
if file == "" then break # last line
- file = file.substring(0, file.length - 1) # strip last oef
var name = file.basename(".md")
if name == "header" or name == "footer" or name == "menu" then continue
files.add file
ACE_BUILDS ?= ../../../ace-builds/
default:
- ../../bin/nitg --semi-global sources/nit/pnacl_nit.nit -I ../../src/
+ ../../bin/nitc --semi-global sources/nit/pnacl_nit.nit -I ../../src/
cp pnacl_nit/pnacl_nit.pexe www/pnacl/ -f
rm -rf pnacl_nit/
rm -rf .nit_compile
all:
mkdir -p bin/
- ../../bin/nitg --dir bin/ src/opportunity_web.nit
+ ../../bin/nitc --dir bin/ src/opportunity_web.nit
redef fun answer(request, uri) do
print "Received REST request from {uri}"
- var get = request.get_args
var req = uri.split("/")
if req.has("people") then
return (new OpportunityPeopleREST).answer(request, uri)
bin/pep8analysis:
mkdir -p bin
- ../../bin/nitg -o bin/pep8analysis src/pep8analysis.nit
+ ../../bin/nitc -o bin/pep8analysis src/pep8analysis.nit
doc/index.html:
../../bin/nitdoc src/pep8analysis.nit
bin/pep8analysis --cfg-long tests/privat/*.pep tests/micro/*.pep tests/terrasa/*.pep
www/pep8analysis.js:
- ../../bin/nitg -o www/pep8analysis.js --semi-global src/pep8analysis_web.nit
+ ../../bin/nitc -o www/pep8analysis.js --semi-global src/pep8analysis_web.nit
mkdir -p www/samples
cp tests/micro/*.pep tests/privat/02-fibo.pep tests/privat/06-calc-non-pur.pep www/samples
var str = "" is writable
- init do end
redef fun visit(n) do n.accept_ast_printer(self)
end
class AnalysisManager
super Noter
var opts = new OptionContext
-
- init do end
end
abstract class Noter
class ReachingDefsAnalysis
super FineFlowAnalysis[ReachingDefsMap]
- init do end
redef fun is_forward do return true
redef fun visit( node )
end
end
end
-
- init do end
end
# Each reduca action has its own class, this one is the root of the hierarchy.
build:
mkdir -p bin/
- ../../bin/nitg -o bin/sort_downloads src/sort_downloads.nit
+ ../../bin/nitc -o bin/sort_downloads src/sort_downloads.nit
install:
install bin/sort_downloads /usr/local/bin/
all:
mkdir -p bin/
- ../../bin/nitg --dir bin src/tnitter.nit
+ ../../bin/nitc --dir bin src/tnitter.nit
all:
mkdir -p bin/
- ../../bin/nitg --dir bin/ src/calculator_gtk.nit src/calculator_test.nit
+ ../../bin/nitc --dir bin/ src/calculator_gtk.nit src/calculator_test.nit
android:
mkdir -p bin/ res/
../../contrib/inkscape_tools/bin/svg_to_icons art/icon.svg --android --out res/
- ../../bin/nitg -o bin/calculator.apk src/calculator_android.nit
+ ../../bin/nitc -o bin/calculator.apk src/calculator_android.nit
emscripten:
- ../../../bin/nitg -o www/fibonacci.js ../../fibonacci.nit -m emscripten
+ ../../../bin/nitc -o www/fibonacci.js ../../fibonacci.nit -m emscripten
emscripten:
- ../../../bin/nitg -o www/hello_world.js ../../hello_world.nit -m emscripten
+ ../../../bin/nitc -o www/hello_world.js ../../hello_world.nit -m emscripten
android: icon
mkdir -p bin
- ../../bin/nitg -o bin/ballz.apk src/ballz_android.nit
+ ../../bin/nitc -o bin/ballz.apk src/ballz_android.nit
icon: ../../contrib/inkscape_tools/bin/svg_to_icons
mkdir -p res
linux:
mkdir -p bin
- ../../bin/nitg -o bin/dino src/dino_linux.nit
+ ../../bin/nitc -o bin/dino src/dino_linux.nit
android: android-icons
mkdir -p bin
- ../../bin/nitg -o bin/dino.apk src/dino_android.nit
+ ../../bin/nitc -o bin/dino.apk src/dino_android.nit
../../contrib/inkscape_tools/bin/svg_to_icons:
$(MAKE) -C ../../contrib/inkscape_tools
linux:
mkdir -p bin
- ../../bin/nitg -o bin/moles src/moles_linux.nit
+ ../../bin/nitc -o bin/moles src/moles_linux.nit
android: android-icons
mkdir -p bin
- ../../bin/nitg -o bin/moles.apk src/moles_android.nit
+ ../../bin/nitc -o bin/moles.apk src/moles_android.nit
../../contrib/inkscape_tools/bin/svg_to_icons:
$(MAKE) -C ../../contrib/inkscape_tools
linux:
mkdir -p bin
- ../../bin/nitg -o bin/simple src/simple_linux.nit
+ ../../bin/nitc -o bin/simple src/simple_linux.nit
android:
mkdir -p bin
- ../../bin/nitg -o bin/simple.apk src/complete_simple_android.nit
+ ../../bin/nitc -o bin/simple.apk src/complete_simple_android.nit
clean:
rm -rf bin
bin/mpi_simple:
mkdir -p bin/
- ../../bin/nitg src/mpi_simple.nit -o bin/mpi_simple
+ ../../bin/nitc src/mpi_simple.nit -o bin/mpi_simple
run:
mpiexec.openmpi --hostfile hosts bin/mpi_simple
all:
mkdir -p bin/
- ../../bin/nitg --dir bin src/nitcorn_hello_world.nit src/file_server_on_port_80.nit
+ ../../bin/nitc --dir bin src/nitcorn_hello_world.nit src/file_server_on_port_80.nit
xymus.net:
mkdir -p bin/
- ../../bin/nitg --dir bin/ -I ../../contrib/tnitter/src/ -I ../../contrib/benitlux/src/ -I ../../contrib/opportunity/src/ src/xymus_net.nit
+ ../../bin/nitc --dir bin/ -I ../../contrib/tnitter/src/ -I ../../contrib/benitlux/src/ -I ../../contrib/opportunity/src/ src/xymus_net.nit
import nitcorn
-class MyAction
+# An action that responds by displaying a static html content.
+class StaticAction
super Action
redef fun answer(http_request, turi)
end
end
+# An action that uses parameterized uris to customize the output.
+class ParamAction
+ super Action
+
+ redef fun answer(http_request, turi)
+ do
+ var response = new HttpResponse(200)
+ var name = http_request.param("name")
+ if name == null then
+ response.body = "No name..."
+ else
+ response.body = "Hello {name}"
+ end
+ return response
+ end
+end
+
+
var vh = new VirtualHost("localhost:8080")
# Serve index.html with our custom handler
-vh.routes.add new Route("/index.html", new MyAction)
+vh.routes.add new Route("/index.html", new StaticAction)
+vh.routes.add new Route("/hello/:name", new ParamAction)
# Serve everything else with a standard `FileServer` with a root at "www/hello_world/"
vh.routes.add new Route(null, new FileServer("www/hello_world/"))
default:
- ../../../bin/nitg --semi-global converter.nit
+ ../../../bin/nitc --semi-global converter.nit
HTTPD_PY := python $(NACL_SDK_ROOT)/tools/httpd.py
serve:
2. Declare the environment variable NACL_SDK_ROOT as the root of the target platform within the SDK (ex: ~/nacl_sdk/pepper_34/) :
$ export NACL_SDK_ROOT=/path/to/nacl_sdk/pepper_[your_version]
-3. Compile the Nit code with: `nitg --semi-global converter.nit` or `make`.
+3. Compile the Nit code with: `nitc --semi-global converter.nit` or `make`.
You must use the '--semi-global' (or `--global`) option. Some features in the standard library are not supported by the NaCL platform, the global compiler do not try to compile them.
do
# Each row is a sequence of fields
var rows = new Array[Array[String]]
- var max = 0
for line in text.split('\n') do
rows.add line.split("$")
end
"and end with: {sequence27[size27 - 4]}, {sequence27[size27 - 3]}, " +
"{sequence27[size27 - 2]}, {sequence27[size27 - 1]}"
-var max: Int = hailstone(1).length
+var max = hailstone(1).length
var max_sequence = hailstone(1)
var max_element = 1
private var open: Bool = false
# Main functionnality, returns path from `self` to `dest`
- fun path_to(dest: N, max_cost: Int, context: PathContext): nullable Path[N]
+ fun path_to(dest: N, max_cost: Int, context: PathContext): nullable AStarPath[N]
do
return path_to_alts(dest, max_cost, context, null)
end
# Find a path to a possible `destination` or a node accepted by `alt_targets`
fun path_to_alts(destination: nullable N, max_cost: Int, context: PathContext,
- alt_targets: nullable TargetCondition[N]): nullable Path[N]
+ alt_targets: nullable TargetCondition[N]): nullable AStarPath[N]
do
var cost = 0
else if frontier_node == destination or
(alt_targets != null and alt_targets.accept(frontier_node)) then
- var path = new Path[N](cost)
+ var path = new AStarPath[N](cost)
while frontier_node != self do
path.nodes.unshift(frontier_node)
end
# Result from path finding and a walkable path
-class Path[N]
+class AStarPath[N]
# The total cost of this path
var total_cost: Int
# Step on the path and get the next node to travel
fun step: N
do
- assert nodes.length >= at else print "a_star::Path::step failed, is at_end_of_path"
+ assert nodes.length >= at else print "a_star::AStarPath::step failed, is at_end_of_path"
var s = nodes[at]
at += 1
# You are allowed to redistribute it and sell it, alone or is a part of
# another product.
+# Simple toolkit for artificial intelligence.
module ai
import backtrack
continue
end
- var c = new Clock
var s = pb.astar
s.memorize = true
var r = s.run
# `steps` is the maximum number of steps a giver configuration can run.
fun run_configs(steps: Int)
do
- var s
-
var c = 0
loop
if astar.run_config(steps, c, "A*") then break
print msg
var t = new Clock
- var res = run_steps(steps)
+ run_steps(steps)
print "\t{self}"
var l = t.lapse
print "\ttime={l}"
# Returns the `null` if none or if it's the wrong value type
fun array_of_string(key: String): nullable Array[String]
do
- var string_array = new Array[String]
sys.jni_env.push_local_frame(1)
var return_value = native_bundle.get_string_array(key.to_java_string)
android:
mkdir -p bin/ res/
../../../contrib/inkscape_tools/bin/svg_to_icons art/icon.svg --android --out res/
- ../../../bin/nitg --dir bin/ src/ui_test.nit
+ ../../../bin/nitc --dir bin/ src/ui_test.nit
adb install -r bin/ui_test.apk
install: android
expected: SequenceRead[SequenceRead[String]]) do
var istream: IStream
var reader: CsvReader
- var i = 0
istream = new StringIStream(input_rfc4180)
reader = new CsvReader(istream)
# Platform for the _emscripten_ framework
#
-# Importing this module from your project will tell _nitg_ to compile
+# Importing this module from your project will tell `nitg` to compile
# to JavaScript for the _emscripten_ framework.
module emscripten is platform
--- /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.
+
+# Github API related features.
+module github
+
+import github_curl
# Curl extention to access the Github API
# See https://developer.github.com/v3/ for details
-module github_api
+module github_curl
import curl
import json::static
p.close
return token.trim
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.
+
+module test_github_curl is test_suite
+
+import github::github_curl
+import test_suite
+
+class TestGithubCurl
+ super TestSuite
+
+ var auth: String = get_github_oauth
+ var user_agent: String = "nit"
+ var testee: GithubCurl is noinit
+
+ redef fun before_test do
+ testee = new GithubCurl(auth, user_agent)
+ end
+
+ fun test_get_repo do
+ var uri = "https://api.github.com/repos/privat/nit"
+ var res = testee.get_and_check(uri)
+
+ assert res isa JsonObject
+ assert res["name"] == "nit"
+ assert res["owner"] isa JsonObject
+ end
+
+ fun test_get_user do
+ var uri = "https://api.github.com/users/Morriar"
+ var res = testee.get_and_check(uri)
+
+ assert res isa JsonObject
+ assert res["login"] == "Morriar"
+ assert res["html_url"] == "https://github.com/Morriar"
+ end
+end
var config = configs.first
-var format = config.attribs(egl_display).native_visual_id
-
# TODO android part
# Opengles1Display_midway_init(recv, format);
private class HTMLRaw
super HTMLTag
- private var content: String
+ var content: String
redef fun render_in(res) do res.add content
end
else if line.has_prefix(";") then
continue
else if line.has_prefix("[") then
- var key = line.trim.substring(1, line.length - 2)
+ line = line.trim
+ var key = line.substring(1, line.length - 2)
path = key
set_node(path, null)
else
module io::push_back_reader
# Input stream that permits to push bytes back to the stream.
-interface PushBackReader
+class PushBackReader
super IStream
# Push the specified byte back to the stream.
fun test_read_line do
var subject = sample
- assert "abcd\n" == subject.read_line
- assert "\n" == subject.read_line
+ assert "abcd" == subject.read_line
+ assert "" == subject.read_line
end
fun test_unread_read_line do
var subject = sample
subject.unread("a\nb")
- assert "a\n" == subject.read_line
- assert "babcd\n" == subject.read_line
+ assert "a" == subject.read_line
+ assert "babcd" == subject.read_line
end
fun test_eof do
# Sqlite3 table used
fun db_table: String do return "data_store"
- private var db_cache: nullable Sqlite3DB = null
+ var db_cache: nullable Sqlite3DB = null
# Database to use to implement the `DataStore`
fun db: nullable Sqlite3DB
var subject: MDLine
- init do end
-
fun test_is_empty do
subject = new MDLine("")
assert subject.is_empty
private var array = new Array[nullable Jsonable]
- init do end
-
# init the JSON Array from a Nit `Collection`
init from(items: Collection[nullable Jsonable]) do
array.add_all(items)
# `params` to embed in the query like in prepared statements
var params = new JsonObject
- init do end
-
# init the query from a query string
init from_string(query: String) do
self.query = query
- [x] Configuration change on the fly
- [x] Sessions
- [x] Reading cookies
+ - [x] Parameterized routes
- [ ] Full cookie support
- [ ] Close interfaces on the fly
- [ ] Better logging
Stephan Michaud and Maxime Bélanger.
It has been adapted to a library, and is currently maintained, by Alexis Laferrière.
+
+Other contributors:
+
+* Alexandre Terrasa
# Words of the first line
private var first_line = new Array[String]
- init do end
-
fun parse_http_request(full_request: String): nullable HttpRequest
do
clear_data
import more_collections
import libevent
-import server_config
+import vararg_routes
import http_request
import http_response
# The associated `HttpFactory`
var factory: HttpFactory
- init(buf_ev: NativeBufferEvent, factory: HttpFactory) do self.factory = factory
+ # Init the server using `HttpFactory`.
+ init(buf_ev: NativeBufferEvent, factory: HttpFactory) is old_style_init do
+ self.factory = factory
+ end
private var parser = new HttpRequestParser is lazy
if virtual_host != null then
var route = virtual_host.routes[request.uri]
if route != null then
+ # include uri parameters in request
+ request.uri_params = route.parse_params(request.uri)
+
var handler = route.handler
var root = route.path
var turi
# `request` is fully formed request object and has a reference to the session
# if one preexists.
#
- # `truncated_uri` is the ending of the fulle request URI, truncated from the route
+ # `truncated_uri` is the ending of the full request URI, truncated from the route
# leading to this `Action`.
fun answer(request: HttpRequest, truncated_uri: String): HttpResponse is abstract
end
var routes = new Routes(self)
# Create a virtual host from interfaces as strings
- init(interfaces: String ...)
- do
+ init(interfaces: String ...) is old_style_init do
for i in interfaces do self.interfaces.add_from_string i
end
end
# Back reference to the config of the virtual host
var config: VirtualHost
- private var array = new Array[Route]
+ # Internal routes array.
+ protected var routes = new Array[Route]
# Add `e` to `self`
- fun add(e: Route) do array.add e
+ fun add(e: Route) do routes.add e
# Remove `e` from `self`
- fun remove(e: Route) do array.remove e
+ fun remove(e: Route) do routes.remove e
# Get the first `Route` than has `key` as prefix to its path
fun [](key: String): nullable Route
do
- for route in array do
+ for route in routes do
var path = route.path
if path == null or key.has_prefix(path) then return route
end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014 Alexandre Terrasa <alexandre@moz-code.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.
+
+# Routes with uri parameters.
+#
+# Using `vararg_routes`, a `Route` can contain variable parts
+# that will be matched against a `HttpRequest` path.
+#
+# Variable parts of path can be specified using the `:` prefix.
+#
+# ## Route matching
+#
+# Route can match variables expression.
+#
+# ~~~
+# # We need an Action to try routes.
+# class DummyAction super Action end
+# var action = new DummyAction
+#
+# var route = new Route("/users/:id", action)
+# assert not route.match("/users")
+# assert route.match("/users/1234")
+# assert route.match("/users/") # empty id
+# ~~~
+#
+# Route without uri parameters still behave like before.
+#
+# ~~~
+# route = new Route("/users", action)
+# assert route.match("/users")
+# assert route.match("/users/1234")
+# assert not route.match("/issues/1234")
+# ~~~
+#
+# ## Route priority
+#
+# Priority depends on the order the routes were added to the `Routes` dispatcher.
+#
+# ~~~
+# var host = new VirtualHost("")
+# var routes = new Routes(host)
+#
+# routes.add new Route("/:a/:b/:c", action)
+# routes.add new Route("/users/:id", action)
+# routes.add new Route("/:foo", action)
+#
+# assert routes["/a/b/c"].path == "/:a/:b/:c"
+# assert routes["/a/b/c/d"].path == "/:a/:b/:c"
+# assert routes["/users/1234/foo"].path == "/:a/:b/:c"
+#
+# assert routes["/users/"].path == "/users/:id"
+# assert routes["users/"].path == "/users/:id"
+# assert routes["/users/1234"].path == "/users/:id"
+#
+# assert routes["/users"].path == "/:foo"
+# assert routes["/"].path == "/:foo"
+# assert routes[""].path == "/:foo"
+# ~~~
+#
+# ## Accessing uri parameter and values
+#
+# Parameters can be accessed by parsing the uri.
+#
+# ~~~
+# route = new Route("/users/:id", action)
+# var params = route.parse_params("/users/1234")
+# assert params.has_key("id")
+# assert not params.has_key("foo")
+# assert params["id"] == "1234"
+# ~~~
+#
+# Or from the `HttpRequest`.
+#
+# ~~~
+# route = new Route("/users/:id", action)
+# var req = new HttpRequest
+# req.uri_params = route.parse_params("/users/1234")
+# assert req.params == ["id"]
+# assert req.param("id") == "1234"
+# assert req.param("foo") == null
+# ~~~
+#
+# Note that normally, all this work is done by nitcorn.
+# Params can then be accessed in the `HttpRequest` given to `Action::answer`.
+module vararg_routes
+
+import server_config
+import http_request
+
+# A route to an `Action` according to a `path`
+redef class Route
+
+ redef init do
+ super
+ parse_pattern(path)
+ end
+
+ # Cut `path` into `UriParts`.
+ private fun parse_pattern(path: nullable String) do
+ if path == null then return
+ path = standardize_path(path)
+ var parts = path.split("/")
+ for part in parts do
+ if not part.is_empty and part.first == ':' then
+ # is an uri param
+ var name = part.substring(1, part.length)
+ var param = new UriParam(name)
+ pattern_parts.add param
+ else
+ # is a standard string
+ pattern_parts.add new UriString(part)
+ end
+ end
+ end
+
+ # `UriPart` forming `self` pattern.
+ private var pattern_parts = new Array[UriPart]
+
+ # Does `self` matches `uri`?
+ fun match(uri: nullable String): Bool do
+ if pattern_parts.is_empty then return true
+ if uri == null then return false
+ uri = standardize_path(uri)
+ var parts = uri.split("/")
+ for i in [0 .. pattern_parts.length[ do
+ if i >= parts.length then return false
+ var ppart = pattern_parts[i]
+ var part = parts[i]
+ if not ppart.match(part) then return false
+ end
+ return true
+ end
+
+ # Extract parameter values from `uri`.
+ fun parse_params(uri: nullable String): Map[String, String] do
+ var res = new HashMap[String, String]
+ if pattern_parts.is_empty then return res
+ if uri == null then return res
+ uri = standardize_path(uri)
+ var parts = uri.split("/")
+ for i in [0 .. pattern_parts.length[ do
+ if i >= parts.length then return res
+ var ppart = pattern_parts[i]
+ var part = parts[i]
+ if not ppart.match(part) then return res
+ if ppart isa UriParam then
+ res[ppart.name] = part
+ end
+ end
+ return res
+ end
+
+ # Remove first occurence of `/`.
+ private fun standardize_path(path: String): String do
+ if not path.is_empty and path.first == '/' then
+ return path.substring(1, path.length)
+ end
+ return path
+ end
+end
+
+# A String that compose an URI.
+#
+# In practice, UriPart can be parameters or static strings.
+private interface UriPart
+ # Does `self` matches a part of the uri?
+ fun match(uri_part: String): Bool is abstract
+end
+
+# An uri parameter string like `:id`.
+private class UriParam
+ super UriPart
+
+ # Param `name` in the route uri.
+ var name: String
+
+ # Parameters match everything.
+ redef fun match(part) do return true
+end
+
+# A static uri string like `users`.
+private class UriString
+ super UriPart
+
+ # Uri part string.
+ var string: String
+
+ # Empty strings match everything otherwise matching is based on string equality.
+ redef fun match(part) do return string.is_empty or string == part
+end
+
+redef class Routes
+ # Use `Route::match` instead of `==`.
+ redef fun [](key) do
+ for route in routes do
+ if route.match(key) then return route
+ end
+ return null
+ end
+end
+
+redef class HttpRequest
+
+ # Parameters found in uri associated to their values.
+ var uri_params: Map[String, String] = new HashMap[String, String] is public writable
+
+ # Get the value for parameter `name` or `null`.
+ fun param(name: String): nullable String do
+ if not uri_params.has_key(name) then return null
+ return uri_params[name]
+ end
+
+ # List all uri parameters matched by this request.
+ fun params: Array[String] do return uri_params.keys.to_a
+end
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
+ #include <poll.h>
#define MAX_DICTIONARY_QUEUE_SIZE 200
#define MAX_MESSAGE_QUEUE_SIZE 10
}
/* Hack in order to avoid the problem with file. */
- int poll(void *fds, int nfds, int timeout) { return 0; }
+ int poll(struct pollfd* fds, nfds_t nfds, int timeout) { return 0; }
`}
# Nit class representing a Pepper C API PP_Var typed as a Dictionary.
#include <time.h>
`}
+# Elapsed time representation.
extern class Timespec `{struct timespec*`}
+
+ # Init a new Timespec from `s` seconds and `ns` nanoseconds.
new ( s, ns : Int ) `{
struct timespec* tv = malloc( sizeof(struct timespec) );
tv->tv_sec = s; tv->tv_nsec = ns;
return tv;
`}
+
+ # Init a new Timespec from now.
new monotonic_now `{
struct timespec* tv = malloc( sizeof(struct timespec) );
clock_gettime( CLOCK_MONOTONIC, tv );
return tv;
`}
+
+ # Init a new Timespec copied from another.
new copy_of( other : Timespec ) `{
struct timespec* tv = malloc( sizeof(struct timespec) );
tv->tv_sec = other->tv_sec;
return tv;
`}
+ # Update `self` clock.
fun update `{
clock_gettime( CLOCK_MONOTONIC, recv );
`}
+
+ # Substract a Timespec from `self`.
fun - ( o : Timespec ) : Timespec
do
var s = sec - o.sec
return new Timespec( s, ns )
end
+ # Number of whole seconds of elapsed time.
fun sec : Int `{
return recv->tv_sec;
`}
+
+ # Rest of the elapsed time (a fraction of a second).
+ #
+ # Number of nanoseconds.
fun nanosec : Int `{
return recv->tv_nsec;
`}
- fun destroy `{
- free( recv );
- `}
-
# Seconds in Float
# Loss of precision but great to print
fun to_f: Float do return sec.to_f + nanosec.to_f / 1000000000.0
return data[index * 5 + 3]
end
else if index isa String and "" != index then
- var i: Int = 0
+ var i = 0
while i < data.length do
if data[i + 2] == index then
return data[index * 5 + 4]
end
else if index isa String and "" != index then
- var i: Int = 0
+ var i = 0
while i < data.length do
if data[i + 2] == index then
# The index of the attribute, or -1 if it does not
# appear in the list.
redef fun index_ns(uri: String, local_name: String): Int do
- var i: Int = 0
+ var i = 0
if "" != local_name then
while i < data.length do
# The index of the attribute, or -1 if it does not
# appear in the list.
redef fun index_of(qname: String): Int do
- var i: Int = 0
+ var i = 0
if "" != qname then
while i < data.length do
# attribute is not in the list or if Namespace
# processing is not being performed.
redef fun type_ns(uri: String, local_name: String): nullable String do
- var i: Int = 0
+ var i = 0
if "" != local_name then
while i < data.length do
# attribute is not in the list or if Namespace
# processing is not being performed.
redef fun value_ns(uri: String, local_name: String): nullable String do
- var i: Int = 0
+ var i = 0
if "" != local_name then
while i < data.length do
#
# * `atts`: attributes to copy.
fun attributes=(atts: Attributes) do
- var i: Int = 0
+ var i = 0
clear
length = atts.length
super TestSuite
private fun sample: AttributesImpl do
- var subject: AttributesImpl = new AttributesImpl
+ var subject = new AttributesImpl
# The parser may include everything...
subject.add("http://example.com/", "bar", "foo:bar", "CDATA", "baz")
end
fun test_length do
- var subject: AttributesImpl = new AttributesImpl
+ var subject = new AttributesImpl
assert 0 == subject.length
subject.add("http://example.com/", "bar", "foo:bar", "CDATA", "baz")
end
fun test_uri do
- var subject: AttributesImpl = sample
+ var subject = sample
assert "http://example.com/" == subject.uri(0)
assert "urn:is:not:often:used" == subject.uri(1)
end
fun test_local_name do
- var subject: AttributesImpl = sample
+ var subject = sample
assert "bar" == subject.local_name(0)
assert "i-am_ME" == subject.local_name(1)
end
fun test_qname do
- var subject: AttributesImpl = sample
+ var subject = sample
assert "foo:bar" == subject.qname(0)
assert "" == subject.qname(1)
end
fun test_type_of do
- var subject: AttributesImpl = sample
+ var subject = sample
assert "CDATA" == subject.type_of(0)
assert "ID" == subject.type_of(1)
end
fun test_type_of_qname do
- var subject: AttributesImpl = sample
+ var subject = sample
assert "CDATA" == subject.type_of("foo:bar")
assert subject.type_of("") == null
end
fun test_value_of do
- var subject: AttributesImpl = sample
+ var subject = sample
assert "baz" == subject.value_of(0)
assert "noop" == subject.value_of(1)
end
fun test_value_of_qname do
- var subject: AttributesImpl = sample
+ var subject = sample
assert "baz" == subject.value_of("foo:bar")
assert subject.value_of("") == null
end
fun test_index_ns do
- var subject: AttributesImpl = sample
+ var subject = sample
assert 0 == subject.index_ns("http://example.com/", "bar")
assert 1 == subject.index_ns("urn:is:not:often:used", "i-am_ME")
end
fun test_index_of do
- var subject: AttributesImpl = sample
+ var subject = sample
assert 0 == subject.index_of("foo:bar")
assert -1 == subject.index_of("")
end
fun test_type_ns do
- var subject: AttributesImpl = sample
+ var subject = sample
assert "CDATA" == subject.type_ns("http://example.com/", "bar")
assert "ID" == subject.type_ns("urn:is:not:often:used", "i-am_ME")
end
fun test_value_ns do
- var subject: AttributesImpl = sample
+ var subject = sample
assert "baz" == subject.value_ns("http://example.com/", "bar")
assert "noop" == subject.value_ns("urn:is:not:often:used", "i-am_ME")
end
fun test_attributes_set do
- var subject: AttributesImpl = sample
- var subject2: AttributesImpl = new AttributesImpl
+ var subject = sample
+ var subject2 = new AttributesImpl
subject.attributes = subject2
assert subject.length == 0
end
fun test_set do
- var subject: AttributesImpl = sample
+ var subject = sample
subject.set(1, "urn:is:not:often:used", "i-am_ME", "i-am_ME", "ID",
"noop")
end
fun test_remove_at do
- var subject: AttributesImpl = sample
+ var subject = sample
subject.remove_at(1)
assert 3 == subject.length
end
fun test_uri_set do
- var subject: AttributesImpl = sample
+ var subject = sample
subject.uri(0) = "https://example.org/serious"
subject.uri(1) = "ftp://wat"
end
fun test_local_name_set do
- var subject: AttributesImpl = sample
+ var subject = sample
subject.local_name(0) = "trololol"
subject.local_name(1) = "ImYou42"
end
fun test_qname_set do
- var subject: AttributesImpl = sample
+ var subject = sample
subject.qname(0) = "go-to:bar"
subject.qname(1) = "yo:i-am_ME"
end
fun test_type_of_set do
- var subject: AttributesImpl = sample
+ var subject = sample
subject.type_of(0) = "NMTOKENS"
subject.type_of(1) = "ENTITY"
end
fun test_value_of_set do
- var subject: AttributesImpl = sample
+ var subject = sample
subject.value_of(0) = "buz"
subject.value_of(1) = "bizzz"
# match `expected`.
fun expect_string(expected: String, context: String): Bool do
var chars = expected.chars
- var i: Int = 0
+ var i = 0
while i < chars.length do
if not accept(chars[i]) then
var buffer: Buffer = new FlatBuffer
# Number of consecutive closing brackets.
- var closing: Int = 0
+ var closing = 0
if lexer.expect_string("CDATA[",
" at the beginning of a CDATA section.") then
var buf = new FlatBuffer
var sub_diff: Array[Int]
var equal: Bool
- var i: Int = 0
+ var i = 0
var min: Int
var max: Int
private fun diff_entry(actual: Array[String], expected: Array[String]):
Array[Int] do
var result = new Array[Int]
- var i: Int = 0
+ var i = 0
var min: Int
var max: Int
private fun diff_append_mismatch_entry(buf: Buffer, entry: Array[String],
sorted_mismatches: Collection[Int], term_normal: String,
term_emphasis: String) do
- var i: Int = 0
+ var i = 0
var j = sorted_mismatches.iterator
var length = entry.length
all:
mkdir -p bin/
- ../../../../bin/nitg -o bin/minimal src/minimal.nit
+ ../../../../bin/nitc -o bin/minimal src/minimal.nit
--- /dev/null
+digraph g {
+rankdir=BT;node[shape=box];
+subgraph cluster_37053984 {
+label=".."
+ m_41649040 [label="kernel"]
+subgraph cluster_37183344 {
+label="../collection"
+ m_38874592 [label="array"]
+ m_40662960 [label="abstract_collection"]
+}
+}
+ m_38874592 -> m_40662960
+ m_40662960 -> m_41649040
+}
# Standard input and output can be handled through streams.
module exec
-import stream
+import file
# Simple sub-process
class Process
super IStream
# File Descriptor used for the input.
- var stream_in: FDIStream is noinit
+ var stream_in: IFStream is noinit
redef fun close do stream_in.close
redef fun execute
do
super
- stream_in = new FDIStream(data.out_fd)
+ stream_in = new IFStream.from_fd(data.out_fd)
end
end
redef fun execute
do
super
- stream_out = new FDOStream(data.in_fd)
+ stream_out = new OFStream.from_fd(data.in_fd)
end
end
if (pipeflag & 1) {
int res = pipe(in_fd);
if ( res == -1 ) {
- fprintf( stderr, "Pipe init failed in Process:basic_exec_execute: %s\n", strerror( errno ) );
- exit(1);
+ return NULL;
}
}
if (pipeflag & 2) {
int res = pipe(out_fd);
if ( res == -1 ) {
- fprintf( stderr, "Pipe init failed in Process:basic_exec_execute: %s\n", strerror( errno ) );
- exit(1);
+ return NULL;
}
}
if (pipeflag & 4) {
int res = pipe(err_fd);
if ( res == -1 ) {
- fprintf( stderr, "Pipe init failed in Process:basic_exec_execute: %s\n", strerror( errno ) );
- exit(1);
+ return NULL;
}
}
#
# This file is free software, which comes along with NIT. This software is
# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. You can modify it is you want, provided this header
# is kept unaltered, and a notification of the changes is added.
# You are allowed to redistribute it and sell it, alone or is a part of
intrude import ropes
import string_search
import time
+import gc
in "C Header" `{
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
+ #include <poll.h>
+ #include <errno.h>
`}
# File Abstract Stream
private var file: nullable NativeFile = null
# The status of a file. see POSIX stat(2).
- fun file_stat: FileStat do return _file.file_stat
+ fun file_stat: NativeFileStat do return _file.file_stat
# File descriptor of this file
fun fd: Int do return _file.fileno
+
+ # Sets the buffering mode for the current FStream
+ #
+ # If the buf_size is <= 0, its value will be 512 by default
+ #
+ # The mode is any of the buffer_mode enumeration in `Sys`:
+ # - buffer_mode_full
+ # - buffer_mode_line
+ # - buffer_mode_none
+ fun set_buffering_mode(buf_size, mode: Int) do
+ if buf_size <= 0 then buf_size = 512
+ if _file.set_buffering_type(buf_size, mode) != 0 then
+ last_error = new IOError("Error while changing buffering type for FStream, returned error {sys.errno.strerror}")
+ end
+ end
end
# File input stream
# The original path is reused, therefore the reopened file can be a different file.
fun reopen
do
- if not eof then close
+ if not eof and not _file.address_is_null then close
+ last_error = null
_file = new NativeFile.io_open_read(path.to_cstring)
+ if _file.address_is_null then
+ last_error = new IOError("Error: Opening file at '{path.as(not null)}' failed with '{sys.errno.strerror}'")
+ end_reached = true
+ return
+ end
end_reached = false
_buffer_pos = 0
_buffer.clear
redef fun close
do
- _file.io_close
+ if _file.address_is_null then return
+ var i = _file.io_close
_buffer.clear
end_reached = true
end
_buffer.length = nb
_buffer_pos = 0
end
-
+
# End of file?
redef var end_reached: Bool = false
self.path = path
prepare_buffer(10)
_file = new NativeFile.io_open_read(path.to_cstring)
- assert not _file.address_is_null else
- print "Error: Opening file at '{path}' failed with '{sys.errno.strerror}'"
+ if _file.address_is_null then
+ last_error = new IOError("Error: Opening file at '{path}' failed with '{sys.errno.strerror}'")
+ end_reached = true
end
end
+ init from_fd(fd: Int) do
+ self.path = ""
+ prepare_buffer(1)
+ _file = fd.fd_to_stream(read_only)
+ if _file.address_is_null then
+ last_error = new IOError("Error: Converting fd {fd} to stream failed with '{sys.errno.strerror}'")
+ end_reached = true
+ end
+ end
end
# File output stream
class OFStream
super FStream
super OStream
-
+
redef fun write(s)
do
- assert _is_writable
+ if last_error != null then return
+ if not _is_writable then
+ last_error = new IOError("Cannot write to non-writable stream")
+ return
+ end
if s isa FlatText then
write_native(s.to_cstring, s.length)
else
for i in s.substrings do write_native(i.to_cstring, i.length)
end
+ _file.flush
end
redef fun close
do
- _file.io_close
+ if _file.address_is_null then
+ if last_error != null then return
+ last_error = new IOError("Cannot close unopened write stream")
+ _is_writable = false
+ return
+ end
+ var i = _file.io_close
+ if i != 0 then
+ last_error = new IOError("Close failed due to error {sys.errno.strerror}")
+ end
_is_writable = false
end
-
redef var is_writable = false
-
+
# Write `len` bytes from `native`.
private fun write_native(native: NativeString, len: Int)
do
- assert _is_writable
+ if last_error != null then return
+ if not _is_writable then
+ last_error = new IOError("Cannot write to non-writable stream")
+ return
+ end
+ if _file.address_is_null then
+ last_error = new IOError("Writing on a null stream")
+ _is_writable = false
+ return
+ end
var err = _file.io_write(native, len)
if err != len then
# Big problem
- printn("Problem in writing : ", err, " ", len, "\n")
+ last_error = new IOError("Problem in writing : {err} {len} \n")
end
end
-
+
# Open the file at `path` for writing.
init open(path: String)
do
_file = new NativeFile.io_open_write(path.to_cstring)
- assert not _file.address_is_null else
- print "Error: Opening file at '{path}' failed with '{sys.errno.strerror}'"
- end
self.path = path
_is_writable = true
+ if _file.address_is_null then
+ last_error = new IOError("Error: Opening file at '{path}' failed with '{sys.errno.strerror}'")
+ is_writable = false
+ end
end
+
+ # Creates a new File stream from a file descriptor
+ init from_fd(fd: Int) do
+ self.path = ""
+ _file = fd.fd_to_stream(wipe_write)
+ _is_writable = true
+ if _file.address_is_null then
+ last_error = new IOError("Error: Opening stream from file descriptor {fd} failed with '{sys.errno.strerror}'")
+ _is_writable = false
+ end
+ end
+end
+
+redef class Int
+ # Creates a file stream from a file descriptor `fd` using the file access `mode`.
+ #
+ # NOTE: The `mode` specified must be compatible with the one used in the file descriptor.
+ private fun fd_to_stream(mode: NativeString): NativeFile is extern "file_int_fdtostream"
end
+# Constant for read-only file streams
+private fun read_only: NativeString do return "r".to_cstring
+
+# Constant for write-only file streams
+#
+# If a stream is opened on a file with this method,
+# it will wipe the previous file if any.
+# Else, it will create the file.
+private fun wipe_write: NativeString do return "w".to_cstring
+
###############################################################################
# Standard input stream.
end
end
-redef class String
- # return true if a file with this names exists
- fun file_exists: Bool do return to_cstring.file_exists
+# Utility class to access file system services
+#
+# Usually created with `Text::to_path`.
+class Path
- # The status of a file. see POSIX stat(2).
- fun file_stat: FileStat do return to_cstring.file_stat
+ private var path: String
- # The status of a file or of a symlink. see POSIX lstat(2).
- fun file_lstat: FileStat do return to_cstring.file_lstat
+ # Path to this file
+ redef fun to_s do return path
- # Remove a file, return true if success
- fun file_delete: Bool do return to_cstring.file_delete
+ # Name of the file name at `to_s`
+ #
+ # ~~~
+ # var path = "/tmp/somefile".to_path
+ # assert path.filename == "somefile"
+ # ~~~
+ var filename: String = path.basename("") is lazy
- # Copy content of file at `self` to `dest`
- fun file_copy_to(dest: String)
+ # Does the file at `path` exists?
+ fun exists: Bool do return stat != null
+
+ # Information on the file at `self` following symbolic links
+ #
+ # Returns `null` if there is no file at `self`.
+ #
+ # ~~~
+ # var p = "/tmp/".to_path
+ # var stat = p.stat
+ # if stat != null then # Does `p` exist?
+ # print "It's size is {stat.size}"
+ # if stat.is_dir then print "It's a directory"
+ # end
+ # ~~~
+ fun stat: nullable FileStat
+ do
+ var stat = path.to_cstring.file_stat
+ if stat.address_is_null then return null
+ return new FileStat(stat)
+ end
+
+ # Information on the file or link at `self`
+ #
+ # Do not follow symbolic links.
+ fun link_stat: nullable FileStat
do
- var input = new IFStream.open(self)
- var output = new OFStream.open(dest)
+ var stat = path.to_cstring.file_lstat
+ if stat.address_is_null then return null
+ return new FileStat(stat)
+ end
+
+ # Delete a file from the file system, return `true` on success
+ #
+ # Require: `exists`
+ fun delete: Bool do return path.to_cstring.file_delete
+
+ # Copy content of file at `path` to `dest`
+ #
+ # Require: `exists`
+ fun copy(dest: Path)
+ do
+ var input = open_ro
+ var output = dest.open_wo
while not input.eof do
var buffer = input.read(1024)
output.close
end
+ # Open this file for reading
+ #
+ # Require: `exists and not link_stat.is_dir`
+ fun open_ro: IFStream
+ do
+ # TODO manage streams error when they are merged
+ return new IFStream.open(path)
+ end
+
+ # Open this file for writing
+ #
+ # Require: `not exists or not stat.is_dir`
+ fun open_wo: OFStream
+ do
+ # TODO manage streams error when they are merged
+ return new OFStream.open(path)
+ end
+
+ # Lists the name of the files contained within the directory at `path`
+ #
+ # Require: `exists and is_dir`
+ fun files: Array[Path]
+ do
+ var files = new Array[Path]
+ for filename in path.files do
+ files.add new Path(path / filename)
+ end
+ return files
+ end
+
+ # Delete a directory and all of its content, return `true` on success
+ #
+ # Does not go through symbolic links and may get stuck in a cycle if there
+ # is a cycle in the file system.
+ fun rmdir: Bool
+ do
+ var ok = true
+ for file in self.files do
+ var stat = file.link_stat
+ if stat.is_dir then
+ ok = file.rmdir and ok
+ else
+ ok = file.delete and ok
+ end
+ end
+
+ # Delete the directory itself
+ if ok then path.to_cstring.rmdir
+
+ return ok
+ end
+
+ redef fun ==(other) do return other isa Path and path.simplify_path == other.path.simplify_path
+ redef fun hash do return path.simplify_path.hash
+end
+
+# Information on a file
+#
+# Created by `Path::stat` and `Path::link_stat`.
+#
+# The information within this class is gathered when the instance is initialized
+# it will not be updated if the targeted file is modified.
+class FileStat
+ super Finalizable
+
+ # TODO private init
+
+ # The low-level status of a file
+ #
+ # See: POSIX stat(2)
+ private var stat: NativeFileStat
+
+ private var finalized = false
+
+ redef fun finalize
+ do
+ if not finalized then
+ stat.free
+ finalized = true
+ end
+ end
+
+ # Returns the last access time in seconds since Epoch
+ fun last_access_time: Int
+ do
+ assert not finalized
+ return stat.atime
+ end
+
+ # Returns the last modification time in seconds since Epoch
+ fun last_modification_time: Int
+ do
+ assert not finalized
+ return stat.mtime
+ end
+
+ # Size of the file at `path`
+ fun size: Int
+ do
+ assert not finalized
+ return stat.size
+ end
+
+ # Is this a regular file and not a device file, pipe, socket, etc.?
+ fun is_file: Bool
+ do
+ assert not finalized
+ return stat.is_reg
+ end
+
+ # Is this a directory?
+ fun is_dir: Bool
+ do
+ assert not finalized
+ return stat.is_dir
+ end
+
+ # Is this a symbolic link?
+ fun is_link: Bool
+ do
+ assert not finalized
+ return stat.is_lnk
+ end
+
+ # FIXME Make the following POSIX only? or implement in some other way on Windows
+
+ # Returns the last status change time in seconds since Epoch
+ fun last_status_change_time: Int
+ do
+ assert not finalized
+ return stat.ctime
+ end
+
+ # Returns the permission bits of file
+ fun mode: Int
+ do
+ assert not finalized
+ return stat.mode
+ end
+
+ # Is this a character device?
+ fun is_chr: Bool
+ do
+ assert not finalized
+ return stat.is_chr
+ end
+
+ # Is this a block device?
+ fun is_blk: Bool
+ do
+ assert not finalized
+ return stat.is_blk
+ end
+
+ # Is this a FIFO pipe?
+ fun is_fifo: Bool
+ do
+ assert not finalized
+ return stat.is_fifo
+ end
+
+ # Is this a UNIX socket
+ fun is_sock: Bool
+ do
+ assert not finalized
+ return stat.is_sock
+ end
+end
+
+redef class Text
+ # Access file system related services on the path at `self`
+ fun to_path: Path do return new Path(to_s)
+end
+
+redef class String
+ # return true if a file with this names exists
+ fun file_exists: Bool do return to_cstring.file_exists
+
+ # The status of a file. see POSIX stat(2).
+ fun file_stat: NativeFileStat do return to_cstring.file_stat
+
+ # The status of a file or of a symlink. see POSIX lstat(2).
+ fun file_lstat: NativeFileStat do return to_cstring.file_lstat
+
+ # Remove a file, return true if success
+ fun file_delete: Bool do return to_cstring.file_delete
+
+ # Copy content of file at `self` to `dest`
+ fun file_copy_to(dest: String) do to_path.copy(dest.to_path)
+
# Remove the trailing extension `ext`.
#
# `ext` usually starts with a dot but could be anything.
#
# Does not go through symbolic links and may get stuck in a cycle if there
# is a cycle in the filesystem.
- fun rmdir: Bool
- do
- var ok = true
- for file in self.files do
- var file_path = self.join_path(file)
- var stat = file_path.file_lstat
- if stat.is_dir then
- ok = file_path.rmdir and ok
- else
- ok = file_path.file_delete and ok
- end
- stat.free
- end
-
- # Delete the directory itself
- if ok then to_cstring.rmdir
-
- return ok
- end
+ fun rmdir: Bool do return to_path.rmdir
# Change the current working directory
#
redef class NativeString
private fun file_exists: Bool is extern "string_NativeString_NativeString_file_exists_0"
- private fun file_stat: FileStat is extern "string_NativeString_NativeString_file_stat_0"
- private fun file_lstat: FileStat `{
+ private fun file_stat: NativeFileStat is extern "string_NativeString_NativeString_file_stat_0"
+ private fun file_lstat: NativeFileStat `{
struct stat* stat_element;
int res;
stat_element = malloc(sizeof(struct stat));
end
# This class is system dependent ... must reify the vfs
-extern class FileStat `{ struct stat * `}
+extern class NativeFileStat `{ struct stat * `}
# Returns the permission bits of file
fun mode: Int is extern "file_FileStat_FileStat_mode_0"
# Returns the last access time
fun atime: Int is extern "file_FileStat_FileStat_atime_0"
- # Returns the last status change time
+ # Returns the last status change time
fun ctime: Int is extern "file_FileStat_FileStat_ctime_0"
# Returns the last modification time
fun mtime: Int is extern "file_FileStat_FileStat_mtime_0"
fun io_read(buf: NativeString, len: Int): Int is extern "file_NativeFile_NativeFile_io_read_2"
fun io_write(buf: NativeString, len: Int): Int is extern "file_NativeFile_NativeFile_io_write_2"
fun io_close: Int is extern "file_NativeFile_NativeFile_io_close_0"
- fun file_stat: FileStat is extern "file_NativeFile_NativeFile_file_stat_0"
+ fun file_stat: NativeFileStat is extern "file_NativeFile_NativeFile_file_stat_0"
fun fileno: Int `{ return fileno(recv); `}
+ # Flushes the buffer, forcing the write operation
+ fun flush: Int is extern "fflush"
+ # Used to specify how the buffering will be handled for the current stream.
+ fun set_buffering_type(buf_length: Int, mode: Int): Int is extern "file_NativeFile_NativeFile_set_buffering_type_0"
new io_open_read(path: NativeString) is extern "file_NativeFileCapable_NativeFileCapable_io_open_read_1"
new io_open_write(path: NativeString) is extern "file_NativeFileCapable_NativeFileCapable_io_open_write_1"
redef class Sys
+ init do
+ if stdout isa FStream then stdout.as(FStream).set_buffering_mode(256, buffer_mode_line)
+ end
+
# Standard input
var stdin: PollableIStream = new Stdin is protected writable
# Standard output for errors
var stderr: OStream = new Stderr is protected writable
+ # Enumeration for buffer mode full (flushes when buffer is full)
+ fun buffer_mode_full: Int is extern "file_Sys_Sys_buffer_mode_full_0"
+ # Enumeration for buffer mode line (flushes when a `\n` is encountered)
+ fun buffer_mode_line: Int is extern "file_Sys_Sys_buffer_mode_line_0"
+ # Enumeration for buffer mode none (flushes ASAP when something is written)
+ fun buffer_mode_none: Int is extern "file_Sys_Sys_buffer_mode_none_0"
+
+ # returns first available stream to read or write to
+ # return null on interruption (possibly a signal)
+ protected fun poll( streams : Sequence[FStream] ) : nullable FStream
+ do
+ var in_fds = new Array[Int]
+ var out_fds = new Array[Int]
+ var fd_to_stream = new HashMap[Int,FStream]
+ for s in streams do
+ var fd = s.fd
+ if s isa IFStream then in_fds.add( fd )
+ if s isa OFStream then out_fds.add( fd )
+
+ fd_to_stream[fd] = s
+ end
+
+ var polled_fd = intern_poll( in_fds, out_fds )
+
+ if polled_fd == null then
+ return null
+ else
+ return fd_to_stream[polled_fd]
+ end
+ end
+
+ private fun intern_poll(in_fds: Array[Int], out_fds: Array[Int]) : nullable Int is extern import Array[Int].length, Array[Int].[], Int.as(nullable Int) `{
+ int in_len, out_len, total_len;
+ struct pollfd *c_fds;
+ sigset_t sigmask;
+ int i;
+ int first_polled_fd = -1;
+ int result;
+
+ in_len = Array_of_Int_length( in_fds );
+ out_len = Array_of_Int_length( out_fds );
+ total_len = in_len + out_len;
+ c_fds = malloc( sizeof(struct pollfd) * total_len );
+
+ /* input streams */
+ for ( i=0; i<in_len; i ++ ) {
+ int fd;
+ fd = Array_of_Int__index( in_fds, i );
+
+ c_fds[i].fd = fd;
+ c_fds[i].events = POLLIN;
+ }
+
+ /* output streams */
+ for ( i=0; i<out_len; i ++ ) {
+ int fd;
+ fd = Array_of_Int__index( out_fds, i );
+
+ c_fds[i].fd = fd;
+ c_fds[i].events = POLLOUT;
+ }
+
+ /* poll all fds, unlimited timeout */
+ result = poll( c_fds, total_len, -1 );
+
+ if ( result > 0 ) {
+ /* analyse results */
+ for ( i=0; i<total_len; i++ )
+ if ( c_fds[i].revents & c_fds[i].events || /* awaited event */
+ c_fds[i].revents & POLLHUP ) /* closed */
+ {
+ first_polled_fd = c_fds[i].fd;
+ break;
+ }
+
+ return Int_as_nullable( first_polled_fd );
+ }
+ else if ( result < 0 )
+ fprintf( stderr, "Error in Stream:poll: %s\n", strerror( errno ) );
+
+ return null_Int();
+ `}
+
end
# Print `objects` on the standard output (`stdout`).
}
return res > 0;
}
+
+FILE* file_int_fdtostream(int fd, char* mode){
+ return fdopen(fd, mode);
+}
+
+int file_NativeFile_NativeFile_set_buffering_type_0(FILE* f, int buf_sz, int mode){
+ return setvbuf(f, NULL, mode, buf_sz);
+}
extern void *string_NativeString_NativeString_file_stat_0(char *f);
extern void *file_NativeFile_NativeFile_file_stat_0(FILE *f);
extern int string_NativeString_NativeString_file_delete_0(char *f);
+FILE* file_int_fdtostream(int fd, char* mode);
+int file_NativeFile_NativeFile_set_buffering_type_0(FILE* f, int buf_sz, int mode);
#define file_NativeFile_NativeFile_io_read_2(p, b, l) fread((b), 1, (l), (FILE*)(p))
#define file_NativeFile_NativeFile_io_write_2(p, b, l) fwrite((b), 1, (l), (FILE*)(p))
#define file_FileStat_FileStat_ctime_0(self) (((struct stat*)self)->st_ctime)
#define file_FileStat_FileStat_mtime_0(self) (((struct stat*)self)->st_mtime)
#define file_FileStat_FileStat_size_0(self) (((struct stat*)self)->st_size)
+#define file_Sys_Sys_buffer_mode_full_0(self) _IOFBF
+#define file_Sys_Sys_buffer_mode_line_0(self) _IOLBF
+#define file_Sys_Sys_buffer_mode_none_0(self) _IONBF
#define string_NativeString_NativeString_file_mkdir_0(p) (mkdir(p, 0777))
#define string_NativeString_NativeString_file_getcwd_0(p) (getcwd(NULL, 0))
fun address_is_null: Bool is extern "address_is_null"
# Free the memory pointed by this pointer
- fun free `{ free(recv); `}
+ fun free is extern "free"
end
module stream
intrude import ropes
+import error
in "C" `{
#include <unistd.h>
- #include <poll.h>
- #include <errno.h>
#include <string.h>
#include <signal.h>
`}
+# Any kind of error that could be produced by an operation on Streams
+class IOError
+ super Error
+end
+
# Abstract stream class
-interface IOS
+abstract class IOS
+ # Error produced by the file stream
+ #
+ # var ifs = new IFStream.open("donotmakethisfile.binx")
+ # ifs.read_all
+ # ifs.close
+ # assert ifs.last_error != null
+ var last_error: nullable IOError = null
+
# close the stream
fun close is abstract
end
# Abstract input streams
-interface IStream
+abstract class IStream
super IOS
# Read a character. Return its ASCII value, -1 on EOF or timeout
fun read_char: Int is abstract
# Read at most i bytes
fun read(i: Int): String
do
+ if last_error != null then return ""
var s = new FlatBuffer.with_capacity(i)
while i > 0 and not eof do
var c = read_char
# Read a string until the end of the line.
#
- # The line terminator '\n', if any, is preserved in each line.
- # Use the method `Text::chomp` to safely remove it.
+ # The line terminator '\n' and '\r\n', if any, is removed in each line.
#
# ~~~
# var txt = "Hello\n\nWorld\n"
# var i = new StringIStream(txt)
- # assert i.read_line == "Hello\n"
- # assert i.read_line == "\n"
- # assert i.read_line == "World\n"
+ # assert i.read_line == "Hello"
+ # assert i.read_line == ""
+ # assert i.read_line == "World"
# assert i.eof
# ~~~
#
- # If `\n` is not present at the end of the result, it means that
- # a non-eol terminated last line was returned.
+ # Only LINE FEED (`\n`), CARRIAGE RETURN & LINE FEED (`\r\n`), and
+ # the end or file (EOF) is considered to delimit the end of lines.
+ # CARRIAGE RETURN (`\r`) alone is not used for the end of line.
#
# ~~~
- # var i2 = new StringIStream("hello")
- # assert not i2.eof
- # assert i2.read_line == "hello"
+ # var txt2 = "Hello\r\n\n\rWorld"
+ # var i2 = new StringIStream(txt2)
+ # assert i2.read_line == "Hello"
+ # assert i2.read_line == ""
+ # assert i2.read_line == "\rWorld"
# assert i2.eof
# ~~~
#
- # NOTE: Only LINE FEED (`\n`) is considered to delimit the end of lines.
+ # NOTE: Use `append_line_to` if the line terminator needs to be preserved.
fun read_line: String
do
- assert not eof
+ if last_error != null then return ""
+ if eof then return ""
var s = new FlatBuffer
append_line_to(s)
- return s.to_s
+ return s.to_s.chomp
end
# Read all the lines until the eof.
#
- # The line terminator '\n' is removed in each line,
+ # The line terminator '\n' and `\r\n` is removed in each line,
#
# ~~~
# var txt = "Hello\n\nWorld\n"
# This method is more efficient that splitting
# the result of `read_all`.
#
- # NOTE: Only LINE FEED (`\n`) is considered to delimit the end of lines.
+ # NOTE: SEE `read_line` for details.
fun read_lines: Array[String]
do
var res = new Array[String]
while not eof do
- res.add read_line.chomp
+ res.add read_line
end
return res
end
# Read all the stream until the eof.
+ #
+ # The content of the file is returned verbatim.
+ #
+ # ~~~
+ # var txt = "Hello\n\nWorld\n"
+ # var i = new StringIStream(txt)
+ # assert i.read_all == txt
+ # ~~~
fun read_all: String
do
+ if last_error != null then return ""
var s = new FlatBuffer
while not eof do
var c = read_char
# Read a string until the end of the line and append it to `s`.
#
- # SEE: `read_line` for details.
+ # Unlike `read_line` and other related methods,
+ # the line terminator '\n', if any, is preserved in each line.
+ # Use the method `Text::chomp` to safely remove it.
+ #
+ # ~~~
+ # var txt = "Hello\n\nWorld\n"
+ # var i = new StringIStream(txt)
+ # var b = new FlatBuffer
+ # i.append_line_to(b)
+ # assert b == "Hello\n"
+ # i.append_line_to(b)
+ # assert b == "Hello\n\n"
+ # i.append_line_to(b)
+ # assert b == txt
+ # assert i.eof
+ # ~~~
+ #
+ # If `\n` is not present at the end of the result, it means that
+ # a non-eol terminated last line was returned.
+ #
+ # ~~~
+ # var i2 = new StringIStream("hello")
+ # assert not i2.eof
+ # var b2 = new FlatBuffer
+ # i2.append_line_to(b2)
+ # assert b2 == "hello"
+ # assert i2.eof
+ # ~~~
+ #
+ # NOTE: The single character LINE FEED (`\n`) delimits the end of lines.
+ # Therefore CARRIAGE RETURN & LINE FEED (`\r\n`) is also recognized.
fun append_line_to(s: Buffer)
do
+ if last_error != null then return
loop
var x = read_char
if x == -1 then
end
# IStream capable of declaring if readable without blocking
-interface PollableIStream
+abstract class PollableIStream
super IStream
# Is there something to read? (without blocking)
end
# Abstract output stream
-interface OStream
+abstract class OStream
super IOS
# write a string
fun write(s: Text) is abstract
super IStream
redef fun read_char
do
- assert not eof
- if _buffer_pos >= _buffer.length then
- fill_buffer
- end
- if _buffer_pos >= _buffer.length then
+ if last_error != null then return -1
+ if eof then
+ last_error = new IOError("Stream has reached eof")
return -1
end
var c = _buffer.chars[_buffer_pos]
redef fun read(i)
do
+ if last_error != null then return ""
if _buffer.length == _buffer_pos then
if not eof then
- fill_buffer
return read(i)
end
return ""
redef fun read_all
do
+ if last_error != null then return ""
var s = new FlatBuffer
while not eof do
var j = _buffer_pos
var i = _buffer_pos
while i < _buffer.length and _buffer.chars[i] != '\n' do i += 1
+ var eol
+ if i < _buffer.length then
+ assert _buffer.chars[i] == '\n'
+ i += 1
+ eol = true
+ else
+ eol = false
+ end
+
# if there is something to append
if i > _buffer_pos then
# Enlarge the string (if needed)
s.add(_buffer.chars[j])
j += 1
end
+ _buffer_pos = i
+ else
+ assert end_reached
+ return
end
- if i < _buffer.length then
- # so \n is in _buffer[i]
- _buffer_pos = i + 1 # skip \n
+ if eol then
+ # so \n is found
return
else
# so \n is not found
- _buffer_pos = i
- if end_reached then
- return
- else
- fill_buffer
- end
+ if end_reached then return
+ fill_buffer
end
end
end
- redef fun eof do return _buffer_pos >= _buffer.length and end_reached
+ redef fun eof
+ do
+ if _buffer_pos < _buffer.length then return false
+ if end_reached then return true
+ fill_buffer
+ return _buffer_pos >= _buffer.length and end_reached
+ end
# The buffer
private var buffer: nullable FlatBuffer = null
end
# An Input/Output Stream
-interface IOStream
+abstract class IOStream
super IStream
super OStream
end
-##############################################################"
-
-# A File Descriptor Stream.
-abstract class FDStream
- super IOS
- # File description
- var fd: Int
-
- redef fun close do native_close(fd)
-
- private fun native_close(i: Int): Int is extern "stream_FDStream_FDStream_native_close_1"
- private fun native_read_char(i: Int): Int is extern "stream_FDStream_FDStream_native_read_char_1"
- private fun native_read(i: Int, buf: NativeString, len: Int): Int is extern "stream_FDStream_FDStream_native_read_3"
- private fun native_write(i: Int, buf: NativeString, len: Int): Int is extern "stream_FDStream_FDStream_native_write_3"
- private fun native_write_char(i: Int, c: Char): Int is extern "stream_FDStream_FDStream_native_write_char_2"
-end
-
-# An Input File Descriptor Stream.
-class FDIStream
- super FDStream
- super IStream
- redef var eof: Bool = false
-
- redef fun read_char
- do
- var nb = native_read_char(fd)
- if nb == -1 then eof = true
- return nb
- end
-end
-
-# An Output File Descriptor Stream.
-class FDOStream
- super FDStream
- super OStream
- redef var is_writable = true
-
- redef fun write(s)
- do
- var nb = native_write(fd, s.to_cstring, s.length)
- if nb < s.length then is_writable = false
- end
-end
-
-# An Input/Output File Descriptor Stream.
-class FDIOStream
- super FDIStream
- super FDOStream
- super IOStream
-end
-
-redef interface Object
- # returns first available stream to read or write to
- # return null on interruption (possibly a signal)
- protected fun poll( streams : Sequence[FDStream] ) : nullable FDStream
- do
- var in_fds = new Array[Int]
- var out_fds = new Array[Int]
- var fd_to_stream = new HashMap[Int,FDStream]
- for s in streams do
- var fd = s.fd
- if s isa FDIStream then in_fds.add( fd )
- if s isa FDOStream then out_fds.add( fd )
-
- fd_to_stream[fd] = s
- end
-
- var polled_fd = intern_poll( in_fds, out_fds )
-
- if polled_fd == null then
- return null
- else
- return fd_to_stream[polled_fd]
- end
- end
-
- private fun intern_poll(in_fds: Array[Int], out_fds: Array[Int]) : nullable Int is extern import Array[Int].length, Array[Int].[], Int.as(nullable Int) `{
- int in_len, out_len, total_len;
- struct pollfd *c_fds;
- sigset_t sigmask;
- int i;
- int first_polled_fd = -1;
- int result;
-
- in_len = Array_of_Int_length( in_fds );
- out_len = Array_of_Int_length( out_fds );
- total_len = in_len + out_len;
- c_fds = malloc( sizeof(struct pollfd) * total_len );
-
- /* input streams */
- for ( i=0; i<in_len; i ++ ) {
- int fd;
- fd = Array_of_Int__index( in_fds, i );
-
- c_fds[i].fd = fd;
- c_fds[i].events = POLLIN;
- }
-
- /* output streams */
- for ( i=0; i<out_len; i ++ ) {
- int fd;
- fd = Array_of_Int__index( out_fds, i );
-
- c_fds[i].fd = fd;
- c_fds[i].events = POLLOUT;
- }
-
- /* poll all fds, unlimited timeout */
- result = poll( c_fds, total_len, -1 );
-
- if ( result > 0 ) {
- /* analyse results */
- for ( i=0; i<total_len; i++ )
- if ( c_fds[i].revents & c_fds[i].events || /* awaited event */
- c_fds[i].revents & POLLHUP ) /* closed */
- {
- first_polled_fd = c_fds[i].fd;
- break;
- }
-
- return Int_as_nullable( first_polled_fd );
- }
- else if ( result < 0 )
- fprintf( stderr, "Error in Stream:poll: %s\n", strerror( errno ) );
-
- return null_Int();
- `}
-end
-
# Stream to a String.
#
# Mainly used for compatibility with OStream type and tests.
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).
- *
- * Copyright 2004-2008 Jean Privat <jean@pryen.org>
- *
- * This file is free software, which comes along with NIT. This software is
- * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. You can modify it is you want, provided this header
- * is kept unaltered, and a notification of the changes is added.
- * You are allowed to redistribute it and sell it, alone or is a part of
- * another product.
- */
-
-#include "stream_nit.h"
-
-int stream_FDStream_FDStream_native_read_char_1(void *s, int fd) {
- int result;
- char buf;
- ssize_t r = read(fd, &buf, 1);
- if (r == 0)
- result = -1;
- else
- result = buf;
- return result;
-}
+++ /dev/null
-#ifndef __STREAM_NIT_H
-#define __STREAM_NIT_H
-/* This file is part of NIT ( http://www.nitlanguage.org ).
- *
- * Copyright 2004-2008 Jean Privat <jean@pryen.org>
- *
- * This file is free software, which comes along with NIT. This software is
- * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. You can modify it is you want, provided this header
- * is kept unaltered, and a notification of the changes is added.
- * You are allowed to redistribute it and sell it, alone or is a part of
- * another product.
- */
-
-#include <unistd.h>
-
-int stream_FDStream_FDStream_native_read_char_1(void *s, int fd);
-
-#define stream_FDStream_FDStream_native_close_1(self, p0) (close(p0))
-#define stream_FDStream_FDStream_native_read_3(s, i, b, l) read((i), ((b)), ((l)))
-#define stream_FDStream_FDStream_native_write_3(s, i, b, l) write((i), ((b)), ((l)))
-#define stream_FDStream_FDStream_native_write_char_2(s, i, c) write((i), (char[]){(c)}, 1 )
-
-#endif
# assert "\na\nb\tc\t".trim == "a\nb\tc"
fun trim: SELFTYPE do return (self.l_trim).r_trim
- # Returns `self` removed from its last `\n` (if any).
+ # Returns `self` removed from its last line terminator (if any).
#
# assert "Hello\n".chomp == "Hello"
# assert "Hello".chomp == "Hello"
- # assert "\n\n\n".chomp == "\n\n"
#
- # This method is mainly used to remove the LINE_FEED character from lines of text.
+ # assert "\n".chomp == ""
+ # assert "".chomp == ""
+ #
+ # Line terminators are `"\n"`, `"\r\n"` and `"\r"`.
+ # A single line terminator, the last one, is removed.
+ #
+ # assert "\r\n".chomp == ""
+ # assert "\r\n\n".chomp == "\r\n"
+ # assert "\r\n\r\n".chomp == "\r\n"
+ # assert "\r\n\r".chomp == "\r\n"
+ #
+ # Note: unlike with most IO methods like `IStream::read_line`,
+ # a single `\r` is considered here to be a line terminator and will be removed.
fun chomp: SELFTYPE
do
- if self.chars.last != '\n' then return self
- return substring(0, length-1)
+ var len = length
+ if len == 0 then return self
+ var l = self.chars.last
+ if l == '\r' then
+ return substring(0, len-1)
+ else if l != '\n' then
+ return self
+ else if len > 1 and self.chars[len-2] == '\r' then
+ return substring(0, len-2)
+ else
+ return substring(0, len-1)
+ end
end
# Justify a self in a space of `length`
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2008 Floréal Morandat <morandat@lirmm.fr>
+# Copyright 2014 Alexandre Terrasa <alexandre@moz-code.org>
#
# This file is free software, which comes along with NIT. This software is
# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. You can modify it is you want, provided this header
# is kept unaltered, and a notification of the changes is added.
# You are allowed to redistribute it and sell it, alone or is a part of
module time
import string_search
+import stream
in "C Header" `{
#include <time.h>
redef fun to_s do return asctime.replace("\n", "")
end
+
+# Date using the international format defined by ISO 8601.
+#
+# Usage:
+#
+# # By default ISODate at today.
+# var date = new ISODate
+# var tm = new Tm.localtime
+# assert date.year == tm.year + 1900
+# assert date.month == tm.mon + 1
+# assert date.day == tm.mday
+#
+# # ISODate can be initialized from a String.
+# date = new ISODate.from_string("1970-01-01T00:00:00Z")
+# assert date.year == 1970
+# assert date.month == 1
+# assert date.day == 1
+#
+# # ISODate can be printed as String following the ISO format.
+# assert date.to_s == "1970-01-01T00:00:00Z"
+#
+# Note that only the `YYYY-MM-DDTHH:MM:SSZ` is supported for now.
+#
+# See <http://www.w3.org/QA/Tips/iso-date>
+class ISODate
+ super Comparable
+
+ # UTC years as Int.
+ var year: Int is noinit
+
+ # UTC months as Int (`1` for January).
+ var month: Int is noinit
+
+ # UTC days as Int (starting at `1`).
+ var day: Int is noinit
+
+ # UTC hours as Int.
+ var hours: Int is noinit
+
+ # UTC minutes as Int.
+ var minutes: Int is noinit
+
+ # UTC seconds as Int.
+ var seconds: Int is noinit
+
+ # UTC timezone marker.
+ #
+ # Note that I don't know what will happen if you change this value...
+ var timezone = "Z"
+
+ init do
+ var t = new Tm.localtime
+ year = 1900 + t.year
+ month = t.mon + 1
+ day = t.mday
+ hours = t.hour
+ minutes = t.min
+ seconds = t.sec
+ end
+
+ # Init `self` from a ISODate formatted string.
+ init from_string(str: String) do
+ year = str.substring(0, 4).to_i
+ month = str.substring(5, 2).to_i
+ day = str.substring(8, 2).to_i
+ hours = str.substring(11, 2).to_i
+ minutes = str.substring(14, 2).to_i
+ seconds = str.substring(17, 2).to_i
+ timezone = str.substring(19, str.length)
+ end
+
+ redef fun to_s do
+ var buff = new FlatBuffer
+ buff.append year.to_s
+ buff.add '-'
+ if month < 10 then buff.add '0'
+ buff.append month.to_s
+ buff.add '-'
+ if day < 10 then buff.add '0'
+ buff.append day.to_s
+ buff.add 'T'
+ if hours < 10 then buff.add '0'
+ buff.append hours.to_s
+ buff.add ':'
+ if minutes < 10 then buff.add '0'
+ buff.append minutes.to_s
+ buff.add ':'
+ if seconds < 10 then buff.add '0'
+ buff.append seconds.to_s
+ buff.append timezone
+ return buff.write_to_string
+ end
+
+ redef type OTHER: ISODate
+
+ # TODO handle timezones
+ redef fun <(o) do return to_s < o.to_s
+end
var index = self.index
var ipos = 0
var max = length
- var items = self.items
while ipos < max do
var u = index[ipos].to_upper
var index = self.index
var ipos = 0
var max = length
- var items = self.items
while ipos < max do
var u = index[ipos].to_lower
# Also build `self` template parts using original template text.
private fun parse do
var text = tpl_text
- var chars = text.chars
var pos = 0
var out = new FlatBuffer
var start_pos: Int
private class TemplateStringIterator
super MapIterator[String, nullable Streamable]
- private var subject: TemplateString
- private var key_it: Iterator[String] is noinit
+ var subject: TemplateString
+ var key_it: Iterator[String] is noinit
init do
self.key_it = subject.macro_names.iterator
return res.value
end
+ # Search `key` in `from` and its children nodes.
protected fun search_down(from: N, key: K): nullable N do
var cmp = key <=> from.key
if cmp == 0 then return from
return min_from(root.as(not null)).value
end
+ # Get the left-most child from `node`.
protected fun min_from(node: N): N do
if node.left == null then return node
return min_from(node.left.as(not null))
return max_from(root.as(not null)).value
end
+ # Get the right-most child from `node`.
protected fun max_from(node: N): N do
if node.right == null then return node
return max_from(node.right.as(not null))
insert_node(new BinTreeNode[K, E](key, item))
end
+ # Add `node` in the tree.
protected fun insert_node(node: N) do
len += 1
if root == null then
return sorted
end
+ # Sort the tree from `node` and place results in `sorted`.
protected fun sort_down(node: N, sorted: Array[E]) do
if node.left != null then sort_down(node.left.as(not null), sorted)
sorted.add(node.value)
return "[{print_tree(root)}]"
end
+ # Print the tree starting from `node`.
protected fun print_tree(node: N): String do
var s = new FlatBuffer
s.append(node.to_s)
f.close
end
+ # Translate the tree in dot format starting from `node`.
protected fun dot_down(node: N, f: OProcess) do
if node.left != null then dot_down(node.left.as(not null), f)
f.write node.to_dot
class BinTreeNode[K: Comparable, E]
super TreeNode[K, E]
- private var prev: nullable BinTreeNode[K, E]
- private var next: nullable BinTreeNode[K, E]
+ private var prev: nullable BinTreeNode[K, E] = null
+ private var next: nullable BinTreeNode[K, E] = null
redef type N: BinTreeNode[K, E]
- init(key: K, item: E) do
- super(key, item)
- end
-
private var left_node: nullable N = null
# `left` tree node child (null if node has no left child)
private class BinTreeMapIterator[K: Comparable, E]
super MapIterator[K, E]
- var current: nullable BinTreeNode[K, E]
+ var tree: BinTreeMap[K, E]
+ var current: nullable BinTreeNode[K, E] = null
- init(tree: BinTreeMap[K, E]) do
- current = tree.first_node
- end
+ init do current = tree.first_node
redef fun is_ok do return not current == null
redef fun next do current = current.next
private extern class ConstPointer `{ const void * `}
# Convert a C `char **` to a Nit `Array[String]`
- private fun to_string_array: Array[String]
+ fun to_string_array: Array[String]
import Array[String], Array[String].add, NativeString.to_s `{
char **strings = (char**)recv;
# and setup a new `complete` for the command
eval "$($1 --bash-completion)"
- # Special case for `nitc` that uses the completion of `nitg`
- if test "$cmd" = "nitc"; then
- cmd=nitg
- complete -F _nitg -o default nitc
+ # Special case for `nitg` that uses the completion of `nitc`
+ if test "$cmd" = "nitg"; then
+ cmd=nitc
+ complete -F _nitc -o default nitg
fi
if [[ $(type -t _$cmd) == function ]]; then
hash=$1
shift
-set +x
+set -x
local_repo=nit/
-remote_repo=privat
-
tools_dir=misc/jenkins/
cd $local_repo
git clean -fdxq .
+git fetch origin
-git fetch $remote_repo
-git checkout $hash
+if ! git checkout $hash; then
+ exit 1
+fi
-# Make nitg and tools
-$tools_dir/unitrun.sh "run-make-0initial_make" make
+# Make nitg (quickly)
+$tools_dir/unitrun.sh "run-make-csrc" make -C c_src
+$tools_dir/unitrun.sh "run-make-version" src/git-gen-version.sh
+$tools_dir/unitrun.sh "run-make-nitg_0" c_src/nitg -o bin/nitg_0 src/nitg.nit
+$tools_dir/unitrun.sh "run-make-nitg" bin/nitg_0 -o bin/nitg src/nitg.nit
# Make nitester
$tools_dir/unitrun.sh "run-make-nitester" make -C contrib/nitester/
Once generated, manpages can then be checked individually with `man -l`
~~~
-man -l man1/nitg.1
+man -l man1/nitc.1
~~~
For global access, one can set the `MANPATH` environment variable to this `man` directory (not the `man1` subdirectory).
~~~
export MANPATH=/path/to/nit/share/man:$MANPATH
-man nitg
+man nitc
~~~
+++ /dev/null
-nitg.1
\ No newline at end of file
The behavior of the interpreter may differs slightly from the compiler.
First, the interpreted is the reference implementation for the specification of the Nit language.
-That means if `nitg` and `nit` have a different behavior on a same program, it is likely that `nit` is right and `nitg` is wrong.
+That means if `nitc` and `nit` have a different behavior on a same program, it is likely that `nit` is right and `nitc` is wrong.
Second, the FFI is not yet implemented in the interpreter.
Only a subset of the standard methods are implemented with some hard-coded behaviors.
While it is enough to use most of the standard library, a lot of additional libraries may not be usable by the interpreter.
-Last, `nit` is the *Naive Interpretation Tool*, it means that it is slow and may take an average of 50.000% in overhead comparatively to `nitg`(it also means that `nitg` is fast).
+Last, `nit` is the *Naive Interpretation Tool*, it means that it is slow and may take an average of 50.000% in overhead comparatively to `nitc`(it also means that `nitc` is fast).
In practice, the slowness is not an issue for simple Nit scripts;
-it is not a big deal if `nit` takes millisecond to execute programs even if `nitg` only need microseconds.
+it is not a big deal if `nit` takes millisecond to execute programs even if `nitc` only need microseconds.
# OPTIONS
-Most options are the same than `nitg(1)`.
+Most options are the same than `nitc(1)`.
Here, only the specific one are indicated.
Note that, unlike in other Nit tools, the options *MUST* be indicated before the main module of a program.
# NAME
-nitg - compiles Nit programs.
+nitc - compiles Nit programs.
# SYNOPSIS
-nitg [*options*] FILE...
+nitc [*options*] FILE...
# DESCRIPTION
-nitg is the current official Nit compiler.
+nitc is the current official Nit compiler.
It takes the main module of a Nit program as argument and produces an executable file.
By default, the generated executables are produced in the current directory.
(see `--dir` for details.)
-Internally, nitg rely on the presence of a C compiler. Usually gcc (but nitg was successfully tested with clang).
+Internally, nitc rely on the presence of a C compiler. Usually gcc (but nitc was successfully tested with clang).
A compilation directory is therefore created and (re-)used.
By default, the compilation directory is named `.nit_compile`.
(see `--compile-dir` for details.)
To improve the compilation time and simplify the compilation of multiple programs, more than one file can be given.
Each one will be compiled into a distinct executable.
- $ nitg prog1.nit prog2.nit
+ $ nitc prog1.nit prog2.nit
To combine files into a single program, use the `-m` option.
- $ nitg prog1.nit -m other_module.nit
+ $ nitc prog1.nit -m other_module.nit
-nitg can produces executables for various platforms when specific modules are used.
+nitc can produces executables for various platforms when specific modules are used.
Currently, android, pnacl and emscripten are supported.
See the documentation of these specific modules for details.
To show only `missing-doc` warnings in standard"
- $ nitg -q -w missing-doc standard
+ $ nitc -q -w missing-doc standard
To show all warnings and advices, except `missing-doc`:
- $ nitg -W -w no-missing-doc standard
+ $ nitc -W -w no-missing-doc standard
To show important warnings except `useless-type-test`, but not advice except `missing-doc`:
- $ nitg -w missing-doc -w no-useless-type-test standard
+ $ nitc -w missing-doc -w no-useless-type-test standard
`-q`, `--quiet`
: Do not show warnings.
`--stop-on-first-error`
: Just display the first encountered error then stop.
- By default, nitg tries to detect and display more than one error before aborting the compilation.
+ By default, nitc tries to detect and display more than one error before aborting the compilation.
`--no-color`
: Do not use color to display errors and warnings.
This option is mainly used to produce C files distributable then compilable on system that do not have a Nit compiler (e.g. embedded system).
In this case, it is suggested to also use the options `--dir`, `--compile-dir` and `--semi-global`.
- $ nitg examples/hello_world.nit --no-cc --dir hello --compile-dir hello --semi-global
+ $ nitc examples/hello_world.nit --no-cc --dir hello --compile-dir hello --semi-global
Will produce a `hello` directory that contains the required C files to finish the compilation.
Only the C files required for the program are generated.
A last usage is to develop programs as product lines with a main basic module (vanilla) and specific distinct features as flavor modules, then to combine them at compile-time.
- $ nitg prog_vanilla.nit -m feature_chocolate.nit -m feature_cherry.nit
+ $ nitc prog_vanilla.nit -m feature_chocolate.nit -m feature_cherry.nit
`-D`, `--define`
: Define a specific property.
The argument of the `-D` option is "{name}={value}".
For Bool, the argument can also be just "{name}", in this case, the value is considered to be `true`.
- $ nitg foo.nit -D prefix=/opt/foo -D port=8080 -D with_ssl
+ $ nitc foo.nit -D prefix=/opt/foo -D port=8080 -D with_ssl
`--release`
: Compile in release mode and finalize application.
## COMPILATION MODES
-`nitg` includes distinct compilation modes.
+`nitc` includes distinct compilation modes.
`--separate`
: Use separate compilation (default mode).
`--make-flags`
: Additional options to the `make` command.
- $ nitg foo.nit --make-flags 'CC=clang' --make-flags 'CFLAGS="-O0 -g"'
+ $ nitc foo.nit --make-flags 'CC=clang' --make-flags 'CFLAGS="-O0 -g"'
`--typing-test-metrics`
: Enable static and dynamic count of all type tests.
`NIT_GC_OPTION`
: Runtime control of the garbage collector.
- The behavior of the GC of the executables produced by nitg can be tuned with this environment variable.
+ The behavior of the GC of the executables produced by nitc can be tuned with this environment variable.
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 tweak their GC options.
Here, the `git rev-parse HEAD` is used to link to the current snapshot revision of the file.
+`--no-attribute`
+: Ignore the attributes.
+
+ Note: In Nit, attributes are private. Therefore, this option is only useful
+ when combined with `--private`.
+
`--no-dot`
: do not generate graphs with graphviz.
`--poset`
: Complete metrics on posets
+`--detect-variance-constraints`
+: Detects the definition-site variance constraints on formal parameters.
+
+ Infers the possible variance annotations of formal types in Nit programs by identifying the existing constraints on the usage of those formal type.
+
## OUTPUT
`--csv`
NITCOPT=
OLDNITCOPT=
-OBJS=nitg nitpick nit nitdoc nitls nitunit nitpretty nitmetrics nitx nitlight nitdbg_client nitserial
+OBJS=nitc nitpick nit nitdoc nitls nitunit nitpretty nitmetrics nitx nitlight nitdbg_client nitserial
SRCS=$(patsubst %,%.nit,$(OBJS))
BINS=$(patsubst %,../bin/%,$(OBJS))
all: $(BINS)
-nitg_0: ../c_src/nitg parser/parser.nit
+nitc_0: ../c_src/nitg parser/parser.nit
@echo '***************************************************************'
- @echo '* Compile nitg_0 from NIT source files *'
+ @echo '* Compile nitc_0 from NIT source files *'
@echo '***************************************************************'
./git-gen-version.sh
- ../c_src/nitg ${OLDNITCOPT} -o nitg_0 -v nitg.nit
+ ../c_src/nitg ${OLDNITCOPT} -o nitc_0 -v nitc.nit
-$(BINS): nitg_0 parser/parser.nit
+$(BINS): nitc_0 parser/parser.nit
@echo '***************************************************************'
@echo '* Compile binaries from NIT source files *'
@echo '***************************************************************'
./git-gen-version.sh
- ./nitg_0 ${NITCOPT} -v --dir ../bin $(SRCS)
+ ./nitc_0 ${NITCOPT} -v --dir ../bin $(SRCS)
-$(OBJS): nitg_0 parser/parser.nit
+$(OBJS): nitc_0 parser/parser.nit
./git-gen-version.sh
- ./nitg_0 ${NITCOPT} -v $@.nit
+ ./nitc_0 ${NITCOPT} -v $@.nit
../c_src/nitg: ../c_src/*.c ../c_src/*.h ../c_src/Makefile
@echo '***************************************************************'
- @echo '* Compile nitg from C source files *'
+ @echo '* Compile nitc from C source files *'
@echo '***************************************************************'
cd ../c_src; make
cd parser; make
clean:
- rm -rf -- .nit_compile* version.nit nitg_0 2> /dev/null || true
+ rm -rf -- .nit_compile* version.nit nitc_0 2> /dev/null || true
cd parser; make clean
do
if last_current != current_node then
last_current = current_node
- var l = current_node._location
- if l != null then
- eol
- out.add(s)
- out.add("\t# {l.colored_line("0;32").split_with('\n').first}")
- has_eol = false
- eol
- return
- end
end
out.add(s)
has_eol = false
--- /dev/null
+#!/bin/bash
+# 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.
+
+# This shell script is used to generate stats for the next niteration (news letter)
+
+orig_def=`git describe --abbrev=0`
+cur_def=origin/master
+
+orig=${1-$orig_def}
+cur=${2-$cur_def}
+
+echo "changelog: ${orig} .. ${cur}"
+echo "shortstat"
+git diff --shortstat "$orig".."$cur"
+echo "PR"
+git log --first-parent "$orig".."$cur" | grep 'Pull-Request: #' | wc -l
+echo "shortlog"
+git shortlog -ens "$orig".."$cur"
+echo log
+echo
+git log --format="* %s [[!commit %h]]" --first-parent "$orig".."$cur" | tac
# Create a tool context to handle options and paths
var toolcontext = new ToolContext
-toolcontext.tooldescription = "Usage: nitg [OPTION]... file.nit...\nCompiles Nit programs."
+toolcontext.tooldescription = "Usage: nitc [OPTION]... file.nit...\nCompiles Nit programs."
# We do not add other options, so process them now!
toolcontext.process_options(args)
end
end
+redef class MAttributeDef
+ redef fun tpl_signature do
+ var tpl = new Template
+ if static_mtype != null then
+ tpl.add ": "
+ tpl.add static_mtype.tpl_signature
+ end
+ return tpl
+ end
+end
+
redef class MMethod
redef fun tpl_signature do
var tpl = new Template
private var opt_source = new OptionString("link for source (%f for filename, %l for first line, %L for last line)", "--source")
private var opt_sharedir = new OptionString("directory containing nitdoc assets", "--sharedir")
private var opt_shareurl = new OptionString("use shareurl instead of copy shared files", "--shareurl")
+ private var opt_no_attributes = new OptionBool("ignore the attributes",
+ "--no-attributes")
private var opt_nodot = new OptionBool("do not generate graphes with graphviz", "--no-dot")
private var opt_private = new OptionBool("also generate private API", "--private")
super
var opts = option_context
- opts.add_option(opt_dir, opt_source, opt_sharedir, opt_shareurl, opt_nodot, opt_private)
+ opts.add_option(opt_dir, opt_source, opt_sharedir, opt_shareurl,
+ opt_no_attributes, opt_nodot, opt_private)
opts.add_option(opt_custom_title, opt_custom_footer, opt_custom_intro, opt_custom_brand)
opts.add_option(opt_github_upstream, opt_github_base_sha1, opt_github_gitdir)
opts.add_option(opt_piwik_tracker, opt_piwik_site_id)
end
end
end
+
+ # Filter the entity based on the options specified by the user.
+ #
+ # Return `true` if the specified entity has to be included in the generated
+ # documentation
+ private fun filter_mclass(mclass: MClass): Bool do
+ return mclass.visibility >= min_visibility
+ end
+
+ # Filter the entity based on the options specified by the user.
+ #
+ # Return `true` if the specified entity has to be included in the generated
+ # documentation
+ private fun filter_mproperty(mproperty: MProperty): Bool do
+ return mproperty.visibility >= min_visibility and
+ not (opt_no_attributes.value and mproperty isa MAttribute)
+ end
end
# The Nitdoc class explores the model and generate pages for each mentities found
private fun classes do
for mclass in model.mclasses do
- if mclass.visibility <= ctx.min_visibility then continue
+ if not ctx.filter_mclass(mclass) then continue
var page = new NitdocClass(ctx, model, mainmodule, mclass)
page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}")
end
private fun properties do
for mproperty in model.mproperties do
- if mproperty.visibility <= ctx.min_visibility then continue
+ if not ctx.filter_mproperty(mproperty) then continue
if mproperty isa MInnerClass then continue
- if mproperty isa MAttribute then continue
var page = new NitdocProperty(ctx, model, mainmodule, mproperty)
page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}")
end
add_result_for(mmodule.name, mmodule.full_name, mmodule.nitdoc_url)
end
for mclass in model.mclasses do
- if mclass.visibility < ctx.min_visibility then continue
+ if not ctx.filter_mclass(mclass) then continue
add_result_for(mclass.name, mclass.full_name, mclass.nitdoc_url)
end
for mproperty in model.mproperties do
- if mproperty.visibility < ctx.min_visibility then continue
- if mproperty isa MAttribute then continue
+ if not ctx.filter_mproperty(mproperty) then continue
for mpropdef in mproperty.mpropdefs do
var full_name = mpropdef.mclassdef.mclass.full_name
var cls_url = mpropdef.mclassdef.mclass.nitdoc_url
private fun classes_list: Array[MClass] do
var sorted = new Array[MClass]
for mclass in model.mclasses do
- if mclass.visibility < ctx.min_visibility then continue
+ if not ctx.filter_mclass(mclass) then continue
sorted.add mclass
end
name_sorter.sort(sorted)
private fun mprops_list: Array[MProperty] do
var sorted = new Array[MProperty]
for mproperty in model.mproperties do
- if mproperty.visibility < ctx.min_visibility then continue
- if mproperty isa MAttribute then continue
- sorted.add mproperty
+ if ctx.filter_mproperty(mproperty) then sorted.add mproperty
end
name_sorter.sort(sorted)
return sorted
# Property list to display in sidebar
fun tpl_sidebar_properties do
- var kind_map = sort_by_kind(mclass_inherited_mprops)
+ var by_kind = new PropertiesByKind.with_elements(mclass_inherited_mprops)
var summary = new TplList.with_classes(["list-unstyled"])
- tpl_sidebar_list("Virtual types", kind_map["type"].to_a, summary)
- tpl_sidebar_list("Constructors", kind_map["init"].to_a, summary)
- tpl_sidebar_list("Methods", kind_map["fun"].to_a, summary)
- if not kind_map["inner"].is_empty then
- tpl_sidebar_list("Inner classes", kind_map["inner"].to_a, summary)
- end
+ by_kind.sort_groups(name_sorter)
+ for g in by_kind.groups do tpl_sidebar_list(g, summary)
tpl_sidebar.boxes.add new TplSideBox.with_content("All properties", summary)
end
- private fun tpl_sidebar_list(name: String, mprops: Array[MProperty], summary: TplList) do
+ private fun tpl_sidebar_list(mprops: PropertyGroup[MProperty], summary: TplList) do
if mprops.is_empty then return
- name_sorter.sort(mprops)
- var entry = new TplListItem.with_content(name)
+ var entry = new TplListItem.with_content(mprops.title)
var list = new TplList.with_classes(["list-unstyled", "list-labeled"])
for mprop in mprops do
list.add_li tpl_sidebar_item(mprop)
# parents
var hparents = new HashSet[MClass]
for c in mclass.in_hierarchy(mainmodule).direct_greaters do
- if c.visibility < ctx.min_visibility then continue
- hparents.add c
+ if ctx.filter_mclass(c) then hparents.add c
end
# ancestors
var hancestors = new HashSet[MClass]
for c in mclass.in_hierarchy(mainmodule).greaters do
if c == mclass then continue
- if c.visibility < ctx.min_visibility then continue
+ if not ctx.filter_mclass(c) then continue
if hparents.has(c) then continue
hancestors.add c
end
# children
var hchildren = new HashSet[MClass]
for c in mclass.in_hierarchy(mainmodule).direct_smallers do
- if c.visibility < ctx.min_visibility then continue
- hchildren.add c
+ if ctx.filter_mclass(c) then hchildren.add c
end
# descendants
var hdescendants = new HashSet[MClass]
for c in mclass.in_hierarchy(mainmodule).smallers do
if c == mclass then continue
- if c.visibility < ctx.min_visibility then continue
+ if not ctx.filter_mclass(c) then continue
if hchildren.has(c) then continue
hdescendants.add c
end
# properties
var mprops = mmodules2mprops[mentity]
- var kind_map = sort_by_kind(mprops)
+ var by_kind = new PropertiesByKind.with_elements(mprops)
- # virtual types
- for article in tpl_mproperty_articles(kind_map, "type") do
- section.add_child article
- end
- # constructors
- for article in tpl_mproperty_articles(kind_map, "init") do
- section.add_child article
- end
- # methods
- for article in tpl_mproperty_articles(kind_map, "fun") do
- section.add_child article
- end
- # inner classes
- for article in tpl_mproperty_articles(kind_map, "inner") do
- section.add_child article
+ for g in by_kind.groups do
+ for article in tpl_mproperty_articles(g) do
+ section.add_child article
+ end
end
parent.add_child section
end
end
end
- private fun tpl_mproperty_articles(kind_map: Map[String, Set[MProperty]],
- kind_name: String): Sequence[TplArticle] do
+ private fun tpl_mproperty_articles(elts: Collection[MProperty]):
+ Sequence[TplArticle] do
var articles = new List[TplArticle]
- var elts = kind_map[kind_name].to_a
- name_sorter.sort(elts)
for elt in elts do
var local_defs = mprops2mdefs[elt]
# var all_defs = elt.mpropdefs
return map
end
- private fun sort_by_kind(mprops: Collection[MProperty]): Map[String, Set[MProperty]] do
- var map = new HashMap[String, Set[MProperty]]
- map["type"] = new HashSet[MProperty]
- map["init"] = new HashSet[MProperty]
- map["fun"] = new HashSet[MProperty]
- map["inner"] = new HashSet[MProperty]
- for mprop in mprops do
- if mprop isa MVirtualTypeProp then
- map["type"].add mprop
- else if mprop isa MMethod then
- if mprop.is_init then
- map["init"].add mprop
- else
- map["fun"].add mprop
- end
- else if mprop isa MInnerClass then
- map["inner"].add mprop
- end
- end
- return map
- end
-
private fun mclass_inherited_mprops: Set[MProperty] do
var res = new HashSet[MProperty]
var local = mclass.local_mproperties(ctx.min_visibility)
end
end
+# Groups properties by kind.
+private class PropertiesByKind
+ # The virtual types.
+ var virtual_types = new PropertyGroup[MVirtualTypeProp]("Virtual types")
+
+ # The constructors.
+ var constructors = new PropertyGroup[MMethod]("Contructors")
+
+ # The attributes.
+ var attributes = new PropertyGroup[MAttribute]("Attributes")
+
+ # The methods.
+ var methods = new PropertyGroup[MMethod]("Methods")
+
+ # The inner classes.
+ var inner_classes = new PropertyGroup[MInnerClass]("Inner classes")
+
+ # All the groups.
+ #
+ # Sorted in the order they are displayed to the user.
+ var groups: SequenceRead[PropertyGroup[MProperty]] = [
+ virtual_types,
+ constructors,
+ attributes,
+ methods,
+ inner_classes: PropertyGroup[MProperty]]
+
+ # Add each the specified property to the appropriate list.
+ init with_elements(properties: Collection[MProperty]) do add_all(properties)
+
+ # Add the specified property to the appropriate list.
+ fun add(property: MProperty) do
+ if property isa MMethod then
+ if property.is_init then
+ constructors.add property
+ else
+ methods.add property
+ end
+ else if property isa MVirtualTypeProp then
+ virtual_types.add property
+ else if property isa MAttribute then
+ attributes.add property
+ else if property isa MInnerClass then
+ inner_classes.add property
+ else
+ abort
+ end
+ end
+
+ # Add each the specified property to the appropriate list.
+ fun add_all(properties: Collection[MProperty]) do
+ for p in properties do add(p)
+ end
+
+ # Sort each group with the specified comparator.
+ fun sort_groups(comparator: Comparator) do
+ for g in groups do comparator.sort(g)
+ end
+end
+
+# A Group of properties of the same kind.
+private class PropertyGroup[E: MProperty]
+ super Array[E]
+
+ # The title of the group, as displayed to the user.
+ var title: String
+end
+
# A MProperty page
class NitdocProperty
super NitdocPage
var intros = new Array[TplListElt]
var redefs = new Array[TplListElt]
- init do end
-
redef fun rendering do
addn "<div class='definition'>"
render_comment
# Add content wrapped in a <li> element
fun add_li(item: TplListItem) do elts.add item
- init do end
-
init with_classes(classes: Array[String]) do self.css_classes = classes
fun is_empty: Bool do return elts.is_empty
# CSS classes of the <li> element
var css_classes = new Array[String]
- init do end
-
init with_content(content: Streamable) do append(content)
init with_classes(content: Streamable, classes: Array[String]) do
end
end
- private fun generate_serialization_method(nclassdef: AClassdef)
+ fun generate_serialization_method(nclassdef: AClassdef)
do
var npropdefs = nclassdef.n_propdefs
end
# Add a constructor to the automated nclassdef
- private fun generate_deserialization_init(nclassdef: AClassdef)
+ fun generate_deserialization_init(nclassdef: AClassdef)
do
var npropdefs = nclassdef.n_propdefs
end
# Added to the abstract serialization service
- private fun generate_deserialization_method(nmodule: AModule, nclassdefs: Array[AStdClassdef])
+ fun generate_deserialization_method(nmodule: AModule, nclassdefs: Array[AStdClassdef])
do
var code = new Array[String]
# Check c_src is up-to-date
make -C ../c_src
-# Compile nitg
-time ../c_src/nitg nitg.nit
+# Compile nitc
+time ../c_src/nitg nitc.nit
# delete old c_src
rm -rf ../c_src
import semantize
private import parser::tables
import mixin
+import primitive_types
redef class ToolContext
# --discover-call-trace
init
do
- self.true_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, true)
- init_instance_primitive(self.true_instance)
- self.false_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, false)
- init_instance_primitive(self.false_instance)
+ if mainmodule.model.get_mclasses_by_name("Bool") != null then
+ self.true_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, true)
+ init_instance_primitive(self.true_instance)
+ self.false_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, false)
+ init_instance_primitive(self.false_instance)
+ end
self.null_instance = new PrimitiveInstance[nullable Object](mainmodule.model.null_type, null)
end
else if pname == "exit" then
exit(args[1].to_i)
abort
+ else if pname == "buffer_mode_full" then
+ return v.int_instance(sys.buffer_mode_full)
+ else if pname == "buffer_mode_line" then
+ return v.int_instance(sys.buffer_mode_line)
+ else if pname == "buffer_mode_none" then
+ return v.int_instance(sys.buffer_mode_none)
else if pname == "sys" then
return v.mainobj
else if cname == "Int" then
end
else if cname == "NativeFile" then
if pname == "native_stdout" then
- var instance = new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, sys.stdout)
+ var inst = new PrimitiveNativeFile.native_stdout
+ var instance = new PrimitiveInstance[PrimitiveNativeFile](mpropdef.mclassdef.mclass.mclass_type, inst)
v.init_instance_primitive(instance)
return instance
else if pname == "native_stdin" then
- var instance = new PrimitiveInstance[IStream](mpropdef.mclassdef.mclass.mclass_type, sys.stdin)
+ var inst = new PrimitiveNativeFile.native_stdin
+ var instance = new PrimitiveInstance[PrimitiveNativeFile](mpropdef.mclassdef.mclass.mclass_type, inst)
v.init_instance_primitive(instance)
return instance
else if pname == "native_stderr" then
- var instance = new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, sys.stderr)
+ var inst = new PrimitiveNativeFile.native_stderr
+ var instance = new PrimitiveInstance[PrimitiveNativeFile](mpropdef.mclassdef.mclass.mclass_type, inst)
v.init_instance_primitive(instance)
return instance
else if pname == "io_open_read" then
var a1 = args[1].val.as(Buffer)
- var instance = new PrimitiveInstance[IStream](mpropdef.mclassdef.mclass.mclass_type, new IFStream.open(a1.to_s))
+ var inst = new PrimitiveNativeFile.io_open_read(a1.to_s)
+ var instance = new PrimitiveInstance[PrimitiveNativeFile](mpropdef.mclassdef.mclass.mclass_type, inst)
v.init_instance_primitive(instance)
return instance
else if pname == "io_open_write" then
var a1 = args[1].val.as(Buffer)
- var instance = new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, new OFStream.open(a1.to_s))
+ var inst = new PrimitiveNativeFile.io_open_write(a1.to_s)
+ var instance = new PrimitiveInstance[PrimitiveNativeFile](mpropdef.mclassdef.mclass.mclass_type, inst)
v.init_instance_primitive(instance)
return instance
end
var recvval = args.first.val
if pname == "io_write" then
var a1 = args[1].val.as(Buffer)
- recvval.as(OStream).write(a1.substring(0, args[2].to_i).to_s)
- return args[2]
+ return v.int_instance(recvval.as(PrimitiveNativeFile).io_write(a1.to_cstring, args[2].to_i))
else if pname == "io_read" then
- var str = recvval.as(IStream).read(args[2].to_i)
var a1 = args[1].val.as(Buffer)
- new FlatBuffer.from(str).copy(0, str.length, a1.as(FlatBuffer), 0)
- return v.int_instance(str.length)
+ var ns = new NativeString(a1.length)
+ var len = recvval.as(PrimitiveNativeFile).io_read(ns, args[2].to_i)
+ a1.clear
+ a1.append(ns.to_s_with_length(len))
+ return v.int_instance(len)
+ else if pname == "flush" then
+ recvval.as(PrimitiveNativeFile).flush
+ return null
else if pname == "io_close" then
- recvval.as(IOS).close
- return v.int_instance(0)
- else if pname == "address_is_null" then
- return v.false_instance
+ return v.int_instance(recvval.as(PrimitiveNativeFile).io_close)
+ else if pname == "set_buffering_type" then
+ return v.int_instance(recvval.as(PrimitiveNativeFile).set_buffering_type(args[1].to_i, args[2].to_i))
end
else if pname == "calloc_array" then
var recvtype = args.first.mtype.as(MClassType)
else if pname == "errno" then
return v.int_instance(sys.errno)
else if pname == "address_is_null" then
+ var recv = args[0]
+ if recv isa PrimitiveInstance[PrimitiveNativeFile] then
+ return v.bool_instance(recv.val.address_is_null)
+ end
return v.false_instance
end
return v.error_instance
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# This file is free software, which comes along with NIT. This software is
+# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. You can modify it is you want, provided this header
+# is kept unaltered, and a notification of the changes is added.
+# You are allowed to redistribute it and sell it, alone or is a part of
+# another product.
+
+# Encapsulates all primitive data types of nit
+#
+# Ensures that the use in the interpreter is independant of the
+# underlying implementation and that the services are semantically correct.
+module primitive_types
+
+intrude import standard::file
+
+# Wrapper for `NativeFile`
+class PrimitiveNativeFile
+
+ var file: FStream
+
+ init native_stdin do
+ file = new IFStream.from_fd(0)
+ end
+
+ init native_stdout do
+ file = new OFStream.from_fd(1)
+ end
+
+ init native_stderr do
+ file = new OFStream.from_fd(2)
+ end
+
+ init io_open_read(path: String) do
+ file = new IFStream.open(path.to_s)
+ end
+
+ init io_open_write(path: String) do
+ file = new OFStream.open(path.to_s)
+ end
+
+ fun address_is_null: Bool do return file._file.address_is_null
+
+ fun io_read(buf: NativeString, len: Int): Int do return file._file.io_read(buf, len)
+
+ fun io_write(buf: NativeString, len: Int): Int do return file._file.io_write(buf, len)
+
+ fun io_close: Int do return file._file.io_close
+
+ fun fileno: Int do return file._file.fileno
+
+ fun flush: Int do return file._file.flush
+
+ fun set_buffering_type(size, mode: Int): Int do
+ return file._file.set_buffering_type(size, mode)
+ 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.
+
+# Collect metrics about detected variances constraints on formal types.
+#
+# In some OO-language that feature safe invariant generics by default,
+# formal parameter types can annotated to be usable in covariant and contravariant positions.
+# The price to pay is that the usage of formal parameter types in the class has constraints:
+#
+# * covariant-annotated formal types cannot be used in parameters or in attributes
+# * contravariant-annotated formal types cannot be used in return or in attributes
+#
+# This module provide a backward analysis that infers the possible variance annotations
+# of formal types in Nit programs by identifying the existing constraints on the usage of those formal type.
+#
+# It collects the types used in the signatures of properties then propagates constraints between types.
+module detect_variance_constraints
+
+import model
+import metrics_base
+
+redef class ToolContext
+ # --detect-variance-constraints
+ var opt_detect_variance_constraints = new OptionBool("Detect the definition-site variance constraints on formal parameters", "--detect-variance-constraints")
+
+ # The DetectVarianceConstraints phase
+ var detect_variance_constraints_phase: Phase = new DetectVarianceConstraintsPhase(self, null)
+end
+
+private class DetectVarianceConstraintsPhase
+ super Phase
+
+ init
+ do
+ toolcontext.option_context.add_option(toolcontext.opt_detect_variance_constraints)
+ end
+
+ redef fun process_mainmodule(mainmodule, given_mmodules)
+ do
+ if not toolcontext.opt_detect_variance_constraints.value and not toolcontext.opt_all.value then return
+
+ print "--- Metrics of covariance detection ---"
+
+ var k = new DetectVarianceConstraints
+ k.collect(mainmodule)
+
+ print "-- Generic classes --"
+ k.cpt_class.print_elements(10)
+ print " total classes: {k.cpt_class.sum}"
+ print " total formal parameters: {k.pts.length}"
+
+ k.propagate
+
+ print "-- Including `private` properties --"
+ k.print_stats
+
+ k = new DetectVarianceConstraints
+ k.exclude_private = true
+ k.collect(mainmodule)
+
+ k.propagate
+
+ print "-- Excluding `private` properties --"
+ k.print_stats
+ end
+end
+
+redef class MParameterType
+ # The fully-qualified name of the formal parameter.
+ fun full_name: String do return "{mclass.full_name}::{name}"
+end
+
+# A specific analysis that detects the variance constraints of formal parameters.
+#
+# The client has 3 steps to do:
+#
+# * call `collect` to initialize the attributes.
+# * call `propagate` to propagate the variance constraints.
+# * call `print_stats` to print the results.
+class DetectVarianceConstraints
+ # Collect all types used in covariant and contravariant positions.
+ #
+ # The collect visits all classes and properties of `mainmodule` and its imported modules.
+ #
+ # After the visit, the attributes of `self` are filled.
+ fun collect(mainmodule: MModule)
+ do
+ for m in mainmodule.in_importation.greaters do
+ for cd in m.mclassdefs do
+ if cd.is_intro then
+ pts.add_all(cd.mclass.mparameters)
+ var a = cd.mclass.arity
+ if a == 0 then
+ cpt_class.inc("non generic")
+ else if a == 1 then
+ cpt_class.inc("with 1 formal type parameter")
+ else
+ cpt_class.inc("with {a} formal type parameters")
+ end
+ end
+ for t in cd.supertypes do
+ # Supertype (covariant)
+ if t.need_anchor then covar_classes.add(t)
+ end
+ for pd in cd.mpropdefs do
+ if exclude_private and pd.mproperty.visibility <= private_visibility then continue
+ if pd isa MMethodDef then
+ # Parameters (contravariant)
+ for p in pd.msignature.mparameters do
+ var t = p.mtype.as_notnullable
+ if not t.need_anchor then
+ # OK
+ else if t isa MParameterType then
+ contravar_pt.add(t)
+ else if t isa MVirtualType then
+ # TODO?
+ else if t isa MClassType then
+ contravar_classes.add(t)
+ else
+ abort
+ end
+ end
+ # Return (covariant)
+ var t = pd.msignature.return_mtype
+ if t != null and t.need_anchor then
+ t = t.as_notnullable
+ if t isa MParameterType then
+ covar_pt.add(t)
+ else if t isa MVirtualType then
+ # TODO?
+ else if t isa MClassType then
+ covar_classes.add(t)
+ else
+ abort
+ end
+ end
+ else if pd isa MAttributeDef then
+ # Attribute (invariant)
+ var t = pd.static_mtype
+ if t != null and t.need_anchor then
+ t = t.as_notnullable
+ if t isa MParameterType then
+ covar_pt.add t
+ contravar_pt.add t
+ else if t isa MVirtualType then
+ # TODO?
+ else if t isa MClassType then
+ covar_classes.add(t)
+ contravar_classes.add(t)
+ else
+ abort
+ end
+ end
+ else if pd isa MVirtualTypeDef then
+ # Virtual type bound (covariant)
+ var t = pd.bound
+ if t != null and t.need_anchor then
+ t = t.as_notnullable
+ if t isa MParameterType then
+ covar_pt.add t
+ else if t isa MVirtualType then
+ # TODO?
+ else if t isa MClassType then
+ covar_classes.add(t)
+ else
+ abort
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ # The set of all collected formal parameters
+ var pts = new HashSet[MParameterType]
+
+ # The set of generic types found in a covariant (and invariant) position
+ var covar_classes = new HashSet[MClassType]
+
+ # The set of formal parameters found in a covariant (and invariant) position
+ var covar_pt = new HashSet[MParameterType]
+
+ # The set of generic types found in a contravariant (and invariant) position
+ var contravar_classes = new HashSet[MClassType]
+
+ # The set of formal parameters found in a contravariant (and invariant) position
+ var contravar_pt = new HashSet[MParameterType]
+
+ # Classes by number of formal parameters
+ var cpt_class = new Counter[String]
+
+ # Does the collect exclude private properties?
+ # Default is `false`
+ var exclude_private = false
+
+ # Propagate the variance constraints on `covar_classes`, `covar_pt`, `contravar_classes` and `contravar_pt`
+ #
+ # The algorithm uses a fixed-point approach on the covariance/contravariance rules.
+ fun propagate
+ do
+ # Classes to add to the `covar_classes` set at the end of an iteration
+ var new_covar = new Array[MClassType]
+ # Classes to add to the `contravar_classes` set at the end of an iteration
+ var new_contravar = new Array[MClassType]
+ # Does a modification occurred, so that another iteration is needed?
+ var dirty = true
+ # Total number of iterations
+ var cpt = 0
+
+ while dirty do
+ cpt += 1
+ dirty = false
+ new_covar.clear
+ new_contravar.clear
+
+ # Process the generic types in a covariant position
+ for c in covar_classes do for i in [0..c.mclass.arity[ do
+ # The type used in the argument
+ var ta = c.arguments[i].as_notnullable
+ # The associated formal parameter
+ var tp = c.mclass.mparameters[i]
+
+ if not ta.need_anchor then
+ # Nothing to do
+ else if ta isa MParameterType then
+ # COVAR * COVAR = COVAR
+ if covar_pt.has(tp) and not covar_pt.has(ta) then
+ covar_pt.add(ta)
+ dirty = true
+ end
+ # COVAR * CONTRAVAR = CONTRAVAR
+ if contravar_pt.has(tp) and not contravar_pt.has(ta) then
+ contravar_pt.add(ta)
+ dirty = true
+ end
+ else if ta isa MVirtualType then
+ # TODO?
+ else if ta isa MClassType then
+ # COVAR * COVAR = COVAR
+ if covar_pt.has(tp) and not covar_classes.has(ta) then
+ new_covar.add ta
+ dirty = true
+ end
+ # COVAR * CONTRAVAR = CONTRAVAR
+ if contravar_pt.has(tp) and not contravar_classes.has(ta) then
+ new_contravar.add ta
+ dirty = true
+ end
+ end
+ end
+
+ # Process the generic types in a contravariant position
+ for c in contravar_classes do for i in [0..c.mclass.arity[ do
+ # The type used in the argument
+ var ta = c.arguments[i].as_notnullable
+ # The associated formal parameter
+ var tp = c.mclass.mparameters[i]
+
+ if not ta.need_anchor then
+ # Nothing to do
+ else if ta isa MParameterType then
+ # CONTRAVAR * CONTRAVAR = COVAR
+ if contravar_pt.has(tp) and not covar_pt.has(ta) then
+ covar_pt.add(ta)
+ dirty = true
+ end
+ # CONTRAVAR * COVAR = CONTRAVAR
+ if covar_pt.has(tp) and not contravar_pt.has(ta) then
+ contravar_pt.add(ta)
+ dirty = true
+ end
+ else if ta isa MVirtualType then
+ # TODO?
+ else if ta isa MClassType then
+ # CONTRAVAR * CONTRAVAR = COVAR
+ if contravar_pt.has(tp) and not covar_classes.has(ta) then
+ new_covar.add ta
+ dirty = true
+ end
+ # CONTRAVAR * COVAR = CONTRAVAR
+ if covar_pt.has(tp) and not contravar_classes.has(ta) then
+ new_contravar.add ta
+ dirty = true
+ end
+ end
+ end
+
+ covar_classes.add_all(new_covar)
+ contravar_classes.add_all(new_contravar)
+ end
+ end
+
+ # Print the final stats on the screen
+ fun print_stats
+ do
+ var nb_cov = 0
+ var nb_con = 0
+ var nb_inv = 0
+ var nb_biv = 0
+
+ for pt in pts do
+ if covar_pt.has(pt) then
+ if contravar_pt.has(pt) then
+ nb_inv += 1
+ else
+ nb_cov += 1
+ #print "covar: {pt.full_name}"
+ end
+ else
+ if contravar_pt.has(pt) then
+ nb_con += 1
+ #print "contravar: {pt.full_name}"
+ else
+ nb_biv += 1
+ #print "bivar: {pt.full_name}"
+ end
+ end
+ end
+
+ print " covariants: {nb_cov} ({div(nb_cov*100, pts.length)}%)"
+ print " contravariants: {nb_con} ({div(nb_con*100, pts.length)}%)"
+ print " bivariants: {nb_biv} ({div(nb_biv*100, pts.length)}%)"
+ print " invariants: {nb_inv} ({div(nb_inv*100, pts.length)}%)"
+ print " total: {pts.length}"
+ end
+end
import tables_metrics
import poset_metrics
import ast_metrics
+import detect_variance_constraints
#!/bin/sh
-# Regeneration of c_src from the current nitg
+# Regeneration of c_src from the current nitc
rm -r ../c_src
-./nitg nith.nit --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
do
var cla = self.model.get_mclasses_by_name(name)
if cla == null then
- if name == "Bool" then
+ if name == "Bool" and self.model.get_mclasses_by_name("Object") != null then
+ # Bool is injected because it is needed by engine to code the result
+ # of the implicit casts.
var c = new MClass(self, name, null, enum_kind, public_visibility)
var cladef = new MClassDef(self, c.mclass_type, new Location(null, 0,0,0,0))
+ cladef.set_supertypes([object_type])
+ cladef.add_in_hierarchy
return c
end
print("Fatal Error: no primitive class {name}")
--- /dev/null
+#!/bin/bash
+# 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.
+
+# nitc all
+# fully build, time and check nitc
+
+rm nitc nitc_? hello_world 2>/dev/null
+set -x
+set -e
+make -C ../c_src
+sh git-gen-version.sh
+time ../c_src/nitg nitc.nit -v -o nitc_0
+time ./nitc_0 nitc.nit -v "$@" -o nitc_2
+cp nitc_2 nitc
+time ./nitc_2 nitc.nit -v "$@" -o nitc_3
+time ./nitc_3 nitc.nit -v "$@" -o nitc_4
+./nitc_4 ../examples/hello_world.nit "$@" -o hello_world
+./hello_world
+
+# save the last one; may be useful...
+cp ./nitc_4 nitc.good
+++ /dev/null
-#!/bin/bash
-rm nitg nitg_? hello_world 2>/dev/null
-set -x
-set -e
-make -C ../c_src
-sh git-gen-version.sh
-time ../c_src/nitg nitg.nit -v -o nitg_0
-time ./nitg_0 nitg.nit -v "$@" -o nitg_2
-cp nitg_2 nitg
-time ./nitg_2 nitg.nit -v "$@" -o nitg_3
-time ./nitg_3 nitg.nit -v "$@" -o nitg_4
-./nitg_4 ../examples/hello_world.nit "$@" -o hello_world
-./hello_world
-
-# save the last one; may be useful...
-cp ./nitg_4 nitg.good
-
# See the License for the specific language governing permissions and
# limitations under the License.
-# A global Nit compiler
-module nitg
+# A Nit compiler
+module nitc
import frontend
import compiler
while not pipe.eof do
var l = pipe.read_line
if l == "" then break # last line
- l = l.substring(0,l.length-1) # strip last oef
files.add l
end
pipe.close
pager.render
end
- private fun props_fulldoc(pager: Pager, raw_mprops: List[MProperty]) do
+ fun props_fulldoc(pager: Pager, raw_mprops: List[MProperty]) do
# group by module
var cats = new HashMap[MModule, Array[MProperty]]
for mprop in raw_mprops do
end
- private fun visit_expr_cast(node: ANode, nexpr: AExpr, ntype: AType): nullable MType
+ fun visit_expr_cast(node: ANode, nexpr: AExpr, ntype: AType): nullable MType
do
var sub = visit_expr(nexpr)
if sub == null then return null # Forward error
-PROGS=*.nit ../examples/*.nit ../examples/leapfrog/leapfrog.nit ../examples/shoot/shoot_logic.nit ../contrib/pep8analysis/src/pep8analysis ../contrib/nitiwiki/src/nitiwiki ../lib/*.nit ../src/nitdoc.nit ../src/test_parser.nit ../src/nit.nit ../src/nitmetrics.nit ../src/nitg.nit
+PROGS=*.nit ../examples/*.nit ../examples/leapfrog/leapfrog.nit ../examples/shoot/shoot_logic.nit ../contrib/pep8analysis/src/pep8analysis ../contrib/nitiwiki/src/nitiwiki ../lib/*.nit ../src/nitdoc.nit ../src/test_parser.nit ../src/nit.nit ../src/nitmetrics.nit ../src/nitc.nit
all: niti nitg-g nitg-s
The `$os.skip` file describes tests that are to be skipped completely on the given OS.
Usually it is because of OS specific libraries.
+The `turing.skip` file describes tests that are to be skipped completely on the Turing cluster doing continuous testing over MPI.
+Usually it is because of an unavailable library or a large work which would not benefit from parallelization.
+
These `*.skip` files contain a list of patterns that will be used against test names.
A single substring can thus be used to skip a full family of tests.
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2004-2008 Jean Privat <jean@pryen.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 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.
+# Test classes for variance analysis
+
+import end
+
+interface Object
+end
+
+# covariant
+class A[T]
+ fun foo: T is abstract
+end
+
+# contravariant
+class B[T]
+ fun foo(t: T) is abstract
+end
+
+# invariant
+class C[T]
+ fun foo(t: T) is abstract
+
+ fun bar: T is abstract
+end
+
+# bivariant
+class D[T]
+ fun foo(x: Object) is abstract
+end
+
+# bivariant, the contravariant position of this complex expression
+# reverse the variance, but contra*bivar = bivar
+class E[T]
+ super D[T]
+
+ fun bar(x: E[D[C[T]]]) is abstract
+end
+
+# Covariant, the contravariant position reverse the variance,
+# and the variance of A[B[T]] is contravariance
+class F[T]
+ super D[T]
+
+ fun bar(x: A[B[T]]) is abstract
+end
+
+# Can be annotated bivariant
+class G[T]
+ super D[T]
+
+ fun bar: A[D[E[T]]] is abstract
+end
+
+# invariant
+class H[T]
+ fun bar: A[B[C[T]]] is abstract
+end
+
+# Bivariant
+class Src[T]
+ fun bar (x: Dest[T]) is abstract
+end
+
+# Bivariant
+class Dest[T]
+ fun bar (x: Src[T]) is abstract
+end
+
+# Contravariant
+class Src2[T]
+ super B[T]
+
+ fun bar(x: Src[B[T]]) is abstract
+end
+
+# Bivariant
+class Cycle2[T]
+ fun foo(x: Cycle2[T]): Cycle2[T] is abstract
+end
+
+# Bivariant
+class Cycle3[T]
+ fun foo(x: Cycle2[T]): C[D[T]] is abstract
+end
module_1.nit -d $WRITE
+base_attr_nullable.nit -d $WRITE
+--private base_attr_nullable.nit -d $WRITE
-nitg
+nitc
nitdoc
nitlight
neo_doxygen_dump
neo_doxygen_file_compound
neo_doxygen_graph_empty_project
neo_doxygen_member_resolve_introducer
+test_docdown
+nith
+nit_pretty
+nitmetrics
nitvm_args1
nitvm_args3
nitc_args1
-nitg_args1
-nitg_args3
-nitg_args5
-nitg_args6
-nitg_args8
+nitc_args3
+nitc_args5
+nitc_args6
+nitc_args8
nitunit_args
test_docdown_args
pep8analysis
--no-colors --all --csv base_simple3.nit -d $WRITE
+--detect-variance-constraints base_ft_detect_variance_constraints.nit
nitvm_args1
nitvm_args3
nitc_args1
-nitg_args1
-nitg_args3
-nitg_args5
-nitg_args6
+nitc_args3
+nitc_args5
+nitc_args6
+nitc_args8
test_markdown_args1
pep8analysis
test_android_platform
-Usage: nitg [OPTION]... file.nit...
+Usage: nitc [OPTION]... file.nit...
Compiles Nit programs.
Use --help for help
--- /dev/null
+class_base_attr_nullable__Bar.html
+class_base_attr_nullable__Bool.html
+class_base_attr_nullable__Foo.html
+class_base_attr_nullable__Int.html
+class_base_attr_nullable__Integer.html
+class_base_attr_nullable__Object.html
+class_base_attr_nullable__Sys.html
+css/
+dep_class_base_attr_nullable__Bar.dot
+dep_class_base_attr_nullable__Bar.map
+dep_class_base_attr_nullable__Bar.png
+dep_class_base_attr_nullable__Bar.s.dot
+dep_class_base_attr_nullable__Bool.dot
+dep_class_base_attr_nullable__Bool.map
+dep_class_base_attr_nullable__Bool.png
+dep_class_base_attr_nullable__Bool.s.dot
+dep_class_base_attr_nullable__Foo.dot
+dep_class_base_attr_nullable__Foo.map
+dep_class_base_attr_nullable__Foo.png
+dep_class_base_attr_nullable__Foo.s.dot
+dep_class_base_attr_nullable__Int.dot
+dep_class_base_attr_nullable__Int.map
+dep_class_base_attr_nullable__Int.png
+dep_class_base_attr_nullable__Int.s.dot
+dep_class_base_attr_nullable__Integer.dot
+dep_class_base_attr_nullable__Integer.map
+dep_class_base_attr_nullable__Integer.png
+dep_class_base_attr_nullable__Integer.s.dot
+dep_class_base_attr_nullable__Object.dot
+dep_class_base_attr_nullable__Object.map
+dep_class_base_attr_nullable__Object.png
+dep_class_base_attr_nullable__Object.s.dot
+dep_class_base_attr_nullable__Sys.dot
+dep_class_base_attr_nullable__Sys.map
+dep_class_base_attr_nullable__Sys.png
+dep_class_base_attr_nullable__Sys.s.dot
+dep_module_base_attr_nullable__base_attr_nullable__base_attr_nullable.dot
+dep_module_base_attr_nullable__base_attr_nullable__base_attr_nullable.map
+dep_module_base_attr_nullable__base_attr_nullable__base_attr_nullable.png
+dep_module_base_attr_nullable__base_attr_nullable__base_attr_nullable.s.dot
+group_base_attr_nullable__base_attr_nullable.html
+index.html
+js/
+less/
+module_base_attr_nullable__base_attr_nullable__base_attr_nullable.html
+property_base_attr_nullable__Bar__a3.html
+property_base_attr_nullable__Foo__a1.html
+property_base_attr_nullable__Foo__a2.html
+property_base_attr_nullable__Foo__nop.html
+property_base_attr_nullable__Foo__run.html
+property_base_attr_nullable__Foo__run_other.html
+property_base_attr_nullable__Int___43d.html
+property_base_attr_nullable__Int__output.html
+property_base_attr_nullable__Integer__init.html
+property_base_attr_nullable__Integer__output.html
+property_base_attr_nullable__Integer__val.html
+property_base_attr_nullable__Object__init.html
+property_base_attr_nullable__Sys__main.html
+quicksearch-list.js
+resources/
+search.html
+vendors/
--- /dev/null
+class_base_attr_nullable__Bar.html
+class_base_attr_nullable__Bool.html
+class_base_attr_nullable__Foo.html
+class_base_attr_nullable__Int.html
+class_base_attr_nullable__Integer.html
+class_base_attr_nullable__Object.html
+class_base_attr_nullable__Sys.html
+css/
+dep_class_base_attr_nullable__Bar.dot
+dep_class_base_attr_nullable__Bar.map
+dep_class_base_attr_nullable__Bar.png
+dep_class_base_attr_nullable__Bar.s.dot
+dep_class_base_attr_nullable__Bool.dot
+dep_class_base_attr_nullable__Bool.map
+dep_class_base_attr_nullable__Bool.png
+dep_class_base_attr_nullable__Bool.s.dot
+dep_class_base_attr_nullable__Foo.dot
+dep_class_base_attr_nullable__Foo.map
+dep_class_base_attr_nullable__Foo.png
+dep_class_base_attr_nullable__Foo.s.dot
+dep_class_base_attr_nullable__Int.dot
+dep_class_base_attr_nullable__Int.map
+dep_class_base_attr_nullable__Int.png
+dep_class_base_attr_nullable__Int.s.dot
+dep_class_base_attr_nullable__Integer.dot
+dep_class_base_attr_nullable__Integer.map
+dep_class_base_attr_nullable__Integer.png
+dep_class_base_attr_nullable__Integer.s.dot
+dep_class_base_attr_nullable__Object.dot
+dep_class_base_attr_nullable__Object.map
+dep_class_base_attr_nullable__Object.png
+dep_class_base_attr_nullable__Object.s.dot
+dep_class_base_attr_nullable__Sys.dot
+dep_class_base_attr_nullable__Sys.map
+dep_class_base_attr_nullable__Sys.png
+dep_class_base_attr_nullable__Sys.s.dot
+dep_module_base_attr_nullable__base_attr_nullable__base_attr_nullable.dot
+dep_module_base_attr_nullable__base_attr_nullable__base_attr_nullable.map
+dep_module_base_attr_nullable__base_attr_nullable__base_attr_nullable.png
+dep_module_base_attr_nullable__base_attr_nullable__base_attr_nullable.s.dot
+group_base_attr_nullable__base_attr_nullable.html
+index.html
+js/
+less/
+module_base_attr_nullable__base_attr_nullable__base_attr_nullable.html
+property_base_attr_nullable__Bar___a3.html
+property_base_attr_nullable__Bar__a3.html
+property_base_attr_nullable__Bar__a3_61d.html
+property_base_attr_nullable__Foo___a1.html
+property_base_attr_nullable__Foo___a2.html
+property_base_attr_nullable__Foo__a1.html
+property_base_attr_nullable__Foo__a1_61d.html
+property_base_attr_nullable__Foo__a2.html
+property_base_attr_nullable__Foo__a2_61d.html
+property_base_attr_nullable__Foo__nop.html
+property_base_attr_nullable__Foo__run.html
+property_base_attr_nullable__Foo__run_other.html
+property_base_attr_nullable__Int___43d.html
+property_base_attr_nullable__Int__output.html
+property_base_attr_nullable__Integer___val.html
+property_base_attr_nullable__Integer__init.html
+property_base_attr_nullable__Integer__output.html
+property_base_attr_nullable__Integer__val.html
+property_base_attr_nullable__Integer__val_61d.html
+property_base_attr_nullable__Object__init.html
+property_base_attr_nullable__Sys__main.html
+quicksearch-list.js
+resources/
+search.html
+vendors/
-Usage: nitg [OPTION]... file.nit...
+Usage: nitc [OPTION]... file.nit...
Compiles Nit programs.
Use --help for help
intern: 1 (1.81%)
Object: 1 (1.81%)
Bool: 1 (1.81%)
+--- Metrics of covariance detection ---
+-- Generic classes --
+ list:
+ non generic: 7 (100.00%)
+ total classes: 7
+ total formal parameters: 0
+-- Including `private` properties --
+ covariants: 0 (na%)
+ contravariants: 0 (na%)
+ bivariants: 0 (na%)
+ invariants: 0 (na%)
+ total: 0
+-- Excluding `private` properties --
+ covariants: 0 (na%)
+ contravariants: 0 (na%)
+ bivariants: 0 (na%)
+ invariants: 0 (na%)
+ total: 0
--- Metrics of refinement usage ---
Number of modules: 1
--- /dev/null
+*** METRICS ***
+--- Metrics of covariance detection ---
+-- Generic classes --
+ list:
+ with 1 formal type parameter: 13 (92.85%)
+ non generic: 1 (7.14%)
+ total classes: 14
+ total formal parameters: 13
+-- Including `private` properties --
+ covariants: 2 (15.38%)
+ contravariants: 2 (15.38%)
+ bivariants: 7 (53.84%)
+ invariants: 2 (15.38%)
+ total: 13
+-- Excluding `private` properties --
+ covariants: 2 (15.38%)
+ contravariants: 2 (15.38%)
+ bivariants: 7 (53.84%)
+ invariants: 2 (15.38%)
+ total: 13
redef class Deserializer
redef fun deserialize_class(name)
do
+ if name == "Array[Object]" then return new Array[Object].from_deserializer(self)
if name == "Array[nullable Object]" then return new Array[nullable Object].from_deserializer(self)
if name == "Array[Serializable]" then return new Array[Serializable].from_deserializer(self)
if name == "Array[String]" then return new Array[String].from_deserializer(self)
- if name == "Array[Object]" then return new Array[Object].from_deserializer(self)
return super
end
end
A hello world!
C hello world!
-B hello world!
-D hello world!
+B hello world!D hello world!
\ No newline at end of file
-777
From Nit
+777
11
12346
d
e
f
-e
-f
remove: a
remove: b
remove: c
remove: d
+e
+f
Created in Nit
-Also created in Nit
Created in Java
+Also created in Nit
Also created in Java
-777
-asdf
From Nit
+777
11
12346
+asdf
--- /dev/null
+Error: Opening file at 'donotcreate.bing' failed with 'No such file or directory'
+Error: Opening file at 'donotcreate.bing' failed with 'No such file or directory'
printn(f.read(10))
printn("|")
printn(f.read_all)
-
# This fil|e is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2004-2008 Jean Privat <jean@pryen.org>
Hello World !!
-
Hello World !!
-
-
+Compilation des classes Java ...
+Initialisation de la JVM ...
+---------------------Test 1----------------------
From java, pushing premier
From java, pushing deuxi?me
From java, pushing troisi?me
From java, popping premier
-From java, popping deuxi?me
-From java, popping troisi?me
-Compilation des classes Java ...
-Initialisation de la JVM ...
----------------------Test 1----------------------
premier
+From java, popping deuxi?me
deuxième
+From java, popping troisi?me
troisième
--------------------Test 2---------------------
true
-Runtime error: Assert failed (alt/test_sqlite3_nity_alt1.nit:27)
-unable to open database file
+UNDEFINED
-Runtime error: Assert failed (alt/test_sqlite3_nity_alt2.nit:39)
-SQL logic error or missing database
+UNDEFINED
redef fun worst_heuristic_cost do return 100
end
-fun print_path(path: nullable Path[NamedNode]) do if path == null then
+fun print_path(path: nullable AStarPath[NamedNode]) do if path == null then
print "null path"
else
var names = new Array[String]
# See the License for the specific language governing permissions and
# limitations under the License.
-import stream
+import file
-var fd_in = new FDIStream(0)
-var fd_out = new FDOStream(1)
-var fd_err = new FDOStream(2)
+var fd_in = new IFStream.from_fd(0)
+var fd_out = new OFStream.from_fd(1)
+var fd_err = new OFStream.from_fd(2)
fd_out.write("Hello\n")
var s = fd_in.read_line
fd_out.write(s)
+fd_out.write("\n")
fd_err.write("World\n")
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+var ifs = new IFStream.open("donotcreate.bing")
+
+var s = ifs.read_all
+
+ifs.close
+
+if ifs.last_error != null then print ifs.last_error.as(not null)
+
+ifs.reopen
+
+s = ifs.read_all
+
+ifs.close
+
+if ifs.last_error != null then print ifs.last_error.as(not null)
p2 = new IProcess( "sleep", "0.1" )
p3 = new IProcess( "sleep", "0.4" )
-var order = new Array[FDStream]
+var order = new Array[FStream]
var streams = [p1.stream_in, p2.stream_in, p3.stream_in]
while not streams.is_empty do
if s == null then continue # may have been interrupted
order.add( s )
- streams.remove( s.as(FDIStream ) )
+ streams.remove( s.as(IFStream ) )
end
print order[0] == p2.stream_in
shopt -s nullglob
JAVA_HOME=$(dirname $(dirname $(readlink -f $(which javac))))
-paths=`echo $JAVA_HOME/jre/lib/*/{client,server}/`
-paths=($paths)
-JNI_LIB_PATH=${paths[0]}
+paths=`echo $JAVA_HOME/jre/lib/*/{client,server}/libjvm.so`
+paths=($paths)
+JNI_LIB_PATH=`dirname ${paths[0]}`
shopt -u nullglob
outdir="out"
-o option Pass option to the engine
-v Verbose (show tests steps)
-h This help
---engine Use a specific engine (default=nitg)
+--engine Use a specific engine (default=nitc)
--noskip Do not skip a test even if the .skip file matches
--outdir Use a specific output folder (default=out/)
--compdir Use a specific temporary compilation folder (default=.nit_compile)
verbose=false
isnode=false
stop=false
-engine=nitg
+engine=nitc
noskip=
savdirs=
while [ $stop = false ]; do
enginebinname=$engine
isinterpret=
case $engine in
- nitg)
+ nitc|nitg)
engine=nitg-s;
- enginebinname=nitg;
+ enginebinname=nitc;
OPT="--separate $OPT --compile-dir $compdir"
savdirs="sav/nitg-common/"
;;
- nitg-s)
- enginebinname=nitg;
+ nitcs|nitg-s)
+ enginebinname=nitc;
OPT="--separate $OPT --compile-dir $compdir"
savdirs="sav/nitg-common/"
;;
- nitg-e)
- enginebinname=nitg;
+ nitce|nitg-e)
+ enginebinname=nitc;
OPT="--erasure $OPT --compile-dir $compdir"
savdirs="sav/nitg-common/"
;;
- nitg-sg)
- enginebinname=nitg;
+ nitcsg|nitg-sg)
+ enginebinname=nitc;
OPT="--semi-global $OPT --compile-dir $compdir"
savdirs="sav/nitg-common/"
;;
- nitg-g)
- enginebinname=nitg;
+ nitcg|nitg-g)
+ enginebinname=nitc;
OPT="--global $OPT --compile-dir $compdir"
savdirs="sav/nitg-common/"
;;
savdirs="sav/niti/"
;;
emscripten)
- enginebinname=nitg
+ enginebinname=nitc
OPT="-m emscripten_nodejs.nit --semi-global $OPT --compile-dir $compdir"
savdirs="sav/nitg-sg/"
;;
--- /dev/null
+nitg
+nitx
+_linux
+android
+gles
+shoot
+curl
+neo
+gtk
+nitcorn
+ffi_objc
+mpi
+pnacl
+emscipten
+nodejs
+nitunit
+test_annot_c_compiler
+base_very
+test_jvm
+test_glsl_validation