Visitor to generate constructor functions for AST.
| 409 | |
| 410 | |
| 411 | class FunctionVisitor(PrototypeVisitor): |
| 412 | """Visitor to generate constructor functions for AST.""" |
| 413 | |
| 414 | def emit_function(self, name, ctype, args, attrs, union=True): |
| 415 | def emit(s, depth=0, reflow=True): |
| 416 | self.emit(s, depth, reflow) |
| 417 | argstr = ", ".join(["%s %s" % (atype, aname) |
| 418 | for atype, aname, opt in args + attrs]) |
| 419 | if argstr: |
| 420 | argstr += ", PyArena *arena" |
| 421 | else: |
| 422 | argstr = "PyArena *arena" |
| 423 | self.emit("%s" % ctype, 0) |
| 424 | emit("%s(%s)" % (ast_func_name(name), argstr)) |
| 425 | emit("{") |
| 426 | emit("%s p;" % ctype, 1) |
| 427 | for argtype, argname, opt in args: |
| 428 | if not opt and argtype != "int": |
| 429 | emit("if (!%s) {" % argname, 1) |
| 430 | emit("PyErr_SetString(PyExc_ValueError,", 2) |
| 431 | msg = "field '%s' is required for %s" % (argname, name) |
| 432 | emit(' "%s");' % msg, |
| 433 | 2, reflow=False) |
| 434 | emit('return NULL;', 2) |
| 435 | emit('}', 1) |
| 436 | |
| 437 | emit("p = (%s)_PyArena_Malloc(arena, sizeof(*p));" % ctype, 1); |
| 438 | emit("if (!p)", 1) |
| 439 | emit("return NULL;", 2) |
| 440 | if union: |
| 441 | self.emit_body_union(name, args, attrs) |
| 442 | else: |
| 443 | self.emit_body_struct(name, args, attrs) |
| 444 | emit("return p;", 1) |
| 445 | emit("}") |
| 446 | emit("") |
| 447 | |
| 448 | def emit_body_union(self, name, args, attrs): |
| 449 | def emit(s, depth=0, reflow=True): |
| 450 | self.emit(s, depth, reflow) |
| 451 | emit("p->kind = %s_kind;" % name, 1) |
| 452 | for argtype, argname, opt in args: |
| 453 | emit("p->v.%s.%s = %s;" % (name, argname, argname), 1) |
| 454 | for argtype, argname, opt in attrs: |
| 455 | emit("p->%s = %s;" % (argname, argname), 1) |
| 456 | |
| 457 | def emit_body_struct(self, name, args, attrs): |
| 458 | def emit(s, depth=0, reflow=True): |
| 459 | self.emit(s, depth, reflow) |
| 460 | for argtype, argname, opt in args: |
| 461 | emit("p->%s = %s;" % (argname, argname), 1) |
| 462 | for argtype, argname, opt in attrs: |
| 463 | emit("p->%s = %s;" % (argname, argname), 1) |
| 464 | |
| 465 | |
| 466 | class PickleVisitor(EmitVisitor): |
no outgoing calls
no test coverage detected
searching dependent graphs…