1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// command.cpp: implements the parsing and execution of a tiny script language
// which is largely backwards compatible with the quake console language.
#include "cube.h"
#include <memory>
#import "Alias.h"
#import "Command.h"
#import "Identifier.h"
#import "OFString+Cube.h"
#import "Variable.h"
// contains ALL vars/commands/aliases
static OFMutableDictionary<OFString *, __kindof Identifier *> *identifiers;
void
alias(OFString *name, OFString *action)
{
Alias *alias = identifiers[name];
if (alias == nil) {
|
<
<
>
>
>
>
>
>
|
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
|
// command.cpp: implements the parsing and execution of a tiny script language
// which is largely backwards compatible with the quake console language.
#include "cube.h"
#import "Alias.h"
#import "Command.h"
#import "Identifier.h"
#import "OFString+Cube.h"
#import "Variable.h"
// contains ALL vars/commands/aliases
static OFMutableDictionary<OFString *, __kindof Identifier *> *identifiers;
static void
cleanup(char **string)
{
free(*string);
}
void
alias(OFString *name, OFString *action)
{
Alias *alias = identifiers[name];
if (alias == nil) {
|
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
165
166
167
|
identifiers[name] = command;
return false;
}
// parse any nested set of () or []
char *
parseexp(char *&p, int right)
{
int left = *p++;
char *word = p;
for (int brak = 1; brak;) {
int c = *p++;
if (c == '\r')
*(p - 1) = ' '; // hack
if (c == left)
brak++;
else if (c == right)
brak--;
else if (!c) {
p--;
conoutf(@"missing \"%c\"", right);
return NULL;
}
}
char *s = strndup(word, p - word - 1);
if (left == '(') {
OFString *t;
@try {
t = [OFString
stringWithFormat:@"%d", execute(@(s), true)];
} @finally {
free(s);
}
s = strdup(t.UTF8String);
}
return s;
}
// parse single argument, including expressions
char *
parseword(char *&p)
{
p += strspn(p, " \t\r");
if (p[0] == '/' && p[1] == '/')
p += strcspn(p, "\n\0");
if (*p == '\"') {
p++;
char *word = p;
p += strcspn(p, "\"\r\n\0");
char *s = strndup(word, p - word);
if (*p == '\"')
p++;
return s;
}
if (*p == '(')
return parseexp(p, ')');
if (*p == '[')
return parseexp(p, ']');
char *word = p;
p += strcspn(p, "; \t\r\n\0");
if (p - word == 0)
return NULL;
return strndup(word, p - word);
}
// find value of ident referenced with $ in exp
OFString *
lookup(OFString *n)
{
__kindof Identifier *identifier = identifiers[[n substringFromIndex:1]];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
165
166
167
168
169
170
171
|
identifiers[name] = command;
return false;
}
// parse any nested set of () or []
static char *
parseexp(char **p, int right)
{
int left = *(*p)++;
char *word = *p;
for (int brak = 1; brak;) {
int c = *(*p)++;
if (c == '\r')
*(*p - 1) = ' '; // hack
if (c == left)
brak++;
else if (c == right)
brak--;
else if (!c) {
(*p)--;
conoutf(@"missing \"%c\"", right);
return NULL;
}
}
char *s = strndup(word, *p - word - 1);
if (left == '(') {
OFString *t;
@try {
t = [OFString
stringWithFormat:@"%d", execute(@(s), true)];
} @finally {
free(s);
}
s = strdup(t.UTF8String);
}
return s;
}
// parse single argument, including expressions
static char *
parseword(char **p)
{
(*p) += strspn(*p, " \t\r");
if ((*p)[0] == '/' && (*p)[1] == '/')
*p += strcspn(*p, "\n\0");
if (**p == '\"') {
(*p)++;
char *word = *p;
*p += strcspn(*p, "\"\r\n\0");
char *s = strndup(word, *p - word);
if (**p == '\"')
(*p)++;
return s;
}
if (**p == '(')
return parseexp(p, ')');
if (**p == '[')
return parseexp(p, ']');
char *word = *p;
*p += strcspn(*p, "; \t\r\n\0");
if (*p - word == 0)
return NULL;
return strndup(word, *p - word);
}
// find value of ident referenced with $ in exp
OFString *
lookup(OFString *n)
{
__kindof Identifier *identifier = identifiers[[n substringFromIndex:1]];
|
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
250
251
252
|
return 0;
}
// all evaluation happens here, recursively
int
execute(OFString *string, bool isDown)
{
std::unique_ptr<char> copy(strdup(string.UTF8String));
char *p = copy.get();
const int MAXWORDS = 25; // limit, remove
OFString *w[MAXWORDS];
int val = 0;
for (bool cont = true; cont;) {
// 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 = strdup("");
}
@try {
if (*s == '$')
// substitute variables
|
>
|
|
|
|
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
return 0;
}
// all evaluation happens here, recursively
int
execute(OFString *string, bool isDown)
{
char *copy __attribute__((__cleanup__(cleanup))) =
strdup(string.UTF8String);
char *p = copy;
const int MAXWORDS = 25; // limit, remove
OFString *w[MAXWORDS];
int val = 0;
for (bool cont = true; cont;) {
// 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 = strdup("");
}
@try {
if (*s == '$')
// substitute variables
|
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
|
return n + 1;
}
void
at(OFString *s_, OFString *pos)
{
int n = pos.cube_intValue;
std::unique_ptr<char> copy(strdup(s_.UTF8String));
char *s = copy.get();
loopi(n) s += strspn(s += strcspn(s, " \0"), " ");
s[strcspn(s, " \0")] = 0;
concat(@(s));
}
COMMANDN(loop, loopa, ARG_2STR)
COMMANDN(while, whilea, ARG_2STR)
COMMANDN(if, ifthen, ARG_3STR)
|
>
|
|
>
>
|
>
>
|
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
|
return n + 1;
}
void
at(OFString *s_, OFString *pos)
{
int n = pos.cube_intValue;
char *copy __attribute__((__cleanup__(cleanup))) =
strdup(s_.UTF8String);
char *s = copy;
loopi(n)
{
s += strcspn(s, " \0");
s += strspn(s, " ");
}
s[strcspn(s, " \0")] = 0;
concat(@(s));
}
COMMANDN(loop, loopa, ARG_2STR)
COMMANDN(while, whilea, ARG_2STR)
COMMANDN(if, ifthen, ARG_3STR)
|