diff --git a/implementations/GNUProlog/Makefile b/implementations/GNUProlog/Makefile new file mode 100644 index 0000000..2448c3c --- /dev/null +++ b/implementations/GNUProlog/Makefile @@ -0,0 +1,12 @@ + +all: joy_to_ast thun printer + +joy_to_ast: joy_to_ast.prolog + gplc --no-top-level joy_to_ast.prolog + +thun: thun.prolog + gplc --no-top-level thun.prolog + +printer: printer.prolog + gplc --no-top-level printer.prolog + diff --git a/implementations/GNUProlog/joy_to_ast.prolog b/implementations/GNUProlog/joy_to_ast.prolog index 7219cc4..1a0fde3 100644 --- a/implementations/GNUProlog/joy_to_ast.prolog +++ b/implementations/GNUProlog/joy_to_ast.prolog @@ -1,5 +1,4 @@ - stdin_to_codes(Codes) :- % Pass in and discard atom 'code' to prime stdin_to_codes/2. stdin_to_codes(code, [code|Codes]). @@ -9,6 +8,7 @@ stdin_to_codes(Code, [Code|Codes]) :- get_code(NextCode), stdin_to_codes(NextCode, Codes). + % %joy(InputString, StackIn, StackOut) :- % text_to_expression(InputString, Expression), @@ -34,7 +34,7 @@ joy_parse([]) --> []. joy_term(list(J)) --> [lbracket], !, joy_parse(J), [rbracket]. joy_term(Token) --> [tok(Codes)], {joy_token(Token, Codes)}. -joy_token(int(I), Codes) :- catch(number_codes(I, Codes), _Err, fail), !. +joy_token(int(I), Codes) :- numeric(Codes), atom_codes(I, Codes), !. joy_token(bool(true), "true") :- !. joy_token(bool(false), "false") :- !. joy_token(symbol(S), Codes) :- atom_codes(S, Codes). @@ -51,6 +51,16 @@ chars([Ch]) --> char(Ch). char(Ch) --> \+ blank, [Ch], { Ch \== 0'[, Ch \== 0'] }. +numeric(Codes) :- digits(Codes, []), !. +numeric([45,FirstDigit|Codes]) :- digit(FirstDigit), digits(Codes, []), !. +% ASCII 45 is '-'. + +digits --> digit, digits. +digits --> []. + +digit --> [Code], { digit(Code) }. + +digit(Code) :- between(0'0, 0'9, Code). blank --> [9]. blank --> [10]. @@ -82,5 +92,5 @@ blank --> [227, 128, 128]. :- initialization(( stdin_to_codes(Codes), text_to_expression(Codes, Expr), - print(Expr), print('\n') - )). \ No newline at end of file + write_term(Expr, [quoted(true)]), print('\n') + )). diff --git a/implementations/GNUProlog/printer.prolog b/implementations/GNUProlog/printer.prolog new file mode 100644 index 0000000..c873ad0 --- /dev/null +++ b/implementations/GNUProlog/printer.prolog @@ -0,0 +1,25 @@ + +format_joy_expression( int(I)) --> { integer(I), !, number_codes(I, Codes) }, Codes. +format_joy_expression( int(I)) --> { atom(I), !, atom_codes(I, Codes) }, Codes. +format_joy_expression( int(I)) --> { write_to_codes(Codes, I) }, [40], Codes, [41]. +format_joy_expression( bool(B)) --> { atom_codes(B, Codes) }, Codes. +format_joy_expression(symbol(S)) --> { atom_codes(S, Codes) }, Codes. +format_joy_expression(symbol(S)) --> { atom_codes(S, Codes) }, Codes. +format_joy_expression( list(J)) --> "[", format_joy_terms(J), "]". + +format_joy_terms( []) --> []. +format_joy_terms( [T]) --> format_joy_expression(T), !. +format_joy_terms([T|Ts]) --> format_joy_expression(T), " ", format_joy_terms(Ts). + +codes_to_stream([Code|Codes], Stream) :- + put_code(Stream, Code), !, + codes_to_stream(Codes, Stream). +codes_to_stream([], _). + +:- initialization(( + read_term(AST, [end_of_term(eof)]), + format_joy_terms(AST, Codes, []), + codes_to_stream(Codes, user_output), print('\n') + )). + + diff --git a/implementations/GNUProlog/thun.prolog b/implementations/GNUProlog/thun.prolog new file mode 100644 index 0000000..2f1dc17 --- /dev/null +++ b/implementations/GNUProlog/thun.prolog @@ -0,0 +1,73 @@ + + +thun([], S, S). +thun([Term|E], Si, So) :- thun(Term, E, Si, So). + +thun(A, [], S, [A|S]) :- var(A), !. +thun(A, [T|E], S, So) :- var(A), !, thun(T, E, [A|S], So). + +thun(int(A), [], B, [int(A)|B]). +thun(int(C), [A|B], D, E) :- thun(A, B, [int(C)|D], E). + +thun(bool(A), [], B, [bool(A)|B]). +thun(bool(C), [A|B], D, E) :- thun(A, B, [bool(C)|D], E). + +thun(list(A), [], B, [list(A)|B]). +thun(list(C), [A|B], D, E) :- thun(A, B, [list(C)|D], E). + +thun(symbol(A), [], B, C) :- func(A, B, C). +thun(symbol(A), [C|D], B, F) :- func(A, B, E), thun(C, D, E, F). + +thun(symbol(Combo), E, Si, So) :- combo(Combo, Si, S, E, Eo), thun(Eo, S, So). + + +func(swap, [A, B|S], [B, A|S]). +func(dup, [A|S], [A, A|S]). +func(pop, [_|S], S ). + +func(cons, [list(A), B |S], [list([B|A])|S]). + +func(swaack, [list(R)|S], [list(S)|R]). +func(stack, S , [list(S)|S]). +func(clear, _ , []). +func(first, [list([X|_])|S], [ X |S]). +func(rest, [list([_|X])|S], [list(X)|S]). + +func(bool, [ int(0)|S], [bool(false)|S]). +func(bool, [ list([])|S], [bool(false)|S]). +func(bool, [bool(false)|S], [bool(false)|S]). + +func(bool, [ int(N)|S], [bool(true)|S]) :- N #\= 0. +func(bool, [list([_|_])|S], [bool(true)|S]). +func(bool, [ bool(true)|S], [bool(true)|S]). + +func( + , [int(A), int(B)|S], [int(A + B)|S]). +func( - , [int(A), int(B)|S], [int(B - A)|S]). +func( * , [int(A), int(B)|S], [int(A * B)|S]). +func( / , [int(A), int(B)|S], [int(B div A)|S]). +func('%', [int(A), int(B)|S], [int(B mod A)|S]). + +func( add , [int(A), int(B)|S], [int(A + B)|S]). +func( sub , [int(A), int(B)|S], [int(B - A)|S]). +func( mul , [int(A), int(B)|S], [int(A * B)|S]). +func( div , [int(A), int(B)|S], [int(B div A)|S]). +func( mod, [int(A), int(B)|S], [int(B mod A)|S]). + + +combo(i, [list(P)|S], S, Ei, Eo) :- append(P, Ei, Eo). +combo(dip, [list(P), X|S], S, Ei, Eo) :- append(P, [X|Ei], Eo). + +combo(branch, [list(T), list(_), bool(true)|S], S, Ei, Eo) :- append(T, Ei, Eo). +combo(branch, [list(_), list(F), bool(false)|S], S, Ei, Eo) :- append(F, Ei, Eo). + +combo(loop, [list(_), bool(false)|S], S, E, E ). +combo(loop, [list(B), bool(true)|S], S, Ei, Eo) :- append(B, [list(B), symbol(loop)|Ei], Eo). + + + +:- initialization(( + read_term(AST, [end_of_term(eof)]), + thun(AST, [], Stack), + write_term(Stack, [quoted(true)]), print('\n') + )). +