diff --git a/.gitignore b/.gitignore index 2c6832c..6132538 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ pep8term app.ini nitunit.out nitunit.xml +*.*~ diff --git a/Dockerfile b/Dockerfile index ad664af..c842436 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM nitlang/nit # Needed for nitcorn and to build mongo-c-driver -RUN apt-get update && apt-get install -y libevent-dev libssl-dev libsasl2-dev libcurl4-openssl-dev file +RUN apt-get update && apt-get install -y libevent-dev libssl-dev libsasl2-dev libcurl4-openssl-dev file openjdk-7-jre-headless # Install mongo-c-driver manually since it is not available in Debian/jessie RUN curl -L https://github.com/mongodb/mongo-c-driver/releases/download/1.4.0/mongo-c-driver-1.4.0.tar.gz -o mongo-c-driver-1.4.0.tar.gz \ @@ -12,8 +12,13 @@ RUN curl -L https://github.com/mongodb/mongo-c-driver/releases/download/1.4.0/mo && make install \ && ldconfig -# Copy and compile the code WORKDIR /missions +RUN curl -L http://downloads.sourceforge.net/project/useocl/USE/4.2.0/use-4.2.0.tar.gz -o use-4.2.0.tar.gz \ + && tar xzf use-4.2.0.tar.gz \ + && echo '/missions/use-4.2.0/bin/use "$@"' > /usr/local/bin/use \ + && chmod +x /usr/local/bin/use + +# Copy and compile the code COPY . /missions/ RUN make pep8term && make diff --git a/share/useoclrun.sh b/share/useoclrun.sh new file mode 100755 index 0000000..848b4fb --- /dev/null +++ b/share/useoclrun.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +# Script to execute a USE-OCL subission. +# Communication is done with the file system: +# +# INPUT +# +# * source.use : the submission source code +# * test*/input.txt : the input for each test +# +# OUTPUT +# +# * test*/output.txt : the produced output for each test +# * test*/execerr.txt : execution error messages, if any +# +# To avoid the submission to look at the expected results or to temper them, the script just compile and run. +# The evaluation of the results has to be done by the caller. + +# Transform a bash return value caused by ulimit into a message for a human. +# Not really portable :( +ulimitmsg() { + code=$1 + file=$2 + # 128+n = signal n + case "$code" in + 137) + # 128+9 = KILL = time out + echo "CPU time limit exceeded" > "$file" + return 1;; + 153) + # 128+25 = XFSZ = file limit + echo "File size limit exceeded" > "$file" + return 1;; + *) + # USE OCL returned 1 (a constraint failed) + return 0 + esac +} + +# Try to compile +compile() { + # Try to compile + ( + ulimit -t 5 # 5s CPU time + ulimit -f 128 # 1kB written files + use -nogui -nr -c source.use 2> cmperr.txt + ) || { + ulimitmsg "$?" cmperr.txt + return 1 + } + + return 0 +} + +# Run a test of subdirectory +runtest() { + t=$1 + + # Try to execute the program on the test input + ( + ulimit -t 5 # 5s CPU time + ulimit -f 128 # 1kB written files + use -nogui -nr -t -qv source.use $t/input.txt > $t/output.txt 2>&1 + # $t/execerr.txt + # cat $t/output.txt + # cat $t/execerr.txt + ) || { + return ulimitmsg "$?" $t/execerr.txt + } + return 0 +} + +# Main +compile || exit 1 +for t in test*; do runtest "$t"; done +exit 0 diff --git a/src/api/api_missions.nit b/src/api/api_missions.nit index 99729d0..e0fba7a 100644 --- a/src/api/api_missions.nit +++ b/src/api/api_missions.nit @@ -53,7 +53,12 @@ class APIMission print "Error deserializing submitted mission: {post}" return end - var runner = config.engine_map[submission_form.engine] + + if not config.engine_map.has_key(mission.engine) then + res.api_error("Engine {mission.engine} not found", 500) + return + end + var runner = config.engine_map[mission.engine] var submission = new Submission(player, mission, submission_form.source.decode_base64.to_s) runner.run(submission, config) diff --git a/src/api/engine_configuration.nit b/src/api/engine_configuration.nit index f36bd7a..b55b442 100644 --- a/src/api/engine_configuration.nit +++ b/src/api/engine_configuration.nit @@ -21,5 +21,6 @@ redef class AppConfig init do engine_map["pep8term"] = new Pep8Engine + engine_map["use-ocl"] = new UseOclEngine end end diff --git a/src/db_loader.nit b/src/db_loader.nit index 22638ee..978de45 100644 --- a/src/db_loader.nit +++ b/src/db_loader.nit @@ -47,7 +47,7 @@ if level >= 1 then var last_missions = new Array[Mission] var mission_count = (10 * level).rand for j in [1..mission_count] do - var mission = new Mission("track{i}:mission{j}", track, "Mission {i}-{j}", "desc {j}") + var mission = new Mission("track{i}:mission{j}", track, "Mission {i}-{j}", "desc {j}", "pep8term", "pep8") if last_missions.not_empty then if 100.rand > 75 then mission.parents.add last_missions.last.id diff --git a/src/model/engines/engine_base.nit b/src/model/engines/engine_base.nit index 8a466c8..e8e0419 100644 --- a/src/model/engines/engine_base.nit +++ b/src/model/engines/engine_base.nit @@ -106,7 +106,6 @@ class Engine test.expected_output.write_to_file(sfile) # Compare the result with diff - # TODO: some HTML-rich diff? Maybe client-side? res.produced_output = ofile.to_path.read_all var r = system("cd {ts} && diff -u sav.txt output.txt > diff.txt") if r != 0 then diff --git a/src/model/engines/engines.nit b/src/model/engines/engines.nit index 5d02f0d..ebb4e75 100644 --- a/src/model/engines/engines.nit +++ b/src/model/engines/engines.nit @@ -16,3 +16,4 @@ module engines import engine_base import pep8 import nitc +import use diff --git a/src/model/engines/use.nit b/src/model/engines/use.nit new file mode 100644 index 0000000..c00026a --- /dev/null +++ b/src/model/engines/use.nit @@ -0,0 +1,46 @@ +# 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. + +# USE-OCL engine +module use + +import engine_base + +# Handler for a USE-OCL submission +class UseOclEngine + super Engine + + redef fun language do return "OCL" + + redef fun extension do return "use" + + redef fun execute(submission) + do + var ws = submission.workspace + if ws == null then return false + + # Copy scripts and requirements + system("cp share/useoclrun.sh {ws}") + + # Run the payload + var r = system("share/saferun.sh {ws} ./useoclrun.sh") + + # Retrieve information + if r != 0 then + var err = (ws/"cmperr.txt").to_path.read_all + submission.compilation.message = "compilation error: {err}" + return false + end + + return true + end +end diff --git a/src/model/loader.nit b/src/model/loader.nit index 709f70b..405156a 100644 --- a/src/model/loader.nit +++ b/src/model/loader.nit @@ -105,6 +105,10 @@ class Loader if sd != null then track.default_size_desc = sd var ss = ini.get_i("star.size.reward") if ss != null then track.default_size_score = ss + var en = ini["engine"] + if en != null then track.default_engine = en + var ed = ini["editor"] + if ed != null then track.default_editor = ed var tmpl = (path / "template").to_path.read_all if not tmpl.is_empty then track.default_template = tmpl @@ -171,7 +175,11 @@ class Loader title_id = title.strip_id end - var m = new Mission(title_id, track, title, html) + var engine = ini["engine"] or else (if track != null then track.default_engine else "") + + var editor = ini["editor"] or else (if track != null then track.default_editor else "") + + var m = new Mission(title_id, track, title, html, engine, editor) m.path = path var reqs = ini["req"] diff --git a/src/model/missions.nit b/src/model/missions.nit index fc9db35..c85f8fe 100644 --- a/src/model/missions.nit +++ b/src/model/missions.nit @@ -36,6 +36,12 @@ class Mission var title: String var desc: String + # Engine used to check submissions + var engine: String is writable + + # Frontend code editor to use + var editor: String is writable + # List of allowed languages var languages = new Array[String] diff --git a/src/model/submissions.nit b/src/model/submissions.nit index d341209..e64a22e 100644 --- a/src/model/submissions.nit +++ b/src/model/submissions.nit @@ -125,10 +125,6 @@ class SubmissionForm # Source code to be run var source: String - # Engine or runner to be used - var engine: String - # Language in which the source code is writte - var lang: String end redef class MissionStar diff --git a/tests/test_base.nit b/tests/test_base.nit index a1aa6cf..d89d35a 100644 --- a/tests/test_base.nit +++ b/tests/test_base.nit @@ -39,7 +39,7 @@ class TestBase end fun new_mission(track: nullable Track, id: String): Mission do - var mission = new Mission(id, track, "title_{id}", "desc_{id}") + var mission = new Mission(id, track, "title_{id}", "desc_{id}", "engine_{id}", "editor") mission.solve_reward = 10 config.missions.save mission return mission diff --git a/tests/tracks/test_useocl.nit b/tests/tracks/test_useocl.nit new file mode 100644 index 0000000..4aa3dfc --- /dev/null +++ b/tests/tracks/test_useocl.nit @@ -0,0 +1,113 @@ +# Copyright 2017 Alexandre Terrasa . +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module test_useocl is test_suite + +import test_base +import model::loader +import api::engine_configuration + +class UseOclTest + super TestBase + + fun test_track_load do + var mission = config.missions.find_all.first + assert mission.title == "Classes" + assert mission.testsuite.length == 2 + end + + fun test_compilation_error do + var player = new_player("p1") + var source = "" + var mission = config.missions.find_all.first + var sub = new Submission(player, mission, source) + var runner = config.engine_map["use-ocl"] + runner.run(sub, config) + + assert sub.status == "error" + assert sub.test_errors == 0 + assert sub.results.length == 0 + assert sub.size_score == null + assert sub.time_score == null + assert sub.compilation.message == """ +compilation error: source.use:line 1:0 mismatched input '' expecting 'model' +""" + end + + fun test_bad_input1 do + var player = new_player("p2") + var source = """ +model bank + +class BankAccount + attributes + balance: Integer +end + +constraints + +context BankAccount + inv: balance >= 0 +""" + var mission = config.missions.find_all.first + var sub = new Submission(player, mission, source) + var runner = config.engine_map["use-ocl"] + runner.run(sub, config) + assert sub.status == "error" + assert sub.test_errors == 2 + assert sub.results.length == 2 + end + + fun test_good_input1 do + var player = new_player("p2") + var source = """ +model SpaceZ + +abstract class Vaisseau + attributes + poids: Integer + operations + decoller() +end + +class VaisseauCargo < Vaisseau + attributes + capacite: Integer + operations + charger(poids: Integer) +end + +class VaisseauCombat < Vaisseau + operations + attaquer(vaisseau: Vaisseau) +end +""" + var mission = config.missions.find_all.first + var sub = new Submission(player, mission, source) + var runner = config.engine_map["use-ocl"] + runner.run(sub, config) + assert sub.status == "success" + assert sub.test_errors == 0 + assert sub.results.length == 2 + end +end + +redef fun before_module do + var config = new AppConfig + config.parse_options(new Array[String]) + var loader = new Loader(config) + loader.load_track("tracks/use-ocl") +end + +redef fun after_module do super diff --git a/tracks-wip/nit/01_hello/config.ini b/tracks-wip/nit/01_hello/config.ini deleted file mode 100644 index ffb7fc9..0000000 --- a/tracks-wip/nit/01_hello/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Hello, World! -star.size.goal=22 diff --git a/tracks-wip/nit/01_hello/mission.md b/tracks-wip/nit/01_hello/mission.md deleted file mode 100644 index 5df4e3f..0000000 --- a/tracks-wip/nit/01_hello/mission.md +++ /dev/null @@ -1,57 +0,0 @@ -# Hello, World! - -Nit is a statically typed language that aims at elegance, simplicity and intuitiveness. - -For instance, `print` is a function that prints something at the screen. - -
print "I print therefore I am."
-
- - -In fact, `print` is a method from the core library that accepts any kind of objects and prints a human-readable form to standard output; but these concepts will be introduced later. - -Nit can be either compiled (with `nitc`) or interpreted (with `nit`). -Bonus: if the source code has the right permissions and starts with `#!/usr/bin/env nit`, it can be executed directly. - - $ cat rene.nit - #!/usr/bin/env nit - print "I print therefore I am." - - $ nitc rene.nit - $ ./rene - I print therefore I am. - - $ nit rene.nit - I print therefore I am. - - $ chmod +x rene.nit - $ ./rene.nit - I print therefore I am. - -## Mission - -* Difficulty: basic - -To prove your achievement, develop the traditional *Hello, World!* - -For all the missions in this tutorial, you can test your Nit source code on [http://test.nitlanguage.org/](http://test.nitlanguage.org/). - -### Template to Use - -For each mission, a template is provided. - -* You must use it. -* You can only write your code in the specified places -* You cannot modify other parts. - -The template of the mission is the following one: - -
module hello
-# CHANGE BELOW
-print "Something, Something"
-# CHANGE ABOVE
-
- -### Expected Output - - Hello, World! diff --git a/tracks-wip/nit/01_hello/result.txt b/tracks-wip/nit/01_hello/result.txt deleted file mode 100644 index 8ab686e..0000000 --- a/tracks-wip/nit/01_hello/result.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, World! diff --git a/tracks-wip/nit/01_hello/template.nit b/tracks-wip/nit/01_hello/template.nit deleted file mode 100644 index cf1716d..0000000 --- a/tracks-wip/nit/01_hello/template.nit +++ /dev/null @@ -1,4 +0,0 @@ -module hello -# CHANGE BELOW -print "Something, Something!" -# CHANGE ABOVE diff --git a/tracks-wip/nit/01_hello/tests.txt b/tracks-wip/nit/01_hello/tests.txt deleted file mode 100644 index 035ff5a..0000000 --- a/tracks-wip/nit/01_hello/tests.txt +++ /dev/null @@ -1,3 +0,0 @@ -=== ---- -Hello, World! diff --git a/tracks-wip/nit/02_value/config.ini b/tracks-wip/nit/02_value/config.ini deleted file mode 100644 index d434476..0000000 --- a/tracks-wip/nit/02_value/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Values and Types -req=01_hello diff --git a/tracks-wip/nit/02_value/mission.md b/tracks-wip/nit/02_value/mission.md deleted file mode 100644 index 631011f..0000000 --- a/tracks-wip/nit/02_value/mission.md +++ /dev/null @@ -1,87 +0,0 @@ -# Values and Types - -Nit is a fully Object-Oriented language. -It means that any value is an object (even primitive values like integers). - -Nit is also Class-Oriented. -It means that any object is an instance of a class. - -Nit is also fully statically typed. -It means that any expression, local variable, parameter, return value and attribute of instance has a static type that documents and controls what kind of values are expected. - -Local variables are used to hold values. -To use variables you must declare them (with the `var` keyword). -You can assign them (with `=`) and use them in expressions. - -
var i
-i = 5
-print i + 1 # Outputs 6
-
- -As you can see, although Nit is statically typed, the language does not force the programmer to annotate most static types. -The static type system automatically associates `i` with the static type `Int`, the static type is then used to check that `+ 1` is legal on `i`. - -For instance, the type system will prevent a tired programmer to add Booleans: - -
var j = true
-print j + 1
-#       ^
-# Compilation Error: method `+` does not exists in `Bool`.
-
- -Beside integers (`Int`) and booleans (`Bool`), the core library defines a lot of other classes like `String` and `Float`. - -Static types are mainly used to ensure that the operations used on the values are legal for any execution of the libraries or the program. - -Common operations are available on the types defined by the core library. For instance: - -
var three = 1 + 2
-var hw = "hello" + " " + "world"
-
- -The type system ensures that operations are valid on the operands. -For instance mixing types does not always work: - -
print three + hw
-#             ^
-# Type Error: expected `Int`, got `String`
-
- -Conversion between types can be achieved with special operations like `to_i`, `to_s`. - -Moreover, string expansion is available through the `{}` notation: - -
print "one plus one is {1+1}" # one plus one is 2
-print "10".to_i + 10 # 20
-print 10.to_s + "10" # 1010
-
- -Inside strings, `"` and `{` can be escaped with `\`. Or a triple quoted notation could be used. - -
print "\"quote" and \{curly brackets\}"
-print """"quote" and {curly brackets}"""
-
- -## Mission - -* Difficulty: basic - -Define two variables, `a_string` and `an_integer` initialized respectively to `"ten"` and `10`. - -### Template to Use - -
module value
-
-# CHANGE BELOW
-var a_string = ?
-var an_integer = ?
-# CHANGE ABOVE
-
-print "a_string! {a_string + "!"}"
-print "an_integer! {an_integer.factorial}"
-
- -### Expected Output - - a_string! ten! - an_integer! 3628800 diff --git a/tracks-wip/nit/02_value/result.txt b/tracks-wip/nit/02_value/result.txt deleted file mode 100644 index d83fc93..0000000 --- a/tracks-wip/nit/02_value/result.txt +++ /dev/null @@ -1,2 +0,0 @@ -a_string! ten! -an_integer! 3628800 diff --git a/tracks-wip/nit/02_value/template.nit b/tracks-wip/nit/02_value/template.nit deleted file mode 100644 index bcdfb32..0000000 --- a/tracks-wip/nit/02_value/template.nit +++ /dev/null @@ -1,9 +0,0 @@ -module value - -# CHANGE BELOW -var a_string = ? -var an_integer = ? -# CHANGE ABOVE - -print "a_string! {a_string + "!"}" -print "an_integer! {an_integer.factorial}" diff --git a/tracks-wip/nit/03_control/config.ini b/tracks-wip/nit/03_control/config.ini deleted file mode 100644 index e83857a..0000000 --- a/tracks-wip/nit/03_control/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Control structures and conditions -req=02_value diff --git a/tracks-wip/nit/03_control/mission.md b/tracks-wip/nit/03_control/mission.md deleted file mode 100644 index f0fa8c8..0000000 --- a/tracks-wip/nit/03_control/mission.md +++ /dev/null @@ -1,82 +0,0 @@ -# Control structures and conditions - -Usual control structures, like conditions and loops, are available. - -Most of them exist in two flavors: one-liner and multi-line. - -The one-liner flavor needs a single statement just after the control. - -
if level > 9000 then print "It's over 9000!!"
-
- -The multi-line flavor has a line-return after the control but requires an `end` keyword. - -
if level > 9000 then
-	print "It's over 9000!!"
-	print "- What! Nine thousand!"
-end
-
- -The `if` control accepts an optional `else` block. - -
if level > 9000 then
-	print "It's over 9000!!"
-else if level > 1000 then
-	print "It's over 1000..."
-else
-	print "It's not impressive."
-end
-
- -`while` loops are also available: - -
var i = 999
-while i > 1 do
-	print "{i} bottles on the wall..."
-	i -= 1
-end
-print "1 last bottle on the wall..."
-
- -`for` is an improved `while` that iterates on collections. -They will be shown in a later mission, for the moment, we will use them to iterate on ranges of integers. - -
for i in [0..5[ do print i # 0 1 2 3 4 (5 is excluded)
-
- -## Mission - -* Difficulty: medium - -Write a loop that computes the first Fibonacci numbers below a given limit. - -Confidential information: fib(0) = 0; fib(1) = 1; fib(n) = fib(n-1) + fib(n-2) - -### Template to Use - -
module fibonacci
-
-var limit = 500
-
-var prev = 0
-var n = 1
-
-# CODE HERE
-
- -### Expected Output - - 1 - 1 - 2 - 3 - 5 - 8 - 13 - 21 - 34 - 55 - 89 - 144 - 233 - 377 diff --git a/tracks-wip/nit/03_control/result.txt b/tracks-wip/nit/03_control/result.txt deleted file mode 100644 index 53bb234..0000000 --- a/tracks-wip/nit/03_control/result.txt +++ /dev/null @@ -1,14 +0,0 @@ -1 -1 -2 -3 -5 -8 -13 -21 -34 -55 -89 -144 -233 -377 diff --git a/tracks-wip/nit/03_control/result_bis.txt b/tracks-wip/nit/03_control/result_bis.txt deleted file mode 100644 index 7d0da54..0000000 --- a/tracks-wip/nit/03_control/result_bis.txt +++ /dev/null @@ -1,19 +0,0 @@ -1 -1 -2 -3 -5 -8 -13 -21 -34 -55 -89 -144 -233 -377 -610 -987 -1597 -2584 -4181 diff --git a/tracks-wip/nit/03_control/template.nit b/tracks-wip/nit/03_control/template.nit deleted file mode 100644 index 3f31790..0000000 --- a/tracks-wip/nit/03_control/template.nit +++ /dev/null @@ -1,8 +0,0 @@ -module fibonacci - -var limit = 500 - -var prev = 0 -var n = 1 - -# CODE HERE diff --git a/tracks-wip/nit/03b_control/config.ini b/tracks-wip/nit/03b_control/config.ini deleted file mode 100644 index 88096aa..0000000 --- a/tracks-wip/nit/03b_control/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Control of Control Structures -req=03_control diff --git a/tracks-wip/nit/03b_control/mission.md b/tracks-wip/nit/03b_control/mission.md deleted file mode 100644 index 4d8a39e..0000000 --- a/tracks-wip/nit/03b_control/mission.md +++ /dev/null @@ -1,81 +0,0 @@ -# Control of Control Structures - -`break` and `continue` can be used to control the exit path from loops. - -
for i in [0..50[ do
-	if i == 2 then continue
-	if i == 5 then break
-	print i
-end
-# output 0 1 3 4
-
- -Two other special control structures are the `do` and the `loop`. - -`do` is mainly used to scope local variables. It is also used to bound a `break`. - -
do
-	if level > 9000 then break # exit the block
-	print "It's over 9000!!"
-	if not opponent.is_android then break # exit the block
-	print "Big Bang Attack"
-end
-
- -`loop` is used as a infinite loop. It usually requires some additional explicit `break` to control the exit. -It is used to implement `do while/until` loops or `while` loops with a complex exit condition. - -
var nb = 0
-loop
-	var line = gets
-	if line == "" then break
-	nb += 1
-end
-print "There was {nb} line(s)."
-
- -## Mission - -* Difficulty: medium - -Finish the program that tests the primality of some numbers. - -### Template to Use - -
module prime
-
-var limit = 20
-
-for i in [2..limit] do
-	for j in [2..i[ do
-		if i % j == 0 then
-# CHANGE BELOW
-...
-print "{i} is not prime."
-...
-print "{i} is prime."
-...
-# CHANGE ABOVE
-
- -### Expected Output - - 2 is prime. - 3 is prime. - 4 is not prime. - 5 is prime. - 6 is not prime. - 7 is prime. - 8 is not prime. - 9 is not prime. - 10 is not prime. - 11 is prime. - 12 is not prime. - 13 is prime. - 14 is not prime. - 15 is not prime. - 16 is not prime. - 17 is prime. - 18 is not prime. - 19 is prime. - 20 is not prime. diff --git a/tracks-wip/nit/03b_control/result.txt b/tracks-wip/nit/03b_control/result.txt deleted file mode 100644 index 47af551..0000000 --- a/tracks-wip/nit/03b_control/result.txt +++ /dev/null @@ -1,19 +0,0 @@ -2 is prime. -3 is prime. -4 is not prime. -5 is prime. -6 is not prime. -7 is prime. -8 is not prime. -9 is not prime. -10 is not prime. -11 is prime. -12 is not prime. -13 is prime. -14 is not prime. -15 is not prime. -16 is not prime. -17 is prime. -18 is not prime. -19 is prime. -20 is not prime. diff --git a/tracks-wip/nit/03b_control/result_bis.txt b/tracks-wip/nit/03b_control/result_bis.txt deleted file mode 100644 index bb40525..0000000 --- a/tracks-wip/nit/03b_control/result_bis.txt +++ /dev/null @@ -1,32 +0,0 @@ -2 is prime. -3 is prime. -4 is not prime. -5 is prime. -6 is not prime. -7 is prime. -8 is not prime. -9 is not prime. -10 is not prime. -11 is prime. -12 is not prime. -13 is prime. -14 is not prime. -15 is not prime. -16 is not prime. -17 is prime. -18 is not prime. -19 is prime. -20 is not prime. -21 is not prime. -22 is not prime. -23 is prime. -24 is not prime. -25 is not prime. -26 is not prime. -27 is not prime. -28 is not prime. -29 is prime. -30 is not prime. -31 is prime. -32 is not prime. -33 is not prime. diff --git a/tracks-wip/nit/03b_control/template.nit b/tracks-wip/nit/03b_control/template.nit deleted file mode 100644 index fffa93d..0000000 --- a/tracks-wip/nit/03b_control/template.nit +++ /dev/null @@ -1,14 +0,0 @@ -module prime - -var limit = 20 - -for i in [2..limit] do - for j in [2..i[ do - if i % j == 0 then -# CHANGE BELOW -... -print "{i} is not prime." -... -print "{i} is prime." -... -# CHANGE ABOVE diff --git a/tracks-wip/nit/04_function/config.ini b/tracks-wip/nit/04_function/config.ini deleted file mode 100644 index 355efff..0000000 --- a/tracks-wip/nit/04_function/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Functions -req=03_control diff --git a/tracks-wip/nit/04_function/mission.md b/tracks-wip/nit/04_function/mission.md deleted file mode 100644 index 02d574e..0000000 --- a/tracks-wip/nit/04_function/mission.md +++ /dev/null @@ -1,114 +0,0 @@ -# Functions - -Functions start with the `fun` keyword. They require a name, parameters (if any) and a return type (if any). - -
fun presentation(name: String, age: Int): String
-do
-	return "Hello, my name is {name} and I am {age}. I live in the Dome and I am an happy Citizen."
-end
-
-print presentation("Alice", 21)
-
- -## Default Argument Values - -Default arguments values rely on the `nullable` information: trailing nulls in a call can be omitted. - -
fun presentation(name: nullable String, age: nullable Int): String
-do
-	if name == null then name = "Anonymous"
-	# Note: Adaptive typing says that `name` is a non-nullable here
-	var res = "Hello, my name is {name}"
-	if age != null then
-		# Note: Adaptive typing says that `age` is a non-nullable here
-		# type adaptation
-		res += " and I am {age}"
-	end
-	res += ". I live in the Dome and I am an happy Citizen."
-	return res
-end
-print presentation("Alice", 21)
-print presentation("Bob")
-print presentation(null, 99)
-print presentation
-
- -## Variadic Function - -A parameter can hold a variable number of arguments, its type has to be suffixed by the ellipsis `...` - -On the call side, one or more parameters can be given, on the method side, the static type of the parameter is an Array. - -
fun present_all(names: String...): String
-do
-	if names.length == 1 then
-		return presentation(names.first)
-	else
-		return "Hello, we are {names.join(", ")} and we are legion."
-	end
-end
-print present_all("Alice", "Bob", "Dylan")
-print present_all("Eve")
-
- -## Mission - -* Difficulty: medium - -Write a function `hanoi` that plays the Towers of Hanoi. - -### Template to Use - -
module hanoi
-
-# CODE HERE
-
-print "Test 3 disks"
-hanoi(3)
-
-print "Test 5 disks"
-hanoi(5)
-
- -### Expected Result - - Test 3 disks - Move disk from 0 to 1. - Move disk from 0 to 2. - Move disk from 1 to 2. - Move disk from 0 to 1. - Move disk from 2 to 0. - Move disk from 2 to 1. - Move disk from 0 to 1. - Test 5 disks - Move disk from 0 to 1. - Move disk from 0 to 2. - Move disk from 1 to 2. - Move disk from 0 to 1. - Move disk from 2 to 0. - Move disk from 2 to 1. - Move disk from 0 to 1. - Move disk from 0 to 2. - Move disk from 1 to 2. - Move disk from 1 to 0. - Move disk from 2 to 0. - Move disk from 1 to 2. - Move disk from 0 to 1. - Move disk from 0 to 2. - Move disk from 1 to 2. - Move disk from 0 to 1. - Move disk from 2 to 0. - Move disk from 2 to 1. - Move disk from 0 to 1. - Move disk from 2 to 0. - Move disk from 1 to 2. - Move disk from 1 to 0. - Move disk from 2 to 0. - Move disk from 2 to 1. - Move disk from 0 to 1. - Move disk from 0 to 2. - Move disk from 1 to 2. - Move disk from 0 to 1. - Move disk from 2 to 0. - Move disk from 2 to 1. - Move disk from 0 to 1. diff --git a/tracks-wip/nit/04_function/result.txt b/tracks-wip/nit/04_function/result.txt deleted file mode 100644 index 3147ca2..0000000 --- a/tracks-wip/nit/04_function/result.txt +++ /dev/null @@ -1,40 +0,0 @@ -Test 3 disks -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Test 5 disks -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. diff --git a/tracks-wip/nit/04_function/result_bis.txt b/tracks-wip/nit/04_function/result_bis.txt deleted file mode 100644 index 9296a36..0000000 --- a/tracks-wip/nit/04_function/result_bis.txt +++ /dev/null @@ -1,136 +0,0 @@ -Test 3 disks -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Test 5 disks -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 1 to 2. -Move disk from 1 to 0. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. -Move disk from 0 to 2. -Move disk from 1 to 2. -Move disk from 0 to 1. -Move disk from 2 to 0. -Move disk from 2 to 1. -Move disk from 0 to 1. diff --git a/tracks-wip/nit/04_function/template.nit b/tracks-wip/nit/04_function/template.nit deleted file mode 100644 index 61834a7..0000000 --- a/tracks-wip/nit/04_function/template.nit +++ /dev/null @@ -1,9 +0,0 @@ -module hanoi - -# CODE HERE - -print "Test 3 disks" -hanoi(3) - -print "Test 5 disks" -hanoi(5) diff --git a/tracks-wip/nit/05_collection/config.ini b/tracks-wip/nit/05_collection/config.ini deleted file mode 100644 index ba183c8..0000000 --- a/tracks-wip/nit/05_collection/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Collections and for loops -req=04_function diff --git a/tracks-wip/nit/05_collection/mission.md b/tracks-wip/nit/05_collection/mission.md deleted file mode 100644 index eb6f81a..0000000 --- a/tracks-wip/nit/05_collection/mission.md +++ /dev/null @@ -1,73 +0,0 @@ -# Collections and for loops - -In Nit there are various kinds of collections. -They are used to manipulate finite groups of objects. - -Because Nit is statically typed, the type of the elements of a collection is statically known. - -The most common collection is `Array`. - -
var a = [2, 3, 5]
-print a.length # 3
-print a.first # 2
-print a[2] # 5
-
- -Array is a mutable data-structure and elements can be added or removed. - -
print a.pop # 5
-print a     # [2,3]
-a.add 50
-print a     # [2,3,50]
-
- -Another useful collection is Range. It is used to store intervals. - -There are two kind of ranges, closed ones and semi-open ones (we'll just refer to them as open even if it is not mathematically accurate). - -
var closed = [10..15]
-print closed # [10,11,12,13,14,15]
-var open = [10..15[
-print open # [10,11,12,13,14]
-
- -The most common operation on collections is to iterate on them. -The `for` control structure does just that. - -
for i in [0..5[ do print i # 0 1 2 3 4
-for i in [2, 3, 5] do print i # 2 3 5
-
- -## Mission - -* Difficulty: easy - -Write a function that prints the numbers of a collection that are odd and lower than 42. - -### Template to Use - -
module filter
-
-fun filter(ints: Collection[Int])
-do
-# CODE HERE
-end
-
-print "Test 1"
-filter([1,2,3,41,42,43,9])
-print "Test 2"
-filter([35..45])
-
- -### Expected Output - - Test 1 - 1 - 3 - 41 - 9 - Test 2 - 35 - 37 - 39 - 41 diff --git a/tracks-wip/nit/05_collection/result.txt b/tracks-wip/nit/05_collection/result.txt deleted file mode 100644 index c2fccb0..0000000 --- a/tracks-wip/nit/05_collection/result.txt +++ /dev/null @@ -1,10 +0,0 @@ -Test 1 -1 -3 -41 -9 -Test 2 -35 -37 -39 -41 diff --git a/tracks-wip/nit/05_collection/result_bis.txt b/tracks-wip/nit/05_collection/result_bis.txt deleted file mode 100644 index e2b6f90..0000000 --- a/tracks-wip/nit/05_collection/result_bis.txt +++ /dev/null @@ -1,27 +0,0 @@ -Test 1 -1 -3 -41 -9 -Test 2 -1 -3 -5 -7 -9 -11 -13 -15 -17 -19 -21 -23 -25 -27 -29 -31 -33 -35 -37 -39 -41 diff --git a/tracks-wip/nit/05_collection/template.nit b/tracks-wip/nit/05_collection/template.nit deleted file mode 100644 index 3236121..0000000 --- a/tracks-wip/nit/05_collection/template.nit +++ /dev/null @@ -1,11 +0,0 @@ -module filter - -fun filter(ints: Collection[Int]) -do -# CODE HERE -end - -print "Test 1" -filter([1,2,3,41,42,43,9]) -print "Test 2" -filter([35..45]) diff --git a/tracks-wip/nit/06_type/config.ini b/tracks-wip/nit/06_type/config.ini deleted file mode 100644 index 1fdcbf3..0000000 --- a/tracks-wip/nit/06_type/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Nullable and Adaptive Typing -req=05_collection diff --git a/tracks-wip/nit/06_type/mission.md b/tracks-wip/nit/06_type/mission.md deleted file mode 100644 index 5ef66bc..0000000 --- a/tracks-wip/nit/06_type/mission.md +++ /dev/null @@ -1,117 +0,0 @@ -# Nullable and Adaptive Typing - -One of the specific features of Nit is the management of `null` values and how static types of expressions and variables are computed. - -Unlike most other languages, the `null` value is statically controlled in Nit, therefore it cannot occur randomly. - -To accept `null`, the static type must be extended with the `nullable` keyword. - -
var a: Int = 10            # OK
-var b: nullable Int = 1    # OK
-var c: nullable Int = null # OK
-var d: Int = null # NOT OK
-#            ^
-# Type Error: expected `Int`, got `null`.
-
- -The static type system ensures that `null` values do not propagate to unwanted places. -Therefore, it is required to test the value of expressions that might be null. - -To control the correction of programs, the static type system of Nit features *adaptive typing*. -Adaptive typing is used to track the static types of variables and expressions. -With adaptive typing, the static type of variables might change according to: - -* its assignments -* its comparisons to null (with `==` and `!=`) -* its type checks (with `isa` seen below) -* the control flow of the program (`if`, `while`, `break`, `and`, etc.) - -
# Double a number; if null is given 0 is returned.
-fun double(value: nullable Int): Int
-do
-	# Here, `value` is a `nullable Int`
-	if value == null then return 0
-	# Here, `value` is a `Int`. It's *adaptive typing!
-	return value * 2
-end
-print double(null)
-print double(10)
-
- -Adaptive typing correctly handles independent assignments. - -
fun triple(value: nullable Int): Int
-do
-	# Here `value` is a `nullable Int`
-	if value == null then
-		# Here `value` is `null`
-		value = 0
-		# Here `value` is `Int`
-	end # In the implicit and empty else, `value` is `Int`
-	# Here `value` is Int
-	return value * 3
-end
-print triple(null)
-print triple(10)
-
- -The `isa` keyword can be used to test the dynamic type of an expression. -If the expression is a variable, then its static type can be adapted. - -
fun what_it_is(value: nullable Object)
-do
-	# `value` is a `nullable Object` that is the most general type is the type hierarchy of Nit.
-	if value == null then
-		print "It's null"
-		return
-	end
-	# Now, `value` is a `Object` that is the root of the class hierarchy.
-	if value isa Int then
-		# Now `value` is a `Int`.
-		# No need to cast, the static type is already adapted.
-		print "It's the integer {value}, the one that follows {value-1}."
-		# Because `value` is an `Int`, `value-1` is accepted
-	else if value isa String then
-		print "It's the string `{value}`, made of {value.length} charcters."
-	else
-		print "Whathever it is, I do not care."
-	end
-end
-what_it_is 5
-what_it_is "five"
-what_it_is true
-
- -## Mission - -* Difficulty: easy - -Implement a method `deep_first` that returns the first non-collection element of an object. - -### Template to Use - -
module deep_first
-
-fun deep_first(a: Object): Object
-do
-	# CHANGE BELOW
-	... a isa Collection[Object] ...
-	# CHANGE ABOVE
-end
-
-var one = 1
-print deep_first(one)
-var range = [1..5]
-print deep_first(range)
-var ranges = [range, [3..8]]
-print deep_first(ranges)
-var arrays = [[2,3],[3,4]]
-print deep_first(arrays)
-
- -### Expected Outputs - - 1 - 1 - 1 - 2 diff --git a/tracks-wip/nit/06_type/result.txt b/tracks-wip/nit/06_type/result.txt deleted file mode 100644 index 1af4bf8..0000000 --- a/tracks-wip/nit/06_type/result.txt +++ /dev/null @@ -1,4 +0,0 @@ -1 -1 -1 -2 diff --git a/tracks-wip/nit/06_type/result_bis.txt b/tracks-wip/nit/06_type/result_bis.txt deleted file mode 100644 index 81628f0..0000000 --- a/tracks-wip/nit/06_type/result_bis.txt +++ /dev/null @@ -1,4 +0,0 @@ -a -1 -1 -2 diff --git a/tracks-wip/nit/06_type/template.nit b/tracks-wip/nit/06_type/template.nit deleted file mode 100644 index 239653c..0000000 --- a/tracks-wip/nit/06_type/template.nit +++ /dev/null @@ -1,17 +0,0 @@ -module deep_first - -fun deep_first(a: Object): Object -do - # CHANGE BELOW - ... a isa Collection[Object] ... - # CHANGE ABOVE -end - -var one = 1 -print deep_first(one) -var range = [1..5] -print deep_first(range) -var ranges = [range, [3..8]] -print deep_first(ranges) -var arrays = [[2,3],[3,4]] -print deep_first(arrays) diff --git a/tracks-wip/nit/class/config.ini b/tracks-wip/nit/class/config.ini deleted file mode 100644 index 3ba11c5..0000000 --- a/tracks-wip/nit/class/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Classes and OOP -req=06_type diff --git a/tracks-wip/nit/class/mission.md b/tracks-wip/nit/class/mission.md deleted file mode 100644 index 571cf61..0000000 --- a/tracks-wip/nit/class/mission.md +++ /dev/null @@ -1,80 +0,0 @@ -# Classes and OOP - -## Classes and Methods - -Nit tries to be POLA in defining classes. - -Classes are defined with the keyword `class`, super-classes are indicated with `super` (multiple inheritance is allowed), methods are introduced with `fun` and overridden with `redef fun`. -Instantiation is done with `new`. - -
class Movie
-	fun is_about_cyclign: Bool do return true
-end
-
-class Americaine
-	super Movie
-	redef fun is_about_cyclign do return false
-end
-
-var f = new Movie
-print f.is_about_cyclign # true
-f = new Americaine
-print f.is_about_cyclign # false
-
- -## Attributes and Constructors - -Attributes (aka fields, slots or instance variables) are declared with `var`. -Their behaviour slightly differs from the majority of other languages and is strongly linked with how constructors are specified. - -* no need to define accessors: attributes come by default with a getter and a setter, the underlying attribute is accessed internally. -* no need to define constructors: attributes without a default value need one when the object is allocated -* an optional parameter-less special method (declared with the keyword `init`) is called to finish the construction - -
class Inventory # à la Prévert
-	var an_int: Int
-	var a_string: String
-	var another_int = 2
-	var another_string = "houses"
-	init do print "{an_int} {a_string}, {another_int} {another_string}..."
-end
-var i = new Inventory(1, "stone")
-# initialize `an_int` and `a_string` and call `init`.
-So print "1 stone, 2 houses..."
-
- -Subclasses inherit the attributes and the constructor behavior and `init` are automatically linked (in fact there is an implicit `super`). - -
class MoreInventory
-	super Inventory
-	var a_3rd_int: Int
-	var a_3rd_string: String
-	init do print "{a_3rd_int} {a_3rd_string}..."
-end
-var j = new MoreInventory(1, "garden", 6, "musicians")
-# print "1 garden, 2 houses..." and "6 musicians..."
-
- -## Mission - -* Difficulty: easy - -Write a class `Hello` with an attribute `what: String`, and a method `say: String` that prints `"Hello, {what}!"`. -Write a class `Goodbye` with an attribute `hello: Hello`, and a method `say` that reply goodby. - -### Template do Use - -
module helloo
-
-# CODE HERE
-
-var h = new Hello("World")
-h.say
-var g = new Goodbye(h)
-g.say
-
- -### Expected Output - - Hello, World! - Goodbye, World! diff --git a/tracks-wip/nit/class/result.txt b/tracks-wip/nit/class/result.txt deleted file mode 100644 index 8d4265f..0000000 --- a/tracks-wip/nit/class/result.txt +++ /dev/null @@ -1,2 +0,0 @@ -Hello, World! -Goodbye, World! diff --git a/tracks-wip/nit/class/result_bis.txt b/tracks-wip/nit/class/result_bis.txt deleted file mode 100644 index 8f1e557..0000000 --- a/tracks-wip/nit/class/result_bis.txt +++ /dev/null @@ -1,2 +0,0 @@ -Hello, Dome! -Goodbye, Dome! diff --git a/tracks-wip/nit/class/template.nit b/tracks-wip/nit/class/template.nit deleted file mode 100644 index 058a304..0000000 --- a/tracks-wip/nit/class/template.nit +++ /dev/null @@ -1,8 +0,0 @@ -module helloo - -# CODE HERE - -var h = new Hello("World") -h.say -var g = new Goodbye(h) -g.say diff --git a/tracks-wip/nit/ffi/config.ini b/tracks-wip/nit/ffi/config.ini deleted file mode 100644 index 78a6534..0000000 --- a/tracks-wip/nit/ffi/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Foreign Function Interface -req=refinement diff --git a/tracks-wip/nit/ffi/mission.md b/tracks-wip/nit/ffi/mission.md deleted file mode 100644 index 7d47cb4..0000000 --- a/tracks-wip/nit/ffi/mission.md +++ /dev/null @@ -1,137 +0,0 @@ -# Foreign Function Interface - -The Nit Foreign Function Interface (FFI) allows the nesting of foreign code within a Nit source file. -Current supported languages are C, C++, Java (used mainly for android support) and Objective C (used mainly for iOS support). - -Common use cases of the FFI is to optimize a method or to wrap existing system or third-party libraries. -The syntax use back-quoted curly-brackets. - - - -
fun in_nit do print "In Nit"
-fun in_c `{ printf("In C\n"); `}
-fun in_cpp in "C+" `{ cout << "In C++" << endl; `}
-fun in_java in "Java" `{ System.out.println("In Java"); `}
-fun in_objc in "ObjC" `{ NSLog (@"In Objective C\n"); `}
-
-in_nit
-in_c
-in_cpp
-in_java
-in_objc
-
- -Advanced features of the Nit FFI include: - -* inclusion of global declarations -* automatic conversion between some Nit and foreign types -* declaration of callback functions to call Nit methods from within the foreign code. - -The following example shows how can the C function `strchr` be used to search a character in a string. - - - -
# global FFI declaration are enclosed by `{ `}
-# Use them for #include and related things.
-
-`{
-#include <string.h
-`}
-
-# Any class can be refined with FFI method.
-redef class String 
-	fun strchr(c: Char): Int import to_cstring `{
-		// Two parameter, `self` and `c`.
-		// `self` is an opaque type in the C side
-		// `c` is converted to the primitive `char`
-
-		// Because `strchr` need a `char`, we must convert the opaque `self`
-		// to something usable.
-		// the `import` clause makes the method `to_cstring` available in C.
-		char *str = String_to_cstring(self);
-
-		// In Nit, `to_cstring` returns a `NativeString`.
-		// In C, `NativeString` are automatically converted to `char`.
-		char *res = strchr(str, c);
-		if (res=NULL) return -1;
-		return res - str;
-	`}
-end
-
-print "Hello, World".strchr('W') # 7
-print "Hello, World".strchr('*') # -1
-
- -## Mission - -* Difficulty: easy - -Refine the class `String` and add a method `fnmatch(pattern: String): Bool` that wrap the POSIX function `fnmatch` (Hint: `man fnmatch`) - -### Template to Use - - - -
module fnmatch
-
-# CODE HERE
-
-print "mpire.nit".fnmatch("*.nit")
-print "mpire.nit".fnmatch("*.zip")
-
- -### Expected Output - - true - false diff --git a/tracks-wip/nit/ffi/result.txt b/tracks-wip/nit/ffi/result.txt deleted file mode 100644 index da29283..0000000 --- a/tracks-wip/nit/ffi/result.txt +++ /dev/null @@ -1,2 +0,0 @@ -true -false diff --git a/tracks-wip/nit/ffi/result_bis.txt b/tracks-wip/nit/ffi/result_bis.txt deleted file mode 100644 index 1d474d5..0000000 --- a/tracks-wip/nit/ffi/result_bis.txt +++ /dev/null @@ -1,2 +0,0 @@ -false -true diff --git a/tracks-wip/nit/ffi/template.nit b/tracks-wip/nit/ffi/template.nit deleted file mode 100644 index 6d42082..0000000 --- a/tracks-wip/nit/ffi/template.nit +++ /dev/null @@ -1,6 +0,0 @@ -module fnmatch - -# CODE HERE - -print "mpire.nit".fnmatch("*.nit") -print "mpire.nit".fnmatch("*.zip") diff --git a/tracks-wip/nit/ffi2/config.ini b/tracks-wip/nit/ffi2/config.ini deleted file mode 100644 index f498455..0000000 --- a/tracks-wip/nit/ffi2/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Wrapping Libraries -req=ffi diff --git a/tracks-wip/nit/ffi2/mission.md b/tracks-wip/nit/ffi2/mission.md deleted file mode 100644 index 5188c63..0000000 --- a/tracks-wip/nit/ffi2/mission.md +++ /dev/null @@ -1,161 +0,0 @@ -# Wrapping Libraries - -Nit can provide automatic wrapping of extern data structures as classes. -Theses classes are declared `extern`. - -The goal of extern classes is to describe data that lives in the foreign language. -Like a normal class, an extern class can define, inherit and refine methods. -Methods can even be foreign or pure Nit. -The only restriction is that extern classes cannot have attributes (data lives in the foreign world) and can only specialize interfaces or other extern classes. - -The advantage of extern classes is that values are no more opaque in extern methods. -When an extern class is used to type a parameter or the return value of an extern method, -the value is then directly accessible. - -The foreign type is indicated after the class name with the now traditional back-quoted curly-bracket notation. - - - -
`{
-#include <systypes.h
-#include <dirent.h
-`}
-
-extern class CDir `{ DIR* `}
-        # Open a directory
-        new(path: NativeString) `{ return opendir(path); `}
-
-        # Close a directory
-        fun closedir `{ closedir(self); `}
-
-        # Read the next directory entry
-        fun readdir: NativeString `{
-                struct dirent *de;
-                de = readdir(self);
-                if (!de) return NULL;
-                return de->d_name;
-        `}
-end
-
-# Simple client
-# Disclaimer: Usually it is often a better idea to add another API level to avoid
-# the direct manipulation of foreign values.
-var dir = new CDir(".".to_cstring)
-loop
-	var ent = dir.readdir
-	if ent.address_is_null then break
-	print ent.to_s
-end
-dir.closedir
-
- -Some included foreign code may require specific compilation flags. -These flags can be declared in the module declaration. - -Most of the time for C and C++ foreign code, the tool `pkg-config` can be used to correctly get these flags. -`nitc` simplifies the process for you. - - - -
module curl is pkgconfig
-
-# Rest of the code...
-
- -## Mission - -* Difficulty: advanced - -Write a simple wrapper around [libcaca](http://caca.zoy.org/doxygen/libcaca/caca_8h.html) that includes the following data types and functions: - -You need to wrap the following: - -* `caca_display_t` as `CadaDisplay` -* `caca_get_canvas` as `CadaDisplay::canvas` -* `caca_refresh_display` as `CadaDisplay::refresh` -* `caca_canvas_t` as `CacaCanvas` -* `caca_put_str` as `CacaCanvas::put` - -Also add a `CadaDisplay::quit` that waits for any input event, then destroys the display. - -Here an example of a working client. - - - -
module caca_client
-
-import caca
-
-var d = new CacaDisplay
-var c = d.canvas
-c.put("Hello, World", 5, 1)
-d.refresh
-d.quit
-
- -Look at the [caca tutorial](http://caca.zoy.org/doxygen/libcaca/libcaca-tutorial.html) and the [caca header file](http://caca.zoy.org/doxygen/libcaca/caca_8h.html) for more information. - -### Template to Use - - - -
module caca is pkgconfig
-
-# CODE HERE
-
- -### Expected Result - -A window with "Hello, World!" at (5,1) when executing `caca_client` compiled with your lib. diff --git a/tracks-wip/nit/ffi2/result.txt b/tracks-wip/nit/ffi2/result.txt deleted file mode 100644 index 8179aeb..0000000 --- a/tracks-wip/nit/ffi2/result.txt +++ /dev/null @@ -1 +0,0 @@ -^[]0;caca for ncurses^G Hello, World!^[]0;^G^M diff --git a/tracks-wip/nit/ffi2/template.nit b/tracks-wip/nit/ffi2/template.nit deleted file mode 100644 index f00a1e9..0000000 --- a/tracks-wip/nit/ffi2/template.nit +++ /dev/null @@ -1,3 +0,0 @@ -module caca is pkgconfig - -# CODE HERE diff --git a/tracks-wip/nit/image.png b/tracks-wip/nit/image.png deleted file mode 100644 index fae2bdf..0000000 Binary files a/tracks-wip/nit/image.png and /dev/null differ diff --git a/tracks-wip/nit/logolas_caca/config.ini b/tracks-wip/nit/logolas_caca/config.ini deleted file mode 100644 index bd63645..0000000 --- a/tracks-wip/nit/logolas_caca/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Final Mission -req=ffi2,nitcc_2 diff --git a/tracks-wip/nit/logolas_caca/mission.md b/tracks-wip/nit/logolas_caca/mission.md deleted file mode 100644 index 704361f..0000000 --- a/tracks-wip/nit/logolas_caca/mission.md +++ /dev/null @@ -1,100 +0,0 @@ -# Final Mission - -* Difficulty: advanced - -Your mission is to combine your `caca` library and your `logolas` parser to render a logolas vectorial image on a terminal. - -The `caca` library is - - - -
module caca is pkgconfig
-
-`{
-#include <caca.h
-`}
-
-extern class CacaCanvas `{ caca_canvas_t* `}
-	fun put(text: String, x, y: Int) do native_put(text.to_cstring, x, y)
-	fun native_put(text: NativeString, x, y: Int) `{  caca_put_str(self, x, y, text); `}
-	fun draw_line(x1, y1, x2, y2: Int) `{ caca_draw_thin_line (self, x1, y1, x2, y2); `}
-	fun width: Int `{ return caca_get_canvas_width(self); `}
-	fun height: Int `{ return caca_get_canvas_height(self); `}
-end
-
-extern class CacaDisplay `{ caca_display_t* `}
-	new `{ return caca_create_display(NULL); `}
-
-	fun canvas: CacaCanvas `{ return caca_get_canvas(self); `}
-
-	fun refresh `{ caca_refresh_display(self); `}
-
-	fun quit `{
-		caca_event_t ev;
-		caca_get_event(self, CACA_EVENT_KEY_PRESS, &ev, -1);
-		caca_free_display(self);
-	`}
-end
-
- -Implement a program that takes a logolas file as an argument to draw things. - -Note that the atùin (the cursor) should start at the middle of the canvas. - -## Template To Use - - - -
module logolas_caca
-
-import logolas_parser 
-import logolas_lexer
-import caca
-
-# CODE HERE
-
- -## Expected Result - - $ ./logolas_caca maenas.logolas - # display an elegant and abstract L letter - $ ./logolas_caca elen.logolas - # show a glowing and inspiring star - $ ./logolas_caca bar.logolas - # renders a peaceful and warm house diff --git a/tracks-wip/nit/logolas_caca/result.txt b/tracks-wip/nit/logolas_caca/result.txt deleted file mode 100644 index 390e78c..0000000 --- a/tracks-wip/nit/logolas_caca/result.txt +++ /dev/null @@ -1,3 +0,0 @@ -^[]0;caca for ncurses^G |||--^[]0;^G^M -^[]0;caca for ncurses^G |,| '-. ||,'|`.,,'--`,-'.|----','' `. ,','`, |,`.'-----------| |'|,''`,|| ^[]0;^G^M -^[]0;caca for ncurses^G -.-'--`| || || ||----^[]0;^G^M diff --git a/tracks-wip/nit/logolas_caca/result_bis.txt b/tracks-wip/nit/logolas_caca/result_bis.txt deleted file mode 100644 index 7d3cd43..0000000 --- a/tracks-wip/nit/logolas_caca/result_bis.txt +++ /dev/null @@ -1 +0,0 @@ -^[]0;caca for ncurses^G |---|,' || |`, ||----^[]0;^G^M diff --git a/tracks-wip/nit/logolas_caca/template.nit b/tracks-wip/nit/logolas_caca/template.nit deleted file mode 100644 index be9f6b6..0000000 --- a/tracks-wip/nit/logolas_caca/template.nit +++ /dev/null @@ -1,7 +0,0 @@ -module logolas_caca - -import logolas_parser -import logolas_lexer -import caca - -# CODE HERE diff --git a/tracks-wip/nit/module/config.ini b/tracks-wip/nit/module/config.ini deleted file mode 100644 index 038f4a9..0000000 --- a/tracks-wip/nit/module/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Modules -req=class diff --git a/tracks-wip/nit/module/mission.md b/tracks-wip/nit/module/mission.md deleted file mode 100644 index 21f06e5..0000000 --- a/tracks-wip/nit/module/mission.md +++ /dev/null @@ -1,68 +0,0 @@ -# Modules - -Nit source files are called *modules*. -A module can define classes and methods, import classes and methods from other modules and refine them. - -The keyword `module` can be used to declare a module. It is optional but when given, the module name must match the filename. -The `module` declaration is also used to attach the documentation and to attach specific module annotations. - -The keyword `import` is used to import other modules. - -
# Simple program that says hello
-module hello
-print "Hello, World"
-
- -
# I don't know why you say hello, I say goodbye
-module goodbye
-import hello
-
-super # Call the previous `main`
-print "Goodbye, World"
-
- -Nit promotes *Concern-Oriented Development* where each module ideally operates on a single concern. -A Nit program is just a module that imports all the required concerns. - -Moreover, importation of modules can be done and configured at link-time (with `-m` and `-D`) to generate specific configurations of a product line. - -
module pire
-fun ctator: String do return "The Emperor says"
-redef fun print(value) do super "{ctator} ``{value}''"
-
- - $ nitc goodbye.nit - $ ./goodbye - Hello, World! - Goodbye, World! - - $ nitc goodbye.nit -m pire.nit # -m means mixin (or module; think what you want, I'm just a comment) - $ ./goodbye - The Emperor says ``Hello, World!'' - The Emperor says ``Goodbye, World!'' - - $ nitc goodbye.nit -m pire.nit -D ctator="The Rebels say" # -D means define - $ ./goodbye - The Rebels say ``Hello, World!'' - The Rebels say ``Goodbye, World!'' - -## Mission - -* Difficulty: easy - -Here a program that prints the command line arguments separated by a comma. - -
print args.join(", ")
-
- -Your mission is to write a mixin module that will change the behavior of this program so it prints "`Y0u, 4r3, H4cK3d`" instead. - -### Template to Use - -
module hacker
-# CODE HERE
-
- -### Expected Output - - Y0u, 4r3, H4cK3d diff --git a/tracks-wip/nit/module/result.txt b/tracks-wip/nit/module/result.txt deleted file mode 100644 index 7758e2e..0000000 --- a/tracks-wip/nit/module/result.txt +++ /dev/null @@ -1 +0,0 @@ -Y0u, 4r3, H4cK3d diff --git a/tracks-wip/nit/module/template.nit b/tracks-wip/nit/module/template.nit deleted file mode 100644 index dbec112..0000000 --- a/tracks-wip/nit/module/template.nit +++ /dev/null @@ -1,2 +0,0 @@ -module hacker -# CODE HERE diff --git a/tracks-wip/nit/nitcc/config.ini b/tracks-wip/nit/nitcc/config.ini deleted file mode 100644 index c0a6170..0000000 --- a/tracks-wip/nit/nitcc/config.ini +++ /dev/null @@ -1,3 +0,0 @@ -title=Elvish Vectorial Images and nitcc -req=visitor -languages=plain diff --git a/tracks-wip/nit/nitcc/mission.md b/tracks-wip/nit/nitcc/mission.md deleted file mode 100644 index 72fa7db..0000000 --- a/tracks-wip/nit/nitcc/mission.md +++ /dev/null @@ -1,23 +0,0 @@ -# Elvish Vectorial Images and nitcc - -Now that you are an expert with class refinement and heterogeneous data structures, let's try something fancier. - -[nitcc](http://info.uqam.ca/~privat/catalog/p/nitcc.html) is an ad-hoc, experimental and work-in-progress compiler generator greatly inspired by [SableCC](http://www.sablecc.org/). -We will use it to transform a formal language description (tokens and grammar) into classes to represent, parse and manipulate abstract syntax trees. - -Here the language specification for a vectorial, elvish drawing system. - -* [logolas grammar](logolas.sablecc) - -## Mission - -* Difficulty: medium - -Your first step is to compile it. - -* compile a recent version of nitcc. -* execute it on the provided grammar of `logolas`. -* compile the generated `logo_test_parser.nit` program -* execute the program on the following example: [elen](elen.logolas) -* compute the MD5 message digest of the generated `logolas.ast.out` -* send the flag `UQAM{md5}` diff --git a/tracks-wip/nit/nitcc_2/config.ini b/tracks-wip/nit/nitcc_2/config.ini deleted file mode 100644 index bb711e4..0000000 --- a/tracks-wip/nit/nitcc_2/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Visit of the Fangorn Forest -req=nitcc diff --git a/tracks-wip/nit/nitcc_2/mission.md b/tracks-wip/nit/nitcc_2/mission.md deleted file mode 100644 index 3e8e8c1..0000000 --- a/tracks-wip/nit/nitcc_2/mission.md +++ /dev/null @@ -1,56 +0,0 @@ -# Visit of the Fangorn Forest - -The main use of `nitcc` is the generation of the classes, AST and visit methods. -Take a look around the generated files for more insight on how it works. - -Let's focus on the Logolas format. - -There is an abstract cursor (atùin in Elvish) that starts at (0,0) and is oriented to the right (because elves like to be right). -The x axis is oriented left and the y axis is oriented towards the bottom. - -There are 3 basic command types: - -* forward (`⭡`) is used to advance in the current direction, the distance is given by the following number (from 1 to 12). - Because elves like purity, the final position must be rounded to the nearest integer for x and y. It means that between commands, the atùin is always at an integer position. -* turn left (`⮢`) and right (`⮣`) change the current direction. - The angle is given from 1 to 12, much like a clock (3 means a 90° angle). -* sequences enclosed between `𝄆` and `𝄇` are repeated a given number of times indicated after the closing `𝄇`. - Note that `Ⅴ` repetitions means that the sequence must be executed 6 times. - -## Mission - -* Difficulty: advanced - -Using the classes generated by nitcc, implement a program that computes the final position of the atùin. The logolas file is given as the first argument of the program. - -To help you, three logolas files are proposed: - -* an elegant and abstract L letter [maenas](maenas.logolas). -* a glowing and inspiring star [elen](elen.logolas). -* a peaceful and warm house [bar](bar.logolas). - -### Template to Use - - - -
module logolas
-
-import logolas_parser
-import logolas_lexer
-
-# CODE HERE
-
- -### Expected Result - -* for maenas: (1,3) -* for elen: (10,-3) -* for bar: (4,0) diff --git a/tracks-wip/nit/nitcc_2/result.txt b/tracks-wip/nit/nitcc_2/result.txt deleted file mode 100644 index b67e035..0000000 --- a/tracks-wip/nit/nitcc_2/result.txt +++ /dev/null @@ -1,3 +0,0 @@ -(1,3) -(10,-3) -(4,0) diff --git a/tracks-wip/nit/nitcc_2/result_bis.txt b/tracks-wip/nit/nitcc_2/result_bis.txt deleted file mode 100644 index 3303228..0000000 --- a/tracks-wip/nit/nitcc_2/result_bis.txt +++ /dev/null @@ -1 +0,0 @@ -(0,0) diff --git a/tracks-wip/nit/nitcc_2/template.nit b/tracks-wip/nit/nitcc_2/template.nit deleted file mode 100644 index 78d2643..0000000 --- a/tracks-wip/nit/nitcc_2/template.nit +++ /dev/null @@ -1,6 +0,0 @@ -module logolas - -import logolas_parser -import logolas_lexer - -# CODE HERE diff --git a/tracks-wip/nit/refinement/config.ini b/tracks-wip/nit/refinement/config.ini deleted file mode 100644 index 5c71ca9..0000000 --- a/tracks-wip/nit/refinement/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Class Refinement -req=module diff --git a/tracks-wip/nit/refinement/mission.md b/tracks-wip/nit/refinement/mission.md deleted file mode 100644 index a5f32e8..0000000 --- a/tracks-wip/nit/refinement/mission.md +++ /dev/null @@ -1,101 +0,0 @@ -# Class Refinement - -One of the best features of Nit is refinement. - -Refinement is modifying existing methods and classes in a statically controlled way: - -* New methods -* New attributes -* Override methods -* New super-classes - -The keyword `redef` is used to declare that a class definition is a refinement. - -
# Improve the class Int with a recursive Fibonacci function.
-redef class Int
-   fun fib: Int do
-      if self < 2 then return self
-      return (self - 1).fib + (self - 2).fib
-   end
-end
-
-print 6.fib # 8
-
- -Refinement is akin to - -* Aspect-Oriented Programming, - - but without weaving issues. - -* Monkey-patching, - - but statically checked. - - -In a refinement of a method, the previous definition is accessible with the `super` keyword. -This allows refiners to add additional behavior before and/or after the original behavior, or change it completely. - -For instance, the core method `run` controls the main execution of a program. -It is often refined to add additional behavior before or after the main program. - -As with classes, the keyword `redef` - -
redef fun run
-do
-	print "Start program"
-	super
-	print "End program"
-end
-
-print "Hello, World"
-
- -Will output - - Start program - Hello, World! - End program - - -By default `super` will reuse all the original parameters, you can provide new ones anyway. -The types of the parameters and the return type are - -
redef fun print(value)
-do
-	super "The Emperor says ``{value}''."
-end
-
-print "Hello, World"
-
- -## Mission - -* Difficulty: easy - -In order to encrypt future communication, refine the `print` method to print anything in ROT13. - -Hint1: do not infinitely recurse - -Hint2: the module `crypto` provides a `rot` method that can be applied on strings. - -### Template to Use - -
module crypto13
-
-import crypto
-
-redef fun print(value)
-do
-	var text = value.to_s
-	# CODE HERE
-end
-
-print "Hello, World!"
-print "Goodbye, World!"
-
- -### Expected Output - - Uryyb, Jbeyq! - Tbbqolr, Jbeyq! diff --git a/tracks-wip/nit/refinement/result.txt b/tracks-wip/nit/refinement/result.txt deleted file mode 100644 index 47ffd34..0000000 --- a/tracks-wip/nit/refinement/result.txt +++ /dev/null @@ -1,2 +0,0 @@ -Uryyb, Jbeyq! -Tbbqolr, Jbeyq! diff --git a/tracks-wip/nit/refinement/result_bis.txt b/tracks-wip/nit/refinement/result_bis.txt deleted file mode 100644 index 4bc908a..0000000 --- a/tracks-wip/nit/refinement/result_bis.txt +++ /dev/null @@ -1,2 +0,0 @@ -QbzrVfYvsr -Tbbqolr, Jbeyq! diff --git a/tracks-wip/nit/refinement/template.nit b/tracks-wip/nit/refinement/template.nit deleted file mode 100644 index 55930d7..0000000 --- a/tracks-wip/nit/refinement/template.nit +++ /dev/null @@ -1,12 +0,0 @@ -module crypto13 - -import crypto - -redef fun print(value) -do - var text = value.to_s - # CODE HERE -end - -print "Hello, World!" -print "Goodbye, World!" diff --git a/tracks-wip/nit/ressource.txt b/tracks-wip/nit/ressource.txt deleted file mode 100644 index bc93b5b..0000000 --- a/tracks-wip/nit/ressource.txt +++ /dev/null @@ -1 +0,0 @@ -( ͡° ͜ʖ ͡°) diff --git a/tracks-wip/nit/track.ini b/tracks-wip/nit/track.ini deleted file mode 100644 index 39c30b4..0000000 --- a/tracks-wip/nit/track.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Nit -languages=Nit diff --git a/tracks-wip/nit/track.md b/tracks-wip/nit/track.md deleted file mode 100644 index 98562d7..0000000 --- a/tracks-wip/nit/track.md +++ /dev/null @@ -1,7 +0,0 @@ -Nit tutorial - -bla bla - -![alt](image.png) - -[ressource](ressource.txt) diff --git a/tracks-wip/nit/visitor/config.ini b/tracks-wip/nit/visitor/config.ini deleted file mode 100644 index 66fca5b..0000000 --- a/tracks-wip/nit/visitor/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Visitor Design Pattern -req=refinement diff --git a/tracks-wip/nit/visitor/mission.md b/tracks-wip/nit/visitor/mission.md deleted file mode 100644 index 3896599..0000000 --- a/tracks-wip/nit/visitor/mission.md +++ /dev/null @@ -1,312 +0,0 @@ -# Visitor Design Pattern - -The well-known Visitor Design Pattern allows for dissociation between the traversal of an heterogeneous data structure and the various computations done on this data structure. - -The standard way is to engineer the visited classes with a special `accept` callback that will invoke a specific `visit_*` method of an abstract Visitor. -Adding new behaviours and computations is done in specific subclasses of the abstract visitor. - -This standard way has some issues: - -* the visitor has to be developed with the data-classes -* the visitor is complex with a lot of methods -* the signature of the `visit_*` methods has to be decided once for all (there is various ways to mitigate the issue dependently on the language) -* there is a specific and independent method `visit_*` method for each concrete data-class, without a nice OO way to factorize them -* most of the implemented behavior is the sole responsibility of the data-class and implementing them in a concrete visitor is not optimal (bad responsibility assignment, bad coupling) - -Concern-oriented programming and class refinement in Nit help solve most of these issues. - -So, let us consider the following classes used to represent a boolean expression. - - - -
# Simple Boolean expressions
-module bool_expr
-
-# A boolean expression
-abstract class BoolExpr
-end
-
-# A boolean binary operation
-abstract class BoolBinOp
-	super BoolExpr
-	# The left operand
-	var left: BoolExpr
-	# The right operand
-	var right: BoolExpr
-end
-
-# A boolean conjunction
-class BoolAnd
-	super BoolBinOp
-end
-
-# A boolean disjunction
-class BoolOr
-	super BoolBinOp
-end
-
-# A boolean negation
-class BoolNot
-	super BoolExpr
-	# the negated boolean
-	var expr: BoolExpr
-end
-
-# A true boolean value
-class BoolTrue
-	super BoolExpr
-end
-
-# A false boolean value
-class BoolFalse
-	super BoolExpr
-end
-
- -Let's add a visitor, by refinement of the existing classes in a new and independent module. - - - -
# Visit the simple Boolean expressions
-module bool_visitor
-
-import bool_expr
-
-# An abstract visitor.
-#
-# Please implement `visit` for specific behavior and computation.
-abstract class BoolVisitor
-	# Visit an
-	fun visit(expr: BoolExpr) is abstract
-end
-
-redef class BoolExpr
-	# Call `visit` in order on each sub-expressions (if any)
-	fun visit_children(v: BoolVisitor) do end
-end
-
-redef class BoolBinOp
-	redef fun visit_children(v)
-	do
-		v.visit(left)
-		v.visit(right)
-	end
-end
-
-redef class BoolNot
-	redef fun visit_children(v)
-	do
-		v.visit(expr)
-	end
-end
-
- -You can see that the visitor can be created after the data-classes without altering the original module. - -Let's now implement some visitor that counts the number of binary operations in an expression. - - - -
module bool_counter
-
-import bool_visitor
-
-class BoolCounter
-	super BoolVisitor
-
-	fun count(expr: BoolExpr): Int
-	do
-		cpt = 0
-		visit(expr)
-		return cpt
-	end
-
-	redef fun visit(expr) do
-		# Call the specific count code
-		expr.accept_count(self)
-		# Recursively process the sub-expressions if any
-		expr.visit_children(self)
-	end
-
-	# Counter of binary operations
-	var cpt = 0
-end
-
-redef class BoolExpr
-	# The specific `counting` behavior.
-	private fun accept_count(v: BoolCounter) do end
-end
-
-redef class BoolBinOp
-	redef fun accept_count(v) do v.cpt += 1
-end
-
-var e1 = new BoolOr(new BoolAnd(new BoolTrue, new BoolFalse), new BoolNot(new BoolTrue))
-var e2 = new BoolAnd(new BoolNot(e1), new BoolTrue)
-
-var v = new BoolCounter
-print v.count(e1) # 2
-print v.count(e2) # 3
-
- -## Mission - -* Difficulty: medium - -Implement an evaluator that can visit and transform one of our Boolean expressions to a standard Bool value `true` or `false`. - -### Template to Use - - - -
module bool_eval
-
-import bool_visitor
-
-# CODE HERE
-
-var e1 = new BoolOr(new BoolAnd(new BoolTrue, new BoolFalse), new BoolNot(new BoolTrue))
-var e2 = new BoolAnd(new BoolNot(e1), new BoolTrue)
-
-print e1.eval
-print e2.eval
-
- -### Expected Output - - false - true diff --git a/tracks-wip/nit/visitor/result.txt b/tracks-wip/nit/visitor/result.txt deleted file mode 100644 index 1d474d5..0000000 --- a/tracks-wip/nit/visitor/result.txt +++ /dev/null @@ -1,2 +0,0 @@ -false -true diff --git a/tracks-wip/nit/visitor/result_bis.txt b/tracks-wip/nit/visitor/result_bis.txt deleted file mode 100644 index 4b095fd..0000000 --- a/tracks-wip/nit/visitor/result_bis.txt +++ /dev/null @@ -1,2 +0,0 @@ -false -false diff --git a/tracks-wip/nit/visitor/template.nit b/tracks-wip/nit/visitor/template.nit deleted file mode 100644 index ee696f1..0000000 --- a/tracks-wip/nit/visitor/template.nit +++ /dev/null @@ -1,11 +0,0 @@ -module bool_eval - -import bool_visitor - -# CODE HERE - -var e1 = new BoolOr(new BoolAnd(new BoolTrue, new BoolFalse), new BoolNot(new BoolTrue)) -var e2 = new BoolAnd(new BoolNot(e1), new BoolTrue) - -print e1.eval -print e2.eval diff --git a/tracks-wip/pep8/lab1-1/config.ini b/tracks-wip/pep8/lab1-1/config.ini deleted file mode 100644 index bebd4ad..0000000 --- a/tracks-wip/pep8/lab1-1/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -title=Addition simple -reward=10 -star.time.goal=24 -star.size.goal=17 diff --git a/tracks-wip/pep8/lab1-1/mission.md b/tracks-wip/pep8/lab1-1/mission.md deleted file mode 100644 index f98da61..0000000 --- a/tracks-wip/pep8/lab1-1/mission.md +++ /dev/null @@ -1,5 +0,0 @@ -Le programme additionne 10 à un nombre saisi par l'utilisateur. - -* Lire un nombre -* Additionner 10 -* Afficher le résultat diff --git a/tracks-wip/pep8/lab1-1/template b/tracks-wip/pep8/lab1-1/template deleted file mode 100644 index 0a16b06..0000000 --- a/tracks-wip/pep8/lab1-1/template +++ /dev/null @@ -1,8 +0,0 @@ -DECI n,d -LDA n,d -ADDA ???,i ; FIXME combien? -STA n,d -DECO n,d -STOP -n: .BLOCK 2 -.END diff --git a/tracks-wip/pep8/lab1-1/tests.txt b/tracks-wip/pep8/lab1-1/tests.txt deleted file mode 100644 index d343869..0000000 --- a/tracks-wip/pep8/lab1-1/tests.txt +++ /dev/null @@ -1,16 +0,0 @@ -=== -5 ---- -15 -=== -0 ---- -10 -=== --5 ---- -5 -=== --50 ---- --40 diff --git a/tracks-wip/pep8/lab1-2/config.ini b/tracks-wip/pep8/lab1-2/config.ini deleted file mode 100644 index 2fb9a8f..0000000 --- a/tracks-wip/pep8/lab1-2/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -title=Addition vraie -req=lab1-1 -star.time.goal=28 -star.size.goal=20 diff --git a/tracks-wip/pep8/lab1-2/mission.md b/tracks-wip/pep8/lab1-2/mission.md deleted file mode 100644 index f4529c3..0000000 --- a/tracks-wip/pep8/lab1-2/mission.md +++ /dev/null @@ -1,6 +0,0 @@ -Le programme affiche la somme de deux nombres saisis par l'utilisateur. - -* Lire un nombre -* Lire un autre nombre -* Faire la somme -* Afficher le résultat diff --git a/tracks-wip/pep8/lab1-2/tests.txt b/tracks-wip/pep8/lab1-2/tests.txt deleted file mode 100644 index 49818be..0000000 --- a/tracks-wip/pep8/lab1-2/tests.txt +++ /dev/null @@ -1,20 +0,0 @@ -=== -10 -10 ---- -20 -=== --10 -10 ---- -0 -=== -30000 -2000 ---- -32000 -=== --30000 --2000 ---- --32000 diff --git a/tracks-wip/pep8/lab1-3/config.ini b/tracks-wip/pep8/lab1-3/config.ini deleted file mode 100644 index 31c2640..0000000 --- a/tracks-wip/pep8/lab1-3/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -title=Répète après moi -req=lab1-2 -star.time.goal=28 -star.size.goal=19 diff --git a/tracks-wip/pep8/lab1-3/mission.md b/tracks-wip/pep8/lab1-3/mission.md deleted file mode 100644 index ac09324..0000000 --- a/tracks-wip/pep8/lab1-3/mission.md +++ /dev/null @@ -1 +0,0 @@ -Le programme affich les trois premiers caractères saisis par l'utilisateur. diff --git a/tracks-wip/pep8/lab1-3/tests.txt b/tracks-wip/pep8/lab1-3/tests.txt deleted file mode 100644 index f51f4f5..0000000 --- a/tracks-wip/pep8/lab1-3/tests.txt +++ /dev/null @@ -1,20 +0,0 @@ -=== -abc ---- -abc -=== - -a - ---- - -a - -=== -hello! ---- -hel -=== - . ---- - . diff --git a/tracks-wip/pep8/lab2-1/config.ini b/tracks-wip/pep8/lab2-1/config.ini deleted file mode 100644 index 46fd7ed..0000000 --- a/tracks-wip/pep8/lab2-1/config.ini +++ /dev/null @@ -1,3 +0,0 @@ -title=Au moins 10 -star.time.goal=30 -star.size.goal=31 diff --git a/tracks-wip/pep8/lab2-1/mission.md b/tracks-wip/pep8/lab2-1/mission.md deleted file mode 100644 index 8b82fe4..0000000 --- a/tracks-wip/pep8/lab2-1/mission.md +++ /dev/null @@ -1,5 +0,0 @@ -Le programme compare un nombre saisi par l'utilisateur à 10. - -* Lire un nombre -* S'il est strictement plus grand que 10, afficher "`> 10`" -* Sinon, afficher "`<= 10`" diff --git a/tracks-wip/pep8/lab2-1/tests.txt b/tracks-wip/pep8/lab2-1/tests.txt deleted file mode 100644 index f3d981d..0000000 --- a/tracks-wip/pep8/lab2-1/tests.txt +++ /dev/null @@ -1,20 +0,0 @@ -=== -100 ---- -> 10 -=== -5 ---- -<= 10 -=== --10 ---- -<= 10 -=== -10 ---- -<= 10 -=== -32000 ---- -> 10 diff --git a/tracks-wip/pep8/lab2-2/config.ini b/tracks-wip/pep8/lab2-2/config.ini deleted file mode 100644 index 842a648..0000000 --- a/tracks-wip/pep8/lab2-2/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -star.size.goal=65 -star.time.goal=48 -title=Sinon si -req=lab2-1 diff --git a/tracks-wip/pep8/lab2-2/mission.md b/tracks-wip/pep8/lab2-2/mission.md deleted file mode 100644 index 2c0b45a..0000000 --- a/tracks-wip/pep8/lab2-2/mission.md +++ /dev/null @@ -1,15 +0,0 @@ -Traduisez ce pseudo-code en assembleur - -~~~nit -var min = deci -var max = deci -var nb = deci - -if nb >= min and nb <= max then - print "In bounds" -else if nb < min then - print "Too low" -else - print "Too high" -end -~~~ diff --git a/tracks-wip/pep8/lab2-2/tests.txt b/tracks-wip/pep8/lab2-2/tests.txt deleted file mode 100644 index 9181d1c..0000000 --- a/tracks-wip/pep8/lab2-2/tests.txt +++ /dev/null @@ -1,30 +0,0 @@ -=== -10 -20 -5 ---- -Too low -=== -100 -200 -300 ---- -Too high -=== -1000 -2000 -1001 ---- -In bounds -=== --200 --100 --100 ---- -In bounds -=== --10 -10 --10 ---- -In bounds diff --git a/tracks-wip/pep8/lab2-3/config.ini b/tracks-wip/pep8/lab2-3/config.ini deleted file mode 100644 index b30b6d1..0000000 --- a/tracks-wip/pep8/lab2-3/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -req=lab2-2 -title=Lettre ou ne pas lettre -star.time.goal=139 -star.size.goal=66 diff --git a/tracks-wip/pep8/lab2-3/mission.md b/tracks-wip/pep8/lab2-3/mission.md deleted file mode 100644 index 291c3ad..0000000 --- a/tracks-wip/pep8/lab2-3/mission.md +++ /dev/null @@ -1,11 +0,0 @@ -Traduisez ce pseudo-code en assembleur - -~~~nit -var chr = chari - -if (chr >= 'a' and chr <= 'z') or (chr >= 'A' and chr <= 'Z') then - print "It is a letter" -else - print "Not a letter" -end -~~~ diff --git a/tracks-wip/pep8/lab2-3/tests.txt b/tracks-wip/pep8/lab2-3/tests.txt deleted file mode 100644 index 9182015..0000000 --- a/tracks-wip/pep8/lab2-3/tests.txt +++ /dev/null @@ -1,52 +0,0 @@ -=== -a ---- -It is a letter -=== -o ---- -It is a letter -=== -z ---- -It is a letter -=== -A ---- -It is a letter -=== -T ---- -It is a letter -=== -Z ---- -It is a letter -=== -@ ---- -Not a letter -=== -1 ---- -Not a letter -=== -[ ---- -Not a letter -=== -] ---- -Not a letter -=== -` ---- -Not a letter -=== -{ ---- -Not a letter -=== -} ---- -Not a letter diff --git a/tracks-wip/pep8/lab2-4/config.ini b/tracks-wip/pep8/lab2-4/config.ini deleted file mode 100644 index 29ca408..0000000 --- a/tracks-wip/pep8/lab2-4/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -star.size.goal=40 -star.time.goal=55 -title=La bonne case -req=lab2-3 diff --git a/tracks-wip/pep8/lab2-4/mission.md b/tracks-wip/pep8/lab2-4/mission.md deleted file mode 100644 index 866663d..0000000 --- a/tracks-wip/pep8/lab2-4/mission.md +++ /dev/null @@ -1 +0,0 @@ -Lisez deux caractères, puis affichez-les dans l'ordre alphanumérique croissant. diff --git a/tracks-wip/pep8/lab2-4/tests.txt b/tracks-wip/pep8/lab2-4/tests.txt deleted file mode 100644 index 0e47972..0000000 --- a/tracks-wip/pep8/lab2-4/tests.txt +++ /dev/null @@ -1,20 +0,0 @@ -=== -ab ---- -ab -=== -ZA ---- -AZ -=== -[] ---- -[] -=== -}{ ---- -{} -=== -88 ---- -88 diff --git a/tracks-wip/pep8/lab2-4b/config.ini b/tracks-wip/pep8/lab2-4b/config.ini deleted file mode 100644 index 44ed3a5..0000000 --- a/tracks-wip/pep8/lab2-4b/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -star.size.goal=135 -star.time.goal=164 -title=La guerre de trois -req=lab2-4 diff --git a/tracks-wip/pep8/lab2-4b/mission.md b/tracks-wip/pep8/lab2-4b/mission.md deleted file mode 100644 index efdedcb..0000000 --- a/tracks-wip/pep8/lab2-4b/mission.md +++ /dev/null @@ -1,2 +0,0 @@ -Lisez trois nombres. -Affichez-les dans l'ordre croissant. diff --git a/tracks-wip/pep8/lab2-4b/tests.txt b/tracks-wip/pep8/lab2-4b/tests.txt deleted file mode 100644 index 88041ae..0000000 --- a/tracks-wip/pep8/lab2-4b/tests.txt +++ /dev/null @@ -1,40 +0,0 @@ -=== -1 2 3 ---- -1 2 3 -=== -10 30 20 ---- -10 20 30 -=== -200 100 300 ---- -100 200 300 -=== -2000 3000 1000 ---- -1000 2000 3000 -=== -30000 10000 20000 ---- -10000 20000 30000 -=== -33 22 11 ---- -11 22 33 -=== -1 -1 -1 ---- --1 -1 1 -=== --2 2 -2 ---- --2 -2 2 -=== --3 -3 3 ---- --3 -3 3 -=== --4 -4 -4 ---- --4 -4 -4 diff --git a/tracks-wip/pep8/lab2-5/config.ini b/tracks-wip/pep8/lab2-5/config.ini deleted file mode 100644 index 11c8e85..0000000 --- a/tracks-wip/pep8/lab2-5/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -req=lab2-4 -title=Pair -star.time.goal=487 -star.size.goal=30 diff --git a/tracks-wip/pep8/lab2-5/mission.md b/tracks-wip/pep8/lab2-5/mission.md deleted file mode 100644 index f93bb15..0000000 --- a/tracks-wip/pep8/lab2-5/mission.md +++ /dev/null @@ -1,3 +0,0 @@ -Lisez un nombre. -Affichez tous les nombres pairs entre 0 et ce nombre. -L'ordre est croissant, un nombre par ligne. diff --git a/tracks-wip/pep8/lab2-5/tests.txt b/tracks-wip/pep8/lab2-5/tests.txt deleted file mode 100644 index 2e7b912..0000000 --- a/tracks-wip/pep8/lab2-5/tests.txt +++ /dev/null @@ -1,86 +0,0 @@ -=== -10 ---- -0 -2 -4 -6 -8 -10 - -=== -100 ---- -0 -2 -4 -6 -8 -10 -12 -14 -16 -18 -20 -22 -24 -26 -28 -30 -32 -34 -36 -38 -40 -42 -44 -46 -48 -50 -52 -54 -56 -58 -60 -62 -64 -66 -68 -70 -72 -74 -76 -78 -80 -82 -84 -86 -88 -90 -92 -94 -96 -98 -100 - -=== -15 ---- -0 -2 -4 -6 -8 -10 -12 -14 - -=== -0 ---- -0 - -=== --10 ---- - diff --git a/tracks-wip/pep8/lab2-5b/config.ini b/tracks-wip/pep8/lab2-5b/config.ini deleted file mode 100644 index fe5dc33..0000000 --- a/tracks-wip/pep8/lab2-5b/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -star.size.goal=89 -star.time.goal=540 -title=Carré -req=lab2-5 diff --git a/tracks-wip/pep8/lab2-5b/mission.md b/tracks-wip/pep8/lab2-5b/mission.md deleted file mode 100644 index 746e24d..0000000 --- a/tracks-wip/pep8/lab2-5b/mission.md +++ /dev/null @@ -1,10 +0,0 @@ -Lisez un nombre *n* et dessinez un carré de *n* étoiles de coté. - -Exemple pour 4: - -~~~ -**** -* * -* * -**** -~~~ diff --git a/tracks-wip/pep8/lab2-5b/tests.txt b/tracks-wip/pep8/lab2-5b/tests.txt deleted file mode 100644 index b343db8..0000000 --- a/tracks-wip/pep8/lab2-5b/tests.txt +++ /dev/null @@ -1,33 +0,0 @@ -=== -4 ---- -**** -* * -* * -**** -=== -10 ---- -********** -* * -* * -* * -* * -* * -* * -* * -* * -********** -=== -2 ---- -** -** -=== -1 ---- -* -=== -0 ---- - diff --git a/tracks-wip/pep8/lab2-6/config.ini b/tracks-wip/pep8/lab2-6/config.ini deleted file mode 100644 index 9743594..0000000 --- a/tracks-wip/pep8/lab2-6/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -star.size.goal=83 -star.time.goal=10041 -title=des mots -req=lab2-5 diff --git a/tracks-wip/pep8/lab2-6/mission.md b/tracks-wip/pep8/lab2-6/mission.md deleted file mode 100644 index a0c9f98..0000000 --- a/tracks-wip/pep8/lab2-6/mission.md +++ /dev/null @@ -1,9 +0,0 @@ -Compter le nombre de mots d'une ligne saisie par l'utilisateur. - -* la ligne est terminée par un caractère saut de ligne (`\n`) -* un mot est une suite de lettre ascii ou de chiffres. - -Exemple: - -* `J'aime Pep/8!` -* 4 mots: `J`, `aime`, `Pep` et `8` diff --git a/tracks-wip/pep8/lab2-6/tests.txt b/tracks-wip/pep8/lab2-6/tests.txt deleted file mode 100644 index 4dd8adf..0000000 --- a/tracks-wip/pep8/lab2-6/tests.txt +++ /dev/null @@ -1,20 +0,0 @@ -=== -J'aime Pep/8! ---- -4 -=== -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. ---- -69 -=== -0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ---- -1 -=== -~`!@#$%^&* ()_-+={[}]| \:;"'<,>.?/ ---- -0 -=== -.a..bb...ccc....dddd..... ---- -4 diff --git a/tracks-wip/pep8/template b/tracks-wip/pep8/template deleted file mode 100644 index 1f5e18e..0000000 --- a/tracks-wip/pep8/template +++ /dev/null @@ -1,3 +0,0 @@ -; Entrez votre code pep8 ici - -.END diff --git a/tracks-wip/pep8/track.ini b/tracks-wip/pep8/track.ini deleted file mode 100644 index dacf5dd..0000000 --- a/tracks-wip/pep8/track.ini +++ /dev/null @@ -1,2 +0,0 @@ -title=Pep8 -languages=Pep/8 diff --git a/tracks-wip/pep8/track.md b/tracks-wip/pep8/track.md deleted file mode 100644 index 1222b79..0000000 --- a/tracks-wip/pep8/track.md +++ /dev/null @@ -1,5 +0,0 @@ -Exercices INF2170 - -Cette série de missions contient des exercices tirés des laboratoires du cours INF2170 - Organisation des ordinateurs et assembleur. - -Les ressources du cours sont sur , le simulateur pep/8 est installable de façon autonome via . diff --git a/tracks/nit/track.ini b/tracks/nit/track.ini index 39c30b4..501f501 100644 --- a/tracks/nit/track.ini +++ b/tracks/nit/track.ini @@ -1,2 +1,3 @@ title=Nit -languages=Nit +language=nit +engine=nitc diff --git a/tracks/pep8/track.ini b/tracks/pep8/track.ini index dacf5dd..3a0c5ff 100644 --- a/tracks/pep8/track.ini +++ b/tracks/pep8/track.ini @@ -1,2 +1,3 @@ title=Pep8 -languages=Pep/8 +language=pep8 +engine=pep8term diff --git a/tracks/use-ocl/01_classes/config.ini b/tracks/use-ocl/01_classes/config.ini new file mode 100644 index 0000000..09d0d16 --- /dev/null +++ b/tracks/use-ocl/01_classes/config.ini @@ -0,0 +1 @@ +title=Classes diff --git a/tracks/use-ocl/01_classes/mission.md b/tracks/use-ocl/01_classes/mission.md new file mode 100644 index 0000000..10cdfe0 --- /dev/null +++ b/tracks/use-ocl/01_classes/mission.md @@ -0,0 +1,38 @@ +## Modéliser des classes avec USE-OCL + +USE-OCL utilise une syntaxe particulière pour définir le modèle à vérifier. + +Chaque fichier de modèle doit commencer par la définition `model `: + + model Animaux + +Pour définir une classe on utilise la directive `class ` et on termine par `end`. + + class Animal + end + +Une classe possède un nom et eventuellement des attributs et des opérations. + +Les attributs sont déclarés grâce à la directive `attributes` suivie des attributs typés: + + class Canard + attributes + nom: String + end + +Les méthodes sont déclarées grâce à la directive `operations` suivie des signatures des méthodes: + + class Canard + attributes + nom: String + operations + cancaner(i: Integer): String + end + +### Exercice + +Dans cet exercice et les suivants, nous allons modéliser un jeu de vaisseaux spaciaux appelé `SpaceZ`. + +Reproduisez le modèle représenté ci-dessous en respectant la syntaxe de USE-OCL. + +![Diagramme de classes](uml.svg) diff --git a/tracks/use-ocl/01_classes/template b/tracks/use-ocl/01_classes/template new file mode 100644 index 0000000..61aac2e --- /dev/null +++ b/tracks/use-ocl/01_classes/template @@ -0,0 +1,3 @@ +model SpaceZ + +-- Entrez votre code ici diff --git a/tracks/use-ocl/01_classes/tests.txt b/tracks/use-ocl/01_classes/tests.txt new file mode 100644 index 0000000..0b128df --- /dev/null +++ b/tracks/use-ocl/01_classes/tests.txt @@ -0,0 +1,17 @@ +=== +!create v: VaisseauCargo +!set v.poids := 10000 +!set v.capacite := 5000 +!openter v charger(10) +--- +checking structure... +checking invariants... +checked 0 invariants, 0 failures. +=== +!create v: VaisseauCombat +!set v.poids := 10000 +!openter v attaquer(v) +--- +checking structure... +checking invariants... +checked 0 invariants, 0 failures. diff --git a/tracks/use-ocl/01_classes/uml.svg b/tracks/use-ocl/01_classes/uml.svg new file mode 100644 index 0000000..89874ec --- /dev/null +++ b/tracks/use-ocl/01_classes/uml.svg @@ -0,0 +1,40 @@ + + + + + + +Vaisseau + +<<abstract>> + + +poids : Integer + + +decoller() + + + +VaisseauCargo + + +capacite : Integer + + +charger(poids : Integer) + + + +VaisseauCombat + + + +attaquer(vaiseau : Vaisseau) + + + + + + + diff --git a/tracks/use-ocl/01_classes/uml.zargo b/tracks/use-ocl/01_classes/uml.zargo new file mode 100644 index 0000000..21f124a Binary files /dev/null and b/tracks/use-ocl/01_classes/uml.zargo differ diff --git a/tracks/use-ocl/02_associations/config.ini b/tracks/use-ocl/02_associations/config.ini new file mode 100644 index 0000000..ab90667 --- /dev/null +++ b/tracks/use-ocl/02_associations/config.ini @@ -0,0 +1,2 @@ +title=Associations +req=01_classes diff --git a/tracks/use-ocl/02_associations/mission.md b/tracks/use-ocl/02_associations/mission.md new file mode 100644 index 0000000..2a1dc90 --- /dev/null +++ b/tracks/use-ocl/02_associations/mission.md @@ -0,0 +1,18 @@ +## Modéliser des associations + +Les associations permettent de définir des relations sémantiques entre des classes. + +![Diagramme de classes](uml_example.svg) + +Pour définir des associations dans USE, on utilise la construction `association`: + + association contient between + Zoo [0..1] role zoo + Car [*] role animaux + end + +### Exercice + +Reproduisez le modèle représenté ci-dessous en respectant la syntaxe de USE-OCL. + +![Diagramme de classes](uml_exercice.svg) diff --git a/tracks/use-ocl/02_associations/template b/tracks/use-ocl/02_associations/template new file mode 100644 index 0000000..d82c653 --- /dev/null +++ b/tracks/use-ocl/02_associations/template @@ -0,0 +1,21 @@ +model SpaceZ + +class Objet + attributes + poids: Integer +end + +class Vaisseau < Objet + attributes + capacite: Integer + operations + charger(objet: Objet) + equiper(arme: Arme) +end + +class Arme < Objet + attributes + puissance: Integer +end + +-- Entrez votre code ici diff --git a/tracks/use-ocl/02_associations/tests.txt b/tracks/use-ocl/02_associations/tests.txt new file mode 100644 index 0000000..a1655f0 --- /dev/null +++ b/tracks/use-ocl/02_associations/tests.txt @@ -0,0 +1,24 @@ +=== +!create o: Objet +!set o.poids := 10 + +!create v: Vaisseau +!set v.poids := 10000 +!set v.capacite := 5000 +!insert(v, o) into contient +--- +checking structure... +checking invariants... +checked 0 invariants, 0 failures. +=== +!create a: Arme +!set a.poids := 100 + +!create v: Vaisseau +!set v.poids := 10000 +!set v.capacite := 5000 +!insert(v, a) into equipe +--- +checking structure... +checking invariants... +checked 0 invariants, 0 failures. diff --git a/tracks/use-ocl/02_associations/uml_example.svg b/tracks/use-ocl/02_associations/uml_example.svg new file mode 100644 index 0000000..b5a0dc7 --- /dev/null +++ b/tracks/use-ocl/02_associations/uml_example.svg @@ -0,0 +1,23 @@ + + + + + + +Zoo + + + +Animal + + +contient + +0..1 + +zoo + +1 + +animaux + diff --git a/tracks/use-ocl/02_associations/uml_example.zargo b/tracks/use-ocl/02_associations/uml_example.zargo new file mode 100644 index 0000000..3479b48 Binary files /dev/null and b/tracks/use-ocl/02_associations/uml_example.zargo differ diff --git a/tracks/use-ocl/02_associations/uml_exercice.svg b/tracks/use-ocl/02_associations/uml_exercice.svg new file mode 100644 index 0000000..f299f53 --- /dev/null +++ b/tracks/use-ocl/02_associations/uml_exercice.svg @@ -0,0 +1,60 @@ + + + + + + +Objet + + +poids : Integer + + + + +Vaisseau + + +capacite : Integer + + +charger(objet : Objet) + +equiper(arme : Arme) + + + +Arme + + +puissance : Integer + + + + + + +equipe + +0..* + +armes + +0..1 + +vaisseau + + +contient + +0..* + +objets + +0..1 + +cargo + + + + diff --git a/tracks/use-ocl/02_associations/uml_exercice.zargo b/tracks/use-ocl/02_associations/uml_exercice.zargo new file mode 100644 index 0000000..66eb8c9 Binary files /dev/null and b/tracks/use-ocl/02_associations/uml_exercice.zargo differ diff --git a/tracks/use-ocl/03_contraintes/config.ini b/tracks/use-ocl/03_contraintes/config.ini new file mode 100644 index 0000000..5ca15d8 --- /dev/null +++ b/tracks/use-ocl/03_contraintes/config.ini @@ -0,0 +1,2 @@ +title=Contraintes +req=02_associations diff --git a/tracks/use-ocl/03_contraintes/mission.md b/tracks/use-ocl/03_contraintes/mission.md new file mode 100644 index 0000000..efe39c3 --- /dev/null +++ b/tracks/use-ocl/03_contraintes/mission.md @@ -0,0 +1,37 @@ +## Saisir les contraintes OCL + +Pour définir les contraintes OCL, on commence par déclarer la section `constraints` dans le fichier de modèle: + + model Animaux + + -- modèle USE + + constraints + + -- contraintes OCL + +Chaque contrainte OCL doit être définie dans un contexte: + + context Animal + -- contraintes sur la classe Animal + +Pour définir des invariants, on utilise le mot clé `inv`: + + context Animal + inv: nom <> null + +Afin de simplifier la lecture des rapports d'erreurs, il est préférable de nommer ses contraintes: + + context Animal + inv NomNotNul: nom <> null + +### Exercice + +Ajoutez les invariants ci-dessous au modèle présenté: + +![Diagramme de classes](uml_exercice.svg) + +Nommez vos contraintes avec les identifiants notés `cX`. + +* `c1`: le poids d'un objet est toujours strictement suppérieur à 0 +* `c2`: si une arme se trouve dans la liste des `armes` d'un vaisseau, elle doit aussi se trouver dans la liste de ses `objets`. diff --git a/tracks/use-ocl/03_contraintes/template b/tracks/use-ocl/03_contraintes/template new file mode 100644 index 0000000..6147b05 --- /dev/null +++ b/tracks/use-ocl/03_contraintes/template @@ -0,0 +1,33 @@ +model SpaceZ + +class Objet + attributes + poids: Integer +end + +class Vaisseau < Objet + attributes + capacite: Integer + operations + charger(objet: Objet) + equiper(arme: Arme) +end + +class Arme < Objet + attributes + puissance: Integer +end + +association contient between + Vaisseau [0..1] role cargo + Objet [*] role objets +end + +association equipe between + Vaisseau [0..1] role vaisseau + Arme [*] role armes +end + +constraints + +-- Entrez vos contraintes ici diff --git a/tracks/use-ocl/03_contraintes/tests.txt b/tracks/use-ocl/03_contraintes/tests.txt new file mode 100644 index 0000000..69c7bf1 --- /dev/null +++ b/tracks/use-ocl/03_contraintes/tests.txt @@ -0,0 +1,40 @@ +=== +!create o: Arme +!set o.poids := 10 + +!create v: Vaisseau +!set v.poids := 1000 + +!insert(v, o) into contient +!insert(v, o) into equipe +--- +checking structure... +checking invariants... +checking invariant (1) `Objet::c1': OK. +checking invariant (2) `Vaisseau::c2': OK. +checked 2 invariants, 0 failures. +=== +!create o: Objet +!set o.poids := -10 +--- +checking structure... +checking invariants... +checking invariant (1) `Objet::c1': FAILED. + -> false : Boolean +checking invariant (2) `Vaisseau::c2': OK. +checked 2 invariants, 1 failure. +=== +!create o: Arme +!set o.poids := 10 + +!create v: Vaisseau +!set v.poids := 1000 + +!insert(v, o) into equipe +--- +checking structure... +checking invariants... +checking invariant (1) `Objet::c1': OK. +checking invariant (2) `Vaisseau::c2': FAILED. + -> false : Boolean +checked 2 invariants, 1 failure. diff --git a/tracks/use-ocl/03_contraintes/uml_exercice.svg b/tracks/use-ocl/03_contraintes/uml_exercice.svg new file mode 120000 index 0000000..df0f6d8 --- /dev/null +++ b/tracks/use-ocl/03_contraintes/uml_exercice.svg @@ -0,0 +1 @@ +/home/morriar/dev/moz/missions/tracks/use-ocl/02_associations/uml_exercice.svg \ No newline at end of file diff --git a/tracks/use-ocl/04_preconditions/config.ini b/tracks/use-ocl/04_preconditions/config.ini new file mode 100644 index 0000000..c95390f --- /dev/null +++ b/tracks/use-ocl/04_preconditions/config.ini @@ -0,0 +1,2 @@ +title=Préconditions +req=03_contraintes diff --git a/tracks/use-ocl/04_preconditions/mission.md b/tracks/use-ocl/04_preconditions/mission.md new file mode 100644 index 0000000..cf92ad8 --- /dev/null +++ b/tracks/use-ocl/04_preconditions/mission.md @@ -0,0 +1,23 @@ +## Préconditions + +Pour définir les préconditions, on précise la signature de la méthode concernée dans le contexte: + + context Canard::cancaner(i: Integer): String + +On utilise ensuite le mot-clé `pre` pour spécifier les préconditions dans le contexte: + + context Canard::cancaner(i: Integer): String + pre: i > 0 + +### Exercice + +Ajoutez les contraintes ci-dessous au modèle suivant: + +![Diagramme de classes](uml_exercice.svg) + +Nommez vos contraintes avec les identifiants notés `cX`. + +#### Methode Vaisseau::charger(objet) + +* `c1`: le vaisseau ne contient pas déjà l'objet à charger +* `c2`: l'objet à charger ne dépasse pas la capacité restante du vaisseau diff --git a/tracks/use-ocl/04_preconditions/template b/tracks/use-ocl/04_preconditions/template new file mode 100644 index 0000000..0554e02 --- /dev/null +++ b/tracks/use-ocl/04_preconditions/template @@ -0,0 +1,47 @@ +model SpaceZ + +class Objet + attributes + poids: Integer +end + +class Vaisseau < Objet + attributes + capacite: Integer + operations + charger(objet: Objet) + equiper(arme: Arme) +end + +class Arme < Objet + attributes + puissance: Integer +end + +association contient between + Vaisseau [0..1] role cargo + Objet [*] role objets +end + +association equipe between + Vaisseau [0..1] role vaisseau + Arme [*] role armes +end + +constraints + +-- Entrez vos contraintes ici + +context Objet + inv c1: poids > 0 + +context Vaisseau::charger(objet: Objet) + pre c2: objets->excludes(objet) + pre c3: objet.poids <= capacite + post c4: capacite = capacite@pre - objet.poids + post c5: objets->includes(objet) + +context Vaisseau::equiper(arme: Arme) + pre c6: objets->includes(arme) + pre c7: armes->excludes(arme) + post c8: armes->size() = armes@pre->size() + 1 diff --git a/tracks/use-ocl/04_preconditions/tests.txt b/tracks/use-ocl/04_preconditions/tests.txt new file mode 100644 index 0000000..66f9018 --- /dev/null +++ b/tracks/use-ocl/04_preconditions/tests.txt @@ -0,0 +1,49 @@ +=== +!create o: Objet +!set o.poids := 10 + +!create v: Vaisseau +!set v.poids := 10000 +!set v.capacite := 5000 + +!openter v charger(o) +--- +precondition `c1' is true +precondition `c2' is true +checking structure... +checking invariants... +checked 0 invariants, 0 failures. +=== +!create o: Objet +!set o.poids := 10 + +!create v: Vaisseau +!set v.poids := 10000 +!set v.capacite := 5000 + +!insert(v, o) into contient + +!openter v charger(o) +--- +precondition `c1' is false +precondition `c2' is true +Error: precondition false in operation call `Vaisseau::charger(self:v, objet:o)'. +checking structure... +checking invariants... +checked 0 invariants, 0 failures. +=== +!create o: Objet +!set o.poids := 100000 + +!create v: Vaisseau +!set v.poids := 10000 +!set v.capacite := 5000 + +!openter v charger(o) +--- +precondition `c1' is true +precondition `c2' is false +Error: precondition false in operation call `Vaisseau::charger(self:v, objet:o)'. +checking structure... +checking invariants... +checked 0 invariants, 0 failures. diff --git a/tracks/use-ocl/04_preconditions/uml_exercice.svg b/tracks/use-ocl/04_preconditions/uml_exercice.svg new file mode 120000 index 0000000..df0f6d8 --- /dev/null +++ b/tracks/use-ocl/04_preconditions/uml_exercice.svg @@ -0,0 +1 @@ +/home/morriar/dev/moz/missions/tracks/use-ocl/02_associations/uml_exercice.svg \ No newline at end of file diff --git a/tracks/use-ocl/05_postconditions/config.ini b/tracks/use-ocl/05_postconditions/config.ini new file mode 100644 index 0000000..be3a3f9 --- /dev/null +++ b/tracks/use-ocl/05_postconditions/config.ini @@ -0,0 +1,2 @@ +title=Postconditions +req=03_contraintes diff --git a/tracks/use-ocl/05_postconditions/mission.md b/tracks/use-ocl/05_postconditions/mission.md new file mode 100644 index 0000000..d75feb4 --- /dev/null +++ b/tracks/use-ocl/05_postconditions/mission.md @@ -0,0 +1,23 @@ +## Saisir les contraintes OCL + +Pour définir des post-conditions, on précise la signature de la méthode concernée dans le contexte: + + context Canard::cancaner(i: Integer): String + +On utilise le mot-clé `post` pour spécifier les post-conditions dans le contexte: + + context Canard::cancaner(i: Integer): String + post: result.size() = 'coin'.size() * i + +### Exercice + +Ajoutez les contraintes ci-dessous au modèle suivant: + +![Diagramme de classes](uml_exercice.svg) + +Nommez vos contraintes avec les identifiants notés `cX`. + +#### Methode Vaisseau::charger(objet) + +* `c1`: une fois l'objet chargé, son poids est soustrait à la capacité du vaisseau +* `c2`: une fois l'objet chargé, il se trouve dans les objets du vaisseau diff --git a/tracks/use-ocl/05_postconditions/template b/tracks/use-ocl/05_postconditions/template new file mode 100644 index 0000000..0554e02 --- /dev/null +++ b/tracks/use-ocl/05_postconditions/template @@ -0,0 +1,47 @@ +model SpaceZ + +class Objet + attributes + poids: Integer +end + +class Vaisseau < Objet + attributes + capacite: Integer + operations + charger(objet: Objet) + equiper(arme: Arme) +end + +class Arme < Objet + attributes + puissance: Integer +end + +association contient between + Vaisseau [0..1] role cargo + Objet [*] role objets +end + +association equipe between + Vaisseau [0..1] role vaisseau + Arme [*] role armes +end + +constraints + +-- Entrez vos contraintes ici + +context Objet + inv c1: poids > 0 + +context Vaisseau::charger(objet: Objet) + pre c2: objets->excludes(objet) + pre c3: objet.poids <= capacite + post c4: capacite = capacite@pre - objet.poids + post c5: objets->includes(objet) + +context Vaisseau::equiper(arme: Arme) + pre c6: objets->includes(arme) + pre c7: armes->excludes(arme) + post c8: armes->size() = armes@pre->size() + 1 diff --git a/tracks/use-ocl/05_postconditions/tests.txt b/tracks/use-ocl/05_postconditions/tests.txt new file mode 100644 index 0000000..ab3ca8d --- /dev/null +++ b/tracks/use-ocl/05_postconditions/tests.txt @@ -0,0 +1,66 @@ +=== +!create o: Objet +!set o.poids := 10 + +!create v: Vaisseau +!set v.poids := 10000 +!set v.capacite := 5000 + +!openter v charger(o) +!set v.capacite := v.capacite - o.poids +!insert(v, o) into contient +!opexit +--- +postcondition `c1' is true +postcondition `c2' is true +checking structure... +checking invariants... +checked 0 invariants, 0 failures. +=== +!create o: Objet +!set o.poids := 10 + +!create v: Vaisseau +!set v.poids := 10000 +!set v.capacite := 5000 + +!openter v charger(o) +!insert(v, o) into contient +!opexit +--- +postcondition `c1' is false + self : Vaisseau = v + self.capacite : Integer = 5000 + self : Vaisseau = v + self.capacite@pre : Integer = 5000 + objet : Objet = o + objet.poids : Integer = 10 + (self.capacite@pre - objet.poids) : Integer = 4990 + (self.capacite = (self.capacite@pre - objet.poids)) : Boolean = false +postcondition `c2' is true +Error: postcondition false in operation call `Vaisseau::charger(self:v, objet:o)'. +checking structure... +checking invariants... +checked 0 invariants, 0 failures. +=== +!create o: Objet +!set o.poids := 10 + +!create v: Vaisseau +!set v.poids := 10000 +!set v.capacite := 5000 + +!openter v charger(o) +!set v.capacite := v.capacite - o.poids +!opexit +--- +postcondition `c1' is true +postcondition `c2' is false + self : Vaisseau = v + self.objets : Set(Objet) = Set{} + objet : Objet = o + self.objets->includes(objet) : Boolean = false +Error: postcondition false in operation call `Vaisseau::charger(self:v, objet:o)'. +checking structure... +checking invariants... +checked 0 invariants, 0 failures. diff --git a/tracks/use-ocl/05_postconditions/uml_exercice.svg b/tracks/use-ocl/05_postconditions/uml_exercice.svg new file mode 120000 index 0000000..df0f6d8 --- /dev/null +++ b/tracks/use-ocl/05_postconditions/uml_exercice.svg @@ -0,0 +1 @@ +/home/morriar/dev/moz/missions/tracks/use-ocl/02_associations/uml_exercice.svg \ No newline at end of file diff --git a/tracks-wip/nit/packages.ini b/tracks/use-ocl/packages.ini similarity index 100% rename from tracks-wip/nit/packages.ini rename to tracks/use-ocl/packages.ini diff --git a/tracks/use-ocl/template b/tracks/use-ocl/template new file mode 100644 index 0000000..d9e9385 --- /dev/null +++ b/tracks/use-ocl/template @@ -0,0 +1 @@ +-- Entrez votre code OCL ici diff --git a/tracks/use-ocl/track.ini b/tracks/use-ocl/track.ini new file mode 100644 index 0000000..194e914 --- /dev/null +++ b/tracks/use-ocl/track.ini @@ -0,0 +1,4 @@ +title=USE-OCL +language=ocl +engine=use-ocl +editor=ocl diff --git a/tracks/use-ocl/track.md b/tracks/use-ocl/track.md new file mode 100644 index 0000000..bb6fe09 --- /dev/null +++ b/tracks/use-ocl/track.md @@ -0,0 +1,3 @@ +Exercices OCL pour le cours INF3143 - Spécification et modélisation formelles de logiciels. + +Les exercices de cette série utilisent USE-OCL. diff --git a/www/index.html b/www/index.html index 297fa6c..41ea235 100644 --- a/www/index.html +++ b/www/index.html @@ -23,6 +23,7 @@ type='text/css' rel='stylesheet'> + @@ -75,6 +76,7 @@ + diff --git a/www/javascripts/submission.js b/www/javascripts/submission.js index f26cd5f..9036744 100644 --- a/www/javascripts/submission.js +++ b/www/javascripts/submission.js @@ -23,14 +23,10 @@ if (vm.missionStatus) vm.source = vm.missionStatus.last_submission; if (!vm.source) vm.source = vm.mission.template; if (!vm.source) vm.source = ""; - vm.lang = "pep8"; - vm.engine = "pep8term"; $scope.submit = function () { var data = { - source: btoa(vm.codeMirror.doc.getValue()), - lang: vm.lang, - engine: vm.engine + source: btoa(vm.codeMirror.doc.getValue()) }; Missions.sendMissionSubmission(data, vm.mission._id, function (data) { // Only launch fireworks on new success @@ -47,7 +43,7 @@ $scope.initCodeMirror = function() { vm.codeMirror = CodeMirror.fromTextArea( document.getElementById('source'), { - mode: "pep8", + mode: vm.mission.editor, lineNumbers: true, }); vm.codeMirror.doc.setValue(vm.source); diff --git a/www/vendors/codemirror/ocl.css b/www/vendors/codemirror/ocl.css new file mode 100644 index 0000000..c43fdc2 --- /dev/null +++ b/www/vendors/codemirror/ocl.css @@ -0,0 +1,32 @@ +/* + * Copyright 2016 Alexandre Terrasa . + * + * 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. + */ + +.cm-keyword, .cm-use-ocl { + color: blue; + font-weight: bold; +} + +.cm-constraint { + color: blue; +} + +.cm-comment, .cm-s-default .cm-comment { + color: #00af05 +} + +.cm-special, .cm-s-default .special { + color: #D432D0 +} diff --git a/www/vendors/codemirror/ocl.js b/www/vendors/codemirror/ocl.js new file mode 100644 index 0000000..a27b1b0 --- /dev/null +++ b/www/vendors/codemirror/ocl.js @@ -0,0 +1,40 @@ +/* + * Copyright 2016 Alexandre Terrasa . + * + * 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. + */ + +CodeMirror.defineSimpleMode("ocl", { + start: [ + // OCL keywords + {regex: /(?:context|package|endpackage|if|then|else|endif|let|in|true|false|invalid|null|not|and|or|xor|implies)\b/, token: "keyword"}, + + // USE-OCL keywords + {regex: /(?:class|enum|end|association|between|role|model|constraints|attributes|operations)\b/, token: "use-ocl"}, + + // OCL constraints + {regex: /(?:inv|pre|post|body|init|derive|def)\b/, token: "constraint"}, + + // Special keywords + {regex: /(?:self|result|@pre|Set|OrderedSet|Sequence|Bag)\b/, token: "special"}, + + // Comments + {regex: /--.*/, token: "comment"}, + + // String + { regex: /'(?:[^\\']|\\.)*'?/, token: "string" }, + + // Numerical + { regex: /\d+/, token: "number" }, + ] +});