root/attic/testscript.txt

Revision 21, 7.0 kB (checked in by JarrettBillingsley, 2 years ago)

Moved remotely

Line 
1 /*
2 OK.  An identifier can refer to either a local variable or to a variable in the context ("this").  So:
3
4 local function func()
5 {
6
7 }
8 */
9
10 // All the code that follows is run as a function - it is compiled, and then run.  Each declaration of
11 // a function, variable, or class, is actually run as a statement, and inserts a symbol into some namespace
12 // (which is just a table).  "local" declarations are local to the function - that is, when the function
13 // returns, the variable will be lost.  These would be like "private" module declarations in D.  "global"
14 // declarations are inserted into the global namespace, and will be accessible to all code after this
15 // function ends; this is usually bad practice, so good practice is to make a global namespace table (the
16 // "module") and then insert any symbols you want to export into that table.
17
18 // We will be using "test" as our module name.  Any symbols we want to be exported go into this table.
19 global test = { };
20
21 // "import" is just a function that checks to see if the given module is loaded, and attempts to load
22 // it if it isn't.
23 import("io");
24 import("string");
25
26 // Create a local function called "fork".
27 local function fork(x, y)
28 {
29     // This is how you do a "default parameter"
30     if(y is null)
31         y = 10;
32
33     io.writefln("fork: ", x + y);
34 }
35
36 // Create a local class called "A".  A class is a special kind of table.
37 local class A
38 {
39     // Some member variables.  We don't declare these as "local" or "global" because
40     // a class declaration is pretty much a table declaration, so these are just
41     // fields in a table.
42     mValue = 0;
43     mName = "";
44
45     // This is the constructor; it is otherwise a normal function, but is only
46     // called when the class is instantiated.
47     function constructor()
48     {
49         io.writefln("A ctor");
50     }
51
52     // You can make "properties" using the opIndex and opIndexAssign operators.
53     // This is because, as in Lua or Squirrel, the syntax 'a.b' is equivalent to 'a["b"]'.
54     function opIndex(index)
55     {
56         switch(index)
57         {
58             case "name":
59                 // Notice the explicit use of "this".  This is because there are four places
60                 // a variable can live: locally (in the function); in an enclosing function
61                 // (called an "upvalue"); globally; or in the function's context, or "this",
62                 // table.  An identifier on its own can only refer to a local variable or
63                 // upvalue; context variables are accessed through "this"; and globals are
64                 // accessed as in D, with the global scope operator (".ident").
65                 return this.mName;
66
67             case "value":
68                 return this.mValue;
69                
70             default:
71                 throw("Property 'A.'" ~ index.toString() ~ "' does not have a getter");
72         }
73     }
74
75     // The setter function.
76     function opIndexAssign(value, index)
77     {
78         switch(index)
79         {
80             case "name":
81                 this.mName = value.toString();
82                 return;
83                
84             default:
85                 throw("Property 'A." ~ index.toString() ~ "' does not have a setter");
86         }
87     }
88
89     // A plain old method.  Again, notice we're using "this" to access the member variable.
90     function incValue()
91     {
92         ++this.mValue;
93     }
94 }
95
96 // We can even derive classes.
97 local class B : A
98 {
99     function constructor()
100     {
101         io.writefln("B ctor");
102         this.super.constructor();
103     }
104 }
105
106 // Remember the "module table" 'test' that we created before?  Here's where we're exporting
107 // everything.
108
109 test =
110 {
111     fork = fork
112     A = A
113     B = B
114 }
115
116 // There is no "main()", since the entire "module" is run as a function.
117 fork(5);
118 fork(8, 3);
119
120 local a = A();
121 a.name = "Hello";
122 io.writefln("a is called \"", a.name, "\"");
123 a.name = 4;
124 io.writefln("a is now called \"", a.name, "\"");
125 io.writefln("a's value is ", a.value);
126 a.incValue();
127 io.writefln("a's value is now ", a.value);
128
129
130 /*
131 Types
132
133 --value--
134 null
135 bool
136 int
137 float
138
139 --ref--
140 string
141 table
142 array
143 closure
144 class
145 classinst
146 userdata
147 */
148
149 /*
150 function name:
151     locals
152     constants
153     enclosed functions
154     upvalues
155     case tables
156 */
157
158 // "push function() {"
159
160 global test = { };
161 /*
162 new table into temp reg;
163 put temp reg into global "test";
164 */
165
166 import("io");
167 /*
168 get global "import" into temp reg;
169 push const "io";
170 call temp reg;
171 */
172
173 import("string");
174 /*
175 get global "import" into temp reg;
176 push const "string";
177 call temp reg;
178 */
179
180 local f = null;
181 // allocate register as "f";
182
183 class Foo
184 {
185     def fork()
186     {
187         f = new Foo();
188     }
189     /*
190     Foo.fork:
191
192     */
193 }
194 /*
195 allocate register as "Foo";
196
197 */
198
199 function caller(f)
200 {
201     f();
202 }
203
204 function foo()
205 {
206     local x =
207     function bar()
208     {
209         ::print("hi!");
210     }
211
212
213 }
214
215 test.Foo = Foo;
216
217 class Test
218 {
219     this()
220     {
221         io.writefln("hi");
222     }
223
224     this(int x)
225     {
226         writefln("hey: ", x);
227     }
228
229     ~this()
230     {
231         writefln("bye");
232     }
233
234     def int mX;
235     def int mY;
236
237     def void fork()
238     {
239         writefln(this.mX + this.mY);
240     }
241
242     namespace x
243     {
244         def int opSet(int val)
245         {
246             return mX = val;
247         }
248
249         def int opSet(char[] val)
250         {
251             return mX = string.toInt(val);
252         }
253
254         def int opGet()
255         {
256             return mX;
257         }
258     }
259 }
260
261 def void foo(int x, int y)
262 {
263     def float z = x + y;
264
265     io.writefln("z = ", z);
266 }
267
268 class A
269 {
270
271 }
272
273 class B : A
274 {
275     def int mX = 3;
276
277     def void method(int x)
278     {
279         io.writefln("mX = ", mX, " x = ", x);
280     }
281 }
282
283 def void knife()
284 {
285
286 }
287
288 def int function(int) foo(int n)
289 {
290     return function int(int i)
291     {
292         n += i;
293         return n;
294     };
295 }
296
297 def void function() fork(int x, int y = 10)
298 {
299     def int z = x + y;
300
301     def void enclosed()
302     {
303         writefln(z);
304     }
305
306     enclosed();
307
308     def Test t = new Test();
309     def B b = new B();
310     def A a = b;
311
312     if(cast(B)a)
313         writefln("it's a B");
314
315     b.method(4);
316
317     def void function(int) f = b.method;
318     def void function() g = enclosed;
319     def void function() h = knife;
320
321     delete b;
322
323     // Function literal is instantiated ("closed") automatically upon being returned
324     return enclosed;
325 }
326
327 def void myWritefln(vararg args)
328 {
329     io.writef("my writefln: ");
330     io.writefln(args);
331 }
332
333 // Making a vararg function
334 def void testVararg(vararg args)
335 {
336     io.writefln("Got ", args.length, " arguments");
337
338     for(def int i = 0; i < args.length; ++i)
339     {
340         io.writef("arg[", i, "] = ");
341
342         switch(args.type(i))
343         {
344             case "int":
345                 io.writefln(args.asInt(i));
346                 break;
347
348             case "float":
349                 io.writefln(args.asFloat(i));
350                 break;
351
352             case "char[]":
353                 io.writefln(`"`, args.asString(i), `"`);
354                 break;
355
356             default:
357                 io.writefln("something scary");
358                 break;
359         }
360     }
361 }
362
363 // Get three instances of the function returned by fork (which has a default argument).
364 def void function() n = fork(5);
365 def void function() m = fork(10);
366 def void function() l = fork(3, 7);
367
368 // Call those three instances.  Notice that they all print different things, as their upvalues
369 // all have different values.
370 n();
371 m();
372 l();
373
374 // Try out the variadic function.
375 testVararg(5, 3.3, "hi");
376 writefln();
377 testVararg();
378 writefln();
379
380 // Calling a function indirectly.
381 def void function(vararg) blah = testVararg;
382 blah(4, 5, 6);
383
384 def Test t = new Test();
385 t.fork();
386 def int[] x = new int[](4);
387
388 if(4 < 5)
389     writefln("hi");
390 else
391     writefln("bye");
392
393 // }
Note: See TracBrowser for help on using the browser.