www.want-tool.org
Initial WANTScript Ideas
   

By Andrew J. Wozniewicz
Milwaukee, June 17, 2007

These are sanitized (spelling-corrected) excerpts from my original newsgroup post in response to Juanca. Note that many details of the language have changed since then. -AJW 2008/08/05

I already have devised most of the language called Modula-7. Originally, I had all statements terminated with semicolons, but I now think this is unnecessary, except in some very specific cases. Here are some highlights of the language, again, by way of example:
project ProjName

  attribute SomeAttr="XYZ" // That's the way to set them
  attribute Name="NewName" // Redefines proj name
    // Not that this is a good idea, but consistent
    // Programmer has access to *all* attributes

  import BuildLib;
    //Other scripts incorporated this way
    // This is exactly equivalent to saying "depends"

  //Anywhere within a block, executable statements can go

  // Setup event handlers
  EventBuildSuccess += OnBuildSuccess
  EventBuildFailure += OnBuildFailure
  //Default procedure/target calls go here
  Compile() // Calls may have to have empty parens


  // Declarations are valid within
  // the entire scope of the enclosing
  // element (multiple passes required)

  const
    Whatever = 42
    ProjectSource = "want.dpr"

  var
    Version = "1.2.0" //Implicitly typed as String
    Counter = 0 //Implicitly typed as Int

  type
    TWeekdays = (Mon, Tue, Wed, Thu, Fri, Sat, Sun)
    TRange100 = 1..100

  target Target1
    //Target is just a special procedure
    // with no parameters.
    depends Target2, Target3;
      //Lists of identifiers are in
      // general terminated with a semicolon???
    task DCC
      Source := ProjectSource
      // Passing trees is a problem here
      // Lists/Collections are no problem
      define SUPPORTS_WIDESTRING
        // Implicit add to the collection
      define ANOTHER
    end
  end


  procedure ShowMsg(...)
    // Multiple, anonymous, parameters...?
    task Echo with
      //It will take whatever is passed.
      ...
    end
    Counter += 1 // Yeah, I like those :-)
    Echo("Continuing...")
      //Alternative way of invoking tasks/procs
  end


  procedure LetsSeeSomeLogic(Param1, Param2)

    procedure Internal
      // Yes, nested procedures, but not tasks
      var X, Y, Z //Only visible in Internal
    end

    var X, Y, Z // Locals
    if param1 then
      WriteLn("Param1 is true")
    else
      WriteLn("Param1 is false")
    end
    switch Param2
    case 1:
      WriteLn("Param2=1")
    case 2..10:
      WriteLn("Param2=2..10")
    else //or case else
      WriteLn("None of the above")
    end
    "End of procedure"
      // could this be a shorthand for WriteLn()?

    procedure Internal2
      // OK, maybe an overkill, but thus avoids BEGINs
    end

    "Can execute statements anywhere within a procedure block"
  end


  function Fib(N)
    if N in [0..1] then
      Result := 1
    else
      Result := Fib(N-1) + Fib(N-2)
    end
  end


  function Sum(N)
    var C = 1;
    Result := 0
    while C <= N loop //or do
      Result += C
    end
  end


  procedure OnBuildSuccess
    "Build succeeded"
    perform EMail with
      AddrTo := "recipient@domain.com";
      AddrFrom := "wantscript@domain.com";
      Subject := "Notification from WANT";
      Body := Message;
    end;
  end


  whitelephant Bamboo
    // statements go here
    // if the exec env. does not know what whiteelephant is,
    // it will either optionally ignore it, or complain
    // or otherwise just treat it as a normal procedure
    // if it is invoked via a call statement
  end

end //module

So, targets are just special procedures that are invoked only once during a run.

Tasks are just invocations of internally registered functions/procedures (which are implemented as task-like objects), with parameters bound either by name, or by position (which allows for anonymous parameters, and a variable number of them).

Identifiers and keywords are case-INsensitive (like in Pascal).

The block-structure of the language allows for things to be nested arbitrarily deep. Every nested block is a module in its own right, with type, const, var, depends, etc., as well as executable statements.

There is nothing special about the keywords like target, procedure, or event. They are just names of the nodes in the parse tree. A compiler option could allow for strict validation, or just ignore unknown nodes.

-Andrew

P.S. The original post appeared at news://news.optimax.com/sdforum.want