1:- module('python_transpiler', [parse/5]).    2:- use_module(library(chr)).    3
    4:- set_prolog_flag(double_quotes,chars).    5
    6% This is a program that translates several programming languages into several other languages.
    7
    8% Edit this list to specify the languages that should be translated. Each language should be written in lowercase:
    9
   10
   11
   12namespace(Data,Data1,Name1,Indent) :-
   13	Data = [Lang,Is_input,Namespace,Indent],
   14	Data1 = [Lang,Is_input,[Name1|Namespace],indent(Indent)],!.
   15
   16namespace(Data,Data1,Name,Indent) -->
   17	    {
   18                namespace(Data,Data1,Name,Indent)
   19        },
   20		optional_indent(Data,Indent),!.
   21
   22offside_rule_langs(['python','cython','coffeescript','english','cosmos','cobra']).
   23
   24prefix_arithmetic_langs(['racket','z3','clips','gnu smalltalk','newlisp','hy','common lisp','emacs lisp','clojure','sibilant','lispyscript']).
   25infix_arithmetic_langs(['pascal','sympy','vhdl','elixir','python','visual basic .net','ruby','lua','scriptol', 'z3py','ats','pydatalog','e','vbscript','livecode','monkey x','perl 6','englishscript','cython','gap','mathematical notation','wolfram','chapel','katahdin','frink','minizinc','picat','java','eclipse','d','ooc','genie','janus','pl/i','idp','processing','maxima','seed7','self','gnu smalltalk','drools','standard ml','oz','cobra','pike','prolog','engscript','kotlin','pawn','freebasic','matlab','ada','freebasic','gosu','gambas','nim','autoit','algol 68','ceylon','groovy','rust','coffeescript','typescript','fortran','octave','ml','hack','autohotkey','scala','delphi','tcl','swift','vala','c','f#','c++','dart','javascript','rebol','julia','erlang','ocaml','c#','nemerle','awk','java','perl','haxe','php','haskell','go','r','bc','visual basic']).
   26
   27
   28%Use this rule to define operators for various languages
   29
   30
   31infix_operator(Symbol,Exp1,Exp2) -->
   32        Exp1,python_ws,Symbol,python_ws,Exp2.
   33
   34prefix_operator(Data,Type,Symbol,Exp1,Exp2) -->
   35        "(",Symbol,ws_,expr(Data,Type,Exp1),ws_,expr(Data,Type,Exp2),")".
   36
   37
   38
   39function_name(Data,Type,A,Params) -->
   40        symbol(A),{reserved_words(A)}.
   41
   42
   43indent(Indent) --> (Indent,("\t")).
   44
   45
   46else(Data,Return_type,Statements_) -->
   47        {
   48                indent_data(Indent,Data,Data1),
   49                A = statements(Data1,Return_type,Statements_)
   50        },
   51        else(Data,[Indent,A]),!.
   52
   53
   54first_case(Data,Return_type,Switch_expr,int,[Expr_,Statements_,Case_or_default_]) -->
   55    {
   56            indent_data(Indent,Data,Data1),
   57            B=statements(Data1,Return_type,Statements_),
   58            Compare_expr = expr(Data,bool,compare(int,Switch_expr,Expr_)),
   59            Expr = expr(Data,int,Expr_),
   60
   61            Case_or_default = (case(Data,Return_type,Switch_expr,int,Case_or_default_);default(Data,Return_type,int,Case_or_default_))
   62    },
   63    optional_indent(Data,Indent),
   64    first_case_(Data,[B,Compare_expr,Expr,Case_or_default]),!.
   65
   66case(Data,Return_type,Switch_expr,int,[Expr_,Statements_,Case_or_default_]) -->
   67        {
   68                indent_data(Indent,Data,Data1),
   69                B=statements(Data1,Return_type,Statements_),
   70                A = expr(Data,bool,compare(int,Switch_expr,Expr_)),
   71                Expr = expr(Data,int,Expr_),
   72                Case_or_default = (case(Data,Return_type,Switch_expr,int,Case_or_default_);default(Data,Return_type,int,Case_or_default_))
   73        },
   74    optional_indent(Data,Indent),
   75    case(Data,[A,B,Expr,Case_or_default,Indent]),!.
   76
   77default(Data,Return_type,int,Statements_) -->
   78        {
   79                indent_data(Indent,Data,Data1),
   80                A = statements(Data1,Return_type,Statements_)
   81        },
   82        optional_indent(Data,Indent),
   83        default(Data,[A,Indent]),!.
   84
   85
   86
   87indent(Data,Indent) :-
   88	Data = [_,_,_,Indent].
   89
   90lang(Data,Lang) :-
   91	Data = [Lang|_].
   92
   93elif_statements(Data,Return_type,[A]) --> elif(Data,Return_type,A),!.
   94elif_statements(Data,Return_type,[A|B]) --> elif(Data,Return_type,A),elif_separator(Data),elif_statements(Data,Return_type,B),!.
   95
   96elif_separator(Data) -->
   97	ws.
   98
   99indent_data(Indent,Data,Data1) :-
  100    Data = [Lang,Is_input,Namespace,Indent],
  101    (
  102    Data1 = [Lang,Is_input,Namespace,indent(Indent)]).
  103
  104elif(Data,Return_type,[Expr_,Statements_]) -->
  105        {
  106                indent_data(Indent,Data,Data1),
  107                B=statements(Data1,Return_type,Statements_),
  108                A=expr(Data,bool,Expr_)
  109        },
  110        elif(Data,[Indent,A,B]),!.
  111
  112
  113%also called optional parameters
  114default_parameter(Data,[Type1,Name1,Default1]) -->
  115        {
  116                Type = type(Data,Type1),
  117                Name = var_name_(Data,Type1,Name1),
  118                Value = var_name_(Data,Type1,Default1)
  119        },
  120        default_parameter_(Data,[Type,Name,Value]).
  121
  122parameter(Data,[Type1,Name1]) -->
  123        {
  124                Type = type(Data,Type1),
  125                Name = var_name_(Data,Type1,Name1)
  126        },
  127		parameter_(Data,[Type,Name]),!.
  128
  129
  130
  131
  132%these parameters are used in a function's definition
  133optional_parameters(Data,A) --> "",parameters(Data,A).
  134
  135parameter1(Data,parameter(A)) -->
  136	parameter(Data,A).
  137parameter1(Data,default_parameter(A)) -->
  138	default_parameter(Data,A).
  139
  140parameters(Data,Params) --> 
  141	{Params = []}, "";parameters_(Data,Params).
  142parameters_(Data,[A]) -->
  143	parameter1(Data,A).
  144parameters_(Data,[A|B]) -->
  145	parameter1(Data,A),python_ws,parameter_separator(Data),python_ws,parameters_(Data,B).
  146
  147function_call_parameters(Data,[Params1_],[[Params2_,_]]) -->
  148        parentheses_expr(Data,Params2_,Params1_).
  149function_call_parameters(Data,[Params1_|Params1__],[[Params2_,_]|Params2__]) -->
  150        (parentheses_expr(Data,Params2_,Params1_),function_call_parameter_separator(Data),function_call_parameters(Data,Params1__,Params2__)).
  151
  152function_call_parameter_separator([Lang|_]) -->
  153    parameter_separator([Lang|_]).
  154
  155top_level_statement_separator(Data) -->
  156	{Data = [Lang|_], memberchk(Lang,['picat','prolog','logtalk','erlang','constraint handling rules'])} -> ws;
  157	statement_separator(Data).
  158
  159key_value(Data,Type,[Key_,Val_]) -->
  160        {
  161                A = symbol(Key_),
  162                B = expr(Data,Type,Val_)
  163        },
  164        key_value_(Data,[A,B]).
  165
  166ws(Data) -->
  167	{Data = [Lang|_]},
  168	({Lang='python'} ->
  169	python_ws;
  170	ws).
  171ws_(Data) -->
  172	{Data = [Lang|_]},
  173	({Lang='python'} ->
  174	python_ws_;ws_).
  175
  176top_level_statement(Data,Type,A_) -->
  177    {A = statement(Data,Type,A_)},
  178    top_level_statement_(Data,A).
  179
  180statements(Data,Return_type,[A]) --> statement(Data,Return_type,A).
  181statements(Data,Return_type,[A|B]) --> statement(Data,Return_type,A),statement_separator(Data),statements(Data,Return_type,B).
  182
  183
  184vars_list(Data,Type,[A]) --> var_name_(Data,Type,A).
  185vars_list(Data,Type,[A|B]) --> var_name_(Data,Type,A),",",vars_list(Data,Type,B).
  186
  187initialize_vars_list(Data,Type,[A]) --> {A = [A1,A2],A1_=var_name_(Data,Type,A1),A2_=parentheses_expr(Data,Type,A2)},set_var_(Data,[A1_,Type,A2_]).
  188initialize_vars_list(Data,Type,[A|B]) --> {A = [A1,A2],A1_=var_name_(Data,Type,A1),A2_=parentheses_expr(Data,Type,A2)},set_var_(Data,[A1_,Type,A2_]),",",initialize_vars_list(Data,Type,B).
  189
  190ws_separated_statements(Data,[A]) --> top_level_statement(Data,_,A).
  191ws_separated_statements(Data,[A|B]) --> top_level_statement(Data,_,A),top_level_statement_separator(Data),ws_separated_statements(Data,B).
  192
  193class_statements(Data,Class_name,[A]) --> class_statement(Data,Class_name,A).
  194class_statements(Data,Class_name,[A|B]) --> class_statement(Data,Class_name,A),statement_separator(Data),class_statements(Data,Class_name,B).
  195
  196dict_(Data,Type,[A]) --> key_value(Data,Type,A).
  197dict_(Data,Type,[A|B]) --> key_value(Data,Type,A),key_value_separator(Data),dict_(Data,Type,B).
  198
  199initializer_list_(Data,Type,[A]) --> expr(Data,Type,A).
  200initializer_list_(Data,Type,[A|B]) --> expr(Data,Type,A),initializer_list_separator(Data),initializer_list_(Data,Type,B).
  201
  202enum_list(Data,[A]) --> enum_list_(Data,A).
  203enum_list(Data,[A|B]) --> enum_list_(Data,A),enum_list_separator(Data),enum_list(Data,B).
  204
  205enum_list_(Data,A_) -->
  206			{
  207					A = symbol(A_)
  208			},
  209			enum_list_(Data,[A]).
  210
  211
  212
  213
  214
  215between_(A,B,C) :- char_code(A,A1),char_code(B,B1),nonvar(C),char_code(C,C1),between(A1,B1,C1).
  216
  217
  218char_literal(A) --> "\'",{dif(A,"\'"),dif(A,"\n")},[A],"\'".
  219
  220:-include(common_grammar).  221
  222regex_literal(Data,S_) -->
  223    {S = regex_inner(S_)},
  224    regex_literal_(Data,[S]).
  225
  226comment_inner([A]) --> comment_inner_(A).
  227comment_inner([A|B]) --> comment_inner_(A),comment_inner(B).
  228comment_inner_(A) --> {dif(A,'\n')},[A].
  229regex_inner([A]) --> regex_inner_(A).
  230regex_inner([A|B]) --> regex_inner_(A),regex_inner(B).
  231regex_inner_(A) --> {A="\\\"";A="\\\'"},A;{dif(A,'"'),dif(A,'\n')},[A].
  232
  233
  234statements_with_ws(Data,A) -->
  235    (include_in_each_file(Data);""),ws_separated_statements(Data,A),ws.
  236
  237
  238print_var_types([A]) :-
  239    writeln(A).
  240print_var_types([A|Rest]) :-
  241    writeln(A),print_var_types(Rest).
  242
  243
  244parse(javascript,_,_,Input,Ls) :-
  245	phrase(statements_with_ws([javascript,true,[],"\n"],Ls), Input),
  246	writeln(Ls).
  247
  248
  249:- include(grammars).  250:- include(statement).  251:- include(statement_with_semicolon).  252:- include(class_statement).  253:- include(expr).  254:- include(dot_expr).  255:- include(parentheses_expr).