unit BuilderThread;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils;

type
  TBuilderThread = class(TThread)
  private
    FBuildMode: integer;
  protected
    procedure Execute; override;
  public
    procedure AfterConstruction; override;
    property  BuildMode: integer read FBuildMode write FBuildMode;
  end;

implementation

uses
  project
  ,process
  ,fpg_base
  ,fpg_iniutils
  ,ideconst
  ,idemacros
  ;

{ TBuilderThread }

procedure TBuilderThread.AfterConstruction;
begin
  inherited AfterConstruction;
  FBuildMode := -1;  // signals use of project's default build mode
  FreeOnTerminate := True;
end;

procedure TBuilderThread.Execute;
var
  p: TProcess;
  c: TfpgString;
begin
  p := TProcess.Create(nil);
  p.ShowWindow := swoShowNormal;
  p.CurrentDirectory := GProject.ProjectDir;

  // build compilation string
  c := gINI.ReadString(cEnvironment, 'Compiler', '');
  c := c + GProject.GenerateCmdLine(False, BuildMode);
  c := GMacroList.ExpandMacro(c);

//  AddMessage('Compile command: ' + c);
  p.CommandLine := c;
  p.Execute;
//  AddMessage('Compilation complete');
  p.Free;

end;

end.

Create unit output directory if it doesn't yet exist.

unit BuilderThread;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils;

type
  TBuilderThread = class(TThread)
  private
    FBuildMode: integer;
  protected
    procedure Execute; override;
  public
    procedure AfterConstruction; override;
    property  BuildMode: integer read FBuildMode write FBuildMode;
  end;

implementation

uses
  project
  ,process
  ,fpg_base
  ,fpg_iniutils
  ,fpg_utils
  ,ideconst
  ,idemacros
  ;

{ TBuilderThread }

procedure TBuilderThread.AfterConstruction;
begin
  inherited AfterConstruction;
  FBuildMode := -1;  // signals use of project's default build mode
  FreeOnTerminate := True;
end;

procedure TBuilderThread.Execute;
var
  p: TProcess;
  c: TfpgString;
  unitdir: TfpgString;
begin
  unitdir := GProject.ProjectDir + GProject.UnitOutputDir;
  unitdir := GMacroList.ExpandMacro(unitdir);
  if not fpgDirectoryExists(unitdir) then
  begin
    writeln('DEBUG:  TBuilderThread.Execute - Creating dir: ' + unitdir);
    fpgForceDirectories(unitDir);

  end;
  p := TProcess.Create(nil);
  p.ShowWindow := swoShowNormal;
  p.CurrentDirectory := GProject.ProjectDir;

  // build compilation string
  c := gINI.ReadString(cEnvironment, 'Compiler', '');
  c := c + GProject.GenerateCmdLine(False, BuildMode);
  c := GMacroList.ExpandMacro(c);

//  AddMessage('Compile command: ' + c);
  p.CommandLine := c;
  p.Execute;
//  AddMessage('Compilation complete');
  p.Free;

end;

end.


program DelphiASTTest;

uses
  Vcl.Forms,
  uMainForm in 'uMainForm.pas' {Form2};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

Add ReportMemoryLeaksOnShutdown to the test app

program DelphiASTTest;

uses
  Vcl.Forms,
  uMainForm in 'uMainForm.pas' {Form2};

{$R *.res}

begin
  System.ReportMemoryLeaksOnShutdown := True;

  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.


unit uMainForm;

{$IFDEF FPC}{$MODE Delphi}{$ENDIF}

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    MainMenu1: TMainMenu;
    OpenDelphiUnit1: TMenuItem;
    OpenDialog1: TOpenDialog;
    procedure OpenDelphiUnit1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  DelphiAST, DelphiAST.Writer, DelphiAST.Classes;

{$R *.lfm}

function Parse(const FileName: string): string;
var
  SyntaxTree: TSyntaxNode;
begin
  Result := '';
  SyntaxTree := TPasSyntaxTreeBuilder.Run(FileName);
  try
    Result := TSyntaxTreeWriter.ToXML(SyntaxTree, True);
  finally
    SyntaxTree.Free;
  end;
end;

procedure TForm1.OpenDelphiUnit1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    try
      Memo1.Lines.Text := Parse(OpenDialog1.FileName);
    except
      on E: EParserException do
        Memo1.Lines.Add(Format('[%d, %d] %s', [E.Line, E.Col, E.Message]));
    end;
  end;
end;

end.

Correct resource include in demo project's main form

unit uMainForm;

{$IFDEF FPC}{$MODE Delphi}{$ENDIF}

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    MainMenu1: TMainMenu;
    OpenDelphiUnit1: TMenuItem;
    OpenDialog1: TOpenDialog;
    procedure OpenDelphiUnit1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  DelphiAST, DelphiAST.Writer, DelphiAST.Classes;

{$IFNDEF FPC}
  {$R *.dfm}
{$ELSE}
  {$R *.lfm}
{$ENDIF}

function Parse(const FileName: string): string;
var
  SyntaxTree: TSyntaxNode;
begin
  Result := '';
  SyntaxTree := TPasSyntaxTreeBuilder.Run(FileName);
  try
    Result := TSyntaxTreeWriter.ToXML(SyntaxTree, True);
  finally
    SyntaxTree.Free;
  end;
end;

procedure TForm1.OpenDelphiUnit1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    try
      Memo1.Lines.Text := Parse(OpenDialog1.FileName);
    except
      on E: EParserException do
        Memo1.Lines.Add(Format('[%d, %d] %s', [E.Line, E.Col, E.Message]));
    end;
  end;
end;

end.


object FormMain: TFormMain
  Left = 0
  Top = 0
  BorderStyle = bsSingle
  Caption = 'VolBalCon'
  ClientHeight = 201
  ClientWidth = 171
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  OnKeyPress = FormKeyPress
  PixelsPerInch = 96
  TextHeight = 13
  object GroupBoxMaster: TGroupBox
    Left = 8
    Top = 8
    Width = 65
    Height = 185
    Caption = ' Master '
    TabOrder = 0
    object TrackBarMaster: TTrackBar
      Left = 16
      Top = 24
      Width = 45
      Height = 145
      Max = 100
      Orientation = trVertical
      PageSize = 10
      Frequency = 10
      TabOrder = 0
      OnChange = TrackBarMasterChange
    end
  end
  object GroupBoxChannels: TGroupBox
    Left = 79
    Top = 8
    Width = 82
    Height = 185
    Caption = ' Channels '
    TabOrder = 1
    object TrackBarChannel0: TTrackBar
      Left = 16
      Top = 24
      Width = 45
      Height = 145
      Max = 100
      Orientation = trVertical
      PageSize = 10
      Frequency = 10
      TabOrder = 0
      OnChange = TrackBarChannelChange
    end
  end
end

Hide minimize and maximize buttons in title bar

object FormMain: TFormMain
  Left = 0
  Top = 0
  BorderIcons = [biSystemMenu]
  BorderStyle = bsSingle
  Caption = 'VolBalCon'
  ClientHeight = 201
  ClientWidth = 171
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  OnKeyPress = FormKeyPress
  PixelsPerInch = 96
  TextHeight = 13
  object GroupBoxMaster: TGroupBox
    Left = 8
    Top = 8
    Width = 65
    Height = 185
    Caption = ' Master '
    TabOrder = 0
    object TrackBarMaster: TTrackBar
      Left = 16
      Top = 24
      Width = 45
      Height = 145
      Max = 100
      Orientation = trVertical
      PageSize = 10
      Frequency = 10
      TabOrder = 0
      OnChange = TrackBarMasterChange
    end
  end
  object GroupBoxChannels: TGroupBox
    Left = 79
    Top = 8
    Width = 82
    Height = 185
    Caption = ' Channels '
    TabOrder = 1
    object TrackBarChannel0: TTrackBar
      Left = 16
      Top = 24
      Width = 45
      Height = 145
      Max = 100
      Orientation = trVertical
      PageSize = 10
      Frequency = 10
      TabOrder = 0
      OnChange = TrackBarChannelChange
    end
  end
end


program MarkdownTestProgram;

{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}

uses
  {$IFDEF MSWINDOWS} Windows, {$ENDIF}
  Interfaces, SysUtils, Forms, idetester_console,
  CommonTestBase, MarkdownDaringFireballTests, MarkdownCommonMarkTests, idetester_runtime, idetester_form;

{$R *.res}

procedure RegisterTests;
begin
  if not getCommandLineParam('mdRoot', MDTestRoot) then
    MDTestRoot := getCurrentDir;
  MarkdownDaringFireballTests.RegisterTests;
  MarkdownCommonMarkTests.RegisterTests;
end;

var
  testApp : TIdeTesterConsoleRunner;
begin
  RegisterTests;
  if IsRunningIDETests then
    RunIDETests
  else if (ParamStr(1) = '-ci') then
  begin
    testApp := TIdeTesterConsoleRunner.Create(nil);
    testApp.Initialize;
    testApp.Title := 'Markdown Tests';
    testApp.Run;
    testApp.Free;
  end
  else
  begin
    {$IFDEF MSWINDOWS} FreeConsole; {$ENDIF}
    Application.Initialize;
    Application.CreateForm(TTesterForm, TesterForm);
    TesterForm.caption := 'Markdown Tests';
    Application.Run;
    Application.Free;
  end;
end.

Update for changes to ide tester

program MarkdownTestProgram;

{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}

uses
  {$IFDEF MSWINDOWS} Windows, {$ENDIF}
  Interfaces, SysUtils, Forms, idetester_console,
  CommonTestBase, MarkdownDaringFireballTests, MarkdownCommonMarkTests, idetester_runtime, idetester_form;

{$R *.res}

procedure RegisterTests;
begin
  if not getCommandLineParam('mdRoot', MDTestRoot) then
    MDTestRoot := getCurrentDir;
  MarkdownDaringFireballTests.RegisterTests;
  MarkdownCommonMarkTests.RegisterTests;
end;

var
  testApp : TIdeTesterConsoleRunner;
begin
  RegisterTests;
  if IsRunningIDETests then
    RunIDETests
  else if (ParamStr(1) = '-ci') then
  begin
    testApp := TIdeTesterConsoleRunner.Create(nil);
    testApp.Initialize;
    testApp.Title := 'Markdown Tests';
    testApp.Run;
    testApp.Free;
  end
  else
  begin
    {$IFDEF MSWINDOWS} FreeConsole; {$ENDIF}
    Application.Initialize;
    Application.CreateForm(TIdeTesterForm, IdeTesterForm);
    IdeTesterForm.caption := 'Markdown Tests';
    Application.Run;
    Application.Free;
  end;
end.


function fib_(x: Integer; var fib_2: Integer): Integer;
var
    a, b, c, d: Integer;
begin
    if x = 0 then
     begin
        fib_  := 0;
        fib_2 := 1;
     end
    else
     begin
        a := fib_(x div 2, b);
        c := a * (2 * b - a);
        d := b * b + a * a;
        if x mod 2 = 0
         then begin
                 fib_  := c;
                 fib_2 := d;
              end
         else begin
                 fib_  := d;
                 fib_2 := c + d;
              end;
     end;
end;

function fib(x: Integer): Integer;
var
    y: Integer;
begin
    fib := fib_(x, y);
end;

var
    x: LongInt;
begin
    ReadLn(x);
    x := fib(x);
    WriteLn(x);
end.

Use LongInt in fibonacci test

function fib_(x: LongInt
    ; var fib_2: LongInt): LongInt;
var
    a, b, c, d: LongInt;
begin
    if x = 0 then
     begin
        fib_  := 0;
        fib_2 := 1;
     end
    else
     begin
        a := fib_(x div 2, b);
        c := a * (2 * b - a);
        d := b * b + a * a;
        if x mod 2 = 0
         then begin
                 fib_  := c;
                 fib_2 := d;
              end
         else begin
                 fib_  := d;
                 fib_2 := c + d;
              end;
     end;
end;

function fib(x: LongInt): LongInt;
var
    y: LongInt;
begin
    fib := fib_(x, y);
end;

var
    x: LongInt;
begin
    ReadLn(x);
    x := fib(x);
    WriteLn(x);
end.


object modWebHttpServer: TmodWebHttpServer
  OldCreateOrder = False
  OnCreate = DataModuleCreate
  OnDestroy = DataModuleDestroy
  Height = 150
  Width = 215
  object http: TIdHTTPServer
    Bindings = <>
    DefaultPort = 8008
    OnCommandGet = httpCommandGet
    Left = 88
    Top = 56
  end
end

Use keepalive to improve web server performance

object modWebHttpServer: TmodWebHttpServer
  OldCreateOrder = False
  OnCreate = DataModuleCreate
  OnDestroy = DataModuleDestroy
  Height = 150
  Width = 215
  object http: TIdHTTPServer
    Bindings = <>
    DefaultPort = 8008
    KeepAlive = True
    OnCommandGet = httpCommandGet
    Left = 88
    Top = 56
  end
end


Uses sysutils;

Var a : String;
    b : Double;
    c : Double;

begin
    read(a);
    read(b);
    read(c);

    WriteLn(Format('TOTAL = R$ %.2f', [b + round((c * 0.15) * 100) / 100]));
end.


program calcwords;

var
   longest : string;
   word	   : string;

procedure readword(var w :string );

begin
   w := '';
   while not eoln do
   begin
      w := w + input^;
      get(input);
   end;
   get(input);
end; { readword }

procedure toupper(var w	: string);
var
   i : integer;
begin
   for i := 1 to length(w) do
   begin
      if w[i] in ['a'..'z'] then
      begin
	 w[i] := chr(ord(w[i]) - 32);
      end;
   end;
end;

(* Check if word is valid in calculator characters *)
function check(var w :  string): boolean;

var
   i   : integer;
   len : integer;
   ok  : boolean;

begin
   i := 1;
   len := length(w);
   ok := true;
   toupper(w);
   while (i < len) and ok do
   begin
      if not (w[i] in ['B', 'E', 'G', 'H', 'I', 'L', 'O', 'S', 'Z']) then
      begin
	 ok := false;
      end;
      i := i + 1;
   end;
   check := ok;
end; { check }

begin
   longest := '';
   while not eof do
   begin
      readword(word);
      if check(word) then
      begin
	 if length(word) > length(longest) then
	    longest := word;
      end;
   end;
   writeln('Longest word:', longest);
end.


unit ValidatorTypes;

interface
type
  TCLIParamRecord = record
    ScriptFile:  string;
    GraphicMode,
    Help,
    AllMaps,
    Campaign,
    Version,
    Verbose:     Boolean;
  end;

implementation
end.


unit UBackGround_FPC;

interface

uses
  IniFiles, DefineUi;

type
  TBackGround = class
    Image     : string;
    constructor Create(aDefault : TBackground);
    procedure   LoadIni(iniFile : TMemIniFile;
                        const section, prefixe : string;
                        defaultStyle : TBackStyle = bsDefaultTexture);
    procedure   SaveIni(iniFile : TMemIniFile;
                        const section, prefixe : string);
  end;

implementation

constructor TBackground.Create(aDefault : TBackground);
begin
  assert(False)
end;

procedure TBackground.LoadIni(iniFile : TMemIniFile;
                              const section, prefixe : string;
                              defaultStyle : TBackStyle = bsDefaultTexture);
begin
end;

procedure TBackground.SaveIni(iniFile : TMemIniFile;
                              const section, prefixe : string);
begin
end;

end.


Program Run;

Uses
  SysUtils,
  Windows,
  ShellApi;

{ $R *.RES}

Const Exts='js;vbs;bat;cmd;lnk;url';

Procedure runLink;
Var
  X, R: String;
  i: Integer;
Begin
  R:=Exts;
  Repeat
   i:=Pos(';', R);
   if 0=i Then i:=1+Length(R);
   X:=ChangeFileExt(ParamStr(0), '.'+Copy(R, 1, i-1));
   if FileExists(X) Then
   Begin
    ShellExecute(0, Nil, PChar(X), Nil, Nil, sw_Show);
    Exit;
   End;
   R:=Copy(R, i+1, Length(R));
  Until Length(R)=0;
End;

Begin
 runLink;
End.


Add bublesort program that repeats itself 10 times

program bubble;
var arr : array [1..10000] of integer;
var n, i, j : integer;
var tmp : integer;
var sorted: boolean;
var swaps : integer;
var runs : integer;
begin
{run the program 10 times}

writeln('Running the program 10 times...');

for runs := 1 to 10 do
begin

n := 10000;
swaps := 0;
{ generate array }

for i:= 1 to n do
begin
	arr[i] := n - i;
end;

{bubble sort}

for i:=2 to n do
begin
	for j:=n downto i do
	begin
		if arr[j] < arr[j-1] then
		begin
			tmp := arr[j];
			arr[j] := arr[j-1];
			arr[j-1] := tmp;
			swaps:=swaps+1;
		end;
	end;
end;

{ check if array is sorted }
sorted := true;

for i:= 1 to n-1 do
begin
	if arr[i] > arr[i+1] then
	begin
		sorted:=false;
	end;
end;

writeln('Array sorted: ', sorted);
writeln('Swaps needed: ', swaps);

{end for runs:=1}
end;

end.


const x=20;
var y, z, a: integer;

function xel(var arg1, arg2: integer): integer;
begin
    z := 2;
	arg1 := arg1 + arg2 + x
end;

begin
    y := 10;
    z := 9;
    a := xel(y, z);
    if y = 32 then
        write("reference argument 3 success.")
    else
        write("reference argument 3 failed.", a)
    ;
end.


Uses sysutils;

Var n : Double;

begin
   read(n);

   WriteLn(Format('A=%.4f', [n * n * 3.14159]));
end.


Uses sysutils;

Var a : Double;
    b : Double;

begin
   read(a);
   read(b);

   WriteLn(Format('MEDIA = %.5f', [(a * 3.5 + b * 7.5) / 11.0]));
end.


use "term"
use "promises"

class Handler is ReadlineNotify
  let _commands: Array[String] = _commands.create()
  var _i: U64 = 0

  new create() =>
    _commands.push("quit")
    _commands.push("happy")
    _commands.push("hello")

  fun ref apply(line: String, prompt: Promise[String]) =>
    if line == "quit" then
      prompt.reject()
    else
      _i = _i + 1
      prompt(_i.string() + " > ")
    end

  fun ref tab(line: String): Seq[String] box =>
    let r = Array[String]

    for command in _commands.values() do
      if command.at(line, 0) then
        r.push(command)
      end
    end

    r

actor Main
  new create(env: Env) =>
    env.out.print("Use 'quit' to exit.")

    // Building a delegate manually
    let term = ANSITerm(Readline(recover Handler end, env.out), env.input)
    term.prompt("0 > ")

    let notify = object iso
      let term: ANSITerm = term
      fun ref apply(data: Array[U8] iso) => term(consume data)
      fun ref dispose() => term.dispose()
    end

    env.input(consume notify)

Store command history in Readline example

use "term"
use "promises"

class Handler is ReadlineNotify
  let _commands: Array[String] = _commands.create()
  var _i: U64 = 0

  new create() =>
    _commands.push("quit")
    _commands.push("happy")
    _commands.push("hello")

  fun ref apply(line: String, prompt: Promise[String]) =>
    if line == "quit" then
      prompt.reject()
    else
      _i = _i + 1
      prompt(_i.string() + " > ")
    end
    _update_commands(line)

  fun ref _update_commands(line: String) =>
    for command in _commands.values() do
      if command.at(line, 0) then
        return
      end
    end

    _commands.push(line)

  fun ref tab(line: String): Seq[String] box =>
    let r = Array[String]

    for command in _commands.values() do
      if command.at(line, 0) then
        r.push(command)
      end
    end

    r

actor Main
  new create(env: Env) =>
    env.out.print("Use 'quit' to exit.")

    // Building a delegate manually
    let term = ANSITerm(Readline(recover Handler end, env.out), env.input)
    term.prompt("0 > ")

    let notify = object iso
      let term: ANSITerm = term
      fun ref apply(data: Array[U8] iso) => term(consume data)
      fun ref dispose() => term.dispose()
    end

    env.input(consume notify)


primitive Platform
  fun freebsd(): Bool => compile_intrinsic
  fun linux(): Bool => compile_intrinsic
  fun osx(): Bool => compile_intrinsic
  fun posix(): Bool => freebsd() or linux() or osx()
  fun windows(): Bool => compile_intrinsic

  fun x86(): Bool => compile_intrinsic
  fun arm(): Bool => compile_intrinsic

  fun lp64(): Bool => compile_intrinsic
  fun llp64(): Bool => compile_intrinsic
  fun ilp32(): Bool => compile_intrinsic

  fun native128(): Bool => compile_intrinsic
  fun debug(): Bool => compile_intrinsic

Add documentation for the builtin package

"""
# Builtin package

The builtin package is home to standard library members that require compiler
support. For details on specific packages, see their individual entity entries.
"""
primitive Platform
  fun freebsd(): Bool => compile_intrinsic
  fun linux(): Bool => compile_intrinsic
  fun osx(): Bool => compile_intrinsic
  fun posix(): Bool => freebsd() or linux() or osx()
  fun windows(): Bool => compile_intrinsic

  fun x86(): Bool => compile_intrinsic
  fun arm(): Bool => compile_intrinsic

  fun lp64(): Bool => compile_intrinsic
  fun llp64(): Bool => compile_intrinsic
  fun ilp32(): Bool => compile_intrinsic

  fun native128(): Bool => compile_intrinsic
  fun debug(): Bool => compile_intrinsic


use "json"
use "debug"

interface BundleDep
  fun root_path(): String
  fun packages_path(): String
  fun ref fetch()?

primitive BundleDepFactory
  fun apply(bundle: Bundle, dep: JsonObject box): BundleDep? =>
    match dep.data("type")
    | "github" => BundleDepGitHub(bundle, dep)
    else error
    end

class BundleDepGitHub
  let bundle: Bundle
  let info: JsonObject box
  let repo: String
  let subdir: String
  let git_tag: (String | None)
  new create(b: Bundle, i: JsonObject box)? =>
    bundle = b
    info   = i
    repo   = try info.data("repo") as String
             else bundle.log("No 'repo' key in dep: " + info.string()); error
             end
    subdir = try info.data("subdir") as String
             else ""
             end
    git_tag = try info.data("tag") as String
              else None
              end

  fun root_path(): String => ".deps/" + repo
  fun packages_path(): String => root_path() + "/" + subdir
  fun url(): String => "https://github.com/" + repo

  fun ref fetch()? =>
    try Shell("test -d "+root_path())
      Shell("git -C "+root_path()+" pull")
    else
      Shell("mkdir -p "+root_path())
      Shell("git clone "+url()+" "+root_path())
    end
    _checkout_tag()

  fun _checkout_tag() ? =>
    if git_tag isnt None then
      Shell("cd " + root_path() + " && git checkout " + (git_tag as String))
    end

Fix `stable fetch` bug when using tags

use "json"
use "debug"

interface BundleDep
  fun root_path(): String
  fun packages_path(): String
  fun ref fetch()?

primitive BundleDepFactory
  fun apply(bundle: Bundle, dep: JsonObject box): BundleDep? =>
    match dep.data("type")
    | "github" => BundleDepGitHub(bundle, dep)
    else error
    end

class BundleDepGitHub
  let bundle: Bundle
  let info: JsonObject box
  let repo: String
  let subdir: String
  let git_tag: (String | None)
  new create(b: Bundle, i: JsonObject box)? =>
    bundle = b
    info   = i
    repo   = try info.data("repo") as String
             else bundle.log("No 'repo' key in dep: " + info.string()); error
             end
    subdir = try info.data("subdir") as String
             else ""
             end
    git_tag = try info.data("tag") as String
              else None
              end

  fun root_path(): String => ".deps/" + repo
  fun packages_path(): String => root_path() + "/" + subdir
  fun url(): String => "https://github.com/" + repo

  fun ref fetch()? =>
    try Shell("test -d "+root_path())
      Shell("git -C "+root_path()+" pull "+url())
    else
      Shell("mkdir -p "+root_path())
      Shell("git clone "+url()+" "+root_path())
    end
    _checkout_tag()

  fun _checkout_tag() ? =>
    if git_tag isnt None then
      Shell("cd " + root_path() + " && git checkout " + (git_tag as String))
    end


actor Main
  new create(env: Env) =>
    try foo(true) end

  fun ref foo(a: Bool): U64 ? =>
    // works
    // match a
    // | true => return 1
    // else
    //   error
    // end

    // works
    // if a then
    //   return 1
    // else
    //   error
    // end

    // internal error
    //while a do
    //  return 1
    //else
    //  error
    //end

    // internal error
    // repeat
    //   return 1
    // until
    //   a
    // else
    //   error
    // end

    // works
    // try
    //   if a then
    //     return 1
    //   else
    //     error
    //   end
    // else
    //   error
    // end

Stop the CI build failing

actor Main
  new create(env: Env) =>
    try foo(true) end

  fun ref foo(a: Bool): U64 ? =>
    // works
    // match a
    // | true => return 1
    // else
    //   error
    // end

    // works
    // if a then
    //   return 1
    // else
    //   error
    // end

    // internal error
    //while a do
    //  return 1
    //else
    //  error
    //end

    // internal error
    // repeat
    //   return 1
    // until
    //   a
    // else
    //   error
    // end

    // works
    // try
    //   if a then
    //     return 1
    //   else
    //     error
    //   end
    // else
    //   error
    // end

    error


use "ponytest"

actor Main

  new create(env: Env) =>
    var test = PonyTest(env)

    test(recover _LeapTest end)

    test.complete()

class _LeapTest iso is UnitTest

  fun name(): String => "leap/Leap"

  fun apply(h: TestHelper): TestResult =>
    h.expect_true(Leap(1996), "Testing a leap year")
    h.expect_false(Leap(1997), "Testing an odd year")
    h.expect_false(Leap(1998), "Testing a non-leap even year")
    h.expect_false(Leap(1900), "Testing a century")
    h.expect_true(Leap(2000), "Testing an exceptional century")

Make leap compatible with Pony 0.2.1

use "ponytest"

actor Main is TestList
  new create(env: Env) =>
    PonyTest(env, this)

  new make() =>
    None

  fun tag tests(test: PonyTest) =>
    test(_LeapTest)

class _LeapTest iso is UnitTest
  """
  Test Leap package
  """
  fun name(): String => "leap/Leap"

  fun apply(h: TestHelper): TestResult =>
    h.expect_true(Leap(1996), "Testing a leap year")
    h.expect_false(Leap(1997), "Testing an odd year")
    h.expect_false(Leap(1998), "Testing a non-leap even year")
    h.expect_false(Leap(1900), "Testing a century")
    h.expect_true(Leap(2000), "Testing an exceptional century")


use "ponytest"

actor Main is TestList
  new create(env: Env) =>
    PonyTest(env, this)

  new make() =>
    None

  fun tag tests(test: PonyTest) =>
    test(_LeapTest)

class _LeapTest iso is UnitTest
  """
  Test Leap package
  """
  fun name(): String => "leap/Leap"

  fun apply(h: TestHelper): TestResult =>
    // Note -> Current master-branch simplifies these functions to
    // assert_true/false, and removes expect
    // https://github.com/ponylang/ponyc/blob/master/packages/ponytest/helper.pony
    h.expect_true(Leap(1996), "Testing a leap year")
    h.expect_false(Leap(1997), "Testing an odd year")
    h.expect_false(Leap(1998), "Testing a non-leap even year")
    h.expect_false(Leap(1900), "Testing a century")
    h.expect_true(Leap(2000), "Testing an exceptional century")

Make leap compatible with Pony 0.7.0

use "ponytest"

actor Main is TestList
  new create(env: Env) =>
    PonyTest(env, this)

  new make() =>
    None

  fun tag tests(test: PonyTest) =>
    test(_LeapTest)

class iso _LeapTest is UnitTest
  """
  Test Leap package
  """
  fun name(): String => "leap/Leap"

  fun apply(h: TestHelper) =>
    // Note -> Current master-branch simplifies these functions to
    // assert_true/false, and removes expect
    // https://github.com/ponylang/ponyc/blob/master/packages/ponytest/helper.pony
    h.assert_true(Leap(1996), "Testing a leap year")
    h.assert_false(Leap(1997), "Testing an odd year")
    h.assert_false(Leap(1998), "Testing a non-leap even year")
    h.assert_false(Leap(1900), "Testing a century")
    h.assert_true(Leap(2000), "Testing an exceptional century")


use "json"
use "debug"

interface BundleDep
  fun root_path(): String
  fun packages_path(): String
  fun ref fetch()?

primitive BundleDepFactory
  fun apply(bundle: Bundle, dep: JsonObject box): BundleDep? =>
    match dep.data("type")
    | "github" => BundleDepGitHub(bundle, dep)
    else error
    end

class BundleDepGitHub
  let bundle: Bundle
  let info: JsonObject box
  let repo: String
  let subdir: String
  new create(b: Bundle, i: JsonObject box)? =>
    bundle = b
    info   = i
    repo   = try info.data("repo") as String
             else bundle.log("No 'repo' key in dep: " + info.string()); error
             end
    subdir = try info.data("subdir") as String
             else ""
             end

  fun root_path(): String => ".deps/" + repo
  fun packages_path(): String => root_path() + "/" + subdir
  fun url(): String => "https://github.com/" + repo

  fun ref fetch()? =>
    try Shell("test -d "+root_path())
      Shell("git -C "+root_path()+" pull")
    else
      Shell("mkdir -p "+root_path())
      Shell("git clone "+url()+" "+root_path())
    end

Support using specific github tags

use "json"
use "debug"

interface BundleDep
  fun root_path(): String
  fun packages_path(): String
  fun ref fetch()?

primitive BundleDepFactory
  fun apply(bundle: Bundle, dep: JsonObject box): BundleDep? =>
    match dep.data("type")
    | "github" => BundleDepGitHub(bundle, dep)
    else error
    end

class BundleDepGitHub
  let bundle: Bundle
  let info: JsonObject box
  let repo: String
  let subdir: String
  let git_tag: (String | None)
  new create(b: Bundle, i: JsonObject box)? =>
    bundle = b
    info   = i
    repo   = try info.data("repo") as String
             else bundle.log("No 'repo' key in dep: " + info.string()); error
             end
    subdir = try info.data("subdir") as String
             else ""
             end
    git_tag = try info.data("tag") as String
              else None
              end

  fun root_path(): String => ".deps/" + repo
  fun packages_path(): String => root_path() + "/" + subdir
  fun url(): String => "https://github.com/" + repo

  fun ref fetch()? =>
    try Shell("test -d "+root_path())
      Shell("git -C "+root_path()+" pull")
    else
      Shell("mkdir -p "+root_path())
      Shell("git clone "+url()+" "+root_path())
    end
    _checkout_tag()

  fun _checkout_tag() ? =>
    if git_tag isnt None then
      Shell("cd " + root_path() + " && git checkout " + (git_tag as String))
    end


use "ponytest"

actor Main is TestList
  new create(env: Env) =>
    PonyTest(env, this)

  new make() =>
    None

  fun tag tests(test: PonyTest) =>
    test(_TestHelloWorld)

class _TestHelloWorld iso is UnitTest
  """
  Test HelloWorld package
  """
  fun name(): String => "hello-world/HelloWorld"

  fun apply(h: TestHelper): TestResult =>
    let hello: HelloWorld = HelloWorld.create()

    h.expect_eq[String]("Hello, World!", hello.say_hello())
    h.expect_eq[String]("Hello, Exercism!", hello.say_hello("Exercism"))

Make hello-world compatible with Pony 0.7.0

use "ponytest"

actor Main is TestList
  new create(env: Env) =>
    PonyTest(env, this)

  new make() =>
    None

  fun tag tests(test: PonyTest) =>
    test(_TestHelloWorld)

class iso _TestHelloWorld is UnitTest
  """
  Test HelloWorld package
  """
  fun name(): String => "hello-world/HelloWorld"

  fun apply(h: TestHelper) =>
    let hello: HelloWorld = HelloWorld.create()

    h.assert_eq[String]("Hello, World!", hello.say_hello())
    h.assert_eq[String]("Hello, Exercism!", hello.say_hello("Exercism"))


use "json"
use "debug"

interface BundleDep
  fun path(): String
  fun ref fetch()?

primitive BundleDepFactory
  fun apply(bundle: Bundle, dep: JsonObject): BundleDep? =>
    match dep.data("type")
    | "github" => BundleDepGitHub(bundle, dep)
    else error
    end

class BundleDepGitHub
  let bundle: Bundle
  let info: JsonObject
  let repo: String
  new create(b: Bundle, i: JsonObject)? =>
    bundle = b; info = i
    repo = try info.data("repo") as String
           else bundle.log("No 'repo' key in dep: " + info.string()); error
           end

  fun path(): String => ".deps/" + repo
  fun url(): String => "https://github.com/" + repo

  fun ref fetch()? =>
    try Shell("test -d "+path())
      Shell("git --git-dir "+path()+"/.git pull")
    else
      Shell("mkdir -p "+path())
      Shell("git clone "+url()+" "+path())
    end

Fix form of git invocation in another directory.

use "json"
use "debug"

interface BundleDep
  fun path(): String
  fun ref fetch()?

primitive BundleDepFactory
  fun apply(bundle: Bundle, dep: JsonObject): BundleDep? =>
    match dep.data("type")
    | "github" => BundleDepGitHub(bundle, dep)
    else error
    end

class BundleDepGitHub
  let bundle: Bundle
  let info: JsonObject
  let repo: String
  new create(b: Bundle, i: JsonObject)? =>
    bundle = b; info = i
    repo = try info.data("repo") as String
           else bundle.log("No 'repo' key in dep: " + info.string()); error
           end

  fun path(): String => ".deps/" + repo
  fun url(): String => "https://github.com/" + repo

  fun ref fetch()? =>
    try Shell("test -d "+path())
      Shell("git -C "+path()+" pull")
    else
      Shell("mkdir -p "+path())
      Shell("git clone "+url()+" "+path())
    end


primitive LongTest
type TestResult is (Bool | LongTest)

trait UnitTest
  """
  Each unit test class must provide this trait. Simple tests only need to
  define the name() and apply() functions. The remaining functions specify
  additional test options.
  """

  fun name(): String
    """
    Report the test name, which is used when printing test results and on the
    command line to select tests to run.
    """

  fun exclusion_group(): String =>
    """
    Report the test exclusion group, returning an empty string for none.
    The default body returns an empty string.
    """
    ""

  fun ref apply(t: TestHelper): TestResult ?
    """
    Run the test.
    Return values:
    * true - test passed.
    * false - test failed.
    * LongTest - test needs to run for longer. See package doc string.
    * error - test failed.
    """

Add access to the environment for tests

primitive LongTest
type TestResult is (Bool | LongTest)

trait UnitTest
  """
  Each unit test class must provide this trait. Simple tests only need to
  define the name() and apply() functions. The remaining functions specify
  additional test options.
  """

  fun name(): String
    """
    Report the test name, which is used when printing test results and on the
    command line to select tests to run.
    """

  fun exclusion_group(): String =>
    """
    Report the test exclusion group, returning an empty string for none.
    The default body returns an empty string.
    """
    ""

  fun ref run(t: TestHelper, env: Env): TestResult ? =>
    """
    Run the test but with access to the environment.  See `apply()`.
    """
    this(t)

  fun ref apply(t: TestHelper): TestResult ?
    """
    Run the test.
    Return values:
    * true - test passed.
    * false - test failed.
    * LongTest - test needs to run for longer. See package doc string.
    * error - test failed.
    """


use "ponytest"

actor Main is TestList
  new create(env: Env) =>
    PonyTest(env, this)

  new make() =>
    None

  fun tag tests(test: PonyTest) =>
    test(_TestSquares)

class _TestSquares iso is UnitTest
  """
  Test Difference of Squares package
  """

  fun name(): String => "difference-of-squares/Squares"

  fun apply(h: TestHelper): TestResult =>
    h.expect_eq[U32](225, Squares(5).square_of_sums())
    h.expect_eq[U32](55, Squares(5).sum_of_squares())
    h.expect_eq[U32](170, Squares(5).difference())

    h.expect_eq[U32](3025, Squares(10).square_of_sums())
    h.expect_eq[U32](385, Squares(10).sum_of_squares())
    h.expect_eq[U32](2640, Squares(10).difference())

    h.expect_eq[U32](25502500, Squares(100).square_of_sums())
    h.expect_eq[U32](338350, Squares(100).sum_of_squares())
    h.expect_eq[U32](25164150, Squares(100).difference())

Make difference-of-squares compatible with pony 0.7.0

use "ponytest"

actor Main is TestList
  new create(env: Env) =>
    PonyTest(env, this)

  new make() =>
    None

  fun tag tests(test: PonyTest) =>
    test(_TestSquares)

class iso _TestSquares is UnitTest
  """
  Test Difference of Squares package
  """

  fun name(): String => "difference-of-squares/Squares"

  fun apply(h: TestHelper) =>
    h.assert_eq[U32](225, Squares(5).square_of_sums())
    h.assert_eq[U32](55, Squares(5).sum_of_squares())
    h.assert_eq[U32](170, Squares(5).difference())

    h.assert_eq[U32](3025, Squares(10).square_of_sums())
    h.assert_eq[U32](385, Squares(10).sum_of_squares())
    h.assert_eq[U32](2640, Squares(10).difference())

    h.assert_eq[U32](25502500, Squares(100).square_of_sums())
    h.assert_eq[U32](338350, Squares(100).sum_of_squares())
    h.assert_eq[U32](25164150, Squares(100).difference())


use "ponytest"

actor Main

  new create(env: Env) =>
    var test = PonyTest(env)

    test(recover _HammingTest end)

    test.complete()

class _HammingTest iso is UnitTest

  """
  Test Hamming package
  """

  fun name(): String => "hamming/Hamming"

  fun apply(h: TestHelper): TestResult ? =>

    h.expect_eq[U8](0, Hamming("A", "A"))
    h.expect_eq[U8](0, Hamming("GGACTGA", "GGACTGA"))
    h.expect_eq[U8](1, Hamming("A", "G"))
    h.expect_eq[U8](2, Hamming("AG", "CT"))
    h.expect_eq[U8](1, Hamming("AT", "CT"))
    h.expect_eq[U8](1, Hamming("GGACG", "GGTCG"))
    h.expect_eq[U8](2, Hamming("ACCAGGG", "ACTATGG"))
    h.expect_eq[U8](1, Hamming("AGG", "AGA"))
    h.expect_eq[U8](4, Hamming("GATACA", "GCATAA"))
    h.expect_eq[U8](9, Hamming("GGACGGATTCTG", "AGGACGGATTCT"))
    h.expect_error(lambda()? => Hamming("AATG", "AAA") end)
    h.expect_error(lambda()? => Hamming("ATA", "AGTG") end)
    true

Make hamming compatible with Pony 0.2.1

use "ponytest"

actor Main is TestList
  new create(env: Env) =>
    PonyTest(env, this)

  new make() =>
    None

  fun tag tests(test: PonyTest) =>
    test(_HammingTest)

class _HammingTest iso is UnitTest
  """
  Test Hamming package
  """
  fun name(): String => "hamming/Hamming"

  fun apply(h: TestHelper): TestResult ? =>
    h.expect_eq[U8](0, Hamming("A", "A"))
    h.expect_eq[U8](0, Hamming("GGACTGA", "GGACTGA"))
    h.expect_eq[U8](1, Hamming("A", "G"))
    h.expect_eq[U8](2, Hamming("AG", "CT"))
    h.expect_eq[U8](1, Hamming("AT", "CT"))
    h.expect_eq[U8](1, Hamming("GGACG", "GGTCG"))
    h.expect_eq[U8](2, Hamming("ACCAGGG", "ACTATGG"))
    h.expect_eq[U8](1, Hamming("AGG", "AGA"))
    h.expect_eq[U8](4, Hamming("GATACA", "GCATAA"))
    h.expect_eq[U8](9, Hamming("GGACGGATTCTG", "AGGACGGATTCT"))
    h.expect_error(lambda()? => Hamming("AATG", "AAA") end)
    h.expect_error(lambda()? => Hamming("ATA", "AGTG") end)
    true


use "ponytest"

actor Main
  new create(env: Env) =>
    var test = PonyTest(env)

    test(recover _TestHelloWorld end)

    test.complete()

class _TestHelloWorld iso is UnitTest
  """
  Test HelloWorld package
  """
  fun name(): String => "hello-world/HelloWorld"

  fun apply(h: TestHelper): TestResult =>
    let hello: HelloWorld = HelloWorld.create()

    h.expect_eq[String]("Hello, World!", hello.say_hello())
    h.expect_eq[String]("Hello, Exercism!", hello.say_hello("Exercism!"))
    true

Make Hello world compatible with Pony 0.2.1

use "ponytest"

actor Main is TestList
  new create(env: Env) =>
    PonyTest(env, this)

  new make() =>
    None

  fun tag tests(test: PonyTest) =>
    test(_TestHelloWorld)

class _TestHelloWorld iso is UnitTest
  """
  Test HelloWorld package
  """
  fun name(): String => "hello-world/HelloWorld"

  fun apply(h: TestHelper) : TestResult =>
    let hello: HelloWorld = HelloWorld.create()

    h.expect_eq[String]("Hello, World!", hello.say_hello())
    h.expect_eq[String]("Hello, Exercism!", hello.say_hello("Exercism!"))
    true


class Notify is StdinNotify
  let _env: Env

  new iso create(env: Env) =>
    _env = env

  fun ref apply(data: Array[U8] iso) =>
    let data' = consume val data

    for c in data'.values() do
      _env.out.write(c.string(IntHex))
    end

    _env.out.write("\n")

actor Main
  new create(env: Env) =>
    env.input(Notify(env))

Fix missed builtin name change

class Notify is StdinNotify
  let _env: Env

  new iso create(env: Env) =>
    _env = env

  fun ref apply(data: Array[U8] iso) =>
    let data' = consume val data

    for c in data'.values() do
      _env.out.write(c.string(FormatHex))
    end

    _env.out.write("\n")

actor Main
  new create(env: Env) =>
    env.input(Notify(env))


use "collections"

actor Mailer
  be ping(receiver: Main, pass: U32) =>
    for i in Range[U32](0, pass) do
      receiver.pong()
    end

actor Main
  var _env: Env
  var _size: U32 = 3
  var _pass: U32 = 0
  var _pongs: U64 = 0

  new create(env: Env) =>
    _env = env

    try
      parse_args()
      start_messaging()
    else
      usage()
    end

  be pong() =>
    _pongs = _pongs + 1

  fun ref start_messaging() =>
    for i in Range[U32](0, _size) do
      Mailer.ping(this, _pass)
    end

  fun ref parse_args() ? =>
    _size = _env.args(1).u32()
    _pass = _env.args(2).u32()

  fun ref usage() =>
    _env.out.print(
      """
      mailbox OPTIONS
        N   number of sending actors
        M   number of messages to pass from each sender to the receiver
      """
      )

Add explanation to Mailbox example

"""
This example is a stress test of Pony messaging and mailbox usage.
All X Mailers send to a single actor, Main, attempting to overload it's
mailbox. This is a degenerate condition, the more actors you have sending
to Main (and the more messages they send), the more memory will be used.

Run this and watch the process memory usage grow as actor Main gets swamped.

Also note, it finishes reasonably quickly for how many messages that single
actor ends up processing.
"""
use "collections"

actor Mailer
  be ping(receiver: Main, pass: U32) =>
    for i in Range[U32](0, pass) do
      receiver.pong()
    end

actor Main
  var _env: Env
  var _size: U32 = 3
  var _pass: U32 = 0
  var _pongs: U64 = 0

  new create(env: Env) =>
    _env = env

    try
      parse_args()
      start_messaging()
    else
      usage()
    end

  be pong() =>
    _pongs = _pongs + 1

  fun ref start_messaging() =>
    for i in Range[U32](0, _size) do
      Mailer.ping(this, _pass)
    end

  fun ref parse_args() ? =>
    _size = _env.args(1).u32()
    _pass = _env.args(2).u32()

  fun ref usage() =>
    _env.out.print(
      """
      mailbox OPTIONS
        N   number of sending actors
        M   number of messages to pass from each sender to the receiver
      """
      )


use "ponytest"

actor Main

  new create(env: Env) =>
    var test = PonyTest(env)

    test(recover _TestSquares end)

    test.complete()

class _TestSquares iso is UnitTest
  """
  Test Difference of Squares package
  """

  fun name(): String => "difference=of-squares/Squares"

  fun apply(h: TestHelper): TestResult =>
    h.expect_eq[U32](225, Squares(5).square_of_sums())
    h.expect_eq[U32](55, Squares(5).sum_of_squares())
    h.expect_eq[U32](170, Squares(5).difference())

    h.expect_eq[U32](3025, Squares(10).square_of_sums())
    h.expect_eq[U32](385, Squares(10).sum_of_squares())
    h.expect_eq[U32](2640, Squares(10).difference())

    h.expect_eq[U32](25502500, Squares(100).square_of_sums())
    h.expect_eq[U32](338350, Squares(100).sum_of_squares())
    h.expect_eq[U32](25164150, Squares(100).difference())
    true

Make difference of squares compatible with Pony 0.2.1

use "ponytest"

actor Main is TestList
  new create(env: Env) =>
    PonyTest(env, this)

  new make() =>
    None

  fun tag tests(test: PonyTest) =>
    test(_TestSquares)

class _TestSquares iso is UnitTest
  """
  Test Difference of Squares package
  """

  fun name(): String => "difference=of-squares/Squares"

  fun apply(h: TestHelper): TestResult =>
    h.expect_eq[U32](225, Squares(5).square_of_sums())
    h.expect_eq[U32](55, Squares(5).sum_of_squares())
    h.expect_eq[U32](170, Squares(5).difference())

    h.expect_eq[U32](3025, Squares(10).square_of_sums())
    h.expect_eq[U32](385, Squares(10).sum_of_squares())
    h.expect_eq[U32](2640, Squares(10).difference())

    h.expect_eq[U32](25502500, Squares(100).square_of_sums())
    h.expect_eq[U32](338350, Squares(100).sum_of_squares())
    h.expect_eq[U32](25164150, Squares(100).difference())
    true


@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:  <http://www.w3.org/2002/07/owl#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
@prefix dct:  <http://purl.org/dc/terms/> .
@prefix dc:   <http://purl.org/dc/elements/1.1/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix version:  <http://purl.org/linked-data/version#> .
@prefix ldp:  <http://www.w3.org/ns/ldp#> .
@prefix ssd:  <http://www.w3.org/ns/sparql-service-description#> .
@prefix vs:   <http://www.w3.org/2003/06/sw-vocab-status/ns#> .
@prefix void: <http://rdfs.org/ns/void#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix reg:  <http://purl.org/linked-data/registry#> .
@prefix er-ui:  <http://environment.data.gov.uk/registry/structure/ui/> .
@prefix er-cat:  <http://environment.data.gov.uk/registry/structure/category/> .
@prefix er-org:  <http://environment.data.gov.uk/registry/structure/org/> .
@prefix er-entity:  <http://environment.data.gov.uk/registry/structure/entity-type/> .

<monitor> a reg:Register;
    rdfs:label "Monitored Registers"@en;
    dct:description "A system register which lists the registers which should be monitored to trigger notifications."@en;
    reg:category  er-cat:System;
    .


@prefix : <http://example/> .
@prefix xsd:     <http://www.w3.org/2001/XMLSchema#> .

:s :p 1 , 2 .

:x1 :q ("a"^^xsd:string "b"^^xsd:string) .

:s1 :b :a .
:s2 :b :a .

:s3 :b1 _:aa .
:s2 :b2 _:aa .

:x2 :q [ :r 4.5 ] .

Align to production of simple literals, not xsd:string


@prefix owl:                    <http://www.w3.org/2002/07/owl#> .
@prefix ogit.Version:           <http://www.purl.org/ogit/Version/> .
@prefix ogit:                   <http://www.purl.org/ogit/> .
@prefix ogit.SaaS:              <http://www.purl.org/ogit/SaaS/> .
@prefix rdfs:                   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms:                <http://purl.org/dc/terms/> .

ogit.SaaS:IntegrationType
	a rdfs:Class;
	rdfs:subClassOf ogit:Entity;
	rdfs:label "IntegrationType";
	dcterms:description "Type of HIRO integration. Used for defining required configurations.";
	dcterms:valid "start=2021-05-18;";
	dcterms:creator "dcassidy@arago.co";
	ogit:scope "NTO";
	ogit:parent "http://www.purl.org/ogit/Node";
	ogit:mandatory-attributes (
		ogit:name
	);
	ogit:optional-attributes (
		ogit:description
	);
	ogit:indexed-attributes (
		ogit:name
	);
	ogit:allowed (
	);
.

Allow attachments for integration types, e.g. for storing an integration logo.

@prefix owl:                    <http://www.w3.org/2002/07/owl#> .
@prefix ogit.Version:           <http://www.purl.org/ogit/Version/> .
@prefix ogit:                   <http://www.purl.org/ogit/> .
@prefix ogit.SaaS:              <http://www.purl.org/ogit/SaaS/> .
@prefix rdfs:                   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms:                <http://purl.org/dc/terms/> .

ogit.SaaS:IntegrationType
	a rdfs:Class;
	rdfs:subClassOf ogit:Entity;
	rdfs:label "IntegrationType";
	dcterms:description "Type of HIRO integration. Used for defining required configurations.";
	dcterms:valid "start=2021-05-18;";
	dcterms:creator "dcassidy@arago.co";
	ogit:scope "NTO";
	ogit:parent "http://www.purl.org/ogit/Node";
	ogit:mandatory-attributes (
		ogit:name
	);
	ogit:optional-attributes (
		ogit:description
	);
	ogit:indexed-attributes (
		ogit:name
	);
	ogit:allowed (
		[ ogit:has ogit:Attachment ]
	);
.


@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix em:   <http://www.mozilla.org/2004/em-rdf#>.

<urn:mozilla:install-manifest>
	em:id "GECKOID";
	em:version "VERSION";
	em:type "2";
	em:targetApplication [
		em:id "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
		em:minVersion "3.0";
		em:maxVersion "9.*"
	] ;
	em:name "SimplyRead";
	em:description "Removes distractions from webpages. Press Ctrl-Alt-r or press the 'sr' button in the addons bar to toggle SimplyRead.";
	em:creator "Nick White";
	em:homepageURL "WEBSITE/";
	em:updateURL "WEBSITE/gecko-updates.rdf";
	em:updateKey "PUBKEY";
	<http://usefulinc.com/ns/doap#license> <http://www.gnu.org/licenses/agpl.html>.

Mark as compatible with firefox 10.*

@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix em:   <http://www.mozilla.org/2004/em-rdf#>.

<urn:mozilla:install-manifest>
	em:id "GECKOID";
	em:version "VERSION";
	em:type "2";
	em:targetApplication [
		em:id "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
		em:minVersion "3.0";
		em:maxVersion "10.*"
	] ;
	em:name "SimplyRead";
	em:description "Removes distractions from webpages. Press Ctrl-Alt-r or press the 'sr' button in the addons bar to toggle SimplyRead.";
	em:creator "Nick White";
	em:homepageURL "WEBSITE/";
	em:updateURL "WEBSITE/gecko-updates.rdf";
	em:updateKey "PUBKEY";
	<http://usefulinc.com/ns/doap#license> <http://www.gnu.org/licenses/agpl.html>.


@prefix : <http://www.networkedplanet.com/people/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

:alice a foaf:Person ;
	foaf:name "Alice" ;
	foaf:mbox "alice@example.org" ;
	foaf:knows :bob .

:bob a foaf:Person ;
	foaf:name "Bob" ;
	foaf:mbox "bob@example.org" ;
	foaf:knows :alice .

Fix for unit test failure

@prefix : <http://www.networkedplanet.com/people/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

:alice a foaf:Person ;
	foaf:name "Alice"^^<http://www.w3.org/2001/XMLSchema#string> ;
	foaf:mbox "alice@example.org"^^<http://www.w3.org/2001/XMLSchema#string> ;
	foaf:knows :bob .

:bob a foaf:Person ;
	foaf:name "Bob"^^<http://www.w3.org/2001/XMLSchema#string> ;
	foaf:mbox "bob@example.org"^^<http://www.w3.org/2001/XMLSchema#string> ;
	foaf:knows :alice .


@base <http://rinfo.lagrummet.se/sys/2011/api> .

@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:     <http://www.w3.org/2002/07/owl#> .
@prefix xsd:     <http://www.w3.org/2001/XMLSchema#> .
@prefix foaf:    <http://xmlns.com/foaf/0.1/> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix rpubl: <http://rinfo.lagrummet.se/ns/2008/11/rinfo/publ#> .
@prefix :     <http://purl.org/linked-data/api/vocab#> .

<#> a :API;
    rdfs:label "RInfo Linked Data API"@en;
    :maxPageSize "50";
    :defaultPageSize "10";
    :defaultLang "sv";
    :endpoint
        [ a :ItemEndpoint;
            :uriTemplate "/publ/{a}/{b}";
            :itemTemplate "http://rinfo.lagrummet.se/publ/{a}/{b}";
            :viewer <#rpublViewer>
        ],
        [ a :ItemEndpoint;
            :uriTemplate "/publ/{a}/{b}/{c}";
            :itemTemplate "http://rinfo.lagrummet.se/publ/{a}/{b}/{c}";
            :viewer <#rpublViewer>
        ],
        [ a :ListEndpoint;
            :uriTemplate "/publishers";
            :selector [
                :where "?item a foaf:Organization"
            ]
        ],
        [ a :ListEndpoint;
            :uriTemplate "/by-publisher/{publisher}";
            :selector [
                    :parent <#publishersEndpoint>;
                    :filter "publisher={publisher}"
                ]
        ];
    :sparqlEndpoint <http://localhost:8080/openrdf-sesame/repositories/rinfo>;
    :defaultViewer :describeViewer .

<#rpublViewer> a :Viewer;
    :name "rinfo doc viewer";
    :property (rpubl:paragraf rpubl:paragrafnummer);
    :property (rpubl:andrar dct:identifier);
    :property (rpubl:upphaver dct:identifier);
    #:properties "identifier,andrar.identifier,upphaver.identifier";
    :include :describeViewer .

rdf:type a owl:ObjectProperty; :label "type" .


Document the first quote from the Brass Plates

# a namespace for referencing particular passages of scripture
# as QNames.  These URLs redirect to scriptures.lds.org to provide
# the content of the scripture passage.  Unfortunately, the
# native URI scheme of that site can't be specified with QNames
# because they contain '/' characters.
@prefix sc: <http://scriptures.ndrix.org/> .

# a namespace for describing relationships related to study of the
# Brass Plates
@prefix bp: <http://plates.ndrix.org/ns/> .

[]
    bp:quoted_in
        sc:en.1_ne.22.24,
        sc:en.3_ne.25.2,
        sc:en.mal.4.2;
    bp:text
        "grow up as calves of the stall"
.


#
# Sesame configuration for a callimachus repository
#
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix rep: <http://www.openrdf.org/config/repository#>.
@prefix sr: <http://www.openrdf.org/config/repository/sail#>.
@prefix sail: <http://www.openrdf.org/config/sail#>.
@prefix ns: <http://www.openrdf.org/config/sail/native#>.
@prefix audit: <http://www.openrdf.org/config/sail/auditing#>.

[] a rep:Repository ;
   rep:repositoryID "callimachus" ;
   rdfs:label "Callimachus Repository" ;
   rep:repositoryImpl [
      rep:repositoryType "openrdf:OptimisticRepository" ;
      sr:sailImpl [
         sail:sailType "openrdf:AuditingSail" ;
         audit:archiving false ;
         audit:maximumArchiveTriples 100 ;
         audit:minimumRecentTransactions 100 ;
         audit:maximumRecentTransactions 1000 ;
         sail:delegate [
            sail:sailType "openrdf:NativeStore" ;
            ns:tripleIndexes "spoc,posc,cspo"
         ]
      ]
   ].

Add object index to store config

#
# Sesame configuration for a callimachus repository
#
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix rep: <http://www.openrdf.org/config/repository#>.
@prefix sr: <http://www.openrdf.org/config/repository/sail#>.
@prefix sail: <http://www.openrdf.org/config/sail#>.
@prefix ns: <http://www.openrdf.org/config/sail/native#>.
@prefix audit: <http://www.openrdf.org/config/sail/auditing#>.

[] a rep:Repository ;
   rep:repositoryID "callimachus" ;
   rdfs:label "Callimachus Repository" ;
   rep:repositoryImpl [
      rep:repositoryType "openrdf:OptimisticRepository" ;
      sr:sailImpl [
         sail:sailType "openrdf:AuditingSail" ;
         audit:archiving false ;
         audit:maximumArchiveTriples 100 ;
         audit:minimumRecentTransactions 100 ;
         audit:maximumRecentTransactions 1000 ;
         sail:delegate [
            sail:sailType "openrdf:NativeStore" ;
            ns:tripleIndexes "spoc,pocs,oscp,cspo"
         ]
      ]
   ].


@prefix ogit:                   <http://www.purl.org/ogit/> .
@prefix rdfs:                   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms:                <http://purl.org/dc/terms/> .

ogit:Subscription
	a rdfs:Class;
	rdfs:subClassOf ogit:Entity;
	rdfs:label "Subscription";
	dcterms:description "A Subscription to an Event.";
	# For ranges, see http://dublincore.org/documents/dcmi-period/
	dcterms:valid "start=2018-03-22;";
	dcterms:creator "qikram@arago.de";
	ogit:scope "SGO";
	ogit:parent "http://www.purl.org/ogit/Node";
	ogit:mandatory-attributes (
	);
	ogit:optional-attributes (
		ogit:status
		ogit:type
		ogit:sourceId
	);
	ogit:indexed-attributes (

	);
.

Store the application name in subscriptions

@prefix ogit:                   <http://www.purl.org/ogit/> .
@prefix rdfs:                   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms:                <http://purl.org/dc/terms/> .

ogit:Subscription
	a rdfs:Class;
	rdfs:subClassOf ogit:Entity;
	rdfs:label "Subscription";
	dcterms:description "A Subscription to an Event.";
	# For ranges, see http://dublincore.org/documents/dcmi-period/
	dcterms:valid "start=2018-03-22;";
	dcterms:creator "qikram@arago.de";
	ogit:scope "SGO";
	ogit:parent "http://www.purl.org/ogit/Node";
	ogit:mandatory-attributes (
	);
	ogit:optional-attributes (
		ogit:status
		ogit:type
		ogit:sourceId
		ogit:application
	);
	ogit:indexed-attributes (

	);
.


Add a file with usefaul default vocabulary annotations

# This file contains default vocabulary annotations for Pubby.
# The annotations allow Pubby to display resources in a more
# friendly way. It should be loaded from the main config.ttl
# file:
#
#     <> conf:loadVocabulary <vocabulary-annotations.ttl>.

@prefix conf: <http://richard.cyganiak.de/2007/pubby/config.rdf#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix void:     <http://rdfs.org/ns/void#> .

rdf:type conf:weight -100.
skos:prefLabel conf:weight -85.
rdfs:label conf:weight -80.
dc:title conf:weight -79.
dcterms:title conf:weight -79.
skos:altLabel conf:weight -75.
rdfs:comment conf:weight -50.
dcterms:identifier conf:weight -20.
skos:notation conf:weight -20.
rdfs:subPropertyOf conf:weight -15.
rdfs:subClassOf conf:weight -15.
rdfs:isDefinedBy conf:weight -12.
void:dataDump conf:weight -10.
void:sparqlEndpoint conf:weight -10.
void:subset conf:weight 10.


@prefix wresultlist:  <http://wellcomecollection.org/ontologies/resultlist/> .
@prefix xsd:          <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:          <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix dcterms:      <http://purl.org/dc/terms/> .
@prefix owl:          <http://www.w3.org/2002/07/owl#> .
@prefix rdfs:         <http://www.w3.org/2000/01/rdf-schema#> .

<http://wellcomecollection.org/ontologies/resultlist>
    rdf:type owl:Ontology ;
    dcterms:title "Result list ontology"@en ;
    dcterms:created "2017-11-07"^^xsd:date ;
    dcterms:description "Ontology describing the properties of a result list"@en .

wresultlist:ResultList rdf:type owl:Class ;
    rdfs:label "Result list"@en ;
    rdfs:comment "A collection of works."@en ;
    rdf:isDefinedBy <http://wellcomecollection.org/ontologies/resultlist>

wresultlist:pageSize rdf:type owl:ObjectProperty ;
    rdfs:label "pageSize"@en ;
    rdfs:comment "The number of works in a single page of results."@en ;
    rdf:isDefinedBy <http://wellcomecollection.org/ontologies/resultlist>

wresultlist:totalPages rdf:type owl:ObjectProperty ;
    rdfs:label "totalPages"@en ;
    rdfs:comment "The number of pages in this set of results."@en ;
    rdf:isDefinedBy <http://wellcomecollection.org/ontologies/resultlist>

wresultlist:totalResults rdf:type owl:ObjectProperty ;
    rdfs:label "totalResults"@en ;
    rdfs:comment "The total number of works in this set of results."@en ;
    rdf:isDefinedBy <http://wellcomecollection.org/ontologies/resultlist>

wresultlist:results rdf:type owl:ObjectProperty ;
    rdfs:label "results"@en ;
    rdfs:comment "The works which are included in this set of results."@en ;
    rdf:isDefinedBy <http://wellcomecollection.org/ontologies/resultlist>


@prefix rr: <http://www.w3.org/ns/r2rml#>.
@prefix rml: <http://semweb.mmlab.be/ns/rml#>.
@prefix ex: <http://example.com/>.
@prefix ql: <http://semweb.mmlab.be/ns/ql#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<#SubjectMapping> a rr:TriplesMap;
	rml:logicalSource [
    	rml:source "simple2TestInput.json";
    	rml:referenceFormulation ql:JSONPath;
    	rml:iterator "$.Child"
  	];

  	rr:subjectMap [
    	rr:template "http://example.com/Child/{first}/{last}";
    	rr:class ex:Child;
    	rr:termType rr:BlankNode;
  	];

	rr:predicateObjectMap [
		rr:predicate ex:BSN;
		rr:constant "25"^^xsd:int;
	].

Fix simple blank node test mapping

@prefix rr: <http://www.w3.org/ns/r2rml#>.
@prefix rml: <http://semweb.mmlab.be/ns/rml#>.
@prefix ex: <http://example.com/>.
@prefix ql: <http://semweb.mmlab.be/ns/ql#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<#SubjectMapping> a rr:TriplesMap;
	rml:logicalSource [
    	rml:source "simple2TestInput.json";
    	rml:referenceFormulation ql:JSONPath;
    	rml:iterator "$.Child"
  	];

  	rr:subjectMap [
    	rr:template "http://example.com/Child/{first}/{last}";
    	rr:class ex:Child;
    	rr:termType rr:BlankNode;
  	];

	rr:predicateObjectMap [
		rr:predicate ex:BSN;
		rr:object "25"^^xsd:int;
	].


@prefix dcs: <http://ontologi.es/doap-changeset#> .
@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<http://drobilla.net/drobilla#me>
	a foaf:Person ;
	foaf:name "David Robillard" ;
	foaf:homepage <http://drobilla.net/> ;
	foaf:mbox <mailto:d@drobilla.net> ;
	rdfs:seeAlso <http://drobilla.net/drobilla> .

<http://lv2plug.in/ns/ext/dynmanifest>
	a doap:Project ;
	doap:license <http://opensource.org/licenses/isc-license> ;
	doap:name "LV2 Dynamic Manifest" ;
	doap:homepage <http://naspro.atheme.org> ;
	doap:created "2009-06-13" ;
	doap:shortdesc "An LV2-based specification for dynamic data generation." ;
	doap:programming-language "C" ;
	doap:developer [
		a foaf:Person ;
		foaf:name "Stefano D'Angelo"
	] ;
	doap:release [
		doap:revision "1.1" ;
		doap:created "2011-11-17" ;
		dcs:blame <http://drobilla.net/drobilla#me> ;
		dcs:changeset [
			dcs:item [
				rdfs:label "Improve documentation."
			]
		]
	] , [
		doap:revision "1.0" ;
		doap:created "2010-04-10" ;
		dcs:blame <http://drobilla.net/drobilla#me> ;
		dcs:changeset [
			dcs:item [
				rdfs:label "Initial packaging."
			]
		]
	] .


@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:  <http://www.w3.org/2002/07/owl#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
@prefix dct:  <http://purl.org/dc/terms/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix version:  <http://purl.org/linked-data/version#> .
@prefix ldp:  <http://www.w3.org/ns/ldp#> .
@prefix reg:  <http://purl.org/linked-data/registry#> .
@prefix ui:   <http://purl.org/linked-data/registry-ui#> .
@prefix dtr: <http://registry.it.csiro.au/ont/dtr#> .

<property> a ui:PathTemplate;
    rdfs:label "Includes property"@en;
    dct:description "UI template for finding dtr:property links"@en;
    ui:path "dtr:property";
    .


Add OnlineBusiness and OnlineStore as subtypes of Organization

@prefix : <https://schema.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

:OnlineBusiness a rdfs:Class ;
    rdfs:label "OnlineBusiness" ;
    :isPartOf <https://pending.schema.org> ;
    :source <https://github.com/schemaorg/schemaorg/issues/3028> ;
    rdfs:comment "A particular online business part of an organization. Examples include an eCommerce site, an online travel booking site, an online learning site, an online logistics and shipping provider, an online (virtual) doctor, etc." ;
    rdfs:subClassOf :Organization .

:OnlineStore a rdfs:Class ;
    rdfs:label "OnlineStore" ;
    :isPartOf <https://pending.schema.org> ;
    :source <https://github.com/schemaorg/schemaorg/issues/3028> ;
    rdfs:comment "An eCommerce site." ;
    rdfs:subClassOf :OnlineBusiness .


@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix weather: <http://vocab-ld.org/vocab/weather#> .
@prefix hydra: <http://www.w3.org/ns/hydra/core#> .
@prefix xhtml: <http://www.w3.org/1999/xhtml#> .
@prefix schema: <http://schema.org/> .

<summary.ttl>
    a weather:Summary ;
    hydra:freetextQuery "spring" ;
    xhtml:start <../index.ttl> ;
    weather:pickLocation <../search.ttl> .

weather:pickLocation
    a hydra:Link ;
    hydra:supportedOperation [
        a weather:PickLocationOperation ;
        hydra:title "Search for a location" ;
        hydra:expects weather:PickLocationForm ;
        hydra:returns weather:PickLocationState ;
        hydra:method "GET"
    ] .

weather:PickLocationForm
    a hydra:Class ;
    hydra:supportedProperty [
        a hydra:SupportedProperty ;
        hydra:property hydra:freetextQuery ;
        hydra:variable "q"
    ] .

Make the form query more accurate

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix weather: <http://vocab-ld.org/vocab/weather#> .
@prefix hydra: <http://www.w3.org/ns/hydra/core#> .
@prefix xhtml: <http://www.w3.org/1999/xhtml#> .
@prefix schema: <http://schema.org/> .

<summary.ttl>
    a weather:Summary ;
    hydra:freetextQuery "Springfield, IL" ;
    xhtml:start <../index.ttl> ;
    weather:pickLocation <../search.ttl> .

weather:pickLocation
    a hydra:Link ;
    hydra:supportedOperation [
        a weather:PickLocationOperation ;
        hydra:title "Search for a location" ;
        hydra:expects weather:PickLocationForm ;
        hydra:returns weather:PickLocationState ;
        hydra:method "GET"
    ] .

weather:PickLocationForm
    a hydra:Class ;
    hydra:supportedProperty [
        a hydra:SupportedProperty ;
        hydra:property hydra:freetextQuery ;
        hydra:variable "q"
    ] .


Add description file with DOAP and host-info information.

@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix hi:   <http://lv2plug.in/ns/dev/host-info#> .

<http://drobilla.net/software/ingen> a doap:Project, hi:Host ;
    doap:name "Ingen" ;
    doap:shortdesc "A modular audio processing environment." ;
    doap:homepage <http://drobilla.net/software/ingen/> ;
    doap:bug-database <http://dev.drobilla.net/> ;
    doap:license <http://usefulinc.com/doap/licenses/gpl> ;
    doap:developer [
        a foaf:Person ;
        foaf:homepage <http://drobilla.net/> ;
        foaf:mbox_sha1sum "253b3c58086250260bac1232d744d150274ad308" ;
        foaf:name "Dave Robillard"
    ] ;
    doap:programming-language "C", "C++" ;
    doap:repository [
        a doap:SVNRepository ;
        doap:browse <http://dev.drobilla.net/browser/trunk/ingen> ;
        doap:location <http://svn.drobilla.net/lad/trunk/ingen>
    ] ;
	hi:supportsExtension [
		hi:extension <http://lv2plug.in/ns/extensions/ui> ;
	] , [
		hi:extension <http://lv2plug.in/ns/ext/midi> ;
	] , [
		hi:extension <http://lv2plug.in/ns/dev/presets> ;
	] , [
		hi:extension <http://lv2plug.in/ns/ext/event> ;
	] ;
    doap:description """
A modular audio processing environment, where most functionality is provided
by generic plugins.  Patching of audio, MIDI, and control data is supported.
The engine and UI are completely separated in a network transparent way, making
it possible to run one or more GUIs on separate machines from the engine.

Ingen is closely based on LV2 plugin technology; Ingen patches are RDF
documents in Turtle in a very similar format to the RDF definition of an
LV2 plugin.
""" .


@prefix ogit.Procurement:     <http://www.purl.org/ogit/Procurement/> .
@prefix ogit:                   <http://www.purl.org/ogit/> .
@prefix rdfs:                   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms:                <http://purl.org/dc/terms/> .

ogit.Procurement:Invoice
  a rdfs:Class;
  rdfs:subClassOf ogit:Entity;
  rdfs:label "Invoice";
  dcterms:description "An invoice for a purchase order.";
  dcterms:valid "start=20221-01-27;";
  dcterms:creator "Marek Meyer";
  ogit:scope "NTO";
  ogit:parent ogit:Node;
  ogit:mandatory-attributes (
  );
  ogit:optional-attributes (
    ogit.Procurement:invoiceId
    ogit.Procurement:invoiceDate
    ogit:description
    ogit:name
  );
  ogit:indexed-attributes (
    ogit.Procurement:invoiceId
    ogit.Procurement:invoiceDate
    ogit:description
    ogit:name
  );
  ogit:allowed (
  );
.

Add relation between invoice and purchase order item.

@prefix ogit.Procurement:     <http://www.purl.org/ogit/Procurement/> .
@prefix ogit:                   <http://www.purl.org/ogit/> .
@prefix rdfs:                   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms:                <http://purl.org/dc/terms/> .

ogit.Procurement:Invoice
  a rdfs:Class;
  rdfs:subClassOf ogit:Entity;
  rdfs:label "Invoice";
  dcterms:description "An invoice for a purchase order.";
  dcterms:valid "start=20221-01-27;";
  dcterms:creator "Marek Meyer";
  ogit:scope "NTO";
  ogit:parent ogit:Node;
  ogit:mandatory-attributes (
  );
  ogit:optional-attributes (
    ogit.Procurement:invoiceId
    ogit.Procurement:invoiceDate
    ogit:description
    ogit:name
  );
  ogit:indexed-attributes (
    ogit.Procurement:invoiceId
    ogit.Procurement:invoiceDate
    ogit:description
    ogit:name
  );
  ogit:allowed (
	[ ogit:contains  ogit.Procurement:PurchaseOrderItem ]
  );
.


@prefix ogit.MARS.Machine:      <http://www.purl.org/ogit/MARS/Machine/> .
@prefix ogit:                   <http://www.purl.org/ogit/> .
@prefix owl:                    <http://www.w3.org/2002/07/owl#> .
@prefix rdfs:                   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms:                <http://purl.org/dc/terms/> .

ogit.MARS.Machine:cpuArch
	a owl:DatatypeProperty;
	rdfs:subPropertyOf ogit:Attribute;
	rdfs:label "Machine/cpuArch";
	dcterms:description "CPU architecture. the output onf 'uname -m' on UNIX like systems";
	# For ranges, see http://dublincore.org/documents/dcmi-period/
	dcterms:valid "start=2018-05-25;";
	dcterms:creator "fotto@arago.de";
	dcterms:created "2018-05-22";
	dcterms:modified "2018-05-22";
	ogit:admin-contact "arago GmbH";
	ogit:tech-contact "arago GmbH";
	ogit:history (
		[
			dcterms:identifier "1";
			dcterms:date "2018-05-22";
			dcterms:description "initial";
			dcterms:creator "fotto@arago.de";
		]
	);
.


@prefix ogit:                   <http://www.purl.org/ogit/> .
@prefix rdfs:                   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms:                <http://purl.org/dc/terms/> .

ogit:Subscription
	a rdfs:Class;
	rdfs:subClassOf ogit:Entity;
	rdfs:label "Subscription";
	dcterms:description "A Subscription to an Event.";
	# For ranges, see http://dublincore.org/documents/dcmi-period/
	dcterms:valid "start=2018-03-22;";
	dcterms:creator "qikram@arago.de";
	ogit:scope "SGO";
	ogit:parent "http://www.purl.org/ogit/Node";
	ogit:mandatory-attributes (
	);
	ogit:optional-attributes (
		ogit:status
		ogit:type
		ogit:sourceId
		ogit:application
	);
	ogit:indexed-attributes (

	);
.

Replace application attribute with name.

@prefix ogit:                   <http://www.purl.org/ogit/> .
@prefix rdfs:                   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms:                <http://purl.org/dc/terms/> .

ogit:Subscription
	a rdfs:Class;
	rdfs:subClassOf ogit:Entity;
	rdfs:label "Subscription";
	dcterms:description "A Subscription to an Event.";
	# For ranges, see http://dublincore.org/documents/dcmi-period/
	dcterms:valid "start=2018-03-22;";
	dcterms:creator "qikram@arago.de";
	ogit:scope "SGO";
	ogit:parent "http://www.purl.org/ogit/Node";
	ogit:mandatory-attributes (
	);
	ogit:optional-attributes (
		ogit:status
		ogit:type
		ogit:sourceId
		ogit:name
	);
	ogit:indexed-attributes (

	);
.


use myrecord;

proc myfunction() {

  var A:[1..10] R;

  for i in 1..10 {
    A[i].verify();
    A[i].init(x=i);
    A[i].verify();
    assert(A[i].x == i);
  }
}

myfunction();

Fix whole array assign test

use myrecord;

proc myfunction() {

  var A:[1..10] R;

  for i in 1..10 {
    A[i].verify();
    A[i].init(x=i);
    A[i].verify();
    assert(A[i].x == i);
  }

  var B:[1..10] R;

  B = A;

  for i in 1..10 {
    B[i].verify();
    assert(B[i].x == i);
  }

}

myfunction();


/* This class will declare a method inside itself, but will have a
   method declared outside it as well */
class Foo {
  proc internalMeth() {

  }
}

// We expect these two methods to be printed outside of the class indentation
// level
proc Foo.externalMeth1() {

}

/* This method has a comment attached to it */
proc Foo.externalMeth2() {

}

Add record with secondary method to chpldoc/ tests.

/* This class will declare a method inside itself, but will have a
   method declared outside it as well */
class Foo {
  proc internalMeth() {

  }
}

// We expect these two methods to be printed outside of the class indentation
// level
proc Foo.externalMeth1() {

}

/* This method has a comment attached to it */
proc Foo.externalMeth2() {

}

/* Declares one primary and one secondary method... */
record Bar {
  /* A primary method declaration. */
  proc internal() {}
}

/* A secondary method declaration. */
proc Bar.external() {}


def foo() { }

def bar() { }

var done: single bool;

def timeout(n: uint) {
  use Time;
  begin { sleep(n); exit(1); }
  begin { done; exit(0); }
}

timeout(30); // exit after 30 seconds or when done is set.

for i in 1..100000 {
  cobegin {
    cobegin { bar(); foo(); }
    cobegin { bar(); foo(); }
    cobegin { bar(); foo(); }
    cobegin { bar(); foo(); }
  }
  if i % 10000 == 0 then
    writeln("iteration ", i, " done.");
}

done = true;

Set up svn:ignore on a directory

def foo() { }

def bar() { }

var done: single bool;

def timeout(n: uint) {
  use Time;
  begin { sleep(n); writeln("Timeout"); exit(1); }
  begin { done; exit(0); }
}

timeout(30); // exit after 30 seconds or when done is set.

for i in 1..100000 {
  cobegin {
    cobegin { bar(); foo(); }
    cobegin { bar(); foo(); }
    cobegin { bar(); foo(); }
    cobegin { bar(); foo(); }
  }
  if i % 10000 == 0 then
    writeln("iteration ", i, " done.");
}

done = true;


/*
 * Smallest multiple
 */

config const rangeMax = 20;

const values: [{1..rangeMax}] int;
forall i in 1..rangeMax {
  values[i] = i;
}

proc isMultiple(value: int, numbers: [] int) {
  for num in numbers {
    if value % num != 0 {
      return false;
    }
  }
  return true;
}

// Return least common multiple for list of ints.
proc lcm(numbers: [] int) {
  var maxNum = max reduce numbers,
    value = maxNum;

  while (!isMultiple(value, numbers)) {
    value += maxNum;
  }

  return value;
}

writeln(lcm(values));

Update solution 5 to work with new-and-improved constness checking.

/*
 * Smallest multiple
 */

config const rangeMax = 20;

const values: [{1..rangeMax}] int = [i in 1..rangeMax] i;

proc isMultiple(value: int, numbers: [] int) {
  for num in numbers {
    if value % num != 0 {
      return false;
    }
  }
  return true;
}

// Return least common multiple for list of ints.
proc lcm(numbers: [] int) {
  var maxNum = max reduce numbers,
    value = maxNum;

  while (!isMultiple(value, numbers)) {
    value += maxNum;
  }

  return value;
}

writeln(lcm(values));


config const n = 11;
var s0 = "kiss kiss";

var l0: atomic int;
var l1: atomic int;

writeln(s0);
begin ref(s0) {
  l0.waitFor(1);
  s0 = "bang bang";
  l1.write(1);
}

on Locales[numLocales-1] {
  l0.write(1);
  l1.waitFor(1);
  writeln(s0);
}

Update one last test to the new task intent syntax

config const n = 11;
var s0 = "kiss kiss";

var l0: atomic int;
var l1: atomic int;

writeln(s0);
begin with (ref s0) {
  l0.waitFor(1);
  s0 = "bang bang";
  l1.write(1);
}

on Locales[numLocales-1] {
  l0.write(1);
  l1.waitFor(1);
  writeln(s0);
}


/*
 * Highly divisible triangular number
 */

config const minDivisors = 500,
  printNumbers = false;

proc main() {
  for t in triangleNumbers() {

    if printNumbers then
      writef("%di: ", t);

    var count = 0;
    for f in factors(t) {
      count += 1;

      if printNumbers then
        writef("%di, ", f);
    }
    if printNumbers then
      writeln();

    if count > minDivisors {
      writeln(t);
      break;
    }
  }
}

// Yield all the factors of n.
iter factors(n) {
  // Yield 1 and n first, then all intermediate factors.
  yield 1;
  yield n;

  var i = 2;
  while (i < sqrt(n)) {
    if n % i == 0 {
      yield i;
      yield n / i;
    }
    i += 1;
  }

  if i ** 2 == n {
    yield i;
  }
}

// Yield triangle numbers infinitely. Up to caller to break iteration.
iter triangleNumbers() {
  var num = 1,
    triangleNum = num;
  for i in 1..max(int) {
    yield triangleNum;
    num += 1;
    triangleNum += num;
  }
}

Update solution 12 to avoid overflow.

/*
 * Highly divisible triangular number
 */

config const minDivisors = 500,
  printNumbers = false;

proc main() {
  for t in triangleNumbers() {

    if printNumbers then
      writef("%n: ", t);

    var count = 0;
    for f in factors(t) {
      count += 1;

      if printNumbers then
        writef("%n, ", f);
    }
    if printNumbers then
      writeln();

    if count > minDivisors {
      writeln(t);
      break;
    }
  }
}

// Yield all the factors of n.
iter factors(n) {
  // Yield 1 and n first, then all intermediate factors.
  yield 1;
  yield n;

  var i = 2;
  while (i < sqrt(n)) {
    if n % i == 0 {
      yield i;
      yield n / i;
    }
    i += 1;
  }

  if i ** 2 == n {
    yield i;
  }
}

// Yield triangle numbers for all integer values. Up to caller to break
// iteration.
iter triangleNumbers() {
  var triangleNum = 1;
  for num in 2..max(int)-1 {
    yield triangleNum;
    triangleNum += num;
  }
}


extern proc return_string_test():string;
extern proc return_string_arg_test(ref string);

writeln("returned string ",return_string_test()); stdout.flush();
var s:string;
on Locales(1) do
  return_string_arg_test(s);
writeln("returned string arg ",s);

Change extern prototypes to specify c_string instead of string

extern proc return_string_test():c_string;
extern proc return_string_arg_test(ref c_string);

writeln("returned string ",return_string_test()); stdout.flush();
var s:string;
on Locales(1) do
  return_string_arg_test(s);
writeln("returned string arg ",s);


var %(aname)s__defaultRect = pych_to_chpl1D(%(aname)s_pych);
var %(aname)s => _getArray(%(aname)s__defaultRect);

Use a ref instead of an alias operation

var %(aname)s__defaultRect = pych_to_chpl1D(%(aname)s_pych);
ref %(aname)s = _getArray(%(aname)s__defaultRect);


iter foo(n: int) {
  for i in 1..n do
    yield i;
}

iter foo(param tag: iterKind, n: int) where tag == iterKind.leader {
  cobegin {
    on Locales(0) do yield tuple(0..n-1 by 2);
    on Locales(1) do yield tuple(1..n-1 by 2);
  }
}

iter foo(param tag: iterKind, followThis, n: int) where tag == iterKind.follower {
  for i in followThis(1)+1 do
    yield i;
}

config var n: int = 8;

var A: [1..n] int;

forall i in foo(n) do
  A(i) = here.id * 100 + i;

writeln(A);

use Random;

{
  var B: [1..n] real;

  var rs = new RandomStream(seed=315);

  forall (i, r) in ({1..n}, rs.iterate({1..n})) do
    B(i) = r;

  writeln(B);
}

{
  var B: [1..n] real;

  var rs = new RandomStream(seed=315);

  forall (f, r) in (foo(n), rs.iterate({1..n})) do
    B(f) = r;

  writeln(B);
}

Update to new zip() syntax.

iter foo(n: int) {
  for i in 1..n do
    yield i;
}

iter foo(param tag: iterKind, n: int) where tag == iterKind.leader {
  cobegin {
    on Locales(0) do yield tuple(0..n-1 by 2);
    on Locales(1) do yield tuple(1..n-1 by 2);
  }
}

iter foo(param tag: iterKind, followThis, n: int) where tag == iterKind.follower {
  for i in followThis(1)+1 do
    yield i;
}

config var n: int = 8;

var A: [1..n] int;

forall i in foo(n) do
  A(i) = here.id * 100 + i;

writeln(A);

use Random;

{
  var B: [1..n] real;

  var rs = new RandomStream(seed=315);

  forall (i, r) in zip({1..n}, rs.iterate({1..n})) do
    B(i) = r;

  writeln(B);
}

{
  var B: [1..n] real;

  var rs = new RandomStream(seed=315);

  forall (f, r) in zip(foo(n), rs.iterate({1..n})) do
    B(f) = r;

  writeln(B);
}


use Time;

config const numIters = 100000;

proc main() {
   begin doSomeWork();
   // while original task exits
   writeln("Original task falling out of main");
}

proc doSomeWork() {
   for i in 1..numIters {
     write("");
     stdout.flush();
   }
   writeln("done working");
}

Fix race condition that was causing valgrind testing non-determinism

use Time;

config const numIters = 100000;
var s$: sync bool;

proc main() {
   begin doSomeWork();
   // while original task exits
   writeln("Original task falling out of main");
   s$ = true;
}

proc doSomeWork() {
   s$;
   for i in 1..numIters {
     write("");
     stdout.flush();
   }
   writeln("done working");
}


use Filerator;

for dir in walkdirs("subdir") {
  writeln("dir ", dir, " contains:");
  for file in glob(dir+"/*") do
    writeln("  ", file);
}

Fix nondeterministic output from walkdir() by requesting sorted output

use Filerator;

for dir in walkdirs("subdir", sort=true) {
  writeln("dir ", dir, " contains:");
  for file in glob(dir+"/*") do
    writeln("  ", file);
}


// Calcuate pi using a monte carlo simulation

use Random, Time;

config const n = 10000, seed = 314159;
config const verbose: bool = false;

var count:int;
var pi, startTime, totalTime: real;
var rs = RandomStream(seed);

startTime = getCurrentTime(microseconds);

// Find random points on the complex plane in (0..1+i)
// and count how many are outside the unit circle.
count = + reduce [1..n] abs(rs.getNext()**2 + rs.getNext()**2):int;

// The probability a point is inside the unit circle is pi / 4.
pi = 4 * (n-count):real(64) / n;

// Write out the results
writeln(pi);
totalTime = (getCurrentTime(microseconds) - startTime) / 1000000;
if (verbose) then
  writeln("Calculation took: ", totalTime, " seconds");

Change an incorrect bracket syntax forall expression into a for expression for a loop that needs to be serial.

// Calcuate pi using a monte carlo simulation

use Random, Time;

config const n = 10000, seed = 314159;
config const verbose: bool = false;

var count:int;
var pi, startTime, totalTime: real;
var rs = RandomStream(seed);

startTime = getCurrentTime(microseconds);

// Find random points on the complex plane in (0..1+i)
// and count how many are outside the unit circle.
count = + reduce for 1..n do abs(rs.getNext()**2 + rs.getNext()**2):int;

// The probability a point is inside the unit circle is pi / 4.
pi = 4 * (n-count):real(64) / n;

// Write out the results
writeln(pi);
totalTime = (getCurrentTime(microseconds) - startTime) / 1000000;
if (verbose) then
  writeln("Calculation took: ", totalTime, " seconds");


// Test logical AND and OR reductions

param M = 10;

var D: domain(1) = [1..M];
var B: [D] bool;
forall i in D do {
  B(i) = true;
}
writeln( "\nB[D] = ", B);
writeln( "&& reduce B[D] = ", && reduce B);
writeln( "|| reduce B[D] = ", || reduce B);

forall i in D do {
  B(i) = false;
}
writeln( "\nB[D] = ", B);
writeln( "&& reduce B[D] = ", && reduce B);
writeln( "|| reduce B[D] = ", || reduce B);

var toggle: sync bool = false;
forall i in D do {
  var my_toggle = !toggle;
  toggle = my_toggle;
  B(i) = my_toggle;
}
writeln( "\nB[D] = ", B);
writeln( "&& reduce B[D] = ", && reduce B);
writeln( "|| reduce B[D] = ", || reduce B);

Change the last forall loop in this reduction test to make it deterministic.

// Test logical AND and OR reductions

param M = 10;

var D: domain(1) = [1..M];
var B: [D] bool;
forall i in D do {
  B(i) = true;
}
writeln( "\nB[D] = ", B);
writeln( "&& reduce B[D] = ", && reduce B);
writeln( "|| reduce B[D] = ", || reduce B);

forall i in D do {
  B(i) = false;
}
writeln( "\nB[D] = ", B);
writeln( "&& reduce B[D] = ", && reduce B);
writeln( "|| reduce B[D] = ", || reduce B);

forall i in D do {
  var toggle: bool = i % 2 == 1;
  B(i) = toggle;
}
writeln( "\nB[D] = ", B);
writeln( "&& reduce B[D] = ", && reduce B);
writeln( "|| reduce B[D] = ", || reduce B);


// A test of the QuickSort function in the Sort module

use Sort;
use Random;

config const size = 4096;

def main() {
  var A: [1..size] int;
  var rands: [1..size] real;
  var randomStream = RandomStream();

  // Fill A with random int values in [0, 99999]
  randomStream.fillRandom(rands);
  [i in 1..size] A(i) = (100000 * rands(i)):int;

  QuickSort(A);

  // Check that A is sorted
  [i in 1..size-1] {
    if A(i) > A(i+1) then
      writeln(A(i), " ", A(i+1));
  }
}

Make the seed to the RandomStream class in my QuickSort test be set to something that causes the "infinite" loop failure instead of the current time.

// A test of the QuickSort function in the Sort module

use Sort;
use Random;

config const size = 4096;
config const seed = 27;

def main() {
  var A: [1..size] int;
  var rands: [1..size] real;
  var randomStream = RandomStream(seed);

  // Fill A with random int values in [0, 99999]
  randomStream.fillRandom(rands);
  [i in 1..size] A(i) = (100000 * rands(i)):int;

  QuickSort(A);

  // Check that A is sorted
  [i in 1..size-1] {
    if A(i) > A(i+1) then
      writeln(A(i), " ", A(i+1));
  }
}


//
// Measures both array iteration and array access time
//

use Memory, Time, Types;

config const zipIter = false;
config const memFraction = 100;
config const printPerf = false;

type elemType = uint(8);

const totalMem = here.physicalMemory(unit = MemUnits.Bytes);
const n = (totalMem / numBytes(elemType)) / memFraction;

const space = 1..n;
var data : [space] elemType;
var x : elemType = 2;

var time : Timer;
time.start();
if zipIter {
  forall (i, j) in zip(data, data) with (ref x) do
    x *= i;
} else {
  forall i in data with (ref x) do
    x *= i;
}
time.stop();

if printPerf then writeln("Time: ", time.elapsed());

Set a maximum problem size to avoid timeouts

//
// Measures both array iteration and array access time
//

use Memory, Time, Types;

config const zipIter = false;
config const memFraction = 100;
config const printPerf = false;

type elemType = uint(8);

const totalMem = here.physicalMemory(unit = MemUnits.Bytes);
const target = (totalMem / numBytes(elemType)) / memFraction;
// set a maximum problem size
const n = min(target, 8 * 1e9) : int;

const space = 1..n;
var data : [space] elemType;
var x : elemType = 2;

var time : Timer;
time.start();
if zipIter {
  forall (i, j) in zip(data, data) with (ref x) do
    x *= i;
} else {
  forall i in data with (ref x) do
    x *= i;
}
time.stop();

if printPerf then writeln("Time: ", time.elapsed());


config const n = 100;
config const shift = 2;
config type myType = real;

use Random;

var randlist = new RandomStream(314159265);
var T: [1..n] real;
randlist.fillRandom(T);

proc foo(type myType) {
  var A = (T*(1<<shift):real):myType;
  var x: sync myType = 0:myType;
  forall i in 1..n do
    x += A[i];
  var sum = + reduce A;
  // This check could run into troubles with floating point types
  if x.readXX() != sum then
    writeln("ERROR: sums do not match for ", typeToString(myType),
            " (should be ", sum, ", result is ", x.readXX(), ")");
}

foo(int(32));
foo(int(64));
foo(uint(32));
foo(uint(64));
foo(real(32));
foo(real(64));

Change initialization to avoid numerical instability.

config const n = 100;
config type myType = real;

var T: [1..n] real;
[i in 1..n] T[i] = i*1.01;

proc foo(type myType) {
  var A = T:myType;
  var x: sync myType = 0:myType;
  forall i in 1..n do
    x += A[i];
  var sum = + reduce A;
  if x.readXX() != sum then
    writeln("ERROR: sums do not match for ", typeToString(myType),
            " (should be ", sum, ", result is ", x.readXX(), ")");
}

foo(int(32));
foo(int(64));
foo(uint(32));
foo(uint(64));
foo(real(32));
foo(real(64));


/*
 * Open a file and confirm its FS type is lustre.
 */

use IO;

var fp = open("SKIPIF", iomode.r),
  fileType = fp.fstype();

if fileType == FTYPE_LUSTRE {
  writeln("SUCCESS");
} else {
  writeln("FAILURE");
}

Update error message to be more helpful.

/*
 * Open a file and confirm its FS type is lustre.
 */

use IO;

const fsTypes: [{0..3}] string = [
  "none",
  "hdfs",
  "UNKNOWN", // lustre is LUSTRE_SUPER_MAGIC (whatever that is)
  "curl"
];

var fp = open("SKIPIF", iomode.r),
  fileType = fp.fstype();

if fileType == FTYPE_LUSTRE {
  writeln("SUCCESS");
} else {
  writef("FAILURE: Expected FTYPE_LUSTRE (%n), actual: %s (%n)\n",
         FTYPE_LUSTRE, fsTypes[fileType], fileType);
}


var a: sync int;
var b = 0;

cobegin {
  {
    b = 1;
    while (a < 3) {
      b = 2;
    }
  }
  a = 1;
  a += 1;
  a += 1;
}

if (b==2) then {
  writeln ("b is good");
} else {
  writeln ("b is bad");
}

Fix my spin wait -> sync var change

var a: sync int;
var b = 0;

cobegin {
  {
    b = 1;
    while (a < 3) {
      b = 2;
    }
  }
  {
    a = 1;
    a = 2;
    a = 3;
  }
}

if (b==2) then {
  writeln ("b is good");
} else {
  writeln ("b is bad: ", b);
}


//
// Measures both array iteration and array access time
//

use Memory, Time, Types;

config const zipIter = false;
config const memFraction = 16;
config const printPerf = false;

type elemType = uint(8);

const totalMem = here.physicalMemory(unit = MemUnits.Bytes);
const n = (totalMem / numBytes(elemType)) / memFraction;

const space = 1..n;
var data : [space] elemType;
var x : elemType = 2;

var time : Timer;
time.start();
if zipIter {
  forall (i, j) in zip(data, data) with (ref x) do
    x *= i;
} else {
  forall i in data with (ref x) do
    x *= i;
}
time.stop();

if printPerf then writeln("Time: ", time.elapsed());

Reduce problem size to avoid timeouts on non-performance configurations

//
// Measures both array iteration and array access time
//

use Memory, Time, Types;

config const zipIter = false;
config const memFraction = 100;
config const printPerf = false;

type elemType = uint(8);

const totalMem = here.physicalMemory(unit = MemUnits.Bytes);
const n = (totalMem / numBytes(elemType)) / memFraction;

const space = 1..n;
var data : [space] elemType;
var x : elemType = 2;

var time : Timer;
time.start();
if zipIter {
  forall (i, j) in zip(data, data) with (ref x) do
    x *= i;
} else {
  forall i in data with (ref x) do
    x *= i;
}
time.stop();

if printPerf then writeln("Time: ", time.elapsed());


fib = method(n,
  i = 0
  j = cur = 1
  while(cur <= n,
    k = i
    i = j
    j = k + j
    cur ++)
  i)

System ifMain(fib(30000) println)

Remove a space in fib

fib = method(n,
  i = 0
  j = 1
  cur = 1
  while(cur <= n,
    k = i
    i = j
    j = k + j
    cur++)
  i)

System ifMain(fib(300000))


Struct = fn(+attributes, +:attributesWithDefaultValues,
  val = fn(+values, +:keywordValues,
    result = val mimic
    (attributesWithDefaultValues seq +
      attributes zipped(values) +
      keywordValues seq) each(vv,
      result cell(vv first) = vv second)
    result
  )
  val mimic!(Struct)
  val)

Make it possible to create new things based on the existing

Struct = fn(+attributes, +:attributesWithDefaultValues,
  attributeNames = attributes + attributesWithDefaultValues map(key)
  val = fn(+values, +:keywordValues,
    result = fn(+newVals, +:newKeywordVals,
      Struct createWithValuesFrom(result, attributeNames, newVals, newKeywordVals))
    result mimic!(val)
    (attributesWithDefaultValues seq +
      values zipped(attributes) mapped(reverse) +
      keywordValues seq) each(vv,
      result cell(vv first) = vv second)
    result
  )
  val mimic!(Struct)
  val)

Struct createWithValuesFrom = method(orig, attributeNames, newValues, newKeywordValues,
  res = orig mimic
  (newValues zipped(attributeNames) mapped(reverse) +
    newKeywordValues seq) each(vv,
    res cell(vv first) = vv second)
  res
)


Number zero? = method(
  "Returns true if this number is zero.",
  @ == 0
)

Number negation = method(
  "Returns the negation of this number",

  0 - @)

Number abs = method(
  "Returns the absolute value of this number",
  if(self < 0, negation, self)
)

Number          do(=== = generateMatchMethod(==))
Number Real     do(=== = generateMatchMethod(==))
Number Rational do(=== = generateMatchMethod(==))
Number Decimal  do(=== = generateMatchMethod(==))

Number Integer odd? = method(
  (@ % 2) != 0
)

Number Integer even? = method(
  (@ % 2) == 0
)

Add documentation to new Integer methods

Number zero? = method(
  "Returns true if this number is zero.",
  @ == 0
)

Number negation = method(
  "Returns the negation of this number",

  0 - @)

Number abs = method(
  "Returns the absolute value of this number",
  if(self < 0, negation, self)
)

Number          do(=== = generateMatchMethod(==))
Number Real     do(=== = generateMatchMethod(==))
Number Rational do(=== = generateMatchMethod(==))
Number Decimal  do(=== = generateMatchMethod(==))

Number Integer odd? = method(
  "Returns true if this number is odd, false otherwise",
  (@ % 2) != 0
)

Number Integer even? = method(
  "Returns true if this number is even, false otherwise",
  (@ % 2) == 0
)


DefaultBehavior FlowControl cond = syntax(
  "takes zero or more arguments. each two arguments are paired, where the first one is the condition part, and the second is the then-part. if there's an uneven number of arguments, that part is the else-part. if no arguments are provided, or no conditions match and there is no else part, cond returns nil.",

  DefaultBehavior FlowControl cell(:cond) createNestedIfStatements(call arguments))

DefaultBehavior FlowControl cell(:cond) createNestedIfStatements = method(args,
  if(args length == 0,
    `nil,
    if(args length == 1,
      ; an else part
      args[0],

      ; a condition, then part
      'if appendArgument(args[0]) appendArgument(args[1]) appendArgument(createNestedIfStatements(args[2..-1]))
    )
  )
)

Refactor cond to use the new composition stuff

DefaultBehavior FlowControl cond = syntax(
  "takes zero or more arguments. each two arguments are paired, where the first one is the condition part, and the second is the then-part. if there's an uneven number of arguments, that part is the else-part. if no arguments are provided, or no conditions match and there is no else part, cond returns nil.",

  DefaultBehavior FlowControl cell(:cond) createNestedIfStatements(call arguments))

DefaultBehavior FlowControl cell(:cond) createNestedIfStatements = method(args,
  if(args length == 0,
    'nil,
    if(args length == 1,
      ; an else part
      args[0],

      ; a condition, then part
      'if <<(args[0]) <<(args[1]) << createNestedIfStatements(args[2..-1])
    )
  )
)


import(:javax:swing, :JFrame, :JButton)
import java:awt:GridLayout

button = JButton new("Press me!") do(
  addActionListener(fn(e, button text = "Hello from Ioke")))

JFrame new("My Frame") do(
  layout = GridLayout new(2, 2, 3, 3)
  add(button)
  setSize(300, 80)
  visible = true)

Update example to do more than one thing on button pressed

import(:javax:swing, :JFrame, :JButton)
import java:awt:GridLayout

button = JButton new("Press me!") do(
  addActionListener(fn(e, button text = "Hello from Ioke"))
  addActionListener(fn(e, "button pressed" println)))

JFrame new("My Frame") do(
  layout = GridLayout new(2, 2, 3, 3)
  add(button)
  setSize(300, 80)
  visible = true)


bottle = method(i,
  if(i == 0, return "no more bottles of beer")
  if(i == 1, return "1 bottle of beer")
  return "#{i} bottles of beer"
)

; TODO List reverse instead of sortBy
(1..99) sortBy(p, -p) each(i,
  "#{bottle(i)} on the wall, " println
  "take one down, pass it around," println
  "#{bottle(i - 1)} on the wall.\n" println
)

Update 99 bottles to use idiomatic Ioke

bottle = method(i,
  case(i,
    0, "no more bottles of beer",
    1, "1 bottle of beer",
    "#{i} bottles of beer"))

(99..1) each(i,
  "#{bottle(i)} on the wall, " println
  "take one down, pass it around," println
  "#{bottle(i - 1)} on the wall.\n" println
)


use("ispec")

describe(Hook,
  it("should have the correct kind",
    Hook should have kind("Hook")
  )

  describe("into",
    it("should return a new hook object connected to the argument object")
  )

  describe("into!",
    it("should add itself to the mimic chain of the first argument and bind it to the second object")
  )

  describe("hook!",
    it("should add a new observed object to the receiver")
  )
)

Add some more waiting tests

use("ispec")

describe(Hook,
  it("should have the correct kind",
    Hook should have kind("Hook")
  )

  describe("into",
    it("should return a new hook object connected to the argument object")
  )

  describe("into!",
    it("should add itself to the mimic chain of the first argument and bind it to the second object")
  )

  describe("hook!",
    it("should add a new observed object to the receiver")
  )

  describe("cellAdded",
    it("should have tests")
  )

  describe("cellRemoved",
    it("should have tests")
  )

  describe("cellChanged",
    it("should have tests")
  )

  describe("cellUndefined",
    it("should have tests")
  )

  describe("mimicked",
    it("should have tests")
  )

  describe("mimicAdded",
    it("should have tests")
  )

  describe("mimicRemoved",
    it("should have tests")
  )

  describe("mimicsChanged",
    it("should have tests")
  )
)


IIk = Origin mimic

IIk Exit = Condition mimic
IIk mainContext = Ground mimic
IIk mainContext exit = method(signal!(IIk Exit))
IIk mainContext aliasMethod("exit", "quit")

IIk mainLoop = method(
  "Runs the main loop of IIk, continously reading input from 'System in' until the interpreter is quitted in some of the standard ways",

  out = System out
  err = System err
  in  = System in

  bind(
    rescue(IIk Exit, fn(c, out println("Bye."))),
    loop(
      bind(
        rescue(Condition Error, fn(c, err println("*** - #{c report}"))),
        out print("iik> ")
        out println("+> #{in read evaluateOn(mainContext) inspect}")
        out println))))

System ifMain(IIk mainLoop)

Upgrade the console a bit, to use the debugger instead of rescuing exceptions. This makes for a cleaner API and so on. Also establish the quit and abort restarts

IIk = Origin mimic

IIk Exit = Condition mimic

IIk mainContext = Ground mimic do(
  exit = method(signal!(IIk Exit))
  aliasMethod("exit", "quit"))

IIk out = System out
IIk err = System err
IIk in  = System in

IIk mainLoop = method(
  "Runs the main loop of IIk, continously reading input from 'System in' until the interpreter is quitted in some of the standard ways",

  debugger = Origin mimic
  System currentDebugger = debugger
  debugger invoke = method(
    condition, context,
    invokeRestart(:abort)
  )

  bind(
    rescue(IIk Exit, fn(c, out println("Bye."))),
    restart(quit, fn()),

    loop(
      bind(
        restart(abort, fn()),

        out print("iik> ")
        out println("+> #{in read evaluateOn(mainContext) inspect}")
        out println))))

System ifMain(IIk mainLoop)


use("ispec")

describe(Message,
  describe("rewrite!",
    it("should rewrite a very simple message chain",
      msg = 'foo
      msg rewrite!(
        '(:x) => '(something(:x))
      )
      msg should == 'blah(foo)
    )
  )
)

Make pending spec of the rewrite stuff

use("ispec")

describe(Message,
  describe("rewrite!",
    it("should rewrite a very simple message chain")
;       msg = 'foo
;       msg rewrite!(
;         '(:x) => '(something(:x))
;       )
;       msg should == 'blah(foo)
;     )
  )
)