MWCC/compiler_and_linker/unsorted/CObjCModern.c

182 lines
4.4 KiB
C
Raw Normal View History

2022-12-29 12:32:55 +00:00
#include "compiler/CObjCModern.h"
#include "compiler/CError.h"
#include "compiler/CExpr.h"
#include "compiler/CObjC.h"
#include "compiler/CPrep.h"
#include "compiler/CPrepTokenizer.h"
#include "compiler/CompilerTools.h"
#include "compiler/objc.h"
#include "compiler/objects.h"
#include "compiler/scopes.h"
static ObjCNamedArg *CObjC_GetKeywordArgList(HashNameNode *name, Boolean *isSingleArg) {
ObjCNamedArg *first;
ObjCNamedArg *arg;
char *start;
char *p;
start = name->name;
first = NULL;
while (1) {
for (p = start; *p != '_'; p++) {
if (*p == 0) {
if (!first) {
first = lalloc(sizeof(ObjCNamedArg));
memclrw(first, sizeof(ObjCNamedArg));
first->name = name;
*isSingleArg = 1;
return first;
}
arg->next = lalloc(sizeof(ObjCNamedArg));
arg = arg->next;
arg->next = NULL;
arg->name = GetHashNameNode(start);
arg->expr = NULL;
*isSingleArg = 0;
return first;
}
}
if (first) {
arg->next = lalloc(sizeof(ObjCNamedArg));
arg = arg->next;
} else {
arg = lalloc(sizeof(ObjCNamedArg));
first = arg;
}
*p = 0;
arg->next = NULL;
arg->name = GetHashNameNode(start);
arg->expr = NULL;
*p = '_';
if (*(++p) == 0) {
*isSingleArg = 0;
return first;
}
start = p;
}
}
static ENode *CObjC_ModernSendMessage(TypeClass *tclass, ENode *expr, HashNameNode *name, Boolean isSuper) {
ENode *callexpr;
ObjCNamedArg *args;
ObjCNamedArg *arg;
ENodeList *unnamedArgs;
Boolean isSingleArg;
CError_ASSERT(92, ENODE_IS(expr, EINDIRECT));
expr = expr->data.monadic;
args = CObjC_GetKeywordArgList(name, &isSingleArg);
if ((tk = lex()) == ')') {
if (!isSingleArg) {
CError_Error(CErrorStr162);
return nullnode();
}
callexpr = CObjC_MakeSendMsgExpr(expr, tclass, args, NULL, 1, isSuper);
tk = lex();
return callexpr;
}
if (isSingleArg) {
CError_Error(CErrorStr162);
return nullnode();
}
unnamedArgs = NULL;
arg = args;
while (1) {
arg->expr = assignment_expression();
if (tk == ')') {
if (arg->next) {
CError_Error(CErrorStr162);
return nullnode();
}
break;
}
if (tk != ',') {
CError_Error(CErrorStr141);
return nullnode();
}
tk = lex();
arg = arg->next;
if (!arg) {
unnamedArgs = CExpr_ScanExpressionList(0);
break;
}
}
callexpr = CObjC_MakeSendMsgExpr(expr, tclass, args, unnamedArgs, 1, isSuper);
tk = lex();
return callexpr;
}
ENode *CObjC_CheckModernSendMessage(TypeClass *tclass, ENode *expr) {
HashNameNode *name;
SInt32 state;
CPrep_TokenStreamGetState(&state);
tk = lex();
CObjC_TranslateSelectorToken();
if (tk == TK_IDENTIFIER) {
if (!strcmp(tkidentifier->name, "super")) {
if (lex() == TK_COLON_COLON) {
tk = lex();
CObjC_TranslateSelectorToken();
name = tkidentifier;
if (tk == TK_IDENTIFIER && lex() == '(')
return CObjC_ModernSendMessage(tclass, expr, name, 1);
}
} else {
name = tkidentifier;
if (lex() == '(')
return CObjC_ModernSendMessage(tclass, expr, name, 0);
}
}
CPrep_TokenStreamSetState(&state);
return NULL;
}
ENode *CObjC_New(TypeClass *tclass) {
ObjCNamedArg *arg;
ENode *objexpr;
arg = lalloc(sizeof(ObjCNamedArg));
memclrw(arg, sizeof(ObjCNamedArg));
arg->name = GetHashNameNode("alloc");
objexpr = create_objectrefnode(tclass->objcinfo->classobject);
return CObjC_MakeSendMsgExpr(objexpr, tclass, arg, NULL, 1, 0);
}
ENode *CObjC_Delete(TypeClass *tclass, ENode *objexpr) {
ObjCNamedArg *arg;
arg = lalloc(sizeof(ObjCNamedArg));
memclrw(arg, sizeof(ObjCNamedArg));
arg->name = GetHashNameNode("dealloc");
return CObjC_MakeSendMsgExpr(objexpr, tclass, arg, NULL, 0, 0);
}