Thun/implementations/oldlog/docs/user-guide/user-guide.md

4.0 KiB

User Guide

There is no use interface as such. At the moment you just load the thun.pl file into SWI Prolog and use some of these "top-level" predicates to interact with it.


joy/3

joy(InputString, StackIn, StackOut)

Evaluation

Accepts a joy expression as a list of codes (in SWI Prolog you can use backticks to quote a string literal and get codes):

?- joy(`+ *`, [int(2), int(3), int(10)], StackOut).
StackOut = [int(50)] ;
false.

?- joy(`2 3 + 10 *`, StackIn, StackOut).
StackOut = [int(50)|StackIn] ;
false.

Type Checking

This predicate can also perform type checking:

?- joy(`2 [] +`, StackIn, StackOut).
false.

Type Inference

And type inference with CLP(FD) constraints on integer operations and comparisons:

?- joy(`+ *`, StackIn, StackOut).
StackIn = [int(_37782), int(_37792), int(_37802)|_37798],
StackOut = [int(_37824)|_37798],
_37782+_37792#=_37842,
_37842*_37802#=_37824 ;
false.

joy_parse//1

If you just want to parse a string into a Joy expression use joy_parse//1 DCG, like so:

phrase(joy_parse(Expression), InputString)

Or directly:

joy_parse(Expression, InputString, [])

Example:

?- phrase(joy_parse(Expression), `1 [i]`).
Expression = [int(1), list([symbol(i)])] ;
false.

thun/3

Once you have a (type-tagged) Joy exression as Prolog data-structure you can use the thun/3 predicate to evaluate it:

thun(Expression, InputStack, OutputStack)

sjc/2

sjc(Name, InputString)

Helper function to see to what Prolog code a given Joy expression would compile. Give it a name (Prolog atom) and a list of code.

?- sjc(third, `third`).
func(third, [list([_, _, A|_])|B], [A|B]).
true ;
false.

?- sjc(ccons, `ccons`).
func(ccons, [list(C), B, A|D], [list([A, B|C])|D]).
true ;
false.

Compilation captures CLP(FD) constraints:

?- sjc(+*, `+ *`).
func(+*, [int(D), int(E), int(B)|A], [int(C)|A]) :-
    maplist(call,
            [ clpfd:(F*B#=C),
            clpfd:(D+E#=F)
            ]).
true ;
false.

show_joy_compile/2

show_joy_compile(Name, Expression)

Same as sjc/2 but you give it an already-parsed expression.


joy_compile/2

joy_compile(Name, Expression)

This actually asserts the new function definition into the Prolog rule database. Use with care.

At some point I'll probably add a build phase that tries to pre-compile all definitions it can into Prolog rules but for now this is just experimental.


compiler/4

compiler(InputString, MachineCode, StackIn, StackOut)

Experimental and unfinished, this predicate attempts to build a list of terms representing machine code for the RISC CPU that Prof. Wirth has specified for his Project Oberon.


grow//0 & shrink//0

These DCGs recursively unfold or fold definitions in a Joy expression:

?- phrase(grow, [symbol(third)], Out).
Out = [symbol(rest), symbol(rest), symbol(first)] ;
Out = [symbol(rest), symbol(rest), symbol(first)] ;
Out = [symbol(rest), symbol(second)] ;
Out = [symbol(third)].

?- phrase(shrink, [symbol(rest), symbol(rest), symbol(first)], Out).
Out = [symbol(rrest), symbol(first)] ;
Out = [symbol(third)] ;
Out = [symbol(rest), symbol(second)] ;
Out = [symbol(rest), symbol(rest), symbol(first)].

They are more a proof-of-concept than useful at the moment. I imagine that it might be possible to set up some kind of automated search through all the variations to see if a more efficient form (after compiling with whatever optimizations) can be found.


joy_terms_to_string/2

joy_terms_to_string(Expr, String)

Converts a Joy expression into a string (an actual string, not a list of codes. See the SWI Prolog manual for more information on strings.)