let rec string_of_global_expression expr = match expr with
SynFunctionDeclare (dt,s,arglist) ->
concat [string_of_datatype dt;" ";s;"(";string_of_arglist arglist;");\n"]
| SynRemotableFunctionDeclare (dt,s,arglist) ->
concat ["remotable ";string_of_datatype dt;" ";s;"(";string_of_arglist arglist;");\n"]
| SynTemplatedDeclare (slist,gexpr) ->
concat ["template <";string_of_string_list slist;">\n"; string_of_global_expression gexpr]
| SynFunctionDefine ((dt,s,arglist),expr_list) ->
concat [string_of_datatype dt;" ";s;"(";string_of_arglist arglist;") {\n";string_of_expr_list expr_list;"}\n"]
| SynTemplatedDefine (slist,gexpr) ->
concat ["template <";string_of_string_list slist;">\n"; string_of_global_expression gexpr]
| SynStructDeclare (sname,vdecl_list) ->
concat ["struct ";sname;" {\n";string_of_var_declare_list vdecl_list;"};\n"]
| SynGlobalEnumDeclare (ename,slist) ->
concat ["enum ";ename;" {";string_of_string_list slist;"};\n"]
| SynGlobalVarDeclare vdecl ->
concat [string_of_var_declare vdecl;";\n"]
| SynInclude include_data ->
concat ["include \"";string_of_include !include_data;"\"\n"]
| SynStateMachine _ ->
raise (Failure "Source-to-source FSM compilation did not occur (code 2).")
and string_of_arglist arglist = match arglist with
(dt,vname)::[] -> concat [string_of_datatype dt;" ";vname]
| (dt,vname)::rest -> concat [string_of_datatype dt;" ";vname;", "]
| [] -> ""
and string_of_datatype dt = match dt with
SynIntType -> "int"
| SynFloatType -> "float"
| SynStringType -> "string"
| SynBoolType -> "bool"
| SynVoidType -> "void"
| SynEnumOrStructType (sname,_) -> sname
| SynArrayType (t,vprod) -> concat [string_of_datatype t;" array [";string_of_value_producer vprod;"]"]
| SynListType t -> concat [string_of_datatype t;" list"]
| SynRefType t -> concat [string_of_datatype t;" ref"]
| SynArrowType (dt_list,t) -> concat ["(";string_of_datatype_list dt_list;") -> ";string_of_datatype t]
and string_of_string_list slist = match slist with
cur::[] -> cur
| cur::rest -> concat [cur;", ";string_of_string_list rest]
| [] -> ""
and string_of_expr_list expr_list = match expr_list with
expr::rest -> concat [string_of_expr expr;string_of_expr_list rest]
| [] -> ""
and string_of_var_declare_list vdecl_list = match vdecl_list with
vdecl::[] -> concat [string_of_var_declare vdecl]
| vdecl::rest -> concat [string_of_var_declare vdecl;", ";string_of_var_declare_list rest]
| [] -> ""
and string_of_var_declare vdecl = match vdecl with
SynVarDeclareNoInit (dt,name) ->
concat [string_of_datatype dt;" ";name]
| SynVarDeclareWithInit (dt,name,vprod) ->
concat [string_of_datatype dt;" ";name;" = ";string_of_value_producer vprod]
and string_of_include data = match data with
IncludeFileName s -> s
| _ -> raise (Failure "Source-to-source FSM compilation did not occur (code 1).")
and string_of_value_producer vprod = match vprod with
SynValue v ->
string_of_value v
| SynFunctionCallValue funcall ->
string_of_function_call funcall
| SynVarIdentifier vident ->
string_of_variable_identifier vident
| SynBinop (vprod1,binop,vprod2) ->
concat [string_of_value_producer vprod1;" "; string_of_binop binop;" "; string_of_value_producer vprod2]
| SynPrefixUnop (op,vprod) ->
concat [string_of_unop op;" ";string_of_value_producer vprod]
| SynParenthesized vprod ->
concat ["(";string_of_value_producer vprod;")"]
| SynArrayValueProducer vprod_list ->
concat ["{";string_of_value_producer_list vprod_list ",";"}"]
| SynListValueProducer lval_prod ->
string_of_list_value_producer lval_prod
and string_of_datatype_list dt_list = match dt_list with
cur::[] -> string_of_datatype cur
| cur::rest -> concat [string_of_datatype cur; string_of_datatype_list rest]
| [] -> ""
and string_of_expr expr = match expr with
SynVarDeclare vdecl ->
concat [string_of_var_declare vdecl;";\n"]
| SynEnumDeclare (ename,slist) ->
concat ["enum ";ename;" {";string_of_string_list slist;"};\n"]
| SynVarAssign vasgn ->
concat [string_of_var_assign vasgn;";\n"]
| SynCond cond ->
concat [string_of_conditional cond;"\n"]
| SynLoop loop ->
concat [string_of_loop loop;"\n"]
| SynFunctionCall funcall ->
concat [string_of_function_call funcall;";\n"]
| SynReturnStatement ret ->
concat [string_of_return_statement ret;";\n"]
| SynBreak -> "break;\n"
| SynContinue -> "continue;\n";
and string_of_value value = match value with
SynIntValue i -> string_of_int i
| SynFloatValue f -> string_of_float f
| SynStringValue s -> s
| SynBoolValue b -> if b then "true" else "false"
and string_of_function_call funcall = match funcall with
SynLocalCall (foo,vprod_list,_) ->
concat [foo;"(";string_of_value_producer_list vprod_list ",";")"]
| SynRemoteCall (foo,vprod_list,retvar) ->
concat ["!(";foo;"(";string_of_value_producer_list vprod_list ",";"), ";string_of_variable_identifier retvar;")"]
| SynRemoteCallNoResult (foo,vprod_list) ->
concat ["!(";foo;"(";string_of_value_producer_list vprod_list ",";")"]
and string_of_variable_identifier vident = match vident with
SynVarName s -> s
| SynStructOrEnumValue (vident,s,_) ->
concat [string_of_variable_identifier vident;".";s]
| SynArrayCell (vident,vprod) ->
concat [string_of_variable_identifier vident;"[";string_of_value_producer vprod;"]"]
and string_of_unop op = match op with
SynUnopNot -> "not"
| SynUnopCar -> "car"
| SynUnopCdr -> "cdr"
| SynUnopTrunc -> "trunc"
| SynUnopDeref -> "$"
| SynUnopNeg -> "-"
| SynUnopNull -> "null"
and string_of_value_producer_list vprod_list del = match vprod_list with
cur::[] ->
string_of_value_producer cur
| cur::rest ->
concat [string_of_value_producer cur;del;" ";string_of_value_producer_list rest del]
| [] -> ""
and string_of_list_value_producer vprod = match vprod with
SynListNil dt ->
concat ["nil[";string_of_datatype dt;"]"]
| SynListList vp_lst ->
concat ["[";string_of_value_producer_list vp_lst ";";"]"]
| SynListCons (vp1,vp2) ->
concat [string_of_value_producer vp1;"::";string_of_value_producer vp2]
and string_of_var_assign vasgn = match vasgn with
SynVarAssignment (vident,vprod) ->
concat [string_of_variable_identifier vident;" = ";string_of_value_producer vprod]
| SynVarModify (vident,binop,vprod) ->
concat [string_of_variable_identifier vident;" ";string_of_binop binop;"= ";string_of_value_producer vprod]
and string_of_conditional cond = match cond with
SynIf (vprod,expr_list) ->
concat ["if (";string_of_value_producer vprod;") {\n";string_of_expr_list expr_list;"}\n"]
| SynIfCase (vprod,expr_list,continued_cond) ->
concat ["if (";string_of_value_producer vprod;") {\n";string_of_expr_list expr_list;"}\n";string_of_continued_conditional continued_cond]
and string_of_continued_conditional cond = match cond with
SynFinalElse expr_list ->
concat ["else {\n";string_of_expr_list expr_list;"}\n"]
| SynElse cond ->
concat ["else ";string_of_conditional cond]
and string_of_loop loop = match loop with
SynWhile (vprod,expr_list) ->
concat ["while (";string_of_value_producer vprod;") {\n";string_of_expr_list expr_list;"}\n"]
| SynFor (expr_init,vprod,expr_step,expr_list) ->
concat ["for (";string_of_expr expr_init;string_of_value_producer vprod;";\n";string_of_expr expr_step;") {\n";string_of_expr_list expr_list;"}\n"]
| SynDoWhile (expr_list,vprod) ->
concat ["do {\n";string_of_expr_list expr_list;"} while (";string_of_value_producer vprod;")"]
and string_of_return_statement ret = match ret with
SynVoidReturn -> "return"
| SynValueReturn vprod ->
concat ["return ";string_of_value_producer vprod]
and string_of_binop op = match op with
SynBinopAnd -> "and"
| SynBinopOr -> "or"
| SynBinopAdd -> "add"
| SynBinopSub -> "sub"
| SynBinopMul -> "mul"
| SynBinopDiv -> "div"
| SynBinopIDiv -> "idiv"
| SynBinopMod -> "mod"
| SynBinopConcat -> "concat"
| SynBinopCons -> "::"
| SynCompLt -> "<"
| SynCompGt -> ">"
| SynCompLte -> "<="
| SynCompGte -> ">="
| SynCompEq -> "="
| SynCompNeq -> "!="