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:
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
//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)
Whatever = 42
ProjectSource = "want.dpr"
Version = "1.2.0" //Implicitly typed as String
Counter = 0 //Implicitly typed as Int
TWeekdays = (Mon, Tue, Wed, Thu, Fri, Sat, Sun)
TRange100 = 1..100
//Target is just a special procedure
// with no parameters.
depends Target2, Target3;
//Lists of identifiers are in
// general terminated with a semicolon???
Source := ProjectSource
// Passing trees is a problem here
// Lists/Collections are no problem
// Implicit add to the collection
// Multiple, anonymous, parameters...?
task Echo with
//It will take whatever is passed.
Counter += 1 // Yeah, I like those :-)
//Alternative way of invoking tasks/procs
procedure LetsSeeSomeLogic(Param1, Param2)
// Yes, nested procedures, but not tasks
var X, Y, Z //Only visible in Internal
var X, Y, Z // Locals
if param1 then
WriteLn("Param1 is true")
WriteLn("Param1 is false")
else //or case else
WriteLn("None of the above")
"End of procedure"
// could this be a shorthand for WriteLn()?
// OK, maybe an overkill, but thus avoids BEGINs
"Can execute statements anywhere within a procedure block"
if N in [0..1] then
Result := 1
Result := Fib(N-1) + Fib(N-2)
var C = 1;
Result := 0
while C <= N loop //or do
Result += C
perform EMail with
AddrTo := "firstname.lastname@example.org";
AddrFrom := "email@example.com";
Subject := "Notification from WANT";
Body := Message;
// 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
So, targets are just special procedures that are invoked only once during a
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.
P.S. The original post appeared at news://news.optimax.com/sdforum.want