config.mk
include/generated.h
.desk
+mkdocs.yml
+*.a
.SUFFIXES: .gw .test
.gw.test:
- @${VALGRIND} ${VALGRIND_OPT} gwion $< &> log
+ @${VALGRIND} ${VALGRIND_OPT} gwion $< 2>&1 > log
@[ -t 1 ] && $(call _interm) || $(call _noterm)
define _test_check
for a in $(CONTAINS); do grep "$$a" log >/dev/null; done && valgrind_parse vlog
endef
-_interm_status=echo -e "$(INTERM_OK)" || echo -e "$(INTERM_NOT_OK)"
+_interm_status=printf "$(INTERM_OK)\n" || printf "$(INTERM_NOT_OK)\n"
_interm=(cat log; $(call _test_check) && $(call _interm_status))
_noterm_log=sed 's/$$/\<br\/>/' log
-_noterm_status=echo -e "$(NOTERM_OK)" || echo -e "$(NOTERM_NOT_OK)"
+_noterm_status=printf "$(NOTERM_OK)\n" || printf "$(NOTERM_NOT_OK)\n"
_noterm_test=$(call _test_check) && $(call _noterm_status)
_noterm_header=echo '<p style=$(CSS)>'
_noterm_footer=echo '</p>'
new Object @=> ref;
<<<"But now it does: ", ref>>>;
@```
-@exec gwion decl1.gw 2>&1
+@exec make decl1.test
## Arrays
### array as refs
+
@``` decl2.gw
int ref[];
<<<ref>>>;
new int[2] @=> ref;
<<<ref>>>;
@```
-@exec gwion decl2.gw 2>&1
+@exec make decl2.test
--- /dev/null
+# Benchmarks
+
+We'll need a bash script
+
+<link rel=styleSheet href="../assets/doc.css" TYPE="text/css"><div id="org-categories"><ul class="lev1"><li><a href="#">Show the code</a></li><ul class="lev2"><a href="#">
+@``` benchmark.sh
+#!/bin/sh
+language=("gwion" "wren" "lua5.3")
+extension=("gw" "wren" "lua")
+test_dir="tests/benchmark"
+plot_script="bench.plot"
+: "${repeats:=10}"
+
+run() {
+ perf stat -r"$repeats" "$1" "$test_dir/$3.$2" 2>&1 | grep "time elapsed" |
+ sed 's/ *\([0-9]*\),\([0-9]*\) seconds time elapsed *( +- *\([0-9]*\),\([0-9]*\)% )/\1.\2 \3.\4/'
+}
+
+get_list() {
+ for file in $test_dir/*.gw
+ do basename "$file" .gw
+ done
+}
+
+get_test() {
+ for (( i=0; i<=$(( ${#language[@]} -1 )); i++ ))
+ do echo "${language[$i]} $(run "${language[$i]}" "${extension[$i]}" "$1")"
+ done > "docs/assets/benchmark/$1.dat"
+}
+
+plot() {
+ gnuplot -e "bench='$1'" "$plot_script"
+}
+
+for bench in $(get_list)
+do
+echo $bench
+ get_test "$bench"
+ plot "$bench"
+ echo "### $bench"
+ echo '<link rel=styleSheet href="../assets/doc.css" TYPE="text/css"><div id="org-categories"><ul class="lev1"><li><a href="#">Show the code</a></li><ul class="lev2"><a href="#">'
+ echo "\`\`\`"
+ cat "$test_dir/$bench.gw"
+ echo "\`\`\`"
+ echo '</a></a></li></ul></ul></div>'
+ echo "![](assets/benchmark/$bench.png)"
+done
+@```
+</a></a></li></ul></ul></div>
+
+### and a gnuplot script
+
+<link rel=styleSheet href="../assets/doc.css" TYPE="text/css"><div id="org-categories"><ul class="lev1"><li><a href="#">Show the code</a></li><ul class="lev2"><a href="#">
+@``` bench.plot
+set terminal png truecolor
+
+#if (!exists("bench"))
+# bench = 'bench'
+if (!exists("test_dir"))
+ test_dir = 'tests/benchmark'
+
+dat_name = sprintf("docs/assets/benchmark/%s.dat", bench)
+
+stats dat_name using 0:2 noout
+max = ceil(STATS_max_y+2)
+
+#set title bench
+set output sprintf("docs/assets/benchmark/%s.png", bench)
+set xrange [-0.5:((ceil(STATS_max_x))+0.5)]
+set yrange [0:max]
+set boxwidth 0.50
+set nokey
+set xtics nomirror
+set ytics nomirror
+
+set style fill transparent solid 0.25 # partial transparency
+set style fill noborder # no separate top/bottom lines
+
+plot dat_name using 0:2:($3/100.):xtic(2) with boxerrorbar lc "blue" notitle, \
+ '' using 0:(max-0.5):1 with labels
+@```
+</a></a></li></ul></ul></div>
+
+## Show the results
+Then just run it
+@exec bash benchmark.sh; rm bench.plot benchmark.sh
# Functions
## a simple (commented example)
-@```function0.gw
+
+@``` function0.gw
// declare function 'test_function'
// with return type int
// taking an int as argument
-# Gwion's Makefile
+# Makefile
## Basic operations
--- /dev/null
+gwion 0.244813625 0.33
+wren 0.358684268 1.43
+lua5.3 0.621848489 5.69
--- /dev/null
+li + .lev2 {
+ display: none;
+}
+
+li:focus-within + .lev2 {
+ display: block;
+}
+++ /dev/null
-#!/bin/sh
-#run benchmarks and make plots
-: "${repeats:=10}"
-
-fib_test() {
-# echo "\"$1\"" "$(perf stat -r"$repeats" "$1" "fib_recurs.$2" 2>&1 | grep "time elapsed" | cut -d s -f 1 | sed 's/+-//' | sed 's/,/./g')"
- printf "$(perf stat -r"$repeats" "$1" "fib_recurs.$2" 2>&1 | grep "time elapsed" | cut -d s -f 1 | sed 's/+-//' | sed 's/,/./g')"
-}
-
-cd ~/fib_recurs/ || exit 1
-printf "\"fib recurs\" "
-fib_test gwion gw
-fib_test lua lua
-fib_test wren wren
-#fib_test chuck ck
-#fib_test ruby rb
-#fib_test perl pl
-#fib_test python2 py
-#fib_test python3 py
-#fib_test runhaskell hs
title() {
TMP=$(head -n 1 $1)
- echo ${TMP:2}
+ sed "s/'/\'/" <<< "${TMP:2}"
}
list_dir() {
+ [[ "$1" == */"assets" ]] && return
for a in $1/*
do
- if [ -d "$a" ]
- then echo "$2- '$(basename $a | sed 's/[0-9][0-9]_//' | sed 's/_/ /g' | sed 's/-/ /g')':"; list_dir $a "$2 "
- else echo "$a" | grep "\.md$" >/dev/null && echo "$2- $(title $a): ${a:5}"
- fi
+ if [ -d "$a" ]
+ then [[ "$a" == */"assets" ]] ||
+ echo "$2- '$(basename $a | sed 's/[0-9][0-9]_//' | sed 's/_/ /g' | sed 's/-/ /g')':"; list_dir "$a" "$2 "
+ else echo "$a" | grep "\.md$" >/dev/null && echo "$2- '$(title $a)': ${a:5}"
+ fi
done
}
--- /dev/null
+// Ported from the Wren version.
+
+class Tree {
+ var _item;
+ var _left;
+ var _right;
+
+ Tree(item, depth) {
+ _item = item;
+ if (depth > 0) {
+ var item2 = item + item;
+ depth--;
+ _left = new Tree(item2 - 1, depth);
+ _right = new Tree(item2, depth);
+ }
+ }
+
+ get check {
+ if (_left == null) {
+ return _item;
+ }
+
+ return _item + _left.check - _right.check;
+ }
+}
+
+main() {
+ var minDepth = 4;
+ var maxDepth = 12;
+ var stretchDepth = maxDepth + 1;
+
+ print("stretch tree of depth ${stretchDepth} check: "
+ "${new Tree(0, stretchDepth).check}");
+
+ var longLivedTree = new Tree(0, maxDepth);
+
+ // iterations = 2 ** maxDepth
+ var iterations = 1;
+ for (var d = 0; d < maxDepth; d++) {
+ iterations = iterations * 2;
+ }
+
+ var depth = minDepth;
+ while (depth < stretchDepth) {
+ var check = 0;
+ for (var i = 1; i <= iterations; i++) {
+ check += new Tree(i, depth).check + new Tree(-i, depth).check;
+ }
+
+ print("${iterations * 2} trees of depth ${depth} check: ${check}");
+ iterations ~/= 4;
+ depth += 2;
+ }
+
+ print("long lived tree of depth ${maxDepth} check: ${longLivedTree.check}");
+}
--- /dev/null
+// Ported from the Wren version.
+
+class Tree {
+ int item;
+ Tree @left, right;
+
+ fun static Tree new_Tree(int it, int depth) {
+ Tree t;
+ it => t.item;
+ if (depth > 0) {
+ it + it => int item2;
+ --depth;
+ Tree.new_Tree(item2 - 1, depth) @=> t.left;
+ Tree.new_Tree(item2, depth) @=> t.right;
+ }
+ return t;
+ }
+
+ fun int check() {
+ if (!left)
+ return item;
+ return item + left.check() - right.check();
+ }
+}
+
+4 => int minDepth;
+12 => int maxDepth;
+maxDepth + 1 => int stretchDepth;
+
+<<<"stretch tree of depth ", stretchDepth, " check: ",
+ Tree.new_Tree(0, stretchDepth).check()>>>;
+
+Tree.new_Tree(0, maxDepth) @=> Tree@ longLivedTree;
+
+// iterations = 2 ** maxDepth
+1 => int iterations;
+for (int d; d < maxDepth; ++d)
+ 2 *=> iterations;
+
+minDepth => int depth;
+while (depth < stretchDepth) {
+ int check;
+ for (int i; i < iterations; ++i)
+ Tree.new_Tree(i, depth).check() + Tree.new_Tree(-i, depth).check() +=> check;
+
+ <<<iterations * 2, " trees of depth ", depth, " check: ", check>>>;
+ 4 /=> iterations;
+ 2 +=> depth;
+}
+
+<<<"long lived tree of depth ", maxDepth, " check: ", longLivedTree.check()>>>;
--- /dev/null
+-- The Computer Language Benchmarks Game
+-- http://shootout.alioth.debian.org/
+-- contributed by Mike Pall
+
+local function BottomUpTree(item, depth)
+ if depth > 0 then
+ local i = item + item
+ depth = depth - 1
+ local left, right = BottomUpTree(i-1, depth), BottomUpTree(i, depth)
+ return { item, left, right }
+ else
+ return { item }
+ end
+end
+
+local function ItemCheck(tree)
+ if tree[2] then
+ return tree[1] + ItemCheck(tree[2]) - ItemCheck(tree[3])
+ else
+ return tree[1]
+ end
+end
+
+local N = 12
+local mindepth = 4
+local maxdepth = mindepth + 2
+if maxdepth < N then maxdepth = N end
+
+do
+ local stretchdepth = maxdepth + 1
+ local stretchtree = BottomUpTree(0, stretchdepth)
+ io.write(string.format("stretch tree of depth %d check: %d\n",
+ stretchdepth, ItemCheck(stretchtree)))
+end
+
+local longlivedtree = BottomUpTree(0, maxdepth)
+
+for depth=mindepth,maxdepth,2 do
+ local iterations = 2 ^ (maxdepth - depth + mindepth)
+ local check = 0
+ for i=1,iterations do
+ check = check + ItemCheck(BottomUpTree(1, depth)) +
+ ItemCheck(BottomUpTree(-1, depth))
+ end
+ io.write(string.format("%d trees of depth %d check: %d\n",
+ iterations*2, depth, check))
+end
+
+io.write(string.format("long lived tree of depth %d check: %d\n",
+ maxdepth, ItemCheck(longlivedtree)))
--- /dev/null
+# The Computer Language Benchmarks Game
+# http://shootout.alioth.debian.org/
+#
+# contributed by Antoine Pitrou
+# modified by Dominique Wahli
+# modified by Heinrich Acker
+from __future__ import print_function
+
+import time
+
+# Map "range" to an efficient range in both Python 2 and 3.
+try:
+ range = xrange
+except NameError:
+ pass
+
+def make_tree(item, depth):
+ if not depth: return item, None, None
+ item2 = item + item
+ depth -= 1
+ return item, make_tree(item2 - 1, depth), make_tree(item2, depth)
+
+def check_tree(node):
+ item, left, right = node
+ if not left: return item
+ return item + check_tree(left) - check_tree(right)
+
+min_depth = 4
+max_depth = 12
+stretch_depth = max_depth + 1
+
+print("stretch tree of depth %d check:" % stretch_depth, check_tree(make_tree(0, stretch_depth)))
+
+long_lived_tree = make_tree(0, max_depth)
+
+iterations = 2 ** max_depth
+for depth in range(min_depth, stretch_depth, 2):
+
+ check = 0
+ for i in range(1, iterations + 1):
+ check += check_tree(make_tree(i, depth)) + check_tree(make_tree(-i, depth))
+
+ print("%d trees of depth %d check:" % (iterations * 2, depth), check)
+ iterations //= 4
+
+print("long lived tree of depth %d check:" % max_depth, check_tree(long_lived_tree))
--- /dev/null
+# The Computer Language Shootout Benchmarks
+# http://shootout.alioth.debian.org
+#
+# contributed by Jesse Millikan
+# Modified by Wesley Moxam
+
+
+def item_check(left, item, right)
+ return item if left.nil?
+ item + item_check(*left) - item_check(*right)
+end
+
+def bottom_up_tree(item, depth)
+ return [nil, item, nil] unless depth > 0
+ item_item = 2 * item
+ depth -= 1
+ [bottom_up_tree(item_item - 1, depth), item, bottom_up_tree(item_item, depth)]
+end
+
+max_depth = 12
+min_depth = 4
+
+max_depth = min_depth + 2 if min_depth + 2 > max_depth
+
+stretch_depth = max_depth + 1
+stretch_tree = bottom_up_tree(0, stretch_depth)
+
+puts "stretch tree of depth #{stretch_depth} check: #{item_check(*stretch_tree)}"
+stretch_tree = nil
+
+long_lived_tree = bottom_up_tree(0, max_depth)
+
+min_depth.step(max_depth + 1, 2) do |depth|
+ iterations = 2**(max_depth - depth + min_depth)
+
+ check = 0
+
+ for i in 1..iterations
+ temp_tree = bottom_up_tree(i, depth)
+ check += item_check(*temp_tree)
+
+ temp_tree = bottom_up_tree(-i, depth)
+ check += item_check(*temp_tree)
+ end
+
+ puts "#{iterations * 2} trees of depth #{depth} check: #{check}"
+end
+
+puts "long lived tree of depth #{max_depth} check: #{item_check(*long_lived_tree)}"
--- /dev/null
+// Ported from the Python version.
+
+class Tree {
+ construct new(item, depth) {
+ _item = item
+ if (depth > 0) {
+ var item2 = item + item
+ depth = depth - 1
+ _left = Tree.new(item2 - 1, depth)
+ _right = Tree.new(item2, depth)
+ }
+ }
+
+ check {
+ if (_left == null) {
+ return _item
+ }
+
+ return _item + _left.check - _right.check
+ }
+}
+
+var minDepth = 4
+var maxDepth = 12
+var stretchDepth = maxDepth + 1
+
+System.print("stretch tree of depth %(stretchDepth) check: " +
+ "%(Tree.new(0, stretchDepth).check)")
+
+var longLivedTree = Tree.new(0, maxDepth)
+
+// iterations = 2 ** maxDepth
+var iterations = 1
+for (d in 0...maxDepth) {
+ iterations = iterations * 2
+}
+
+var depth = minDepth
+while (depth < stretchDepth) {
+ var check = 0
+ for (i in 1..iterations) {
+ check = check + Tree.new(i, depth).check + Tree.new(-i, depth).check
+ }
+
+ System.print("%(iterations * 2) trees of depth %(depth) check: %(check)")
+ iterations = iterations / 4
+ depth = depth + 2
+}
+
+System.print(
+ "long lived tree of depth %(maxDepth) check: %(longLivedTree.check)")
--- /dev/null
+// Ported from the Python version.
+
+class Tree {
+ construct new(item, depth) {
+ _item = item
+ if (depth > 0) {
+ var item2 = item + item
+ depth = depth - 1
+ _left = Tree.new(item2 - 1, depth)
+ _right = Tree.new(item2, depth)
+ }
+ }
+
+ check {
+ if (_left == null) {
+ return _item
+ }
+
+ return _item + _left.check - _right.check
+ }
+}
+
+var minDepth = 4
+var maxDepth = 12
+var stretchDepth = maxDepth + 1
+
+System.print("stretch tree of depth %(stretchDepth) check: " +
+ "%(Tree.new(0, stretchDepth).check)")
+for (i in 1...1000) System.gc()
+
+var longLivedTree = Tree.new(0, maxDepth)
+
+// iterations = 2 ** maxDepth
+var iterations = 1
+for (d in 0...maxDepth) {
+ iterations = iterations * 2
+}
+
+var depth = minDepth
+while (depth < stretchDepth) {
+ var check = 0
+ for (i in 1..iterations) {
+ check = check + Tree.new(i, depth).check + Tree.new(-i, depth).check
+ }
+
+ System.print("%(iterations * 2) trees of depth %(depth) check: %(check)")
+ for (i in 1...1000) System.gc()
+
+ iterations = iterations / 4
+ depth = depth + 2
+}
+
+System.print(
+ "long lived tree of depth %(maxDepth) check: %(longLivedTree.check)")
+for (i in 1...1000) System.gc()