HoNet's in-house interpreter, strongly influenced by Modula-3 programming language.

Can be found in yum repository with source rpm and all related packages.

Current tasks/ideas for XL are:

  • Make runtime "extensible" at runtime -- possibility to "eval" whole block of code at runtime -- interpret it, and setup it for execution, then execute it in frame of its eval.

Examples (idea phase)

Source codeResulting in
var
  a, b;
begin
  a := 1;
  b := 3;
  ...
  eval ":Result1: $a+b$";
  eval "b := a + b;";
  :Result2: $a+b$
end
Result1: 4
Result2: 5
Source codeResulting in
var
  a, b;
begin
  a := 1;
  b := 3;
  ...
  eval "
module inside;
var 
  c; 
proc d(m, n) =
  begin
    return m*c+n;
  end d;
begin
  c := 4;
end inside.
";
  :Result3: $d(2,3)$
...
Result3: 11

Example (live code)

Source codeResulting in
module c;

var
  f, g;

proc pera() =
  var
    g := 17;
  begin
    f := "while false do end; printf('%s je g\\n', g);";
    :prasing "$f$" in pera()
    eval(f);
  end pera;
  
begin
  g := 33;

  :g je sada $g$

  f := "while g>4 do g := g - 1; end;";
  :prasing "$f$"
  eval(f);

  :g je sada $g$
  :
   
  f := "{'ab' := 1} + {2 := 3,3}";
  :prasing "$f$"
  g := eval(f); 
  :$g$
  :   
      
  f := '[2+3, "ab" + "@" + "cd"]';
  :prasing "$f$"
  g, f := eval(f);
  :g = $g$, f = $f$
  :
   
  pera();
end c.  
g je sada 33
prasing "while g>4 do g := g - 1; end;"
g je sada 4

prasing "{'ab' := 1} + {2 := 3,3}"
{ 3, 2 := 3, ab := 1 }

prasing "[2+3, "ab" + "@" + "cd"]"
g = 5, f = ab@cd

prasing "while false do end; printf('%s je g\n', g);" in pera()
17 je g

Limitations

#44 explains one problem with this implementation.

Random thoughts

Arguments to eval can be...

  • Expression, (implemented)
  • statement(s), (implemented)
  • whole block, (not likely to be, but I can try it just for fun)

In case when argument is whole block, it's better to regard it as module (and not as nested new scope), as it's parts are then visible at same level where it is evaluated (created). If it's nested block (new scope) then it cannot be used from current scope or any other scopes. It's only use would be to create subenvironment for it's begin...end and execute it. Too little.

Ideally, eval is kind of expression, acceptable as XLExprCall in place of statement. In fact, it's implemented as a builtin procedure in MAIN - visible without qualification. It's also exempted from standard scope handling, and it's context is current one, where it appears, not MAIN as it's usual and normal for all other builtin procedures.

eval("@filename") would be logical form for "evaluating" (dynamically importing module contained in that file, in fact) code from external source file. It would parse, setup, and execute main body. After that, it can be used by subsequent eval's. It would return some kind of handle, but more about it later. It's similar to builtin compile(), run(), exec() suite, but not quite - it's external to current interpreters runtime/scopes

Also logical would be possibility to destroy dynamically imported modules. With this possibility one can have, for example, XL hosting environment manageable from XL.

Also logical is need for permissions on eval/import... Imported module must have some kind of permissions on import... This is nice idea, with this we can limit what dynamically imported module can do with other (higher placed in some hierarchy) modules. Some variables can be made read only, some totally unreadable... Interesting train of thought, and very interesting for XL hosting.... Very safe-by-design app hosting environment.