Clean up identifiers
FossilOrigin-Name: d35fd65699e79d96fc0588fff075f73b0dd7eb6ebfa0f6cffd0b0a3940e5fecd
This commit is contained in:
parent
570b9e3bb3
commit
c690c2b9ed
12 changed files with 364 additions and 276 deletions
15
src/Alias.h
Normal file
15
src/Alias.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#import "Identifier.h"
|
||||||
|
|
||||||
|
OF_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface Alias : Identifier
|
||||||
|
@property (copy, nonatomic) OFString *action;
|
||||||
|
@property (readonly, nonatomic) bool persisted;
|
||||||
|
|
||||||
|
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
|
||||||
|
- (instancetype)initWithName:(OFString *)name
|
||||||
|
action:(OFString *)action
|
||||||
|
persisted:(bool)persisted;
|
||||||
|
@end
|
||||||
|
|
||||||
|
OF_ASSUME_NONNULL_END
|
15
src/Alias.m
Normal file
15
src/Alias.m
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#import "Alias.h"
|
||||||
|
|
||||||
|
@implementation Alias
|
||||||
|
- (instancetype)initWithName:(OFString *)name
|
||||||
|
action:(OFString *)action
|
||||||
|
persisted:(bool)persisted
|
||||||
|
{
|
||||||
|
self = [super initWithName:name];
|
||||||
|
|
||||||
|
_action = [action copy];
|
||||||
|
_persisted = persisted;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
@end
|
18
src/Command.h
Normal file
18
src/Command.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#import "Identifier.h"
|
||||||
|
|
||||||
|
OF_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface Command : Identifier
|
||||||
|
@property (readonly, nonatomic) void (*function)();
|
||||||
|
@property (readonly, nonatomic) int argumentsTypes;
|
||||||
|
|
||||||
|
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
|
||||||
|
- (instancetype)initWithName:(OFString *)name
|
||||||
|
function:(void (*)())function
|
||||||
|
argumentsTypes:(int)argumentsTypes;
|
||||||
|
- (int)callWithArguments:(char *_Nonnull *_Nonnull)arguments
|
||||||
|
numArguments:(size_t)numArguments
|
||||||
|
isDown:(bool)isDown;
|
||||||
|
@end
|
||||||
|
|
||||||
|
OF_ASSUME_NONNULL_END
|
131
src/Command.mm
Normal file
131
src/Command.mm
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#import "Command.h"
|
||||||
|
|
||||||
|
#include <cube.h>
|
||||||
|
|
||||||
|
@implementation Command
|
||||||
|
- (instancetype)initWithName:(OFString *)name
|
||||||
|
function:(void (*)())function
|
||||||
|
argumentsTypes:(int)argumentsTypes
|
||||||
|
{
|
||||||
|
self = [super initWithName:name];
|
||||||
|
|
||||||
|
_function = function;
|
||||||
|
_argumentsTypes = argumentsTypes;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)callWithArguments:(char **)arguments
|
||||||
|
numArguments:(size_t)numArguments
|
||||||
|
isDown:(bool)isDown
|
||||||
|
{
|
||||||
|
switch (_argumentsTypes) {
|
||||||
|
case ARG_1INT:
|
||||||
|
if (isDown)
|
||||||
|
((void(__cdecl *)(int))_function)(ATOI(arguments[1]));
|
||||||
|
break;
|
||||||
|
case ARG_2INT:
|
||||||
|
if (isDown)
|
||||||
|
((void(__cdecl *)(int, int))_function)(
|
||||||
|
ATOI(arguments[1]), ATOI(arguments[2]));
|
||||||
|
break;
|
||||||
|
case ARG_3INT:
|
||||||
|
if (isDown)
|
||||||
|
((void(__cdecl *)(int, int, int))_function)(
|
||||||
|
ATOI(arguments[1]), ATOI(arguments[2]),
|
||||||
|
ATOI(arguments[3]));
|
||||||
|
break;
|
||||||
|
case ARG_4INT:
|
||||||
|
if (isDown)
|
||||||
|
((void(__cdecl *)(int, int, int, int))_function)(
|
||||||
|
ATOI(arguments[1]), ATOI(arguments[2]),
|
||||||
|
ATOI(arguments[3]), ATOI(arguments[4]));
|
||||||
|
break;
|
||||||
|
case ARG_NONE:
|
||||||
|
if (isDown)
|
||||||
|
((void(__cdecl *)())_function)();
|
||||||
|
break;
|
||||||
|
case ARG_1STR:
|
||||||
|
if (isDown) {
|
||||||
|
@autoreleasepool {
|
||||||
|
((void(__cdecl *)(OFString *))_function)(
|
||||||
|
@(arguments[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ARG_2STR:
|
||||||
|
if (isDown) {
|
||||||
|
@autoreleasepool {
|
||||||
|
((void(__cdecl *)(
|
||||||
|
OFString *, OFString *))_function)(
|
||||||
|
@(arguments[1]), @(arguments[2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ARG_3STR:
|
||||||
|
if (isDown) {
|
||||||
|
@autoreleasepool {
|
||||||
|
((void(__cdecl *)(OFString *, OFString *,
|
||||||
|
OFString *))_function)(@(arguments[1]),
|
||||||
|
@(arguments[2]), @(arguments[3]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ARG_5STR:
|
||||||
|
if (isDown) {
|
||||||
|
@autoreleasepool {
|
||||||
|
((void(__cdecl *)(OFString *, OFString *,
|
||||||
|
OFString *, OFString *,
|
||||||
|
OFString *))_function)(@(arguments[1]),
|
||||||
|
@(arguments[2]), @(arguments[3]),
|
||||||
|
@(arguments[4]), @(arguments[5]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ARG_DOWN:
|
||||||
|
((void(__cdecl *)(bool))_function)(isDown);
|
||||||
|
break;
|
||||||
|
case ARG_DWN1:
|
||||||
|
((void(__cdecl *)(bool, char *))_function)(
|
||||||
|
isDown, arguments[1]);
|
||||||
|
break;
|
||||||
|
case ARG_1EXP:
|
||||||
|
if (isDown)
|
||||||
|
return ((int(__cdecl *)(int))_function)(
|
||||||
|
execute(arguments[1]));
|
||||||
|
break;
|
||||||
|
case ARG_2EXP:
|
||||||
|
if (isDown)
|
||||||
|
return ((int(__cdecl *)(int, int))_function)(
|
||||||
|
execute(arguments[1]), execute(arguments[2]));
|
||||||
|
break;
|
||||||
|
case ARG_1EST:
|
||||||
|
if (isDown)
|
||||||
|
return ((int(__cdecl *)(char *))_function)(
|
||||||
|
arguments[1]);
|
||||||
|
break;
|
||||||
|
case ARG_2EST:
|
||||||
|
if (isDown)
|
||||||
|
return ((int(__cdecl *)(char *, char *))_function)(
|
||||||
|
arguments[1], arguments[2]);
|
||||||
|
break;
|
||||||
|
case ARG_VARI:
|
||||||
|
if (isDown) {
|
||||||
|
// limit, remove
|
||||||
|
string r;
|
||||||
|
r[0] = 0;
|
||||||
|
for (int i = 1; i < numArguments; i++) {
|
||||||
|
// make string-list out of all arguments
|
||||||
|
strcat_s(r, arguments[i]);
|
||||||
|
if (i == numArguments - 1)
|
||||||
|
break;
|
||||||
|
strcat_s(r, " ");
|
||||||
|
}
|
||||||
|
((void(__cdecl *)(char *))_function)(r);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@end
|
18
src/Ident.h
18
src/Ident.h
|
@ -1,18 +0,0 @@
|
||||||
#import <ObjFW/ObjFW.h>
|
|
||||||
|
|
||||||
OF_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
enum IdentType { ID_VAR, ID_COMMAND, ID_ALIAS };
|
|
||||||
|
|
||||||
@interface Ident : OFObject
|
|
||||||
@property (nonatomic) enum IdentType type;
|
|
||||||
@property (copy, nonatomic) OFString *name;
|
|
||||||
@property (nonatomic) int min, max; // ID_VAR
|
|
||||||
@property (nonatomic) int *storage; // ID_VAR
|
|
||||||
@property (nonatomic) void (*fun)(); // ID_VAR, ID_COMMAND
|
|
||||||
@property (nonatomic) int narg; // ID_VAR, ID_COMMAND
|
|
||||||
@property (copy, nonatomic) OFString *action; // ID_ALIAS
|
|
||||||
@property (nonatomic) bool persist;
|
|
||||||
@end
|
|
||||||
|
|
||||||
OF_ASSUME_NONNULL_END
|
|
|
@ -1,4 +0,0 @@
|
||||||
#import "Ident.h"
|
|
||||||
|
|
||||||
@implementation Ident
|
|
||||||
@end
|
|
12
src/Identifier.h
Normal file
12
src/Identifier.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#import <ObjFW/ObjFW.h>
|
||||||
|
|
||||||
|
OF_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface Identifier : OFObject
|
||||||
|
@property (readonly, copy, nonatomic) OFString *name;
|
||||||
|
|
||||||
|
- (instancetype)init OF_UNAVAILABLE;
|
||||||
|
- (instancetype)initWithName:(OFString *)name;
|
||||||
|
@end
|
||||||
|
|
||||||
|
OF_ASSUME_NONNULL_END
|
12
src/Identifier.m
Normal file
12
src/Identifier.m
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#import "Identifier.h"
|
||||||
|
|
||||||
|
@implementation Identifier
|
||||||
|
- (instancetype)initWithName:(OFString *)name
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
|
||||||
|
_name = [name copy];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
@end
|
20
src/Variable.h
Normal file
20
src/Variable.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#import "Identifier.h"
|
||||||
|
|
||||||
|
OF_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface Variable : Identifier
|
||||||
|
@property (readonly, nonatomic) int min, max;
|
||||||
|
@property (readonly, nonatomic) int *storage;
|
||||||
|
@property (readonly, nonatomic) void (*function)();
|
||||||
|
@property (readonly, nonatomic) bool persisted;
|
||||||
|
|
||||||
|
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
|
||||||
|
- (instancetype)initWithName:(OFString *)name
|
||||||
|
min:(int)min
|
||||||
|
max:(int)max
|
||||||
|
storage:(int *)storage
|
||||||
|
function:(void (*)())function
|
||||||
|
persisted:(bool)persisted;
|
||||||
|
@end
|
||||||
|
|
||||||
|
OF_ASSUME_NONNULL_END
|
21
src/Variable.m
Normal file
21
src/Variable.m
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#import "Variable.h"
|
||||||
|
|
||||||
|
@implementation Variable
|
||||||
|
- (instancetype)initWithName:(OFString *)name
|
||||||
|
min:(int)min
|
||||||
|
max:(int)max
|
||||||
|
storage:(int *)storage
|
||||||
|
function:(void (*)())function
|
||||||
|
persisted:(bool)persisted
|
||||||
|
{
|
||||||
|
self = [super initWithName:name];
|
||||||
|
|
||||||
|
_min = min;
|
||||||
|
_max = max;
|
||||||
|
_storage = storage;
|
||||||
|
_function = function;
|
||||||
|
_persisted = persisted;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
@end
|
|
@ -5,7 +5,10 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#import "Ident.h"
|
#import "Alias.h"
|
||||||
|
#import "Command.h"
|
||||||
|
#import "Identifier.h"
|
||||||
|
#import "Variable.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
itoa(char *s, int i)
|
itoa(char *s, int i)
|
||||||
|
@ -21,24 +24,25 @@ exchangestr(char *o, const char *n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// contains ALL vars/commands/aliases
|
// contains ALL vars/commands/aliases
|
||||||
OFMutableDictionary<OFString *, Ident *> *idents;
|
static OFMutableDictionary<OFString *, __kindof Identifier *> *identifiers;
|
||||||
|
|
||||||
void
|
void
|
||||||
alias(OFString *name, OFString *action)
|
alias(OFString *name, OFString *action)
|
||||||
{
|
{
|
||||||
Ident *b = idents[name];
|
Alias *alias = identifiers[name];
|
||||||
|
|
||||||
if (b == nil) {
|
if (alias == nil) {
|
||||||
Ident *b = [[Ident alloc] init];
|
alias = [[Alias alloc] initWithName:name
|
||||||
b.type = ID_ALIAS;
|
action:action
|
||||||
b.name = name;
|
persisted:true];
|
||||||
b.action = action;
|
|
||||||
b.persist = true;
|
|
||||||
|
|
||||||
idents[b.name] = b;
|
if (identifiers == nil)
|
||||||
|
identifiers = [[OFMutableDictionary alloc] init];
|
||||||
|
|
||||||
|
identifiers[name] = alias;
|
||||||
} else {
|
} else {
|
||||||
if (b.type == ID_ALIAS)
|
if ([alias isKindOfClass:[Alias class]])
|
||||||
b.action = action;
|
alias.action = action;
|
||||||
else
|
else
|
||||||
conoutf(
|
conoutf(
|
||||||
@"cannot redefine builtin %@ with an alias", name);
|
@"cannot redefine builtin %@ with an alias", name);
|
||||||
|
@ -47,22 +51,20 @@ alias(OFString *name, OFString *action)
|
||||||
COMMAND(alias, ARG_2STR)
|
COMMAND(alias, ARG_2STR)
|
||||||
|
|
||||||
int
|
int
|
||||||
variable(OFString *name, int min, int cur, int max, int *storage, void (*fun)(),
|
variable(OFString *name, int min, int cur, int max, int *storage,
|
||||||
bool persist)
|
void (*function)(), bool persisted)
|
||||||
{
|
{
|
||||||
if (idents == nil)
|
Variable *variable = [[Variable alloc] initWithName:name
|
||||||
idents = [[OFMutableDictionary alloc] init];
|
min:min
|
||||||
|
max:max
|
||||||
|
storage:storage
|
||||||
|
function:function
|
||||||
|
persisted:persisted];
|
||||||
|
|
||||||
Ident *v = [[Ident alloc] init];
|
if (identifiers == nil)
|
||||||
v.type = ID_VAR;
|
identifiers = [[OFMutableDictionary alloc] init];
|
||||||
v.name = name;
|
|
||||||
v.min = min;
|
|
||||||
v.max = max;
|
|
||||||
v.storage = storage;
|
|
||||||
v.fun = fun;
|
|
||||||
v.persist = persist;
|
|
||||||
|
|
||||||
idents[name] = v;
|
identifiers[name] = variable;
|
||||||
|
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
@ -70,43 +72,43 @@ variable(OFString *name, int min, int cur, int max, int *storage, void (*fun)(),
|
||||||
void
|
void
|
||||||
setvar(OFString *name, int i)
|
setvar(OFString *name, int i)
|
||||||
{
|
{
|
||||||
*idents[name].storage = i;
|
*[identifiers[name] storage] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
getvar(OFString *name)
|
getvar(OFString *name)
|
||||||
{
|
{
|
||||||
return *idents[name].storage;
|
return *[identifiers[name] storage];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
identexists(OFString *name)
|
identexists(OFString *name)
|
||||||
{
|
{
|
||||||
return (idents[name] != nil);
|
return (identifiers[name] != nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
OFString *
|
OFString *
|
||||||
getalias(OFString *name)
|
getalias(OFString *name)
|
||||||
{
|
{
|
||||||
Ident *i = idents[name];
|
Alias *alias = identifiers[name];
|
||||||
return i != nil && i.type == ID_ALIAS ? i.action : nil;
|
|
||||||
|
if ([alias isKindOfClass:[Alias class]])
|
||||||
|
return alias.action;
|
||||||
|
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
addcommand(OFString *name, void (*fun)(), int narg)
|
addcommand(OFString *name, void (*function)(), int argumentsTypes)
|
||||||
{
|
{
|
||||||
if (idents == nil)
|
Command *command = [[Command alloc] initWithName:name
|
||||||
idents = [[OFMutableDictionary alloc] init];
|
function:function
|
||||||
|
argumentsTypes:argumentsTypes];
|
||||||
|
|
||||||
@autoreleasepool {
|
if (identifiers == nil)
|
||||||
Ident *c = [[Ident alloc] init];
|
identifiers = [[OFMutableDictionary alloc] init];
|
||||||
c.type = ID_COMMAND;
|
|
||||||
c.name = name;
|
|
||||||
c.fun = fun;
|
|
||||||
c.narg = narg;
|
|
||||||
|
|
||||||
idents[name] = c;
|
identifiers[name] = command;
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -171,18 +173,14 @@ char *
|
||||||
lookup(char *n) // find value of ident referenced with $ in exp
|
lookup(char *n) // find value of ident referenced with $ in exp
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
Ident *ID = idents[@(n + 1)];
|
__kindof Identifier *identifier = identifiers[@(n + 1)];
|
||||||
|
|
||||||
if (ID != nil) {
|
if ([identifier isKindOfClass:[Variable class]]) {
|
||||||
switch (ID.type) {
|
|
||||||
case ID_VAR:
|
|
||||||
string t;
|
string t;
|
||||||
itoa(t, *(ID.storage));
|
itoa(t, *[identifier storage]);
|
||||||
return exchangestr(n, t);
|
return exchangestr(n, t);
|
||||||
case ID_ALIAS:
|
} else if ([identifier isKindOfClass:[Alias class]])
|
||||||
return exchangestr(n, ID.action.UTF8String);
|
return exchangestr(n, [identifier action].UTF8String);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conoutf(@"unknown alias lookup: %s", n + 1);
|
conoutf(@"unknown alias lookup: %s", n + 1);
|
||||||
|
@ -223,185 +221,37 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
|
||||||
continue; // empty statement
|
continue; // empty statement
|
||||||
|
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
Ident *ID = idents[@(c)];
|
__kindof Identifier *identifier = identifiers[@(c)];
|
||||||
|
|
||||||
if (ID == nil) {
|
if (identifier == nil) {
|
||||||
val = ATOI(c);
|
val = ATOI(c);
|
||||||
if (!val && *c != '0')
|
if (!val && *c != '0')
|
||||||
conoutf(@"unknown command: %s", c);
|
conoutf(@"unknown command: %s", c);
|
||||||
} else {
|
} else {
|
||||||
switch (ID.type) {
|
if ([identifier
|
||||||
|
isKindOfClass:[Command class]]) {
|
||||||
// game defined commands
|
// game defined commands
|
||||||
case ID_COMMAND:
|
|
||||||
// use very ad-hoc function signature,
|
// use very ad-hoc function signature,
|
||||||
// and just call it
|
// and just call it
|
||||||
switch (ID.narg) {
|
val = [identifier
|
||||||
case ARG_1INT:
|
callWithArguments:w
|
||||||
if (isdown)
|
numArguments:numargs
|
||||||
((void(__cdecl *)(
|
isDown:isdown];
|
||||||
int))ID.fun)(
|
} else if ([identifier
|
||||||
ATOI(w[1]));
|
isKindOfClass:[Variable
|
||||||
break;
|
class]]) {
|
||||||
case ARG_2INT:
|
|
||||||
if (isdown)
|
|
||||||
((void(__cdecl *)(
|
|
||||||
int, int))ID.fun)(
|
|
||||||
ATOI(w[1]),
|
|
||||||
ATOI(w[2]));
|
|
||||||
break;
|
|
||||||
case ARG_3INT:
|
|
||||||
if (isdown)
|
|
||||||
((void(__cdecl *)(int,
|
|
||||||
int, int))ID.fun)(
|
|
||||||
ATOI(w[1]),
|
|
||||||
ATOI(w[2]),
|
|
||||||
ATOI(w[3]));
|
|
||||||
break;
|
|
||||||
case ARG_4INT:
|
|
||||||
if (isdown)
|
|
||||||
((void(__cdecl *)(int,
|
|
||||||
int, int,
|
|
||||||
int))ID.fun)(
|
|
||||||
ATOI(w[1]),
|
|
||||||
ATOI(w[2]),
|
|
||||||
ATOI(w[3]),
|
|
||||||
ATOI(w[4]));
|
|
||||||
break;
|
|
||||||
case ARG_NONE:
|
|
||||||
if (isdown)
|
|
||||||
((void(__cdecl *)())
|
|
||||||
ID.fun)();
|
|
||||||
break;
|
|
||||||
case ARG_1STR:
|
|
||||||
if (isdown) {
|
|
||||||
@autoreleasepool {
|
|
||||||
((void(
|
|
||||||
__cdecl *)(
|
|
||||||
OFString *))
|
|
||||||
ID.fun)(
|
|
||||||
@(w[1]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ARG_2STR:
|
|
||||||
if (isdown) {
|
|
||||||
@autoreleasepool {
|
|
||||||
((void(
|
|
||||||
__cdecl *)(
|
|
||||||
OFString *,
|
|
||||||
OFString *))
|
|
||||||
ID.fun)(
|
|
||||||
@(w[1]),
|
|
||||||
@(w[2]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ARG_3STR:
|
|
||||||
if (isdown) {
|
|
||||||
@autoreleasepool {
|
|
||||||
((void(
|
|
||||||
__cdecl *)(
|
|
||||||
OFString *,
|
|
||||||
OFString *,
|
|
||||||
OFString *))
|
|
||||||
ID.fun)(
|
|
||||||
@(w[1]),
|
|
||||||
@(w[2]),
|
|
||||||
@(w[3]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ARG_5STR:
|
|
||||||
if (isdown) {
|
|
||||||
@autoreleasepool {
|
|
||||||
((void(
|
|
||||||
__cdecl *)(
|
|
||||||
OFString *,
|
|
||||||
OFString *,
|
|
||||||
OFString *,
|
|
||||||
OFString *,
|
|
||||||
OFString *))
|
|
||||||
ID.fun)(
|
|
||||||
@(w[1]),
|
|
||||||
@(w[2]),
|
|
||||||
@(w[3]),
|
|
||||||
@(w[4]),
|
|
||||||
@(w[5]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ARG_DOWN:
|
|
||||||
((void(__cdecl *)(bool))ID.fun)(
|
|
||||||
isdown);
|
|
||||||
break;
|
|
||||||
case ARG_DWN1:
|
|
||||||
((void(__cdecl *)(
|
|
||||||
bool, char *))ID.fun)(
|
|
||||||
isdown, w[1]);
|
|
||||||
break;
|
|
||||||
case ARG_1EXP:
|
|
||||||
if (isdown)
|
|
||||||
val = ((int(__cdecl *)(
|
|
||||||
int))ID.fun)(
|
|
||||||
execute(w[1]));
|
|
||||||
break;
|
|
||||||
case ARG_2EXP:
|
|
||||||
if (isdown)
|
|
||||||
val = ((int(__cdecl *)(
|
|
||||||
int, int))ID.fun)(
|
|
||||||
execute(w[1]),
|
|
||||||
execute(w[2]));
|
|
||||||
break;
|
|
||||||
case ARG_1EST:
|
|
||||||
if (isdown)
|
|
||||||
val = ((int(__cdecl *)(
|
|
||||||
char *))ID.fun)(
|
|
||||||
w[1]);
|
|
||||||
break;
|
|
||||||
case ARG_2EST:
|
|
||||||
if (isdown)
|
|
||||||
val = ((int(__cdecl *)(
|
|
||||||
char *,
|
|
||||||
char *))ID.fun)(
|
|
||||||
w[1], w[2]);
|
|
||||||
break;
|
|
||||||
case ARG_VARI:
|
|
||||||
if (isdown) {
|
|
||||||
// limit, remove
|
|
||||||
string r;
|
|
||||||
r[0] = 0;
|
|
||||||
for (int i = 1;
|
|
||||||
i < numargs; i++) {
|
|
||||||
// make
|
|
||||||
// string-list
|
|
||||||
// out of all
|
|
||||||
// arguments
|
|
||||||
strcat_s(
|
|
||||||
r, w[i]);
|
|
||||||
if (i ==
|
|
||||||
numargs - 1)
|
|
||||||
break;
|
|
||||||
strcat_s(
|
|
||||||
r, " ");
|
|
||||||
}
|
|
||||||
((void(__cdecl *)(
|
|
||||||
char *))ID.fun)(r);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// game defined variables
|
// game defined variables
|
||||||
case ID_VAR:
|
|
||||||
if (isdown) {
|
if (isdown) {
|
||||||
if (!w[1][0])
|
if (!w[1][0])
|
||||||
// var with no value
|
// var with no value
|
||||||
// just prints its
|
// just prints its
|
||||||
// current value
|
// current value
|
||||||
conoutf(@"%s = %d", c,
|
conoutf(@"%s = %d", c,
|
||||||
*ID.storage);
|
*[identifier
|
||||||
|
storage]);
|
||||||
else {
|
else {
|
||||||
if (ID.min > ID.max) {
|
if ([identifier min] >
|
||||||
|
[identifier max]) {
|
||||||
conoutf(
|
conoutf(
|
||||||
@"variable "
|
@"variable "
|
||||||
@"is "
|
@"is "
|
||||||
|
@ -411,17 +261,22 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
|
||||||
int i1 =
|
int i1 =
|
||||||
ATOI(w[1]);
|
ATOI(w[1]);
|
||||||
if (i1 <
|
if (i1 <
|
||||||
ID.min ||
|
[identifier
|
||||||
|
min] ||
|
||||||
i1 >
|
i1 >
|
||||||
ID.max) {
|
[identifier
|
||||||
|
max]) {
|
||||||
// clamp
|
// clamp
|
||||||
// to
|
// to
|
||||||
// valid
|
// valid
|
||||||
// range
|
// range
|
||||||
i1 =
|
i1 =
|
||||||
i1 < ID.min
|
i1 < [identifier
|
||||||
? ID.min
|
min]
|
||||||
: ID.max;
|
? [identifier
|
||||||
|
min]
|
||||||
|
: [identifier
|
||||||
|
max];
|
||||||
conoutf(
|
conoutf(
|
||||||
@"v"
|
@"v"
|
||||||
@"a"
|
@"a"
|
||||||
|
@ -452,26 +307,30 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
|
||||||
@"%"
|
@"%"
|
||||||
@"d",
|
@"d",
|
||||||
c,
|
c,
|
||||||
ID.min,
|
[identifier
|
||||||
ID.max);
|
min],
|
||||||
|
[identifier
|
||||||
|
max]);
|
||||||
}
|
}
|
||||||
*ID.storage =
|
*[identifier
|
||||||
|
storage] =
|
||||||
i1;
|
i1;
|
||||||
}
|
}
|
||||||
if (ID.fun)
|
if ([identifier
|
||||||
|
function] !=
|
||||||
|
NULL)
|
||||||
// call trigger
|
// call trigger
|
||||||
// function if
|
// function if
|
||||||
// available
|
// available
|
||||||
((void(__cdecl
|
((void(__cdecl
|
||||||
*)())ID
|
*)())[identifier
|
||||||
.fun)();
|
function])();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
} else if ([identifier
|
||||||
|
isKindOfClass:[Alias class]]) {
|
||||||
// alias, also used as functions and (global)
|
// alias, also used as functions and
|
||||||
// variables
|
// (global) variables
|
||||||
case ID_ALIAS:
|
|
||||||
for (int i = 1; i < numargs; i++) {
|
for (int i = 1; i < numargs; i++) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
// set any arguments as
|
// set any arguments as
|
||||||
|
@ -486,8 +345,8 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
|
||||||
}
|
}
|
||||||
// create new string here because alias
|
// create new string here because alias
|
||||||
// could rebind itself
|
// could rebind itself
|
||||||
char *action =
|
char *action = newstring(
|
||||||
newstring(ID.action.UTF8String);
|
[identifier action].UTF8String);
|
||||||
val = execute(action, isdown);
|
val = execute(action, isdown);
|
||||||
gp()->deallocstr(action);
|
gp()->deallocstr(action);
|
||||||
break;
|
break;
|
||||||
|
@ -500,7 +359,7 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tab-completion of all idents
|
// tab-completion of all identifiers
|
||||||
|
|
||||||
int completesize = 0, completeidx = 0;
|
int completesize = 0, completeidx = 0;
|
||||||
|
|
||||||
|
@ -533,13 +392,13 @@ complete(OFString *s_)
|
||||||
}
|
}
|
||||||
|
|
||||||
__block int idx = 0;
|
__block int idx = 0;
|
||||||
[idents enumerateKeysAndObjectsUsingBlock:^(
|
[identifiers enumerateKeysAndObjectsUsingBlock:^(
|
||||||
OFString *name, Ident *ident, bool *stop) {
|
OFString *name, Identifier *identifier, bool *stop) {
|
||||||
if (strncmp(ident.name.UTF8String, s + 1,
|
if (strncmp(identifier.name.UTF8String, s + 1,
|
||||||
completesize) == 0 &&
|
completesize) == 0 &&
|
||||||
idx++ == completeidx) {
|
idx++ == completeidx) {
|
||||||
strcpy_s(s, "/");
|
strcpy_s(s, "/");
|
||||||
strcat_s(s, ident.name.UTF8String);
|
strcat_s(s, identifier.name.UTF8String);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -602,24 +461,28 @@ writecfg()
|
||||||
writeclientinfo(stream);
|
writeclientinfo(stream);
|
||||||
[stream writeString:@"\n"];
|
[stream writeString:@"\n"];
|
||||||
|
|
||||||
[idents enumerateKeysAndObjectsUsingBlock:^(
|
[identifiers enumerateKeysAndObjectsUsingBlock:^(
|
||||||
OFString *name, Ident *ident, bool *stop) {
|
OFString *name, __kindof Identifier *identifier, bool *stop) {
|
||||||
if (ident.type == ID_VAR && ident.persist) {
|
if (![identifier isKindOfClass:[Variable class]] ||
|
||||||
[stream
|
![identifier persisted])
|
||||||
writeFormat:@"%@ %d\n", ident.name, *ident.storage];
|
return;
|
||||||
}
|
|
||||||
|
[stream writeFormat:@"%@ %d\n", identifier.name,
|
||||||
|
*[identifier storage]];
|
||||||
}];
|
}];
|
||||||
[stream writeString:@"\n"];
|
[stream writeString:@"\n"];
|
||||||
|
|
||||||
writebinds(stream);
|
writebinds(stream);
|
||||||
[stream writeString:@"\n"];
|
[stream writeString:@"\n"];
|
||||||
|
|
||||||
[idents enumerateKeysAndObjectsUsingBlock:^(
|
[identifiers enumerateKeysAndObjectsUsingBlock:^(
|
||||||
OFString *name, Ident *ident, bool *stop) {
|
OFString *name, __kindof Identifier *identifier, bool *stop) {
|
||||||
if (ident.type == ID_ALIAS &&
|
if (![identifier isKindOfClass:[Alias class]] ||
|
||||||
![ident.name hasPrefix:@"nextmap_"])
|
[identifier.name hasPrefix:@"nextmap_"])
|
||||||
[stream writeFormat:@"alias \"%@\" [%@]\n", ident.name,
|
return;
|
||||||
ident.action];
|
|
||||||
|
[stream writeFormat:@"alias \"%@\" [%@]\n", identifier.name,
|
||||||
|
[identifier action]];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[stream close];
|
[stream close];
|
|
@ -1,17 +1,20 @@
|
||||||
executable('client',
|
executable('client',
|
||||||
[
|
[
|
||||||
|
'Alias.m',
|
||||||
|
'Command.mm',
|
||||||
'Cube.mm',
|
'Cube.mm',
|
||||||
'Ident.m',
|
'Identifier.m',
|
||||||
'KeyMapping.m',
|
'KeyMapping.m',
|
||||||
'MD2.mm',
|
'MD2.mm',
|
||||||
'MapModelInfo.m',
|
'MapModelInfo.m',
|
||||||
'Menu.m',
|
'Menu.m',
|
||||||
'MenuItem.m',
|
'MenuItem.m',
|
||||||
|
'Variable.m',
|
||||||
'client.mm',
|
'client.mm',
|
||||||
'clientextras.mm',
|
'clientextras.mm',
|
||||||
'clientgame.mm',
|
'clientgame.mm',
|
||||||
'clients2c.mm',
|
'clients2c.mm',
|
||||||
'command.mm',
|
'commands.mm',
|
||||||
'console.mm',
|
'console.mm',
|
||||||
'editing.mm',
|
'editing.mm',
|
||||||
'entities.mm',
|
'entities.mm',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue