From: Jean Privat Date: Tue, 22 Sep 2015 19:41:37 +0000 (-0400) Subject: Merge: new game: memory X-Git-Tag: v0.7.8~11 X-Git-Url: http://nitlanguage.org?hp=92417608bd606362794f9501c6b4aabf6ca7192e Merge: new game: memory The code is good enough and the game complete enough I think. Pull-Request: #1730 Reviewed-by: Lucas Bajolet Reviewed-by: Alexis Laferrière --- diff --git a/benchmarks/.gitignore b/benchmarks/.gitignore index 43fa343..b6bd96d 100644 --- a/benchmarks/.gitignore +++ b/benchmarks/.gitignore @@ -7,3 +7,5 @@ index.html nitc nitdoc nitdoc.* +logs +nit_compile diff --git a/benchmarks/Makefile b/benchmarks/Makefile new file mode 100644 index 0000000..6c62287 --- /dev/null +++ b/benchmarks/Makefile @@ -0,0 +1,5 @@ +all: + ./bench_engines.sh all + +check: + ./bench_engines.sh --fast --fast bench_nitc_options diff --git a/benchmarks/bench_common.sh b/benchmarks/bench_common.sh index 4ea5ffe..207edd0 100644 --- a/benchmarks/bench_common.sh +++ b/benchmarks/bench_common.sh @@ -94,3 +94,9 @@ function skip_test() return 1 } +# Helper function. Print the error message and set $died to 1 +function die() +{ + echo >&2 "error: $*" + died=1 +} diff --git a/benchmarks/bench_engines.sh b/benchmarks/bench_engines.sh index b2534e7..37b2fb9 100755 --- a/benchmarks/bench_engines.sh +++ b/benchmarks/bench_engines.sh @@ -26,14 +26,6 @@ source ./bench_plot.sh # Can be overrided with 'the option -n' count=2 -### HELPER FUNCTIONS ## - -function die() -{ - echo >&2 "error: $*" - died=1 -} - # HELPER FOR NIT # # Run standards benchs on a compiler command @@ -93,7 +85,6 @@ function usage() echo " -n count: number of execution for each bar (default: $count)" echo " --dry: Do not run the commands, just reuse the data and generate the graph" echo " --fast: Run less and faster tests" - echo " --html: Generate and HTML output" echo " -h: this help" } @@ -105,11 +96,14 @@ while [ "$stop" = false ]; do -n) count="$2"; shift; shift;; --dry) dry_run=true; shift;; --fast) fast=true$fast; shift;; - --html) html="index.html"; echo >"$html" ""; shift;; + --html) shift;; # Deprecated *) stop=true esac done +html="index.html" +echo >"$html" "" + xml="bench_engines.xml" echo "" > "$xml" @@ -195,12 +189,12 @@ function bench_nitc_options() for opt in "$@"; do ot=${opt// /} - prepare_res "$name$ot.dat" "$opt" "nitc-g with option $opt" + prepare_res "$name$ot.dat" "$opt" "nitc with option $opt" run_compiler "nitc-$name" ./nitc $common $opt done if test -n "$2" -a -n "$withall"; then - prepare_res "$name-all.dat" "all" "nitc-g with all options $@" + prepare_res "$name-all.dat" "all" "nitc with all options $@" run_compiler "nitc-$name" ./nitc $common $@ fi @@ -210,20 +204,22 @@ function bench_nitc_options() bench_nitc_options "slower" --global --hardening --no-shortcut-range bench_nitc_options "nocheck" --global --no-check-null --no-check-autocast --no-check-attr-isset --no-check-covariance --no-check-assert -bench_nitc_options "slower" --separate --hardening --no-shortcut-equal --no-union-attribute --no-shortcut-range --no-inline-intern "--no-gcc-directive likely --no-gcc-directive noreturn" "--no-tag-primitives" +bench_nitc_options "slower" --separate --hardening --no-shortcut-equal --no-union-attribute --no-shortcut-range --no-inline-intern "--no-gcc-directive likely --no-gcc-directive noreturn" "--no-tag-primitives" "--colo-dead-methods" --type-poset bench_nitc_options "nocheck" --separate --no-check-null --no-check-autocast --no-check-attr-isset --no-check-covariance --no-check-assert bench_nitc_options "faster" --separate --skip-dead-methods --inline-coloring-numbers --inline-some-methods --direct-call-monomorph "--inline-some-methods --direct-call-monomorph" bench_nitc_options "slower" --erasure --hardening --no-shortcut-equal --no-union-attribute --no-shortcut-range --no-inline-intern -bench_nitc_options "nocheck" --erasure --no-check-null --no-check-autocast --no-check-attr-isset --no-check-covariance --no-check-assert --no-check-erasure-cast +bench_nitc_options "nocheck" --erasure --no-check-null --no-check-autocast --no-check-attr-isset --no-check-covariance --no-check-assert --no-check-erasure-cast --no-check-all bench_nitc_options "faster" --erasure --skip-dead-methods --inline-coloring-numbers --inline-some-methods --direct-call-monomorph --rta bench_nitc_options "engine" "" NOALL "--separate" "--erasure" "--separate --semi-global" "--erasure --semi-global" "--erasure --semi-global --rta" "--global" bench_nitc_options "policy" "" NOALL "--separate" "--erasure" "--separate --no-check-covariance" "--erasure --no-check-covariance --no-check-erasure-cast" bench_nitc_options "nullables" "" "--no-check-attr-isset" "--no-union-attribute" -bench_nitc_options "linkboost" "" NOALL --trampoline-call --colors-are-symbols "--colors-are-symbols --trampoline-call" "--separate --link-boost" "--separate --colors-are-symbols --guard-call" "--separate --colors-are-symbols --direct-call-monomorph0" +bench_nitc_options "linkboost" "" NOALL --trampoline-call --colors-are-symbols "--colors-are-symbols --trampoline-call" "--separate --link-boost" "--separate --colors-are-symbols --guard-call" "--separate --colors-are-symbols --direct-call-monomorph0" "--substitute-monomorph" bench_nitc_options "monomorph" "" --direct-call-monomorph0 --direct-call-monomorph +bench_nitc_options "misc" "" --log --typing-test-metrics --invocation-metrics --isset-checks-metrics --tables-metrics --no-stacktrace --release --debug #FIXME add --sloppy + function bench_nitc-e_gc() { name="$FUNCNAME" @@ -272,9 +268,7 @@ function bench_compilation_time } bench_compilation_time -if test -n "$html"; then - echo >>"$html" "" -fi +echo >>"$html" "" echo >>"$xml" "" diff --git a/benchmarks/bench_languages.sh b/benchmarks/bench_languages.sh index 0e0b59a..2a33170 100755 --- a/benchmarks/bench_languages.sh +++ b/benchmarks/bench_languages.sh @@ -26,14 +26,6 @@ source ./bench_plot.sh # Can be overrided with 'the option -n' count=2 -### HELPER FUNCTIONS ## - -function die() -{ - echo >&2 "error: $*" - died=1 -} - ## HANDLE OPTIONS ## function usage() diff --git a/benchmarks/bench_nitdoc.sh b/benchmarks/bench_nitdoc.sh index 07613b2..4a1d2a7 100755 --- a/benchmarks/bench_nitdoc.sh +++ b/benchmarks/bench_nitdoc.sh @@ -24,14 +24,6 @@ source ./bench_plot.sh # Can be overrided with 'the option -n' count=3 -### HELPER FUNCTIONS ## - -function die() -{ - echo >&2 "error: $*" - died=1 -} - ## HANDLE OPTIONS ## function usage() diff --git a/benchmarks/bench_nitunit.sh b/benchmarks/bench_nitunit.sh index 53eb38c..23279f1 100755 --- a/benchmarks/bench_nitunit.sh +++ b/benchmarks/bench_nitunit.sh @@ -24,14 +24,6 @@ source ./bench_plot.sh # Can be overrided with 'the option -n' count=3 -### HELPER FUNCTIONS ## - -function die() -{ - echo >&2 "error: $*" - died=1 -} - ## HANDLE OPTIONS ## function usage() diff --git a/benchmarks/bench_plot.sh b/benchmarks/bench_plot.sh index e874308..08a13e6 100755 --- a/benchmarks/bench_plot.sh +++ b/benchmarks/bench_plot.sh @@ -103,7 +103,8 @@ if test -n "$html"; then echo gnuplot -e "set term png; set output \"$bn.png\"" "$1" echo >>"$html" "" -else +fi +if test -n "$DISPLAY"; then echo "# gnuplot -p $1" gnuplot -p "$1" fi diff --git a/benchmarks/markdown/Makefile b/benchmarks/markdown/Makefile index 802fab6..ca25141 100644 --- a/benchmarks/markdown/Makefile +++ b/benchmarks/markdown/Makefile @@ -15,6 +15,9 @@ all: ./bench_markdown.sh all +check: + ./bench_markdown.sh -s 1 nit + clean: $(MAKE) clean -C benches $(MAKE) clean -C engines diff --git a/benchmarks/markdown/bench_markdown.sh b/benchmarks/markdown/bench_markdown.sh index aaa34f0..485b944 100755 --- a/benchmarks/markdown/bench_markdown.sh +++ b/benchmarks/markdown/bench_markdown.sh @@ -24,13 +24,8 @@ source ../bench_plot.sh # Can be overrided with 'the option -n' count=2 -### HELPER FUNCTIONS ## - -function die() -{ - echo >&2 "error: $*" - died=1 -} +# Default number of times the input file is transformed during a single run +s=200 ## HANDLE OPTIONS ## @@ -39,6 +34,7 @@ function usage() echo "run_bench: [options]* benchname" echo " -v: verbose mode" echo " -n count: number of execution for each bar (default: $count)" + echo " -s size: number of transformations for each run (default: $s)" echo " --dry: Do not run the commands, just reuse the data and generate the graph" echo " -h: this help" } @@ -49,6 +45,7 @@ while [ "$stop" = false ]; do -v) verbose=true; shift;; -h) usage; exit;; -n) count="$2"; shift; shift;; + -s) s="$2"; shift; shift;; --dry) dry_run=true; shift;; *) stop=true esac @@ -73,8 +70,8 @@ outdir="./out" engdir="./engines" bncdir="./benches/out" mkdir -p $outdir - -s=200 +html="index.html" +echo >"$html" "" function bench_nitmd() { @@ -140,6 +137,8 @@ if test "$#" -gt 0; then plot $outdir/bench_markdown.gnu fi +echo >>"$html" "" + if test -n "$died"; then echo "Some commands failed" exit 1 diff --git a/benchmarks/polygons/Makefile b/benchmarks/polygons/Makefile index e6bd303..f7d0763 100644 --- a/benchmarks/polygons/Makefile +++ b/benchmarks/polygons/Makefile @@ -1,3 +1,6 @@ all: $(MAKE) all -C nit $(MAKE) all -C java + +check: + $(MAKE) check -C nit diff --git a/benchmarks/polygons/nit/Makefile b/benchmarks/polygons/nit/Makefile index e327368..71dffea 100644 --- a/benchmarks/polygons/nit/Makefile +++ b/benchmarks/polygons/nit/Makefile @@ -17,3 +17,11 @@ convexity_b: contain_b: ./bench_polygon.sh contain + +check: + ./bench_polygon.sh -p 100 add_vertex + ./bench_polygon.sh -p 100 sort_vertices + ./bench_polygon.sh -p 100 intersection + ./bench_polygon.sh -p 100 convex_hull + ./bench_polygon.sh -p 100 convexity + ./bench_polygon.sh -p 100 contain diff --git a/benchmarks/polygons/nit/bench_polygon.sh b/benchmarks/polygons/nit/bench_polygon.sh index 52895e9..8b7fc08 100755 --- a/benchmarks/polygons/nit/bench_polygon.sh +++ b/benchmarks/polygons/nit/bench_polygon.sh @@ -166,3 +166,9 @@ case "$1" in contain) shift; bench_contain $@;; *) usage; exit;; esac + +if test -n "$died"; then + echo "Some commands failed" + exit 1 +fi +exit 0 diff --git a/benchmarks/strings/Makefile b/benchmarks/strings/Makefile index 3717681..2453d1b 100644 --- a/benchmarks/strings/Makefile +++ b/benchmarks/strings/Makefile @@ -12,6 +12,8 @@ iter: index: ./bench_strings.sh index 10000000 50 25 200 +check: basic + basic: ./bench_strings.sh basic diff --git a/benchmarks/strings/bench_strings.sh b/benchmarks/strings/bench_strings.sh index 7a09065..5d24653 100755 --- a/benchmarks/strings/bench_strings.sh +++ b/benchmarks/strings/bench_strings.sh @@ -205,14 +205,14 @@ function launch_bench() echo " Trying variant $variant for benchmark $bench" echo "---------------------------------------------------------" git diff-index --quiet HEAD || { - echo "Cannot run benches on a dirty working directory." - echo "Please commit or stash your modifications and relaunch the command." - exit 1 + die "Cannot run benches on a dirty working directory." + die "Please commit or stash your modifications and relaunch the command." + return } git am $curr_rev || { - echo "Error when applying patch $curr_rev" - git am --abort; - exit 1; + die "Error when applying patch $curr_rev" + git am --abort + return } if [ "$need_bootstrap" = true ]; then prepare_compiler @@ -263,12 +263,6 @@ function main() bench=$1 shift; - git diff-index --quiet HEAD || { - echo "Cannot run benches on a dirty working directory." - echo "Please commit or stash your modifications and relaunch the command." - exit 1 - } - head=`git rev-parse HEAD` variant="HEAD" need_plot=true @@ -314,3 +308,9 @@ function main() } main "$@"; + +if test -n "$died"; then + echo "Some commands failed" + exit 1 +fi +exit 0 diff --git a/contrib/benitlux/package.ini b/contrib/benitlux/package.ini index 53acc9d..e53853c 100644 --- a/contrib/benitlux/package.ini +++ b/contrib/benitlux/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=contrib/benitlux/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +tryit=http://benitlux.xymus.net/ diff --git a/contrib/brainfuck/brainfuck.nit b/contrib/brainfuck/brainfuck.nit index f7de908..4216952 100644 --- a/contrib/brainfuck/brainfuck.nit +++ b/contrib/brainfuck/brainfuck.nit @@ -18,29 +18,24 @@ module brainfuck # Interpreter for Brainfuck source code. class BFInterpreter # Data cells - var dr = new Array[Char] + var dr = new Array[Byte] # Data pointer var dp = 0 # Instruction pointer var ip = 0 # The program being interpreted - var program: String - - # Contains the set of valid instructions, used in next - var valid_instr: Set[Char] is noinit + var program: Bytes # Create an interpreter for `program`. init do - valid_instr = new HashSet[Char] - valid_instr.add_all "><[].,+-".chars - dr.add 0.ascii + dr.add 0u8 end # Create an interpreter for the file located at `path`. init from_file(path: String) do var ifs = new FileReader.open(path) - init(ifs.read_all) + init(ifs.read_all_bytes) end # Starts the interpretation of the loaded program @@ -48,50 +43,43 @@ class BFInterpreter loop if ip >= program.length then break eval - next - end - end - - # Go to the next executable instruction - fun next do - ip += 1 - while ip < program.length and not valid_instr.has(program[ip]) do ip += 1 end end + # Evaluates the current instruction fun eval do var instr = program[ip] - if instr == '.' then printn dr[dp] - if instr == '[' then - if dr[dp] == 0.ascii then + if instr == '.'.ascii then printn dr[dp].ascii + if instr == '['.ascii then + if dr[dp] == 0u8 then ip = find_matching_rbra return end end - if instr == ']' then - if dr[dp] != 0.ascii then + if instr == ']'.ascii then + if dr[dp] != 0u8 then ip = find_matching_lbra return end end - if instr == '>' then + if instr == '>'.ascii then dp += 1 - if dp >= dr.length then dr.add(0.ascii) + if dp >= dr.length then dr.add(0u8) end - if instr == '<' then + if instr == '<'.ascii then dp -= 1 if dp < 0 then abort end - if instr == '+' then - dr[dp] = (dr[dp].ascii + 1).ascii + if instr == '+'.ascii then + dr[dp] = dr[dp] + 1u8 end - if instr == '-' then - dr[dp] = (dr[dp].ascii - 1).ascii + if instr == '-'.ascii then + dr[dp] = dr[dp] - 1u8 end - if instr == ',' then - dr[dp] = getc + if instr == ','.ascii then + dr[dp] = getc.ascii end end @@ -101,14 +89,14 @@ class BFInterpreter var lbracnt = 0 loop if pos > program.length then abort - if program[pos] == ']' then + if program[pos] == ']'.ascii then if lbracnt > 0 then lbracnt -= 1 else break end end - if program[pos] == '[' then lbracnt += 1 + if program[pos] == '['.ascii then lbracnt += 1 pos += 1 end return pos @@ -120,14 +108,14 @@ class BFInterpreter var rbracnt = 0 loop if pos < 0 then abort - if program[pos] == '[' then + if program[pos] == '['.ascii then if rbracnt > 0 then rbracnt -= 1 else break end end - if program[pos] == ']' then rbracnt += 1 + if program[pos] == ']'.ascii then rbracnt += 1 pos -= 1 end return pos diff --git a/contrib/crazy_moles/Makefile b/contrib/crazy_moles/Makefile index 049e851..113329d 100644 --- a/contrib/crazy_moles/Makefile +++ b/contrib/crazy_moles/Makefile @@ -1,3 +1,7 @@ + +SVG2ICONS=../inkscape_tools/bin/svg_to_icons +SVG2PNG=../inkscape_tools/bin/svg_to_png_and_nit + default: bin/moles bin/moles: $(shell ../../bin/nitls -M src/moles_linux.nit) assets/images/drawing.png @@ -13,19 +17,19 @@ android-release: android-icons $(shell ../../bin/nitls -M src/moles_android.nit) mkdir -p bin ../../bin/nitc -o bin/moles.apk src/moles_android.nit --release -../inkscape_tools/bin/svg_to_icons: +$(SVG2ICONS): $(MAKE) -C ../inkscape_tools -android-icons: ../../contrib/inkscape_tools/bin/svg_to_icons art/icon.svg +android-icons: $(SVG2ICONS) art/icon.svg mkdir -p res - ../inkscape_tools/bin/svg_to_icons art/icon.svg --android --out res/ + $(SVG2ICONS) art/icon.svg --android --out res/ android-install: bin/moles.apk adb install -rf bin/moles.apk -assets/images/drawing.png: art/drawing.svg ../../contrib/inkscape_tools/bin/svg_to_icons +assets/images/drawing.png: art/drawing.svg $(SVG2ICONS) mkdir -p assets/images - ../inkscape_tools/bin/svg_to_png_and_nit --src src/ --scale 2.0 art/drawing.svg + $(SVG2PNG) --src src/ --scale 2.0 art/drawing.svg check-android: bin/moles.apk ../../misc/jenkins/check_android.sh bin/moles.apk diff --git a/contrib/crazy_moles/package.ini b/contrib/crazy_moles/package.ini index 42eae16..719752f 100644 --- a/contrib/crazy_moles/package.ini +++ b/contrib/crazy_moles/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=contrib/crazy_moles/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +apk=http://nitlanguage.org/fdroid/apk/moles_android.apk diff --git a/contrib/friendz/package.ini b/contrib/friendz/package.ini index b1398f2..7ef0618 100644 --- a/contrib/friendz/package.ini +++ b/contrib/friendz/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=contrib/friendz/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +apk=http://nitlanguage.org/fdroid/apk/friendz_android.apk diff --git a/contrib/friendz/src/friendz.nit b/contrib/friendz/src/friendz.nit index 9425abe..c0554fe 100644 --- a/contrib/friendz/src/friendz.nit +++ b/contrib/friendz/src/friendz.nit @@ -19,7 +19,6 @@ import realtime import solver import mnit::tileset import app::data_store -import md5 intrude import grid intrude import level @@ -217,11 +216,11 @@ class LevelButton self.over = self.level.fullname if self.level.get_state >= l.l_won then - if game.levels[9].get_state >= l.l_won then self.over += " --- {self.level.score}/{self.level.par}" + if game.levels[9].get_state >= l.l_won then self.over += " --- {self.level.score}/{self.level.gold}" else if self.level.get_state >= l.l_open then - if game.levels[9].get_state >= l.l_open then self.over += " --- ?/{self.level.par}" + if game.levels[9].get_state >= l.l_open then self.over += " --- ?/{self.level.gold}" end - #self.enabled = l.get_state >= l.l_open + self.enabled = l.get_state >= l.l_open or game.cheated end redef fun draw(ctx) @@ -242,7 +241,7 @@ class LevelButton end ctx.blit(game.img[ix,iy], self.x, self.y) - if s == l.l_par then + if s == l.l_gold then ctx.blit(game.img2[7,0], self.x + bw*5/8, self.y-bh*1/8) end ctx.textx(self.level.name, self.x+5, self.y+5, 24, null, null) @@ -730,9 +729,9 @@ class Score end if game.levels[9].get_state >= level.l_won then if level.is_challenge then - ctx.textx("GOAL: {level.par}",self.x,self.y+44,21,"yellow",null) + ctx.textx("GOAL: {level.gold}",self.x,self.y+44,21,"yellow",null) else - ctx.textx("PAR: {level.par}",self.x,self.y+44,21,"yellow",null) + ctx.textx("GOLD: {level.gold}",self.x,self.y+44,21,"yellow",null) end end end @@ -777,7 +776,7 @@ class StatusBar do print "***STATUS** {txt}" self.tmp_txt = txt - self.tmp_txt_ttl = 20 + self.tmp_txt_ttl = 60 self.tmp_txt_color = color end @@ -873,26 +872,6 @@ redef class Game # Font var font = new TileSetFont(app.load_image("deltaforce_font.png"), 16, 17, "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789.:;!?\"'() -,/") - var xxx = """ - fun save_cookie(name, val:String) do - var days = 365 - var date = new Date() - date.setTime(date.getTime()+(days*24*60*60*1000)) - document.cookie = name+"="+val+"; expires="+date.toGMTString()+"; path=/" - end - - fun read_cookie(name:String):String do - var key = name + "=" - var ca = document.cookie.split(';') - for(var i=0; i 0 then score else null + app.data_store["s{str}"] = if score > 0 then score else null + var saved = game.grid.save + saved_str = saved + app.data_store["g{str}"] = saved + print "SAVE: {name}: {saved}" end + + # The saved player grid (to continue games) + var saved_str: nullable String = null end diff --git a/contrib/friendz/src/grid.nit b/contrib/friendz/src/grid.nit index a097ff5..6f1c883 100644 --- a/contrib/friendz/src/grid.nit +++ b/contrib/friendz/src/grid.nit @@ -191,14 +191,14 @@ class Grid fun save: String do var res = "" - var str = ".#ABCDEFGHI" + var str = ".abcdefghi#ABCDEFGHI" for y in [0..height[ do var rle = 0 var last: nullable Int = null for x in [0..width[ do var t = self.grid[x][y] - var tk = 0 - if t.fixed then tk = t.kind + 1 + var tk = t.kind + if t.fixed then tk += 10 if tk == last and rle<9 then rle += 1 else @@ -243,14 +243,20 @@ class Grid x += 1 else if c == '#' then var t = self.get(x,y) + assert t != null t.fixed = true x += 1 else if c >= 'A' and c <= 'I' then var t = self.get(x,y) assert t != null - t.update(c.ascii-'A'.ascii+1) + t.update(c.code_point-'A'.code_point+1) t.fixed = true x += 1 + else if c >= 'a' and c <= 'i' then + var t = self.get(x,y) + assert t != null + t.update(c.code_point-'a'.code_point+1) + x += 1 else if c >= '1' and c <= '9' then rle = c.to_i else @@ -261,7 +267,7 @@ class Grid if x>0 then y += 1 if x > mx then mx = x if y > my then my = y - if mx<3 or my<3 or mx>=max_width or my>=max_height then + if mx<3 or my<3 or mx>max_width or my>max_height then return false end self.resize(mx,my) @@ -283,16 +289,16 @@ class Grid if k == 0 then if t.fixed then c = '#' else - b.add(0x1b.ascii) + b.add(0x1b.code_point) b.add('[') b.append ansicols[k] - c = (k + 'a'.ascii - 1).ascii + c = (k + 'a'.code_point - 1).code_point if t.fixed then c = c.to_upper b.append("m") end b.add(c) if k != 0 then - b.add(0x1b.ascii) + b.add(0x1b.code_point) b.append("[0m") end diff --git a/contrib/friendz/src/level.nit b/contrib/friendz/src/level.nit index 9d8029e..b09f1f2 100644 --- a/contrib/friendz/src/level.nit +++ b/contrib/friendz/src/level.nit @@ -23,7 +23,7 @@ class Level var ls = code.split(";") self.number = i self.str = ls[0] - self.par = ls[1].to_i + self.gold = ls[1].to_i if ls.length >= 3 then self.status = ls[2] end @@ -47,8 +47,8 @@ class Level # initial grid position var str: String - # top score - var par: Int + # top score to get gold + var gold: Int # Help message if any var status: String = "" @@ -72,32 +72,28 @@ class Level var l_disabled = 1 var l_open = 2 var l_won = 3 - var l_par = 4 + var l_gold = 4 fun get_state: Int do if self.score == 0 then if self.number == 0 or game.levels[self.number-1].score > 0 then return l_open if self.number == 25 and game.levels[19].score > 0 then return l_open else return l_disabled - else if self.score < self.par or not game.levels[9].score > 0 then + else if self.score < self.gold or not game.levels[9].score > 0 then return l_won - else return l_par + else return l_gold end # Returns true if g is a wining condition for the level. fun check_won(g: Grid): Bool do - var w = g.won and (not self.is_challenge or g.number >= self.par) + var w = g.won and (not self.is_challenge or g.number >= self.gold) if not w then return false if g.number > self.score then self.score = g.number - self.save end return true end - - # Save the score of the level - fun save do end end # main game object diff --git a/contrib/mnit_test/org.nitlanguage.test_minimal.txt b/contrib/mnit_test/org.nitlanguage.test_minimal.txt new file mode 100644 index 0000000..9f3bb3c --- /dev/null +++ b/contrib/mnit_test/org.nitlanguage.test_minimal.txt @@ -0,0 +1,10 @@ +Categories:Nit +License:Apache2 +Web Site:http://nitlanguage.org +Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/contrib/mnit_test +Issue Tracker:https://github.com/nitlang/nit/issues + +Summary:Minimal Demo for MNit +Description: +A useless application that test various basic API usage of the mnit framework on Android. +. diff --git a/contrib/mnit_test/package.ini b/contrib/mnit_test/package.ini index 29856ff..adcdf8f 100644 --- a/contrib/mnit_test/package.ini +++ b/contrib/mnit_test/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=examples/mnit_simple/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +apk=http://nitlanguage.org/fdroid/apk/test_all.apk diff --git a/contrib/nitcc/src/autom.nit b/contrib/nitcc/src/autom.nit index 19e113c..946b420 100644 --- a/contrib/nitcc/src/autom.nit +++ b/contrib/nitcc/src/autom.nit @@ -714,7 +714,7 @@ private class DFAGenerator else add("\tredef fun trans(char) do\n") - add("\t\tvar c = char.ascii\n") + add("\t\tvar c = char.code_point\n") var haslast = false var last = -1 for sym, next in trans do @@ -791,14 +791,14 @@ class TSymbol if f <= 32 then res = "#{f}" else - res = f.ascii.to_s + res = f.code_point.to_s end var l = last if f == l then return res res += " .. " if l == null then return res if l <= 32 or l >= 127 then return res + "#{l}" - return res + l.ascii.to_s + return res + l.code_point.to_s end end diff --git a/contrib/nitcc/src/nitcc_semantic.nit b/contrib/nitcc/src/nitcc_semantic.nit index af417d4..795cee0 100644 --- a/contrib/nitcc/src/nitcc_semantic.nit +++ b/contrib/nitcc/src/nitcc_semantic.nit @@ -588,7 +588,7 @@ redef class Token if text != null then var nfa = new Automaton.epsilon for c in text.chars do - nfa.concat(new Automaton.atom(c.ascii)) + nfa.concat(new Automaton.atom(c.code_point)) end return nfa end diff --git a/contrib/nitcc/src/re2nfa.nit b/contrib/nitcc/src/re2nfa.nit index d0d90ac..886eaea 100644 --- a/contrib/nitcc/src/re2nfa.nit +++ b/contrib/nitcc/src/re2nfa.nit @@ -38,7 +38,7 @@ redef class Nstr do var a = new Automaton.epsilon for c in self.value.chars do - var b = new Automaton.atom(c.ascii) + var b = new Automaton.atom(c.code_point) a.concat(b) end return a @@ -46,19 +46,19 @@ redef class Nstr end redef class Nch_dec - redef fun value: String do return text.substring_from(1).to_i.ascii.to_s + redef fun value: String do return text.substring_from(1).to_i.code_point.to_s redef fun make_rfa: Automaton do - var a = new Automaton.atom(self.value.chars.first.ascii) + var a = new Automaton.atom(self.value.chars.first.code_point) return a end end redef class Nch_hex - redef fun value: String do return text.substring_from(2).to_hex.ascii.to_s + redef fun value: String do return text.substring_from(2).to_hex.code_point.to_s redef fun make_rfa: Automaton do - var a = new Automaton.atom(self.value.chars.first.ascii) + var a = new Automaton.atom(self.value.chars.first.code_point) return a end end @@ -227,7 +227,7 @@ redef class Nre_class exit(1) abort end - var a = new Automaton.cla(c1.chars.first.ascii, c2.chars.first.ascii) + var a = new Automaton.cla(c1.chars.first.code_point, c2.chars.first.code_point) return a end end diff --git a/contrib/nitrpg/package.ini b/contrib/nitrpg/package.ini index 125e96c..812edca 100644 --- a/contrib/nitrpg/package.ini +++ b/contrib/nitrpg/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=contrib/nitrpg/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +tryit=http://nitlanguage.org/rpg/games/nitlang/nit diff --git a/contrib/online_ide/package.ini b/contrib/online_ide/package.ini index ee1afbd..841f552 100644 --- a/contrib/online_ide/package.ini +++ b/contrib/online_ide/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=contrib/online_ide/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +tryit=http://nitlanguage.org/online_ide/ diff --git a/contrib/opportunity/package.ini b/contrib/opportunity/package.ini index 9e3dae9..5f819b4 100644 --- a/contrib/opportunity/package.ini +++ b/contrib/opportunity/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=contrib/opportunity/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +tryit=http://xymus.net/opportunity/ diff --git a/contrib/pep8analysis/package.ini b/contrib/pep8analysis/package.ini index 5f5fba5..43d5e4a 100644 --- a/contrib/pep8analysis/package.ini +++ b/contrib/pep8analysis/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=contrib/pep8analysis/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +tryit=http://pep8.xymus.net/ diff --git a/contrib/pep8analysis/src/location.nit b/contrib/pep8analysis/src/location.nit index 6fd9edf..634b695 100644 --- a/contrib/pep8analysis/src/location.nit +++ b/contrib/pep8analysis/src/location.nit @@ -165,7 +165,7 @@ class Location # * `"0;32"` for green fun colored_line(color: String): String do - var esc = 27.ascii + var esc = 27.code_point var def = "{esc}[0m" var col = "{esc}[{color}m" diff --git a/contrib/pep8analysis/src/model/operands.nit b/contrib/pep8analysis/src/model/operands.nit index 592e1af..d74d1f1 100644 --- a/contrib/pep8analysis/src/model/operands.nit +++ b/contrib/pep8analysis/src/model/operands.nit @@ -24,12 +24,12 @@ redef class ANumberValue end redef class ACharValue - redef fun to_i do return n_char.content.first.ascii + redef fun to_i do return n_char.content.first.code_point end redef class AStringValue # legal but no not recommended - redef fun to_i do return n_string.content.first.ascii + redef fun to_i do return n_string.content.first.code_point end redef class AHexValue diff --git a/contrib/pep8analysis/src/parser/lexer.nit b/contrib/pep8analysis/src/parser/lexer.nit index 912336c..718ee98 100644 --- a/contrib/pep8analysis/src/parser/lexer.nit +++ b/contrib/pep8analysis/src/parser/lexer.nit @@ -337,7 +337,7 @@ class Lexer if sp >= string_len then dfa_state = -1 else - var c = string[sp].ascii + var c = string[sp].code_point if c >= 255 then c = 255 sp += 1 diff --git a/contrib/tinks/net.xymus.tinks.txt b/contrib/tinks/net.xymus.tinks.txt new file mode 100644 index 0000000..ceed2bc --- /dev/null +++ b/contrib/tinks/net.xymus.tinks.txt @@ -0,0 +1,13 @@ +Categories:Nit,Games +License:Apache2 +Web Site:http://nitlanguage.org +Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/contrib/tinks +Issue Tracker:https://github.com/nitlang/nit/issues + +Summary:Multiplayer crossplatform action game with destructible procedurally generated worlds +Description: +Each player controls a tank, opens fire from the turret and navigates between the terrain features. +Explosions from turret fire and tank destruction have different forces and destroy the terrain. +Each tank needs 4 hits to be destroyed. +Destroyed tanks drop health power-ups which can repair other tanks. +. diff --git a/contrib/tinks/package.ini b/contrib/tinks/package.ini index dc04026..cf4f9ee 100644 --- a/contrib/tinks/package.ini +++ b/contrib/tinks/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=contrib/tinks/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +apk=http://nitlanguage.org/fdroid/apk/tinks.apk diff --git a/contrib/tnitter/package.ini b/contrib/tnitter/package.ini index 42a426c..26ba69a 100644 --- a/contrib/tnitter/package.ini +++ b/contrib/tnitter/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=contrib/tnitter/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +tryit=http://tnitter.xymus.net/ diff --git a/examples/calculator/Makefile b/examples/calculator/Makefile index edcfc14..24b10ab 100644 --- a/examples/calculator/Makefile +++ b/examples/calculator/Makefile @@ -1,17 +1,26 @@ NITC=../../bin/nitc NITLS=../../bin/nitls -all: bin/calculator bin/calculator.apk bin/test +all: bin/calculator bin/test bin/calculator: $(shell ${NITLS} -M src/calculator.nit -m linux) ${NITC} mkdir -p bin ${NITC} -o $@ src/calculator.nit -m linux -bin/calculator.apk: $(shell ${NITLS} -M src/calculator.nit -m android) ${NITC} ../../contrib/inkscape_tools/bin/svg_to_icons - mkdir -p bin res - ../../contrib/inkscape_tools/bin/svg_to_icons art/icon.svg --android --out res/ +android: bin/calculator.apk + +bin/calculator.apk: $(shell ${NITLS} -M src/calculator.nit -m android) ${NITC} res/drawable-ldpi/icon.png + mkdir -p bin ${NITC} -o $@ src/calculator.nit -m ../../lib/android/ui/ -D debug +android-release: $(shell ${NITLS} -M src/calculator.nit -m android) ${NITC} res/drawable-ldpi/icon.png + mkdir -p bin + ${NITC} -o bin/calculator.apk src/calculator.nit -m ../../lib/android/ui/ --release + +res/drawable-ldpi/icon.png: art/icon.svg ../../contrib/inkscape_tools/bin/svg_to_icons + mkdir -p res + ../../contrib/inkscape_tools/bin/svg_to_icons art/icon.svg --android --out res/ + ../../contrib/inkscape_tools/bin/svg_to_icons: make -C ../../contrib/inkscape_tools/ diff --git a/examples/calculator/org.nitlanguage.calculator.txt b/examples/calculator/org.nitlanguage.calculator.txt new file mode 100644 index 0000000..264d18b --- /dev/null +++ b/examples/calculator/org.nitlanguage.calculator.txt @@ -0,0 +1,12 @@ +Categories:Nit +License:Apache2 +Web Site:http://nitlanguage.org +Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/examples/calculator +Issue Tracker:https://github.com/nitlang/nit/issues + +Summary:A Basic Calculator +Description: +10 digits, 4 operations, hours of fun. + +This is the official example of a portable GUI application built using app.nit. +. diff --git a/examples/calculator/package.ini b/examples/calculator/package.ini index adeb755..80b32cb 100644 --- a/examples/calculator/package.ini +++ b/examples/calculator/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=examples/calculator/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +apk=http://nitlanguage.org/fdroid/apk/calculator.apk diff --git a/examples/mnit_ballz/package.ini b/examples/mnit_ballz/package.ini index 7314aeb..9db4745 100644 --- a/examples/mnit_ballz/package.ini +++ b/examples/mnit_ballz/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=examples/mnit_ballz/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +apk=http://nitlanguage.org/fdroid/apk/ballz.apk diff --git a/examples/mnit_dino/package.ini b/examples/mnit_dino/package.ini index fbd7d4f..efa6693 100644 --- a/examples/mnit_dino/package.ini +++ b/examples/mnit_dino/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=examples/mnit_dino/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +apk=http://nitlanguage.org/fdroid/apk/dino.apk diff --git a/examples/rosettacode/vignere_cipher.nit b/examples/rosettacode/vignere_cipher.nit index 73a3f41..565c19e 100644 --- a/examples/rosettacode/vignere_cipher.nit +++ b/examples/rosettacode/vignere_cipher.nit @@ -19,7 +19,7 @@ fun encrypt(src, key: String): String do continue end - out.add(((c.ascii + key[j].ascii - 2 * 'A'.ascii) % 26 + 'A'.ascii).ascii) + out.add(((c.ascii + key[j].ascii - 2u8 * 'A'.ascii) % 26u8 + 'A'.ascii).ascii) j = (j + 1) % key.length end @@ -39,7 +39,7 @@ fun decrypt(src, key: String): String do continue end - out.add(((c.ascii - key[j].ascii + 26) % 26 + 'A'.ascii).ascii) + out.add(((c.ascii - key[j].ascii + 26u8) % 26u8 + 'A'.ascii).ascii) j = (j + 1) % key.length end diff --git a/examples/shoot/package.ini b/examples/shoot/package.ini index 0fe112a..099ba60 100644 --- a/examples/shoot/package.ini +++ b/examples/shoot/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=examples/shoot/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +apk=http://nitlanguage.org/fdroid/apk/shoot_android.apk diff --git a/lib/android/audio.nit b/lib/android/audio.nit index b361b4f..9cc54d7 100644 --- a/lib/android/audio.nit +++ b/lib/android/audio.nit @@ -377,6 +377,16 @@ class MediaPlayer # Load a sound for a given resource id fun load_sound(id: Int, context: NativeActivity): Music do + # FIXME: maybe find a better way to handle this situation + # If two different music are loaded with the same `MediaPlayer`, + # a new `NativeMediaPlayer` will be created for the secondd music + # and the nit program will loose the handle to the previous one + # If the previous music is playing, we need to stop it + if playing then + stop + reset + destroy + end self.nmedia_player = self.nmedia_player.create(context, id) if self.nmedia_player.is_java_null then self.error = new Error("Failed to load a sound") @@ -482,6 +492,10 @@ class MediaPlayer end redef class PlayableAudio + # Flag to know if the user paused the sound + # Used when the app pause all sounds or resume all sounds + var paused: Bool = false + redef init do add_to_sounds(self) end @@ -544,11 +558,13 @@ redef class Sound redef fun pause do if self.error != null or not self.is_loaded then return soundpool.pause_stream(soundpool_id) + paused = true end redef fun resume do if self.error != null or not self.is_loaded then return soundpool.resume(soundpool_id) + paused = false end end @@ -606,11 +622,13 @@ redef class Music redef fun pause do if self.error != null or not self.is_loaded then return media_player.pause + paused = true end redef fun resume do if self.error != null or not self.is_loaded then return play + paused = false end end @@ -674,7 +692,16 @@ redef class App redef fun on_pause do super - for s in sounds do s.pause + for s in sounds do + # Pausing sounds that are not already paused by user + # `s.paused` is set to false because `pause` set it to true + # and we want to know which sound has been paused by the user + # and which one has been paused by the app + if not s.paused then + s.pause + s.paused = false + end + end audio_manager.abandon_audio_focus end @@ -687,7 +714,10 @@ redef class App redef fun on_resume do super audio_manager.request_audio_focus - for s in sounds do s.resume + for s in sounds do + # Resumes only the sounds paused by the App + if not s.paused then s.resume + end end end diff --git a/lib/base64.nit b/lib/base64.nit index 4eae395..cb73b3b 100644 --- a/lib/base64.nit +++ b/lib/base64.nit @@ -42,7 +42,7 @@ redef class NativeString # assert "string".encode_base64 == "c3RyaW5n" private fun encode_base64(length: Int, padding: nullable Byte): Bytes do var base64_bytes = once base64_chars - if padding == null then padding = '='.ascii.to_b + if padding == null then padding = '='.ascii var steps = length / 3 var bytes_in_last_step = length % 3 var result_length = steps * 4 @@ -81,7 +81,7 @@ redef class NativeString # # REQUIRE: `length % 4 == 0` private fun decode_base64(length: Int, padding: nullable Byte): Bytes do - if padding == null then padding = '='.ascii.to_b + if padding == null then padding = '='.ascii var inv = once inverted_base64_chars if length == 0 then return new Bytes.empty assert length % 4 == 0 else print "base64::decode_base64 only supports strings of length multiple of 4" diff --git a/lib/bcm2835/bcm2835.nit b/lib/bcm2835/bcm2835.nit index dad9899..48f0ed2 100644 --- a/lib/bcm2835/bcm2835.nit +++ b/lib/bcm2835/bcm2835.nit @@ -442,10 +442,10 @@ class HD44780 #write(true, "C0".to_hex) # instead we use the following which may not be portable - for s in [count..40[ do write(false, ' '.ascii) + for s in [count..40[ do write(false, ' '.code_point) count = 0 else - write(false, c.ascii) + write(false, c.code_point) count += 1 end end diff --git a/lib/binary/binary.nit b/lib/binary/binary.nit index b6909cd..c15cb52 100644 --- a/lib/binary/binary.nit +++ b/lib/binary/binary.nit @@ -107,7 +107,7 @@ redef abstract class Writer # Compared to `write_string`, this method supports null bytes in `text`. fun write_block(text: Text) do - write_int64 text.length + write_int64 text.bytelen write text end @@ -197,7 +197,7 @@ redef abstract class Reader do var length = read_int64 if length == 0 then return "" - return read(length) + return read_bytes(length).to_s end # Read a floating point on 32 bits and return it as a `Float` diff --git a/lib/binary/serialization.nit b/lib/binary/serialization.nit index d36f9c0..e069304 100644 --- a/lib/binary/serialization.nit +++ b/lib/binary/serialization.nit @@ -17,16 +17,16 @@ # The serialized data format uses a dictionary structure similar to BSON: # # ~~~raw -# object = 0x01 # null -# | 0x02 id attributes # New object -# | 0x03 id # Ref to object -# | 0x04 int64 # Int -# | 0x05 int8 # Bool (int8 != 0) -# | 0x06 int8 # Char -# | 0x07 double(64 bits) # Float -# | 0x08 block # String -# | 0x09 block # NativeString -# | 0x0A flat_array; # Array[nullable Object] +# object = 0x01 # null +# | 0x02 id attributes # New object +# | 0x03 id # Ref to object +# | 0x04 int64 # Int +# | 0x05 int8 # Bool (int8 != 0) +# | 0x06 utf8 byte sequence # Char +# | 0x07 double(64 bits) # Float +# | 0x08 block # String +# | 0x09 block # NativeString +# | 0x0A flat_array; # Array[nullable Object] # # block = int64 int8*; # cstring = int8* 0x00; @@ -128,6 +128,9 @@ class BinaryDeserializer # Tree of attributes, deserialized but not yet claimed private var unclaimed_attributes = new UnrolledList[HashMap[String, nullable Object]] + # Buffer for one char + private var char_buf: NativeString is lazy do return new NativeString(4) + # Read and deserialize the next attribute name and value # # A `peeked_char` can suffix the next attribute name. @@ -217,9 +220,17 @@ class BinaryDeserializer if kind == kind_bool then return stream.read_bool if kind == kind_float then return stream.read_double if kind == kind_char then + var bf = char_buf var b = stream.read_byte - if b == null then return 0 - return b.to_i.ascii + if b == null then return '�' + var ln = b.u8len + bf[0] = b + for i in [1 .. ln[ do + b = stream.read_byte + if b == null then return '�' + bf[i] = b + end + return bf.to_s_with_length(ln)[0] end if kind == kind_string then return stream.read_block if kind == kind_native_string then return stream.read_block.to_cstring @@ -382,8 +393,7 @@ redef class Char redef fun serialize_to_binary(v) do v.stream.write_byte kind_char - # Fix when UTF-8 - v.stream.write_byte self.ascii.to_b + for i in bytes do v.stream.write_byte i end end diff --git a/lib/bitmap/bitmap.nit b/lib/bitmap/bitmap.nit index e408402..0aceff5 100644 --- a/lib/bitmap/bitmap.nit +++ b/lib/bitmap/bitmap.nit @@ -211,11 +211,11 @@ class Bitmap var fw = new FileWriter.open(path) # Write bitmap header for x in [0..self.bitmap_header.length[ do - fw.write(self.bitmap_header[x].ascii.to_s) + fw.write(self.bitmap_header[x].code_point.to_s) end # Write dib header for x in [0..self.dib_header.length[ do - fw.write(self.dib_header[x].ascii.to_s) + fw.write(self.dib_header[x].code_point.to_s) end # Write color table (if any) # Write data (no padding for now) @@ -226,9 +226,9 @@ class Bitmap var red = pixel >> 16 var green = (pixel & 0x00FF00) >> 8 var blue = pixel & 0x000000FF - fw.write(red.ascii.to_s) - fw.write(green.ascii.to_s) - fw.write(blue.ascii.to_s) + fw.write(red.code_point.to_s) + fw.write(green.code_point.to_s) + fw.write(blue.code_point.to_s) end end fw.close diff --git a/lib/buffered_ropes.nit b/lib/buffered_ropes.nit index 8ed1f6b..fcc90c7 100644 --- a/lib/buffered_ropes.nit +++ b/lib/buffered_ropes.nit @@ -109,7 +109,7 @@ private class Leaf redef fun substrings do return new LeafSubstrings(self) - redef fun [](i) do return buf[i].to_i.ascii + redef fun [](i) do return buf[i].to_i.code_point init do bns = buf.ns diff --git a/lib/console.nit b/lib/console.nit index c0a8772..0020b7a 100644 --- a/lib/console.nit +++ b/lib/console.nit @@ -18,7 +18,7 @@ module console # A ANSI/VT100 escape sequence. abstract class TermEscape # The US-ASCII ESC character. - protected fun esc: Char do return 27.ascii + protected fun esc: Char do return 27.code_point # The Control Sequence Introducer (CSI). protected fun csi: String do return "{esc}[" diff --git a/lib/core/bytes.nit b/lib/core/bytes.nit index 356f386..227759a 100644 --- a/lib/core/bytes.nit +++ b/lib/core/bytes.nit @@ -32,18 +32,18 @@ redef class Byte # # ~~~nit # intrude import core::bytes - # assert not '/'.ascii.to_b.is_valid_hexdigit - # assert '0'.ascii.to_b.is_valid_hexdigit - # assert '9'.ascii.to_b.is_valid_hexdigit - # assert not ':'.ascii.to_b.is_valid_hexdigit - # assert not '@'.ascii.to_b.is_valid_hexdigit - # assert 'A'.ascii.to_b.is_valid_hexdigit - # assert 'F'.ascii.to_b.is_valid_hexdigit - # assert not 'G'.ascii.to_b.is_valid_hexdigit - # assert not '`'.ascii.to_b.is_valid_hexdigit - # assert 'a'.ascii.to_b.is_valid_hexdigit - # assert 'f'.ascii.to_b.is_valid_hexdigit - # assert not 'g'.ascii.to_b.is_valid_hexdigit + # assert not '/'.ascii.is_valid_hexdigit + # assert '0'.ascii.is_valid_hexdigit + # assert '9'.ascii.is_valid_hexdigit + # assert not ':'.ascii.is_valid_hexdigit + # assert not '@'.ascii.is_valid_hexdigit + # assert 'A'.ascii.is_valid_hexdigit + # assert 'F'.ascii.is_valid_hexdigit + # assert not 'G'.ascii.is_valid_hexdigit + # assert not '`'.ascii.is_valid_hexdigit + # assert 'a'.ascii.is_valid_hexdigit + # assert 'f'.ascii.is_valid_hexdigit + # assert not 'g'.ascii.is_valid_hexdigit # ~~~ private fun is_valid_hexdigit: Bool do return (self >= 0x30u8 and self <= 0x39u8) or diff --git a/lib/core/fixed_ints.nit b/lib/core/fixed_ints.nit index 17ef576..36f21a3 100644 --- a/lib/core/fixed_ints.nit +++ b/lib/core/fixed_ints.nit @@ -158,6 +158,9 @@ universal Int8 redef fun to_i32 is intern redef fun to_u32 is intern + # Returns `self` as a Char according to its ASCII value. + fun ascii: Char `{ return (uint32_t)self; `} + redef fun distance(i) do return (self - i).to_i redef fun <=>(other) @@ -271,6 +274,9 @@ universal Int16 redef fun *(i) is intern redef fun /(i) is intern + # Returns `self` as a Char according to its ASCII value. + fun ascii: Char `{ return (uint32_t)self; `} + # Modulo of `self` with `i`. # # Returns the remainder of division of `self` by `i`. @@ -425,6 +431,9 @@ universal UInt16 redef fun zero do return 0.to_u16 redef fun value_of(val) do return val.to_u16 + # Returns `self` as a Char according to its ASCII value. + fun ascii: Char `{ return (uint32_t)self; `} + # `i` bits shift to the left # # assert 5u16 << 1 == 10u16 @@ -558,6 +567,9 @@ universal Int32 redef fun *(i) is intern redef fun /(i) is intern + # Returns `self` as a Char according to its ASCII value. + fun ascii: Char `{ return (uint32_t)self; `} + # Modulo of `self` with `i`. # # Returns the remainder of division of `self` by `i`. @@ -701,6 +713,9 @@ universal UInt32 redef fun *(i) is intern redef fun /(i) is intern + # Returns `self` as a Char according to its ASCII value. + fun ascii: Char `{ return (uint32_t)self; `} + # Modulo of `self` with `i`. # # Returns the remainder of division of `self` by `i`. diff --git a/lib/core/kernel.nit b/lib/core/kernel.nit index b2ac524..650360a 100644 --- a/lib/core/kernel.nit +++ b/lib/core/kernel.nit @@ -651,6 +651,11 @@ universal Byte # assert 5u8 >> 1 == 2u8 fun >>(i: Int): Byte `{ return self >> i; `} + # Returns the character equivalent of `self` + # + # REQUIRE: `self <= 127u8` + fun ascii: Char `{ return (uint32_t)self; `} + redef fun to_i is intern redef fun to_f is intern redef fun to_b do return self @@ -797,11 +802,12 @@ universal Int end end - # The character whose ASCII value is `self`. + # The character which code point (unicode-wise) is `self` # - # assert 65.ascii == 'A' - # assert 10.ascii == '\n' - fun ascii: Char is intern + # assert 65.code_point == 'A' + # assert 10.code_point == '\n' + # assert 0x220B.code_point == '∋' + fun code_point: Char `{ return (uint32_t)self; `} # Number of digits of an integer in base `b` (plus one if negative) # @@ -861,9 +867,9 @@ universal Int do assert self >= 0 and self <= 36 # TODO plan for this if self < 10 then - return (self + '0'.ascii).ascii + return (self + '0'.code_point).code_point else - return (self + ('a'.ascii - 10)).ascii + return (self - 10 + 'a'.code_point).code_point end end @@ -905,7 +911,7 @@ universal Char printf("%c", self); } `} - redef fun hash do return ascii + redef fun hash do return code_point redef fun ==(o) is intern redef fun !=(o) is intern @@ -919,7 +925,7 @@ universal Char redef fun distance(c) do - var d = self.ascii - c.ascii + var d = self.code_point - c.code_point if d >= 0 then return d else @@ -936,17 +942,32 @@ universal Char if self == '-' then return -1 else if is_digit then - return self.ascii - '0'.ascii + return self.code_point - '0'.code_point else - return self.to_lower.ascii - 'a'.ascii + 10 + return self.to_lower.code_point - 'a'.code_point + 10 end end - # the ascii value of self + # The ascii value of `self` + # + # assert 'a'.ascii == 97u8 + # assert '\n'.ascii == 10u8 + # + # REQUIRE: `is_ascii` + fun ascii: Byte do return code_point.to_b + + # The unicode code point value of `self` + # + # assert 'A'.code_point == 65 + # assert '\n'.code_point == 10 + # assert '∋'.code_point == 0x220B + fun code_point: Int `{ return (long)self; `} + + # Is `self` an ASCII character ? # - # assert 'a'.ascii == 97 - # assert '\n'.ascii == 10 - fun ascii: Int is intern + # assert 'x'.is_ascii + # assert not 'ま'.is_ascii + fun is_ascii: Bool do return code_point <= 127 # Return the lower case version of self. # If self is not a letter, then return self @@ -957,7 +978,7 @@ universal Char fun to_lower: Char do if is_upper then - return (ascii + ('a'.distance('A'))).ascii + return (code_point + ('a'.distance('A'))).code_point else return self end @@ -972,7 +993,7 @@ universal Char fun to_upper: Char do if is_lower then - return (ascii - ('a'.distance('A'))).ascii + return (code_point - ('a'.distance('A'))).code_point else return self end @@ -1033,7 +1054,7 @@ universal Char # assert '\t'.is_whitespace == true fun is_whitespace: Bool do - var i = ascii + var i = code_point return i <= 0x20 or i == 0x7F end end diff --git a/lib/core/stream.nit b/lib/core/stream.nit index 4b1e826..b4a0e2b 100644 --- a/lib/core/stream.nit +++ b/lib/core/stream.nit @@ -275,7 +275,7 @@ abstract class Reader # ~~~ # var w = new StringReader(" Hello, \n\t World!") # assert w.read_word == "Hello," - # assert w.read_char == '\n'.ascii + # assert w.read_char == '\n' # assert w.read_word == "World!" # assert w.read_word == "" # ~~~ @@ -441,7 +441,7 @@ abstract class BufferedReader return null end # TODO: Fix when supporting UTF-8 - var c = _buffer[_buffer_pos].to_i.ascii + var c = _buffer[_buffer_pos].to_i.code_point _buffer_pos += 1 return c end diff --git a/lib/core/text/abstract_text.nit b/lib/core/text/abstract_text.nit index b1e6a04..63fb920 100644 --- a/lib/core/text/abstract_text.nit +++ b/lib/core/text/abstract_text.nit @@ -543,7 +543,7 @@ abstract class Text if c >= '0' and c <= '9' then res.add('_') - res.append(c.ascii.to_s) + res.append(c.code_point.to_s) res.add('d') start = 1 end @@ -555,7 +555,7 @@ abstract class Text continue end if underscore then - res.append('_'.ascii.to_s) + res.append('_'.code_point.to_s) res.add('d') end if c >= '0' and c <= '9' then @@ -566,13 +566,13 @@ abstract class Text underscore = true else res.add('_') - res.append(c.ascii.to_s) + res.append(c.code_point.to_s) res.add('d') underscore = false end end if underscore then - res.append('_'.ascii.to_s) + res.append('_'.code_point.to_s) res.add('d') end return res.to_s @@ -587,7 +587,7 @@ abstract class Text # Three digits are always used to avoid following digits to be interpreted as an element # of the octal sequence. # - # assert "{0.ascii}{1.ascii}{8.ascii}{31.ascii}{32.ascii}".escape_to_c == "\\000\\001\\010\\037 " + # assert "{0.code_point}{1.code_point}{8.code_point}{31.code_point}{32.code_point}".escape_to_c == "\\000\\001\\010\\037 " # # The exceptions are the common `\t` and `\n`. fun escape_to_c: String @@ -605,9 +605,9 @@ abstract class Text b.append("\\\'") else if c == '\\' then b.append("\\\\") - else if c.ascii < 32 then + else if c.code_point < 32 then b.add('\\') - var oct = c.ascii.to_base(8, false) + var oct = c.code_point.to_base(8, false) # Force 3 octal digits since it is the # maximum allowed in the C specification if oct.length == 1 then @@ -680,8 +680,8 @@ abstract class Text else if c == ':' or c == ' ' or c == '#' then b.add('\\') b.add(c) - else if c.ascii < 32 or c == ';' or c == '|' or c == '\\' or c == '=' then - b.append("?{c.ascii.to_base(16, false)}") + else if c.code_point < 32 or c == ';' or c == '|' or c == '\\' or c == '=' then + b.append("?{c.code_point.to_base(16, false)}") else b.add(c) end @@ -695,7 +695,7 @@ abstract class Text # assert s.length == 2 # var u = s.unescape_nit # assert u.length == 1 - # assert u.chars[0].ascii == 10 # (the ASCII value of the "new line" character) + # assert u.chars[0].code_point == 10 # (the ASCII value of the "new line" character) fun unescape_nit: String do var res = new Buffer.with_cap(self.length) @@ -787,7 +787,7 @@ abstract class Text if c == '%' then if i + 2 >= length then # What follows % has been cut off - buf[l] = '?'.ascii.to_b + buf[l] = '?'.ascii else i += 1 var hex_s = substring(i, 2) @@ -797,11 +797,11 @@ abstract class Text i += 1 else # What follows a % is not Hex - buf[l] = '?'.ascii.to_b + buf[l] = '?'.ascii i -= 1 end end - else buf[l] = c.ascii.to_b + else buf[l] = c.ascii i += 1 l += 1 @@ -905,7 +905,7 @@ abstract class Text for i in [0..length[ do var char = chars[i] - h = (h << 5) + h + char.ascii + h = (h << 5) + h + char.code_point end hash_cache = h @@ -1050,7 +1050,7 @@ private abstract class StringByteView redef fun is_empty do return target.is_empty - redef fun length do return target.length + redef fun length do return target.bytelen redef fun iterator do return self.iterator_from(0) @@ -1573,9 +1573,15 @@ end redef class Char + # Returns a sequence with the UTF-8 bytes of `self` + # + # assert 'a'.bytes == [0x61u8] + # assert 'ま'.bytes == [0xE3u8, 0x81u8, 0xBEu8] + fun bytes: SequenceRead[Byte] do return to_s.bytes + # Length of `self` in a UTF-8 String private fun u8char_len: Int do - var c = self.ascii + var c = self.code_point if c < 0x80 then return 1 if c <= 0x7FF then return 2 if c <= 0xFFFF then return 3 diff --git a/lib/core/text/flat.nit b/lib/core/text/flat.nit index 52de988..4d2ff48 100644 --- a/lib/core/text/flat.nit +++ b/lib/core/text/flat.nit @@ -1035,7 +1035,7 @@ redef class NativeString end var ok_c: Bool var c = char_at(pos) - var cp = c.ascii + var cp = c.code_point if nxst == 1 then ok_c = cp >= 0 and cp <= 0x7F else if nxst == 2 then diff --git a/lib/core/text/native.nit b/lib/core/text/native.nit index acc9a12..4028ea0 100644 --- a/lib/core/text/native.nit +++ b/lib/core/text/native.nit @@ -16,7 +16,7 @@ import math redef class Byte # Gives the length of the UTF-8 char starting with `self` - private fun u8len: Int do + fun u8len: Int do if self & 0b1000_0000u8 == 0u8 then return 1 else if self & 0b1110_0000u8 == 0b1100_0000u8 then diff --git a/lib/core/text/ropes.nit b/lib/core/text/ropes.nit index 3e7b761..c164529 100644 --- a/lib/core/text/ropes.nit +++ b/lib/core/text/ropes.nit @@ -468,7 +468,7 @@ class RopeBuffer rp = 0 end # TODO: Fix when supporting UTF-8 - ns[rp] = c.ascii.to_b + ns[rp] = c.ascii rp += 1 _bytelen += 1 rpos = rp diff --git a/lib/crypto.nit b/lib/crypto.nit index 310f725..011347d 100644 --- a/lib/crypto.nit +++ b/lib/crypto.nit @@ -30,7 +30,7 @@ redef class Char x = x % 26 if x < 0 then x += 26 var up = false - var val = ascii + var val = code_point if is_upper then up = true val += 32 @@ -38,7 +38,7 @@ redef class Char val += x if val > 122 then val -= 26 if up then val -= 32 - return val.ascii + return val.code_point end end diff --git a/lib/json/json_lexer.nit b/lib/json/json_lexer.nit index 88b270b..b6bf2c1 100644 --- a/lib/json/json_lexer.nit +++ b/lib/json/json_lexer.nit @@ -47,7 +47,7 @@ end private class DFAState0 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 8 then return null if c <= 10 then return dfastate_1 if c <= 31 then return null @@ -84,7 +84,7 @@ private class DFAState1 return null end redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 8 then return null if c <= 10 then return dfastate_1 if c <= 31 then return null @@ -95,7 +95,7 @@ end private class DFAState2 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 33 then return dfastate_2 if c <= 34 then return dfastate_29 if c <= 91 then return dfastate_2 @@ -116,7 +116,7 @@ end private class DFAState4 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 47 then return null if c <= 57 then return dfastate_5 return null @@ -132,7 +132,7 @@ private class DFAState5 return t end redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 45 then return null if c <= 46 then return dfastate_24 if c <= 47 then return null @@ -177,7 +177,7 @@ end private class DFAState9 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 96 then return null if c <= 97 then return dfastate_20 return null @@ -186,7 +186,7 @@ end private class DFAState10 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 116 then return null if c <= 117 then return dfastate_17 return null @@ -195,7 +195,7 @@ end private class DFAState11 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 113 then return null if c <= 114 then return dfastate_14 return null @@ -224,7 +224,7 @@ end private class DFAState14 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 116 then return null if c <= 117 then return dfastate_15 return null @@ -233,7 +233,7 @@ end private class DFAState15 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 100 then return null if c <= 101 then return dfastate_16 return null @@ -252,7 +252,7 @@ end private class DFAState17 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 107 then return null if c <= 108 then return dfastate_18 return null @@ -261,7 +261,7 @@ end private class DFAState18 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 107 then return null if c <= 108 then return dfastate_19 return null @@ -280,7 +280,7 @@ end private class DFAState20 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 107 then return null if c <= 108 then return dfastate_21 return null @@ -289,7 +289,7 @@ end private class DFAState21 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 114 then return null if c <= 115 then return dfastate_22 return null @@ -298,7 +298,7 @@ end private class DFAState22 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 100 then return null if c <= 101 then return dfastate_23 return null @@ -317,7 +317,7 @@ end private class DFAState24 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 47 then return null if c <= 57 then return dfastate_28 return null @@ -326,7 +326,7 @@ end private class DFAState25 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 42 then return null if c <= 43 then return dfastate_26 if c <= 44 then return null @@ -339,7 +339,7 @@ end private class DFAState26 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 47 then return null if c <= 57 then return dfastate_27 return null @@ -355,7 +355,7 @@ private class DFAState27 return t end redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 47 then return null if c <= 57 then return dfastate_27 return null @@ -371,7 +371,7 @@ private class DFAState28 return t end redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 47 then return null if c <= 57 then return dfastate_28 if c <= 68 then return null @@ -394,7 +394,7 @@ end private class DFAState30 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 33 then return null if c <= 34 then return dfastate_2 if c <= 46 then return null @@ -418,7 +418,7 @@ end private class DFAState31 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 47 then return null if c <= 57 then return dfastate_32 if c <= 64 then return null @@ -431,7 +431,7 @@ end private class DFAState32 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 47 then return null if c <= 57 then return dfastate_33 if c <= 64 then return null @@ -444,7 +444,7 @@ end private class DFAState33 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 47 then return null if c <= 57 then return dfastate_34 if c <= 64 then return null @@ -457,7 +457,7 @@ end private class DFAState34 super DFAState redef fun trans(char) do - var c = char.ascii + var c = char.code_point if c <= 47 then return null if c <= 57 then return dfastate_2 if c <= 64 then return null diff --git a/lib/json/static.nit b/lib/json/static.nit index fdb9f65..966f2c9 100644 --- a/lib/json/static.nit +++ b/lib/json/static.nit @@ -99,22 +99,22 @@ redef class Text buffer.append "\\\"" else if char == '\/' then buffer.append "\\/" - else if char < 16.ascii then + else if char < 16.code_point then if char == '\n' then buffer.append "\\n" else if char == '\r' then buffer.append "\\r" else if char == '\t' then buffer.append "\\t" - else if char == 0x0C.ascii then + else if char == 0x0C.code_point then buffer.append "\\f" - else if char == 0x08.ascii then + else if char == 0x08.code_point then buffer.append "\\b" else - buffer.append "\\u000{char.ascii.to_hex}" + buffer.append "\\u000{char.code_point.to_hex}" end else if char < ' ' then - buffer.append "\\u00{char.ascii.to_hex}" + buffer.append "\\u00{char.code_point.to_hex}" else buffer.add char end @@ -435,9 +435,9 @@ redef class Nstring i += 1 char = text[i] if char == 'b' then - char = 0x08.ascii + char = 0x08.code_point else if char == 'f' then - char = 0x0C.ascii + char = 0x0C.code_point else if char == 'n' then char = '\n' else if char == 'r' then @@ -450,7 +450,7 @@ redef class Nstring if code >= 128 then char = '?' else - char = code.ascii + char = code.code_point end i += 4 end diff --git a/lib/mnit/numbers.nit b/lib/mnit/numbers.nit index 1b7a017..e7462b4 100644 --- a/lib/mnit/numbers.nit +++ b/lib/mnit/numbers.nit @@ -41,7 +41,7 @@ redef class Display do var str = number.to_s for c in str.chars do - var d = c.ascii-'0'.ascii + var d = c.code_point-'0'.code_point assert d >= 0 and d <= 9 var img = imgs.imgs[d] blit(img, x, y) diff --git a/lib/saxophonit/lexer.nit b/lib/saxophonit/lexer.nit index acfe9fa..92f293b 100644 --- a/lib/saxophonit/lexer.nit +++ b/lib/saxophonit/lexer.nit @@ -49,9 +49,9 @@ class XophonLexer # read the next byte. Else, return `-1`. fun expect_delimiter: Int do if accept('"') then - return '"'.ascii + return '"'.code_point else if accept('\'') then - return '\''.ascii + return '\''.code_point else fire_unexpected_char(". Expecting `\"` or `'`") return -1 @@ -71,7 +71,7 @@ class XophonLexer # If the last read byte is forbidden, fire a fatal error instead. fun expect_xml_char(buffer: Buffer): Bool do if is_xml_char then - buffer.chars.push(last_char.ascii) + buffer.chars.push(last_char.code_point) read_char return true else if eof then @@ -91,7 +91,7 @@ class XophonLexer buffer.chars.push(' ') read_char return true - else if last_char == '<'.ascii then + else if last_char == '<'.code_point then return fire_fatal_error("`<` is forbidden in attribute values.") else return expect_xml_char(buffer) @@ -127,10 +127,10 @@ class XophonLexer # Is the last read byte matches the `NameStartChar` production? fun is_name_start_char: Bool do # TODO: Handle code points above 0x7F. - return ['A'.ascii .. 'Z'.ascii].has(last_char) or - ['a'.ascii .. 'z'.ascii].has(last_char) or - last_char == '_'.ascii or - last_char == ':'.ascii or + return ['A'.code_point .. 'Z'.code_point].has(last_char) or + ['a'.code_point .. 'z'.code_point].has(last_char) or + last_char == '_'.code_point or + last_char == ':'.code_point or last_char > 127 end @@ -138,8 +138,8 @@ class XophonLexer fun is_name_char: Bool do # TODO: Handle code points above 0x7F. return is_name_start_char or - last_char == '-'.ascii or - last_char == '.'.ascii or + last_char == '-'.code_point or + last_char == '.'.code_point or is_digit end @@ -150,10 +150,10 @@ class XophonLexer if not is_name_start_char then return fire_unexpected_char(" at the beginning of a name") end - buffer.chars.push(last_char.ascii) + buffer.chars.push(last_char.code_point) read_char while is_name_char do - buffer.chars.push(last_char.ascii) + buffer.chars.push(last_char.code_point) read_char end return true @@ -187,14 +187,14 @@ class XophonLexer # Is the last read byte matches the `[0-9]` production? fun is_digit: Bool do - return ['0'.ascii .. '9'.ascii].has(last_char) + return ['0'.code_point .. '9'.code_point].has(last_char) end # Accept a `[0-9]+` token. fun accept_digits(buffer: Buffer): Bool do if is_digit then loop - buffer.chars.push(last_char.ascii) + buffer.chars.push(last_char.code_point) read_char if not is_digit then return true end @@ -210,16 +210,16 @@ class XophonLexer # Is `last_char` matches the `[0-9a-fA-F]` production? fun is_hex: Bool do - return ['0'.ascii .. '9'.ascii].has(last_char) or - ['A'.ascii .. 'Z'.ascii].has(last_char) or - ['a'.ascii .. 'Z'.ascii].has(last_char) + return ['0'.code_point .. '9'.code_point].has(last_char) or + ['A'.code_point .. 'Z'.code_point].has(last_char) or + ['a'.code_point .. 'Z'.code_point].has(last_char) end # Expect a `[0-9a-fA-F]+` token. fun expect_hex(buffer: Buffer): Bool do if is_hex then loop - buffer.chars.push(last_char.ascii) + buffer.chars.push(last_char.code_point) read_char if not is_hex then return true end @@ -247,7 +247,7 @@ class XophonLexer else if last_char < 0 then fire_fatal_error("Internal error: Already at the end of the file.") return - else if last_char == '\n'.ascii then + else if last_char == '\n'.code_point then locator.line_number += 1 locator.column_number = 1 else @@ -264,7 +264,7 @@ class XophonLexer # XML 1.0 end-of-line handling # Note: Regardless the XML version, any EOL defined by the # recommandation MUST be reported as a single LINE FEED. - if was_cr and last_char == '\n'.ascii then + if was_cr and last_char == '\n'.code_point then # EOL already reported. => Skip this byte. s = input.read_byte if s == null then @@ -273,10 +273,10 @@ class XophonLexer last_char = s.to_i end end - was_cr = last_char == '\r'.ascii + was_cr = last_char == '\r'.code_point if was_cr then # Regardless the following byte, '\r' always introduce an EOL. - last_char = '\n'.ascii + last_char = '\n'.code_point end end @@ -303,7 +303,7 @@ class XophonLexer fun is_int(c: Int): Bool do return last_char == c # Does the last read byte equal `c`? - fun is_char(c: Char): Bool do return last_char == c.ascii + fun is_char(c: Char): Bool do return last_char == c.code_point # Expect the specified byte. fun accept_int(expected: Int): Bool do @@ -317,7 +317,7 @@ class XophonLexer # Accept the specified byte. fun accept(expected: Char): Bool do - return accept_int(expected.ascii) + return accept_int(expected.code_point) end # Ensure the last read byte is equal to `expected`. @@ -330,7 +330,7 @@ class XophonLexer # Return `true` if and only if the last read byte as the expected value. fun expect_int(expected: Int, context: String): Bool do return accept_int(expected) or - fire_unexpected_char("{context}. Expecting `{expected.ascii}`.") + fire_unexpected_char("{context}. Expecting `{expected.code_point}`.") end # Ensure the last read byte is equal to `expected`. @@ -363,7 +363,7 @@ class XophonLexer if not accept(chars[i]) then if is_xml_char then return fire_fatal_error("Unexpected " + - "`{expected.substring(0, i)}{last_char.ascii.to_s}`" + + "`{expected.substring(0, i)}{last_char.code_point.to_s}`" + "{context}. Expecting `{expected}`.") else if eof then return fire_fatal_error("Unexpected end of file{context}. " + @@ -386,7 +386,7 @@ class XophonLexer # Return `false`. fun fire_unexpected_char(rest_of_message: String): Bool do if is_xml_char then - return fire_fatal_error("Unexpected character `{last_char.ascii.to_s}`{rest_of_message}.") + return fire_fatal_error("Unexpected character `{last_char.code_point.to_s}`{rest_of_message}.") else if eof then return fire_fatal_error("Unexpected end of file{rest_of_message}.") else diff --git a/lib/saxophonit/saxophonit.nit b/lib/saxophonit/saxophonit.nit index 2693086..d5ddeb3 100644 --- a/lib/saxophonit/saxophonit.nit +++ b/lib/saxophonit/saxophonit.nit @@ -656,14 +656,14 @@ class XophonReader if lexer.accept('#') then if lexer.accept('x') then if lexer.expect_hex(ref) then - buffer.chars.add(ref.to_hex.ascii) + buffer.chars.add(ref.to_hex.code_point) return lexer.expect(';', "") else return lexer.fire_unexpected_char( ". Expecting an hexadecimal digit") end else if lexer.accept_digits(ref) then - buffer.chars.add(ref.to_i.ascii) + buffer.chars.add(ref.to_i.code_point) return lexer.expect(';', "") else return lexer.fire_unexpected_char(" in a character reference. " + diff --git a/misc/jenkins/check_contrib.sh b/misc/jenkins/check_contrib.sh index fafeb92..df81660 100755 --- a/misc/jenkins/check_contrib.sh +++ b/misc/jenkins/check_contrib.sh @@ -29,19 +29,22 @@ failed= for p in $projects; do dir=`dirname "$p"` name=`basename "$dir"` - echo "*** make $dir ***" - if misc/jenkins/unitrun.sh "cmd-$name-make" make -C "$dir"; then - # Make OK. Check additional rules if they exists - for rule in $rules; do - make -C "$dir" $rule -n 2>/dev/null || - continue - echo "*** make$rule $dir ***" - misc/jenkins/unitrun.sh "cmd-$name-make$rule" make -C "$dir" $rule || - failed="$failed $name-$rule" - done - else - failed="$failed $name" - fi + echo "### in $dir ###" + # Check each rules, if they exists + for rule in $rules; do + make -C "$dir" $rule -n >/dev/null 2>/dev/null || { + # Special case for `all` that falls back as the default target + if [ "$rule" = "all" ]; then + echo "*** make -C $dir ***" + misc/jenkins/unitrun.sh "cmd-$name-make" make -C "$dir" || + failed="$failed $name" + fi + continue + } + echo "*** make $rule -C $dir ***" + misc/jenkins/unitrun.sh "cmd-$name-make$rule" make -C "$dir" $rule || + failed="$failed $name-$rule" + done done grep 'class == &class_{mtype1.c_name}); /* is_same_type_test */") + self.add("{res} = ({value2} != NULL) && ({class_info(value2)} == &class_{mtype1.c_name}); /* is_same_type_test */") end else self.add("{res} = ({value1} == {value2}) || ({value1} != NULL && {value2} != NULL && {class_info(value1)} == {class_info(value2)}); /* is_same_type_test */") @@ -1891,20 +1894,58 @@ class SeparateCompilerVisitor value2 = tmp end if value1.mtype.is_c_primitive then - if value2.mtype == value1.mtype then + var t1 = value1.mtype + assert t1 == value1.mcasttype + + # Fast case: same C type. + if value2.mtype == t1 then + # Same exact C primitive representation. self.add("{res} = {value1} == {value2};") - else if value2.mtype.is_c_primitive then - self.add("{res} = 0; /* incompatible types {value1.mtype} vs. {value2.mtype}*/") - else if value1.mtype.is_tagged then - self.add("{res} = ({value2} != NULL) && ({self.autobox(value2, value1.mtype)} == {value1});") + return res + end + + # Complex case: value2 has a different representation + # Thus, it should be checked if `value2` is type-compatible with `value1` + # This compatibility is done statically if possible and dynamically else + + # Conjunction (ands) of dynamic tests according to the static knowledge + var tests = new Array[String] + + var t2 = value2.mcasttype + if t2 isa MNullableType then + # The destination type cannot be null + tests.add("({value2} != NULL)") + t2 = t2.mtype + else if t2 isa MNullType then + # `value2` is known to be null, thus incompatible with a primitive + self.add("{res} = 0; /* incompatible types {t1} vs. {t2}*/") + return res + end + + if t2 == t1 then + # Same type but different representation. + else if t2.is_c_primitive then + # Type of `value2` is a different primitive type, thus incompatible + self.add("{res} = 0; /* incompatible types {t1} vs. {t2}*/") + return res + else if t1.is_tagged then + # To be equal, `value2` should also be correctly tagged + tests.add("({extract_tag(value2)} == {t1.tag_value})") else - var mtype1 = value1.mtype.as(MClassType) - self.require_declaration("class_{mtype1.c_name}") - self.add("{res} = ({value2} != NULL) && ({value2}->class == &class_{mtype1.c_name});") - self.add("if ({res}) \{") - self.add("{res} = ({self.autobox(value2, value1.mtype)} == {value1});") - self.add("\}") + # To be equal, `value2` should also be boxed with the same class + self.require_declaration("class_{t1.c_name}") + tests.add "({class_info(value2)} == &class_{t1.c_name})" end + + # Compare the unboxed `value2` with `value1` + if tests.not_empty then + self.add "if ({tests.join(" && ")}) \{" + end + self.add "{res} = {self.autobox(value2, t1)} == {value1};" + if tests.not_empty then + self.add "\} else {res} = 0;" + end + return res end var maybe_null = true @@ -2327,6 +2368,12 @@ redef class MType # Are values of `self` tagged? # If false, it means that the type is not primitive, or is boxed. var is_tagged = false + + # The tag value of the type + # + # ENSURE `is_tagged == (tag_value > 0)` + # ENSURE `not is_tagged == (tag_value == 0)` + var tag_value = 0 end redef class MEntity diff --git a/src/doc/doc_phases/doc_console.nit b/src/doc/doc_phases/doc_console.nit index e4f6bb1..b118019 100644 --- a/src/doc/doc_phases/doc_console.nit +++ b/src/doc/doc_phases/doc_console.nit @@ -551,8 +551,8 @@ private class Pager b.append("\\\\") else if c == '`' then b.append("'") - else if c.ascii < 32 then - b.append("\\{c.ascii.to_base(8, false)}") + else if c.code_point < 32 then + b.append("\\{c.code_point.to_base(8, false)}") else b.add(c) end diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index b484f15..da7b288 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -972,8 +972,6 @@ redef class AMethPropdef return v.bool_instance(recvval >= args[1].to_i) else if pname == "<=>" then return v.int_instance(recvval <=> args[1].to_i) - else if pname == "ascii" then - return v.char_instance(recvval.ascii) else if pname == "to_f" then return v.float_instance(recvval.to_f) else if pname == "to_b" then @@ -1045,9 +1043,7 @@ redef class AMethPropdef end else if cname == "Char" then var recv = args[0].val.as(Char) - if pname == "ascii" then - return v.int_instance(recv.ascii) - else if pname == "successor" then + if pname == "successor" then return v.char_instance(recv.successor(args[1].to_i)) else if pname == "predecessor" then return v.char_instance(recv.predecessor(args[1].to_i)) diff --git a/src/location.nit b/src/location.nit index 786ffc2..0c5b55d 100644 --- a/src/location.nit +++ b/src/location.nit @@ -246,7 +246,7 @@ class Location # * `"0;32"` for green fun colored_line(color: String): String do - var esc = 27.ascii + var esc = 27.code_point var def = "{esc}[0m" var col = "{esc}[{color}m" diff --git a/src/nitcatalog.nit b/src/nitcatalog.nit index 28ae918..59d76b0 100644 --- a/src/nitcatalog.nit +++ b/src/nitcatalog.nit @@ -313,6 +313,21 @@ class Catalog