File Annotation
Not logged in
423f308350 2010-11-07        kinaba: -----------------------------------------------------------------------------
423f308350 2010-11-07        kinaba:   Polemy 0.1.0
423f308350 2010-11-07        kinaba:                                                  by k.inaba (www.kmonos.net)
515502e8d1 2010-11-20        kinaba:                                                                Nov 20, 2010
423f308350 2010-11-07        kinaba: -----------------------------------------------------------------------------
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba: <<How to Build>>
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba:   - Install DMD
423f308350 2010-11-07        kinaba:       http://www.digitalmars.com/d/2.0/changelog.html
515502e8d1 2010-11-20        kinaba:     Version 2.050 is recommended. Older or newer version may not work.
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba:   - Build
423f308350 2010-11-07        kinaba:       (for Windows) Run build.bat
423f308350 2010-11-07        kinaba:       (for Unix) Run build.sh
423f308350 2010-11-07        kinaba:       or use your favorite build tools upon main.d and polemy/*.d.
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba:   Then you will get the executable "polemy" in the "bin" directory.
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba: <<License>>
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba:   d2stacktrace/*
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba:     is written by Benjamin Thaut and licensed under 2-clause BSD License.
423f308350 2010-11-07        kinaba:     See http://3d.benjamin-thaut.de/?p=15 for the detail.
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba:     (this package is used only for enabling stack-traces during printing exceptions;
c48ba67854 2010-11-08        kinaba:      it is not used for release builds.)
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba:   polemy/*
423f308350 2010-11-07        kinaba:   main.d
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba:     All the other parts are written by Kazuhiro Inaba and
423f308350 2010-11-07        kinaba:     licensed under NYSL 0.9982 ( http://www.kmonos.net/nysl/ ).
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba: 
423f308350 2010-11-07        kinaba: <<How to Use>>
423f308350 2010-11-07        kinaba: 
9eec42eba1 2010-11-09        kinaba:   > polemy
9eec42eba1 2010-11-09        kinaba:       starts REPL
9eec42eba1 2010-11-09        kinaba: 
9eec42eba1 2010-11-09        kinaba:   > polemy foo.pmy
9eec42eba1 2010-11-09        kinaba:       executes foo.pmy
9eec42eba1 2010-11-09        kinaba: 
515502e8d1 2010-11-20        kinaba:   > polemy -l foo.pmy
515502e8d1 2010-11-20        kinaba:       after executing foo.pmy, starts REPL
515502e8d1 2010-11-20        kinaba: 
3464a035ec 2010-11-20        kinaba:   > polemy -l foo.pmy -l bar.pmy buz.pmy
3464a035ec 2010-11-20        kinaba:       executes foo.pmy, bar.bmy, and then buz.pmy
3464a035ec 2010-11-20        kinaba: 
9eec42eba1 2010-11-09        kinaba: 
9eec42eba1 2010-11-09        kinaba: 
515502e8d1 2010-11-20        kinaba: <<Syntax>>
9eec42eba1 2010-11-09        kinaba: 
515502e8d1 2010-11-20        kinaba:  Comment is "# ... \n"
9eec42eba1 2010-11-09        kinaba: 
515502e8d1 2010-11-20        kinaba:  E ::=
515502e8d1 2010-11-20        kinaba:    // declaration
515502e8d1 2010-11-20        kinaba:      | ("var"|"let"|"def"|LAYER) ID "=" E (";"|"in") E
515502e8d1 2010-11-20        kinaba:      | ("var"|"let"|"def"|LAYER) ID "(" PARAMS ")" "{" E "}" (";"|"in") E
515502e8d1 2010-11-20        kinaba:      | ("var"|"let"|"def"|LAYER) ID "=" E
515502e8d1 2010-11-20        kinaba:      | ("var"|"let"|"def"|LAYER) ID "(" PARAMS ")" "{" E "}"
515502e8d1 2010-11-20        kinaba:    // literal
515502e8d1 2010-11-20        kinaba:      | INTEGER
515502e8d1 2010-11-20        kinaba: 	 | STRING
435fa085ec 2010-11-21        kinaba: 	 | "{" ENTRYS "}"                   // table
435fa085ec 2010-11-21        kinaba:      | "fun" "(" PARAMS ")" "{" E "}"   // anonymous function
515502e8d1 2010-11-20        kinaba:    // function call
515502e8d1 2010-11-20        kinaba:      | E "(" ARGS")"
515502e8d1 2010-11-20        kinaba: 	     where ARGS ::= E "," ... "," E
515502e8d1 2010-11-20        kinaba: 	         PARAMS ::= ID LAYER* "," ... "," ID LAYER*
515502e8d1 2010-11-20        kinaba: 			 ENTRYS ::= ID ":" E  "," ... "," ID ":" E
515502e8d1 2010-11-20        kinaba:                  ID ::= 'a-zA-Z0-9_...'+
515502e8d1 2010-11-20        kinaba:               LAYER ::= "@" ID
515502e8d1 2010-11-20        kinaba:    // operators
9eec42eba1 2010-11-09        kinaba:      | "(" E ")"
435fa085ec 2010-11-21        kinaba: 	 | E "." ID           // table field access
435fa085ec 2010-11-21        kinaba: 	 | E ".?" ID          // table field existence check
435fa085ec 2010-11-21        kinaba:      | E "{" ENTRYS "}"   // table extend (pure functionally)
9eec42eba1 2010-11-09        kinaba:      | E BINOP E
9eec42eba1 2010-11-09        kinaba:      | "if" "(" E ")" "{" E "}"
9eec42eba1 2010-11-09        kinaba:      | "if" "(" E ")" "{" E "}" "else "{" E "}"
515502e8d1 2010-11-20        kinaba:    // layered exec
515502e8d1 2010-11-20        kinaba:      | LAYER "(" E ")"
515502e8d1 2010-11-20        kinaba: 
515502e8d1 2010-11-20        kinaba: The following are actually rewritten to function calls:
515502e8d1 2010-11-20        kinaba: 
515502e8d1 2010-11-20        kinaba:   - if (E) then{E} else{E} ==> if( E, fun(){E}, fun(){E} )
515502e8d1 2010-11-20        kinaba:   - E BINOP E              ==> BINOP(E, E)
515502e8d1 2010-11-20        kinaba:   - E.ID                   ==> . (E, ID)
515502e8d1 2010-11-20        kinaba:   - E.?ID                  ==> .?(E, ID)
515502e8d1 2010-11-20        kinaba:   - {}                     ==> {}()
435fa085ec 2010-11-21        kinaba:   - { ENTRIES }            ==> {}{ ENTRIES }
435fa085ec 2010-11-21        kinaba:   - E {ID:E, ...}          ==> (.=(E, ID, E)) { ... }
515502e8d1 2010-11-20        kinaba: 
515502e8d1 2010-11-20        kinaba: Several styles of variable declaration can be used:
515502e8d1 2010-11-20        kinaba: 
515502e8d1 2010-11-20        kinaba:   - fun(x){ fun(y){x} }               # K-combinator
515502e8d1 2010-11-20        kinaba:   - fun(x){ let f = fun(y){x} in f }  # let-in style
515502e8d1 2010-11-20        kinaba:   - fun(x){ var f = fun(y){x}; f }    # var-;  style
515502e8d1 2010-11-20        kinaba:   - fun(x){ def f = fun(y){x} in f }  # you can use any combination of (let|var|def)-(;|in)
515502e8d1 2010-11-20        kinaba:   - fun(x){ def f(y){x} in f } # syntax sugar for function declaration
515502e8d1 2010-11-20        kinaba:   - fun(x){ let f(y){x}; f }   # this is also ok
515502e8d1 2010-11-20        kinaba:   - fun(x){ var f(y){x} }      # omitting (;|in) returns the last declared object directly
515502e8d1 2010-11-20        kinaba:   - fun(x,y){x} #< this is not equal to the above ones. functions are no curried.
515502e8d1 2010-11-20        kinaba: 
515502e8d1 2010-11-20        kinaba: NOTE: Theres no "let rec" syntax, but still recursive definition works
515502e8d1 2010-11-20        kinaba:     def f(x) { if(x==0){1}else{x*f(x-1)} } in f(10)  #=> 3628800
515502e8d1 2010-11-20        kinaba:   yet still the code below also works
515502e8d1 2010-11-20        kinaba:     def x=21 in def x=x+x in x  #=> 42.
515502e8d1 2010-11-20        kinaba:   The internal scoping mechanism is a little tricky (this is for coping with
515502e8d1 2010-11-20        kinaba:   the "layer" feature explained below), but I hope that it works as everyone
515502e8d1 2010-11-20        kinaba:   expects in most cases, as long as you don't use the same-name-variables heavily :).
515502e8d1 2010-11-20        kinaba: 
c1f2717799 2010-11-21        kinaba: (Experimental) pattern matching is also available. Here is an example.
c1f2717799 2010-11-21        kinaba: 
c1f2717799 2010-11-21        kinaba:   def adjSum(lst)
c1f2717799 2010-11-21        kinaba:   {
c1f2717799 2010-11-21        kinaba:     case( lst )
c1f2717799 2010-11-21        kinaba:       when( {car:x, cdr:{car: y, cdr:z}} ) { {car: x+y, cdr: adjSum(z)} }
c1f2717799 2010-11-21        kinaba:       when( {car:x, cdr:{}} ) { {car: x, cdr: {}} }
c1f2717799 2010-11-21        kinaba:       when( {} ) { {} }
c1f2717799 2010-11-21        kinaba:   };
c1f2717799 2010-11-21        kinaba: 
c1f2717799 2010-11-21        kinaba: It is expanded to a sequence of if-then-elses prefering the first-match.
c1f2717799 2010-11-21        kinaba: Note that {a: _} pattern matches all the tables that have the .a field.
c1f2717799 2010-11-21        kinaba: It also matches to {a: 123, b: 456} having extra .b field. So, changing the
c1f2717799 2010-11-21        kinaba: order of "when"s in the above code changes the behavior.
c1f2717799 2010-11-21        kinaba: 
c1f2717799 2010-11-21        kinaba: 
515502e8d1 2010-11-20        kinaba: 
515502e8d1 2010-11-20        kinaba: 
515502e8d1 2010-11-20        kinaba: <<Basic Features>>
515502e8d1 2010-11-20        kinaba: 
515502e8d1 2010-11-20        kinaba:   Polemy is an untyped functional programming language that has
515502e8d1 2010-11-20        kinaba:    - integers:   0, 123, 456666666666666666666666666666666666666789, ...
515502e8d1 2010-11-20        kinaba:    - strings:    "hello, world!\n", ...
515502e8d1 2010-11-20        kinaba:    - tables:     {car: 1, cdr: {car: 2, cdr: {}}}
515502e8d1 2010-11-20        kinaba:    - functions:  fun(x){x+1}
515502e8d1 2010-11-20        kinaba:   as primitive datatypes. Functions capture lexical closures.
515502e8d1 2010-11-20        kinaba:   It is almost 'pure' (except the primitve function "print" and some
515502e8d1 2010-11-20        kinaba:   trick inside scoping mechanisms).
515502e8d1 2010-11-20        kinaba: 
515502e8d1 2010-11-20        kinaba: 
435fa085ec 2010-11-21        kinaba: <<Layers :: Overview>>
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   Polemy's runtime environment has many "layer"s.
435fa085ec 2010-11-21        kinaba:   Usual execution run in the @value layer.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> 1 + 2
435fa085ec 2010-11-21        kinaba:     3
435fa085ec 2010-11-21        kinaba:     >> @value( 1 + 2 )
435fa085ec 2010-11-21        kinaba:     3
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   Here you can see that @LayerName( Expression ) executes the inner Expression in
435fa085ec 2010-11-21        kinaba:   the @LayerName layer. Other than @value, one other predefined layer exists: @macro.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @macro( 1+2 )
435fa085ec 2010-11-21        kinaba:     {pos@value:{lineno@value:3, column@value:9, filename@value:<REPL>},
435fa085ec 2010-11-21        kinaba:       is@value:app,
c1f2717799 2010-11-21        kinaba:     args@value:{car@value:{pos@value:{lineno@value:3, column@value:9, filename@value:<REPL>},
435fa085ec 2010-11-21        kinaba:                             is@value:int,
435fa085ec 2010-11-21        kinaba:                           data@value:1},
435fa085ec 2010-11-21        kinaba:                 cdr@value:{
435fa085ec 2010-11-21        kinaba:                   car@value:{pos@value:{lineno@value:3, column@value:11, filename@value:<REPL>},
435fa085ec 2010-11-21        kinaba:                               is@value:int,
435fa085ec 2010-11-21        kinaba:                             data@value:2},
435fa085ec 2010-11-21        kinaba:                   cdr@value:{}}},
435fa085ec 2010-11-21        kinaba:      fun@value:{pos@value:{lineno@value:3, column@value:10, filename@value:<REPL>},
435fa085ec 2010-11-21        kinaba:                  is@value:var,
435fa085ec 2010-11-21        kinaba:                name@value:+}}
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   (Sorry, this pretty printing is not available on the actual interpreter...)
435fa085ec 2010-11-21        kinaba:   This evaluates the expression 1+2 in the @macro layer. In this layer, the meaning of
435fa085ec 2010-11-21        kinaba:   the program is its abstract syntax tree.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   You can interleave layers.
435fa085ec 2010-11-21        kinaba:   The root node of the abstract syntax tree is function "app"lication.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @value(@macro( 1+2 ).is)
435fa085ec 2010-11-21        kinaba:     app
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: <<Layers :: Defining a new layer>>
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   To define a new layer, you should first tell how to "lift" existing values two the new layer.
435fa085ec 2010-11-21        kinaba:   Let us define the "@type" layer, where the meaning of programs is their static type.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @@type = fun(x) {
435fa085ec 2010-11-21        kinaba:     >>   if( _isint(x) ) { "int" } else {
435fa085ec 2010-11-21        kinaba:     >>   if( _isfun(x) ) { x } else { "unknown" } }
435fa085ec 2010-11-21        kinaba:     >> }
435fa085ec 2010-11-21        kinaba:     (Note: polemy REPL may warn some exception here but please ignore)
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   For simplicity, I here deal only with integers.
435fa085ec 2010-11-21        kinaba:   _isint is a primitive function of Polemy that checks the dynamic type of a value.
435fa085ec 2010-11-21        kinaba:   For function, leaving it untouched works well for almost all layers.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @type( 1 )
435fa085ec 2010-11-21        kinaba:     int
435fa085ec 2010-11-21        kinaba:     >> @type( 2 )
435fa085ec 2010-11-21        kinaba:     int
435fa085ec 2010-11-21        kinaba:     >> @type( "foo" )
435fa085ec 2010-11-21        kinaba:     unknown
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   Fine! Let's try to type 1+2.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @type( 1 + 2 )
435fa085ec 2010-11-21        kinaba:     ...\value.d(119): [<REPL>:6:8] only @value layer can call native function
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   Note that the behavior of this program is
435fa085ec 2010-11-21        kinaba:     - run 1+2 in the @type layer
435fa085ec 2010-11-21        kinaba:   and NOT
435fa085ec 2010-11-21        kinaba:     - run 1+2 in @value and obtain 3 and run 3 in the @type.
435fa085ec 2010-11-21        kinaba:   The problem is, the variable "+" is defined only in the @value layer.
435fa085ec 2010-11-21        kinaba:   To carry out computation in the @type layer. We need to define it also
435fa085ec 2010-11-21        kinaba:   in the @type layer.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   To define some variable in a specific layer, use @LayerName in place of
435fa085ec 2010-11-21        kinaba:   (let|var|def)s.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> let x = 2
435fa085ec 2010-11-21        kinaba:     >> @value x = 2
435fa085ec 2010-11-21        kinaba:     >> @type x = "int"
435fa085ec 2010-11-21        kinaba:     >> @hoge x = "fuga"
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   For "+", do it like this.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @type "+" = fun(x,y) {@value(
435fa085ec 2010-11-21        kinaba:     >>   if( @type(x)=="int" && @type(y)=="int" ) { "int" } else { "typeerror" }
435fa085ec 2010-11-21        kinaba:     >> )}
435fa085ec 2010-11-21        kinaba:     polemy.value.native!(IntValue,IntValue,IntValue).native.__anonclass24
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   It is just computing the return type from the input type.
435fa085ec 2010-11-21        kinaba:   Not here that the intended "meaning" of if-then-else is the runtime-branching,
435fa085ec 2010-11-21        kinaba:   and the meaning of "==" is the value-comparison. These are the @value layer
435fa085ec 2010-11-21        kinaba:   behavior. So we have defined the function body inside @value layer.
435fa085ec 2010-11-21        kinaba:   But when we refer the variables x and y, we need its @type layer meaning.
435fa085ec 2010-11-21        kinaba:   Hence we use @type() there.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   Now we get it.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @type( 1 + 2 )
435fa085ec 2010-11-21        kinaba:     int
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   Well, but do we have to define the @type layer meaning for every variables???
435fa085ec 2010-11-21        kinaba:   No. After you defined @type "+", you'll automatically get the following:
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> def double(x) { x + x }
435fa085ec 2010-11-21        kinaba:     (function:17e4740:1789720)
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @type( double(123) )
435fa085ec 2010-11-21        kinaba:     int
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   Every user-defined functions are automatically "lift"ed to the appropriate layer.
435fa085ec 2010-11-21        kinaba:   Only primitive functions like "+" requires @yourNewLayer annotation.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: <<Layers :: neutral-layer>>
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   let|var|def is to define a variable in the "current" layer.
435fa085ec 2010-11-21        kinaba:   Not necessary to the @value layer.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @value( let x = 1 in @value(x) )
435fa085ec 2010-11-21        kinaba:     1
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @macro( let x = 1 in @value(x) )
435fa085ec 2010-11-21        kinaba:     polemy.failure.RuntimeException: [<REPL>:14:29] variable x not found
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> @macro( let x = 1 in @macro(x) )
435fa085ec 2010-11-21        kinaba:     {pos@value:{lineno@value:15, ...
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: <<Layers :: Layered-Parameters>>
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> def foo(x @macro @value) { {fst: x, snd: @macro(x)} }
435fa085ec 2010-11-21        kinaba:     (function:1730360:1789720)
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   If you annotate function parameters by @LayerNames, when you invoke the function...
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:     >> foo(1+2)
435fa085ec 2010-11-21        kinaba:     {snd@value: {pos@value:{lineno@value:17, column@value:5, filename@value:<REPL>},
435fa085ec 2010-11-21        kinaba:                   is@value:app, arg@value:{...
435fa085ec 2010-11-21        kinaba:     /fst@value:3
435fa085ec 2010-11-21        kinaba:     /}
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:   its corresponding arguments are evaluated in the layer and passed to it.
435fa085ec 2010-11-21        kinaba:   If you specify multiple layers, the argument expression is run multiple times.
435fa085ec 2010-11-21        kinaba:   If you do not specify any layer for a parameter, it works in the neutral layer.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: <<@macro layer>>
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:    When function is invoked, it first run in the @macro layer, and after that,
435fa085ec 2010-11-21        kinaba:    it run in the neutral layer. Here is an example.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:      >> @macro twice(x) { x; x }
435fa085ec 2010-11-21        kinaba:      >> def f() { twice(print("Hello")); 999 }
435fa085ec 2010-11-21        kinaba:      (function:173b6a0:1789720)
435fa085ec 2010-11-21        kinaba:      >> f()
435fa085ec 2010-11-21        kinaba:      Hello
435fa085ec 2010-11-21        kinaba:      Hello
435fa085ec 2010-11-21        kinaba:      999
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:    When the interpreter evaluates f(), it first executes
435fa085ec 2010-11-21        kinaba:      "twice(print("Hello")); 999"
435fa085ec 2010-11-21        kinaba:    in the @macro layer. Basically what it does is to just construct its syntax tree.
435fa085ec 2010-11-21        kinaba:    But, since we have defined the "twice" function in the @macro layer, it is
435fa085ec 2010-11-21        kinaba:    execute as a function. Resulting syntax tree is
435fa085ec 2010-11-21        kinaba:      "print("Hello"); print("Hello"); 999"
435fa085ec 2010-11-21        kinaba:    and this is executed on the neutral (in this example, @value) layer.
435fa085ec 2010-11-21        kinaba:    This is the reason why you see two "Hello"s.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:       [[limitations]]
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:    This @macro layer is a very primitive one, and not a perfect macro language.
435fa085ec 2010-11-21        kinaba:    Two major limitations are seen in the following "it" example.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:      >> @macro LetItBe(x, y) { let it = x in y };
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:    The variable name is not hygenic, and so without any effort, the syntax tree "y"
435fa085ec 2010-11-21        kinaba:    can access the outer variable "it".
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:      >> def foo() { LetItBe( 1+2+3, it*it ) }
435fa085ec 2010-11-21        kinaba:      >> foo()
435fa085ec 2010-11-21        kinaba:      36
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:    Of course, this is not just a limitation; it can sometimes allow us to write
435fa085ec 2010-11-21        kinaba:    many interesting macros.
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:    The other problem is that the macro expansion is only done at function startup.
435fa085ec 2010-11-21        kinaba:    So
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:      >> LetItBe( 1+2+3, it*it )
435fa085ec 2010-11-21        kinaba:      ...\value.d(173): [<REPL>:24:1] variable LetItBe is not set in layer @value
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:    you cannot directly use the macro in the same scope as the definition.
435fa085ec 2010-11-21        kinaba:    You need to wrap it up in a function (like the foo() in the above example).
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:       [[quote and unquote]]
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:    Here is more involved example of code genration.
435fa085ec 2010-11-21        kinaba:    From "x", it generates "x*x*x*x*x*x*x*x*x*x".
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:      @macro pow10(x) {
435fa085ec 2010-11-21        kinaba:        @value(
435fa085ec 2010-11-21        kinaba:          def pow(x, n) {
435fa085ec 2010-11-21        kinaba:            if( n == 1 ) { x }
435fa085ec 2010-11-21        kinaba:            else {
435fa085ec 2010-11-21        kinaba:              @macro( @value(x) * @value(pow(x,n-1)) )
435fa085ec 2010-11-21        kinaba:            }
435fa085ec 2010-11-21        kinaba:          }
435fa085ec 2010-11-21        kinaba:          in
435fa085ec 2010-11-21        kinaba:            pow(@macro(x),10)
435fa085ec 2010-11-21        kinaba:        )
435fa085ec 2010-11-21        kinaba:      };
435fa085ec 2010-11-21        kinaba: 
435fa085ec 2010-11-21        kinaba:    Here, x is a syntax tree but n is an actual integer. If you read carefully,
435fa085ec 2010-11-21        kinaba:    you should get what is going on. Basically, @macro can be considered like
435fa085ec 2010-11-21        kinaba:    quasiquoting and @value to be an escape from it.
c1f2717799 2010-11-21        kinaba: 
c1f2717799 2010-11-21        kinaba: 
c1f2717799 2010-11-21        kinaba: 
c1f2717799 2010-11-21        kinaba: <<Primitives>>
c1f2717799 2010-11-21        kinaba: 
c1f2717799 2010-11-21        kinaba:   {}  0-ary  create-empty-table
c1f2717799 2010-11-21        kinaba:   .   2-ary  table-get
c1f2717799 2010-11-21        kinaba:   .?  2-ary  table-has?
c1f2717799 2010-11-21        kinaba:   .=  3-ary  table-set
c1f2717799 2010-11-21        kinaba: 
c1f2717799 2010-11-21        kinaba:   if  3-ary  if-then-else
c1f2717799 2010-11-21        kinaba: 
5e924caac9 2010-11-23        kinaba:   + - * / % || &&    2-ary  integer-operations (NOTE! no short-circuit for && and ||.)
c1f2717799 2010-11-21        kinaba:   < > <= >= == !=    2-ary  generic comparison
5e924caac9 2010-11-23        kinaba:   ~                  2-ary  string concatenation (works also for non-string objects)
c1f2717799 2010-11-21        kinaba: 
c1f2717799 2010-11-21        kinaba:   print 1-ary print-to-stdout
c1f2717799 2010-11-21        kinaba: 
c1f2717799 2010-11-21        kinaba:   _isint _isstr _isfun _isundefined _istable  1-ary  dynamic-type-test
c1f2717799 2010-11-21        kinaba: