W Wrapl, The Programming Language

Basic Samples

Hello world!

1MOD Hello; 2 3IMP IO.Terminal USE Out; 4 5Out:write("Hello world!"); 6 7END Hello.

Factorials

Recursive

1MOD Fact; 2 3IMP IO.Terminal USE Out; 4 5DEF Fact(n) n < 2 => 1 // n * Fact(n - 1); 6 7Out:write('10! = {Fact(10)}'); 8 9END Fact.

Iterative

1MOD Fact; 2 3DEF Fact(n) ( 4 VAR f <- 1; 5 EVERY f <- f * 1:to(n); 6 RET f; 7); 8 9Out:write('10! = {Fact(10)}'); 10 11END Fact.

Prime Numbers

The following function generates all the prime numbers.

1DEF Primes() ( 2 WITH store <- [] DO EVERY store:put(SUSP 2:up \ NOT ($ % store:values = 0)); 3);
--> ALL 10 OF 10 SKIP Primes(); [31, 37, 41, 43, 47, 53, 59, 61, 67, 71]

How it works is left as an exercise to the reader :).

Objects and Methods

Complex Numbers

1MOD Complex; 2 3IMP Std.String; 4 5-- Type for complex numbers 6DEF T! <- <[] re, im>; 7 8-- Converts a complex number to a string 9TO :"@"(cmplx@T, =String.T) '{cmplx:re} + {cmplx:im}i'; 10 11-- Arithmetic methods 12TO :"+"(a@T, b@T) T(a:re + b:re, a:im + b:im); 13 14TO :"-"(a@T, b@T) T(a:re - b:re, a:im - b:im); 15 16TO :"*"(a@T, b@T) T(a:re * b:re - a:im * b:im, a:re * b:im + a:im * b:re); 17 18END Complex.
$ wrapl --> IMP .Complex; NIL --> VAR a <- Complex.T(1, 2); 1 + 2i --> VAR b <- Complex.T(3, -5); 3 + -5i --> a + b; 4 + -3i --> a - b; -2 + 7i --> a * b; 13 + -7i

wrpp

wrpp

Here is the entire source code for the wrpp preprocessor.

1#!/home/raja/Work/Wrapl/bin/riva -tWrapl 2MOD Mark; 3 4IMP Sys.FileSys; 5IMP Sys.Config; 6IMP Sys.Program USE Args; 7IMP Sys.Module; 8IMP IO.Terminal USE Out; 9IMP IO.File; 10IMP IO.Buffer; 11IMP IO.Stream; 12IMP Wrapl.Loader; 13IMP Std.Function; 14IMP Std.String; 15IMP Std.Integer; 16 17DEF Defines <- {}; 18DEF Includes <- [""]; 19 20DEF SourceT <- <[Stream.ReaderT]>; 21DEF buffer <- []; 22 23VAR in <- Terminal.In, out <- Terminal.Out, line; 24 25TO :readi(src@SourceT, n@Integer.SmallT, t@String.T) buffer:pop | in:readi(n, t); 26 27VAR source <- SourceT(); 28VAR session <- Loader.SessionNew(source); 29 30session:var("out", out); 31 32VAR stack <- []; 33session:def("stack", stack); 34session:def("push", <b> stack:push(out <- (NIL ~== b) | Buffer.New())); 35session:def("pop", <> stack:pop \ (out <- stack[1])); 36session:def("begin", :?); 37session:def("end", :?); 38session:def("buffer", Buffer.New); 39session:def("include", Include); 40session:def("_include_", <filename> Include(filename, 1)); 41session:def("write", <text> out:write(text)); 42session:def("defines", Defines); 43session:def("includes", Includes); 44session:def("dbg", Out); 45 46VAR escape <- "\\"; 47session:var("escape", escape); 48 49DEF Process(strip) ( 50 VAR pos; 51 line <- in:readi(0, "\n"); 52 REP ( 53 pos <- 1; 54 REP (WHILE pos <- line:find(escape, pos); 55 line[pos + 1] = ";" => ( 56 line <- line[1, pos + 1] + (line[pos + 2, 0] | ""); 57 pos <- pos + 1; 58 ) // ( 59 out:write(line[1, pos]); 60 buffer:put(line[pos + 1, 0]); 61 line <- NIL; 62 pos <- 1; 63 session:eval; 64 (NIL == line) <- session:line; 65 ); 66 ); 67 (NIL ~== strip) & (line = "\n") => line <- ""; 68 out:write(line); 69 WHILE line <- in:readi(0, "\n"); 70 ); 71); 72 73DEF Include(filename, strip) ( 74 VAR oldline <- session:line; 75 VAR oldin <- in; 76 VAR path; 77 FileSys.Exists(path <- Includes:values + filename) // ( 78 Out:write('Error: file "{filename}" not found.\n'); 79 FAIL; 80 ); 81 in <- File.Open(path, File.Flag.Read + File.Flag.Text); 82 Process(strip); 83 in:close; 84 in <- oldin; 85 line <- oldline; 86); 87 88DEF ParseArgs() ( 89 VAR i <- 1, arg; 90 REP (WHILE i <= Args:length; 91 arg <- Args[i]; 92 arg[1] = '-' => ( 93 WHEN arg[2] IS "u" DO ( 94 Config.Set("Wrapl.AllowUndeclared"); 95 ) IS "D" DO ( 96 arg <- arg[3, 0] | Args[i <- i + 1] | SEND "Missing argument"; 97 Defines:insert(arg:before("="), arg:after("=")); 98 ) IS "o" DO ( 99 arg <- arg[3, 0] | Args[i <- i + 1] | SEND "Missing argument"; 100 out <- File.Open(arg, File.Flag.Write + File.Flag.Text); 101 ) IS "I" DO ( 102 arg <- arg[3, 0] | Args[i <- i + 1] | SEND "Missing argument"; 103 arg <- arg + (arg[-1] ~= "/"); 104 Includes:put(arg); 105 ) IS "L" DO ( 106 arg <- arg[3, 0] | Args[i <- i + 1] | SEND "Missing argument"; 107 Module.AddDirectory(arg); 108 ) IS "p" DO ( 109 arg <- arg[3, 0] | Args[i <- i + 1] | SEND "Missing argument"; 110 Include(arg); 111 ) IS "P" DO ( 112 arg <- arg[3, 0] | Args[i <- i + 1] | SEND "Missing argument"; 113 Include(arg, 1); 114 ) DO ( 115 SEND 'Unknown argument: {arg}'; 116 ); 117 ) // ( 118 in <- File.Open(arg, File.Flag.Read + File.Flag.Text); 119 ); 120 i <- i + 1; 121 ); 122 --(in == NIL) => in <- Terminal.In; 123 --(out == NIL) => out <- Terminal.Out; 124 stack:put(out); 125 RECV msg DO ( 126 Out:write('Error[125]: {msg}\n'); 127 Program.Exit(1); 128 ); 129); 130 131ParseArgs(); 132Process(); 133Program.Exit(0); 134 135END Mark.

Other Examples

To see some more complex sample code using several of the included libraries, check the following:

GTK+

For an example on using the GTK+ binding, see here.