Cube  Diff

Differences From Artifact [f53c401a17]:

To Artifact [f1b5888486]:


131
132
133
134
135
136
137
138
139
140




141
142
143
144
145
146
147
131
132
133
134
135
136
137



138
139
140
141
142
143
144
145
146
147
148







-
-
-
+
+
+
+







			conoutf(@"missing \"%c\"", right);
			return NULL;
		}
	}
	char *s = newstring(word, p - word - 1);
	if (left == '(') {
		string t;
		itoa(t,
		    execute(
		        s)); // evaluate () exps directly, and substitute result
		// evaluate () exps directly, and substitute result
		@autoreleasepool {
			itoa(t, execute(@(s)));
		}
		s = exchangestr(s, t);
	}
	return s;
}

char *
parseword(char *&p) // parse single argument, including expressions
184
185
186
187
188
189
190

191

192



193
194
195
196




197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212


















213
214

215
216
217
218
219
220
221









222
223
224
225
226
227
228
229
230
231
232
233
234
235



236
237
238
239
240
241
242
185
186
187
188
189
190
191
192

193
194
195
196
197




198
199
200
201
















202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

221







222
223
224
225
226
227
228
229
230
231

232

233
234
235
236
237
238
239



240
241
242
243
244
245
246
247
248
249







+
-
+

+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-

-







-
-
-
+
+
+







	}

	conoutf(@"unknown alias lookup: %s", n + 1);
	return n;
}

int
execute(
execute(char *p, bool isdown) // all evaluation happens here, recursively
    OFString *string, bool isdown) // all evaluation happens here, recursively
{
	@autoreleasepool {
		std::unique_ptr<char> copy(strdup(string.UTF8String));
		char *p = copy.get();
	const int MAXWORDS = 25; // limit, remove
	char *w[MAXWORDS];
	int val = 0;
	for (bool cont = true; cont;) // for each ; seperated statement
		const int MAXWORDS = 25; // limit, remove
		char *w[MAXWORDS];
		int val = 0;
		for (bool cont = true; cont;) {
	{
		int numargs = MAXWORDS;
		loopi(MAXWORDS) // collect all argument values
		{
			w[i] = "";
			if (i > numargs)
				continue;
			char *s = parseword(p); // parse and evaluate exps
			if (!s) {
				numargs = i;
				s = "";
			}
			if (*s == '$')
				s = lookup(s); // substitute variables
			w[i] = s;
		}
			// for each ; seperated statement
			int numargs = MAXWORDS;
			loopi(MAXWORDS)
			{
				// collect all argument values
				w[i] = "";
				if (i > numargs)
					continue;
				// parse and evaluate exps
				char *s = parseword(p);
				if (!s) {
					numargs = i;
					s = "";
				}
				if (*s == '$')
					s = lookup(s); // substitute variables
				w[i] = s;
			}

		p += strcspn(p, ";\n\0");
			p += strcspn(p, ";\n\0");
		cont = *p++ !=
		       0; // more statements if this isn't the end of the string
		char *c = w[0];
		if (*c == '/')
			c++; // strip irc-style command prefix
		if (!*c)
			continue; // empty statement
			// more statements if this isn't the end of the string
			cont = *p++ != 0;
			char *c = w[0];
			// strip irc-style command prefix
			if (*c == '/')
				c++;
			// empty statement
			if (!*c)
				continue;

		@autoreleasepool {
			__kindof Identifier *identifier = identifiers[@(c)];

			if (identifier == nil) {
				val = ATOI(c);
				if (!val && *c != '0')
					conoutf(@"unknown command: %s", c);
			} else {
				if ([identifier
				        isKindOfClass:[Command class]]) {
					// game defined commands
					// use very ad-hoc function signature,
					// and just call it
					// game defined commands use very
					// ad-hoc function signature, and just
					// call it
					val = [identifier
					    callWithArguments:w
					         numArguments:numargs
					               isDown:isdown];
				} else if ([identifier
				               isKindOfClass:[Variable
				                                 class]]) {
263
264
265
266
267
268
269
270
271
272
273


274
275
276
277
278
279


280
281


282
283
284
285
286
287
288
270
271
272
273
274
275
276




277
278
279
280
281



282
283
284

285
286
287
288
289
290
291
292
293







-
-
-
-
+
+



-
-
-
+
+

-
+
+







							    stringWithFormat:
							        @"arg%d", i];
							alias(t, @(w[i]));
						}
					}
					// create new string here because alias
					// could rebind itself
					char *action = newstring(
					    [identifier action].UTF8String);
					val = execute(action, isdown);
					gp()->deallocstr(action);
					val = execute(
					    [[identifier action] copy], isdown);
					break;
				}
			}
		}
		loopj(numargs) gp()->deallocstr(w[j]);
	}
			loopj(numargs) gp()->deallocstr(w[j]);
		}

	return val;
		return val;
	}
}

// tab-completion of all identifiers

int completesize = 0, completeidx = 0;

void
341
342
343
344
345
346
347
348

349
350
351
352
353
354
355
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360







-
+







		} @catch (id e) {
			return false;
		}

		// Ensure \0 termination.
		[data addItem:""];

		execute((char *)data.mutableItems);
		execute(@((char *)data.mutableItems));
		return true;
	}
}

void
exec(OFString *cfgfile)
{
423
424
425
426
427
428
429
430
431
432
433

434
435
436


437
438
439

440
441
442
443
444
445
446
447
448

449
450
451
452
453
454

455
456
457
458
459
460
461


462
463
464
465
466
467
468

469
470
471
472



473
474
475
476
477
478

479
480
481
482
483
484
485
486
428
429
430
431
432
433
434




435



436
437

438

439
440
441
442

443
444
445
446

447
448
449
450
451
452

453
454






455
456

457
458
459
460
461

462




463
464
465

466
467
468


469

470
471
472
473
474
475
476







-
-
-
-
+
-
-
-
+
+
-

-
+



-




-
+





-
+

-
-
-
-
-
-
+
+
-





-
+
-
-
-
-
+
+
+
-



-
-
+
-







		alias(name, [OFString stringWithFormat:@"%d", v]);
	}
}

void
ifthen(OFString *cond, OFString *thenp, OFString *elsep)
{
	@autoreleasepool {
		std::unique_ptr<char> cmd(strdup(
		    (cond.UTF8String[0] != '0' ? thenp : elsep).UTF8String));

	execute((![cond hasPrefix:@"0"] ? thenp : elsep));
		execute(cmd.get());
	}
}
}


void
loopa(OFString *times, OFString *body_)
loopa(OFString *times, OFString *body)
{
	@autoreleasepool {
		int t = (int)times.longLongValue;
		std::unique_ptr<char> body(strdup(body_.UTF8String));

		loopi(t)
		{
			intset(@"i", i);
			execute(body.get());
			execute(body);
		}
	}
}

void
whilea(OFString *cond_, OFString *body_)
whilea(OFString *cond, OFString *body)
{
	@autoreleasepool {
		std::unique_ptr<char> cond(strdup(cond_.UTF8String));
		std::unique_ptr<char> body(strdup(body_.UTF8String));

		while (execute(cond.get()))
			execute(body.get());
	while (execute(cond))
		execute(body);
	}
}

void
onrelease(bool on, OFString *body)
{
	if (!on) {
	if (!on)
		std::unique_ptr<char> copy(strdup(body.UTF8String));
		execute(copy.get());
	}
}
		execute(body);
}


void
concat(OFString *s)
{
	@autoreleasepool {
		alias(@"s", s);
	alias(@"s", s);
	}
}

void
concatword(OFString *s)
{
	// The original used this code which does nothing:
	// for (char *a = s, *b = s; *a = *b; b++)