-
Notifications
You must be signed in to change notification settings - Fork 56
/
code.go
149 lines (117 loc) · 3.7 KB
/
code.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package py
/*
#include <Python.h>
static inline int codeCheck(PyObject *o) { return PyCode_Check(o); }
static inline void decref(PyObject *obj) { Py_DECREF(obj); }
static inline FILE* openFile(char* name) {
return fopen(name, "r");
}
static inline PyObject* compileString(char* text, char* filename, int start) {
return Py_CompileString(text, filename, start);
}
static PyObject* compileFile(FILE* f, char* name, int start) {
struct _node *n = PyParser_SimpleParseFile(f, name, start);
if (!n) return NULL;
return (PyObject*)PyNode_Compile(n, name);
}
*/
import "C"
import "unsafe"
// ------------------------------------------------------------------------------------------
// type StartToken
type StartToken int
const (
EvalInput = StartToken(C.Py_eval_input) // for isolated expressions
FileInput = StartToken(C.Py_file_input) // for sequences of statements as read from a file or other source;
// to use when compiling arbitrarily long Python source code.
SingleInput = StartToken(C.Py_single_input) // for a single statement; used for the interactive interpreter loop.
)
// ------------------------------------------------------------------------------------------
// type Code
type Code struct {
Base
o C.PyCodeObject
}
// CodeType is the Type object that represents the Code type.
var CodeType = (*Type)(unsafe.Pointer(&C.PyCode_Type))
func newCode(obj *C.PyObject) *Code {
return (*Code)(unsafe.Pointer(obj))
}
func AsCode(o *Base) (v *Code, ok bool) {
if ok = C.codeCheck(o.c()) != 0; ok {
v = newCode(o.c())
}
return
}
func Compile(text, filename string, start StartToken) (*Code, error) {
t := C.CString(text)
defer C.free(unsafe.Pointer(t))
fn := C.CString(filename)
defer C.free(unsafe.Pointer(fn))
ret := C.compileString(t, fn, C.int(start))
if ret == nil {
return nil, exception()
}
return newCode(ret), nil
}
func CompileFile(name string, start StartToken) (*Code, error) {
fn := C.CString(name)
defer C.free(unsafe.Pointer(fn))
file, err := C.openFile(fn)
if file == nil {
return nil, err
}
defer C.fclose(file)
ret := C.compileFile(file, fn, C.int(start))
if ret == nil {
return nil, exception()
}
return newCode(ret), nil
}
// Return value: New reference.
func (code *Code) Eval(globals, locals *Base) (*Base, error) {
pyCode := (*C.PyCodeObject)(unsafe.Pointer(code))
ret := C.PyEval_EvalCode(pyCode, globals.c(), locals.c())
return obj2ObjErr(ret)
}
func (code *Code) Run(globals, locals *Base) error {
pyCode := (*C.PyCodeObject)(unsafe.Pointer(code))
ret := C.PyEval_EvalCode(pyCode, globals.c(), locals.c())
if ret == nil {
return exception()
}
C.decref(ret)
return nil
}
// ------------------------------------------------------------------------------------------
func Run(text string) error {
t := C.CString(text)
defer C.free(unsafe.Pointer(t))
ret := C.PyRun_SimpleStringFlags(t, nil)
return int2Err(ret)
}
// Return a dictionary of the builtins in the current execution frame, or the interpreter of
// the thread state if no frame is currently executing.
//
// Return value: Borrowed reference.
func GetBuiltins() *Base {
ret := C.PyEval_GetBuiltins()
return newObject(ret)
}
// Return a dictionary of the global variables in the current execution frame,
// or NULL if no frame is currently executing.
//
// Return value: Borrowed reference
func GetLocals() *Base {
ret := C.PyEval_GetLocals()
return newObject(ret)
}
// Return a dictionary of the local variables in the current execution frame,
// or NULL if no frame is currently executing.
//
// Return value: Borrowed reference
func GetGlobals() *Base {
ret := C.PyEval_GetGlobals()
return newObject(ret)
}
// ------------------------------------------------------------------------------------------