-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest.lox
164 lines (132 loc) · 4.42 KB
/
test.lox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
print "file: test.lox";
print "# Class";
{ print "## Class ─ This";
{
class Egotist {
fun speak() {
print this;
}
};
var egotist = Egotist();
var method = Egotist().speak;
method(); //> Egotist instance
}
{
class Cake {
fun taste() {
var adjective = "delicious";
if (this.flavor == "Belgian chocolate") {
adjective = "yummy";
}
print "The " + this.flavor + " cake is " + adjective + "!";
this.tasted_counter = this.tasted_counter + 1;
if (this.tasted_counter >= 2) {
print "But now I am full.";
}
}
};
var cake = Cake();
cake.flavor = "German chocolate";
cake.tasted_counter = 0;
cake.taste();//> The German chocolate cake is delicious!
print cake.tasted_counter; //> 1
cake.flavor = "Belgian chocolate";
{
var taste_cake_method = cake.taste;
taste_cake_method(); //> The Belgian chocolate cake is delicious!\nBut now I am full.
print cake.tasted_counter; //> 2
print taste_cake_method; //> <fn taste>
}
}
{ print "### Class ─ This: Invalid uses of this";
// Error at 'this': Can't use 'this' outside of a class.
// print this;
fun not_a_method() {
// Error at 'this': Can't use 'this' outside of a class.
// print this;
}
not_a_method(); //> Undefined variable 'this'.
}
}
{ print "## Class ─ Constructors & Initializer";
class Foo {
fun init() {
print this;
// return nil;
}
};
var foo = Foo(); //> Foo instance
{ print "### Class ─ Constructors & Initializer: Invoking init() directly";
{ // Without `return` in `init()`.
print foo.init(); //> Foo instance
}
{ // With `return` in `init()`.
class Bar {
fun init() {
print this;
// Can't return from an initializer
// return 42;
}
};
var bar = Bar(); //> Bar instance
print bar.init(); //> Bar instance
fun init() {
// Error at 'this': Can't use 'this' outside of a class.
// print this;
print 4;
return 2;
}
print init(); //> 4\n2
}
}
}
print "Skipping block that has errors due to 'invoking init() directly'.";
if (true) {
var is_enabled_block = true;
// FIXME:
//
// NO ERROR REPORTED WHEN UNDEFINED VARIABLE IN A BLOCK SCOPE
class Foo { };
var foo = Foo();
// ok
is_enabled_block = false;
if (is_enabled_block) {
print is_reported_at_runtime;
}
// TODO: That is actually kind of useful sometimes, so we don’t want to
// disallow it entirely. Instead, it should return this instead of nil.
// That’s an easy fix over in LoxFunction.
//
// FIXME: FIXED
// Skipping block that has errors due to 'invoking init() directly'.
// interpreter.execute:669:39: warn: method: IDENTIFIER init null,
// is_initializer in .class: true.
// thread 7990 panic: access of union field 'ret' while field 'nil' is active
// interpreter.zig:714:64: 0x107a69a in execute__anon_6626 (main)
// runtime_return_value = ReturnValue.fromValue(value).ret;
// ^
// interpreter.zig:623:37: 0x10ba945 in executeBlock__anon_10207 (main)
// _ = try self.execute(statement, writer);
class EmptyBar {
fun init() {
return;
}
};
var empty_bar = EmptyBar();
print empty_bar; //> EmptyBar instance
print empty_bar.init(); //> nil
// !ok
is_enabled_block = false;
print "is_enabled_block:";
print is_enabled_block;
// MAKE SURE WE DO NOT SKIP RESOLVER CHECKS IF THERE IS INIT.
// I GUESS, due to binding this, we are skipping the current
// closure/environment just after init totally?
if (is_enabled_block) {
print is_not_reported_at_runtime;
}
}
// see `:h modeline`
// vim: set commentstring=//\ %s :
// vim: set filetype=cpp :
// vim: set sts=4 sw=4 et :