Home

Awesome

Programming language Dino and its implementation

Develepment version of future release 0.98

Vladimir Makarov, vmakarov@gcc.gnu.org

Apr 2, 2016

Description Layout


Some history

The first taste of Dino

      var i, prime, k, count = 0, SieveSize = 8191, flags = [SieveSize : 1];
      for (i = 0; i < SieveSize; i++)
        if (flags[i]) {
          prime = i + i + 3;
          k = i + prime;
          for (;;) {
            if (k >= SieveSize)
              break;
            flags[k] = 0;
            k += prime;
          }
          count++;
        }
      putln (count);

DINO as a scripting language


Arrays and Tables


Array Slices

      var i, prime, count = 0, SieveSize = 8191, flags = [SieveSize : 1];
      for (i = 0; i < SieveSize; i++)
        if (flags[i]) {
          prime = i + i + 3;
          flags[i + prime:SieveSize:prime] = 0;
          count++;
        }
      putln (count);

Functions

      fun even;
      fun odd  (i) {i == 0 ? 0 : even (i - 1);}
      fun even (i) {i == 0 ? 1 : odd (i - 1);}
      putln (odd (1_000_000));
      filter (fun (a) {a > 0;}, v);
      fold (fun (a, b) {a * b;}, v, 1);
      fun incr (base) {fun (incr) {base + incr;}}

Threads

      fiber t (n) {for (var i = 0; i < n; i++) putln (i);}
      t(100); // the following code don't wait for t finish
      for (var i = 0; i < 1000; i++) putln (“main”, i);
      wait (cond) [stmt];

Object orientation

          class num (i) {fun print {put (i);}}
          class binop (l, r) { fun print_op;
            fun print {l.print(); print_op (); r.print ();}
          }
          class add (l, r) {
            use binop former l, r later print_op;
            fun print_op {put (“ + “);}
          }

Object orientation -- continuation


Object orientation -- continuation

      isa (add, binop);
      isa (add (num (1), num (2)), binop);
      obj int_pair {
        val min = 0, max = 10;
      }

Object orientation -- continuation

      obj sorts {
        var compare_fun;
        fun quick_sort (...) {...}
        fun heap_sort (...) {...}
      }
      ...
      sorts.fft (...);
      expose sorts.quick_sort;
      quick_sort (...);
      expose sorts.quick_sort (asort);
      asort (...);
      expose sorts.*;
      compare_fun = ...; quick_sort (...); heap_sort (...);

Standard spaces


Pattern matching


Pattern matching -- pmatch statement

    pmatch (v) {
      case [...]: putln ("array"); continue;
      case [a, ...]: if (a == 0) break; putln ("array with non-zero 1st element");
      case node (v) if v != 0: putln ("object of class node with nozero parameter");
      case _: putln ("any but array");
    }

Example: classes and functions with pattern matching

      class tree {}
      class leaf (i) {use tree;}
      class node (l, r) {use tree;}
      fun exists_leaf (test, t) {
        pmatch (t) {
          case leaf (v): return test (v);
          case node (l, r):
            return exists_leaf (test, l) || exists_leaf (test, r);
        }
      }
      fun has_odd_leaf (t) {
        exists_leaf (fun (n) {type (n) == int && n % 2 == 1;}, t);
      }

Regular expression matching -- rmatch statement

    rmatch (str) {
      case "[a-zA-Z]+": putln ("word starting at ", m[0]);
      case "[0-9]+": putln ("number starting at ", m[0]);
      case _: putln ("anything else, m is undefined");
    }

Exception handling

            class my_except (msg) {use except;}
            throw my_except ("my special exceptions");

Exception handling -- continuation

            try {
              var ln;
              for (;;) {
                var ln = getln (); putln (ln);
              }
            } catch (eof) { putln ("end of file"); }
            var ln;
            for (; try (ln = getln (), eof);) putln (ln);
            fun {try {ln = getln (); return 1;} catch (eof) {return 0;} ()

Earley parser


Earley parser -- tiny language example

expose yaep.*;
val grammar =
 "TERM ident=301, num=302, if=303, then=304, for=305, do=307, var=308;
  program = program stmt                     # list (0 1)
  stmt = ident '=' expr ';'                  # asgn (0 2)
       | if expr then stmt else stmt         # if (1 3 5)
       | for ident '=' expr expr do stmt     # for (1 3 4 6)
       | '{' program '}'                     # block (1)
       | var ident ';'                       # var (1)
       | error
  expr = expr '+' factor                     # plus (0 2)
  factor = factor '*' term                   # mult (0 2)
  term = ident                               # 0
       | '(' expr ')'                        # 1";
val p = parser ();       // create an Earley parser
p.set_grammar (grammar); // set grammar
fun syntax_error;        // forward decl of syntax error reporting func
val asbtract_tree = p.parse (token_vector, syntax_error);

Implementation -- General Structure

Dino Flow


Implementation -- Byte Code


Implementation -- Byte Code example

      var i, n = 1000;
      for (i = 0; i < n; i++);
      0 block fn="ex.d" ln=1 pos=1 next=730 vars_num=29 tvars_num=3 // ident=
      ...
      372 vdecl fn="ex.d" ln=1 pos=5 ident=i ident_num=268 decl_scope=0 var_num=27
      373 vdecl pos=8 ident=n ident_num=269 decl_scope=0 var_num=28
      ...
      788 ldi fn="ex.d" ln=1 pos=12 op1=28 op2=1000 // 28 <- i1000
      789 ldi ln=2 pos=10 next=791 op1=27 op2=0 // 27 <- i0
      790 btltinc pos=15 next=792 op1=27 binc_inc=1 bcmp_op2=28 bcmp_res=29 pc=790
                                          // goto 790 if 29 <- (27 += i1) cmp 28
      791 btlt pos=15 op1=27 bcmp_op2=28 bcmp_res=29 pc=790 // goto 790 if 29 <- 27 cmp 28
      792 bend pos=17 block=0

Implementation -- BC optimizations

            label: addi op1, op1, i1; lt res, op1, op2; bt res, label =>
            label: addi op1, op1, i1; blt res, op1, op2, label =>
            label: btltinc op1, op2, i2, res, label

Implementation


Implementation -- Continuation

            fun fact (n) !jit {n <=1 ? 1 : n * fact (n - 1);}

Implementation -- Type Inference


Implementation -- Type Inference 2


Implementation -- Type Inference 3


Implementation -- Tools and libraries


Implementation -- Profiling

      ** Calls *** Time **** Name **************************************
        761087     0.43  --  search1: "meteor.d": 229
        561264     0.07  --  ctz: "meteor.d": 28
          1260     0.01  --  GoodPiece: "meteor.d": 37
           ...
                   0.51  --  All Program
      ** Calls *** Time **** Name **************************************
        761087     0.15  --  search1: "meteor.d": 229
           ...
             0     0.00  --  ctz: "meteor.d": 28
           ...
                   0.17  --  All Program

Implementation -- C Interface

      extern v, f ();
      val_t f (int npars, val_t *args);

Implementation -- C Interface 2

      #include d_api.h
      ...
      val_t v;
      ...
      val_t f (int n_pars, val_t *args) {
        ER_node_t first_arg = (ER_node_t) &args[0];
        if (npars == 1 && ER_NODE_MODE (first_arg) == ER_NM_int)
	  <do something with integer value> ER_i (first_arg);
	...
      }

Implementation -- C Interface 3

      %{
        ...
        val_t f (int n_pars, val_t *args) {
          ...
        }
      %}
      extern f ();
      val r = f(10);

Code Metrics

	Totals grouped by language (dominant language first):
	sh:          265452 (54.10%)
	ansic:       194472 (39.64%)
	yacc:         23297 (4.75%)
	cpp:           7403 (1.51%)
	Totals grouped by language (dominant language first):
	sh:          161561 (62.13%)
	ansic:        95124 (36.58%)
	yacc:          3365 (1.29%)

Benchmarking -- Programs


Benchmarking -- Languages and CPUs


Benchmarking -- x86-64

LoopHashFactFibExceptMethodObjectSieveSortStat.RandomThreadStartCompile
Dino11.021.01.031.031.01.01.01.01.021.01.041.01.01.0
Dino191.013.21121.01.01.01.01.41.03.11.01.01.0
Python2572.490.44929.75.84.437.913.32.626.912510.93.3
Ruby1572.225.21425.51.51.44.54.53.512.443.629.41.8
PyPy8.10.40.4590.40.20.14.51.41.30.947.022.117.8
JS1511.433.3211---5.50.6-0.5-1.10.8
Scala9.61.62.814760.31.20.72.40.79.41.2-352-5
Ocaml34.41.05.2690.30.50.81.81.83.22.2-5,3283

Benchmarking -- AARCH64

LoopHashFactFibExceptMethodObjectSieveSortStat.RandomThreadStartCompile
Dino11.021.01.031.031.01.01.01.01.021.01.041.01.01.0
Dino17.51.713.12651.01.01.01.01.41.02.21.01.01.0
Python2220.568.8111612.44.72.840.35.32.515.51492462.6
Ruby1702.832.35426.01.71.48.53.73.813.11186551.6
JS2821.4631.6471---16.22.5-6.5-1.00.5
Ocaml44.71.25.01660.30.50.92.62.14.03.5-82.7232

Benchmarking -- ARM

LoopHashFactFibExceptMethodObjectSieveSortStat.RandomThreadStartCompile
Dino11.021.01.031.031.01.01.01.01.021.01.041.01.01.0
Dino4.21.018.14901.01.01.01.01.81.02.51.01.01.0
Python28.20.64.4160011.73.45.119.36.72.217.515710.92.7
Ruby31.52.671.26516.31.31.74.84.03.311.317412.71.7
PyPy1031.415141589.912.17.942.111.75.530.44857.27
JS29.81.4632.2634---4.10.4-0.4-1.10.7
Scala7.48.26.423966.91.21.05.80.7191.2-1097
Ocaml13.81.08.83270.40.61.02.52.23.31.7-3.07

Benchmarking - PPC64

LoopHashFactFibExceptMethodObjectSieveSortStat.RandomThreadStartCompile
Dino11.021.01.031.031.01.01.01.01.021.01.041.01.01.0
Dino23.21.016.22221.01.01.01.04.31.04.41.01.01.0
Python1821.551.096515.13.64.129.87.52.015.71605.15.0
Ruby17.61.743.039020.01.63.17.64.25.211.462.846.11.5
JS27.03.053.8453---14.22.8-4.6-2.70.7
Ocaml33.21.85.41330.30.41.53.72.64.83.9-4.4360

Implementation - Conclusions


Future directions of research


Dino availability


Dino Building

      <dino-path>/configure --srcidir=<dino-path> --prefix=<install-path>
      <dino-path>/configure --srcidir=<dino-path> --prefix=<install-path> --enable-debug
      make
      make check
      cd DINO; make check
      make install

Footnotes

  1. Dino best result. 2 3 4

  2. Dino JIT hint was used. 2 3 4 5 6 7 8

  3. Dino pure func hint was used. 2 3 4 5 6 7 8

  4. Dino inline hint was used. 2 3 4

  5. Scala can not even handle 10 times smaller code.

  6. Non-JIT JS was used as JIT failed. 2

  7. PyPy, Scala, and Ocaml failed to compile long code. 2 3