From: Jean Privat Date: Thu, 31 Mar 2016 17:43:26 +0000 (-0400) Subject: Merge remote-tracking branch 'origin/master' into init_auto X-Git-Url: http://nitlanguage.org?hp=d12eadf3421185e2bedd5ed50e083e301c6822c4 Merge remote-tracking branch 'origin/master' into init_auto --- diff --git a/benchmarks/bench_common.sh b/benchmarks/bench_common.sh index 207edd0..dfdbc6b 100644 --- a/benchmarks/bench_common.sh +++ b/benchmarks/bench_common.sh @@ -13,6 +13,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Global variables + +# Number of times a command must be run with bench_command +count=1 + +# User time limit (in second) before a command is aborted +usertimelimit=120 + # Common functions for all the bench scripts # Run a single command multiple time and store the execution times @@ -41,21 +49,27 @@ function bench_command() # Execute the commands $count times for i in `seq 1 "$count"`; do - /usr/bin/time -f "%U" -o "$timeout" -a "$@" > $outputopts 2>&1 || { failed=true; die "$1: failed"; } + ( + ulimit -t "$usertimelimit" 2> /dev/null + /usr/bin/time -f "%U" -o "$timeout" -a "$@" > $outputopts 2>&1 + ) || { err=$?; failed=true; die "$1: failed with $err"; } echo -n "$i. " tail -n 1 "$timeout" + test -n "$failed" && break done line=`compute_stats "$timeout"` echo "$line ($res)" echo $line >> "$res" - test -z "$xml" && return - echo >>"$xml" "" - if test -n "$failed"; then - echo >>"$xml" "" + if test -n "$xml"; then + echo >>"$xml" "" + if test -n "$failed"; then + echo >>"$xml" "" + fi + echo >>"$xml" "" fi - echo >>"$xml" "" + test -z "$failed" } # Run a simble command witout storing the execution time @@ -86,7 +100,7 @@ function skip_test() return 0 fi if test -n "$html"; then - echo >>"$html" "

$1

" + echo >>"$html" "

$1

" fi echo "*" echo "* $1 *****" @@ -99,4 +113,5 @@ function die() { echo >&2 "error: $*" died=1 + return 1 } diff --git a/benchmarks/languages/Makefile b/benchmarks/languages/Makefile new file mode 100644 index 0000000..ca35e94 --- /dev/null +++ b/benchmarks/languages/Makefile @@ -0,0 +1,5 @@ +all: + ./bench_languages.sh all + +check: + ./bench_languages.sh --fast bench_meth diff --git a/benchmarks/languages/bench_base.nit b/benchmarks/languages/bench_base.nit deleted file mode 100644 index 9f79133..0000000 --- a/benchmarks/languages/bench_base.nit +++ /dev/null @@ -1,483 +0,0 @@ -#!/usr/bin/env nit - -# Microbenchmak generation for multiple language -# Just a quick an dirty Nit script file :) - -# This benchmark focuses on effects of the hierarchy dept -# on the typetest performances - -# class Root -# class Klass[E] super Root -# class C1...CX super Root -# Klass[CX] isa Klass[C1] - -class Klass - var id: Int - var supers = new Array[Klass] - var all_supers = new HashSet[Klass] - redef fun to_s - do - return "C{id}" - end -end - -class Generator - - var classes = new Array[Klass] - - var dept writable = 5 - var loops writable = 50000 - var middle writable = 0 - var dry writable = false - var check writable = false - - fun genhier - do - var s: nullable Klass = null - for d in [1..dept] do - var c = new Klass(d) - - classes.add(c) - c.all_supers.add(c) - if s != null then - c.supers.add(s) - c.all_supers.add_all(s.all_supers) - end - s = c - end - middle = (dept + 1) / 2 - end - - var file: nullable FileWriter = null - fun write(str: String) - do - file.write(str) - file.write("\n") - end - - fun initnit(res: Array[String]) is abstract - fun testnit: String do return "true" - - fun writenit(dir: String, name: String) - do - dir = "{dir}/nit" - dir.mkdir - file = new FileWriter.open("{dir}/{name}.nit") - - write "class Root\n\tfun id: Int do return 0\nend" - for c in classes do - write "class {c}[E]" - if c.supers.is_empty then - write "\tsuper Root" - else for s in c.supers do - write "\tsuper {s}[E]" - end - write "\tredef fun id do return {c.id}" - write "end" - end - - write "fun test(a,b: Root, loops, start: Int)" - write "do" - write "var x = start" - write "var i = 0" - write "while i < loops do" - write "\tvar j = 0" - write "\twhile j < loops do" - var test = "true" - if not dry then test = testnit - write "\t\tif {test} and x >= 0 then" - if check then write "\t\tx += 1" - write "\telse" - write "\t\t\tx = x - 1 + i - j" - write "\t\t\ta = b" - write "\t\tend" - write "\t\tj += 1" - write "\tend" - write "\ti += 1" - write "end" - write "print x" - write "end" - - var ia = new Array[String] - initnit(ia) - write "var a: Root = {ia.first}" - write "var b: Root = a" - for i in ia do - write "\t\t\tif a.id > 0 then a = {i}" - end - write "test(b, b, 10, -100)" - write "test(a, a, {loops}, 0)" - - file.close - end - - fun initjava(res: Array[String], interfaces: Bool) is abstract - fun testjava(interfaces: Bool): String do return "true" - fun writejava(dir: String, name: String, interfaces: Bool) - do - dir = "{dir}/java" - dir.mkdir - file = new FileWriter.open("{dir}/{name}.java") - - var cl = "" - if interfaces then cl = "X" - write "class {name} \{" - if interfaces then - write "static interface Root\n\t\{ int id(); \}" - else - write "static class Root\n\t\{ int id() \{ return 0;\} \}" - end - for c in classes do - if interfaces then - write "static interface {c} " - else - write "static class {c} " - end - if c.supers.is_empty then - write "\textends Root" - else for s in [c.supers.first] do - write "\textends {s}" - end - if interfaces then - write "\{\}" - write "static class X{c} implements {c}" - end - write "\{" - write "\tpublic int id() \{ return {c.id}; \}" - write "\}" - end - - write "static public void main(String args[]) \{" - var ia = new Array[String] - initjava(ia, interfaces) - write "Root a = {ia.first};" - write "Root b = a;" - for i in ia do - write "\t\t\tif (a.id() > 0) a = {i};" - end - write "\ttest(b, b, 10, -100);" - write "\ttest(a, a, {loops}, 0);" - write "\}" - - write "static public void test(Root a, Root b, int loops, int start) \{" - write "\tint x = start;" - write "\tfor(int i = 0; i < loops; i++) \{" - write "\t\tfor(int j = 0; j < loops; j++) \{" - var test = "true" - if not dry then test = testjava(interfaces) - write "\t\t\tif({test} && x>=0) \{" - if check then write "\t\t\t\tx = x + 1;" - write "\t\t\t\} else \{ x = x - 1 + i - j; a = b;\}" - #write "\t\t\t\} else \{ x = x - 1; a = b;\}" - write "\t\t}" - write "\t\}" - write "\tSystem.out.println(x);" - write "\}" - write "\}" - file.close - end - - fun initcsharp(res: Array[String], interfaces: Bool) is abstract - fun testcsharp(interfaces: Bool): String do return "true" - fun writecsharp(dir: String, name: String, interfaces: Bool) - do - dir = "{dir}/cs" - dir.mkdir - file = new FileWriter.open("{dir}/{name}.cs") - - var cl = "" - if interfaces then cl = "X" - write "class {name} \{" - if interfaces then - write "interface Root\n\t\{ int Id(); \}" - else - write "class Root\n\t\{ public int Id() \{ return 0;\} \}" - end - for c in classes do - if interfaces then - write "interface {c} " - else - write "class {c} " - end - if c.supers.is_empty then - write "\t: Root" - else for s in [c.supers.first] do - write "\t: {s}" - end - if interfaces then - write "\{\}" - write "class X{c} : {c}" - end - write "\{" - write "\tpublic int Id() \{ return {c.id}; \}" - write "\}" - end - - write "static void Main(string[] args) \{" - var ia = new Array[String] - initcsharp(ia, interfaces) - write "Root a = {ia.first};" - write "Root b = a;" - for i in ia do - write "\t\t\tif (a.Id() > 0) a = {i};" - end - write "\tTest(b, b, 10, -100);" - write "\tTest(a, a, {loops}, 0);" - write "\}" - - write "static void Test(Root a, Root b, int loops, int start) \{" - write "\tint x = start;" - write "\tfor(int i = 0; i < loops; i++) \{" - write "\t\tfor(int j = 0; j < loops; j++) \{" - var test = "true" - if not dry then test = testcsharp(interfaces) - write "\t\t\tif({test} && x>=0) \{" - if check then write "\t\t\t\tx++;" - write "\} else \{ x = x - 1 + i - j; a = b; \};" - write "\t\t}" - write "\t\}" - write "\tSystem.Console.WriteLine(x);" - write "\}" - write "\}" - file.close - end - - fun initscala(res: Array[String], interfaces: Bool) is abstract - fun testscala(interfaces: Bool): String do return "true" - fun writescala(dir: String, name: String, interfaces: Bool) - do - dir = "{dir}/scala" - dir.mkdir - file = new FileWriter.open("{dir}/{name}.scala") - - var cl = "" - write "object {name} \{" - write "class Root\n\t\{ def id: Int = 0 \}" - for c in classes do - if interfaces then - write "trait {c}[+E] " - else - write "class {c}[+E] " - end - if c.supers.is_empty then - write "\textends Root" - else for s in [c.supers.first] do - write "\textends {s}[E]" - end - if interfaces then - write "\{\}" - write "class X{c}[E] extends {c}[E]" - end - write "\{" - write "\toverride def id: Int = {c.id}" - write "\}" - end - - write "def main(args: Array[String]) = \{" - var ia = new Array[String] - initscala(ia, interfaces) - write "var a: Root = {ia.first};" - write "var b: Root = a;" - for i in ia do - write "\t\t\tif (a.id > 0) a = {i};" - end - write "\ttest(b, b, 10, -100)" - write "\ttest(a, a, {loops}, 0)" - write "\}" - - write "def test(aa:Root, b:Root, l: Int, start: Int) = \{" - write "\tvar a = aa" - write "\tvar x = start" - write "\tvar loops = l" - write "\tvar i = 0" - write "\twhile (i < loops) \{" - write "\t\tvar j = 0" - write "\t\twhile (j < loops) \{" - var test = "true" - if not dry then test = testscala(interfaces) - write "\t\tif ({test} && x>=0) \{" - if check then write "\t\t\tx += 1;" - #write "\} else \{ x = x - 1 + i - j; a = b; \}" - write "\} else \{ x = x - 1; a = b; \}" - write "\t\tj += 1" - write "\t\t\}" - write "\ti += 1" - write "\t\}" - write "\t\t\tprintln(x)" - write "\}" - write "\}" - - file.close - end - - fun initcpp(res: Array[String]) is abstract - fun testcpp: String do return "true" - fun writecpp(dir: String, name: String) - do - dir = "{dir}/cpp" - dir.mkdir - file = new FileWriter.open("{dir}/{name}.cpp") - - write "#include " - write "#include " - write "class Root\n\t\{ public: virtual int id() \{ return 0;\} \};" - for c in classes do - write "template" - write "class {c} " - if c.supers.is_empty then - write "\t: public virtual Root" - else for s in [c.supers.first] do - write "\t: public virtual {s}" - end - write "\{" - write "\tpublic: virtual int id() \{ return {c.id}; \}" - write "\};" - end - - write "void test(Root *a, Root *b, int loops, int start) \{" - write "\tint x = start;" - write "\tfor(int i = 0; i < loops; i++) \{" - write "\t\tfor(int j = 0; j < loops; j++) \{" - var test = "true" - if not dry then test = testcpp - write "\t\tif({test} && x>=0) \{" - if check then write "\t\t\tx += 1;" - write "\} else \{ x = x - 1 + i - j; a = b;\}" - write "\t\t}" - write "\t\}" - write "\tstd::cout << x << std::endl;" - write "\}" - - write "int main(int argc, char **argv) \{" - var ia = new Array[String] - initcpp(ia) - write "Root *a = {ia.first};" - write "Root *b = a;" - for i in ia do - write "\t\t\tif (a->id() > 0) a = {i};" - end - write "\ttest(b, b, 10, -100);" - write "\ttest(a, a, {loops}, 0);" - write "\}" - - file.close - end - - fun inite(res: Array[String], se: Bool) is abstract - fun teste(se: Bool): String do return "true" - fun locale(se: Bool) do end - fun writee(dir: String, name: String, se: Bool) - do - if se then - dir = "{dir}/se/{name}" - else - dir = "{dir}/es/{name}" - end - dir.mkdir - file = new FileWriter.open("{dir}/root.e") - - var istk = "" - if se then istk = " is" - write "class ROOT" - write "feature id: INTEGER {istk} do Result := 0 end" - write "end" - file.close - - for c in classes do - file = new FileWriter.open("{dir}/{c}.e") - write "class {c}[E] " - if c.supers.is_empty then - write "\tinherit ROOT" - else for s in [c.supers.first] do - write "\tinherit {s}[E]" - end - write "\t\tredefine id end" - write "feature" - write "\tid: INTEGER {istk} do Result := {c.id} end" - write "end" - file.close - end - - file = new FileWriter.open("{dir}/app{name}.e") - write "class APP{name.to_upper}" - if se then - write "insert ARGUMENTS" - end - write "create make" - write "feature" - - if se then - write "\tmake{istk}" - else - write "\tmake(args: ARRAY[STRING]){istk}" - end - write "\t\tlocal" - write "\t\t\ta: ROOT" - write "\t\t\tb: ROOT" - write "\t\tdo" - var ia = new Array[String] - inite(ia,se) - write "{ia.first}" - write "b := a" - for i in ia do - write "\t\t\tif a.id > 0 then {i} end" - end - write "\t\t\ttest(b, b, 10, -100)" - write "\t\t\ttest(a, a, {loops}, 0)" - write "\t\tend" - - write "\ttest(aa: ROOT; b: ROOT; l: INTEGER; start: INTEGER){istk}" - write "\t\tlocal" - write "\t\t\ta: ROOT" - write "\t\t\ti: INTEGER" - write "\t\t\tj: INTEGER" - write "\t\t\tx: INTEGER" - locale(se) - write "\t\t\tloops: INTEGER" - write "\t\tdo" - write "\t\t\ta := aa" - write "\t\t\tx := start" - write "\t\t\tloops := l" - write "\t\t\tfrom i := 0 until i>=loops loop" - write "\t\t\t\tfrom j := 0 until j>=loops loop" - var test = "True" - if not dry then test = teste(se) - write "\t\t\t\t\tif {test} and then x >= 0 then" - if check then write "\t\t\t\t\tx := x + 1" - write "\t\t\t\t\telse x := x - 1 + i - j; a := b end" - write "\t\t\t\t\tj := j + 1" - write "\t\t\t\tend" - write "\t\t\t\ti := i + 1" - write "\t\t\tend" - write "\t\t\tprint(x.out)" - write "\t\t\tprint(\"%N\")" - write "\t\tend" - write "end" - file.close - end - - var count = false - - fun genall - do - var g = self - var outdir = args.first - var name = args[1] - var use_interfaces = true - if args.length > 2 then g.dept = args[2].to_i - if args.length > 3 then use_interfaces = false - - g.genhier - - g.writenit(outdir, name) - g.writejava(outdir, name, use_interfaces) - g.writecsharp(outdir, name, use_interfaces) - g.writescala(outdir, name, use_interfaces) - g.writecpp(outdir, name) - g.writee(outdir, "{name}_se", true) - g.writee(outdir, name, false) - end -end - -var g = new Generator -g.genall diff --git a/benchmarks/bench_languages.sh b/benchmarks/languages/bench_languages.sh similarity index 56% rename from benchmarks/bench_languages.sh rename to benchmarks/languages/bench_languages.sh index 2a33170..e204133 100755 --- a/benchmarks/bench_languages.sh +++ b/benchmarks/languages/bench_languages.sh @@ -17,8 +17,8 @@ # TODO: cleanup and libify the helper-parts -source ./bench_common.sh -source ./bench_plot.sh +source ../bench_common.sh +source ../bench_plot.sh ## CONFIGURATION OPTIONS ## @@ -26,6 +26,13 @@ source ./bench_plot.sh # Can be overrided with 'the option -n' count=2 +xml=bench_languages.xml +html=bench_languages.html +verbose=true + +echo "" > $xml +echo "" > $html + ## HANDLE OPTIONS ## function usage() @@ -38,10 +45,31 @@ function usage() echo " -h: this help" } +function system_info() +{ + ( # use a subshell to protect the set -x + export LANG=C + set -x + uname -a + lscpu + git describe --always HEAD + ./nitc --version + gcc --version + clang --version + javac -version + java -version + gcj --version + scalac -version + scala -version + ec -version + pypy --version + ) +} + stop=false while [ "$stop" = false ]; do case "$1" in - -v) verbose=true; shift;; + -v) verbose=true; system_info; shift;; -h) usage; exit;; -n) count="$2"; shift; shift;; --dry) dry_run=true; shift;; @@ -59,10 +87,12 @@ if test -z "$NOTSKIPED"; then fi ## COMPILE ENGINES -cd ../src -test -f ./nitc_3 || ./ncall.sh -O -cd ../benchmarks -test -f ./nitc || ../src/nitc_3 ../src/nitc.nit -O -v +test -f ./nitc || ../../bin/nitc ../../src/nitc.nit --semi-global -v + +today=`date +%Y-%m-%d_%H-%M-%S` +bdir="languages.${today}.out" +rm -r "$bdir" "./languages.out" 2> /dev/null +ln -sf "$bdir" "./languages.out" ## EFFECTIVE BENCHS ## @@ -71,107 +101,124 @@ function bench_language() name="$1" skip_test "$name" && return rootdir=`pwd` - basedir="./${name}.out" - - mkdir $basedir + basedir="${bdir}/${name}" + mkdir -p "$basedir" t=t - s=20 - seq="2 4 8" + s=50000 + seq="3 4 8 16" + + if [ "$fast" = "true" ]; then + s=10000 + seq=3 + fi + for b in $seq; do - run_command ./nitc languages/$name.nit -o $basedir/$name.bin - run_command $basedir/$name.bin $basedir "${t}_$b" "$b" + run_command ./nitc benches/$name.nit -o $basedir/$name.bin && + run_command $basedir/$name.bin $basedir "${t}_$b" "$b" "$s" done prepare_res $basedir/$name-g++.dat "g++" "g++" cppdir="${basedir}/cpp" - for b in $seq; do - run_command g++ "${cppdir}/${t}_$b.cpp" -O2 -o "${cppdir}/${t}_$b.g++.bin" + test -d $cppdir && for b in $seq; do + run_command g++ "${cppdir}/${t}_$b.cpp" -O2 -o "${cppdir}/${t}_$b.g++.bin" && bench_command "$b" "" "${cppdir}/${t}_$b.g++.bin" $s done prepare_res $basedir/$name-clang++.dat "clang++" "clang++" - for b in $seq; do - run_command clang++ "${cppdir}/${t}_$b.cpp" -O2 -o "${cppdir}/${t}_$b.clang++.bin" + test -d $cppdir && for b in $seq; do + run_command clang++ "${cppdir}/${t}_$b.cpp" -O2 -o "${cppdir}/${t}_$b.clang++.bin" && bench_command "$b" "" "${cppdir}/${t}_$b.clang++.bin" $s done prepare_res $basedir/$name-java.dat "java" "java" javadir="${basedir}/java" - for b in $seq; do - run_command javac "${javadir}/${t}_$b.java" + test -d $javadir && for b in $seq; do + run_command javac "${javadir}/${t}_$b.java" && bench_command "$b" "" java -cp "${javadir}/" "${t}_$b" $s done prepare_res $basedir/$name-gcj.dat "gcj" "gcj" - for b in $seq; do - run_command gcj --main=${t}_$b -O2 "${javadir}/${t}_$b.java" -o "${javadir}/${t}_$b.gcj.bin" + test -d $javadir && for b in $seq; do + run_command gcj --main=${t}_$b -O2 "${javadir}/${t}_$b.java" -o "${javadir}/${t}_$b.gcj.bin" && bench_command "$b" "" "${javadir}/${t}_$b.gcj.bin" $s done prepare_res $basedir/$name-scala.dat "scala" "scala" scaladir="${basedir}/scala" - for b in $seq; do - run_command scalac "${scaladir}/${t}_$b.scala" -d "${scaladir}" + test -d $scaladir && for b in $seq; do + run_command scalac "${scaladir}/${t}_$b.scala" -d "${scaladir}" && bench_command "$b" "" scala -cp "${scaladir}/" "${t}_$b" $s done prepare_res $basedir/$name-cs.dat "c#" "c#" csdir="${basedir}/cs" - for b in $seq; do - run_command gmcs "$csdir/${t}_$b.cs" + test -d $csdir && for b in $seq; do + run_command mcs "$csdir/${t}_$b.cs" && bench_command "$b" "" mono "$csdir/${t}_$b.exe" $s done prepare_res $basedir/$name-es.dat "es" "es" esdir="${basedir}/es" - for b in $seq; do - cd $esdir - run_command ec -clean -finalize ${t}_$b/app${t}_$b.e - chmod +x app${t}_$b - mv app${t}_$b ${t}_$b.es.bin - cd $rootdir + test -d $esdir && for b in $seq; do + run_command ec -clean -finalize "$esdir/${t}_$b/app${t}_$b.e" && + chmod +x "app${t}_$b" && + mv "app${t}_$b" "$esdir/${t}_$b.es.bin" && bench_command "$b" "" "$esdir/${t}_$b.es.bin" $s done +<System Info" >> "$html" +system_info 2>&1 | sed -e 's/$/
/;s|+\( .*\)|

\1

|' >> "$html" + if test -n "$died"; then echo "Some commands failed" exit 1 diff --git a/benchmarks/languages/bench_typetest_covar.nit b/benchmarks/languages/bench_typetest_covar.nit deleted file mode 100644 index d0bb2b8..0000000 --- a/benchmarks/languages/bench_typetest_covar.nit +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env nit - -import bench_base - -class TypeTestCovarGenerator - super Generator - - redef fun initnit(res) - do - for c in classes do - res.add "new {classes.first}[{c}[Root]]" - end - - end - - redef fun testnit - do - return "a isa {classes.first}[{classes[middle]}[Root]]" - end - - redef fun initjava(res, interfaces) - do - - var tagc = "" - if interfaces then tagc = "X" - for c in classes do - res.add "new {tagc}{classes.first}<{c}>()" - end - end - - redef fun testjava(interfaces) - do - return "a instanceof {classes.first}" - end - - redef fun initcsharp(res, interfaces) - do - var tagc = "" - if interfaces then tagc = "X" - for c in classes do - res.add "new {tagc}{classes.first}<{c}>()" - end - end - - redef fun testcsharp(interfaces) - do - return "a is {classes.first}<{classes[middle]}>" - end - - redef fun initscala(res, interfaces) - do - var tagc = "" - if interfaces then tagc = "X" - for c in classes do - res.add "new {tagc}{classes.first}[{c}[Root]]()" - end - end - - redef fun testscala(interfaces) - do - return "a.isInstanceOf[{classes.first}[{classes[middle]}[Root]]]" - end - - redef fun initcpp(res) - do - for c in classes do - res.add "new {classes.first}<{c}*>()" - end - end - - redef fun testcpp - do - write "\t\t\t{classes.first}<{classes[middle]}*> *to = dynamic_cast<{classes.first}<{classes[middle]}*>*>(a);" - return "to != 0" - end - - redef fun inite(res, se) - do - for c in classes do - res.add "create \{{classes.first}[{c}[ROOT]]\} a" - end - end - - redef fun teste(se) - do - write "\t\t\t\t\tto ?= a" - return "to /= Void" - end - - redef fun locale(se) - do - write "\t\t\tto: {classes.first}[{classes[middle]}[ROOT]]" - end -end - -var g = new TypeTestCovarGenerator -g.genall diff --git a/benchmarks/languages/benches/bench_attr.nit b/benchmarks/languages/benches/bench_attr.nit new file mode 100644 index 0000000..22cf626 --- /dev/null +++ b/benchmarks/languages/benches/bench_attr.nit @@ -0,0 +1,115 @@ +#!/usr/bin/env nit +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import bench_base + +class TypeTestDepthGenerator + super Generator + + redef fun initnit(res) + do + for c in classes do + res.add "new {c}[Root]" + end + end + + redef fun testnit + do + return "a._aid >= {middle}" + end + + redef fun initjava(res, interfaces) + do + + var tagc = "" + if interfaces then tagc = "X" + for c in classes do + res.add "new {tagc}{c}()" + end + end + + redef fun testjava(interfaces) + do + return "a.aid >= {middle}" + end + + redef fun initcsharp(res, interfaces) + do + var tagc = "" + if interfaces then tagc = "X" + for c in classes do + res.add "new {tagc}{c}()" + end + end + + redef fun testcsharp(interfaces) + do + return "a.aid >= {middle}" + end + + redef fun initscala(res, interfaces) + do + var tagc = "" + if interfaces then tagc = "X" + for c in classes do + res.add "new {tagc}{c}[Root]()" + end + end + + redef fun testscala(interfaces) + do + return "a.aid >= {middle}" + end + + redef fun initcpp(res) + do + for c in classes do + res.add "new {c}()" + end + end + + redef fun testcpp + do + return "a->aid >= {middle}" + end + + redef fun inite(res, se) + do + for c in classes do + res.add "create \{{c}[ROOT]\}" + end + end + + redef fun teste(se) + do + return "a.aid >= {middle}" + end + + redef fun initpython(res) + do + for c in classes do + res.add "{c}()" + end + end + + redef fun testpython + do + return "a.aid >= {middle}" + end +end + +var g = new TypeTestDepthGenerator +g.use_interfaces = false +g.genall diff --git a/benchmarks/languages/benches/bench_base.nit b/benchmarks/languages/benches/bench_base.nit new file mode 100644 index 0000000..f97bd65 --- /dev/null +++ b/benchmarks/languages/benches/bench_base.nit @@ -0,0 +1,797 @@ +#!/usr/bin/env nit +# 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. + +# Microbenchmak generation for multiple language +# Just a quick an dirty Nit script file :) + +# This benchmark focuses on effects of the hierarchy dept +# on the typetest performances + +# class Root +# class Klass[E] super Root +# class C1...CX super Root +# Klass[CX] isa Klass[C1] + +class Klass + var id: Int + var supers = new Array[Klass] + var all_supers = new HashSet[Klass] + redef fun to_s + do + return "C{id}" + end +end + +class Generator + + var classes = new Array[Klass] + + var dept = 5 is writable + var loops = 50000 is writable + var middle = 0 is writable + var dry = false is writable + var check = false is writable + + # Polymorphism level + # This is the number of distinct dynamic types for the receiver + var poly = 2 is writable + + # Use only interfaces (or traits) in the hierarchy + # + # If `false` then java&cs&scala will use classes, thus will break if MH is used + var use_interfaces = true is writable + + # Add Root0, the superclass to Root that introduce common services. + # + # This add another level of un-optimization since the services are not introduced + # by the static type of the receiver. + var use_root0 = true is writable + + fun genhier + do + var s: nullable Klass = null + for d in [1..dept] do + var c = new Klass(d) + + classes.add(c) + c.all_supers.add(c) + if s != null then + c.supers.add(s) + c.all_supers.add_all(s.all_supers) + end + s = c + end + middle = (dept) / 2 + end + + var file: nullable FileWriter = null + fun write(str: String) + do + file.write(str) + file.write("\n") + end + + fun initnit(res: Array[String]) do return + fun testnit: String do return "true" + + fun writenit(dir: String, name: String) + do + var ia = new Array[String] + initnit(ia) + if ia.is_empty then + print "Nit disabled" + return + end + + dir = "{dir}/nit" + dir.mkdir + file = new FileWriter.open("{dir}/{name}.nit") + + if use_root0 then + write "class Root0" + else + write "class Root" + end + write "\tfun id: Int do return 0" + write "\tvar aid: Int = id" + write "\tvar next: Root is noautoinit" + write "\tfun set_next(next: Root): Root do\n\t\tself.next = next\n\t\treturn next\n\tend" + write "end" + if use_root0 then + write "class Root\n\tsuper Root0\nend" + end + for c in classes do + write "class {c}[E]" + if c.supers.is_empty then + write "\tsuper Root" + else for s in c.supers do + write "\tsuper {s}[E]" + end + write "\tredef fun id do return {c.id}" + write "\tfun f{c.id}: Int do return {c.id}" + write "\tvar a{c.id}: Int = {c.id}" + write "end" + end + + write "fun test(a,b: Root, loops, start: Int)" + write "do" + write "var x = start" + write "var i = loops" + write "while i > 0 do" + write "\tvar j = loops" + write "\twhile j > 0 do" + var test = "x >= 0" + if not dry then test = testnit + write "\t\tif {test} then" + write "\t\t\tvar tmp = a; a = b; b = tmp" + if check then write "\t\tx += 1" + write "\t\telse" + write "\t\t\tx += 1" + write "\t\t\ta = a.next" + write "\t\t\tb = b.next" + write "\t\tend" + write "\t\tj -= 1" + write "\tend" + write "\tx += 1" + write "\ta = a.next" + write "\tb = b.next" + write "\ti -= 1" + write "end" + write "print x" + write "end" + + write "var b: Root = {ia.first}" + write "var tmp = b" + for i in ia do + write "b = b.set_next({i})" + end + write "b.next = tmp" + write "var a: Root = {ia.last}" + write "tmp = a" + for i in [1..poly[ do + write "a = a.set_next({ia[ia.length - 1 - i]})" + end + write "a.next = tmp" + write "test(b, b.next, 10, -100)" + write "test(a, a.next, {loops}, 0)" + + file.close + end + + fun initjava(res: Array[String], interfaces: Bool) do return + fun testjava(interfaces: Bool): String do return "true" + fun writejava(dir: String, name: String, interfaces: Bool) + do + var ia = new Array[String] + initjava(ia, interfaces) + if ia.is_empty then + print "Java disabled" + return + end + + dir = "{dir}/java" + dir.mkdir + file = new FileWriter.open("{dir}/{name}.java") + + write "class {name} \{" + var root0 = "Root" + if use_root0 then root0 = "Root0" + if interfaces then + write "static interface {root0} \{ long id(); Root getNext(); Root setNext(Root next); \}" + write "static class XRoot implements {root0} \{" + else + write "static class {root0} \{" + end + write "\tpublic long id() \{ return 0;\}" + write "\tpublic long aid = id();" + write "\tpublic Root next;" + write "\tpublic Root getNext() \{ return next;\}" + write "\tpublic Root setNext(Root next) \{ this.next = next; return next; \}" + write "\}" + + if use_root0 then + if interfaces then + write "static interface Root extends Root0 \{\}" + else + write "static class Root extends Root0 \{\}" + end + end + + for c in classes do + if interfaces then + write "static interface {c} " + else + write "static class {c} " + end + if c.supers.is_empty then + write "\textends Root" + else for s in [c.supers.first] do + write "\textends {s}" + end + if interfaces then + write "\{\}" + if c.supers.is_empty then + write "static class X{c} extends XRoot implements {c}" + else + write "static class X{c} extends X{c.supers.first} implements {c}" + end + end + write "\{" + write "\tpublic long id() \{ return {c.id}; \}" + write "\tpublic long f{c.id}() \{ return {c.id}; \}" + write "\tpublic long a{c.id} = {c.id};" + write "\}" + end + + write "static public void main(String args[]) \{" + write "\tRoot b = {ia.first};" + write "\tRoot tmp = b;" + for i in ia do + write "\tb = b.setNext({i});" + end + write "\tb.setNext(tmp);" + write "\tRoot a = {ia.last};" + write "\ttmp = a;" + for i in [1..poly[ do + write "\ta = a.setNext({ia[ia.length - 1 - i]});" + end + write "\ta.setNext(tmp);" + write "\ttest(b, b.getNext(), 10, -100);" + write "\ttest(a, a.getNext(), {loops}, 0);" + write "\}" + + write "static public void test(Root a, Root b, long loops, long start) \{" + write "\tlong x = start;" + write "\tfor(long i = loops; i > 0; i--) \{" + write "\t\tfor(long j = loops; j > 0; j--) \{" + var test = "x>=0" + if not dry then test = testjava(interfaces) + write "\t\t\tif({test}) \{" + write "\t\t\t\tRoot tmp = a; a = b; b = tmp;" + if check then write "\t\t\t\tx = x + 1;" + write "\t\t\t\} else \{ x++; a = a.getNext(); b = b.getNext(); \}" + write "\t\t\}" + write "\t\tx++; a = a.getNext(); b = b.getNext();" + write "\t\}" + write "\tSystem.out.println(x);" + write "\}" + write "\}" + file.close + end + + fun initcsharp(res: Array[String], interfaces: Bool) do return + fun testcsharp(interfaces: Bool): String do return "true" + fun writecsharp(dir: String, name: String, interfaces: Bool) + do + var ia = new Array[String] + initcsharp(ia, interfaces) + if ia.is_empty then + print "C# disabled" + return + end + + dir = "{dir}/cs" + dir.mkdir + file = new FileWriter.open("{dir}/{name}.cs") + + write "class {name} \{" + var root0 = "Root" + if use_root0 then root0 = "Root0" + if interfaces then + write "interface {root0} \{ long Id(); Root GetNext(); Root SetNext(Root next); \}" + write "class XRoot: {root0} \{ " + else + write "class {root0}\n\t\{ " + end + write "\tvirtual public long Id() \{ return 0; \}" + write "\tpublic long aid;" + write "\tpublic Root next;" + write "\tvirtual public Root GetNext() \{ return next; \}" + write "\tvirtual public Root SetNext(Root next) \{ this.next = next; return next; \}" + write "\}" + + if use_root0 then + if interfaces then + write "interface Root: Root0 \{\}" + else + write "class Root: Root0 \{\}" + end + end + + for c in classes do + var cname + if interfaces then + write "interface {c} " + cname = "X"+c.to_s + else + write "class {c} " + cname = c.to_s + end + if c.supers.is_empty then + write "\t: Root" + else for s in [c.supers.first] do + write "\t: {s}" + end + if interfaces then + write "\{\}" + if c.supers.is_empty then + write "class X{c}: XRoot, {c}" + else + write "class X{c}: X{c.supers.first}, {c}" + end + end + write "\{" + write "\toverride public long Id() \{ return {c.id}; \}" + write "\tvirtual public long F{c.id}() \{ return {c.id}; \}" + write "\tpublic long A{c.id} = {c.id};" + write "\tpublic {cname}() \{ aid = {c.id}; \}" + write "\}" + end + + write "static void Main(string[] args) \{" + write "\tRoot b = {ia.first};" + write "\tRoot tmp = b;" + for i in ia do + write "\tb = b.SetNext({i});" + end + write "\tb.SetNext(tmp);" + write "\tRoot a = {ia.last};" + write "\ttmp = a;" + for i in [1..poly[ do + write "\ta = a.SetNext({ia[ia.length - 1 - i]});" + end + write "\ta.SetNext(tmp);" + write "\tTest(b, b.GetNext(), 10, -100);" + write "\tTest(a, a.GetNext(), {loops}, 0);" + write "\}" + + write "static void Test(Root a, Root b, long loops, long start) \{" + write "\tlong x = start;" + write "\tfor(long i = loops; i > 0; i--) \{" + write "\t\tfor(long j = loops; j >0; j--) \{" + var test = "x>=0" + if not dry then test = testcsharp(interfaces) + write "\t\t\tif({test}) \{" + write "\t\t\t\tRoot tmp = a; a = b; b = tmp;" + if check then write "\t\t\t\tx++;" + write "\t\t\t\} else \{ x += 1; a = a.GetNext(); b = b.GetNext();\};" + write "\t\t\}" + write "\t\tx += 1; a = a.GetNext(); b = b.GetNext();" + write "\t\}" + write "\tSystem.Console.WriteLine(x);" + write "\}" + write "\}" + file.close + end + + fun initscala(res: Array[String], interfaces: Bool) do return + fun testscala(interfaces: Bool): String do return "true" + fun writescala(dir: String, name: String, interfaces: Bool) + do + var ia = new Array[String] + initscala(ia, interfaces) + if ia.is_empty then + print "Scala disabled" + return + end + + dir = "{dir}/scala" + dir.mkdir + file = new FileWriter.open("{dir}/{name}.scala") + + write "object {name} \{" + if use_root0 then + write "class Root0 \{" + else + write "class Root \{" + end + write "\tdef id: Long = 0; var aid: Long = id; var next: Root = null; def getNext: Root = next; def setNext(next: Root): Root = \{ this.next = next; return next; \} \}" + + if use_root0 then + write "class Root extends Root0 \{\}" + end + + for c in classes do + if interfaces then + write "trait {c}[+E] " + else + write "class {c}[+E] " + end + if c.supers.is_empty then + write "\textends Root" + else for s in [c.supers.first] do + write "\textends {s}[E]" + end + if interfaces then + write "\{\}" + if c.supers.is_empty then + write "class X{c}[E] extends {c}[E]" + else + write "class X{c}[E] extends X{c.supers.first}[E] with {c}[E]" + end + end + write "\{" + write "\toverride def id: Long = {c.id}" + write "\tdef f{c.id}: Long = {c.id}" + if interfaces then + write "\tvar a{c.id}: Long = {c.id}" + end + write "\}" + end + + write "def main(args: Array[String]) = \{" + write "\tvar b: Root = {ia.first};" + write "\tvar tmp = b;" + for i in ia do + write "\tb = b.setNext({i});" + end + write "\tb.setNext(tmp);" + write "\tvar a: Root = {ia.last};" + write "\ttmp = a;" + for i in [1..poly[ do + write "\ta = a.setNext({ia[ia.length - 1 - i]});" + end + write "\ta.setNext(tmp);" + write "\ttest(b, b.getNext, 10, -100);" + write "\ttest(a, a.getNext, {loops}, 0);" + write "\}" + + write "def test(aa:Root, bb:Root, l: Long, start: Long) = \{" + write "\tvar a = aa" + write "\tvar b = bb" + write "\tvar x = start" + write "\tvar loops = l" + write "\tvar i = loops" + write "\twhile (i > 0) \{" + write "\t\tvar j = loops" + write "\t\twhile (j > 0) \{" + var test = "x>=0" + if not dry then test = testscala(interfaces) + write "\t\t\tif ({test}) \{" + write "\t\t\t\tval tmp = a; a = b; b = tmp;" + if check then write "\t\t\t\tx += 1;" + write "\t\t\t\} else \{ x += 1; a = a.getNext; b = b.getNext;\}" + write "\t\t\tj -= 1" + write "\t\t\}" + write "\t\tx += 1; a = a.getNext; b = b.getNext;" + write "\t\ti -= 1" + write "\t\t\}" + write "\tprintln(x)" + write "\}" + write "\}" + + file.close + end + + fun initcpp(res: Array[String]) do return + fun testcpp: String do return "true" + fun writecpp(dir: String, name: String) + do + var ia = new Array[String] + initcpp(ia) + if ia.is_empty then + print "C++ diabled" + return + end + + dir = "{dir}/cpp" + dir.mkdir + file = new FileWriter.open("{dir}/{name}.cpp") + + write "#include " + write "#include " + if use_root0 then + write "class Root;" + write "class Root0" + else + write "class Root" + end + write "\t\{ public: virtual long id() \{ return 0;\} long aid; Root *next; virtual Root *setNext(Root *n) \{this->next = n; return n;\} \};" + + if use_root0 then + write "class Root: public virtual Root0 \{\};" + end + + for c in classes do + write "template" + write "class {c} " + if c.supers.is_empty then + write "\t: public virtual Root" + else for s in [c.supers.first] do + write "\t: public virtual {s}" + end + write "\{" + write "\tpublic: virtual long id() \{ return {c.id}; \}" + write "\tvirtual long f{c.id}() \{ return {c.id}; \}" + write "\tlong a{c.id};" + write "\t{c}(): a{c.id}({c.id}) \{ this->aid = {c.id}; \}" + write "\};" + end + + write "void test(Root *a, Root *b, long loops, long start) \{" + write "\tlong x = start;" + write "\tfor(long i = loops; i > 0; i--) \{" + write "\t\tfor(int j = loops; j > 0; j--) \{" + var test = "x>=0" + if not dry then test = testcpp + write "\t\t\tif({test}) \{" + write "\t\t\t\tRoot *tmp = a; a = b; b = tmp;" + if check then write "\t\t\t\tx += 1;" + write "\t\t\t\} else \{ x++; a = a->next; b = b->next;\}" + write "\t\t\}" + write "\t\tx++; a = a->next; b = b->next;" + write "\t\}" + write "\tstd::cout << x << std::endl;" + write "\}" + + write "int main(int argc, char **argv) \{" + write "\tRoot *b = {ia.first};" + write "\tRoot *tmp = b;" + for i in ia do + write "\tb = b->setNext({i});" + end + write "\tb->setNext(tmp);" + write "\tRoot *a = {ia.last};" + write "\ttmp = a;" + for i in [1..poly[ do + write "\ta = a->setNext({ia[ia.length - 1 - i]});" + end + write "\ta->setNext(tmp);" + write "\ttest(b, b->next, 10, -100);" + write "\ttest(a, a->next, {loops}, 0);" + write "\}" + + file.close + end + + fun inite(res: Array[String], se: Bool) do return + fun teste(se: Bool): String do return "true" + fun locale(se: Bool) do end + fun writee(dir: String, name: String, se: Bool) + do + var ia = new Array[String] + inite(ia,se) + if ia.is_empty then + print "Eiffel disabled" + return + end + + if se then + dir = "{dir}/se/{name}" + else + dir = "{dir}/es/{name}" + end + dir.mkdir + + var root0 + if use_root0 then + root0 = "ROOT0" + file = new FileWriter.open("{dir}/root0.e") + else + root0 = "ROOT" + file = new FileWriter.open("{dir}/root.e") + end + + var istk = "" + if se then istk = " is" + write "class {root0}" + write "feature id: INTEGER_64 {istk} do Result := 0 end" + write "aid: INTEGER_64" + write "xnext: detachable ROOT" + write "next: ROOT do check attached xnext as n then Result := n end end" + write "set_next(n: ROOT): ROOT do xnext := n Result := n end" + write "make do aid := id end" + write "end" + file.close + + if use_root0 then + file = new FileWriter.open("{dir}/root.e") + write "class ROOT inherit ROOT0 end " + file.close + end + + for c in classes do + file = new FileWriter.open("{dir}/{c}.e") + write "class {c}[E] " + if c.supers.is_empty then + write "\tinherit ROOT" + else for s in [c.supers.first] do + write "\tinherit {s}[E]" + end + write "\t\tredefine id, make end" + write "create make" + write "feature" + write "\tid: INTEGER_64 {istk} do Result := {c.id} end" + write "\tf{c.id}: INTEGER_64 {istk} do Result := {c.id} end" + write "\ta{c.id}: INTEGER_64 {istk} attribute Result := {c.id} end" + write "make do aid := {c.id} end" + write "end" + file.close + end + + file = new FileWriter.open("{dir}/app{name}.e") + write "class APP{name.to_upper}" + if se then + write "insert ARGUMENTS" + end + write "create make" + write "feature" + + if se then + write "\tmake{istk}" + else + write "\tmake(args: ARRAY[STRING]){istk}" + end + write "\t\tlocal" + write "\t\t\ta: ROOT" + write "\t\t\tb: ROOT" + write "\t\t\ttmp: ROOT" + write "\t\tdo" + write "\t\t\tb := {ia.first} .make" + write "\t\t\ttmp := b" + for i in ia do + write "\t\t\tb := b.set_next({i} .make)" + end + write "\t\t\ttmp := b.set_next(tmp)" + + write "\t\t\ta := {ia.last} .make" + write "\t\t\ttmp := a" + for i in [1..poly[ do + write "\t\t\ta := a.set_next({ia[ia.length - 1 - i]} .make)" + end + write "\t\t\ttmp := a.set_next(tmp);" + write "\t\t\ttest(b, b.next, 10, -100)" + write "\t\t\ttest(a, a.next, {loops}, 0)" + write "\t\tend" + + write "\ttest(aa: ROOT; bb: ROOT; l: INTEGER_64; start: INTEGER_64){istk}" + write "\t\tlocal" + write "\t\t\ta: ROOT" + write "\t\t\tb: ROOT" + write "\t\t\ttmp: ROOT" + write "\t\t\ti: INTEGER_64" + write "\t\t\tj: INTEGER_64" + write "\t\t\tx: INTEGER_64" + locale(se) + write "\t\t\tloops: INTEGER_64" + write "\t\tdo" + write "\t\t\ta := aa" + write "\t\t\tb := bb" + write "\t\t\tx := start" + write "\t\t\tloops := l" + write "\t\t\tfrom i := loops until i<=0 loop" + write "\t\t\t\tfrom j := loops until j<=0 loop" + var test = "x >= 0" + if not dry then test = teste(se) + write "\t\t\t\t\tif {test} then" + write "\t\t\t\t\t\ttmp := a; a := b; b := tmp" + if check then write "\t\t\t\t\tx := x + 1" + write "\t\t\t\t\telse x := x + 1; a := a.next; b := b.next end" + write "\t\t\t\t\tj := j - 1" + write "\t\t\t\tend" + write "\t\t\t\tx := x + 1; a := a.next; b := b.next" + write "\t\t\t\ti := i - 1" + write "\t\t\tend" + write "\t\t\tprint(x.out)" + write "\t\t\tprint(\"%N\")" + write "\t\tend" + write "end" + file.close + end + + fun initpython(res: Array[String]) do return + fun testpython: String do return "true" + fun writepython(dir: String, name: String) + do + var ia = new Array[String] + initpython(ia) + if ia.is_empty then + print "Python disabled" + return + end + + dir = "{dir}/python" + dir.mkdir + file = new FileWriter.open("{dir}/{name}.py") + + if use_root0 then + write "class Root0(object):" + else + write "class Root(object):" + end + write "\tdef id(self): return 0" + write "\tdef set_next(self, n):\n\t\tself.next = n\n\t\treturn n" + write "\tdef __init__(self): self.aid = self.id()" + + if use_root0 then + write "class Root(Root0): pass" + end + + for c in classes do + if c.supers.is_empty then + write "class {c}(Root):" + else + write "class {c}({c.supers.join(",")}):" + end + write "\tdef id(self): return {c.id}" + write "\tdef f{c.id}(self): return {c.id}" + write "\tdef __init__(self):" + write "\t\tsuper({c}, self).__init__()" + write "\t\ta{c.id} = {c.id}" + end + + write "def test(a, b, loops, start):" + write "\tx = start" + write "\ti = loops" + write "\twhile i > 0:" + write "\t\tj = loops" + write "\t\twhile j > 0:" + var test = "x >= 0" + if not dry then test = testpython + write "\t\t\tif {test}:" + write "\t\t\t\ttmp = a; a = b; b = tmp" + if check then write "\t\t\t\tx += 1" + write "\t\t\telse:" + write "\t\t\t\tx = x + 1; a = a.next; b = b.next" + write "\t\t\tj -= 1" + write "\t\tx = x + 1; a = a.next; b = b.next" + write "\t\ti -= 1" + write "\tprint(x)" + + write "b = {ia.first}" + write "tmp = b" + for i in ia do + write "b = b.set_next({i})" + end + write "b.next = tmp" + write "a = {ia.last}" + write "tmp = a" + for i in [1..poly[ do + write "a = a.set_next({ia[ia.length - 1 - i]})" + end + write "a.next = tmp" + write "test(b, b.next, 10, -100)" + write "test(a, a.next, {loops}, 0)" + + file.close + end + + var count = false + + fun genall + do + var g = self + var outdir = args.first + var name = args[1] + var use_interfaces = self.use_interfaces + if args.length > 2 then g.dept = args[2].to_i + if args.length > 3 then loops = args[3].to_i + if args.length > 4 then use_interfaces = false + + g.genhier + + g.writenit(outdir, name) + g.writejava(outdir, name, use_interfaces) + g.writecsharp(outdir, name, use_interfaces) + g.writescala(outdir, name, use_interfaces) + g.writecpp(outdir, name) + g.writee(outdir, "{name}_se", true) + g.writee(outdir, name, false) + g.writepython(outdir, name) + end +end + +var g = new Generator +g.genall diff --git a/benchmarks/languages/benches/bench_meth.nit b/benchmarks/languages/benches/bench_meth.nit new file mode 100644 index 0000000..3eaaa28 --- /dev/null +++ b/benchmarks/languages/benches/bench_meth.nit @@ -0,0 +1,114 @@ +#!/usr/bin/env nit +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import bench_base + +class TypeTestDepthGenerator + super Generator + + redef fun initnit(res) + do + for c in classes do + res.add "new {c}[Root]" + end + end + + redef fun testnit + do + return "a.id >= {middle}" + end + + redef fun initjava(res, interfaces) + do + + var tagc = "" + if interfaces then tagc = "X" + for c in classes do + res.add "new {tagc}{c}()" + end + end + + redef fun testjava(interfaces) + do + return "a.id() >= {middle}" + end + + redef fun initcsharp(res, interfaces) + do + var tagc = "" + if interfaces then tagc = "X" + for c in classes do + res.add "new {tagc}{c}()" + end + end + + redef fun testcsharp(interfaces) + do + return "a.Id() >= {middle}" + end + + redef fun initscala(res, interfaces) + do + var tagc = "" + if interfaces then tagc = "X" + for c in classes do + res.add "new {tagc}{c}[Root]()" + end + end + + redef fun testscala(interfaces) + do + return "a.id >= {middle}" + end + + redef fun initcpp(res) + do + for c in classes do + res.add "new {c}()" + end + end + + redef fun testcpp + do + return "a->id() >= {middle}" + end + + redef fun inite(res, se) + do + for c in classes do + res.add "create \{{c}[ROOT]\}" + end + end + + redef fun teste(se) + do + return "a.id >= {middle}" + end + + redef fun initpython(res) + do + for c in classes do + res.add "{c}()" + end + end + + redef fun testpython + do + return "a.id() >= {middle}" + end +end + +var g = new TypeTestDepthGenerator +g.genall diff --git a/benchmarks/languages/benches/bench_null.nit b/benchmarks/languages/benches/bench_null.nit new file mode 100644 index 0000000..a67c27b --- /dev/null +++ b/benchmarks/languages/benches/bench_null.nit @@ -0,0 +1,80 @@ +#!/usr/bin/env nit +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import bench_base + +class TypeTestDepthGenerator + super Generator + + redef fun initnit(res) + do + for c in classes do + res.add "new {c}[Root]" + end + end + + redef fun initjava(res, interfaces) + do + + var tagc = "" + if interfaces then tagc = "X" + for c in classes do + res.add "new {tagc}{c}()" + end + end + + redef fun initcsharp(res, interfaces) + do + var tagc = "" + if interfaces then tagc = "X" + for c in classes do + res.add "new {tagc}{c}()" + end + end + + redef fun initscala(res, interfaces) + do + var tagc = "" + if interfaces then tagc = "X" + for c in classes do + res.add "new {tagc}{c}[Root]()" + end + end + + redef fun initcpp(res) + do + for c in classes do + res.add "new {c}()" + end + end + + redef fun inite(res, se) + do + for c in classes do + res.add "create \{{c}[ROOT]\}" + end + end + + redef fun initpython(res) + do + for c in classes do + res.add "{c}()" + end + end +end + +var g = new TypeTestDepthGenerator +g.dry = true +g.genall diff --git a/benchmarks/languages/benches/bench_typetest_covar.nit b/benchmarks/languages/benches/bench_typetest_covar.nit new file mode 100644 index 0000000..4ccbcf3 --- /dev/null +++ b/benchmarks/languages/benches/bench_typetest_covar.nit @@ -0,0 +1,68 @@ +#!/usr/bin/env nit +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import bench_base + +class TypeTestCovarGenerator + super Generator + + redef fun initnit(res) + do + for c in classes do + res.add "new {classes.first}[{c}[Root]]" + end + + end + + redef fun testnit + do + return "a isa {classes.first}[{classes[middle]}[Root]]" + end + + redef fun initcsharp(res, interfaces) + do + var tagc = "" + if interfaces then tagc = "X" + for c in classes do + res.add "new {tagc}{classes.first}<{c}>()" + end + end + + redef fun testcsharp(interfaces) + do + return "a is {classes.first}<{classes[middle]}>" + end + + redef fun inite(res, se) + do + for c in classes do + res.add "create \{{classes.first}[{c}[ROOT]]\}" + end + end + + redef fun teste(se) + do + write "\t\t\t\t\tto ?= a" + return "to /= Void" + end + + redef fun locale(se) + do + write "\t\t\tto: detachable {classes.first}[{classes[middle]}[ROOT]]" + end +end + +var g = new TypeTestCovarGenerator +g.genall diff --git a/benchmarks/languages/bench_typetest_depth.nit b/benchmarks/languages/benches/bench_typetest_depth.nit similarity index 62% rename from benchmarks/languages/bench_typetest_depth.nit rename to benchmarks/languages/benches/bench_typetest_depth.nit index d5d2f2a..bc6f00d 100644 --- a/benchmarks/languages/bench_typetest_depth.nit +++ b/benchmarks/languages/benches/bench_typetest_depth.nit @@ -1,4 +1,17 @@ #!/usr/bin/env nit +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import bench_base @@ -77,7 +90,7 @@ class TypeTestDepthGenerator redef fun inite(res, se) do for c in classes do - res.add "create \{{c}[ROOT]\} a" + res.add "create \{{c}[ROOT]\}" end end @@ -89,7 +102,18 @@ class TypeTestDepthGenerator redef fun locale(se) do - write "\t\t\tto: {classes[middle]}[ROOT]" + write "\t\t\tto: detachable {classes[middle]}[ROOT]" + end + + redef fun initpython(res) + do + for c in classes do + res.add "{c}()" + end + end + redef fun testpython + do + return "isinstance(a, {classes[middle]})" end end diff --git a/benchmarks/languages/bench_typetest_depth_not.nit b/benchmarks/languages/benches/bench_typetest_depth_not.nit similarity index 55% rename from benchmarks/languages/bench_typetest_depth_not.nit rename to benchmarks/languages/benches/bench_typetest_depth_not.nit index 633e52e..075632a 100644 --- a/benchmarks/languages/bench_typetest_depth_not.nit +++ b/benchmarks/languages/benches/bench_typetest_depth_not.nit @@ -1,4 +1,17 @@ #!/usr/bin/env nit +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import bench_base import pipeline @@ -9,7 +22,7 @@ class TypeTestDepthNotGenerator redef fun initnit(res) do res.add "new {classes.last}[Root]" - for c in classes.skip_tail(1) do + for c in classes.iterator.skip_tail(1) do res.add "new {c}[Root]" end end @@ -25,7 +38,7 @@ class TypeTestDepthNotGenerator var tagc = "" if interfaces then tagc = "X" res.add "new {tagc}{classes.last}()" - for c in classes.skip_tail(1) do + for c in classes.iterator.skip_tail(1) do res.add "new {tagc}{c}()" end end @@ -40,7 +53,7 @@ class TypeTestDepthNotGenerator var tagc = "" if interfaces then tagc = "X" res.add "new {tagc}{classes.last}()" - for c in classes.skip_tail(1) do + for c in classes.iterator.skip_tail(1) do res.add "new {tagc}{c}()" end end @@ -55,7 +68,7 @@ class TypeTestDepthNotGenerator var tagc = "" if interfaces then tagc = "X" res.add "new {tagc}{classes.last}[Root]()" - for c in classes.skip_tail(1) do + for c in classes.iterator.skip_tail(1) do res.add "new {tagc}{c}[Root]()" end end @@ -68,7 +81,7 @@ class TypeTestDepthNotGenerator redef fun initcpp(res) do res.add "new {classes.last}()" - for c in classes.skip_tail(1) do + for c in classes.iterator.skip_tail(1) do res.add "new {c}()" end end @@ -81,9 +94,9 @@ class TypeTestDepthNotGenerator redef fun inite(res, se) do - res.add "create \{{classes.last}[ROOT]\} a" - for c in classes.skip_tail(1) do - res.add "create \{{c}[ROOT]\} a" + res.add "create \{{classes.last}[ROOT]\}" + for c in classes.iterator.skip_tail(1) do + res.add "create \{{c}[ROOT]\}" end end @@ -95,7 +108,19 @@ class TypeTestDepthNotGenerator redef fun locale(se) do - write "\t\t\tto: {classes.last}[ROOT]" + write "\t\t\tto: detachable {classes.last}[ROOT]" + end + + redef fun initpython(res) + do + res.add "{classes.last}()" + for c in classes.iterator.skip_tail(1) do + res.add "{c}()" + end + end + redef fun testpython + do + return "not isinstance(a, {classes.last})" end end diff --git a/benchmarks/languages/bench_typetest_fts_nesting.nit b/benchmarks/languages/benches/bench_typetest_fts_nesting.nit similarity index 51% rename from benchmarks/languages/bench_typetest_fts_nesting.nit rename to benchmarks/languages/benches/bench_typetest_fts_nesting.nit index 732dab3..f8c52af 100644 --- a/benchmarks/languages/bench_typetest_fts_nesting.nit +++ b/benchmarks/languages/benches/bench_typetest_fts_nesting.nit @@ -1,4 +1,17 @@ #!/usr/bin/env nit +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import bench_base @@ -8,15 +21,16 @@ class TypeTestFtsNestingGenerator fun clanit(i: Int): String do var s = new FlatBuffer - s.append("{classes.first}[" * i) + s.append("{classes[i]}[") + s.append("{classes.first}[" * (dept-1)) s.append("Root") - s.append("]" * i) + s.append("]" * dept) return s.to_s end redef fun initnit(res) do - for i in [1..dept] do + for i in [0..dept[ do res.add "new {clanit(i)}" end @@ -30,32 +44,18 @@ class TypeTestFtsNestingGenerator fun clajava(i: Int): String do var s = new FlatBuffer - s.append("{classes.first}<" * i) + s.append("{classes[i]}<") + s.append("{classes.first}<" * (dept-1)) s.append("Root") - s.append(">" * i) + s.append(">" * dept) return s.to_s end - redef fun initjava(res, interfaces) - do - - var tagc = "" - if interfaces then tagc = "X" - for i in [1..dept] do - res.add "new {tagc}{clajava(i)}()" - end - end - - redef fun testjava(interfaces) - do - return "a instanceof {classes.first}" - end - redef fun initcsharp(res, interfaces) do var tagc = "" if interfaces then tagc = "X" - for i in [1..dept] do + for i in [0..dept[ do res.add "new {tagc}{clajava(i)}()" end end @@ -65,32 +65,19 @@ class TypeTestFtsNestingGenerator return "a is {clajava(middle)}" end - redef fun initscala(res, interfaces) - do - var tagc = "" - if interfaces then tagc = "X" - for i in [1..dept] do - res.add "new {tagc}{clanit(i)}()" - end - end - - redef fun testscala(interfaces) - do - return "a.isInstanceOf[{clanit(middle)}]" - end - fun clacpp(i: Int): String do var s = new FlatBuffer - s.append("{classes.first}<" * i) + s.append("{classes[i]}<") + s.append("{classes.first}<" * (dept-1)) s.append("Root") - s.append("*>" * i) + s.append("*>" * dept) return s.to_s end redef fun initcpp(res) do - for i in [1..dept] do + for i in [0..dept[ do res.add "new {clacpp(i)}()" end end @@ -104,16 +91,17 @@ class TypeTestFtsNestingGenerator fun clae(i: Int): String do var s = new FlatBuffer - s.append("{classes.first}[" * i) + s.append("{classes[i]}[") + s.append("{classes.first}[" * (dept-1)) s.append("ROOT") - s.append("]" * i) + s.append("]" * dept) return s.to_s end redef fun inite(res, se) do - for i in [1..dept] do - res.add "create \{{clae(i)}\} a" + for i in [0..dept[ do + res.add "create \{{clae(i)}\}" end end @@ -125,7 +113,7 @@ class TypeTestFtsNestingGenerator redef fun locale(se) do - write "\t\t\tto: {clae(middle)}" + write "\t\t\tto: detachable {clae(middle)}" end end diff --git a/benchmarks/markdown/engines/nitmd/nitmd.nit b/benchmarks/markdown/engines/nitmd/nitmd.nit index 2db91b2..09c7d07 100644 --- a/benchmarks/markdown/engines/nitmd/nitmd.nit +++ b/benchmarks/markdown/engines/nitmd/nitmd.nit @@ -19,6 +19,7 @@ var n = args[1].to_i var str = file.to_path.read_all var parser = new MarkdownProcessor +parser.no_location = true for i in [1..n] do print parser.process(str) end diff --git a/contrib/benitlux/Makefile b/contrib/benitlux/Makefile index 7041b04..be1543b 100644 --- a/contrib/benitlux/Makefile +++ b/contrib/benitlux/Makefile @@ -2,13 +2,22 @@ all: server pre-build: src/benitlux_serial.nit -server: +bin/benitlux_daily: $(shell ../../bin/nitls -M src/benitlux_daily.nit) mkdir -p bin/ - ../../bin/nitc --dir bin/ src/benitlux_daily.nit src/benitlux_web.nit + ../../bin/nitc -o $@ src/benitlux_daily.nit + +bin/benitlux_web: $(shell ../../bin/nitls -M src/benitlux_web.nit) + mkdir -p bin/ + ../../bin/nitc -o $@ src/benitlux_web.nit + +server: bin/benitlux_daily bin/benitlux_web src/benitlux_serial.nit: ../../bin/nitserial -o $@ src/benitlux_web.nit +# --- +# Report + bin/report: $(shell ../../bin/nitls -M src/report.nit) ../../bin/nitc -o bin/report src/report.nit diff --git a/contrib/benitlux/src/benitlux_controller.nit b/contrib/benitlux/src/benitlux_controller.nit index f124315..806b42e 100644 --- a/contrib/benitlux/src/benitlux_controller.nit +++ b/contrib/benitlux/src/benitlux_controller.nit @@ -96,7 +96,7 @@ class BenitluxRESTAction if not words.is_empty and words.first.is_empty then words.shift if words.length >= 2 and words[0] == "since" then - var since = words[1] + var since = words[1].std_date var db = new DB.open(db_path) var events = db.beer_events_since(since.to_sql_string) @@ -123,3 +123,21 @@ class BenitluxRESTAction return response end end + +redef class Text + # Rewrite the date represented by `self` in the format expected by SQLite + private fun std_date: String + do + var parts = self.split("-") + if parts.length != 3 then return "1970-01-01" + + var y = parts[0].to_s + var m = parts[1].to_s + var d = parts[2].to_s + + m = "0"*(2 - m.length) + m + d = "0"*(2 - d.length) + d + + return "{y}-{m}-{d}" + end +end diff --git a/contrib/benitlux/src/benitlux_daily.nit b/contrib/benitlux/src/benitlux_daily.nit index f9e8400..27b8169 100644 --- a/contrib/benitlux/src/benitlux_daily.nit +++ b/contrib/benitlux/src/benitlux_daily.nit @@ -175,7 +175,8 @@ class Benitlux for line in lines do var parts = line.split("- ") if parts.length >= 2 then - beers.add new Beer(parts[0].trim, parts[1].trim) + # Let the DB set the id, use 0 temporary + beers.add new Beer(0, parts[0].trim, parts[1].trim) end end return beers diff --git a/contrib/benitlux/src/benitlux_db.nit b/contrib/benitlux/src/benitlux_db.nit index 36906c8..14cf229 100644 --- a/contrib/benitlux/src/benitlux_db.nit +++ b/contrib/benitlux/src/benitlux_db.nit @@ -95,23 +95,23 @@ class DB var events = new BeerEvents # New - var stmt = select("name, desc FROM beers WHERE " + - "ROWID IN (SELECT beer FROM daily WHERE date(day) = date('now')) AND " + + var stmt = select("ROWID, name, desc FROM beers WHERE " + + "ROWID IN (SELECT beer FROM daily WHERE day=(SELECT MAX(day) FROM daily)) AND " + "NOT ROWID IN (SELECT beer FROM daily WHERE date(day) = date({prev_day}))") if stmt == null then return null for row in stmt do events.new_beers.add row.to_beer # Gone - stmt = select("name, desc FROM beers WHERE " + - "NOT ROWID IN (SELECT beer FROM daily WHERE date(day) = date('now')) AND " + - "ROWID IN (SELECT beer FROM daily WHERE date(day) = date({prev_day}))") + stmt = select("ROWID, name, desc FROM beers WHERE " + + "NOT ROWID IN (SELECT beer FROM daily WHERE day=(SELECT MAX(day) FROM daily)) AND " + + "ROWID IN (SELECT beer FROM daily WHERE date(day) = date({prev_day}))") if stmt == null then return null for row in stmt do events.gone_beers.add row.to_beer # Fix - stmt = select("name, desc FROM beers WHERE " + - "ROWID IN (SELECT beer FROM daily WHERE date(day) = date('now')) AND " + - "ROWID IN (SELECT beer FROM daily WHERE date(day) = date({prev_day}))") + stmt = select("ROWID, name, desc FROM beers WHERE " + + "ROWID IN (SELECT beer FROM daily WHERE day=(SELECT MAX(day) FROM daily)) AND " + + "ROWID IN (SELECT beer FROM daily WHERE date(day) = date({prev_day}))") if stmt == null then return null for row in stmt do events.fix_beers.add row.to_beer @@ -123,11 +123,20 @@ class DB # Return `null` on error. fun beers: nullable Array[Beer] do - var stmt = select("name, desc FROM beers") + var stmt = select("rowid, name, desc FROM beers") if stmt == null then return null return [for row in stmt do row.to_beer] end + # Load beer information from its database id + fun beer_from_id(id: Int): nullable Beer + do + var stmt = select("ROWID, name, desc FROM beers WHERE ROWID = {id}") + if stmt == null then return null + for row in stmt do return row.to_beer + return null + end + # Days where `beer` was available, all known days if `beer == null` # # Return `null` on error. @@ -172,5 +181,5 @@ end redef class StatementRow # Convert this BD row to a `Beer` - fun to_beer: Beer do return new Beer(self[0].to_s, self[1].to_s) + fun to_beer: Beer do return new Beer(self[0].to_i, self[1].to_s, self[2].to_s) end diff --git a/contrib/benitlux/src/benitlux_model.nit b/contrib/benitlux/src/benitlux_model.nit index 4649a5c..a186212 100644 --- a/contrib/benitlux/src/benitlux_model.nit +++ b/contrib/benitlux/src/benitlux_model.nit @@ -23,6 +23,9 @@ import serialization class Beer auto_serializable + # Database id + var id: Int + # Name of the beer var name: String diff --git a/contrib/benitlux/src/benitlux_web.nit b/contrib/benitlux/src/benitlux_web.nit index 90e7d24..9739241 100644 --- a/contrib/benitlux/src/benitlux_web.nit +++ b/contrib/benitlux/src/benitlux_web.nit @@ -21,10 +21,8 @@ import benitlux_model import benitlux_view import benitlux_controller -# Avoid executing when running tests -if "NIT_TESTING".environ == "true" then exit 0 - -var iface = "localhost:8080" +# Listening interface +fun iface: String do return "localhost:8080" var vh = new VirtualHost(iface) vh.routes.add new Route("/rest/", new BenitluxRESTAction) diff --git a/contrib/benitlux/src/correct.nit b/contrib/benitlux/src/correct.nit index 3c2384c..b840e3d 100644 --- a/contrib/benitlux/src/correct.nit +++ b/contrib/benitlux/src/correct.nit @@ -68,7 +68,7 @@ redef class DB # Merge days of `corrections` to `beer` for from, to in corrections do if to == beer.name then - var missing_days = super(new Beer(from, "")) + var missing_days = super(new Beer(0, from, "")) if missing_days != null then days.add_all missing_days end end diff --git a/contrib/jwrapper/examples/android_api/Makefile b/contrib/jwrapper/examples/android_api/Makefile index f7ce401..0dc6526 100644 --- a/contrib/jwrapper/examples/android_api/Makefile +++ b/contrib/jwrapper/examples/android_api/Makefile @@ -19,6 +19,11 @@ bitmap.nit: ../../bin/jwrapper ../../bin/jwrapper -vv -u comment -o $@ -r "^(android.graphics.Bitmap|java.nio.Buffer|java.nio.ByteBuffer).class$$" \ -i ../../../../lib/android/assets_and_resources.nit $(ANDROID_JAR) -i ../../../../lib/java/collections.nit +# Base wrappers to implement the lib/android/wifi.nit module +wifi.nit: ../../bin/jwrapper + ../../bin/jwrapper -vv -u comment -o $@ -r "^(android.net.wifi)" \ + -i ../../../../lib/android/assets_and_resources.nit $(ANDROID_JAR) -i ../../../../lib/java/collections.nit + check: android_api.nit ../../../../bin/nitpick android_api.nit diff --git a/contrib/nitcc/src/nitcc.sablecc b/contrib/nitcc/src/nitcc.sablecc index c3208ae..18d52cc 100644 --- a/contrib/nitcc/src/nitcc.sablecc +++ b/contrib/nitcc/src/nitcc.sablecc @@ -7,7 +7,7 @@ Lexer id = ('a'..'z')('a'..'z'|'0'..'9'|'_')*; // A printable character (inside strings) -ch = ' ' .. '~'; +ch = ' ' ...; // Literal strings str = '\'' (ch-'\\'-'\''|'\\'ch)* '\''; @@ -21,7 +21,7 @@ ch_hex = '#' ('x'|'X') ('0'..'9'|'a'..'z'|'A'..'Z')+ ; // A single-line comment comment = '//' ch* '\n'?; -any = '\t'..'~'; +any = '\t' ...; not_star = any - '*'; not_star_not_slash = not_star - '/'; @@ -67,6 +67,7 @@ re3 {-> re} = {id:} id | {par:} '(' re ')' | {class:} text '.' '.' text | + {openclass:} text '.' '.' '.' | {any:} 'Any' | {end:} 'End' | {text:} text ; diff --git a/contrib/nitcc/src/nitcc_parser_gen.nit b/contrib/nitcc/src/nitcc_parser_gen.nit index c15238b..bf3d57b 100644 --- a/contrib/nitcc/src/nitcc_parser_gen.nit +++ b/contrib/nitcc/src/nitcc_parser_gen.nit @@ -141,6 +141,7 @@ p_re3.new_alt("re_shortest", t_shortest, t_opar, p_re, t_cpar) p_re3.new_alt("re_longest", t_longest, t_opar, p_re, t_cpar) p_re3.new_alt("re_par", t_opar, p_re, t_cpar) p_re3.new_alt("re_class", p_text, t_dot, t_dot, p_text) +p_re3.new_alt("re_openclass", p_text, t_dot, t_dot, t_dot) p_re3.new_alt("re_any", t_any) p_re3.new_alt("re_end", t_end) p_re3.new_alt("re_id", t_id) diff --git a/contrib/nitcc/src/re2nfa.nit b/contrib/nitcc/src/re2nfa.nit index 886eaea..d523e51 100644 --- a/contrib/nitcc/src/re2nfa.nit +++ b/contrib/nitcc/src/re2nfa.nit @@ -223,7 +223,7 @@ redef class Nre_class var c1 = children[0].children[0].value var c2 = children[3].children[0].value if c1.length != 1 or c2.length != 1 then - print "Classes only works on single char" + print "Classes expect a single char" exit(1) abort end @@ -232,6 +232,20 @@ redef class Nre_class end end +redef class Nre_openclass + redef fun make_rfa: Automaton + do + var c1 = children[0].children[0].value + if c1.length != 1 then + print "Classes expect a single char" + exit(1) + abort + end + var a = new Automaton.cla(c1.chars.first.code_point, null) + return a + end +end + redef class Nre_any redef fun make_rfa: Automaton do diff --git a/contrib/nitcc/tests/lexer-any.input b/contrib/nitcc/tests/lexer-any.input index 955bebf..a679988 100644 --- a/contrib/nitcc/tests/lexer-any.input +++ b/contrib/nitcc/tests/lexer-any.input @@ -2,3 +2,4 @@ aa bb cc dd +ee diff --git a/contrib/nitcc/tests/lexer-any.sablecc b/contrib/nitcc/tests/lexer-any.sablecc index 5b248a6..4abc863 100644 --- a/contrib/nitcc/tests/lexer-any.sablecc +++ b/contrib/nitcc/tests/lexer-any.sablecc @@ -6,10 +6,11 @@ a = 'a' Any; b = 'b' (Any - 'b'); c = 'c' (#0..'c'); d = 'd' (Any-(#0..'c')); +e = 'e' 'e'...; blank = #10 | #13 | #32; Parser Ignored blank; p = t+; -t = a | b | c | d; +t = a | b | c | d | e; diff --git a/contrib/nitcc/tests/sav/lexer-any.input.res b/contrib/nitcc/tests/sav/lexer-any.input.res index 6cc0cff..1250e0c 100644 --- a/contrib/nitcc/tests/sav/lexer-any.input.res +++ b/contrib/nitcc/tests/sav/lexer-any.input.res @@ -9,4 +9,6 @@ Start c@(3:1-3:3)='cc' t_3 d@(4:1-4:3)='dd' - Eof@(5:1-5:1)='' + t_4 + e@(5:1-5:3)='ee' + Eof@(6:1-6:1)='' diff --git a/contrib/opportunity/art/opportunity.svg b/contrib/opportunity/art/opportunity.svg new file mode 100644 index 0000000..2614e5f --- /dev/null +++ b/contrib/opportunity/art/opportunity.svg @@ -0,0 +1,394 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + Layer 1 + + + Opportunité + + + + + + + + + + + + + + + Opportunity + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Opportunité + + + + diff --git a/contrib/opportunity/src/opportunity_web.nit b/contrib/opportunity/src/opportunity_web.nit index 05e8e4e..bbee410 100644 --- a/contrib/opportunity/src/opportunity_web.nit +++ b/contrib/opportunity/src/opportunity_web.nit @@ -19,13 +19,11 @@ import opportunity_controller import opts import privileges -# Avoids a crash when running automatic tests -if "NIT_TESTING".environ == "true" then exit 0 - var iface = "localhost:8080" var vh = new VirtualHost(iface) vh.routes.add new Route("/rest/", new OpportunityRESTAction) +vh.routes.add new Route("/static/", new FileServer("art")) vh.routes.add new Route(null, new OpportunityWelcome) var fac = new HttpFactory.and_libevent diff --git a/contrib/opportunity/src/templates/boilerplate.nit b/contrib/opportunity/src/templates/boilerplate.nit index e00ce4c..53996b0 100644 --- a/contrib/opportunity/src/templates/boilerplate.nit +++ b/contrib/opportunity/src/templates/boilerplate.nit @@ -92,7 +92,7 @@ class OpportunityFooter {{{"Opportunity, the meetup planner."}}}

- {{{"Proudly powered by %1!".format("Nit")}}} + {{{"Proudly powered by %0!".format("Nit")}}}

diff --git a/contrib/opportunity/src/templates/languages/fr/LC_MESSAGES/boilerplate.po b/contrib/opportunity/src/templates/languages/fr/LC_MESSAGES/boilerplate.po index 443192e..ab9b9f7 100644 --- a/contrib/opportunity/src/templates/languages/fr/LC_MESSAGES/boilerplate.po +++ b/contrib/opportunity/src/templates/languages/fr/LC_MESSAGES/boilerplate.po @@ -7,5 +7,5 @@ msgstr "Opportunité" msgid "Opportunity, the meetup planner." msgstr "Opportunité, l'organisateur d'événements." -msgid "Proudly powered by %1!" -msgstr "Fièrement codé en %1!" +msgid "Proudly powered by %0!" +msgstr "Fièrement codé en %0!" diff --git a/contrib/opportunity/src/templates/meetup.nit b/contrib/opportunity/src/templates/meetup.nit index c243407..71d18e1 100644 --- a/contrib/opportunity/src/templates/meetup.nit +++ b/contrib/opportunity/src/templates/meetup.nit @@ -458,7 +458,7 @@ redef class Meetup - {{{"%1 ratio × %2".format("∇", "")}}} + {{{"%0 ratio × %1".format("∇", "")}}} """ for i in answers(db) do t.add """ diff --git a/contrib/opportunity/src/templates/welcome.nit b/contrib/opportunity/src/templates/welcome.nit index 2d321da..0ea1cf2 100644 --- a/contrib/opportunity/src/templates/welcome.nit +++ b/contrib/opportunity/src/templates/welcome.nit @@ -23,18 +23,19 @@ class OpportunityHomePage init do body = """ - -

-

{{{"Opportunity is a free (as in free software), easy-to-use, meetup planner."}}}

-

{{{"You can start using it right now by creating a new Meetup and sharing it with your friends!"}}}

-

-

- -
-

-

+
+

+ +
+

+ {{{"Opportunity is a free (as in free software), easy-to-use, meetup planner."}}} + {{{"You can start using it right now by creating a new Meetup and sharing it with your friends!"}}} +

+
+ +
+
+
""" end end diff --git a/contrib/pep8analysis/www/index.html b/contrib/pep8analysis/www/index.html index 46b62be..f3ec358 100644 --- a/contrib/pep8analysis/www/index.html +++ b/contrib/pep8analysis/www/index.html @@ -133,10 +133,10 @@