# HG changeset patch # User Paul Boddie # Date 1222465685 -7200 # Node ID c34b409b96e54524154b3479cf6fc84a28b1d068 # Parent f4a3c0049b31fdf6db9144d51fc14bfa46618587 Moved some documentation to separate files in the docs directory, updating some old details. Made a few adjustments to the rationale. diff -r f4a3c0049b31 -r c34b409b96e5 README.txt --- a/README.txt Tue Sep 23 00:33:01 2008 +0200 +++ b/README.txt Fri Sep 26 23:48:05 2008 +0200 @@ -1,167 +1,3 @@ -Namespace Definition -==================== - -Module attributes are defined either at the module level or by global -statements. - -Class attributes are defined only within class statements. - -Instance attributes are defined only by assignments to attributes of self -within __init__ methods. - -(These restrictions apply because such attributes are thus explicitly -declared. Module and class attributes can also be finalised in this way in -order to permit certain optimisations.) - -Potential Restrictions ----------------------- - -Names of classes and functions could be restricted to only refer to those -objects within the same namespace. If redefinition were to occur, or if -multiple possibilities were present, these restrictions could be moderated as -follows: - - * Classes assigned to the same name could provide the union of their - attributes. This would, however, cause a potential collision of attribute - definitions such as methods. - - * Functions, if they share compatible signatures, could share parameter list - definitions. - -Instruction Evaluation Model -============================ - -Programs use a value stack where evaluated instructions may save their -results. A value stack pointer indicates the top of this stack. In addition, a -separate stack is used to record the invocation frames. All stack pointers -refer to the next address to be used by the stack, not the address of the -uppermost element. - - Frame Stack Value Stack - ----------- ----------- Address of Callable - ------------------- - previous ... - current ------> callable -----> identifier - arg1 reference to code - arg2 - arg3 - local4 - local5 - ... - -Loading local names is a matter of performing frame-relative accesses to the -value stack. - -Invocations and Argument Evaluation ------------------------------------ - -When preparing for an invocation, the caller first sets the invocation frame -pointer. Then, positional arguments are added to the stack such that the first -argument positions are filled. A number of stack locations for the remaining -arguments specified in the program are then reserved. The names of keyword -arguments are used (in the form of table index values) to consult the -parameter table and to find the location in which such arguments are to be -stored. - - fn(a, b, d=1, e=2, c=3) -> fn(a, b, c, d, e) - - Value Stack - ----------- - - ... ... ... ... - fn fn fn fn - a a a a - b b b b - ___ ___ ___ --> 3 - ___ --> 1 1 | 1 - ___ | ___ --> 2 | 2 - 1 ----------- 2 ----------- 3 ----------- - -Conceptually, the frame can be considered as a collection of attributes, as -seen in other kinds of structures: - -Frame for invocation of fn: - - 0 1 2 3 4 5 - code a b c d e - reference - -However, where arguments are specified positionally, such "attributes" are not -set using a comparable approach to that employed with other structures. -Keyword arguments are set using an attribute-like mechanism, though, where the -position of each argument discovered using the parameter table. - -Where the target of the invocation is known, the above procedure can be -optimised slightly by attempting to add keyword argument values directly to -the stack: - - Value Stack - ----------- - - ... ... ... ... ... - fn fn fn fn fn - a a a a a - b b b b b - ___ ___ ___ --> 3 - 1 1 1 | 1 - 2 1 | 2 - 3 ----------- - - (reserve for (add in-place) (add in-place) (evaluate) (store by - parameter c) index) - -Method Invocations ------------------- - -Method invocations incorporate an implicit first argument which is obtained -from the context of the method: - - method(a, b, d=1, e=2, c=3) -> method(self, a, b, c, d, e) - - Value Stack - ----------- - - ... - method - context of method - a - b - 3 - 1 - 2 - -Although it could be possible to permit any object to be provided as the first -argument, in order to optimise instance attribute access in methods, we should -seek to restrict the object type. - -Verifying Supplied Arguments ----------------------------- - -In order to ensure a correct invocation, it is also necessary to check the -number of supplied arguments. If the target of the invocation is known at -compile-time, no additional instructions need to be emitted; otherwise, the -generated code must test for the following situations: - - 1. That the number of supplied arguments is equal to the number of expected - parameters. - - 2. That no keyword argument overwrites an existing positional parameter. - -Default Arguments ------------------ - -Some arguments may have default values which are used if no value is provided -in an invocation. Such defaults are initialised when the function itself is -initialised, and are used to fill in any invocation frames that are known at -compile-time. - -Tuples, Frames and Allocation ------------------------------ - -Using the approach where arguments are treated like attributes in some kind of -structure, we could choose to allocate frames in places other than a stack. -This would produce something somewhat similar to a plain tuple object. - Optimisations ============= diff -r f4a3c0049b31 -r c34b409b96e5 docs/evaluation.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/evaluation.txt Fri Sep 26 23:48:05 2008 +0200 @@ -0,0 +1,113 @@ +Instruction Evaluation Model +============================ + +Programs use a value stack containing local and temporary storage. A value +stack pointer indicates the top of this stack. In addition, a separate stack +is used to record the invocation frames. All stack pointers refer to the next +address to be used by the stack, not the address of the uppermost element. + + Frame Stack Value Stack + ----------- ----------- Address of Callable + ------------------- + previous ... + current ------> callable -----> identifier + arg1 reference to code + arg2 + arg3 + local4 + local5 + ... + +Unlike the CPython virtual machine, programs do not use a value stack +containing the results of expression evaluations. Instead, temporary storage +is statically allocated and employed by instructions. + +Loading local names and temporary values is a matter of performing +frame-relative accesses to the value stack. + +Invocations and Argument Evaluation +----------------------------------- + +When preparing for an invocation, the caller first sets the invocation frame +pointer. A number of locations for the arguments required by the invocation +are then reserved. With a frame to prepare, positional arguments are added to +the frame in order such that the first argument positions are filled. The +names of keyword arguments are used (in the form of table index values) to +consult the parameter table and to find the frame location in which such +arguments are to be stored. + + fn(a, b, d=1, e=2, c=3) -> fn(a, b, c, d, e) + + Frame + ----- + + a a a a + b b b b + ___ ___ ___ --> 3 + ___ --> 1 1 | 1 + ___ | ___ --> 2 | 2 + 1 ----------- 2 ----------- 3 ----------- + +Conceptually, the frame can be considered as a collection of attributes, as +seen in other kinds of structures: + +Frame for invocation of fn: + + 0 1 2 3 4 5 + code a b c d e + reference + +However, where arguments are specified positionally, such "attributes" are not +set using a comparable approach to that employed with other structures. +Keyword arguments are set using an attribute-like mechanism, though, where the +position of each argument discovered using the parameter table. + +Method Invocations +------------------ + +Method invocations incorporate an implicit first argument which is obtained +from the context of the method: + + method(a, b, d=1, e=2, c=3) -> method(self, a, b, c, d, e) + + Frame + ----- + + context of method + a + b + 3 + 1 + 2 + +Although it could be possible to permit any object to be provided as the first +argument, in order to optimise instance attribute access in methods, we should +seek to restrict the object type. + +Verifying Supplied Arguments +---------------------------- + +In order to ensure a correct invocation, it is also necessary to check the +number of supplied arguments. If the target of the invocation is known at +compile-time, no additional instructions need to be emitted; otherwise, the +generated code must test for the following situations: + + 1. That the number of supplied arguments is equal to the number of expected + parameters. + + 2. That no keyword argument overwrites an existing positional parameter. + +Default Arguments +----------------- + +Some arguments may have default values which are used if no value is provided +in an invocation. Such defaults are initialised when the function itself is +initialised, and are used to fill in any invocation frames that are known at +compile-time. + +Tuples, Frames and Allocation +----------------------------- + +Using the approach where arguments are treated like attributes in some kind of +structure, we could choose to allocate frames in places other than a stack. +This would produce something somewhat similar to a plain tuple object. diff -r f4a3c0049b31 -r c34b409b96e5 docs/namespaces.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/namespaces.txt Fri Sep 26 23:48:05 2008 +0200 @@ -0,0 +1,33 @@ +Namespace Definition +==================== + +Module attributes are defined either at the module level or by global +statements. + +Class attributes are defined only within class statements. + +Instance attributes are defined only by assignments to attributes of self +within __init__ methods. + +(These restrictions apply because such attributes are thus explicitly +declared. Module and class attributes can also be finalised in this way in +order to permit certain optimisations.) + +Potential Restrictions +---------------------- + +Names of classes and functions could be restricted to only refer to those +objects within the same namespace. If redefinition were to occur, or if +multiple possibilities were present, these restrictions could be moderated as +follows: + + * Classes assigned to the same name could provide the union of their + attributes. This would, however, cause a potential collision of attribute + definitions such as methods. + + * Functions, if they share compatible signatures, could share parameter list + definitions. + +It is easier, however, to regard multiply defined classes and functions as +non-constant and to either disallow optimisations or to actually prevent the +program describing them from compiling. diff -r f4a3c0049b31 -r c34b409b96e5 docs/rationale.txt --- a/docs/rationale.txt Tue Sep 23 00:33:01 2008 +0200 +++ b/docs/rationale.txt Fri Sep 26 23:48:05 2008 +0200 @@ -1,8 +1,11 @@ Micropython: A minimal implementation of Python for constrained devices - * Python provides a rich programming environment - * CPython enforces the "official" language version - * CPython, Jython, etc. expose the full strength language + * "Full strength" Python: + * Introspection, interactivity, PEP/reference-compliance + * CPython, Jython, IronPython, PyPy, CLPython, etc. + * "Reduced strength" Python: + * Remove "luxury" semantics + * Shed Skin, RPython, etc. Motivations @@ -22,6 +25,7 @@ * Locals, modules and classes are special in some way * Locals don't tend to change unilaterally + * Parameter lists don't tend to change if fully specified * Modules usually retain their identity * Classes differ from objects (despite metaclasses)