1
0
forked from Mirror/wren

Use "construct" instead of "this" to define constructors.

This commit is contained in:
Bob Nystrom
2015-07-21 07:24:53 -07:00
parent ed8ec262e4
commit 71ab3ca887
31 changed files with 68 additions and 81 deletions

View File

@ -103,7 +103,7 @@ class Sequence {
}
class MapSequence is Sequence {
this new(sequence, fn) {
construct new(sequence, fn) {
_sequence = sequence
_fn = fn
}
@ -113,7 +113,7 @@ class MapSequence is Sequence {
}
class WhereSequence is Sequence {
this new(sequence, fn) {
construct new(sequence, fn) {
_sequence = sequence
_fn = fn
}
@ -133,7 +133,7 @@ class String is Sequence {
}
class StringByteSequence is Sequence {
this new(string) {
construct new(string) {
_string = string
}
@ -180,7 +180,7 @@ class Map {
}
class MapKeySequence is Sequence {
this new(map) {
construct new(map) {
_map = map
}
@ -189,7 +189,7 @@ class MapKeySequence is Sequence {
}
class MapValueSequence is Sequence {
this new(map) {
construct new(map) {
_map = map
}

View File

@ -172,18 +172,18 @@ constructor, like so:
:::dart
class Unicorn {
this new(name, color) {
construct new(name, color) {
IO.print("My name is " + name + " and I am " + color + ".")
}
}
The `this` before the method name makes it a constructor. The `new` isn't
The `construct` before the method name makes it a constructor. The `new` isn't
special. Constructors can have any name you like, which lets you clarify how it
creates the instance:
:::dart
class Unicorn {
this brown(name) {
construct brown(name) {
IO.print("My name is " + name + " and I am brown.")
}
}

View File

@ -28,8 +28,8 @@ Some people like to see all of the reserved words in a programming language in
one lump. If you're one of those folks, here you go:
:::dart
break class else false for foreign if import in
is null return static super this true var while
break class construct else false for foreign if import
in is null return static super this true var while
## Identifiers

View File

@ -7,7 +7,7 @@
// Class definition with a toplevel name.
class SyntaxExample {
// Constructor
this new() {
construct new() {
// Top-level name `IO`
IO.print("I am a constructor!")
@ -26,7 +26,7 @@ class SyntaxExample {
}
// Constructor with arguments
this constructor(a, b) {
construct constructor(a, b) {
print(a, b)
field = a
}

View File

@ -73,6 +73,7 @@ typedef enum
TOKEN_BREAK,
TOKEN_CLASS,
TOKEN_CONSTRUCT,
TOKEN_ELSE,
TOKEN_FALSE,
TOKEN_FOR,
@ -628,6 +629,7 @@ static void readName(Parser* parser, TokenType type)
if (isKeyword(parser, "break")) type = TOKEN_BREAK;
else if (isKeyword(parser, "class")) type = TOKEN_CLASS;
else if (isKeyword(parser, "construct")) type = TOKEN_CONSTRUCT;
else if (isKeyword(parser, "else")) type = TOKEN_ELSE;
else if (isKeyword(parser, "false")) type = TOKEN_FALSE;
else if (isKeyword(parser, "for")) type = TOKEN_FOR;
@ -2489,6 +2491,7 @@ GrammarRule rules[] =
/* TOKEN_BANGEQ */ INFIX_OPERATOR(PREC_EQUALITY, "!="),
/* TOKEN_BREAK */ UNUSED,
/* TOKEN_CLASS */ UNUSED,
/* TOKEN_CONSTRUCT */ { NULL, NULL, constructorSignature, PREC_NONE, NULL },
/* TOKEN_ELSE */ UNUSED,
/* TOKEN_FALSE */ PREFIX(boolean),
/* TOKEN_FOR */ UNUSED,
@ -2501,7 +2504,7 @@ GrammarRule rules[] =
/* TOKEN_RETURN */ UNUSED,
/* TOKEN_STATIC */ UNUSED,
/* TOKEN_SUPER */ PREFIX(super_),
/* TOKEN_THIS */ { this_, NULL, constructorSignature, PREC_NONE, NULL },
/* TOKEN_THIS */ PREFIX(this_),
/* TOKEN_TRUE */ PREFIX(boolean),
/* TOKEN_VAR */ UNUSED,
/* TOKEN_WHILE */ UNUSED,
@ -3239,17 +3242,20 @@ static void variableDefinition(Compiler* compiler)
// like the non-curly body of an if or while.
void definition(Compiler* compiler)
{
if (match(compiler, TOKEN_CLASS)) {
if (match(compiler, TOKEN_CLASS))
{
classDefinition(compiler);
return;
}
if (match(compiler, TOKEN_IMPORT)) {
if (match(compiler, TOKEN_IMPORT))
{
import(compiler);
return;
}
if (match(compiler, TOKEN_VAR)) {
if (match(compiler, TOKEN_VAR))
{
variableDefinition(compiler);
return;
}

View File

@ -117,7 +117,7 @@ static const char* coreLibSource =
"}\n"
"\n"
"class MapSequence is Sequence {\n"
" this new(sequence, fn) {\n"
" construct new(sequence, fn) {\n"
" _sequence = sequence\n"
" _fn = fn\n"
" }\n"
@ -127,7 +127,7 @@ static const char* coreLibSource =
"}\n"
"\n"
"class WhereSequence is Sequence {\n"
" this new(sequence, fn) {\n"
" construct new(sequence, fn) {\n"
" _sequence = sequence\n"
" _fn = fn\n"
" }\n"
@ -147,7 +147,7 @@ static const char* coreLibSource =
"}\n"
"\n"
"class StringByteSequence is Sequence {\n"
" this new(string) {\n"
" construct new(string) {\n"
" _string = string\n"
" }\n"
"\n"
@ -194,7 +194,7 @@ static const char* coreLibSource =
"}\n"
"\n"
"class MapKeySequence is Sequence {\n"
" this new(map) {\n"
" construct new(map) {\n"
" _map = map\n"
" }\n"
"\n"
@ -203,7 +203,7 @@ static const char* coreLibSource =
"}\n"
"\n"
"class MapValueSequence is Sequence {\n"
" this new(map) {\n"
" construct new(map) {\n"
" _map = map\n"
" }\n"
"\n"

View File

@ -1,7 +1,7 @@
// Ported from the Python version.
class Tree {
this new(item, depth) {
construct new(item, depth) {
_item = item
if (depth > 0) {
var item2 = item + item

View File

@ -50,7 +50,7 @@ var ORDERED = null
// disrupting current constraints. Strengths cannot be created outside
// this class, so == can be used for value comparison.
class Strength {
this new(value, name) {
construct new(value, name) {
_value = value
_name = name
}
@ -82,7 +82,7 @@ ORDERED = [
var ThePlanner
class Constraint {
this new(strength) {
construct new(strength) {
_strength = strength
}
@ -131,7 +131,7 @@ class Constraint {
// Abstract superclass for constraints having a single possible output variable.
class UnaryConstraint is Constraint {
this new(myOutput, strength) {
construct new(myOutput, strength) {
super(strength)
_satisfied = false
_myOutput = myOutput
@ -187,7 +187,7 @@ class UnaryConstraint is Constraint {
// change their output during plan execution. This is called "stay
// optimization".
class StayConstraint is UnaryConstraint {
this new(variable, strength) {
construct new(variable, strength) {
super(variable, strength)
}
@ -199,7 +199,7 @@ class StayConstraint is UnaryConstraint {
// A unary input constraint used to mark a variable that the client
// wishes to change.
class EditConstraint is UnaryConstraint {
this new(variable, strength) {
construct new(variable, strength) {
super(variable, strength)
}
@ -219,7 +219,7 @@ var BACKWARD = 0
// Abstract superclass for constraints having two possible output
// variables.
class BinaryConstraint is Constraint {
this new(v1, v2, strength) {
construct new(v1, v2, strength) {
super(strength)
_v1 = v1
_v2 = v2
@ -328,7 +328,7 @@ class BinaryConstraint is Constraint {
// this relationship but the scale factor and offset are considered
// read-only.
class ScaleConstraint is BinaryConstraint {
this new(src, scale, offset, dest, strength) {
construct new(src, scale, offset, dest, strength) {
_scale = scale
_offset = offset
super(src, dest, strength)
@ -376,7 +376,7 @@ class ScaleConstraint is BinaryConstraint {
// Constrains two variables to have the same value.
class EqualityConstraint is BinaryConstraint {
this new(v1, v2, strength) {
construct new(v1, v2, strength) {
super(v1, v2, strength)
}
@ -391,7 +391,7 @@ class EqualityConstraint is BinaryConstraint {
// various parameters of interest to the DeltaBlue incremental
// constraint solver.
class Variable {
this new(name, value) {
construct new(name, value) {
_constraints = []
_determinedBy = null
_mark = 0
@ -430,7 +430,7 @@ class Variable {
// to resatisfy all currently satisfiable constraints in the face of
// one or more changing inputs.
class Plan {
this new() {
construct new() {
_list = []
}
@ -448,7 +448,7 @@ class Plan {
}
class Planner {
this new() {
construct new() {
_currentMark = 0
}

View File

@ -1,5 +1,5 @@
class Toggle {
this new(startState) {
construct new(startState) {
_state = startState
}
@ -11,7 +11,7 @@ class Toggle {
}
class NthToggle is Toggle {
this new(startState, maxCounter) {
construct new(startState, maxCounter) {
super(startState)
_countMax = maxCounter
_count = 0

View File

@ -1,6 +1,6 @@
// Infinite iterator demonstrating that Sequence.map is not eager
class FibIterator {
this new() {
construct new() {
_current = 0
_next = 1
}

View File

@ -1,6 +1,6 @@
// Infinite iterator demonstrating that Sequence.where is not eager
class FibIterator {
this new() {
construct new() {
_current = 0
_next = 1
}

View File

@ -1,6 +0,0 @@
class Foo {}
var foo = Foo.new()
IO.print(foo is Foo) // expect: true
// TODO: Test precedence and grammar of what follows "new".

View File

@ -1,4 +1,4 @@
class Foo {
static this new() {} // expect error
this static new() {} // expect error
static construct new() {} // expect error
construct static new() {} // expect error
}

View File

@ -1,5 +1,5 @@
class Foo {
this new() {
construct new() {
IO.print("ok")
}
}

View File

@ -1,5 +1,5 @@
class Foo {
this new() {
construct new() {
IO.print("Foo.new()")
}
}

View File

@ -1,9 +0,0 @@
class Foo {
+(other) { "Foo " + other }
}
IO.print(Foo.new() + "value") // expect: Foo value
// TODO: Other expressions following a constructor, like new Foo.bar("arg").
// TODO: Delete this test?
// TODO: Other constructor tests, like named constructors, etc.

View File

@ -1,8 +1,6 @@
// TODO: Change this.
class Foo {
this named() { _field = "named" }
this other() { _field = "other" }
construct named() { _field = "named" }
construct other() { _field = "other" }
toString { _field }
}

View File

@ -1,5 +1,5 @@
class Foo {
this real() {}
construct real() {}
}
// Classes do not get an argument-less "new()" if they define a constructor.

View File

@ -1,5 +1,5 @@
class Foo {
this base() {}
construct base() {}
}
class Bar is Foo {}

View File

@ -2,12 +2,10 @@
// super() call in a subclass, so this does that.
class Foo {
this new() {
construct new() {
super() // Should not cause a no method error.
IO.print("ok")
}
}
Foo.new() // expect: ok
// TODO: Test that can't invoke initializer on existing instance.

View File

@ -1,7 +1,7 @@
class A {}
class B is A {
this new() {
construct new() {
super // expect error
}
}

View File

@ -1,5 +1,5 @@
class A {
this new(arg) {
construct new(arg) {
IO.print("new A ", arg)
_field = arg
}
@ -8,7 +8,7 @@ class A {
}
class B is A {
this new(arg1, arg2) {
construct new(arg1, arg2) {
super(arg2)
IO.print("new B ", arg1)
_field = arg1
@ -18,7 +18,7 @@ class B is A {
}
class C is B {
this new() {
construct new() {
super("one", "two")
IO.print("new C")
_field = "c"

View File

@ -1,5 +1,5 @@
class Foo {
this new() { _field = "Foo field" }
construct new() { _field = "Foo field" }
closeOverGet {
return Fn.new { _field }

View File

@ -1,6 +1,6 @@
// This test exists mainly to make sure the GC traces instance fields.
class Node {
this new(left, value, right) {
construct new(left, value, right) {
_left = left
_value = value
_right = right

View File

@ -1,5 +1,5 @@
class Iter {
this new(value) { _value = value }
construct new(value) { _value = value }
iterate(iterator) { _value }
iteratorValue(iterator) { "value" }
}

View File

@ -1,5 +1,5 @@
class Foo {
this new() { _field = "Foo field" }
construct new() { _field = "Foo field" }
closeOverFooGet {
return Fn.new { Fn.new { _field } }
@ -11,7 +11,7 @@ class Foo {
}
class Bar is Foo {
this new() {
construct new() {
super()
_field = "Bar field"
}

View File

@ -1,5 +1,5 @@
class Foo {
this new(value) { _value = value }
construct new(value) { _value = value }
toString { _value }
bar=(value) {
_value = value

View File

@ -1,5 +1,5 @@
class Foo {
this new() {
construct new() {
_field1 = 1
_field2 = 2
_field3 = 3

View File

@ -1,5 +1,5 @@
class Foo {
this new() {
construct new() {
_field1 = 1
_field2 = 2
_field3 = 3
@ -137,7 +137,7 @@ class Foo {
}
class Bar is Foo {
this new() {
construct new() {
super()
_field129 = 129
_field130 = 130

View File

@ -1,5 +1,5 @@
class Foo {
this new() {
construct new() {
_field1 = 1
_field2 = 2
_field3 = 3

View File

@ -1,5 +1,5 @@
class Foo {
this new() {
construct new() {
_field1 = 1
_field2 = 2
_field3 = 3
@ -137,7 +137,7 @@ class Foo {
}
class Bar is Foo { // expect runtime error: Class 'Bar' may not have more than 255 fields, including inherited ones.
this new() {
construct new() {
super()
_field129 = 129
_field130 = 130