Skip to content

Commit

Permalink
More spec work...
Browse files Browse the repository at this point in the history
--HG--
branch : com.mozilla.es4.smlnj
extra : convert_revision : b867571d80fd59cb6df98bcb16f33a069aea3353
  • Loading branch information
[email protected] committed Mar 15, 2008
1 parent 102c3c0 commit 3020848
Show file tree
Hide file tree
Showing 16 changed files with 538 additions and 329 deletions.
12 changes: 6 additions & 6 deletions builtins/Function.es
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ package


/* E262-3 15.3.4.3: Function.prototype.apply */
prototype function apply(/*this: function,*/ thisArg=undefined, argArray=undefined)
prototype function apply(/*this: Callable,*/ thisArg=undefined, argArray=undefined)
Function.apply(this,
thisArg === undefined ? null : thisArg,
argArray === undefined ? null : argArray);
Expand All @@ -136,7 +136,7 @@ package
Function object, and everyone eventually ends up in
Function.apply().
*/
static public function apply(fn/*: function*/, thisArg: Object=null, argArray: Object=null) {
static public function apply(fn/*: Callable*/, thisArg: Object=null, argArray: Object=null) {
if (thisArg === null)
thisArg = global;
if (argArray === null)
Expand All @@ -150,7 +150,7 @@ package
"length" of the function, so the length of
Function.prototype.call is 1, which is what we want.
*/
prototype function call(/*this: function,*/ thisObj=undefined, ...args)
prototype function call(/*this: Callable,*/ thisObj=undefined, ...args)
Function.apply(this,
thisObj === undefined ? null : thisObj,
args);
Expand All @@ -160,20 +160,20 @@ package

/* E262-4 draft: "apply" and "call" are static methods on the
Function object. */
static public function call(fn/*: function*/, thisObj: Object=null, ...args)
static public function call(fn/*: Callable*/, thisObj: Object=null, ...args)
Function.apply(fn, thisObj, args);


/* E262-4 draft: "bind" is a static method on the Function object and
also a method on function objects.
*/
prototype function bind(/*this: function,*/ thisObj, ...args)
prototype function bind(/*this: Callable,*/ thisObj, ...args)
Function.helper::bind(this, thisObj, args);

intrinsic function bind(thisObj: Object, ...args)
Function.helper::bind(this, thisObj, args);

static public function bind(method/*: function*/, thisObj: Object, ...args)
static public function bind(method/*: Callable*/, thisObj: Object, ...args)
helper::bind(method, thisObj, args);

static helper function bind(method, thisObj, args) {
Expand Down
8 changes: 8 additions & 0 deletions builtins/Global.es
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,12 @@ package
return h;
}

informative function namespaceHash(x)
informativ::stringHash(x);

informative function nameHash(x)
informativ::stringHash(x);

// Return a hash code for the object.

informative native function objectHash(x:Object!): double;
Expand All @@ -328,6 +334,8 @@ package
case (x: AnyBoolean) { return Number(x) }
case (x: AnyNumber) { return intrinsic::toUint(x) }
case (x: AnyString) { return informative::stringHash(x) }
case (x: Namespace) { return informative::namespaceHash(x) }
case (x: Name) { return informative::nameHash(x) }
case (x: *) { return informative::objectHash(x) }
}
}
Expand Down
27 changes: 27 additions & 0 deletions builtins/Object.es
Original file line number Diff line number Diff line change
Expand Up @@ -189,5 +189,32 @@ package
return oldval;
}
*/

prototype function __createProperty__(name, value, enumerable=undefined, removable=undefined, writable=undefined)
this.Private::__createProperty__(helper::toEnumerableId(name),
value,
enumerable === undefined ? true : boolean(enumerable),
removable === undefined ? true : boolean(removable),
writable === undefined ? true : boolean(writable));

intrinsic function __createProperty__(name: EnumerableId, value, enumerable:boolean=true, removable:boolean=true, writable:boolean=true): void
Private::__createProperty__(name, value, enumerable, removable, writable);

Private function __createProperty__(name, value, enumerable, removable, writable) {
if (!magic::hasOwnProperty(this, name))
throw new TypeError(/* Property exists */);

let obj = magic::getPrototype(this);
while (obj != null) {
if (magic::hasOwnProperty(obj, name) && magic::getPropertyIsReadOnly(obj, name))
throw new TypeError(/* Property is ReadOnly in prototype chain */);
obj = magic::getPrototype(obj);
}

this[name] = value;
magic::setPropertyIsDontEnum(this, name, !enumerable);
magic::setPropertyIsDontDelete(this, name, !removable);
magic::setPropertyIsReadOnly(this, name, !writable);
}
}
}
4 changes: 2 additions & 2 deletions spec/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ language.html: stitch.py part2.html es4.css language/*.html ../builtins/*.es ../
library.html: stitch.py part3.html es4.css library/*.html ../builtins/*.es ../*.sml
python stitch.py part3.html library.html

lib-march-2008.html: stitch.py build-march-2008/lib-template.html es4.css library/*.html ../builtins/*.es ../*.sml
python stitch.py build-march-2008/lib-template.html lib-march-2008.html
lib-march-2008.html: stitch.py lib-march-2008-template.html es4.css library/*.html ../builtins/*.es ../*.sml
python stitch.py lib-march-2008-template.html lib-march-2008.html

LIBDEPS=stitch.py es4.css ../builtins/*.es ../*.sml

Expand Down
26 changes: 13 additions & 13 deletions spec/library/Function.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ <h1 id="class Function"> The class ''Function'' </h1>
CATEGORY: Pre-defined classes (E262-3 Chapter 15)
SOURCES: REFERENCES [1], [2], [3], [5]
SPEC AUTHOR: Lars
DRAFT STATUS: DRAFT 1 - 2008-03-10
DRAFT STATUS: DRAFT 2 - 2008-03-14
REVIEWED AGAINST ES3: YES
REVIEWED AGAINST ERRATA: YES
REVIEWED AGAINST BASE DOC: YES
Expand All @@ -23,12 +23,20 @@ <h1 id="class Function"> The class ''Function'' </h1>
* The 'thisObj' parameter to 'bind' is no longer optional, it must
be an object (not null).

* Removed the "Implementation" section for the 'meta::invoke' method
(it added nothing).

* Replaced note about host functions being "anything" with a
paragraph about the type 'Callable'.

OPEN ISSUES

* ES3 restrictions on argArray having to be an Array or an arguments
object in Function.prototype.apply have been removed here.

* Is it reasonable to allow the thisObj parameter to bind to be null
(so that it defaults to the global object of the bind function)?


NOTES

Expand All @@ -55,14 +63,10 @@ <h1 id="class Function"> The class ''Function'' </h1>

<P> Not all objects that can be called as functions are instances of
subclasses of the ''Function'' class, however. Any object that has a
''meta::invoke'' method can be called as a function.
''meta::invoke'' property can be called as a function.

<NOTE> Host functions may also not be instances of ''Function'' or its
subclasses, but must to some extent behave as if they are (see <XREF
target="Host objects">). However, host functions need not provide
''meta::invoke'' methods to be callable. The type ''function'',
defined elsewhere, matches invokable host functions even if they do
not have a ''meta::invoke'' method.
<P> The structural type ''Callable'' (see <XREF target="type:Callable">)
matches every object that has a ''meta::invoke'' property.


== Synopsis ==
Expand Down Expand Up @@ -256,7 +260,7 @@ <h3 id="Function: static meta invoke"> Function (p1, p2, <LDOTS> , pn, body) </h

<FIXME> (Ticket #173.) While it is necessary that the ''invoke''
method is completely magic in ''Function'' instances, it's not clear
it needs to be magic for instances of subclasses of ''Function'',
that it needs to be magic for instances of subclasses of ''Function'',
because these can be treated like other objects that have ''invoke''
methods (and which already work just fine in the reference
implementation). Therefore it should not be ''final''.
Expand All @@ -266,10 +270,6 @@ <h3 id="Function: static meta invoke"> Function (p1, p2, <LDOTS> , pn, body) </h
the executable code for the function represented by this ''Function''
object.

<IMPL>
The implementation of the meta function ''invoke'' is
implementation-dependent.

=== intrinsic::toString ( ) ===

<DESC> The intrinsic ''toString'' method converts the executable code
Expand Down
108 changes: 54 additions & 54 deletions spec/library/Name.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ <H1 id="class Name"> The class ''Name'' </H1>
CATEGORY: Pre-defined classes
SOURCES: REFERENCES [1], [2]
SPEC AUTHOR: Lars
DRAFT STATUS: DRAFT 2 - 2008-03-10
DRAFT STATUS: DRAFT 3 - 2008-03-14
REVIEWED AGAINST ES3: N/A
REVIEWED AGAINST ERRATA: N/A
REVIEWED AGAINST BASE DOC: N/A
Expand All @@ -20,7 +20,17 @@ <H1 id="class Name"> The class ''Name'' </H1>

CHANGES SINCE DRAFT 2 (2008-03-10)

* More open issues logged below!
* Name is now a subclass of 'Object' (not of 'String')

* The 'valueOf' method has been removed; 'Name' inherits the method
from the class 'Object'

* The constructor interface spec has been broken up into one and two
argument cases, for the sake of clarity.

* The qualifier field is never null; if the namespace passed to
the constructor is null then the qualifier field is noNS.


CHANGES SINCE DRAFT 1 (2008-03-05)

Expand All @@ -42,18 +52,6 @@ <H1 id="class Name"> The class ''Name'' </H1>
of 'private'.


OPEN ISSUES

* This class probably need not subclass String?

* intrinsic::valueOf returns a string, but should it return the Name
object instead? (The original proposal returns a string.)

* The constructor accepts combinations of arguments deemed to be
useful (a convenient but restrained superset of the types in
EnumerableId). It's pretty ad-hoc, though. Any better proposals?


REFERENCES

[1] http:&#x2f;&#x2f;wiki.ecmascript.org/doku.php?id=proposals:name_objects
Expand All @@ -62,7 +60,7 @@ <H1 id="class Name"> The class ''Name'' </H1>
<HR>

<P> The class ''Name'' is a final, nullable, non-dynamic, direct
subclass of ''String'' that reflects a property name as a pair of
subclass of ''Object'' that reflects a property name as a pair of
''Namespace'' and ''string'' values.

<COMP> The ''Namespace'' class is new in the 4th Edition of this Standard.
Expand All @@ -72,15 +70,14 @@ <H1 id="class Name"> The class ''Name'' </H1>
<P> The class ''Name'' provides the following interface:

{{{
__ES4__ final class Name extends String
__ES4__ final class Name extends Object
{
<SIGNATURE file="Name.es" name="public function Name">
<SIGNATURE file="Name.es" name="static meta function invoke">
public function Name(...args) <LDOTS>
static meta function invoke(...args): Name <LDOTS>

public static const length = 2

<SIGNATURE file="Name.es" name="override intrinsic function toString">
<SIGNATURE file="Name.es" name="override intrinsic function valueOf">

public const qualifier: Namespace
public const identifier: string
Expand All @@ -91,48 +88,59 @@ <H1 id="class Name"> The class ''Name'' </H1>

{{{
toString: function (this: Name) <LDOTS>
valueOf: function (this: Name) <LDOTS>
}}}

== Operators ==

<P> The operators ''=='' and ''==='' compare as equal two ''Name''
objects that are separately created from the same
(qualifier,identifier) pair; similarly, the operators ''!='' and
''!=='' compare as not equal two ''Name'' objects that are separately
created from (qualifier,identifier) pairs.


== Methods on the ''Name'' class object ==

=== new Name( a, b=<LDOTS> ) ===
=== new Name ( id ) ===

<RETN> When the ''Name'' constructor is called with one argument
//id// it returns a ''Name'' object whose ''qualifier'' is the
compatibility namespace **noNS** and whose ''identifier'' is //id//
converted to ''string''.

<DESC> The ''Name'' constructor initializes a new ''Name'' object.
Various combinations of the two arguments //a// and //b// are allowed.
If //a// is a string, a ''Name'', or an integer in the range
[0,2<SUP>32</SUP>) then //b// must be **undefined**. Otherwise, if
//a// is a ''Namespace'' then //b// must be a string or an integer in
the range [0,2<SUP>32</SUP>).
<SHORTIMPL>
{{{
public function Name( id ) <LDOTS>
}}}

<P> The ''Name'' constructor is not required to construct a new,
unique object every time it is called.
=== new Name( ns, id ) ===

<IMPL> The ''Name'' constructor is implementation-dependent.
<RETN> When the ''Name'' constructor is called with two arguments
//ns// and //id// it returns a ''Name'' object whose ''qualifier'' is
//ns// and whose ''identifier'' is //id// converted to ''string''.

<P> The helper function ''analyzeArgs'', called by the ''Name''
constructor, takes the two values //a// and //b// that were passed to
the ''Name'' constructor and returns an object containing a ''qualifier''
in the form of a namespace (which may be **null**) and an ''identifier''
in the form of a string. The qualifier and identifier are used to
create the ''Name'' object.
<P> //ns// may be **null**, in which case the ''qualifier'' will be
the compatibility namespace **noNS**.

<INCLUDE file="Name.es" name="static helper function analyzeArgs">
<SHORTIMPL>
{{{
public function Name( ns: Namespace?, id ) <LDOTS>
}}}

=== Name (a, b=<LDOTS>) ===
=== Name ( ...args ) ===

<DESC> When the ''Name''class object called as a function it creates a
''Name'' object. If ''a'' is a ''Name'' object and ''b'' is
**undefined** then ''a'' is returned. Otherwise, a ''Name'' object is
created by invoking the ''Name'' constructor on the parameters //a//
and //b//.
<DESC> The ''Name'' class object called as a function creates a
''Name'' object by invoking the ''Name'' constructor on its
argumen(s)

<RETN> The ''Name'' class object called as a function returns a
''Name'' object.

<SHORTIMPL>
<INCLUDE file="Name.es" name="static meta function invoke">

{{{
static meta function invoke( ...args )
new Name(...args);
}}}

== Methods on ''Name'' instances ==

Expand All @@ -147,20 +155,13 @@ <H1 id="class Name"> The class ''Name'' </H1>
<INCLUDE file="Name.es" name="override intrinsic function toString">
<INCLUDE file="Name.es" name="Private function toString">

=== intrinsic::valueOf ( ) ===

<RETN> The intrinsic ''valueOf'' method returns what the private
''toString'' method returns.

<SHORTIMPL>
<INCLUDE file="Name.es" name="override intrinsic function valueOf">

== Value properties of ''Name'' instances ==

=== qualifier ===

<P> The ''qualifier'' property holds the namespace value for this
''Name'' object. It may be null.
''Name'' object. It is never null.

=== identifier ===

Expand All @@ -178,6 +179,5 @@ <H1 id="class Name"> The class ''Name'' </H1>

<SHORTIMPL>
<INCLUDE file="Name.es" name="prototype function toString">
<INCLUDE file="Name.es" name="prototype function valueOf">

<!-- end -->
Loading

0 comments on commit 3020848

Please sign in to comment.