12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697openErrorstypesexp=|Integerofint|Floatoffloat|Stringofstring|Symbolofstring|SExpofsexplistletrecrender_string_of_sexp(se:sexp):string=matchsewith|Integeri->string_of_inti|Floatf->string_of_floatf|Strings->"\""^s^"\""|Symbols->s|SExpsexps->"("^String.concat" "(List.maprender_string_of_sexpsexps)^")"letrecrepr_string_of_sexp(se:sexp):string=matchsewith|Integeri->"Integer "^string_of_inti|Floatf->"Float "^string_of_floatf|Strings->{|String "|}^s^{|"|}|Symbols->{|Symbol "|}^s^{|"|}|SExpsexps->"SExp ["^String.concat"; "(List.maprepr_string_of_sexpsexps)^"]"letsexp_not_err(desired_type:string)(se:sexp):'a=letarticle=ifList.exists((=)desired_type.[0])['a';'e';'i';'o';'u']then"an"else"a"inraise(CamlrackError("S-Expression is not "^article^" "^desired_type^": "^render_string_of_sexpse))(* The following functions are based heavily (almost exactly copied) from the
PLAIT language by Matthew Flatt:
https://docs.racket-lang.org/plait/Predefined_Functions_and_Constants.html#%28part._.S-.Expressions%29
*)letsexp_to_list_opt(se:sexp):(sexplist)option=matchsewith|SExpsexps->Somesexps|_->Noneletsexp_to_list(se:sexp):sexplist=matchsexp_to_list_optsewith|Someses->ses|None->sexp_not_err"list"seletlist_to_sexp(ses:sexplist):sexp=SExpsesletsexp_to_int_opt(se:sexp):intoption=matchsewith|Integeri->Somei|_->Noneletsexp_to_int(se:sexp):int=matchsexp_to_int_optsewith|Somei->i|None->sexp_not_err"integer"seletint_to_sexp(i:int):sexp=Integeriletsexp_to_float_opt(se:sexp):floatoption=matchsewith|Floatf->Somef|_->Noneletsexp_to_float(se:sexp):float=matchsexp_to_float_optsewith|Somef->f|None->sexp_not_err"float"seletfloat_to_sexp(f:float):sexp=Floatfletsexp_to_string_opt(se:sexp):stringoption=matchsewith|Strings->Somes|_->Noneletsexp_to_string(se:sexp):string=matchsexp_to_string_optsewith|Somes->s|None->sexp_not_err"string"seletstring_to_sexp(s:string):sexp=Stringsletsexp_to_symbol_opt(se:sexp):stringoption=matchsewith|Symbols->Somes|_->Noneletsexp_to_symbol(se:sexp):string=matchsexp_to_symbol_optsewith|Somes->s|None->sexp_not_err"symbol"seletsymbol_to_sexp(s:string):sexp=Symbols