@@ -3,6 +3,7 @@ package builtin
3
3
4
4
import (
5
5
"fmt"
6
+ "github.com/ncw/gpython/compile"
6
7
"github.com/ncw/gpython/py"
7
8
"github.com/ncw/gpython/vm"
8
9
"unicode/utf8"
@@ -24,7 +25,7 @@ func init() {
24
25
// py.NewMethod("bin", builtin_bin, 0, bin_doc),
25
26
// py.NewMethod("callable", builtin_callable, 0, callable_doc),
26
27
// py.NewMethod("chr", builtin_chr, 0, chr_doc),
27
- // py.NewMethod("compile", builtin_compile, 0, compile_doc),
28
+ py .NewMethod ("compile" , builtin_compile , 0 , compile_doc ),
28
29
// py.NewMethod("delattr", builtin_delattr, 0, delattr_doc),
29
30
// py.NewMethod("dir", builtin_dir, 0, dir_doc),
30
31
// py.NewMethod("divmod", builtin_divmod, 0, divmod_doc),
@@ -444,3 +445,101 @@ func builtin_setattr(self py.Object, args py.Tuple) py.Object {
444
445
445
446
return py .SetAttr (v , name , value )
446
447
}
448
+
449
+ // Reads the source as a string
450
+ func source_as_string (cmd py.Object , funcname , what string /*, PyCompilerFlags *cf */ ) string {
451
+ // FIXME only understands strings, not bytes etc at the moment
452
+ if str , ok := cmd .(py.String ); ok {
453
+ // FIXME cf->cf_flags |= PyCF_IGNORE_COOKIE;
454
+ return string (str )
455
+ }
456
+ // } else if (!PyObject_CheckReadBuffer(cmd)) {
457
+ panic (py .ExceptionNewf (py .TypeError , "%s() arg 1 must be a %s object" , funcname , what ))
458
+ // } else if (PyObject_AsReadBuffer(cmd, (const void **)&str, &size) < 0) {
459
+ // return nil;
460
+ }
461
+
462
+ const compile_doc = `compile(source, filename, mode[, flags[, dont_inherit]]) -> code object
463
+
464
+ Compile the source string (a Python module, statement or expression)
465
+ into a code object that can be executed by exec() or eval().
466
+ The filename will be used for run-time error messages.
467
+ The mode must be 'exec' to compile a module, 'single' to compile a
468
+ single (interactive) statement, or 'eval' to compile an expression.
469
+ The flags argument, if present, controls which future statements influence
470
+ the compilation of the code.
471
+ The dont_inherit argument, if non-zero, stops the compilation inheriting
472
+ the effects of any future statements in effect in the code calling
473
+ compile; if absent or zero these statements do influence the compilation,
474
+ in addition to any features explicitly specified.`
475
+
476
+ func builtin_compile (self py.Object , args py.Tuple , kwargs py.StringDict ) py.Object {
477
+ // FIXME lots of unsupported stuff here!
478
+ var filename py.Object
479
+ var startstr py.Object
480
+ // var mode = -1
481
+ var dont_inherit py.Object = py .Int (0 )
482
+ var supplied_flags py.Object = py .Int (0 )
483
+ var optimizeInt py.Object = py .Int (- 1 )
484
+ //is_ast := false
485
+ // var cf PyCompilerFlags
486
+ var cmd py.Object
487
+ kwlist := []string {"source" , "filename" , "mode" , "flags" , "dont_inherit" , "optimize" }
488
+ // start := []int{Py_file_input, Py_eval_input, Py_single_input}
489
+ var result py.Object
490
+
491
+ py .ParseTupleAndKeywords (args , kwargs , "Oss|iii:compile" , kwlist ,
492
+ & cmd ,
493
+ & filename ,
494
+ & startstr ,
495
+ & supplied_flags ,
496
+ & dont_inherit ,
497
+ & optimizeInt )
498
+
499
+ // cf.cf_flags = supplied_flags | PyCF_SOURCE_IS_UTF8
500
+
501
+ // if supplied_flags&^(PyCF_MASK|PyCF_MASK_OBSOLETE|PyCF_DONT_IMPLY_DEDENT|PyCF_ONLY_AST) != 0 {
502
+ // panic(py.ExceptionNewf(py.ValueError, "compile(): unrecognised flags"))
503
+ // }
504
+ // XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0?
505
+
506
+ optimize := int (optimizeInt .(py.Int ))
507
+ if optimize < - 1 || optimize > 2 {
508
+ panic (py .ExceptionNewf (py .ValueError , "compile(): invalid optimize value" ))
509
+ }
510
+
511
+ if dont_inherit .(py.Int ) != 0 {
512
+ // PyEval_MergeCompilerFlags(&cf)
513
+ }
514
+
515
+ // switch string(startstr.(py.String)) {
516
+ // case "exec":
517
+ // mode = 0
518
+ // case "eval":
519
+ // mode = 1
520
+ // case "single":
521
+ // mode = 2
522
+ // default:
523
+ // panic(py.ExceptionNewf(py.ValueError, "compile() arg 3 must be 'exec', 'eval' or 'single'"))
524
+ // }
525
+
526
+ // is_ast = PyAST_Check(cmd)
527
+ // if is_ast {
528
+ // if supplied_flags & PyCF_ONLY_AST {
529
+ // result = cmd
530
+ // } else {
531
+
532
+ // arena := PyArena_New()
533
+ // mod := PyAST_obj2mod(cmd, arena, mode)
534
+ // PyAST_Validate(mod)
535
+ // result = PyAST_CompileObject(mod, filename, &cf, optimize, arena)
536
+ // PyArena_Free(arena)
537
+ // }
538
+ // } else {
539
+ str := source_as_string (cmd , "compile" , "string, bytes or AST" /*, &cf*/ )
540
+ // result = py.CompileStringExFlags(str, filename, start[mode], &cf, optimize)
541
+ result = compile .Compile (str , string (filename .(py.String )), string (startstr .(py.String )), int (supplied_flags .(py.Int )), dont_inherit .(py.Int ) != 0 )
542
+ // }
543
+
544
+ return result
545
+ }
0 commit comments