code.scm added and fixes

parent 74e59dee
......@@ -31,6 +31,7 @@ SOURCES = \
language/python/dir.scm \
language/python/checksum.scm \
language/python/format2.scm \
language/python/code.scm \
language/python/procedure.scm \
language/python/property.scm \
language/python/completer.scm \
......
......@@ -24,6 +24,7 @@
(define-syntax-rule (r2set x v) (vector-set! x 2 v))
(define-syntax-rule (vset x v) (vector-set! x 6 v))
(define frame? (@@ (system vm frame) frame?))
(define frame-address (@@ (system vm frame) frame-instruction-pointer))
......
(define-module (language python code)
#:use-module (oop pf-objects)
#:use-module (system vm program)
#:use-module (language python property)
#:use-module (ice-9 match)
#:export (Code))
(define-syntax-rule (aif it p x y) (let ((it p)) (if it x y)))
(define-python-class Code ()
"
co_argcount number of arguments (not including keyword only arguments,
* or ** args)
co_code string of raw compiled bytecode
co_cellvars tuple of names of cell variables
(referenced by containing scopes)
co_consts tuple of constants used in the bytecode
co_filename name of file in which this code object was created
co_firstlineno number of first line in Python source code
co_flags bitmap of CO_* flags, read more here
co_lnotab encoded mapping of line numbers to bytecode indices
co_freevars tuple of names of free variables
(referenced via a function’s closure)
co_posonlyargcount number of positional only arguments
co_kwonlyargcount number of keyword only arguments (not including ** arg)
co_name name with which this code object was defined
co_names tuple of names of local variables
co_nlocals number of local variables
co_stacksize virtual machine stack space required
co_varnames tuple of names of arguments and local variables
"
(define __init__
(lambda (self f)
(set self '_f f)))
(define _get_co_argcount
(lambda (self)
(let ((f (ref self '_f)))
(aif it (ref f 'arglist)
(let lp ((l it) (n 0))
(match l
((('* _) . _)
n)
((('** _) . _)
n)
(()
n)
((_ . l)
(lp l (+ n 1)))))
((@@ (system vm program) program-minimum-arity) f)))))
(define co_argcount (property _get_co_argcount))
(define co_code "")
(define co_cellvars '())
(define co_consts '())
(define _co_filename_ref
(lambda (self)
(aif it (ref (ref self '_f) 'filename)
it
#f)))
(define co_filename (property _co_filename_ref))
(define _co_firstlineno_ref
(lambda (self)
(ref (ref self '_f) 'lane)))
(define co_firstlineno (property _co_firstlineno_ref))
(define co_flags 1)
(define co_freevars '())
(define _co_posonlyargcount_ref
(lambda (self)
(let ((f (ref self '_f)))
(aif it (ref f 'arglist)
(let lp ((l it) (n 0))
(match l
((('* _) . _)
n)
((('** _) . _)
n)
((('= _ _) . _)
n)
(()
n)
((_ . l)
(lp l (+ n 1)))))
((@@ (system vm program program-minimum-arity) f))))))
(define co_posonlyargcount (property _co_posonlyargcount_ref))
(define _co_kwonlyargcount_ref
(lambda (self)
(let ((f (ref self '_f)))
(aif it (ref f 'arglist)
(let lp ((l it) (n 0))
(match l
((('* _) . _)
n)
((('** _) . _)
n)
((('= _ _) . l)
(lp l (+ n 1)))
(()
n)
((_ . l)
(lp l n))))
0))))
(define co_kwonlyargcount (property _co_kwonlyargcount_ref))
(define co_lnotab 0)
(define _co_name_ref
(lambda (self)
(symbol->string (procedure-name (ref (ref self '_f) 'name)))))
(define co_name (property _co_name_ref))
(define co_nlocals 0)
(define co_stacksize 0)
(define _co_varnames_ref
(lambda (self)
(ref (ref self '_f) 'arglist)))
(define co_varnames (property _co_varnames_ref)))
......@@ -331,7 +331,7 @@ empty list."
(fold f (f (car l) init) (cdr l))
init))
(define do-pr #f)
(define do-pr #t)
(define (pr . x)
(if do-pr
......@@ -1025,15 +1025,15 @@ empty list."
(define lr-and (lr `((#:band . ,(mklr (N 'py-logand))))))
(define lr-xor (lr `((#:bxor . ,(mklr (N 'py-logxor))))))
(define-syntax-parameter N (lambda (x) 0))
(define-syntax-parameter M (lambda (x) 0))
(define-syntax-parameter Ni (lambda (x) 0))
(define-syntax-parameter Mi (lambda (x) 0))
(define-syntax-rule (gen-table x vs (tag code ...) ...)
(begin
(hash-set! tagis tag
(lambda (x vs n m)
(syntax-parameterize
((N (lambda (x) #'n))
(M (lambda (x) #'m)))
((Ni (lambda (x) #'n))
(Mi (lambda (x) #'m)))
(match x code ...))))
...))
......@@ -1143,7 +1143,7 @@ empty list."
((_ . l)
(cons (N 'py-lshift) (map (g vs exp) l))))
(#:>>
(#:>>
((_ . l)
(cons (N 'py-rshift) (map (g vs exp) l))))
......@@ -1402,7 +1402,7 @@ empty list."
(f b))))
`(define-values ,(map get-name l)
(catch #t
(,(G 'catch) #t
(,(G 'lambda) ()
(,(G 'values)
,@(map get-imp l)))
......@@ -1455,7 +1455,7 @@ empty list."
(f b))))
`(define-values ,(map get-name l)
(catch #t
(,(G 'catch) #t
(,(G 'lambda) ()
(,(G 'values)
,@(map get-imp l)))
......@@ -1920,7 +1920,7 @@ empty list."
`(,(C 'def-decor) ,decor
(,(C 'def-wrap) ,y? ,f ,ab
(,(O 'object-method)
(,(C 'NR) (,(G 'quote) ,f) ,N ,M
(,(C 'NR) (,(G 'quote) ,f) ,Ni ,Mi
(,(D 'lam) ,aa
(,(C 'with-return) ,r
,(mk `(,(G 'let) ,(map (lambda (x) (list x #f)) ls)
......@@ -1931,7 +1931,7 @@ empty list."
,(docer
`(,(C 'def-decor) ,decor
(,(O 'object-method)
(,(C 'NR) (,(G 'quote) ,f) ,N ,M
(,(C 'NR) (,(G 'quote) ,f) ,Ni ,Mi
(,(D 'lam) ,aa
(,(C 'with-return) ,r
,(mk `(,(G 'let) ,(map (lambda (x) (list x #f)) ls)
......@@ -1944,7 +1944,7 @@ empty list."
`(,(C 'def-decor) ,decor
(,(C 'def-wrap) ,y? (,(G 'quote) ,f) ,ab
(,(O 'object-method)
(,(C 'NR) (,(G 'quote) ,f) ,N ,M
(,(C 'NR) (,(G 'quote) ,f) ,Ni ,Mi
(,(D 'lam) ,aa
(,(C 'with-return) ,r
(,(G 'let) ,(map (lambda (x) (list x #f)) ls)
......@@ -1954,7 +1954,7 @@ empty list."
,(docer
`(,(C 'def-decor) ,decor
(,(O 'object-method)
(,(C 'NR) (,(G 'quote) ,f) ,N ,M
(,(C 'NR) (,(G 'quote) ,f) ,Ni ,Mi
(,(D 'lam) ,aa
(,(C 'with-return) ,r
(,(G 'let) ,(map (lambda (x) (list x #f)) ls)
......
......@@ -82,9 +82,11 @@
s))))
(define-method (to-list x)
(for ((i : x)) ((r '()))
(cons i r)
#:final (reverse r)))
(if (bool x)
(for ((i : x)) ((r '()))
(cons i r)
#:final (reverse r))
'()))
(define-method (to-list (x <p>))
(aif it (ref x '__tolist__)
......
......@@ -43,7 +43,7 @@
tuple bytes bytearray locals globals
exec type object __import__ frozenset
Warning BytesWarning DeprecationWarning
py-list
py-list raise
)
#:export (print repr complex float int str
......@@ -142,11 +142,49 @@
(define-method (isinstance x y)
(cond
((keyword? y)
(cond
((eq? y #:Method)
(and
(isinstance x <procedure>)
(ref x '__self__ #f)))
((eq? y #:Procedure)
(and
(isinstance x <procedure>)
(not (ref x '__self__ #f))))
((eq? y #:Lambda)
#f)
((eq? y #:GeneratorType)
(and
(ref x '__next__)))
((eq? y #:DynamicClassAttribute)
#t)
(else
#f)))
((null? y)
#f)
((pair? y)
(or (isinstance x (car y))
(isinstance x (cdr y))))
((eq? y staticmethod)
(and (isinstance x <procedure>)
(not (ref x '__kind__ #f))))
((eq? y objectmethod)
(and (isinstance x <procedure>)
(eq? object-method (ref x '__kind__ #f))))
((eq? y classmethod)
(and (isinstance x <procedure>)
(eq? class-method (ref x '__kind__ #f))))
(else
(catch #t
(lambda () (is-a? x y))
......
......@@ -610,7 +610,8 @@
(let ((seen (py-set)))
(if (string? field_names)
(set! field_names
(string-split field_names #\,)))
(map string-trim-both
(string-split field_names #\,))))
(set! field_names
(for ((fs : field_names)) ((r '()))
......@@ -620,8 +621,9 @@
(cons fs r))
#:final
r))
(set! field_names (py-list (py-map scm-str field_names)))
(set! field_names (py-list (map scm-str field_names)))
(set! typename (scm-str typename))
(if rename
......@@ -660,16 +662,17 @@
(set! field_names (map string->symbol (to-list field_names)))
(make-p-class (string->symbol typename) '(())
(lambda (dict)
(lambda (dict)
(pylist-set! dict '_fields (map symbol->string field_names))
(pylist-set! dict '__init__
(object-method
(eval (v `(lam
(eval (v `(lam
(self
,@(map (lambda (key) `(= ,key #f))
field_names))
,@(map (lambda (key) `(= ,key ,None))
(reverse field_names)))
,@(map (lambda (key) `(set self ',key ,key))
field_names)))
(reverse field_names))))
mod)))
(pylist-set! dict '__getitem__
......
......@@ -150,11 +150,6 @@ def _has_code_flag(f, flag):
"""Return true if ``f`` is a function (or a method or functools.partial
wrapper wrapping a function) whose code object has the given ``flag``
set in its flags."""
while ismethod(f):
f = f.__func__
f = functools._unwrap_partial(f)
if not isfunction(f):
return False
return bool(f.__code__.co_flags & flag)
def isgeneratorfunction(obj):
......@@ -200,12 +195,9 @@ def iscoroutine(object):
"""Return true if the object is a coroutine."""
return isinstance(object, types.CoroutineType)
def isawaitable(object):
def isawaitable(object):
"""Return true if object can be passed to an ``await`` expression."""
return (isinstance(object, types.CoroutineType) or
isinstance(object, types.GeneratorType) and
bool(object.gi_code.co_flags & CO_ITERABLE_COROUTINE) or
isinstance(object, collections.abc.Awaitable))
return False;
def istraceback(object):
"""Return true if the object is a traceback.
......@@ -272,8 +264,6 @@ def isabstract(object):
"""Return true if the object is an abstract base class (ABC)."""
if not isinstance(object, type):
return False
if object.__flags__ & TPFLAGS_IS_ABSTRACT:
return True
if not issubclass(type(object), abc.ABCMeta):
return False
if hasattr(object, '__abstractmethods__'):
......@@ -429,10 +419,10 @@ def classify_class_attrs(cls):
continue
obj = get_obj if get_obj is not None else dict_obj
# Classify the object or its descriptor.
if isinstance(dict_obj, (staticmethod, types.BuiltinMethodType)):
if isinstance(dict_obj, (staticmethod)):
kind = "static method"
obj = dict_obj
elif isinstance(dict_obj, (classmethod, types.ClassMethodDescriptorType)):
elif isinstance(dict_obj, (classmethod)):
kind = "class method"
obj = dict_obj
elif isinstance(dict_obj, property):
......@@ -1531,14 +1521,14 @@ def getattr_static(obj, attr, default=_sentinel):
return default
raise AttributeError(attr)
pk(-1)
# ------------------------------------------------ generator introspection
GEN_CREATED = 'GEN_CREATED'
GEN_RUNNING = 'GEN_RUNNING'
GEN_SUSPENDED = 'GEN_SUSPENDED'
GEN_CLOSED = 'GEN_CLOSED'
pk(10)
def getgeneratorstate(generator):
"""Get current state of a generator-iterator.
Possible states are:
......@@ -1555,7 +1545,7 @@ def getgeneratorstate(generator):
return GEN_CREATED
return GEN_SUSPENDED
pk(11)
def getgeneratorlocals(generator):
"""
Get the mapping of generator local variables to their current values.
......@@ -1573,12 +1563,12 @@ def getgeneratorlocals(generator):
# ------------------------------------------------ coroutine introspection
pk(12)
CORO_CREATED = 'CORO_CREATED'
CORO_RUNNING = 'CORO_RUNNING'
CORO_SUSPENDED = 'CORO_SUSPENDED'
CORO_CLOSED = 'CORO_CLOSED'
pk(0)
def getcoroutinestate(coroutine):
"""Get current state of a coroutine object.
Possible states are:
......@@ -1613,16 +1603,9 @@ def getcoroutinelocals(coroutine):
###############################################################################
_WrapperDescriptor = type(type.__call__)
_MethodWrapper = type(all.__call__)
_ClassMethodWrapper = type(int.__dict__['from_bytes'])
_NonUserDefinedCallables = (_WrapperDescriptor,
_MethodWrapper,
_ClassMethodWrapper,
types.BuiltinFunctionType)
_NonUserDefinedCallables = tuple([])
pk(2)
def _signature_get_user_defined_method(cls, method_name):
"""Private helper. Checks if ``cls`` has an attribute
named ``method_name`` and returns it only if it is a
......@@ -1714,7 +1697,7 @@ def _signature_get_partial(wrapped_sig, partial, extra_args=()):
return wrapped_sig.replace(parameters=new_params.values())
pk(3)
def _signature_bound_method(sig):
"""Private helper to transform signatures for unbound
functions to bound methods.
......@@ -1800,7 +1783,7 @@ def _signature_get_bound_param(spec):
return spec[2:pos]
pk(0)
def _signature_strip_non_python_syntax(signature):
"""
Private helper function. Takes a signature in Argument Clinic's
......@@ -2025,7 +2008,7 @@ def _signature_from_builtin(cls, func, skip_bound_arg=True):
return _signature_fromstr(cls, func, s, skip_bound_arg)
pk(1)
def _signature_from_function(cls, func, skip_bound_arg=True):
"""Private helper: constructs Signature for the given python function."""
......@@ -2637,7 +2620,7 @@ class BoundArguments:
args.append('{}={!r}'.format(arg, value))
return '<{} ({})>'.format(self.__class__.__name__, ', '.join(args))
pk(2)
class Signature:
"""A Signature object represents the overall signature of a function.
It stores a Parameter object for each parameter accepted by the
......@@ -3230,14 +3213,8 @@ def getcoroutinelocals(coroutine):
###############################################################################
_WrapperDescriptor = type(type.__call__)
_MethodWrapper = type(all.__call__)
_ClassMethodWrapper = type(int.__dict__['from_bytes'])
_NonUserDefinedCallables = (_WrapperDescriptor,
_MethodWrapper,
_ClassMethodWrapper,
types.BuiltinFunctionType)
_NonUserDefinedCallables = tuple([])
def _signature_get_user_defined_method(cls, method_name):
......@@ -3642,7 +3619,7 @@ def _signature_from_builtin(cls, func, skip_bound_arg=True):
return _signature_fromstr(cls, func, s, skip_bound_arg)
pk(3)
def _signature_from_function(cls, func, skip_bound_arg=True):
"""Private helper: constructs Signature for the given python function."""
......
......@@ -3,21 +3,33 @@
#:use-module (oop pf-objects)
#:use-module (language python exceptions)
#:use-module (language python def)
#:use-module (language python code)
#:use-module (language python bool)
#:use-module (language python module)
#:use-module (language python dict)
#:use-module ((language python module python)
#:select (getattr type))
#:export (MappingProxyType DynamicClassAttribute Functiontype LambdaType
MethodType BuiltinMethodType))
MethodType BuiltinMethodType CodeType
AsyncGeneratorType CoroutineType GeneratorType
TracebackType FrameType DynamicClassAttribute))
"""
Define names for built-in types that aren't directly accessible as a builtin.
"""
(define MappingProxyType dict)
(define FunctionType <procedure>)
(define LambdaType <procedure>)
(define MethodType <procedure>)
(define BuiltinMethodType #f)
(define FunctionType #:Procedure)
(define LambdaType #:Lambda)
(define MethodType #:Method)
(define BuiltinMethodType #:BuiltinMethodType)
(define CodeType Code)
(define ModuleType Module)
(define AsyncGeneratorType #:AsyncGeneratorType)
(define GeneratorType #:GeneratorType)
(define CoroutineType #:CoroutineType)
(define TracebackType #:TracebackType)
(define FrameType #:FrameType)
(define DynamicClassAttribute #:DynamicClassAttribute)
(define-python-class DynamicClassAttribute ()
"Route attribute access on a class to __getattr__.
......
(define-module (language python procedure)
#:use-module (oop pf-objects)
#:use-module (oop goops)
#:use-module (language python code)
#:use-module (language python dir)
#:use-module (language python try)
#:use-module (language python def)
......@@ -52,6 +53,9 @@
(symbol->string (procedure-name f))
r)))
((equal? tag '__code__)
(Code f))
((equal? tag '__doc__)
(let ((r (procedure-property- f tag)))
(if (not r)
......@@ -140,7 +144,7 @@
(set-procedure-property!- f tag val))))
(define-method (dir (o <procedure>))
(let ((ret (+ (to-pylist '("__name__" "__qualname__"))
(let ((ret (+ (to-pylist '("__name__" "__qualname__" "__code__"))
(to-pylist fixed-str)
(to-pylist (map (lambda (x)
(let ((x (car x)))
......
......@@ -271,11 +271,13 @@ explicitly tell it to not update etc.
(set! class-method
(lambda (f)
(set f '__get__ (mk-getter-class f))
(set f '__kind__ 'class-method)
(set f '__get__ (mk-getter-class f))
f))
(set! object-method
(lambda (f)
(set f '__kind__ 'object-method)
(set f '__get__ (mk-getter-object f))
f))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment