(** Bombs-Must-Detonate: AST Definition & Print function @author Brian Go *) (** SYNTAX TREE *) (** Field info is annotated by the type checker for use in the IR compiler *) type field_info = VIdUnspecified (** Not yet set by type checker *) | VIdStructField of int (** The field is the (int)th field of the struct *) | VIdEnumValue of int (** The field is the (int)th value of an enum *) (** Top-level expressions *) type global_expression = SynFunctionDeclare of function_declare | SynRemotableFunctionDeclare of function_declare | SynTemplatedDeclare of string list * global_expression | SynFunctionDefine of function_define | SynTemplatedDefine of string list * global_expression | SynStructDeclare of struct_declare | SynGlobalEnumDeclare of enum_declare | SynGlobalVarDeclare of var_declare | SynInclude of include_data ref | SynStateMachine of fsm_state_machine (** The include string is replaced by an AST so as to only parse it once *) and include_data = IncludeFileName of string | IncludeAst of global_expression list (** Expressions *) and expression = SynVarDeclare of var_declare | SynEnumDeclare of enum_declare | SynVarAssign of var_assign | SynCond of conditional | SynLoop of loop | SynFunctionCall of function_call | SynReturnStatement of return_statement | SynBreak (** Produces a type error if not in a loop *) | SynContinue (** Produces a type error if not in a loop *) (** Functions *) and function_declare = data_type * string * (data_type * string) list (** return type, name, arg list *) and function_define = function_declare * expression list (** declaration, body *) and function_call = SynLocalCall of string * value_producer list * bool ref (** name, args, true if it is a variable-function *) | SynRemoteCall of string * value_producer list * var_ident (** name, args, return value target variable *) | SynRemoteCallNoResult of string * value_producer list (** name, args *) and return_statement = SynVoidReturn | SynValueReturn of value_producer (** Data Structures *) and struct_declare = string * var_declare list (** name, fields *) and enum_declare = string * string list (** name, values *) (** Variables *) and var_declare = SynVarDeclareNoInit of data_type * string (** type, name *) | SynVarDeclareWithInit of data_type * string * value_producer (** type, name, initial value *) and var_assign = SynVarAssignment of var_ident * value_producer (** var_ident = value_producer *) | SynVarModify of var_ident * binop * value_producer (** e.g. +=,*=. for cons (::=), the list is on the LHS *) (** Conditionals *) and conditional = SynIf of value_producer * expression list | SynIfCase of value_producer * expression list * continued_conditional and continued_conditional = SynFinalElse of expression list | SynElse of conditional (** Loops *) and loop = SynWhile of value_producer * expression list | SynFor of expression * value_producer * expression * expression list (** init, test, step, body. Note: step expression must end in a semicolon *) | SynDoWhile of expression list * value_producer (** Value Producers *) and value_producer = SynValue of value | SynFunctionCallValue of function_call | SynVarIdentifier of var_ident | SynBinop of value_producer * binop * value_producer | SynPrefixUnop of pre_unop * value_producer | SynParenthesized of value_producer | SynArrayValueProducer of value_producer list | SynListValueProducer of list_value_producer and value = SynIntValue of int | SynFloatValue of float | SynStringValue of string | SynBoolValue of bool and list_value_producer = SynListNil of data_type | SynListList of value_producer list | SynListCons of value_producer * value_producer (** car, cdr *) and var_ident = SynVarName of string | SynStructOrEnumValue of var_ident * string * field_info ref (** field info set by type checker for use by IR compiler *) | SynArrayCell of var_ident * value_producer (** Data Types *) and data_type = SynIntType | SynFloatType | SynStringType | SynBoolType | SynVoidType | SynEnumOrStructType of string * (data_type list) ref (** field types set by type checker for use by IR compiler *) | SynArrayType of data_type * value_producer | SynListType of data_type | SynRefType of data_type | SynArrowType of data_type list * data_type (** arg types, return type *) (** Operators *) and binop = | SynBinopAnd | SynBinopOr | SynBinopAdd | SynBinopSub | SynBinopMul | SynBinopDiv | SynBinopIDiv | SynBinopMod | SynBinopConcat | SynBinopCons | SynCompLt | SynCompGt | SynCompLte | SynCompGte | SynCompEq | SynCompNeq and pre_unop = | SynUnopNot | SynUnopCar | SynUnopCdr | SynUnopTrunc | SynUnopDeref | SynUnopNeg | SynUnopNull (** State Machine Syntax *) and fsm_state_machine = string * string * fsm_state list (** name, onInit handler, state list *) and fsm_state = string * fsm_callback list * fsm_transition list (** name, callbacks, transitions *) and fsm_callback = SynFsmOnInit of string (** This is not actually a callback but is executed every time the state is visited *) | SynFsmOnMoveRequest of string | SynFsmOnTeammateDeath of string | SynFsmOnBombDetonate of string | SynFsmOnDeath of string and fsm_transition = string list * (string * float) list and src_program = global_expression list let concat s = String.concat "" s 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 -> "!=" let string_of_ast ast = concat (List.map string_of_global_expression ast) let print_ast ast = print_string (string_of_ast ast)