| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  | #include <Python.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-23 18:36:06 +03:00
										 |  |  | #include "pegen_interface.h"
 | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  | static int | 
					
						
							|  |  |  | _mode_str_to_int(char *mode_str) | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     int mode; | 
					
						
							|  |  |  |     if (strcmp(mode_str, "exec") == 0) { | 
					
						
							|  |  |  |         mode = Py_file_input; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     else if (strcmp(mode_str, "eval") == 0) { | 
					
						
							|  |  |  |         mode = Py_eval_input; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     else if (strcmp(mode_str, "single") == 0) { | 
					
						
							|  |  |  |         mode = Py_single_input; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |         mode = -1; | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     return mode; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  | static mod_ty | 
					
						
							|  |  |  | _run_parser(char *str, char *filename, int mode, PyCompilerFlags *flags, PyArena *arena, int oldparser) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     mod_ty mod; | 
					
						
							|  |  |  |     if (!oldparser) { | 
					
						
							|  |  |  |         mod = PyPegen_ASTFromString(str, filename, mode, flags, arena); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         mod = PyParser_ASTFromString(str, filename, mode, flags, arena); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return mod; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | _Py_compile_string(PyObject *self, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static char *keywords[] = {"string", "filename", "mode", "oldparser", NULL}; | 
					
						
							|  |  |  |     char *the_string; | 
					
						
							|  |  |  |     char *filename = "<string>"; | 
					
						
							|  |  |  |     char *mode_str = "exec"; | 
					
						
							|  |  |  |     int oldparser = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|ssp", keywords, | 
					
						
							|  |  |  |             &the_string, &filename, &mode_str, &oldparser)) { | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     int mode = _mode_str_to_int(mode_str); | 
					
						
							|  |  |  |     if (mode == -1) { | 
					
						
							|  |  |  |         return PyErr_Format(PyExc_ValueError, "mode must be either 'exec' or 'eval' or 'single'"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-27 18:02:07 +01:00
										 |  |  |     PyCompilerFlags flags = _PyCompilerFlags_INIT; | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     flags.cf_flags = PyCF_IGNORE_COOKIE; | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     PyArena *arena = PyArena_New(); | 
					
						
							|  |  |  |     if (arena == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mod_ty mod = _run_parser(the_string, filename, mode, &flags, arena, oldparser); | 
					
						
							|  |  |  |     if (mod == NULL) { | 
					
						
							|  |  |  |         PyArena_Free(arena); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     PyObject *filename_ob = PyUnicode_DecodeFSDefault(filename); | 
					
						
							|  |  |  |     if (filename_ob == NULL) { | 
					
						
							|  |  |  |         PyArena_Free(arena); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     PyCodeObject *result = PyAST_CompileObject(mod, filename_ob, &flags, -1, arena); | 
					
						
							|  |  |  |     Py_XDECREF(filename_ob); | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     PyArena_Free(arena); | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     return (PyObject *)result; | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | _Py_parse_string(PyObject *self, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-05 21:41:12 -07:00
										 |  |  |     static char *keywords[] = {"string", "filename", "mode", "oldparser", "ast", NULL}; | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     char *the_string; | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     char *filename = "<string>"; | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     char *mode_str = "exec"; | 
					
						
							| 
									
										
										
										
											2020-04-30 01:53:30 +03:00
										 |  |  |     int oldparser = 0; | 
					
						
							| 
									
										
										
										
											2020-06-05 21:41:12 -07:00
										 |  |  |     int ast = 1; | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-05 21:41:12 -07:00
										 |  |  |     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|sspp", keywords, | 
					
						
							|  |  |  |             &the_string, &filename, &mode_str, &oldparser, &ast)) { | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     int mode = _mode_str_to_int(mode_str); | 
					
						
							|  |  |  |     if (mode == -1) { | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |         return PyErr_Format(PyExc_ValueError, "mode must be either 'exec' or 'eval' or 'single'"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     PyCompilerFlags flags = _PyCompilerFlags_INIT; | 
					
						
							|  |  |  |     flags.cf_flags = PyCF_IGNORE_COOKIE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     PyArena *arena = PyArena_New(); | 
					
						
							|  |  |  |     if (arena == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     mod_ty mod = _run_parser(the_string, filename, mode, &flags, arena, oldparser); | 
					
						
							|  |  |  |     if (mod == NULL) { | 
					
						
							|  |  |  |         PyArena_Free(arena); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-05 21:41:12 -07:00
										 |  |  |     PyObject *result; | 
					
						
							|  |  |  |     if (ast) { | 
					
						
							|  |  |  |         result = PyAST_mod2obj(mod); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         Py_INCREF(Py_None); | 
					
						
							|  |  |  |         result = Py_None; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     PyArena_Free(arena); | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef ParseMethods[] = { | 
					
						
							| 
									
										
										
										
											2020-05-25 13:11:36 -07:00
										 |  |  |     { | 
					
						
							|  |  |  |         "parse_string", | 
					
						
							|  |  |  |         (PyCFunction)(void (*)(void))_Py_parse_string, | 
					
						
							|  |  |  |         METH_VARARGS|METH_KEYWORDS, | 
					
						
							|  |  |  |         "Parse a string, return an AST." | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         "compile_string", | 
					
						
							|  |  |  |         (PyCFunction)(void (*)(void))_Py_compile_string, | 
					
						
							|  |  |  |         METH_VARARGS|METH_KEYWORDS, | 
					
						
							|  |  |  |         "Compile a string, return a code object." | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     {NULL, NULL, 0, NULL} /* Sentinel */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyModuleDef parsemodule = { | 
					
						
							|  |  |  |     PyModuleDef_HEAD_INIT, | 
					
						
							|  |  |  |     .m_name = "peg_parser", | 
					
						
							|  |  |  |     .m_doc = "A parser.", | 
					
						
							|  |  |  |     .m_methods = ParseMethods, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyMODINIT_FUNC | 
					
						
							|  |  |  | PyInit__peg_parser(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return PyModule_Create(&parsemodule); | 
					
						
							|  |  |  | } |