Artifact 6629940451babbd38ec926b9d5212dbb65c9fd3a
-----------------------------------------------------------------------------
Polemy 0.1.0
by k.inaba (www.kmonos.net)
Nov 20, 2010
-----------------------------------------------------------------------------
<<How to Build>>
- Install DMD
http://www.digitalmars.com/d/2.0/changelog.html
Version 2.050 is recommended. Older or newer version may not work.
- Build
(for Windows) Run build.bat
(for Unix) Run build.sh
or use your favorite build tools upon main.d and polemy/*.d.
Then you will get the executable "polemy" in the "bin" directory.
<<License>>
d2stacktrace/*
is written by Benjamin Thaut and licensed under 2-clause BSD License.
See http://3d.benjamin-thaut.de/?p=15 for the detail.
(this package is used only for enabling stack-traces during printing exceptions;
it is not used for release builds.)
polemy/*
main.d
All the other parts are written by Kazuhiro Inaba and
licensed under NYSL 0.9982 ( http://www.kmonos.net/nysl/ ).
<<How to Use>>
> polemy
starts REPL
> polemy foo.pmy
executes foo.pmy
> polemy -l foo.pmy
after executing foo.pmy, starts REPL
> polemy -l foo.pmy -l bar.pmy buz.pmy
executes foo.pmy, bar.bmy, and then buz.pmy
<<Syntax>>
Comment is "# ... \n"
E ::=
// declaration
| ("var"|"let"|"def"|LAYER) ID "=" E (";"|"in") E
| ("var"|"let"|"def"|LAYER) ID "(" PARAMS ")" "{" E "}" (";"|"in") E
| ("var"|"let"|"def"|LAYER) ID "=" E
| ("var"|"let"|"def"|LAYER) ID "(" PARAMS ")" "{" E "}"
// literal
| INTEGER
| STRING
| "{" ENTRYS "}"
| "fun" "(" PARAMS ")" "{" E "}"
// function call
| E "(" ARGS")"
where ARGS ::= E "," ... "," E
PARAMS ::= ID LAYER* "," ... "," ID LAYER*
ENTRYS ::= ID ":" E "," ... "," ID ":" E
ID ::= 'a-zA-Z0-9_...'+
LAYER ::= "@" ID
// operators
| "(" E ")"
| E "." ID
| E ".?" ID
| E BINOP E
| "if" "(" E ")" "{" E "}"
| "if" "(" E ")" "{" E "}" "else "{" E "}"
// layered exec
| LAYER "(" E ")"
The following are actually rewritten to function calls:
- if (E) then{E} else{E} ==> if( E, fun(){E}, fun(){E} )
- E BINOP E ==> BINOP(E, E)
- E.ID ==> . (E, ID)
- E.?ID ==> .?(E, ID)
- {} ==> {}()
- {ID:E, ...} ==> .=({...}, ID, E)
Several styles of variable declaration can be used:
- fun(x){ fun(y){x} } # K-combinator
- fun(x){ let f = fun(y){x} in f } # let-in style
- fun(x){ var f = fun(y){x}; f } # var-; style
- fun(x){ def f = fun(y){x} in f } # you can use any combination of (let|var|def)-(;|in)
- fun(x){ def f(y){x} in f } # syntax sugar for function declaration
- fun(x){ let f(y){x}; f } # this is also ok
- fun(x){ var f(y){x} } # omitting (;|in) returns the last declared object directly
- fun(x,y){x} #< this is not equal to the above ones. functions are no curried.
NOTE: Theres no "let rec" syntax, but still recursive definition works
def f(x) { if(x==0){1}else{x*f(x-1)} } in f(10) #=> 3628800
yet still the code below also works
def x=21 in def x=x+x in x #=> 42.
The internal scoping mechanism is a little tricky (this is for coping with
the "layer" feature explained below), but I hope that it works as everyone
expects in most cases, as long as you don't use the same-name-variables heavily :).
<<Basic Features>>
Polemy is an untyped functional programming language that has
- integers: 0, 123, 456666666666666666666666666666666666666789, ...
- strings: "hello, world!\n", ...
- tables: {car: 1, cdr: {car: 2, cdr: {}}}
- functions: fun(x){x+1}
as primitive datatypes. Functions capture lexical closures.
It is almost 'pure' (except the primitve function "print" and some
trick inside scoping mechanisms).
<<Layer>>
to be written