diff --git a/.gitignore b/.gitignore index 265c8cd..280632a 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ implementations/Nim/joy implementations/Python/joy docs/notebooks/.ipynb_checkpoints joy.py.* +joy_to_ast diff --git a/implementations/GNUProlog/joy_to_ast.prolog b/implementations/GNUProlog/joy_to_ast.prolog new file mode 100644 index 0000000..7219cc4 --- /dev/null +++ b/implementations/GNUProlog/joy_to_ast.prolog @@ -0,0 +1,86 @@ + + +stdin_to_codes(Codes) :- + % Pass in and discard atom 'code' to prime stdin_to_codes/2. + stdin_to_codes(code, [code|Codes]). + +stdin_to_codes(-1, []) :- !. +stdin_to_codes(Code, [Code|Codes]) :- + get_code(NextCode), + stdin_to_codes(NextCode, Codes). + +% +%joy(InputString, StackIn, StackOut) :- +% text_to_expression(InputString, Expression), +% !, +% thun(Expression, StackIn, StackOut). +% + +joy_lex([tok(Token)|Ls]) --> chars(Token), !, joy_lex(Ls). +joy_lex([ lbracket|Ls]) --> "[", !, joy_lex(Ls). +joy_lex([ rbracket|Ls]) --> "]", !, joy_lex(Ls). + +joy_lex(Ls) --> blank, !, joy_lex(Ls). + +joy_lex([]) --> []. + + +% Then parse the tokens converting them to Prolog values and building up +% the list structures (if any.) + +joy_parse([J|Js]) --> joy_term(J), !, joy_parse(Js). +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(bool(true), "true") :- !. +joy_token(bool(false), "false") :- !. +joy_token(symbol(S), Codes) :- atom_codes(S, Codes). + +text_to_expression(Text, Expression) :- + phrase(joy_lex(Tokens), Text), !, + phrase(joy_parse(Expression), Tokens). + +% Apologies for all the (green, I hope) cuts. The strength of the Joy +% syntax is that it's uninteresting. + +chars([Ch|Rest]) --> char(Ch), chars(Rest). +chars([Ch]) --> char(Ch). + +char(Ch) --> \+ blank, [Ch], { Ch \== 0'[, Ch \== 0'] }. + + +blank --> [9]. +blank --> [10]. +blank --> [11]. +blank --> [12]. +blank --> [13]. +blank --> [32]. +blank --> [194, 133]. +blank --> [194, 160]. +blank --> [225, 154, 128]. +blank --> [226, 128, 128]. +blank --> [226, 128, 129]. +blank --> [226, 128, 130]. +blank --> [226, 128, 131]. +blank --> [226, 128, 132]. +blank --> [226, 128, 133]. +blank --> [226, 128, 134]. +blank --> [226, 128, 135]. +blank --> [226, 128, 136]. +blank --> [226, 128, 137]. +blank --> [226, 128, 138]. +blank --> [226, 128, 168]. +blank --> [226, 128, 169]. +blank --> [226, 128, 175]. +blank --> [226, 129, 159]. +blank --> [227, 128, 128]. + + +:- initialization(( + stdin_to_codes(Codes), + text_to_expression(Codes, Expr), + print(Expr), print('\n') + )). \ No newline at end of file