Introduce basic methodmaps (PR #38).
commit 1e5213d43fdd170bb0c30af914a4e40610014b2b
Author: David Anderson <dvander@alliedmods.net>
Date: Sat Jun 21 04:09:27 2014 -0700
Quell MSVC C99 bugs.
commit f2e166c5925fda49b5abeadc0aa0f9156b99cf11
Author: David Anderson <dvander@alliedmods.net>
Date: Sat Jun 21 03:59:23 2014 -0700
Fix varying levels of stupid memory errors.
commit b0773d7be45345351ab1c1738681d5215a97f3f3
Author: David Anderson <dvander@alliedmods.net>
Date: Sat Jun 21 03:36:39 2014 -0700
Fix memory leak in parsing some control flow structures.
commit 5aca55713cfc2dd09c5900132fc4a6be51e3e309
Author: David Anderson <dvander@alliedmods.net>
Date: Sat Jun 21 03:35:17 2014 -0700
Fix memory leak in struct parsing.
commit b46ec5cd281b46177e83c4f0a4acac9cc1065c53
Author: David Anderson <dvander@alliedmods.net>
Date: Sat Jun 21 03:32:03 2014 -0700
Fix build.
commit 17bbbb9a46bfc00862adca7d3e15369a48e9ac0f
Merge: c083409 2107599
Author: David Anderson <dvander@alliedmods.net>
Date: Sat Jun 21 01:26:27 2014 -0700
Merge branch 'master' into methodmaps
commit c083409b569abff13f24d3b8c47f8ff199036840
Author: David Anderson <dvander@alliedmods.net>
Date: Fri Jun 20 23:49:36 2014 -0700
Add VS2k13 support.
commit b7993778494d538cb1c1965116030142a7f7765b
Author: David Anderson <dvander@alliedmods.net>
Date: Fri Jun 20 01:28:08 2014 -0700
Implement destructors.
commit 1a340dec260d079ed1b79351ed7b50b58a997cea
Author: David Anderson <dvander@alliedmods.net>
Date: Fri Jun 20 00:08:04 2014 -0700
Add some tests.
commit 12db52ee64eb009ead9294495e9034c63ab75b09
Author: David Anderson <dvander@alliedmods.net>
Date: Fri Jun 20 00:05:49 2014 -0700
Initial implementation of constructors.
commit 074669a658caa2822aa864164b615a244c00a0bc
Author: David Anderson <dvander@alliedmods.net>
Date: Thu Jun 19 22:42:35 2014 -0700
Add simple test harness.
commit 27c1e3cf14e1e6c5cf35c80c792cce2744b804d7
Author: David Anderson <dvander@alliedmods.net>
Date: Thu Jun 19 22:15:42 2014 -0700
Big refactoring for new syntax.
commit f3c37fdc919e76ee0815e2394cbe8d221f9fc0ca
Author: David Anderson <dvander@alliedmods.net>
Date: Thu Jun 19 22:12:54 2014 -0700
Refactor tests for the new syntax.
commit 6211f392f8e722b907474cf380cfac4347e46b8e
Author: David Anderson <dvander@alliedmods.net>
Date: Wed Jun 18 22:25:48 2014 -0700
Make lexer tokens an enum.
commit 5210b013756b0b00de3a61c6490685c768ff8cbd
Author: David Anderson <dvander@alliedmods.net>
Date: Tue Jun 17 06:48:15 2014 -0700
Add comment.
commit 06688ff4aced14077dd21a9cc1db4c26c7420ff3
Author: David Anderson <dvander@alliedmods.net>
Date: Tue Jun 17 06:46:10 2014 -0700
Allow |this| to be a base type of the methodmap.
commit 05cf3682020e0e6d9f47b1a0a6727b9edbfe7622
Author: David Anderson <dvander@alliedmods.net>
Date: Mon Jun 16 22:11:58 2014 -0700
Unify duplicate typesymbol checking.
commit 09161bf2691c8c1ed25b9b70fda01c336f21aa0b
Author: David Anderson <dvander@alliedmods.net>
Date: Mon Jun 16 19:53:36 2014 -0700
Close loophole that allowed methodmaps for enums.
commit 5bb4aeba89fec47a4de7a7532d27830999d1fcb4
Author: David Anderson <dvander@alliedmods.net>
Date: Mon Jun 16 01:50:42 2014 -0700
Add tests and dbi/handle changes.
commit b9203e2491daec2a8073874d6375949483778d14
Author: David Anderson <dvander@alliedmods.net>
Date: Mon Jun 16 01:38:29 2014 -0700
Ensure methodmap tags are fixed.
commit 878b80fd87a2ea500d3a28ce2d53f616d1efe5e8
Author: David Anderson <dvander@alliedmods.net>
Date: Mon Jun 16 01:36:04 2014 -0700
Implement inheritance.
commit 6ba9e004fbae18ad68056368ddd0affdc78659f1
Author: David Anderson <dvander@alliedmods.net>
Date: Mon Jun 16 01:31:00 2014 -0700
Refactor matchtag() to not be insane.
commit 4ede6343b0682c6df98fa869153828e92f891bcc
Author: David Anderson <dvander@alliedmods.net>
Date: Mon Jun 16 01:20:50 2014 -0700
Fix indenting.
commit e3ddef8916e3dd5f4ff0fe571d6e1c3acd163352
Author: David Anderson <dvander@alliedmods.net>
Date: Mon Jun 16 01:20:27 2014 -0700
Initial prototype.
This commit is contained in:
parent
210759907d
commit
63ad5eff18
@ -701,18 +701,7 @@ native SQL_TQuery(Handle:database, SQLTCallback:callback, const String:query[],
|
||||
*
|
||||
* @return A transaction handle.
|
||||
*/
|
||||
native Handle:SQL_CreateTransaction();
|
||||
|
||||
/**
|
||||
* Adds a query to a transaction object.
|
||||
*
|
||||
* @param txn A transaction handle.
|
||||
* @param query Query string.
|
||||
* @param data Extra data value to pass to the final callback.
|
||||
* @return The index of the query in the transaction's query list.
|
||||
* @error Invalid transaction handle.
|
||||
*/
|
||||
native SQL_AddQuery(Handle:txn, const String:query[], any:data=0);
|
||||
native Transaction:SQL_CreateTransaction();
|
||||
|
||||
/**
|
||||
* Callback for a successful transaction.
|
||||
@ -739,6 +728,23 @@ functag public SQLTxnSuccess(Handle:db, any:data, numQueries, Handle:results[],
|
||||
*/
|
||||
functag public SQLTxnFailure(Handle:db, any:data, numQueries, const String:error[], failIndex, any:queryData[]);
|
||||
|
||||
/**
|
||||
* Adds a query to a transaction object.
|
||||
*
|
||||
* @param txn A transaction handle.
|
||||
* @param query Query string.
|
||||
* @param data Extra data value to pass to the final callback.
|
||||
* @return The index of the query in the transaction's query list.
|
||||
* @error Invalid transaction handle.
|
||||
*/
|
||||
native SQL_AddQuery(Transaction:txn, const String:query[], any:data=0);
|
||||
|
||||
methodmap Transaction < Handle
|
||||
{
|
||||
public Transaction() = SQL_CreateTransaction;
|
||||
public AddQuery() = SQL_AddQuery;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a transaction to the database thread. The transaction handle is
|
||||
* automatically closed. When the transaction completes, the optional
|
||||
@ -755,7 +761,7 @@ functag public SQLTxnFailure(Handle:db, any:data, numQueries, const String:error
|
||||
*/
|
||||
native SQL_ExecuteTransaction(
|
||||
Handle:db,
|
||||
Handle:txn,
|
||||
Transaction:txn,
|
||||
SQLTxnSuccess:onSuccess=SQLTxnSuccess:-1,
|
||||
SQLTxnFailure:onError=SQLTxnFailure:-1,
|
||||
any:data=0,
|
||||
|
@ -36,9 +36,9 @@
|
||||
#define _handles_included
|
||||
|
||||
/**
|
||||
* Handle helper macros.
|
||||
* Preset Handle values.
|
||||
*/
|
||||
enum Handle
|
||||
enum Handle: // Tag disables introducing "Handle" as a symbol.
|
||||
{
|
||||
INVALID_HANDLE = 0,
|
||||
};
|
||||
@ -52,10 +52,9 @@ enum Handle
|
||||
* sure you read the documentation on whatever provided the Handle.
|
||||
*
|
||||
* @param hndl Handle to close.
|
||||
* @return True if successful, false if not closeable.
|
||||
* @error Invalid handles will cause a run time error.
|
||||
*/
|
||||
native bool:CloseHandle(Handle:hndl);
|
||||
native CloseHandle(Handle:hndl);
|
||||
|
||||
/**
|
||||
* Clones a Handle. When passing handles in between plugins, caching handles
|
||||
@ -76,6 +75,15 @@ native bool:CloseHandle(Handle:hndl);
|
||||
*/
|
||||
native Handle:CloneHandle(Handle:hndl, Handle:plugin=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Helper for object-oriented syntax.
|
||||
*/
|
||||
methodmap Handle
|
||||
{
|
||||
public Clone() = CloneHandle;
|
||||
public ~Handle() = CloseHandle;
|
||||
};
|
||||
|
||||
/**
|
||||
* Do not use this function. Returns if a Handle and its contents
|
||||
* are readable, whereas INVALID_HANDLE only checks for the absence
|
||||
|
@ -279,10 +279,10 @@ public Action:Command_TestTxn(args)
|
||||
|
||||
SetTestContext("CreateTransaction");
|
||||
|
||||
new Handle:txn = SQL_CreateTransaction();
|
||||
AssertEq("AddQuery", SQL_AddQuery(txn, "INSERT INTO egg (id) VALUES (4)", 50), 0);
|
||||
AssertEq("AddQuery", SQL_AddQuery(txn, "INSERT INTO egg (id) VALUES (5)", 60), 1);
|
||||
AssertEq("AddQuery", SQL_AddQuery(txn, "SELECT COUNT(id) FROM egg", 70), 2);
|
||||
new Transaction:txn = SQL_CreateTransaction();
|
||||
AssertEq("AddQuery", txn.AddQuery("INSERT INTO egg (id) VALUES (4)", 50), 0);
|
||||
AssertEq("AddQuery", txn.AddQuery("INSERT INTO egg (id) VALUES (5)", 60), 1);
|
||||
AssertEq("AddQuery", txn.AddQuery("SELECT COUNT(id) FROM egg", 70), 2);
|
||||
SQL_ExecuteTransaction(
|
||||
db,
|
||||
txn,
|
||||
@ -292,9 +292,9 @@ public Action:Command_TestTxn(args)
|
||||
);
|
||||
|
||||
txn = SQL_CreateTransaction();
|
||||
AssertEq("AddQuery", SQL_AddQuery(txn, "INSERT INTO egg (id) VALUES (6)", 50), 0);
|
||||
AssertEq("AddQuery", SQL_AddQuery(txn, "INSERT INTO egg (id) VALUES (6)", 60), 1);
|
||||
AssertEq("AddQuery", SQL_AddQuery(txn, "SELECT COUNT(id) FROM egg", 70), 2);
|
||||
AssertEq("AddQuery", txn.AddQuery("INSERT INTO egg (id) VALUES (6)", 50), 0);
|
||||
AssertEq("AddQuery", txn.AddQuery("INSERT INTO egg (id) VALUES (6)", 60), 1);
|
||||
AssertEq("AddQuery", txn.AddQuery("SELECT COUNT(id) FROM egg", 70), 2);
|
||||
SQL_ExecuteTransaction(
|
||||
db,
|
||||
txn,
|
||||
@ -306,13 +306,13 @@ public Action:Command_TestTxn(args)
|
||||
// Make sure the transaction was rolled back - COUNT should be 5.
|
||||
txn = SQL_CreateTransaction();
|
||||
AssertEq("CloneHandle", _:CloneHandle(txn), _:INVALID_HANDLE);
|
||||
SQL_AddQuery(txn, "SELECT COUNT(id) FROM egg");
|
||||
txn.AddQuery("SELECT COUNT(id) FROM egg");
|
||||
SQL_ExecuteTransaction(
|
||||
db,
|
||||
txn,
|
||||
Txn_Test3_OnSuccess
|
||||
);
|
||||
|
||||
CloseHandle(db);
|
||||
db.Close();
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ compiler.includes += [
|
||||
]
|
||||
|
||||
if compiler.cc.behavior == 'gcc':
|
||||
compiler.cflags += ['-Wno-format']
|
||||
compiler.cflags += ['-std=c99', '-Wno-format']
|
||||
if builder.target_platform == 'linux':
|
||||
compiler.postlink += ['-lgcc', '-lm']
|
||||
elif compiler.cc.behavior == 'msvc':
|
||||
|
@ -113,7 +113,8 @@ typedef struct s_constvalue {
|
||||
*/
|
||||
typedef struct s_symbol {
|
||||
struct s_symbol *next;
|
||||
struct s_symbol *parent; /* hierarchical types (multi-dimensional arrays) */
|
||||
struct s_symbol *parent; /* hierarchical types */
|
||||
struct s_symbol *target; /* proxy target */
|
||||
char name[sNAMEMAX+1];
|
||||
uint32_t hash; /* value derived from name, for quicker searching */
|
||||
cell addr; /* address or offset (or value for constant, index for native function) */
|
||||
@ -150,7 +151,6 @@ typedef struct s_symbol {
|
||||
char *documentation; /* optional documentation string */
|
||||
} symbol;
|
||||
|
||||
|
||||
/* Possible entries for "ident". These are used in the "symbol", "value"
|
||||
* and arginfo structures. Not every constant is valid for every use.
|
||||
* In an argument list, the list is terminated with a "zero" ident; labels
|
||||
@ -168,6 +168,7 @@ typedef struct s_symbol {
|
||||
#define iFUNCTN 9
|
||||
#define iREFFUNC 10
|
||||
#define iVARARGS 11 /* function specified ... as argument(s) */
|
||||
#define iPROXY 12 /* proxies to another symbol. */
|
||||
|
||||
/* Possible entries for "usage"
|
||||
*
|
||||
@ -237,7 +238,7 @@ typedef struct s_symbol {
|
||||
|
||||
#define sSTATEVAR 3 /* criterion to find variables (sSTATEVAR implies a global variable) */
|
||||
|
||||
typedef struct s_value {
|
||||
typedef struct value_s {
|
||||
symbol *sym; /* symbol in symbol table, NULL for (constant) expression */
|
||||
cell constval; /* value of the constant expression (if ident==iCONSTEXPR)
|
||||
* also used for the size of a literal array */
|
||||
@ -249,6 +250,20 @@ typedef struct s_value {
|
||||
cell *arrayidx; /* last used array indices, for checking self assignment */
|
||||
} value;
|
||||
|
||||
/* Wrapper around value + l/rvalue bit. */
|
||||
typedef struct svalue_s {
|
||||
value val;
|
||||
int lvalue;
|
||||
} svalue;
|
||||
|
||||
/* For parsing declarations. */
|
||||
typedef struct {
|
||||
char type[sNAMEMAX + 1];
|
||||
constvalue *enumroot;
|
||||
int tag;
|
||||
char usage;
|
||||
} declinfo_t;
|
||||
|
||||
/* "while" statement queue (also used for "for" and "do - while" loops) */
|
||||
enum {
|
||||
wqBRK, /* used to restore stack for "break" */
|
||||
@ -284,6 +299,13 @@ typedef struct s_stringpair {
|
||||
char *documentation;
|
||||
} stringpair;
|
||||
|
||||
// Helper for token info.
|
||||
typedef struct {
|
||||
int id;
|
||||
cell val;
|
||||
char *str;
|
||||
} token_t;
|
||||
|
||||
/* macros for code generation */
|
||||
#define opcodes(n) ((n)*sizeof(cell)) /* opcode size */
|
||||
#define opargs(n) ((n)*sizeof(cell)) /* size of typical argument */
|
||||
@ -291,101 +313,110 @@ typedef struct s_stringpair {
|
||||
/* Tokens recognized by lex()
|
||||
* Some of these constants are assigned as well to the variable "lastst" (see SC1.C)
|
||||
*/
|
||||
#define tFIRST 256 /* value of first multi-character operator */
|
||||
#define tMIDDLE 280 /* value of last multi-character operator */
|
||||
#define tLAST 332 /* value of last multi-character match-able token */
|
||||
/* multi-character operators */
|
||||
#define taMULT 256 /* *= */
|
||||
#define taDIV 257 /* /= */
|
||||
#define taMOD 258 /* %= */
|
||||
#define taADD 259 /* += */
|
||||
#define taSUB 260 /* -= */
|
||||
#define taSHL 261 /* <<= */
|
||||
#define taSHRU 262 /* >>>= */
|
||||
#define taSHR 263 /* >>= */
|
||||
#define taAND 264 /* &= */
|
||||
#define taXOR 265 /* ^= */
|
||||
#define taOR 266 /* |= */
|
||||
#define tlOR 267 /* || */
|
||||
#define tlAND 268 /* && */
|
||||
#define tlEQ 269 /* == */
|
||||
#define tlNE 270 /* != */
|
||||
#define tlLE 271 /* <= */
|
||||
#define tlGE 272 /* >= */
|
||||
#define tSHL 273 /* << */
|
||||
#define tSHRU 274 /* >>> */
|
||||
#define tSHR 275 /* >> */
|
||||
#define tINC 276 /* ++ */
|
||||
#define tDEC 277 /* -- */
|
||||
#define tELLIPS 278 /* ... */
|
||||
#define tDBLDOT 279 /* .. */
|
||||
#define tDBLCOLON 280 /* :: */
|
||||
enum {
|
||||
/* value of first multi-character operator */
|
||||
tFIRST = 256,
|
||||
/* multi-character operators */
|
||||
taMULT = tFIRST, /* *= */
|
||||
taDIV, /* /= */
|
||||
taMOD, /* %= */
|
||||
taADD, /* += */
|
||||
taSUB, /* -= */
|
||||
taSHL, /* <<= */
|
||||
taSHRU, /* >>>= */
|
||||
taSHR, /* >>= */
|
||||
taAND, /* &= */
|
||||
taXOR, /* ^= */
|
||||
taOR, /* |= */
|
||||
tlOR, /* || */
|
||||
tlAND, /* && */
|
||||
tlEQ, /* == */
|
||||
tlNE, /* != */
|
||||
tlLE, /* <= */
|
||||
tlGE, /* >= */
|
||||
tSHL, /* << */
|
||||
tSHRU, /* >>> */
|
||||
tSHR, /* >> */
|
||||
tINC, /* ++ */
|
||||
tDEC, /* -- */
|
||||
tELLIPS, /* ... */
|
||||
tDBLDOT, /* .. */
|
||||
tDBLCOLON, /* :: */
|
||||
/* value of last multi-character operator */
|
||||
tMIDDLE = tDBLCOLON,
|
||||
/* reserved words (statements) */
|
||||
#define tASSERT 281
|
||||
#define tBEGIN 282
|
||||
#define tBREAK 283
|
||||
#define tCASE 284
|
||||
#define tCELLSOF 285
|
||||
#define tCHAR 286
|
||||
#define tCONST 287
|
||||
#define tCONTINUE 288
|
||||
#define tDEFAULT 289
|
||||
#define tDEFINED 290
|
||||
#define tDO 291
|
||||
#define tELSE 292
|
||||
#define tEND 293
|
||||
#define tENUM 294
|
||||
#define tEXIT 295
|
||||
#define tFOR 296
|
||||
#define tFORWARD 297
|
||||
#define tFUNCENUM 298
|
||||
#define tFUNCTAG 299
|
||||
#define tGOTO 300
|
||||
#define tIF 301
|
||||
#define tNATIVE 302
|
||||
#define tNEW 303
|
||||
#define tDECL 304
|
||||
#define tOPERATOR 305
|
||||
#define tPUBLIC 306
|
||||
#define tRETURN 307
|
||||
#define tSIZEOF 308
|
||||
#define tSLEEP 309
|
||||
#define tSTATIC 310
|
||||
#define tSTOCK 311
|
||||
#define tSTRUCT 312
|
||||
#define tSWITCH 313
|
||||
#define tTAGOF 314
|
||||
#define tTHEN 315
|
||||
#define tWHILE 316
|
||||
/* compiler directives */
|
||||
#define tpASSERT 317 /* #assert */
|
||||
#define tpDEFINE 318
|
||||
#define tpELSE 319 /* #else */
|
||||
#define tpELSEIF 320 /* #elseif */
|
||||
#define tpEMIT 321
|
||||
#define tpENDIF 322
|
||||
#define tpENDINPUT 323
|
||||
#define tpENDSCRPT 324
|
||||
#define tpERROR 325
|
||||
#define tpFILE 326
|
||||
#define tpIF 327 /* #if */
|
||||
#define tINCLUDE 328
|
||||
#define tpLINE 329
|
||||
#define tpPRAGMA 330
|
||||
#define tpTRYINCLUDE 331
|
||||
#define tpUNDEF 332
|
||||
/* semicolon is a special case, because it can be optional */
|
||||
#define tTERM 333 /* semicolon or newline */
|
||||
#define tENDEXPR 334 /* forced end of expression */
|
||||
/* other recognized tokens */
|
||||
#define tNUMBER 335 /* integer number */
|
||||
#define tRATIONAL 336 /* rational number */
|
||||
#define tSYMBOL 337
|
||||
#define tLABEL 338
|
||||
#define tSTRING 339
|
||||
#define tEXPR 341 /* for assigment to "lastst" only (see SC1.C) */
|
||||
#define tENDLESS 342 /* endless loop, for assigment to "lastst" only */
|
||||
#define tEMPTYBLOCK 343 /* empty blocks for AM bug 4825 */
|
||||
tASSERT,
|
||||
tBEGIN,
|
||||
tBREAK,
|
||||
tCASE,
|
||||
tCELLSOF,
|
||||
tCHAR,
|
||||
tCONST,
|
||||
tCONTINUE,
|
||||
tDEFAULT,
|
||||
tDEFINED,
|
||||
tDELETE,
|
||||
tDO,
|
||||
tELSE,
|
||||
tEND,
|
||||
tENUM,
|
||||
tEXIT,
|
||||
tFOR,
|
||||
tFORWARD,
|
||||
tFUNCENUM,
|
||||
tFUNCTAG,
|
||||
tGOTO,
|
||||
tIF,
|
||||
tINT,
|
||||
tMETHODMAP,
|
||||
tNATIVE,
|
||||
tNEW,
|
||||
tDECL,
|
||||
tOPERATOR,
|
||||
tPUBLIC,
|
||||
tRETURN,
|
||||
tSIZEOF,
|
||||
tSLEEP,
|
||||
tSTATIC,
|
||||
tSTOCK,
|
||||
tSTRUCT,
|
||||
tSWITCH,
|
||||
tTAGOF,
|
||||
tTHEN,
|
||||
tVOID,
|
||||
tWHILE,
|
||||
/* compiler directives */
|
||||
tpASSERT, /* #assert */
|
||||
tpDEFINE,
|
||||
tpELSE, /* #else */
|
||||
tpELSEIF, /* #elseif */
|
||||
tpEMIT,
|
||||
tpENDIF,
|
||||
tpENDINPUT,
|
||||
tpENDSCRPT,
|
||||
tpERROR,
|
||||
tpFILE,
|
||||
tpIF, /* #if */
|
||||
tINCLUDE,
|
||||
tpLINE,
|
||||
tpPRAGMA,
|
||||
tpTRYINCLUDE,
|
||||
tpUNDEF,
|
||||
tLAST = tpUNDEF, /* value of last multi-character match-able token */
|
||||
/* semicolon is a special case, because it can be optional */
|
||||
tTERM, /* semicolon or newline */
|
||||
tENDEXPR, /* forced end of expression */
|
||||
/* other recognized tokens */
|
||||
tNUMBER, /* integer number */
|
||||
tRATIONAL, /* rational number */
|
||||
tSYMBOL,
|
||||
tLABEL,
|
||||
tSTRING,
|
||||
tEXPR, /* for assigment to "lastst" only (see SC1.C) */
|
||||
tENDLESS, /* endless loop, for assigment to "lastst" only */
|
||||
tEMPTYBLOCK, /* empty blocks for AM bug 4825 */
|
||||
tLAST_TOKEN_ID
|
||||
};
|
||||
|
||||
/* (reversed) evaluation of staging buffer */
|
||||
#define sSTARTREORDER 0x01
|
||||
@ -467,8 +498,12 @@ typedef enum s_optmark {
|
||||
int pc_compile(int argc, char **argv);
|
||||
int pc_addconstant(char *name,cell value,int tag);
|
||||
int pc_addtag(char *name);
|
||||
int pc_addtag_flags(char *name, int flags);
|
||||
int pc_findtag(const char *name);
|
||||
int pc_addfunctag(char *name);
|
||||
int pc_enablewarning(int number,int enable);
|
||||
const char *pc_tagname(int tag);
|
||||
int parse_decl(declinfo_t *decl, const token_t *first, int flags);
|
||||
|
||||
/*
|
||||
* Functions called from the compiler (to be implemented by you)
|
||||
@ -553,11 +588,13 @@ SC_FUNC int plungefile(char *name,int try_currentpath,int try_includepaths); /
|
||||
SC_FUNC void preprocess(void);
|
||||
SC_FUNC void lexinit(void);
|
||||
SC_FUNC int lex(cell *lexvalue,char **lexsym);
|
||||
SC_FUNC int lextok(token_t *tok);
|
||||
SC_FUNC void lexpush(void);
|
||||
SC_FUNC void lexclr(int clreol);
|
||||
SC_FUNC int matchtoken(int token);
|
||||
SC_FUNC int tokeninfo(cell *val,char **str);
|
||||
SC_FUNC int needtoken(int token);
|
||||
SC_FUNC int expecttoken(int id, token_t *tok);
|
||||
SC_FUNC void litadd(cell value);
|
||||
SC_FUNC void litinsert(cell value,int pos);
|
||||
SC_FUNC int alphanum(char c);
|
||||
@ -570,8 +607,7 @@ SC_FUNC symbol *findglb(const char *name,int filter);
|
||||
SC_FUNC symbol *findloc(const char *name);
|
||||
SC_FUNC symbol *findconst(const char *name,int *matchtag);
|
||||
SC_FUNC symbol *finddepend(const symbol *parent);
|
||||
SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,
|
||||
int usage);
|
||||
SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag, int usage);
|
||||
SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag,
|
||||
int dim[],int numdim,int idxtag[]);
|
||||
SC_FUNC symbol *addvariable2(const char *name,cell addr,int ident,int vclass,int tag,
|
||||
@ -834,7 +870,8 @@ SC_VDECL int sc_curstates; /* ID of the current state list */
|
||||
SC_VDECL int pc_optimize; /* (peephole) optimization level */
|
||||
SC_VDECL int pc_memflags; /* special flags for the stack/heap usage */
|
||||
SC_VDECL int pc_functag; /* global function tag */
|
||||
SC_VDECL int pc_tag_string; /* global string tag */
|
||||
SC_VDECL int pc_tag_string; /* global String tag */
|
||||
SC_VDECL int pc_tag_void; /* global void tag */
|
||||
SC_VDECL int pc_anytag; /* global any tag */
|
||||
SC_VDECL int glbstringread; /* last global string read */
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* vim: set sts=2 ts=8 sw=2 tw=99 et: */
|
||||
/* Pawn compiler
|
||||
*
|
||||
* Function and variable definition and declaration, statement parser.
|
||||
@ -75,6 +76,7 @@
|
||||
int pc_anytag = 0;
|
||||
int pc_functag = 0;
|
||||
int pc_tag_string = 0;
|
||||
int pc_tag_void = 0;
|
||||
|
||||
static void resetglobals(void);
|
||||
static void initglobals(void);
|
||||
@ -93,6 +95,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,
|
||||
int stock,int fconst);
|
||||
static void declstructvar(char *firstname,int fpublic, pstruct_t *pstruct);
|
||||
static int declloc(int fstatic);
|
||||
static void dodelete();
|
||||
static void decl_const(int table);
|
||||
static void declstruct();
|
||||
static void decl_enum(int table);
|
||||
@ -107,7 +110,7 @@ static cell initvector(int ident,int tag,cell size,int fillzero,
|
||||
static cell init(int ident,int *tag,int *errorfound);
|
||||
static int getstates(const char *funcname);
|
||||
static void attachstatelist(symbol *sym, int state_id);
|
||||
static void funcstub(int fnative);
|
||||
static symbol *funcstub(int fnative);
|
||||
static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stock);
|
||||
static int declargs(symbol *sym,int chkshadow);
|
||||
static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
@ -137,6 +140,7 @@ static void dogoto(void);
|
||||
static void dolabel(void);
|
||||
static void doreturn(void);
|
||||
static void dofuncenum(int listmode);
|
||||
static void domethodmap(LayoutSpec spec);
|
||||
static void dobreak(void);
|
||||
static void docont(void);
|
||||
static void dosleep(void);
|
||||
@ -345,7 +349,8 @@ int pc_compile(int argc, char *argv[])
|
||||
#endif
|
||||
resetglobals();
|
||||
pstructs_free();
|
||||
funcenums_free();
|
||||
funcenums_free();
|
||||
methodmaps_free();
|
||||
sc_ctrlchar=sc_ctrlchar_org;
|
||||
sc_packstr=lcl_packstr;
|
||||
sc_needsemicolon=lcl_needsemicolon;
|
||||
@ -407,6 +412,7 @@ int pc_compile(int argc, char *argv[])
|
||||
reduce_referrers(&glbtab);
|
||||
delete_symbols(&glbtab,0,TRUE,FALSE);
|
||||
funcenums_free();
|
||||
methodmaps_free();
|
||||
pstructs_free();
|
||||
#if !defined NO_DEFINE
|
||||
delete_substtable();
|
||||
@ -529,6 +535,7 @@ cleanup:
|
||||
delete_sourcefiletable();
|
||||
delete_dbgstringtable();
|
||||
funcenums_free();
|
||||
methodmaps_free();
|
||||
pstructs_free();
|
||||
#if !defined NO_DEFINE
|
||||
delete_substtable();
|
||||
@ -628,14 +635,33 @@ static void inst_datetime_defines(void)
|
||||
insert_subst("__TIME__", ltime, 8);
|
||||
}
|
||||
|
||||
const char *pc_tagname(int tag)
|
||||
{
|
||||
constvalue *ptr=tagname_tab.next;
|
||||
for (; ptr; ptr=ptr->next) {
|
||||
if ((int)(ptr->value & TAGMASK) == (tag & TAGMASK))
|
||||
return ptr->name;
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
int pc_findtag(const char *name)
|
||||
{
|
||||
constvalue *ptr=tagname_tab.next;
|
||||
for (; ptr; ptr=ptr->next) {
|
||||
if (strcmp(name,ptr->name)==0)
|
||||
return (int)(ptr->value & TAGMASK);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int pc_addtag(char *name)
|
||||
{
|
||||
cell val;
|
||||
constvalue *ptr;
|
||||
int last,tag;
|
||||
int val;
|
||||
int flags = 0;
|
||||
|
||||
if (name==NULL) {
|
||||
/* no tagname was given, check for one */
|
||||
@ -645,6 +671,17 @@ int pc_addtag(char *name)
|
||||
} /* if */
|
||||
} /* if */
|
||||
|
||||
if (isupper(*name))
|
||||
flags |= FIXEDTAG;
|
||||
|
||||
return pc_addtag_flags(name, flags);
|
||||
}
|
||||
|
||||
int pc_addtag_flags(char *name, int flags)
|
||||
{
|
||||
constvalue *ptr;
|
||||
int last,tag;
|
||||
|
||||
assert(strchr(name,':')==NULL); /* colon should already have been stripped */
|
||||
last=0;
|
||||
ptr=tagname_tab.next;
|
||||
@ -661,8 +698,7 @@ int pc_addtag(char *name)
|
||||
|
||||
/* tagname currently unknown, add it */
|
||||
tag=last+1; /* guaranteed not to exist already */
|
||||
if (isupper(*name))
|
||||
tag |= (int)FIXEDTAG;
|
||||
tag|=flags;
|
||||
append_constval(&tagname_tab,name,(cell)tag,0);
|
||||
return tag;
|
||||
}
|
||||
@ -1326,6 +1362,8 @@ static void setconstants(void)
|
||||
pc_anytag = pc_addtag("any");
|
||||
pc_functag = pc_addfunctag("Function");
|
||||
pc_tag_string = pc_addtag("String");
|
||||
pc_tag_void = pc_addtag_flags("void", FIXEDTAG);
|
||||
sc_rationaltag = pc_addtag("Float");
|
||||
|
||||
add_constant("true",1,sGLOBAL,1); /* boolean flags */
|
||||
add_constant("false",0,sGLOBAL,1);
|
||||
@ -1488,6 +1526,9 @@ static void parse(void)
|
||||
case tFUNCENUM:
|
||||
dofuncenum(TRUE);
|
||||
break;
|
||||
case tMETHODMAP:
|
||||
domethodmap(Layout_MethodMap);
|
||||
break;
|
||||
case tFUNCTAG:
|
||||
dofuncenum(FALSE);
|
||||
break;
|
||||
@ -1826,6 +1867,8 @@ static void declstructvar(char *firstname,int fpublic, pstruct_t *pstruct)
|
||||
matchtoken(';');
|
||||
/* Mark it as undefined instead */
|
||||
mysym->usage = uSTOCK|uSTRUCT;
|
||||
free(found);
|
||||
free(values);
|
||||
return;
|
||||
} else {
|
||||
mysym->usage = usage;
|
||||
@ -3110,6 +3153,13 @@ static void decl_const(int vclass)
|
||||
needtoken(tTERM);
|
||||
}
|
||||
|
||||
static void check_struct_name(const char *name)
|
||||
{
|
||||
LayoutSpec spec = deduce_layout_spec_by_name(name);
|
||||
if (!can_redef_layout_spec(spec, Layout_PawnStruct))
|
||||
error(110, name, layout_spec_name(spec));
|
||||
}
|
||||
|
||||
/*
|
||||
* declstruct - declare a struct type
|
||||
*/
|
||||
@ -3128,10 +3178,7 @@ static void declstruct(void)
|
||||
error(93);
|
||||
}
|
||||
|
||||
if (pstructs_find(str) != NULL)
|
||||
{
|
||||
error(98);
|
||||
}
|
||||
check_struct_name(str);
|
||||
|
||||
pstruct = pstructs_add(str);
|
||||
|
||||
@ -3202,13 +3249,423 @@ static void declstruct(void)
|
||||
}
|
||||
if (pstructs_addarg(pstruct, &arg) == NULL)
|
||||
{
|
||||
error(99, arg.name, pstruct->name);
|
||||
error(103, arg.name, layout_spec_name(Layout_PawnStruct));
|
||||
}
|
||||
} while (matchtoken(','));
|
||||
needtoken('}');
|
||||
matchtoken(';'); /* eat up optional semicolon */
|
||||
}
|
||||
|
||||
int parse_typeexpr(declinfo_t *decl, const token_t *first, int flags)
|
||||
{
|
||||
token_t tok;
|
||||
|
||||
if (first) {
|
||||
tok = *first;
|
||||
} else {
|
||||
lextok(&tok);
|
||||
}
|
||||
|
||||
if (tok.id == tCONST) {
|
||||
decl->usage |= uCONST;
|
||||
lextok(&tok);
|
||||
}
|
||||
|
||||
if (tok.id == tLABEL || tok.id == '[')
|
||||
return FALSE;
|
||||
|
||||
switch (tok.id) {
|
||||
case tINT:
|
||||
strcpy(decl->type, "int");
|
||||
decl->tag = 0;
|
||||
break;
|
||||
case tCHAR:
|
||||
strcpy(decl->type, "char");
|
||||
decl->tag = pc_tag_string;
|
||||
break;
|
||||
case tVOID:
|
||||
strcpy(decl->type, "void");
|
||||
decl->tag = pc_tag_void;
|
||||
break;
|
||||
case tSYMBOL:
|
||||
strcpy(decl->type, tok.str);
|
||||
if (strcmp(decl->type, "float") == 0) {
|
||||
decl->tag = sc_rationaltag;
|
||||
} else {
|
||||
decl->tag = pc_findtag(decl->type);
|
||||
if (decl->tag == sc_rationaltag)
|
||||
error(98, "Float", "float");
|
||||
else if (decl->tag == pc_tag_string)
|
||||
error(98, "String", "char");
|
||||
else if (decl->tag == 0)
|
||||
error(98, "_", "int");
|
||||
}
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Parse a new-style declaration. If the name was already fetched (because we
|
||||
// didn't have enough lookahead), it can be given ahead of time.
|
||||
int parse_decl(declinfo_t *decl, const token_t *first, int flags)
|
||||
{
|
||||
memset(decl, 0, sizeof(*decl));
|
||||
|
||||
if (!parse_typeexpr(decl, first, flags))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void define_constructor(methodmap_t *map, methodmap_method_t *method)
|
||||
{
|
||||
symbol *sym = findglb(map->name, sGLOBAL);
|
||||
if (sym && sym->ident == iPROXY && sym->parent == method->target)
|
||||
return;
|
||||
|
||||
if (sym) {
|
||||
const char *type = "<unknown>";
|
||||
switch (sym->ident) {
|
||||
case iVARIABLE:
|
||||
case iARRAY:
|
||||
case iARRAYCELL:
|
||||
case iARRAYCHAR:
|
||||
type = "variable";
|
||||
break;
|
||||
case iFUNCTN:
|
||||
type = "function";
|
||||
break;
|
||||
}
|
||||
error(113, map->name, type);
|
||||
return;
|
||||
}
|
||||
|
||||
sym = addsym(map->name, 0, iPROXY, sGLOBAL, 0, 0);
|
||||
sym->target = method->target;
|
||||
}
|
||||
|
||||
methodmap_method_t *parse_method(methodmap_t *map)
|
||||
{
|
||||
int is_dtor = 0;
|
||||
int is_bind = 0;
|
||||
int is_native = 0;
|
||||
const char *spectype = layout_spec_name(map->spec);
|
||||
|
||||
// We keep a wider buffer since we do name munging.
|
||||
char ident[sNAMEMAX * 3 + 1] = "<unknown>";
|
||||
char bindname[sNAMEMAX * 3 + 1] = "<unknown>";
|
||||
|
||||
needtoken(tPUBLIC);
|
||||
|
||||
token_t tok;
|
||||
declinfo_t decl;
|
||||
if (matchtoken('~')) {
|
||||
// We got something like "public ~Blah = X"
|
||||
is_bind = 1;
|
||||
is_dtor = 1;
|
||||
if (needtoken(tSYMBOL)) {
|
||||
tokeninfo(&tok.val, &tok.str);
|
||||
strcpy(ident, tok.str);
|
||||
}
|
||||
needtoken('(');
|
||||
needtoken(')');
|
||||
needtoken('=');
|
||||
if (!expecttoken(tSYMBOL, &tok))
|
||||
return NULL;
|
||||
strcpy(bindname, tok.str);
|
||||
} else {
|
||||
is_native = matchtoken(tNATIVE);
|
||||
|
||||
if (is_native) {
|
||||
// If we have a native, we should always get a type expression next.
|
||||
parse_decl(&decl, NULL, 0);
|
||||
} else {
|
||||
// Parsing "public Clone =" and "public Handle Clone = " requires two tokens
|
||||
// of lookahead. By the time we see the '=' in the first example, we'd have
|
||||
// expected a function name, but it's too late to back up - _lexpush is only
|
||||
// one token deep.
|
||||
//
|
||||
// If we see a symbol and a '=', we know it's a simple binding. Otherwise,
|
||||
// we have to take the token we got from lextok() and ask parse_decl() to
|
||||
// start parsing it as a type expression.
|
||||
int is_symbol = (lextok(&tok) == tSYMBOL);
|
||||
if (is_symbol) {
|
||||
// Save the string because matchtoken() will overwrite the token buffer.
|
||||
// Note we also have to repoint tok so parse_decl will point at our
|
||||
// local copy.
|
||||
strcpy(ident, tok.str);
|
||||
tok.str = ident;
|
||||
|
||||
if (matchtoken('(')) {
|
||||
needtoken(')');
|
||||
needtoken('=');
|
||||
|
||||
// Grab the name we're binding to.
|
||||
is_bind = 1;
|
||||
if (!expecttoken(tSYMBOL, &tok))
|
||||
return NULL;
|
||||
strcpy(bindname, tok.str);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_bind) {
|
||||
// We didn't find an '=', so proceed with a normal function signature.
|
||||
parse_decl(&decl, &tok, 0);
|
||||
is_dtor = matchtoken('~');
|
||||
|
||||
if (lextok(&tok) != tSYMBOL) {
|
||||
// Error, and if EOF, return. The lexpush is so we don't accidentally
|
||||
// skip over a terminator or something, since we scan to the end of the
|
||||
// line.
|
||||
lexpush();
|
||||
error(111);
|
||||
if (tok.id == 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy(ident, tok.str);
|
||||
} // if (tok == symbol && matchtoken('='))
|
||||
} // if (is_native)
|
||||
} // if (matchtoken('~'))
|
||||
|
||||
symbol *target = NULL;
|
||||
if (is_bind) {
|
||||
target = findglb(bindname, sGLOBAL);
|
||||
if (!target)
|
||||
error(17, ident);
|
||||
else if (target->ident != iFUNCTN)
|
||||
error(10);
|
||||
} else {
|
||||
error(10);
|
||||
}
|
||||
|
||||
if (!target)
|
||||
return NULL;
|
||||
|
||||
if (is_dtor) {
|
||||
// Make sure the dtor has the right name.
|
||||
if (strcmp(ident, map->name) != 0)
|
||||
error(114, spectype, map->name);
|
||||
|
||||
if (!(target->usage & uNATIVE)) {
|
||||
// Must be a native.
|
||||
error(118);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (target->tag != 0 && target->tag != pc_tag_void) {
|
||||
// Cannot return a value.
|
||||
error(99);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (target->dim.arglist[0].ident && target->dim.arglist[1].ident) {
|
||||
// Cannot have extra arguments.
|
||||
error(119);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Make sure the final name includes the ~.
|
||||
strcpy(ident, "~");
|
||||
strcat(ident, map->name);
|
||||
}
|
||||
|
||||
// Check that a method with this name doesn't already exist.
|
||||
for (size_t i = 0; i < map->nummethods; i++) {
|
||||
if (strcmp(map->methods[i]->name, ident) == 0) {
|
||||
error(103, ident, spectype);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
methodmap_method_t *method = (methodmap_method_t *)calloc(1, sizeof(methodmap_method_t));
|
||||
strcpy(method->name, ident);
|
||||
method->target = target;
|
||||
if (is_dtor)
|
||||
map->dtor = method;
|
||||
|
||||
// If the symbol is a constructor, we bypass the initial argument checks,
|
||||
// and instead require that it returns something with the same tag.
|
||||
if (strcmp(ident, map->name) == 0) {
|
||||
if (target->tag != map->tag)
|
||||
error(112, map->name);
|
||||
define_constructor(map, method);
|
||||
return method;
|
||||
}
|
||||
|
||||
// Check the implicit this parameter. Currently we only allow scalars. As
|
||||
// to not encourage enum-structs, we will not allow those either.
|
||||
const arginfo *first_arg = &target->dim.arglist[0];
|
||||
if (first_arg->ident == 0 ||
|
||||
first_arg->ident != iVARIABLE ||
|
||||
(first_arg->usage & uCONST) ||
|
||||
first_arg->hasdefault ||
|
||||
first_arg->numtags != 1)
|
||||
{
|
||||
free(method);
|
||||
error(108, spectype, map->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Ensure the methodmap tag is compatible with |this|.
|
||||
int ok = 0;
|
||||
for (methodmap_t *mapptr = map; mapptr; mapptr = mapptr->parent) {
|
||||
if (first_arg->tags[0] == mapptr->tag) {
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
error(108, spectype, map->name);
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
static int consume_line()
|
||||
{
|
||||
int val;
|
||||
char *str;
|
||||
|
||||
// First check for EOF.
|
||||
if (lex(&val, &str) == 0)
|
||||
return FALSE;
|
||||
lexpush();
|
||||
|
||||
while (!matchtoken(tTERM)) {
|
||||
// Check for EOF.
|
||||
if (lex(&val, &str) == 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* domethodmap - declare a method map for OO-ish syntax.
|
||||
*
|
||||
*/
|
||||
static void domethodmap(LayoutSpec spec)
|
||||
{
|
||||
int val;
|
||||
char *str;
|
||||
LayoutSpec old_spec;
|
||||
methodmap_t *parent = NULL;
|
||||
const char *spectype = layout_spec_name(spec);
|
||||
|
||||
// methodmap ::= "methodmap" symbol ("<" symbol)? "{" methodmap-body "}"
|
||||
char mapname[sNAMEMAX + 1];
|
||||
if (lex(&val, &str) != tSYMBOL)
|
||||
error(93);
|
||||
strcpy(mapname, str);
|
||||
|
||||
if (!isupper(*mapname))
|
||||
error(109, spectype);
|
||||
|
||||
old_spec = deduce_layout_spec_by_name(mapname);
|
||||
if (!can_redef_layout_spec(spec, old_spec))
|
||||
error(110, mapname, layout_spec_name(old_spec));
|
||||
|
||||
if (matchtoken('<')) {
|
||||
if (lex(&val, &str) != tSYMBOL) {
|
||||
error(93);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((parent = methodmap_find_by_name(str)) == NULL) {
|
||||
error(102, str);
|
||||
}
|
||||
}
|
||||
|
||||
methodmap_t *map = (methodmap_t *)calloc(1, sizeof(methodmap_t));
|
||||
map->parent = parent;
|
||||
map->tag = pc_addtag(mapname);
|
||||
map->spec = spec;
|
||||
strcpy(map->name, mapname);
|
||||
|
||||
methodmap_add(map);
|
||||
|
||||
needtoken('{');
|
||||
while (!matchtoken('}')) {
|
||||
methodmap_method_t *method;
|
||||
methodmap_method_t **methods;
|
||||
|
||||
if ((method = parse_method(map)) == NULL) {
|
||||
if (!consume_line())
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
needtoken(tTERM);
|
||||
|
||||
methods = (methodmap_method_t **)realloc(map->methods, sizeof(methodmap_method_t *) * (map->nummethods + 1));
|
||||
if (!methods) {
|
||||
error(123);
|
||||
return;
|
||||
}
|
||||
map->methods = methods;
|
||||
map->methods[map->nummethods++] = method;
|
||||
}
|
||||
|
||||
needtoken(tTERM);
|
||||
}
|
||||
|
||||
// delete ::= "delete" expr
|
||||
static void dodelete()
|
||||
{
|
||||
int tag;
|
||||
symbol *sym;
|
||||
|
||||
int ident = doexpr(TRUE, FALSE, TRUE, FALSE, &tag, &sym, TRUE);
|
||||
needtoken(tTERM);
|
||||
|
||||
switch (ident) {
|
||||
case iFUNCTN:
|
||||
case iREFFUNC:
|
||||
error(115, "functions");
|
||||
return;
|
||||
|
||||
case iARRAY:
|
||||
case iREFARRAY:
|
||||
case iARRAYCELL:
|
||||
case iARRAYCHAR:
|
||||
error(115, "arrays");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tag == 0) {
|
||||
error(115, "primitive types or enums");
|
||||
return;
|
||||
}
|
||||
|
||||
methodmap_t *map = methodmap_find_by_tag(tag);
|
||||
if (!map) {
|
||||
error(115, pc_tagname(tag));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!map->dtor) {
|
||||
error(115, layout_spec_name(map->spec), map->name);
|
||||
return;
|
||||
}
|
||||
|
||||
// For some reason, we don't get a sysreq.n once this passes through the
|
||||
// peephole optimizer. I can't tell why. -dvander
|
||||
//
|
||||
// push pri
|
||||
// push.c 1
|
||||
// sysreq.c N 1
|
||||
// stack 8
|
||||
pushreg(sPRI);
|
||||
markexpr(sPARM,NULL,0);
|
||||
{
|
||||
pushval(1);
|
||||
ffcall(map->dtor->target, NULL, 1);
|
||||
map->dtor->target->usage |= uREAD;
|
||||
}
|
||||
markexpr(sEXPR,NULL,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* dofuncenum - declare function enumerations
|
||||
@ -3449,13 +3906,17 @@ static void decl_enum(int vclass)
|
||||
cell increment,multiplier;
|
||||
constvalue *enumroot;
|
||||
symbol *enumsym;
|
||||
LayoutSpec spec;
|
||||
|
||||
/* get an explicit tag, if any (we need to remember whether an explicit
|
||||
* tag was passed, even if that explicit tag was "_:", so we cannot call
|
||||
* pc_addtag() here
|
||||
*/
|
||||
if (lex(&val,&str)==tLABEL) {
|
||||
tag=pc_addtag(str);
|
||||
tag = pc_addtag(str);
|
||||
spec = deduce_layout_spec_by_tag(tag);
|
||||
if (!can_redef_layout_spec(spec, Layout_Enum))
|
||||
error(110, str, layout_spec_name(spec));
|
||||
explicittag=TRUE;
|
||||
} else {
|
||||
lexpush();
|
||||
@ -3466,8 +3927,16 @@ static void decl_enum(int vclass)
|
||||
/* get optional enum name (also serves as a tag if no explicit tag was set) */
|
||||
if (lex(&val,&str)==tSYMBOL) { /* read in (new) token */
|
||||
strcpy(enumname,str); /* save enum name (last constant) */
|
||||
if (!explicittag)
|
||||
if (!explicittag) {
|
||||
tag=pc_addtag(enumname);
|
||||
spec = deduce_layout_spec_by_tag(tag);
|
||||
if (!can_redef_layout_spec(spec, Layout_Enum))
|
||||
error(110, enumname, layout_spec_name(spec));
|
||||
} else {
|
||||
spec = deduce_layout_spec_by_name(enumname);
|
||||
if (!can_redef_layout_spec(spec, Layout_Enum))
|
||||
error(110, enumname, layout_spec_name(spec));
|
||||
}
|
||||
} else {
|
||||
lexpush(); /* analyze again */
|
||||
enumname[0]='\0';
|
||||
@ -3997,7 +4466,7 @@ SC_FUNC char *funcdisplayname(char *dest,char *funcname)
|
||||
return dest;
|
||||
}
|
||||
|
||||
static void funcstub(int fnative)
|
||||
static symbol *funcstub(int fnative)
|
||||
{
|
||||
int tok,tag,fpublic;
|
||||
char *str;
|
||||
@ -4022,7 +4491,7 @@ static void funcstub(int fnative)
|
||||
*/
|
||||
if (numdim == sDIMEN_MAX) {
|
||||
error(53); /* exceeding maximum number of dimensions */
|
||||
return;
|
||||
return NULL;
|
||||
} /* if */
|
||||
size=needsub(&idxtag[numdim],NULL); /* get size; size==0 for "var[]" */
|
||||
if (size==0)
|
||||
@ -4050,12 +4519,12 @@ static void funcstub(int fnative)
|
||||
if (tok==tOPERATOR) {
|
||||
opertok=operatorname(symbolname);
|
||||
if (opertok==0)
|
||||
return; /* error message already given */
|
||||
return NULL; /* error message already given */
|
||||
check_operatortag(opertok,tag,symbolname);
|
||||
} else {
|
||||
if (tok!=tSYMBOL && freading) {
|
||||
error(10); /* illegal function or declaration */
|
||||
return;
|
||||
return NULL;
|
||||
} /* if */
|
||||
strcpy(symbolname,str);
|
||||
} /* if */
|
||||
@ -4063,7 +4532,7 @@ static void funcstub(int fnative)
|
||||
|
||||
sym=fetchfunc(symbolname,tag);/* get a pointer to the function entry */
|
||||
if (sym==NULL)
|
||||
return;
|
||||
return NULL;
|
||||
if (fnative) {
|
||||
sym->usage=(char)(uNATIVE | uRETVALUE | uDEFINE | (sym->usage & uPROTOTYPED));
|
||||
sym->x.lib=curlibrary;
|
||||
@ -4122,6 +4591,8 @@ static void funcstub(int fnative)
|
||||
|
||||
litidx=0; /* clear the literal pool */
|
||||
delete_symbols(&loctab,0,TRUE,TRUE);/* clear local variables queue */
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
/* newfunc - begin a function
|
||||
@ -5364,6 +5835,9 @@ static int testsymbols(symbol *root,int level,int testlabs,int testconst)
|
||||
error(203,sym->name); /* symbol isn't used: ... */
|
||||
} /* if */
|
||||
break;
|
||||
case iPROXY:
|
||||
// Ignore usage on proxies.
|
||||
break;
|
||||
default:
|
||||
/* a variable */
|
||||
if (sym->parent!=NULL)
|
||||
@ -5651,6 +6125,10 @@ static void statement(int *lastindent,int allow_decl)
|
||||
error(3); /* declaration only valid in a block */
|
||||
} /* if */
|
||||
break;
|
||||
case tDELETE:
|
||||
dodelete();
|
||||
lastst=tDELETE;
|
||||
break;
|
||||
case tDECL:
|
||||
if (allow_decl) {
|
||||
autozero=0;
|
||||
@ -5675,7 +6153,7 @@ static void statement(int *lastindent,int allow_decl)
|
||||
compound(save==fline,tok);
|
||||
} else {
|
||||
lastst = tEMPTYBLOCK;
|
||||
}
|
||||
}
|
||||
/* lastst (for "last statement") does not change
|
||||
you're not my father, don't tell me what to do */
|
||||
break;
|
||||
|
@ -242,8 +242,6 @@ static void check_empty(const unsigned char *lptr)
|
||||
static void doinclude(int silent)
|
||||
{
|
||||
char name[_MAX_PATH];
|
||||
char symname[sNAMEMAX+1];
|
||||
char *ptr;
|
||||
char c;
|
||||
int i, result;
|
||||
|
||||
@ -1927,9 +1925,10 @@ char *sc_tokens[] = {
|
||||
"||", "&&", "==", "!=", "<=", ">=", "<<", ">>>", ">>", "++", "--",
|
||||
"...", "..", "::",
|
||||
"assert", "*begin", "break", "case", "cellsof", "chars", "const", "continue", "default",
|
||||
"defined", "do", "else", "*end", "enum", "exit", "for", "forward", "funcenum", "functag", "goto",
|
||||
"if", "native", "new", "decl", "operator", "public", "return", "sizeof",
|
||||
"sleep", "static", "stock", "struct", "switch", "tagof", "*then", "while",
|
||||
"defined", "delete", "do", "else", "*end", "enum", "exit", "for", "forward", "funcenum",
|
||||
"functag", "goto",
|
||||
"if", "int", "methodmap", "native", "new", "decl", "operator", "public", "return", "sizeof",
|
||||
"sleep", "static", "stock", "struct", "switch", "tagof", "*then", "void", "while",
|
||||
"#assert", "#define", "#else", "#elseif", "#emit", "#endif", "#endinput",
|
||||
"#endscript", "#error", "#file", "#if", "#include", "#line", "#pragma",
|
||||
"#tryinclude", "#undef",
|
||||
@ -2611,6 +2610,29 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
|
||||
constvalue *stateptr;
|
||||
int mustdelete;
|
||||
|
||||
// Hack - proxies have a "target" pointer, but the target could be deleted
|
||||
// already if done inside the main loop below. To get around this we do a
|
||||
// precursor pass. Note that proxies can only be at the global scope.
|
||||
if (origRoot == &glbtab) {
|
||||
symbol *iter = root;
|
||||
while (iter->next) {
|
||||
sym = iter->next;
|
||||
|
||||
if (sym->ident != iPROXY) {
|
||||
iter = sym;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (delete_functions || (sym->target->usage & uNATIVE) != 0) {
|
||||
RemoveFromHashTable(sp_Globals, sym);
|
||||
iter->next = sym->next;
|
||||
free_symbol(sym);
|
||||
} else {
|
||||
iter = sym;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* erase only the symbols with a deeper nesting level than the
|
||||
* specified nesting level */
|
||||
while (root->next!=NULL) {
|
||||
@ -2653,6 +2675,10 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
|
||||
mustdelete=delete_functions || (sym->usage & uNATIVE)!=0;
|
||||
assert(sym->parent==NULL);
|
||||
break;
|
||||
case iPROXY:
|
||||
// Original loop determined it was okay to keep.
|
||||
mustdelete=FALSE;
|
||||
break;
|
||||
case iARRAYCELL:
|
||||
case iARRAYCHAR:
|
||||
case iEXPRESSION:
|
||||
@ -2831,6 +2857,10 @@ SC_FUNC symbol *findglb(const char *name,int filter)
|
||||
*/
|
||||
if (sym==NULL)
|
||||
sym=FindInHashTable(sp_Globals,name,fcurrent);
|
||||
|
||||
if (sym && sym->ident == iPROXY)
|
||||
return sym->target;
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
@ -3012,3 +3042,18 @@ static char itohstr[30];
|
||||
return itohstr;
|
||||
}
|
||||
|
||||
SC_FUNC int lextok(token_t *tok)
|
||||
{
|
||||
tok->id = lex(&tok->val, &tok->str);
|
||||
return tok->id;
|
||||
}
|
||||
|
||||
SC_FUNC int expecttoken(int id, token_t *tok)
|
||||
{
|
||||
int rval = needtoken(id);
|
||||
if (rval) {
|
||||
tok->id = tokeninfo(&tok->val, &tok->str);
|
||||
return rval;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* vim: set ts=8 sts=2 sw=2 tw=99 et: */
|
||||
/* Pawn compiler - Recursive descend expresion parser
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 1997-2005
|
||||
@ -56,7 +57,7 @@ static int hier2(value *lval);
|
||||
static int hier1(value *lval1);
|
||||
static int primary(value *lval);
|
||||
static void clear_value(value *lval);
|
||||
static void callfunction(symbol *sym,value *lval_result,int matchparanthesis);
|
||||
static void callfunction(symbol *sym, const svalue *implicitthis, value *lval_result, int matchparanthesis);
|
||||
static int dbltest(void (*oper)(),value *lval1,value *lval2);
|
||||
static int commutative(void (*oper)());
|
||||
static int constant(value *lval);
|
||||
@ -291,7 +292,7 @@ SC_FUNC int checktags_string(int tags[], int numtags, value *sym1)
|
||||
}
|
||||
for (i=0; i<numtags; i++) {
|
||||
if ((sym1->tag == pc_tag_string && tags[i] == 0) ||
|
||||
(sym1->tag == 0 && tags[i] == pc_tag_string))
|
||||
(sym1->tag == 0 && tags[i] == pc_tag_string))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@ -299,13 +300,13 @@ SC_FUNC int checktags_string(int tags[], int numtags, value *sym1)
|
||||
|
||||
SC_FUNC int checktag_string(value *sym1, value *sym2)
|
||||
{
|
||||
if (sym1->ident == iARRAY || sym2->ident == iARRAY
|
||||
|| sym1->ident == iREFARRAY || sym2->ident == iREFARRAY)
|
||||
if (sym1->ident == iARRAY || sym2->ident == iARRAY ||
|
||||
sym1->ident == iREFARRAY || sym2->ident == iREFARRAY)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if ((sym1->tag == pc_tag_string && sym2->tag == 0)
|
||||
|| (sym1->tag == 0 && sym2->tag == pc_tag_string))
|
||||
if ((sym1->tag == pc_tag_string && sym2->tag == 0) ||
|
||||
(sym1->tag == 0 && sym2->tag == pc_tag_string))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@ -320,191 +321,190 @@ SC_FUNC int matchtag_string(int ident, int tag)
|
||||
return (tag == pc_tag_string) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce)
|
||||
SC_FUNC int matchtag(int formaltag, int actualtag, int allowcoerce)
|
||||
{
|
||||
if (formaltag != actualtag) {
|
||||
/* if the formal tag is zero and the actual tag is not "fixed", the actual
|
||||
* tag is "coerced" to zero
|
||||
*/
|
||||
if (!allowcoerce || formaltag!=0 || (actualtag & FIXEDTAG)!=0) {
|
||||
if (formaltag == pc_anytag || actualtag == pc_anytag)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (formaltag == actualtag)
|
||||
return TRUE;
|
||||
|
||||
if (formaltag & FUNCTAG)
|
||||
{
|
||||
if (actualtag == pc_functag || (formaltag == pc_functag && actualtag & FUNCTAG))
|
||||
{
|
||||
return TRUE;
|
||||
} else if (actualtag & FUNCTAG) {
|
||||
constvalue *v = find_tag_byval(actualtag);
|
||||
int index;
|
||||
short usage = uPUBLIC;
|
||||
symbol *sym, *found = NULL;
|
||||
funcenum_t *e;
|
||||
functag_t *t;
|
||||
/* if the formal tag is zero and the actual tag is not "fixed", the actual
|
||||
* tag is "coerced" to zero
|
||||
*/
|
||||
if (allowcoerce && !formaltag && !(actualtag & FIXEDTAG))
|
||||
return TRUE;
|
||||
|
||||
if (strncmp(v->name, "$Func", 5) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (formaltag == pc_anytag || actualtag == pc_anytag)
|
||||
return TRUE;
|
||||
|
||||
/* Now we have to go about looking up each function in this enum. WHICH IS IT. */
|
||||
e = funcenums_find_byval(formaltag);
|
||||
if (!e)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (formaltag & FUNCTAG) {
|
||||
if (actualtag == pc_functag || (formaltag == pc_functag && actualtag & FUNCTAG))
|
||||
return TRUE;
|
||||
|
||||
assert(v->name[5] == '@' || v->name[5] == '!');
|
||||
if (actualtag & FUNCTAG) {
|
||||
constvalue *v = find_tag_byval(actualtag);
|
||||
int index;
|
||||
short usage = uPUBLIC;
|
||||
symbol *sym, *found = NULL;
|
||||
funcenum_t *e;
|
||||
functag_t *t;
|
||||
|
||||
/* Deduce which function type this is */
|
||||
if (v->name[5] == '@')
|
||||
{
|
||||
usage = uPUBLIC;
|
||||
} else if (v->name[5] == '!') {
|
||||
usage = uSTOCK;
|
||||
}
|
||||
if (strncmp(v->name, "$Func", 5) != 0)
|
||||
return FALSE;
|
||||
|
||||
index = atoi(&v->name[6]);
|
||||
/* Now we have to go about looking up each function in this enum. WHICH IS IT. */
|
||||
e = funcenums_find_byval(formaltag);
|
||||
if (!e)
|
||||
return FALSE;
|
||||
|
||||
assert(index >= 0);
|
||||
assert(v->name[5] == '@' || v->name[5] == '!');
|
||||
|
||||
/* Find the function, either by public idx or code addr */
|
||||
if (usage == uPUBLIC)
|
||||
{
|
||||
for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
|
||||
if (sym->ident==iFUNCTN && (sym->usage & uPUBLIC)!=0 && (sym->vclass == sGLOBAL))
|
||||
{
|
||||
if (index-- == 0)
|
||||
{
|
||||
found = sym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (usage == uSTOCK) {
|
||||
for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
|
||||
if (sym->ident==iFUNCTN && (sym->vclass == sGLOBAL))
|
||||
{
|
||||
if (sym->codeaddr == index)
|
||||
{
|
||||
found = sym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Deduce which function type this is */
|
||||
if (v->name[5] == '@')
|
||||
{
|
||||
usage = uPUBLIC;
|
||||
} else if (v->name[5] == '!') {
|
||||
usage = uSTOCK;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
assert(found);
|
||||
return FALSE;
|
||||
}
|
||||
index = atoi(&v->name[6]);
|
||||
|
||||
/* Wow, we now have:
|
||||
* 1) The functional enum deduced from formaltag
|
||||
* 2) The function trying to be shoved in deduced from actualtag
|
||||
* Now we have to check if it matches any one of the functags inside the enum.
|
||||
*/
|
||||
t = e->first;
|
||||
while (t)
|
||||
{
|
||||
int curarg,skip=0,i;
|
||||
arginfo *func_arg;
|
||||
funcarg_t *enum_arg;
|
||||
/* Check return type first. */
|
||||
if (t->ret_tag != sym->tag)
|
||||
{
|
||||
t = t->next;
|
||||
continue;
|
||||
}
|
||||
/* Check usage */
|
||||
if (t->type != usage)
|
||||
{
|
||||
t = t->next;
|
||||
continue;
|
||||
}
|
||||
/* Begin iterating arguments */
|
||||
for (curarg=0; curarg<t->argcount; curarg++)
|
||||
{
|
||||
enum_arg = &t->args[curarg];
|
||||
/* Check whether we've exhausted our arguments */
|
||||
if (sym->dim.arglist[curarg].ident == 0)
|
||||
{
|
||||
/* Can we bail out early? */
|
||||
if (!enum_arg->ommittable)
|
||||
{
|
||||
/* No! */
|
||||
skip = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
func_arg = &sym->dim.arglist[curarg];
|
||||
/* First check the ident type */
|
||||
if (enum_arg->ident != func_arg->ident)
|
||||
{
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
/* Next check arrayness */
|
||||
if (enum_arg->dimcount != func_arg->numdim)
|
||||
{
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
if (enum_arg->dimcount > 0)
|
||||
{
|
||||
for (i=0; i<enum_arg->dimcount; i++)
|
||||
{
|
||||
if (enum_arg->dims[i] != func_arg->dim[i])
|
||||
{
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Lastly, check the tags */
|
||||
if (enum_arg->tagcount != func_arg->numtags)
|
||||
{
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
/* They should all be in the same order just for clarity... */
|
||||
for (i=0; i<enum_arg->tagcount; i++)
|
||||
{
|
||||
if (enum_arg->tags[i] != func_arg->tags[i])
|
||||
{
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!skip)
|
||||
{
|
||||
/* Make sure there are no trailing arguments */
|
||||
if (sym->dim.arglist[curarg].ident == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
t = t->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
} /* if */
|
||||
return TRUE;
|
||||
assert(index >= 0);
|
||||
|
||||
/* Find the function, either by public idx or code addr */
|
||||
if (usage == uPUBLIC)
|
||||
{
|
||||
for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
|
||||
if (sym->ident==iFUNCTN && (sym->usage & uPUBLIC)!=0 && (sym->vclass == sGLOBAL))
|
||||
{
|
||||
if (index-- == 0)
|
||||
{
|
||||
found = sym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (usage == uSTOCK) {
|
||||
for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
|
||||
if (sym->ident==iFUNCTN && (sym->vclass == sGLOBAL))
|
||||
{
|
||||
if (sym->codeaddr == index)
|
||||
{
|
||||
found = sym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
assert(found);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Wow, we now have:
|
||||
* 1) The functional enum deduced from formaltag
|
||||
* 2) The function trying to be shoved in deduced from actualtag
|
||||
* Now we have to check if it matches any one of the functags inside the enum.
|
||||
*/
|
||||
t = e->first;
|
||||
while (t)
|
||||
{
|
||||
int curarg,skip=0,i;
|
||||
arginfo *func_arg;
|
||||
funcarg_t *enum_arg;
|
||||
/* Check return type first. */
|
||||
if (t->ret_tag != sym->tag)
|
||||
{
|
||||
t = t->next;
|
||||
continue;
|
||||
}
|
||||
/* Check usage */
|
||||
if (t->type != usage)
|
||||
{
|
||||
t = t->next;
|
||||
continue;
|
||||
}
|
||||
/* Begin iterating arguments */
|
||||
for (curarg=0; curarg<t->argcount; curarg++)
|
||||
{
|
||||
enum_arg = &t->args[curarg];
|
||||
/* Check whether we've exhausted our arguments */
|
||||
if (sym->dim.arglist[curarg].ident == 0)
|
||||
{
|
||||
/* Can we bail out early? */
|
||||
if (!enum_arg->ommittable)
|
||||
{
|
||||
/* No! */
|
||||
skip = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
func_arg = &sym->dim.arglist[curarg];
|
||||
/* First check the ident type */
|
||||
if (enum_arg->ident != func_arg->ident)
|
||||
{
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
/* Next check arrayness */
|
||||
if (enum_arg->dimcount != func_arg->numdim)
|
||||
{
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
if (enum_arg->dimcount > 0)
|
||||
{
|
||||
for (i=0; i<enum_arg->dimcount; i++)
|
||||
{
|
||||
if (enum_arg->dims[i] != func_arg->dim[i])
|
||||
{
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip)
|
||||
break;
|
||||
}
|
||||
/* Lastly, check the tags */
|
||||
if (enum_arg->tagcount != func_arg->numtags)
|
||||
{
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
/* They should all be in the same order just for clarity... */
|
||||
for (i=0; i<enum_arg->tagcount; i++)
|
||||
{
|
||||
if (enum_arg->tags[i] != func_arg->tags[i])
|
||||
{
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip)
|
||||
break;
|
||||
}
|
||||
if (!skip)
|
||||
{
|
||||
/* Make sure there are no trailing arguments */
|
||||
if (sym->dim.arglist[curarg].ident == 0)
|
||||
return TRUE;
|
||||
}
|
||||
t = t->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if the tag has a methodmap associated with it. If so, see if the given
|
||||
// tag is anywhere on the inheritance chain.
|
||||
methodmap_t *map = methodmap_find_by_tag(actualtag);
|
||||
if (map) {
|
||||
for (; map; map = map->parent) {
|
||||
if (map->tag == formaltag)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1583,7 +1583,7 @@ static int hier2(value *lval)
|
||||
if (subsym!=NULL)
|
||||
subsym=finddepend(subsym);
|
||||
} /* for */
|
||||
if (level>sym->dim.array.level+1) {
|
||||
if (level>sym->dim.array.level+1) {
|
||||
error(28,sym->name); /* invalid subscript */
|
||||
} else if (level==sym->dim.array.level+1) {
|
||||
lval->constval=(idxsym!=NULL && idxsym->dim.array.length>0) ? idxsym->dim.array.length : 1;
|
||||
@ -1637,7 +1637,7 @@ static int hier2(value *lval)
|
||||
if (subsym!=NULL)
|
||||
subsym=finddepend(subsym);
|
||||
} /* for */
|
||||
if (level>sym->dim.array.level+1) {
|
||||
if (level>sym->dim.array.level+1) {
|
||||
error(28,sym->name); /* invalid subscript */
|
||||
} else if (level==sym->dim.array.level+1) {
|
||||
lval->constval= (idxsym!=NULL && idxsym->dim.array.length>0) ? idxsym->dim.array.length : 1;
|
||||
@ -1812,7 +1812,7 @@ static int hier1(value *lval1)
|
||||
cursym=lval1->sym;
|
||||
restart:
|
||||
sym=cursym;
|
||||
if (matchtoken('[') || matchtoken('{') || matchtoken('(')) {
|
||||
if (matchtoken('[') || matchtoken('{') || matchtoken('(') || matchtoken('.')) {
|
||||
tok=tokeninfo(&val,&st); /* get token read by matchtoken() */
|
||||
magic_string = (sym && (sym->tag == pc_tag_string && sym->dim.array.level == 0));
|
||||
if (sym==NULL && symtok!=tSYMBOL) {
|
||||
@ -1974,14 +1974,66 @@ restart:
|
||||
lval1->tag=sym->tag;
|
||||
lval1->constval=0;
|
||||
} /* if */
|
||||
|
||||
// If there's a call coming up, keep parsing.
|
||||
if (matchtoken('.')) {
|
||||
lexpush();
|
||||
goto restart;
|
||||
}
|
||||
|
||||
/* a cell in an array is an lvalue, a character in an array is not
|
||||
* always a *valid* lvalue */
|
||||
return TRUE;
|
||||
} else { /* tok=='(' -> function(...) */
|
||||
svalue thisval;
|
||||
thisval.val = *lval1;
|
||||
thisval.lvalue = lvalue;
|
||||
|
||||
svalue *implicitthis = NULL;
|
||||
if (tok == '.') {
|
||||
methodmap_t *map;
|
||||
|
||||
/* Catch invalid calls early so we don't compile with a tag mismatch. */
|
||||
switch (thisval.val.ident) {
|
||||
case iARRAY:
|
||||
case iREFARRAY:
|
||||
error(106);
|
||||
break;
|
||||
|
||||
case iFUNCTN:
|
||||
case iREFFUNC:
|
||||
error(107);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((map = methodmap_find_by_tag(thisval.val.tag)) == NULL) {
|
||||
error(104, pc_tagname(thisval.val.tag));
|
||||
}
|
||||
|
||||
if (needtoken(tSYMBOL) && map) {
|
||||
cell lexval;
|
||||
char *lexstr;
|
||||
methodmap_method_t *method;
|
||||
|
||||
tokeninfo(&lexval, &lexstr);
|
||||
if ((method = methodmap_find_method(map, lexstr)) == NULL)
|
||||
error(105, map->name, lexstr);
|
||||
if (method) {
|
||||
implicitthis = &thisval;
|
||||
sym = method->target;
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't find a '(' next, just fail to compile for now -- and
|
||||
// don't even try to do a function call, just restart the parse loop.
|
||||
if (!needtoken('('))
|
||||
goto restart;
|
||||
|
||||
tok = '(';
|
||||
}
|
||||
|
||||
assert(tok=='(');
|
||||
if (sym==NULL
|
||||
|| (sym->ident!=iFUNCTN && sym->ident!=iREFFUNC))
|
||||
{
|
||||
if (sym==NULL || (sym->ident!=iFUNCTN && sym->ident!=iREFFUNC)) {
|
||||
if (sym==NULL && sc_status==statFIRST) {
|
||||
/* could be a "use before declaration"; in that case, create a stub
|
||||
* function so that the usage can be marked.
|
||||
@ -1998,14 +2050,14 @@ restart:
|
||||
funcdisplayname(symname,sym->name);
|
||||
error(4,symname); /* function not defined */
|
||||
} /* if */
|
||||
callfunction(sym,lval1,TRUE);
|
||||
callfunction(sym,implicitthis,lval1,TRUE);
|
||||
return FALSE; /* result of function call is no lvalue */
|
||||
} /* if */
|
||||
} /* if */
|
||||
if (sym!=NULL && lval1->ident==iFUNCTN) {
|
||||
assert(sym->ident==iFUNCTN);
|
||||
if (sc_allowproccall) {
|
||||
callfunction(sym,lval1,FALSE);
|
||||
callfunction(sym,NULL,lval1,FALSE);
|
||||
} else if ((sym->usage & uNATIVE) != uNATIVE) {
|
||||
symbol *oldsym=sym;
|
||||
int n=-1,iter=0;
|
||||
@ -2036,14 +2088,14 @@ restart:
|
||||
}
|
||||
lval1->tag=pc_addfunctag(faketag);
|
||||
oldsym->usage |= uREAD;
|
||||
sym->usage |= uREAD;
|
||||
sym->usage |= uREAD;
|
||||
} else {
|
||||
error(76); /* invalid function call, or syntax error */
|
||||
} /* if */
|
||||
return FALSE;
|
||||
} else {
|
||||
error(76); /* invalid function call, or syntax error */
|
||||
}
|
||||
} else {
|
||||
error(76); /* invalid function call, or syntax error */
|
||||
}
|
||||
} /* if */
|
||||
return lvalue;
|
||||
}
|
||||
@ -2243,7 +2295,7 @@ enum {
|
||||
* Generates code to call a function. This routine handles default arguments
|
||||
* and positional as well as named parameters.
|
||||
*/
|
||||
static void callfunction(symbol *sym,value *lval_result,int matchparanthesis)
|
||||
static void callfunction(symbol *sym, const svalue *implicitthis, value *lval_result, int matchparanthesis)
|
||||
{
|
||||
static long nest_stkusage=0L;
|
||||
static int nesting=0;
|
||||
@ -2261,6 +2313,7 @@ static int nesting=0;
|
||||
symbol *symret;
|
||||
cell lexval;
|
||||
char *lexstr;
|
||||
int pending_this = (implicitthis ? TRUE : FALSE);
|
||||
|
||||
assert(sym!=NULL);
|
||||
lval_result->ident=iEXPRESSION; /* preset, may be changed later */
|
||||
@ -2321,9 +2374,9 @@ static int nesting=0;
|
||||
lexpush(); /* reset the '.' */
|
||||
} /* if */
|
||||
} /* if */
|
||||
if (!close) {
|
||||
if (pending_this || !close) {
|
||||
do {
|
||||
if (matchtoken('.')) {
|
||||
if (!pending_this && matchtoken('.')) {
|
||||
namedparams=TRUE;
|
||||
if (needtoken(tSYMBOL))
|
||||
tokeninfo(&lexval,&lexstr);
|
||||
@ -2350,7 +2403,7 @@ static int nesting=0;
|
||||
stgmark((char)(sEXPRSTART+argpos));/* mark beginning of new expression in stage */
|
||||
if (arglist[argpos]!=ARG_UNHANDLED)
|
||||
error(58); /* argument already set */
|
||||
if (matchtoken('_')) {
|
||||
if (!pending_this && matchtoken('_')) {
|
||||
arglist[argpos]=ARG_IGNORED; /* flag argument as "present, but ignored" */
|
||||
if (arg[argidx].ident==0 || arg[argidx].ident==iVARARGS) {
|
||||
error(92); /* argument count mismatch */
|
||||
@ -2368,7 +2421,12 @@ static int nesting=0;
|
||||
arglist[argpos]=ARG_DONE; /* flag argument as "present" */
|
||||
if (arg[argidx].ident!=0 && arg[argidx].numtags==1) /* set the expected tag, if any */
|
||||
lval.cmptag=arg[argidx].tags[0];
|
||||
lvalue=hier14(&lval);
|
||||
if (pending_this) {
|
||||
lval = implicitthis->val;
|
||||
lvalue = implicitthis->lvalue;
|
||||
} else {
|
||||
lvalue = hier14(&lval);
|
||||
}
|
||||
assert(sc_status==statFIRST || arg[argidx].ident == 0 || arg[argidx].tags!=NULL);
|
||||
switch (arg[argidx].ident) {
|
||||
case 0:
|
||||
@ -2428,14 +2486,14 @@ static int nesting=0;
|
||||
/* otherwise, the expression result is already in PRI */
|
||||
assert(arg[argidx].numtags>0);
|
||||
check_userop(NULL,lval.tag,arg[argidx].tags[0],2,NULL,&lval.tag);
|
||||
if (!checktags_string(arg[argidx].tags, arg[argidx].numtags, &lval)
|
||||
&& !checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag))
|
||||
{
|
||||
if (arg[argidx].numtags == 1 && arg[argidx].tags[0] & FUNCTAG)
|
||||
if (!checktags_string(arg[argidx].tags, arg[argidx].numtags, &lval) &&
|
||||
!checktag(arg[argidx].tags, arg[argidx].numtags, lval.tag))
|
||||
{
|
||||
if (arg[argidx].numtags == 1 && arg[argidx].tags[0] & FUNCTAG)
|
||||
error(100); /* error - function prototypes do not match */
|
||||
else
|
||||
else
|
||||
error(213); /* warning - tag mismatch */
|
||||
}
|
||||
}
|
||||
if (lval.tag!=0)
|
||||
append_constval(&taglst,arg[argidx].name,lval.tag,0);
|
||||
argidx++; /* argument done */
|
||||
@ -2547,18 +2605,32 @@ static int nesting=0;
|
||||
} /* if */
|
||||
assert(arglist[argpos]!=ARG_UNHANDLED);
|
||||
nargs++;
|
||||
|
||||
/**
|
||||
* We can already have decided it was time to close because of pending_this.
|
||||
* If that's the case, then bail out now.
|
||||
*/
|
||||
if (pending_this && close) {
|
||||
pending_this = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (matchparanthesis) {
|
||||
close=matchtoken(')');
|
||||
if (!close) /* if not paranthese... */
|
||||
if (!needtoken(',')) /* ...should be comma... */
|
||||
/* Not expecting comma if the first argument was implicit. */
|
||||
if (!pending_this && !needtoken(','))
|
||||
break; /* ...but abort loop if neither */
|
||||
} else {
|
||||
close=!matchtoken(',');
|
||||
/* Not expecting comma if the first argument was implicit. */
|
||||
close = (!pending_this && !matchtoken(','));
|
||||
if (close) { /* if not comma... */
|
||||
if (needtoken(tTERM)==1)/* ...must be end of statement */
|
||||
lexpush(); /* push again, because end of statement is analised later */
|
||||
} /* if */
|
||||
} /* if */
|
||||
|
||||
pending_this = FALSE;
|
||||
} while (!close && freading && !matchtoken(tENDEXPR)); /* do */
|
||||
} /* if */
|
||||
/* check remaining function arguments (they may have default values) */
|
||||
@ -2797,7 +2869,7 @@ static int constant(value *lval)
|
||||
* value distinguishes between literal arrays
|
||||
* and literal strings (this was done for
|
||||
* array assignment). */
|
||||
lval->tag=pc_tag_string;
|
||||
lval->tag=pc_tag_string;
|
||||
} else if (tok=='{') {
|
||||
int tag,lasttag=-1;
|
||||
val=litidx;
|
||||
|
@ -52,8 +52,8 @@
|
||||
static unsigned char warndisable[(NUM_WARNINGS + 7) / 8]; /* 8 flags in a char */
|
||||
|
||||
static int errflag;
|
||||
static int errstart; /* line number at which the instruction started */
|
||||
static int errline; /* forced line number for the error message */
|
||||
static int errstart; /* line number at which the instruction started */
|
||||
static int sErrLine; /* forced line number for the error message */
|
||||
|
||||
/* error
|
||||
*
|
||||
@ -75,6 +75,12 @@ static short lastfile;
|
||||
char *msg,*pre;
|
||||
va_list argptr;
|
||||
|
||||
// sErrLine is used to temporarily change the line number of reported errors.
|
||||
// Pawn has an upstream bug where this is not reset on early-return, which
|
||||
// can lead to broken line numbers in error messages.
|
||||
int errline = sErrLine;
|
||||
sErrLine = -1;
|
||||
|
||||
/* errflag is reset on each semicolon.
|
||||
* In a two-pass compiler, an error should not be reported twice. Therefore
|
||||
* the error reporting is enabled only in the second pass (and only when
|
||||
@ -148,7 +154,6 @@ static short lastfile;
|
||||
longjmp(errbuf,2); /* fatal error, quit */
|
||||
} /* if */
|
||||
|
||||
errline=-1;
|
||||
/* check whether we are seeing many errors on the same line */
|
||||
if ((errstart<0 && lastline!=fline) || lastline<errstart || lastline>fline || fcurrent!=lastfile)
|
||||
errorcount=0;
|
||||
@ -176,10 +181,10 @@ SC_FUNC void errorset(int code,int line)
|
||||
break;
|
||||
case sEXPRRELEASE:
|
||||
errstart=-1; /* forget start line number */
|
||||
errline=-1;
|
||||
sErrLine=-1;
|
||||
break;
|
||||
case sSETPOS:
|
||||
errline=line;
|
||||
sErrLine=line;
|
||||
break;
|
||||
} /* switch */
|
||||
}
|
||||
|
@ -1,361 +1,407 @@
|
||||
/* Pawn compiler - Error message strings (plain and compressed formats)
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 2000-2006
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
* the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]);
|
||||
|
||||
#define SCPACK_TABLE errstr_table
|
||||
/*-*SCPACK start of pair table, do not change or remove this line */
|
||||
unsigned char errstr_table[][2] = {
|
||||
{101,32}, {111,110}, {116,32}, {105,110}, {97,114}, {115,32}, {116,105}, {100,32}, {101,114}, {37,115}, {101,110}, {134,129}, {34,137}, {140,34}, {97,108}, {117,110},
|
||||
{114,101}, {110,111}, {97,116}, {115,105}, {121,32}, {97,110}, {111,114}, {109,98}, {115,116}, {32,141}, {100,101}, {41,10}, {109,138}, {145,130}, {101,135}, {139,32},
|
||||
{98,108}, {111,108}, {114,97}, {143,99}, {118,142}, {102,163}, {115,121}, {166,151}, {167,161}, {97,32}, {117,115}, {103,32}, {115,147}, {132,162}, {97,160}, {136,32},
|
||||
{150,32}, {99,104}, {103,117}, {105,135}, {178,156}, {164,179}, {132,180}, {111,102}, {116,104}, {101,120}, {165,159}, {131,181}, {101,100}, {101,133}, {105,133}, {168,153},
|
||||
{154,102}, {118,132}, {183,32}, {105,174}, {193,195}, {116,111}, {173,148}, {109,97}, {99,129}, {101,10}, {115,10}, {112,144}, {116,97}, {182,130}, {98,128}, {152,146},
|
||||
{44,32}, {132,97}, {192,131}, {170,130}, {153,10}, {109,146}, {191,155}, {109,211}, {40,214}, {104,97}, {196,128}, {34,32}, {129,32}, {142,32}, {105,99}, {117,108},
|
||||
{99,111}, {147,122}, {110,32}, {100,105}, {101,108}, {108,111}, {111,112}, {116,136}, {200,152}, {131,32}, {149,32}, {131,171}, {213,177}, {58,212}, {109,101}, {102,105},
|
||||
{100,111}, {97,115}, {108,128}, {118,128}, {230,136}, {232,149}, {204,171}, {203,172}, {215,206}, {119,105}, {109,112}, {110,117}, {185,247}, {165,139}, {251,151}
|
||||
};
|
||||
/*-*SCPACK end of pair table, do not change or remove this line */
|
||||
|
||||
static char *errmsg[] = {
|
||||
#if 1
|
||||
/*001*/ "expected token: \"%s\", but found \"%s\"\n",
|
||||
/*002*/ "only a single statement (or expression) can follow each \"case\"\n",
|
||||
/*003*/ "declaration of a local variable must appear in a compound block\n",
|
||||
/*004*/ "function \"%s\" is not implemented\n",
|
||||
/*005*/ "function may not have arguments\n",
|
||||
/*006*/ "must be assigned to an array\n",
|
||||
/*007*/ "operator cannot be redefined\n",
|
||||
/*008*/ "must be a constant expression; assumed zero\n",
|
||||
/*009*/ "invalid array size (negative, zero or out of bounds)\n",
|
||||
/*010*/ "invalid function or declaration\n",
|
||||
/*011*/ "invalid outside functions\n",
|
||||
/*012*/ "invalid function call, not a valid address\n",
|
||||
/*013*/ "no entry point (no public functions)\n",
|
||||
/*014*/ "invalid statement; not in switch\n",
|
||||
/*015*/ "\"default\" case must be the last case in switch statement\n",
|
||||
/*016*/ "multiple defaults in \"switch\"\n",
|
||||
/*017*/ "undefined symbol \"%s\"\n",
|
||||
/*018*/ "initialization data exceeds declared size\n",
|
||||
/*019*/ "not a label: \"%s\"\n",
|
||||
/*020*/ "invalid symbol name \"%s\"\n",
|
||||
/*021*/ "symbol already defined: \"%s\"\n",
|
||||
/*022*/ "must be lvalue (non-constant)\n",
|
||||
/*023*/ "array assignment must be simple assignment\n",
|
||||
/*024*/ "\"break\" or \"continue\" is out of context\n",
|
||||
/*025*/ "function heading differs from prototype\n",
|
||||
/*026*/ "no matching \"#if...\"\n",
|
||||
/*027*/ "invalid character constant\n",
|
||||
/*028*/ "invalid subscript (not an array or too many subscripts): \"%s\"\n",
|
||||
/*029*/ "invalid expression, assumed zero\n",
|
||||
/*030*/ "compound statement not closed at the end of file (started at line %d)\n",
|
||||
/*031*/ "unknown directive\n",
|
||||
/*032*/ "array index out of bounds (variable \"%s\")\n",
|
||||
/*033*/ "array must be indexed (variable \"%s\")\n",
|
||||
/*034*/ "argument does not have a default value (argument %d)\n",
|
||||
/*035*/ "argument type mismatch (argument %d)\n",
|
||||
/*036*/ "empty statement\n",
|
||||
/*037*/ "invalid string (possibly non-terminated string)\n",
|
||||
/*038*/ "extra characters on line\n",
|
||||
/*039*/ "constant symbol has no size\n",
|
||||
/*040*/ "duplicate \"case\" label (value %d)\n",
|
||||
/*041*/ "invalid ellipsis, array size is not known\n",
|
||||
/*042*/ "invalid combination of class specifiers\n",
|
||||
/*043*/ "character constant exceeds range for packed string\n",
|
||||
/*044*/ "positional parameters must precede all named parameters\n",
|
||||
/*045*/ "too many function arguments\n",
|
||||
/*046*/ "unknown array size (variable \"%s\")\n",
|
||||
/*047*/ "array sizes do not match, or destination array is too small\n",
|
||||
/*048*/ "array (s do not match\n",
|
||||
/*049*/ "invalid line continuation\n",
|
||||
/*050*/ "invalid range\n",
|
||||
/*051*/ "invalid subscript, use \"[ ]\" operators on major dimensions\n",
|
||||
/*052*/ "multi-dimensional arrays must be fully initialized\n",
|
||||
/*053*/ "exceeding maximum number of dimensions\n",
|
||||
/*054*/ "unmatched closing brace (\"}\")\n",
|
||||
/*055*/ "start of function body without function header\n",
|
||||
/*056*/ "arrays, local variables and function arguments cannot be public (variable \"%s\")\n",
|
||||
/*057*/ "unfinished expression before compiler directive\n",
|
||||
/*058*/ "duplicate argument; same argument is passed twice\n",
|
||||
/*059*/ "function argument may not have a default value (variable \"%s\")\n",
|
||||
/*060*/ "multiple \"#else\" directives between \"#if ... #endif\"\n",
|
||||
/*061*/ "\"#elseif\" directive follows an \"#else\" directive\n",
|
||||
/*062*/ "number of operands does not fit the operator\n",
|
||||
/*063*/ "function result tag of operator \"%s\" must be \"%s\"\n",
|
||||
/*064*/ "cannot change predefined operators\n",
|
||||
/*065*/ "function argument may only have a single tag (argument %d)\n",
|
||||
/*066*/ "function argument may not be a reference argument or an array (argument \"%s\")\n",
|
||||
/*067*/ "variable cannot be both a reference and an array (variable \"%s\")\n",
|
||||
/*068*/ "invalid rational number precision in #pragma\n",
|
||||
/*069*/ "rational number format already defined\n",
|
||||
/*070*/ "rational number support was not enabled\n",
|
||||
/*071*/ "user-defined operator must be declared before use (function \"%s\")\n",
|
||||
/*072*/ "\"sizeof\" operator is invalid on \"function\" symbols\n",
|
||||
/*073*/ "function argument must be an array (argument \"%s\")\n",
|
||||
/*074*/ "#define pattern must start with an alphabetic character\n",
|
||||
/*075*/ "input line too long (after substitutions)\n",
|
||||
/*076*/ "syntax error in the expression, or invalid function call\n",
|
||||
/*077*/ "malformed UTF-8 encoding, or corrupted file: %s\n",
|
||||
/*078*/ "function uses both \"return\" and \"return <value>\"\n",
|
||||
/*079*/ "inconsistent return types (array & non-array)\n",
|
||||
/*080*/ "unknown symbol, or not a constant symbol (symbol \"%s\")\n",
|
||||
/*081*/ "cannot take a tag as a default value for an indexed array parameter (symbol \"%s\")\n",
|
||||
/*082*/ "user-defined operators and native functions may not have states\n",
|
||||
/*083*/ "a function or variable may only belong to a single automaton (symbol \"%s\")\n",
|
||||
/*084*/ "state conflict: one of the states is already assigned to another implementation (symbol \"%s\")\n",
|
||||
/*085*/ "no states are defined for symbol \"%s\"\n",
|
||||
/*086*/ "unknown automaton \"%s\"\n",
|
||||
/*087*/ "unknown state \"%s\" for automaton \"%s\"\n",
|
||||
/*088*/ "public variables and local variables may not have states (symbol \"%s\")\n",
|
||||
/*089*/ "state variables may not be initialized (symbol \"%s\")\n",
|
||||
/*090*/ "public functions may not return arrays (symbol \"%s\")\n",
|
||||
/*091*/ "ambiguous constant; tag override is required (symbol \"%s\")\n",
|
||||
/*092*/ "number of arguments does not match definition\n",
|
||||
/*093*/ "expected tag name identifier\n",
|
||||
/*094*/ "function enumeration requires unique tag\n",
|
||||
/*095*/ "cannot have required parameters after optional parameters\n",
|
||||
/*096*/ "could not find member \"%s\" in struct \"%s\"\n",
|
||||
/*097*/ "symbol \"%s\" does not have a matching type\n",
|
||||
/*098*/ "struct requires unique struct name\n",
|
||||
/*099*/ "member \"%s\" appears more than once in struct \"%s\"\n",
|
||||
/*100*/ "function prototypes do not match\n",
|
||||
/*101*/ "specify either all dimensions or only the last dimension\n"
|
||||
#else
|
||||
"\271pect\236\305k\212:\231\320bu\202fo\217\207\215\012",
|
||||
"\201l\224\251s\203g\362\317e\234\202(\260\374\201) c\352f\241\345w ea\261 \042c\361e\042\012",
|
||||
"\232cl\321\237\302\251\345c\335\332\327appe\204 \351\251\340\372o\217\207\240ock\012",
|
||||
"\375\231 \276\235i\372le\234t\274\012",
|
||||
"\272\307\224\235\331\363\266t\312",
|
||||
"\370a\254gn\236\305 \352\255y\012",
|
||||
"\364\222\260c\225\235\316\220\322\274\012",
|
||||
"\370\251\365\202\374\201; \361sum\236z\210o\012",
|
||||
"\273\306\341\200(nega\206ve\320z\210o \260ou\202\302bo\217ds\233",
|
||||
"\273\272\260\232cl\321\213\012",
|
||||
"\273out\223d\200\375\312",
|
||||
"\273\272c\216l\320\235\251\265add\220s\312",
|
||||
"\221 \212tr\224po\203\202(\221 pu\240\336 \375s\233",
|
||||
"\273\317e\234t; \235\351s\371t\261\012",
|
||||
"\042\300a\337t\333c\361\200\370\270\200l\361\202c\361\200\351s\371t\261 \317e\234t\012",
|
||||
"m\337\206p\362\300a\337t\205\351\042s\371t\261\042\012",
|
||||
"\217\322\236\277\012",
|
||||
"\203i\206\216iza\237d\222\251\271ce\274\205\232cl\204\236\341\311",
|
||||
"\235\251lab\344\355",
|
||||
"\273\250 nam\200\215\012",
|
||||
"\250 \216\220ad\224\322\274\355",
|
||||
"\370l\244u\200(n\201-\365t\233",
|
||||
"\306a\254gn\234\202\370\223\372\362a\254gn\234t\012",
|
||||
"\042b\220ak\333\260\042\310t\203ue\333\276ou\202\302\310t\271t\012",
|
||||
"\272head\353\343ff\210\205from pro\305typ\311",
|
||||
"\221 \354\353\042#if...\042\012",
|
||||
"\273\261\321ct\257\365t\012",
|
||||
"\273subscrip\202(\235\352\306\260\305o m\225\224subscripts)\355",
|
||||
"\273\374\201\320\361sum\236z\210o\012",
|
||||
"\340\372o\217\207\317e\234\202\235c\345s\236a\202\270\200\212\207\302\357\362(\230\204t\236a\202l\203\200%d\233",
|
||||
"\217k\221w\342\343\220c\206v\311",
|
||||
"\306\203\232x ou\202\302bo\217d\205(\332\215\233",
|
||||
"\306\370\203\232x\236(\332\215\233",
|
||||
"\315\360\275\235\331\363\251\300a\337\202\244u\200(\315%d\233",
|
||||
"\315typ\200mis\354 (\315%d\233",
|
||||
"e\372t\224\317e\234t\012",
|
||||
"\273\230r\353(po\254\240\224n\201-\347m\203\222\236\230r\203g\233",
|
||||
"\271t\242 \261\321c\347\205\334l\203\311",
|
||||
"\365\202\250 \331\205\221 \341\311",
|
||||
"dupl\336\222\200\042c\361e\333lab\344 (\244u\200%d\233",
|
||||
"\273\344lip\223s\320\306\341\200\276\235k\221wn\012",
|
||||
"\273\340\227\203a\237\302cl\361\205speci\357\210\312",
|
||||
"\261\321ct\257\365\202\271ce\274\205r\225g\200f\260pack\236\230r\203g\012",
|
||||
"po\223\213\335p\321\356\347\205\327\313c\274\200\216l nam\236p\321\356\347\312",
|
||||
"\305o m\225\224\272\266t\312",
|
||||
"\217k\221w\342\306\341\200(\332\215\233",
|
||||
"\306\341\275\360 \235\354\320\260\232\230\203a\237\306\276\305o sm\216l\012",
|
||||
"\306(\205\360 \235\354\012",
|
||||
"\273l\203\200\310t\203ua\213\012",
|
||||
"\273r\225g\311",
|
||||
"\273subscript\320\252\200\042[ ]\333\364\222\226\205\334\307j\260\343\234\223\201\312",
|
||||
"m\337\206-\343\234\223\201\335\255y\205\370f\337l\224\203i\206\216iz\274\012",
|
||||
"\271ce\274\353\307ximum \376\257\302\343\234\223\201\312",
|
||||
"\217\354\236c\345s\353b\242c\200(\042}\042\233",
|
||||
"\230\204\202\302\272bod\224\371\270ou\202\272head\210\012",
|
||||
"\255ys\320\345c\335\304\275\225\207\272\266t\205c\225\235\316pu\240\336 (\332\215\233",
|
||||
"\217f\203ish\236\374\334bef\226\200\340\372il\257\343\220c\206v\311",
|
||||
"dupl\336\222\200\266t; sam\200\315\276p\361s\236tw\336\311",
|
||||
"\272\315\307\224\235\331\363\251\300a\337\202\244u\200(\332\215\233",
|
||||
"m\337\206p\362\042#\344se\333\343\220c\206v\275betwe\212 \042#if ... #\212\343f\042\012",
|
||||
"\042#\344seif\333\343\220c\206\363f\241\345w\205\352\042#\344se\333\343\220c\206v\311",
|
||||
"\376\257\302\364\225d\205\360\275\235\357\202\270\200\364\222\226\012",
|
||||
"\272\220s\337\202\366\302\364\222\226\231 \370\215\012",
|
||||
"c\225\235\261\225g\200\313\322\236\364\222\226\312",
|
||||
"\272\315\307\224\201l\224\331\363\251s\203g\362\366(\315%d\233",
|
||||
"\272\315\307\224\235\316\251\220f\210\212c\200\315\260\352\306(\315\215\233",
|
||||
"\332c\225\235\316bo\270 \251\220f\210\212c\200\225\207\352\306(\332\215\233",
|
||||
"\273\242\213\335\376\257\313ci\223\334\351#p\242g\307\012",
|
||||
"\242\213\335\376\257f\226\307\202\216\220ad\224\322\274\012",
|
||||
"\242\213\335\376\257supp\226\202wa\205\235\212\256\274\012",
|
||||
"\252\210-\322\236\364\222\260\370\232cl\204\236bef\226\200\252\200(\375\231\233",
|
||||
"\042\341e\267\333\364\222\260\276\273\334\042\375\333\250\312",
|
||||
"\272\315\370\352\306(\315\215\233",
|
||||
"#\322\200p\222\347\342\327\230\204\202\371\270 \352\216p\331be\206c \261\321c\347\012",
|
||||
"\203pu\202l\203\200\305o l\201\253(aft\257subs\206tu\213s\233",
|
||||
"\246n\314x \210r\260\351\270\200\374\201\320\260\273\272c\216l\012",
|
||||
"m\216f\226m\236UTF-8 \212\340d\203g\320\260c\226rupt\236\357le: \211\012",
|
||||
"\272\252\275bo\270 \042\220turn\333\225\207\042\220tur\342<\244ue>\042\012",
|
||||
"\203\310\223\230\212\202\220tur\342typ\275(\306& n\201-\255y\233",
|
||||
"\217k\221w\342\250\320\260\235\251\365\202\250 \330",
|
||||
"c\225\235\314k\200\251\366a\205\251\300a\337\202\244u\200f\260\352\203\232x\236\306p\321\356t\257\330",
|
||||
"\252\210-\322\236\364\222\226\205\225\207na\206\363\375\205\307\224\235\331\363\317e\312",
|
||||
"\251\272\260\332\307\224\201l\224b\344\201\253\305 \251s\203g\362au\305\325\334\330",
|
||||
"\317\200\310fl\336t: \201\200\302\270\200\317\275\276\216\220ad\224a\254gn\236\305 a\221\270\257i\372le\234\314\237\330",
|
||||
"\221 \317\275\204\200\322\236f\260\277\012",
|
||||
"\217k\221w\342au\305\325\201\324",
|
||||
"\217k\221w\342\317\200\215 f\260au\305\325\201\324",
|
||||
"pu\240\336 \304\275\225\207\345c\335\304\275\307\224\235\331\363\317\275\330",
|
||||
"\317\200\304\275\307\224\235\316\203i\206\216iz\236\330",
|
||||
"pu\240\336 \375\205\307\224\235\220tur\342\255y\205\330",
|
||||
"a\227i\262ou\205\365t; \366ov\210rid\200\276\220qui\220\207\330",
|
||||
"\376\257\302\266t\205\360\275\235\354 \322i\213\012",
|
||||
"\271pect\236\366nam\200id\212\206\357\210\012",
|
||||
"\272\212um\210a\237\220qui\220\205\217iqu\200\314g\012",
|
||||
"c\225\235\331\363\220qui\220\207p\321\356\347\205aft\257\346\213\335p\321\356\347\312",
|
||||
"\340\337\207\235f\203\207\356\227\210\231 \351\230ruc\202\215\012",
|
||||
"\277 \360\275\235\331\363\251\354\353typ\311",
|
||||
"\230ruc\202\220qui\220\205\217iqu\200\230ruc\202nam\311",
|
||||
"\356\227\210\231 appe\204\205m\226\200\270\352\201c\200\351\230ruc\202\215\012",
|
||||
"\272pro\305typ\275\360 \235\354\012"
|
||||
#endif
|
||||
};
|
||||
|
||||
static char *fatalmsg[] = {
|
||||
#if 1
|
||||
/*120*/ "cannot read from file: \"%s\"\n",
|
||||
/*121*/ "cannot write to file: \"%s\"\n",
|
||||
/*122*/ "table overflow: \"%s\"\n",
|
||||
/* table can be: loop table
|
||||
* literal table
|
||||
* staging buffer
|
||||
* option table (response file)
|
||||
* peephole optimizer table
|
||||
*/
|
||||
/*123*/ "insufficient memory\n",
|
||||
/*124*/ "invalid assembler instruction \"%s\"\n",
|
||||
/*125*/ "numeric overflow, exceeding capacity\n",
|
||||
/*126*/ "compiled script exceeds the maximum memory size (%ld bytes)\n",
|
||||
/*127*/ "too many error messages on one line\n",
|
||||
/*128*/ "codepage mapping file not found\n",
|
||||
/*129*/ "invalid path: \"%s\"\n",
|
||||
/*130*/ "assertion failed: %s\n",
|
||||
/*131*/ "user error: %s\n",
|
||||
#else
|
||||
"c\225\235\220a\207from \357le\355",
|
||||
"c\225\235writ\200\305 \357le\355",
|
||||
"t\256\200ov\210f\345w\355",
|
||||
"\203suff\336i\212\202\356m\226y\012",
|
||||
"\273\361se\227l\257\203\230ruc\213\324",
|
||||
"\373m\210\336 ov\210f\345w\320\271ce\274\353capacity\012",
|
||||
"\340\372il\236scrip\202\271ce\274\205\270\200\307ximum \356m\226\224\341\200(%l\207bytes\233",
|
||||
"\305o m\225\224\210r\260\356ssag\275\334\201\200l\203\311",
|
||||
"\340\232pag\200\307pp\353\357\362\235fo\217d\012",
|
||||
"\273p\222h\355",
|
||||
"\361s\210\237fail\274: \211\012",
|
||||
"\252\257\210r\226: \211\012"
|
||||
#endif
|
||||
};
|
||||
|
||||
static char *warnmsg[] = {
|
||||
#if 1
|
||||
/*200*/ "symbol \"%s\" is truncated to %d characters\n",
|
||||
/*201*/ "redefinition of constant/macro (symbol \"%s\")\n",
|
||||
/*202*/ "number of arguments does not match definition\n",
|
||||
/*203*/ "symbol is never used: \"%s\"\n",
|
||||
/*204*/ "symbol is assigned a value that is never used: \"%s\"\n",
|
||||
/*205*/ "redundant code: constant expression is zero\n",
|
||||
/*206*/ "redundant test: constant expression is non-zero\n",
|
||||
/*207*/ "unknown #pragma\n",
|
||||
/*208*/ "function with tag result used before definition, forcing reparse\n",
|
||||
/*209*/ "function \"%s\" should return a value\n",
|
||||
/*210*/ "possible use of symbol before initialization: \"%s\"\n",
|
||||
/*211*/ "possibly unintended assignment\n",
|
||||
/*212*/ "possibly unintended bitwise operation\n",
|
||||
/*213*/ "tag mismatch\n",
|
||||
/*214*/ "possibly a \"const\" array argument was intended: \"%s\"\n",
|
||||
/*215*/ "expression has no effect\n",
|
||||
/*216*/ "nested comment\n",
|
||||
/*217*/ "loose indentation\n",
|
||||
/*218*/ "old style prototypes used with optional semicolumns\n",
|
||||
/*219*/ "local variable \"%s\" shadows a variable at a preceding level\n",
|
||||
/*220*/ "expression with tag override must appear between parentheses\n",
|
||||
/*221*/ "label name \"%s\" shadows tag name\n",
|
||||
/*222*/ "number of digits exceeds rational number precision\n",
|
||||
/*223*/ "redundant \"sizeof\": argument size is always 1 (symbol \"%s\")\n",
|
||||
/*224*/ "indeterminate array size in \"sizeof\" expression (symbol \"%s\")\n",
|
||||
/*225*/ "unreachable code\n",
|
||||
/*226*/ "a variable is assigned to itself (symbol \"%s\")\n",
|
||||
/*227*/ "more initializers than enum fields\n",
|
||||
/*228*/ "length of initializer exceeds size of the enum field\n",
|
||||
/*229*/ "index tag mismatch (symbol \"%s\")\n",
|
||||
/*230*/ "no implementation for state \"%s\" in function \"%s\", no fall-back\n",
|
||||
/*231*/ "state specification on forward declaration is ignored\n",
|
||||
/*232*/ "output file is written, but with compact encoding disabled\n",
|
||||
/*233*/ "state variable \"%s\" shadows a global variable\n",
|
||||
/*234*/ "symbol \"%s\" is marked as deprecated: %s\n",
|
||||
/*235*/ "public function lacks forward declaration (symbol \"%s\")\n",
|
||||
/*236*/ "unknown parameter in substitution (incorrect #define pattern)\n"
|
||||
#else
|
||||
"\277 \276tr\243\222\236\305 %\207\261\321c\347\312",
|
||||
"\220\322i\237\302\365t/\307cro \330",
|
||||
"\376\257\302\266t\205\360\275\235\354 \322i\213\012",
|
||||
"\250 \276nev\257\252\274\355",
|
||||
"\250 \276a\254gn\236\251\244u\200\270a\202\276nev\257\252\274\355",
|
||||
"\220d\217d\225\202\340\232: \365\202\374\334\276z\210o\012",
|
||||
"\220d\217d\225\202te\230: \365\202\374\334\276n\201-z\210o\012",
|
||||
"\217k\221w\342#p\242g\307\012",
|
||||
"\272\371\270 \366\220s\337\202\252\236bef\226\200\322i\213\320f\226c\353\220p\204s\311",
|
||||
"\375\231 sho\337\207\220tur\342\251\244u\311",
|
||||
"po\254\240\200\252\200\302\250 bef\226\200\203i\206\216iza\213\355",
|
||||
"po\254\240\224\217\203t\212\232\207a\254gn\234t\012",
|
||||
"po\254\240\224\217\203t\212\232\207bit\371s\200\364a\213\012",
|
||||
"\366mis\354\012",
|
||||
"po\254\240\224\251\042\350\333\306\315wa\205\203t\212\232d\355",
|
||||
"\374\334\331\205\221 effect\012",
|
||||
"ne\230\236\340m\234t\012",
|
||||
"\345os\200\203d\212\314\213\012",
|
||||
"\241\207\230y\362pro\305typ\275\252\236\371\270 \346\213\335sem\336\241umn\312",
|
||||
"\345c\335\332\215 s\331\360w\205\251\332a\202\251\313c\274\353lev\344\012",
|
||||
"\374\334\371\270 \366ov\210rid\200\327appe\204 betwe\212 p\204\212\270ese\312",
|
||||
"lab\344 nam\200\215 s\331\360w\205\366nam\311",
|
||||
"\376\257\302\343git\205\271ce\274\205\242\213\335\376\257\313ci\223\201\012",
|
||||
"\220d\217d\225\202\042\341e\267\042: \315\341\200\276\216way\2051 \330",
|
||||
"\203\232\347m\203\222\200\306\341\200\351\042\341e\267\333\374\334\330",
|
||||
"\217\220a\261\256\200\340\232\012",
|
||||
"\251\332\276a\254gn\236\305 its\344f \330",
|
||||
"m\226\200\203i\206\216iz\210\205\270\352\212um \357\344d\312",
|
||||
"l\212g\270 \302\203i\206\216iz\257\271ce\274\205\341\200\302\270\200\212um \357\344d\012",
|
||||
"\203\232x \366mis\354 \330",
|
||||
"\221 i\372le\234\314\237f\260\317\200\215 \351\375\231\320\221 f\216l-back\012",
|
||||
"\317\200specif\336a\237\334f\226w\204\207\232cl\321\237\276ig\221\220d\012",
|
||||
"outpu\202\357\362\276writt\212\320bu\202\371\270 \340\372ac\202\212\340d\353\343s\256\274\012",
|
||||
"\317\200\332\215 s\331\360w\205\251g\345b\335\304\311",
|
||||
"\277 \276m\204k\236a\205\232\313c\222\274: \211\012",
|
||||
"pu\240\336 \272lack\205f\226w\204\207\232cl\321\237\330",
|
||||
"\217k\221w\342p\321\356t\257\351subs\206tu\237(\203c\226\220c\202#\322\200p\222\347n\233"
|
||||
#endif
|
||||
};
|
||||
/* Pawn compiler - Error message strings (plain and compressed formats)
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 2000-2006
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
* the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]);
|
||||
|
||||
#ifndef SCPACK
|
||||
# define SCPACK
|
||||
# define SCPACK_PUSH
|
||||
#endif
|
||||
|
||||
#define SCPACK_TABLE errstr_table
|
||||
/*-*SCPACK start of pair table, do not change or remove this line */
|
||||
unsigned char errstr_table[][2] = {
|
||||
{101,32}, {116,32}, {111,110}, {105,110}, {115,32}, {97,114}, {100,32}, {116,105}, {37,115}, {101,114}, {101,110}, {97,108}, {135,130}, {110,111}, {34,136}, {142,34},
|
||||
{117,110}, {114,101}, {111,114}, {97,110}, {121,32}, {115,116}, {100,101}, {115,105}, {97,116}, {141,129}, {32,143}, {109,98}, {109,138}, {41,10}, {101,134}, {140,32},
|
||||
{116,104}, {98,108}, {144,99}, {102,162}, {114,97}, {111,108}, {117,115}, {146,32}, {118,139}, {97,32}, {115,121}, {170,155}, {171,165}, {103,32}, {137,32}, {103,117},
|
||||
{101,120}, {175,156}, {133,164}, {133,177}, {102,131}, {105,134}, {115,151}, {97,161}, {99,104}, {163,159}, {168,181}, {111,102}, {105,132}, {115,10}, {131,186}, {101,100},
|
||||
{166,129}, {101,132}, {172,154}, {109,192}, {98,128}, {99,130}, {118,133}, {99,147}, {187,32}, {105,183}, {198,201}, {104,97}, {109,97}, {116,111}, {112,145}, {178,148},
|
||||
{199,153}, {150,180}, {116,97}, {109,101}, {99,116}, {179,129}, {130,32}, {133,97}, {149,152}, {44,32}, {102,105}, {118,128}, {154,10}, {101,10}, {109,152}, {194,157},
|
||||
{110,32}, {40,223}, {100,105}, {119,105}, {117,108}, {99,111}, {97,115}, {202,128}, {136,10}, {197,149}, {34,32}, {139,32}, {151,122}, {98,101}, {108,111}, {111,112},
|
||||
{108,128}, {163,140}, {102,146}, {131,32}, {147,32}, {160,32}, {210,173}, {131,173}, {222,184}, {195,196}, {203,219}, {58,220}, {100,111}, {109,112}, {160,128}
|
||||
};
|
||||
/*-*SCPACK end of pair table, do not change or remove this line */
|
||||
|
||||
static char *errmsg[] = {
|
||||
#ifdef SCPACK
|
||||
/*001*/ "expected token: \"%s\", but found \"%s\"\n",
|
||||
/*002*/ "only a single statement (or expression) can follow each \"case\"\n",
|
||||
/*003*/ "declaration of a local variable must appear in a compound block\n",
|
||||
/*004*/ "function \"%s\" is not implemented\n",
|
||||
/*005*/ "function may not have arguments\n",
|
||||
/*006*/ "must be assigned to an array\n",
|
||||
/*007*/ "operator cannot be redefined\n",
|
||||
/*008*/ "must be a constant expression; assumed zero\n",
|
||||
/*009*/ "invalid array size (negative, zero or out of bounds)\n",
|
||||
/*010*/ "invalid function or declaration\n",
|
||||
/*011*/ "invalid outside functions\n",
|
||||
/*012*/ "invalid function call, not a valid address\n",
|
||||
/*013*/ "no entry point (no public functions)\n",
|
||||
/*014*/ "invalid statement; not in switch\n",
|
||||
/*015*/ "\"default\" case must be the last case in switch statement\n",
|
||||
/*016*/ "multiple defaults in \"switch\"\n",
|
||||
/*017*/ "undefined symbol \"%s\"\n",
|
||||
/*018*/ "initialization data exceeds declared size\n",
|
||||
/*019*/ "not a label: \"%s\"\n",
|
||||
/*020*/ "invalid symbol name \"%s\"\n",
|
||||
/*021*/ "symbol already defined: \"%s\"\n",
|
||||
/*022*/ "must be lvalue (non-constant)\n",
|
||||
/*023*/ "array assignment must be simple assignment\n",
|
||||
/*024*/ "\"break\" or \"continue\" is out of context\n",
|
||||
/*025*/ "function heading differs from prototype\n",
|
||||
/*026*/ "no matching \"#if...\"\n",
|
||||
/*027*/ "invalid character constant\n",
|
||||
/*028*/ "invalid subscript (not an array or too many subscripts): \"%s\"\n",
|
||||
/*029*/ "invalid expression, assumed zero\n",
|
||||
/*030*/ "compound statement not closed at the end of file (started at line %d)\n",
|
||||
/*031*/ "unknown directive\n",
|
||||
/*032*/ "array index out of bounds (variable \"%s\")\n",
|
||||
/*033*/ "array must be indexed (variable \"%s\")\n",
|
||||
/*034*/ "argument does not have a default value (argument %d)\n",
|
||||
/*035*/ "argument type mismatch (argument %d)\n",
|
||||
/*036*/ "empty statement\n",
|
||||
/*037*/ "invalid string (possibly non-terminated string)\n",
|
||||
/*038*/ "extra characters on line\n",
|
||||
/*039*/ "constant symbol has no size\n",
|
||||
/*040*/ "duplicate \"case\" label (value %d)\n",
|
||||
/*041*/ "invalid ellipsis, array size is not known\n",
|
||||
/*042*/ "invalid combination of class specifiers\n",
|
||||
/*043*/ "character constant exceeds range for packed string\n",
|
||||
/*044*/ "positional parameters must precede all named parameters\n",
|
||||
/*045*/ "too many function arguments\n",
|
||||
/*046*/ "unknown array size (variable \"%s\")\n",
|
||||
/*047*/ "array sizes do not match, or destination array is too small\n",
|
||||
/*048*/ "array (s do not match\n",
|
||||
/*049*/ "invalid line continuation\n",
|
||||
/*050*/ "invalid range\n",
|
||||
/*051*/ "invalid subscript, use \"[ ]\" operators on major dimensions\n",
|
||||
/*052*/ "multi-dimensional arrays must be fully initialized\n",
|
||||
/*053*/ "exceeding maximum number of dimensions\n",
|
||||
/*054*/ "unmatched closing brace (\"}\")\n",
|
||||
/*055*/ "start of function body without function header\n",
|
||||
/*056*/ "arrays, local variables and function arguments cannot be public (variable \"%s\")\n",
|
||||
/*057*/ "unfinished expression before compiler directive\n",
|
||||
/*058*/ "duplicate argument; same argument is passed twice\n",
|
||||
/*059*/ "function argument may not have a default value (variable \"%s\")\n",
|
||||
/*060*/ "multiple \"#else\" directives between \"#if ... #endif\"\n",
|
||||
/*061*/ "\"#elseif\" directive follows an \"#else\" directive\n",
|
||||
/*062*/ "number of operands does not fit the operator\n",
|
||||
/*063*/ "function result tag of operator \"%s\" must be \"%s\"\n",
|
||||
/*064*/ "cannot change predefined operators\n",
|
||||
/*065*/ "function argument may only have a single tag (argument %d)\n",
|
||||
/*066*/ "function argument may not be a reference argument or an array (argument \"%s\")\n",
|
||||
/*067*/ "variable cannot be both a reference and an array (variable \"%s\")\n",
|
||||
/*068*/ "invalid rational number precision in #pragma\n",
|
||||
/*069*/ "rational number format already defined\n",
|
||||
/*070*/ "rational number support was not enabled\n",
|
||||
/*071*/ "user-defined operator must be declared before use (function \"%s\")\n",
|
||||
/*072*/ "\"sizeof\" operator is invalid on \"function\" symbols\n",
|
||||
/*073*/ "function argument must be an array (argument \"%s\")\n",
|
||||
/*074*/ "#define pattern must start with an alphabetic character\n",
|
||||
/*075*/ "input line too long (after substitutions)\n",
|
||||
/*076*/ "syntax error in the expression, or invalid function call\n",
|
||||
/*077*/ "malformed UTF-8 encoding, or corrupted file: %s\n",
|
||||
/*078*/ "function uses both \"return\" and \"return <value>\"\n",
|
||||
/*079*/ "inconsistent return types (array & non-array)\n",
|
||||
/*080*/ "unknown symbol, or not a constant symbol (symbol \"%s\")\n",
|
||||
/*081*/ "cannot take a tag as a default value for an indexed array parameter (symbol \"%s\")\n",
|
||||
/*082*/ "user-defined operators and native functions may not have states\n",
|
||||
/*083*/ "a function or variable may only belong to a single automaton (symbol \"%s\")\n",
|
||||
/*084*/ "state conflict: one of the states is already assigned to another implementation (symbol \"%s\")\n",
|
||||
/*085*/ "no states are defined for symbol \"%s\"\n",
|
||||
/*086*/ "unknown automaton \"%s\"\n",
|
||||
/*087*/ "unknown state \"%s\" for automaton \"%s\"\n",
|
||||
/*088*/ "public variables and local variables may not have states (symbol \"%s\")\n",
|
||||
/*089*/ "state variables may not be initialized (symbol \"%s\")\n",
|
||||
/*090*/ "public functions may not return arrays (symbol \"%s\")\n",
|
||||
/*091*/ "ambiguous constant; tag override is required (symbol \"%s\")\n",
|
||||
/*092*/ "number of arguments does not match definition\n",
|
||||
/*093*/ "expected tag name identifier\n",
|
||||
/*094*/ "function enumeration requires unique tag\n",
|
||||
/*095*/ "cannot have required parameters after optional parameters\n",
|
||||
/*096*/ "could not find member \"%s\" in struct \"%s\"\n",
|
||||
/*097*/ "symbol \"%s\" does not have a matching type\n",
|
||||
/*098*/ "type \"%s\" should be \"%s\" in new-style declarations\n",
|
||||
/*099*/ "destructors cannot return values\n",
|
||||
/*100*/ "function prototypes do not match\n",
|
||||
/*101*/ "specify either all dimensions or only the last dimension\n",
|
||||
/*102*/ "cannot find %s %s\n",
|
||||
/*103*/ "%s was already defined on this %s\n",
|
||||
/*104*/ "cannot find any methods for %s\n",
|
||||
/*105*/ "cannot find method %s.%s\n",
|
||||
/*106*/ "cannot call methods on an array\n",
|
||||
/*107*/ "cannot call methods on a function\n",
|
||||
/*108*/ "method must have a first argument compatible with the %s type (%s)\n",
|
||||
/*109*/ "%s name must start with an uppercase letter\n",
|
||||
/*110*/ "%s has already been defined (previously seen as %s)\n",
|
||||
/*111*/ "expected identifier - did you forget a type?\n",
|
||||
/*112*/ "constructor function must return tag %s\n",
|
||||
/*113*/ "cannot define constructor for \"%s\"; already exists as a %s\n",
|
||||
/*114*/ "destructor must have the same name as %s \"%s\"\n",
|
||||
/*115*/ "delete cannot be used with %s\n",
|
||||
/*116*/ "no methodmap or class was found for %s\n",
|
||||
/*117*/ "no destructor was found for %s %s\n",
|
||||
/*118*/ "destructors must be native functions\n",
|
||||
/*119*/ "destructors cannot have extra arguments\n",
|
||||
#else
|
||||
"\260pe\324\236\315k\212:\232\331bu\201fo\220\206\217\012",
|
||||
"\202l\224\251s\203g\360\330e\234\201(\247\260\316\266\202) \307 f\245\356w ea\270 \042c\346e\042\012",
|
||||
"\226cl\327\237\310\251\356c\353\347\303appe\205 \363\251\345\375o\220\206\241ock\012",
|
||||
"\361\232 \274\231i\375le\234t\277\012",
|
||||
"\271\314\224\231\372\263t\275",
|
||||
"\371a\266gn\236\315 \364\262y\012",
|
||||
"\357\211\230\247\320\304\221\321\277\012",
|
||||
"\371\251\351\223\201\260\316\266\202; \346sum\236z\211o\012",
|
||||
"\276\317\354\200(nega\207ve\331z\211o \247ou\201\310bo\220ds\235",
|
||||
"\276\271\247\226cl\327\214\012",
|
||||
"\276out\227d\200\361\275",
|
||||
"\276\271c\213l\331\231\251\272add\221s\275",
|
||||
"\215 \212tr\224po\203\201(\215 pu\241ic \361s\235",
|
||||
"\276\330e\234t; \231\363s\343t\270\012",
|
||||
"\042\226fa\344t\352c\346\200\371\376l\346\201c\346\200\363s\343t\270 \330e\234t\012",
|
||||
"m\344\207p\360\226fa\344t\204\363\042s\343t\270\042\012",
|
||||
"\220\321\236\302\012",
|
||||
"\203i\207\213iza\237d\230\251\260ce\277\204\226cl\205\236\354\335",
|
||||
"\231\251la\355l\373",
|
||||
"\276\254 nam\200\217\012",
|
||||
"\254 \213\221ad\224\321\277\373",
|
||||
"\371l\250u\200(n\202-\351\223t\235",
|
||||
"\317a\266gn\234\201\371\227\375\360a\266gn\234t\012",
|
||||
"\042b\221ak\352\247\042\305t\203ue\352\274ou\201\310\305t\260t\012",
|
||||
"\271head\367\342ff\211\204from pro\315typ\335",
|
||||
"\215 \370\367\042#if...\042\012",
|
||||
"\276\270\327\324\256\351\223t\012",
|
||||
"\276subscrip\201(\231\364\317\247\315o m\223\224subscripts)\373",
|
||||
"\276\260\316\266\202\331\346sum\236z\211o\012",
|
||||
"\345\375o\220\206\330e\234\201\231c\356s\236a\201\376\212\206\310\332\360(\225\205t\236a\201l\203\200%d\235",
|
||||
"\220k\215w\340\342\221c\207v\335",
|
||||
"\317\203\226x ou\201\310bo\220d\204(\347\217\235",
|
||||
"\317\371\203\226x\236(\347\217\235",
|
||||
"\325\374\301\231\372\251\226fa\344\201\250u\200(\325%d\235",
|
||||
"\325typ\200mis\370 (\325%d\235",
|
||||
"e\375t\224\330e\234t\012",
|
||||
"\276\225r\367(po\266\241\224n\202-t\211m\203\230\236\225r\203g\235",
|
||||
"\260t\244 \270\327\324\211\204\326l\203\335",
|
||||
"\351\223\201\254 \313\204\215 \354\335",
|
||||
"duplic\230\200\042c\346e\352la\355l (\250u\200%d\235",
|
||||
"\276ellip\227s\331\317\354\200\274\231k\215wn\012",
|
||||
"\276\345\233\203a\237\310cl\346\204speci\332\211\275",
|
||||
"\270\327\324\256\351\223\201\260ce\277\204r\223g\200f\247pack\236\225r\203g\012",
|
||||
"po\227\214\353p\327\323t\211\204\303\316c\277\200\213l nam\236p\327\323t\211\275",
|
||||
"\315o m\223\224\271\263t\275",
|
||||
"\220k\215w\340\317\354\200(\347\217\235",
|
||||
"\317\354\301\374 \231\370\331\247\226\225\203a\237\317\274\315o sm\213l\012",
|
||||
"\317(\204\374 \231\370\012",
|
||||
"\276l\203\200\305t\203ua\214\012",
|
||||
"\276r\223g\335",
|
||||
"\276subscript\331\246\200\042[ ]\352\357\211\230\222\204\326\314j\247\342\234\227\202\275",
|
||||
"m\344\207-\342\234\227\202\353\262y\204\371f\344l\224\203i\207\213iz\277\012",
|
||||
"\260ce\277\367\314ximum nu\233\256\310\342\234\227\202\275",
|
||||
"\220\370\236c\356s\367b\244c\200(\042}\042\235",
|
||||
"\225\205\201\310\271bod\224\343\240ou\201\271head\211\012",
|
||||
"\262ys\331\356c\353\312\301\223\206\271\263t\204\320\304pu\241ic (\347\217\235",
|
||||
"\220\264ish\236\260\316\266\326\355\362\200\345\375il\256\342\221c\207v\335",
|
||||
"duplic\230\200\263t; sam\200\325\274p\346s\236t\343c\335",
|
||||
"\271\325\314\224\231\372\251\226fa\344\201\250u\200(\347\217\235",
|
||||
"m\344\207p\360\042#else\352\342\221c\207v\301\355twe\212 \042#if ... #\212\342f\042\012",
|
||||
"\042#elseif\352\342\221c\207\333f\245\356w\204\364\042#else\352\342\221c\207v\335",
|
||||
"nu\233\256\310\357\211\223d\204\374\301\231\332\201\376\357\211\230\222\012",
|
||||
"\271\221s\344\201\366\310\357\211\230\222\232 \371\217\012",
|
||||
"\320\270\223g\200\316\321\236\357\211\230\222\275",
|
||||
"\271\325\314\224\202l\224\372\251s\203g\360\366(\325%d\235",
|
||||
"\271\325\314\224\231\304\251\221f\211\212c\200\325\247\364\317(\325\217\235",
|
||||
"\347\320\304bo\365\251\221f\211\212c\200\223\206\364\317(\347\217\235",
|
||||
"\276\244\214\353nu\233\256\316ci\227\326\363#p\244g\314\012",
|
||||
"\244\214\353nu\233\256\362\314\201\213\221ad\224\321\277\012",
|
||||
"\244\214\353nu\233\256supp\222\201wa\204\231\212\267\277\012",
|
||||
"\246\211-\321\236\357\211\230\247\371\226cl\205\236\355\362\200\246\200(\361\232\235",
|
||||
"\042\354e\273\352\357\211\230\247\274\276\326\042\361\352\254\275",
|
||||
"\271\325\371\364\317(\325\217\235",
|
||||
"#\321\200p\230t\211\340\303\225\205\201\343\365\364\213p\313\355\207c \270\327\324\211\012",
|
||||
"\203pu\201l\203\200\315o l\202\255(aft\256subs\207tu\214s\235",
|
||||
"\252n\322x \211r\247\363\376\260\316\266\202\331\247\276\271c\213l\012",
|
||||
"m\213\362m\236UTF-8 \212\345d\203g\331\247c\222rupt\236\332le: \350",
|
||||
"\271\246\301bo\365\042\221turn\352\223\206\042\221tur\340<\250ue>\042\012",
|
||||
"\203\305\227\225\212\201\221tur\340typ\301(\317& n\202-\262y\235",
|
||||
"\220k\215w\340\254\331\247\231\251\351\223\201\254 \341",
|
||||
"\320\322k\200\251\366a\204\251\226fa\344\201\250u\200f\247\364\203\226x\236\317p\327\323t\256\341",
|
||||
"\246\211-\321\236\357\211\230\222\204\223\206na\207\333\361\204\314\224\231\372\330e\275",
|
||||
"\251\271\247\347\314\224\202l\224\355l\202\255\315 \251s\203g\360au\315\336\326\341",
|
||||
"\330\200\305fli\324: \202\200\310\376\330\301\274\213\221ad\224a\266gn\236\315 a\215\240\256i\375le\234\322\237\341",
|
||||
"\215 \330\301\205\200\321\236f\247\302\012",
|
||||
"\220k\215w\340au\315\336\202\334",
|
||||
"\220k\215w\340\330\200\217 f\247au\315\336\202\334",
|
||||
"pu\241ic \312\301\223\206\356c\353\312\301\314\224\231\372\330\301\341",
|
||||
"\330\200\312\301\314\224\231\304\203i\207\213iz\236\341",
|
||||
"pu\241ic \361\204\314\224\231\221tur\340\262y\204\341",
|
||||
"a\233i\257ou\204\351\223t; \366ov\211rid\200\274\221qui\221\206\341",
|
||||
"nu\233\256\310\263t\204\374\301\231\370 \321i\214\012",
|
||||
"\260pe\324\236\366nam\200id\212\207\332\211\012",
|
||||
"\271\212um\211a\237\221qui\221\204\220iqu\200\322g\012",
|
||||
"\320\372\221qui\221\206p\327\323t\211\204aft\256\357\214\353p\327\323t\211\275",
|
||||
"\345\344\206\231\264\206\323\233\211\232 \363\225ruc\201\217\012",
|
||||
"\302 \374\301\231\372\251\370\367typ\335",
|
||||
"typ\200\217 sho\344\206\304\217 \363new-\225y\360\226cl\327\214\275",
|
||||
"\226\225ru\324\222\204\320\221tur\340\250ue\275",
|
||||
"\271pro\315typ\301\374 \231\370\012",
|
||||
"specif\224ei\240\256\213l \342\234\227\202\204\247\202l\224\376l\346\201\342\234\227\202\012",
|
||||
"\320\264\206%\204\350",
|
||||
"%\204wa\204\213\221ad\224\321\236\326\240\274\350",
|
||||
"\320\264\206\223\224\323\240od\204f\247\350",
|
||||
"\320\264\206\323\240o\206\210.\350",
|
||||
"\320c\213l \323\240od\204\326\364\262y\012",
|
||||
"\320c\213l \323\240od\204\326\251\361\012",
|
||||
"\323\240o\206\303\372\251\332rs\201\325\345\375a\207\241\200\343\365\376%\204typ\200(\210\235",
|
||||
"%\204nam\200\303\225\205\201\343\365\364upp\211c\346\200lett\211\012",
|
||||
"%\204\313\204\213\221ad\224\355\212 \321\236(\316vio\246l\224se\212 a\204\210\235",
|
||||
"\260pe\324\236id\212\207\332\256- d\265you \362ge\201\251type?\012",
|
||||
"\351ru\324\247\271\303\221tur\340\366\350",
|
||||
"\320\321\200\351ru\324\247\362\232; \213\221ad\224\260i\225\204a\204\251\350",
|
||||
"\226\225ru\324\247\303\372\376sam\200nam\200a\204%\204\217\012",
|
||||
"\226let\200\320\304\246\236\343\365\350",
|
||||
"\215 \323\240od\314p \247cl\346\204wa\204fo\220\206f\247\350",
|
||||
"\215 \226\225ru\324\247wa\204fo\220\206f\247%\204\350",
|
||||
"\226\225ru\324\222\204\371na\207\333\361\275",
|
||||
"\226\225ru\324\222\204\320\372\260t\244 \263t\275"
|
||||
#endif
|
||||
};
|
||||
|
||||
static char *fatalmsg[] = {
|
||||
#ifdef SCPACK
|
||||
/*120*/ "cannot read from file: \"%s\"\n",
|
||||
/*121*/ "cannot write to file: \"%s\"\n",
|
||||
/*122*/ "table overflow: \"%s\"\n",
|
||||
/* table can be: loop table
|
||||
* literal table
|
||||
* staging buffer
|
||||
* option table (response file)
|
||||
* peephole optimizer table
|
||||
*/
|
||||
/*123*/ "insufficient memory\n",
|
||||
/*124*/ "invalid assembler instruction \"%s\"\n",
|
||||
/*125*/ "numeric overflow, exceeding capacity\n",
|
||||
/*126*/ "compiled script exceeds the maximum memory size (%ld bytes)\n",
|
||||
/*127*/ "too many error messages on one line\n",
|
||||
/*128*/ "codepage mapping file not found\n",
|
||||
/*129*/ "invalid path: \"%s\"\n",
|
||||
/*130*/ "assertion failed: %s\n",
|
||||
/*131*/ "user error: %s\n",
|
||||
#else
|
||||
"\320\221a\206from \332le\373",
|
||||
"\320writ\200\315 \332le\373",
|
||||
"t\267\200ov\211f\356w\373",
|
||||
"\203suf\332ci\212\201\323m\222y\012",
|
||||
"\276\346se\233l\256\203\225ruc\214\334",
|
||||
"num\211ic ov\211f\356w\331\260ce\277\367capacity\012",
|
||||
"\345\375il\236scrip\201\260ce\277\204\376\314ximum \323m\222\224\354\200(%l\206bytes\235",
|
||||
"\315o m\223\224\211r\247\323ssag\301\326\202\200l\203\335",
|
||||
"\345\226pag\200\314pp\367\332\360\231fo\220d\012",
|
||||
"\276p\230h\373",
|
||||
"\346s\211\237fail\277: \350",
|
||||
"\246\256\211r\222: \350"
|
||||
#endif
|
||||
};
|
||||
|
||||
static char *warnmsg[] = {
|
||||
#ifdef SCPACK
|
||||
/*200*/ "symbol \"%s\" is truncated to %d characters\n",
|
||||
/*201*/ "redefinition of constant/macro (symbol \"%s\")\n",
|
||||
/*202*/ "number of arguments does not match definition\n",
|
||||
/*203*/ "symbol is never used: \"%s\"\n",
|
||||
/*204*/ "symbol is assigned a value that is never used: \"%s\"\n",
|
||||
/*205*/ "redundant code: constant expression is zero\n",
|
||||
/*206*/ "redundant test: constant expression is non-zero\n",
|
||||
/*207*/ "unknown #pragma\n",
|
||||
/*208*/ "function with tag result used before definition, forcing reparse\n",
|
||||
/*209*/ "function \"%s\" should return a value\n",
|
||||
/*210*/ "possible use of symbol before initialization: \"%s\"\n",
|
||||
/*211*/ "possibly unintended assignment\n",
|
||||
/*212*/ "possibly unintended bitwise operation\n",
|
||||
/*213*/ "tag mismatch\n",
|
||||
/*214*/ "possibly a \"const\" array argument was intended: \"%s\"\n",
|
||||
/*215*/ "expression has no effect\n",
|
||||
/*216*/ "nested comment\n",
|
||||
/*217*/ "loose indentation\n",
|
||||
/*218*/ "old style prototypes used with optional semicolumns\n",
|
||||
/*219*/ "local variable \"%s\" shadows a variable at a preceding level\n",
|
||||
/*220*/ "expression with tag override must appear between parentheses\n",
|
||||
/*221*/ "label name \"%s\" shadows tag name\n",
|
||||
/*222*/ "number of digits exceeds rational number precision\n",
|
||||
/*223*/ "redundant \"sizeof\": argument size is always 1 (symbol \"%s\")\n",
|
||||
/*224*/ "indeterminate array size in \"sizeof\" expression (symbol \"%s\")\n",
|
||||
/*225*/ "unreachable code\n",
|
||||
/*226*/ "a variable is assigned to itself (symbol \"%s\")\n",
|
||||
/*227*/ "more initializers than enum fields\n",
|
||||
/*228*/ "length of initializer exceeds size of the enum field\n",
|
||||
/*229*/ "index tag mismatch (symbol \"%s\")\n",
|
||||
/*230*/ "no implementation for state \"%s\" in function \"%s\", no fall-back\n",
|
||||
/*231*/ "state specification on forward declaration is ignored\n",
|
||||
/*232*/ "output file is written, but with compact encoding disabled\n",
|
||||
/*233*/ "state variable \"%s\" shadows a global variable\n",
|
||||
/*234*/ "symbol \"%s\" is marked as deprecated: %s\n",
|
||||
/*235*/ "public function lacks forward declaration (symbol \"%s\")\n",
|
||||
/*236*/ "unknown parameter in substitution (incorrect #define pattern)\n"
|
||||
#else
|
||||
"\302 \274tr\242\230\236\315 %\206\270\327\324\211\275",
|
||||
"\221\321i\237\310\351\223t/\314cro \341",
|
||||
"nu\233\256\310\263t\204\374\301\231\370 \321i\214\012",
|
||||
"\254 \274nev\256\246\277\373",
|
||||
"\254 \274a\266gn\236\251\250u\200\240a\201\274nev\256\246\277\373",
|
||||
"\221d\220d\223\201\345\226: \351\223\201\260\316\266\326\274z\211o\012",
|
||||
"\221d\220d\223\201te\225: \351\223\201\260\316\266\326\274n\202-z\211o\012",
|
||||
"\220k\215w\340#p\244g\314\012",
|
||||
"\271\343\365\366\221s\344\201\246\236\355\362\200\321i\214\331\362c\367\221p\205s\335",
|
||||
"\361\232 sho\344\206\221tur\340\251\250u\335",
|
||||
"po\266\241\200\246\200\310\254 \355\362\200\203i\207\213iza\214\373",
|
||||
"po\266\241\224\220\203t\212\226\206a\266gn\234t\012",
|
||||
"po\266\241\224\220\203t\212\226\206bit\343s\200\357\211a\214\012",
|
||||
"\366mis\370\012",
|
||||
"po\266\241\224\251\042\351\352\317\325wa\204\203t\212\226d\373",
|
||||
"\260\316\266\326\313\204\215 effe\324\012",
|
||||
"ne\225\236\345m\234t\012",
|
||||
"\356os\200\203d\212\322\214\012",
|
||||
"\245\206\225y\360pro\315typ\301\246\236\343\365\357\214\353semic\245umn\275",
|
||||
"\356c\353\347\217 s\313\374w\204\251\347a\201\251\316c\277\367level\012",
|
||||
"\260\316\266\326\343\365\366ov\211rid\200\303appe\205 \355twe\212 p\205\212\240ese\275",
|
||||
"la\355l nam\200\217 s\313\374w\204\366na\323\012",
|
||||
"nu\233\256\310\342git\204\260ce\277\204\244\214\353nu\233\256\316ci\227\202\012",
|
||||
"\221d\220d\223\201\042\354e\273\042: \325\354\200\274\213way\2041 \341",
|
||||
"\203\226t\211m\203\230\200\317\354\200\363\042\354e\273\352\260\316\266\326\341",
|
||||
"\220\221a\270\267\200\345\226\012",
|
||||
"\251\347\274a\266gn\236\315 itself \341",
|
||||
"m\222\200\203i\207\213iz\211\204\240\364\212um \332eld\275",
|
||||
"l\212g\365\310\203i\207\213iz\256\260ce\277\204\354\200\310\376\212um \332eld\012",
|
||||
"\203\226x \366mis\370 \341",
|
||||
"\215 i\375le\234\322\237f\247\330\200\217 \363\361\232\331\215 f\213l-back\012",
|
||||
"\330\200speci\332ca\237\326\362w\205\206\226cl\327\237\274ig\215\221d\012",
|
||||
"outpu\201\332\360\274writt\212\331bu\201\343\365\345\375ac\201\212\345d\367\342s\267\277\012",
|
||||
"\330\200\347\217 s\313\374w\204\251g\356b\353\312\335",
|
||||
"\302 \274m\205k\236a\204\226\316c\230\277: \350",
|
||||
"pu\241ic \271lack\204\362w\205\206\226cl\327\237\341",
|
||||
"\220k\215w\340p\327\323t\256\363subs\207tu\237(\203c\222\221c\201#\321\200p\230t\211n\235"
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef SCPACK_PUSH
|
||||
# undef SCPACK
|
||||
#endif
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* vim: set ts=8 sts=2 sw=2 tw=99 et: */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@ -10,6 +11,8 @@ funcenum_t *firstenum = NULL;
|
||||
funcenum_t *lastenum = NULL;
|
||||
pstruct_t *firststruct = NULL;
|
||||
pstruct_t *laststruct = NULL;
|
||||
methodmap_t *methodmap_first = NULL;
|
||||
methodmap_t *methodmap_last = NULL;
|
||||
|
||||
structarg_t *pstructs_getarg(pstruct_t *pstruct, const char *member)
|
||||
{
|
||||
@ -345,20 +348,20 @@ void _stack_genusage(memuse_list_t *stack, int dofree)
|
||||
while (cur)
|
||||
{
|
||||
if (cur->type == MEMUSE_DYNAMIC)
|
||||
{
|
||||
{
|
||||
/* no idea yet */
|
||||
assert(0);
|
||||
} else {
|
||||
} else {
|
||||
modstk(cur->size * sizeof(cell));
|
||||
}
|
||||
if (dofree)
|
||||
{
|
||||
}
|
||||
if (dofree)
|
||||
{
|
||||
tmp = cur->prev;
|
||||
free(cur);
|
||||
cur = tmp;
|
||||
} else {
|
||||
} else {
|
||||
cur = cur->prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dofree)
|
||||
{
|
||||
@ -411,6 +414,13 @@ void popstacklist(int codegen)
|
||||
{
|
||||
_stack_genusage(stackusage, 1);
|
||||
assert(stackusage->head==NULL);
|
||||
} else {
|
||||
memuse_t *use = stackusage->head;
|
||||
while (use) {
|
||||
memuse_t *temp = use->prev;
|
||||
free(use);
|
||||
use = temp;
|
||||
}
|
||||
}
|
||||
|
||||
oldlist = stackusage->prev;
|
||||
@ -427,3 +437,141 @@ void resetheaplist()
|
||||
{
|
||||
_reset_memlist(&heapusage);
|
||||
}
|
||||
|
||||
void methodmap_add(methodmap_t *map)
|
||||
{
|
||||
if (!methodmap_first) {
|
||||
methodmap_first = map;
|
||||
methodmap_last = map;
|
||||
} else {
|
||||
methodmap_last->next = map;
|
||||
methodmap_last = map;
|
||||
}
|
||||
}
|
||||
|
||||
methodmap_t *methodmap_find_by_tag(int tag)
|
||||
{
|
||||
methodmap_t *ptr = methodmap_first;
|
||||
for (; ptr; ptr = ptr->next) {
|
||||
if (ptr->tag == tag)
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
methodmap_t *methodmap_find_by_name(const char *name)
|
||||
{
|
||||
int tag = pc_findtag(name);
|
||||
if (tag == -1)
|
||||
return NULL;
|
||||
return methodmap_find_by_tag(tag);
|
||||
}
|
||||
|
||||
methodmap_method_t *methodmap_find_method(methodmap_t *map, const char *name)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < map->nummethods; i++) {
|
||||
if (strcmp(map->methods[i]->name, name) == 0)
|
||||
return map->methods[i];
|
||||
}
|
||||
if (map->parent)
|
||||
return methodmap_find_method(map->parent, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void methodmaps_free()
|
||||
{
|
||||
methodmap_t *ptr = methodmap_first;
|
||||
while (ptr) {
|
||||
methodmap_t *next = ptr->next;
|
||||
for (size_t i = 0; i < ptr->nummethods; i++)
|
||||
free(ptr->methods[i]);
|
||||
free(ptr->methods);
|
||||
free(ptr);
|
||||
ptr = next;
|
||||
}
|
||||
methodmap_first = NULL;
|
||||
methodmap_last = NULL;
|
||||
}
|
||||
|
||||
LayoutSpec deduce_layout_spec_by_tag(int tag)
|
||||
{
|
||||
symbol *sym;
|
||||
const char *name;
|
||||
methodmap_t *map;
|
||||
if ((map = methodmap_find_by_tag(tag)) != NULL)
|
||||
return map->spec;
|
||||
if (tag & FUNCTAG)
|
||||
return Layout_FuncTag;
|
||||
|
||||
name = pc_tagname(tag);
|
||||
if (pstructs_find(name))
|
||||
return Layout_PawnStruct;
|
||||
if ((sym = findglb(name, sGLOBAL)) != NULL)
|
||||
return Layout_Enum;
|
||||
|
||||
return Layout_None;
|
||||
}
|
||||
|
||||
LayoutSpec deduce_layout_spec_by_name(const char *name)
|
||||
{
|
||||
symbol *sym;
|
||||
methodmap_t *map;
|
||||
int tag = pc_findtag(name);
|
||||
if (tag != -1 && (tag & FUNCTAG))
|
||||
return Layout_FuncTag;
|
||||
if (pstructs_find(name))
|
||||
return Layout_PawnStruct;
|
||||
if ((map = methodmap_find_by_name(name)) != NULL)
|
||||
return map->spec;
|
||||
if ((sym = findglb(name, sGLOBAL)) != NULL)
|
||||
return Layout_Enum;
|
||||
|
||||
return Layout_None;
|
||||
}
|
||||
|
||||
const char *layout_spec_name(LayoutSpec spec)
|
||||
{
|
||||
switch (spec) {
|
||||
case Layout_None:
|
||||
return "<none>";
|
||||
case Layout_Enum:
|
||||
return "enum";
|
||||
case Layout_FuncTag:
|
||||
return "functag";
|
||||
case Layout_PawnStruct:
|
||||
return "deprecated-struct";
|
||||
case Layout_MethodMap:
|
||||
return "methodmap";
|
||||
case Layout_Class:
|
||||
return "class";
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
int can_redef_layout_spec(LayoutSpec def1, LayoutSpec def2)
|
||||
{
|
||||
// Normalize the ordering, since these checks are symmetrical.
|
||||
if (def1 > def2) {
|
||||
LayoutSpec temp = def2;
|
||||
def2 = def1;
|
||||
def1 = temp;
|
||||
}
|
||||
|
||||
switch (def1) {
|
||||
case Layout_None:
|
||||
return TRUE;
|
||||
case Layout_Enum:
|
||||
if (def2 == Layout_Enum || def2 == Layout_FuncTag)
|
||||
return TRUE;
|
||||
return def2 == Layout_MethodMap;
|
||||
case Layout_FuncTag:
|
||||
return def2 == Layout_Enum || def2 == Layout_FuncTag;
|
||||
case Layout_PawnStruct:
|
||||
case Layout_MethodMap:
|
||||
return FALSE;
|
||||
case Layout_Class:
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* vim: set sts=2 ts=8 sw=2 tw=99 et: */
|
||||
#ifndef _INCLUDE_SOURCEPAWN_COMPILER_TRACKER_H_
|
||||
#define _INCLUDE_SOURCEPAWN_COMPILER_TRACKER_H_
|
||||
|
||||
@ -66,6 +67,42 @@ typedef struct pstruct_s
|
||||
struct pstruct_s *next;
|
||||
} pstruct_t;
|
||||
|
||||
// The ordering of these definitions should be preserved for
|
||||
// can_redef_layout_spec().
|
||||
typedef enum LayoutSpec_t
|
||||
{
|
||||
Layout_None,
|
||||
Layout_Enum,
|
||||
Layout_FuncTag,
|
||||
Layout_PawnStruct,
|
||||
Layout_MethodMap,
|
||||
Layout_Class
|
||||
} LayoutSpec;
|
||||
|
||||
// The method name buffer is larger since we can include our parent class's
|
||||
// name, a "." to separate it, and a "~" for constructors.
|
||||
#define METHOD_NAMEMAX sNAMEMAX * 2 + 2
|
||||
|
||||
typedef struct methodmap_method_s
|
||||
{
|
||||
char name[METHOD_NAMEMAX + 1];
|
||||
symbol *target;
|
||||
} methodmap_method_t;
|
||||
|
||||
typedef struct methodmap_s
|
||||
{
|
||||
struct methodmap_s *next;
|
||||
struct methodmap_s *parent;
|
||||
int tag;
|
||||
LayoutSpec spec;
|
||||
char name[sNAMEMAX+1];
|
||||
methodmap_method_t **methods;
|
||||
size_t nummethods;
|
||||
|
||||
// Shortcut.
|
||||
methodmap_method_t *dtor;
|
||||
} methodmap_t;
|
||||
|
||||
/**
|
||||
* Pawn Structs
|
||||
*/
|
||||
@ -83,6 +120,14 @@ funcenum_t *funcenums_add(const char *name);
|
||||
funcenum_t *funcenums_find_byval(int value);
|
||||
functag_t *functags_add(funcenum_t *en, functag_t *src);
|
||||
|
||||
/**
|
||||
* Given a name or tag, find any extra weirdness it has associated with it.
|
||||
*/
|
||||
LayoutSpec deduce_layout_spec_by_tag(int tag);
|
||||
LayoutSpec deduce_layout_spec_by_name(const char *name);
|
||||
const char *layout_spec_name(LayoutSpec spec);
|
||||
int can_redef_layout_spec(LayoutSpec olddef, LayoutSpec newdef);
|
||||
|
||||
/**
|
||||
* Heap functions
|
||||
*/
|
||||
@ -111,6 +156,15 @@ void genheapfree(int stop_id);
|
||||
void resetstacklist();
|
||||
void resetheaplist();
|
||||
|
||||
/**
|
||||
* Method maps.
|
||||
*/
|
||||
void methodmap_add(methodmap_t *map);
|
||||
methodmap_t *methodmap_find_by_tag(int tag);
|
||||
methodmap_t *methodmap_find_by_name(const char *name);
|
||||
methodmap_method_t *methodmap_find_method(methodmap_t *map, const char *name);
|
||||
void methodmaps_free();
|
||||
|
||||
extern memuse_list_t *heapusage;
|
||||
extern memuse_list_t *stackusage;
|
||||
|
||||
|
9
sourcepawn/compiler/tests/fail-array-on-implicit-this.sp
Normal file
9
sourcepawn/compiler/tests/fail-array-on-implicit-this.sp
Normal file
@ -0,0 +1,9 @@
|
||||
native CloseHandle(Handle:this[]);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
}
|
@ -0,0 +1 @@
|
||||
method must have a first argument compatible with the methodmap type (Handle)
|
13
sourcepawn/compiler/tests/fail-ctor-bad-return-type.sp
Normal file
13
sourcepawn/compiler/tests/fail-ctor-bad-return-type.sp
Normal file
@ -0,0 +1,13 @@
|
||||
native Float:CreateHandle(count);
|
||||
native CloseHandle(Handle:handle);
|
||||
|
||||
methodmap Handle {
|
||||
public Handle() = CreateHandle;
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main() {
|
||||
new Handle:handle = Handle(3);
|
||||
handle.Close();
|
||||
}
|
||||
|
1
sourcepawn/compiler/tests/fail-ctor-bad-return-type.txt
Normal file
1
sourcepawn/compiler/tests/fail-ctor-bad-return-type.txt
Normal file
@ -0,0 +1 @@
|
||||
constructor function must return tag Handle
|
8
sourcepawn/compiler/tests/fail-dtor-extra-args.sp
Normal file
8
sourcepawn/compiler/tests/fail-dtor-extra-args.sp
Normal file
@ -0,0 +1,8 @@
|
||||
native Q(X:this, a);
|
||||
|
||||
methodmap X {
|
||||
public ~X() = Q;
|
||||
}
|
||||
|
||||
public main() {
|
||||
}
|
1
sourcepawn/compiler/tests/fail-dtor-extra-args.txt
Normal file
1
sourcepawn/compiler/tests/fail-dtor-extra-args.txt
Normal file
@ -0,0 +1 @@
|
||||
destructors cannot have extra arguments
|
10
sourcepawn/compiler/tests/fail-dtor-non-native.sp
Normal file
10
sourcepawn/compiler/tests/fail-dtor-non-native.sp
Normal file
@ -0,0 +1,10 @@
|
||||
Q(X:this)
|
||||
{
|
||||
}
|
||||
|
||||
methodmap X {
|
||||
public ~X() = Q;
|
||||
}
|
||||
|
||||
public main() {
|
||||
}
|
1
sourcepawn/compiler/tests/fail-dtor-non-native.txt
Normal file
1
sourcepawn/compiler/tests/fail-dtor-non-native.txt
Normal file
@ -0,0 +1 @@
|
||||
destructors must be native functions
|
8
sourcepawn/compiler/tests/fail-dtor-returns-value.sp
Normal file
8
sourcepawn/compiler/tests/fail-dtor-returns-value.sp
Normal file
@ -0,0 +1,8 @@
|
||||
native bool:Q();
|
||||
|
||||
methodmap X {
|
||||
public ~X() = Q;
|
||||
}
|
||||
|
||||
public main() {
|
||||
}
|
1
sourcepawn/compiler/tests/fail-dtor-returns-value.txt
Normal file
1
sourcepawn/compiler/tests/fail-dtor-returns-value.txt
Normal file
@ -0,0 +1 @@
|
||||
destructors cannot return values
|
8
sourcepawn/compiler/tests/fail-duplicate-methods.sp
Normal file
8
sourcepawn/compiler/tests/fail-duplicate-methods.sp
Normal file
@ -0,0 +1,8 @@
|
||||
native X:Crab();
|
||||
methodmap X {
|
||||
public X() = Crab;
|
||||
public X() = Crab;
|
||||
}
|
||||
|
||||
public main() {
|
||||
}
|
1
sourcepawn/compiler/tests/fail-duplicate-methods.txt
Normal file
1
sourcepawn/compiler/tests/fail-duplicate-methods.txt
Normal file
@ -0,0 +1 @@
|
||||
X was already defined on this methodmap
|
12
sourcepawn/compiler/tests/fail-method-on-array.sp
Normal file
12
sourcepawn/compiler/tests/fail-method-on-array.sp
Normal file
@ -0,0 +1,12 @@
|
||||
native CloseHandle(Handle:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
new Handle:x[2];
|
||||
|
||||
x.Close();
|
||||
}
|
1
sourcepawn/compiler/tests/fail-method-on-array.txt
Normal file
1
sourcepawn/compiler/tests/fail-method-on-array.txt
Normal file
@ -0,0 +1 @@
|
||||
cannot call methods on an array
|
10
sourcepawn/compiler/tests/fail-method-on-function.sp
Normal file
10
sourcepawn/compiler/tests/fail-method-on-function.sp
Normal file
@ -0,0 +1,10 @@
|
||||
native CloseHandle(Handle:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
main.Close();
|
||||
}
|
1
sourcepawn/compiler/tests/fail-method-on-function.txt
Normal file
1
sourcepawn/compiler/tests/fail-method-on-function.txt
Normal file
@ -0,0 +1 @@
|
||||
cannot call methods on a function
|
@ -0,0 +1,9 @@
|
||||
native CloseHandle(HandleEgg:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
}
|
@ -0,0 +1 @@
|
||||
method must have a first argument compatible with the methodmap type (Handle)
|
@ -0,0 +1,9 @@
|
||||
native CloseHandle({Handle, Egg}:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
}
|
@ -0,0 +1 @@
|
||||
method must have a first argument compatible with the methodmap type (Handle)
|
@ -0,0 +1,9 @@
|
||||
native CloseHandle(this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
}
|
@ -0,0 +1 @@
|
||||
method must have a first argument compatible with the methodmap type (Handle)
|
9
sourcepawn/compiler/tests/fail-ref-on-implicit-this.sp
Normal file
9
sourcepawn/compiler/tests/fail-ref-on-implicit-this.sp
Normal file
@ -0,0 +1,9 @@
|
||||
native CloseHandle(&Handle:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
}
|
1
sourcepawn/compiler/tests/fail-ref-on-implicit-this.txt
Normal file
1
sourcepawn/compiler/tests/fail-ref-on-implicit-this.txt
Normal file
@ -0,0 +1 @@
|
||||
method must have a first argument compatible with the methodmap type (Handle)
|
14
sourcepawn/compiler/tests/ok-base-type-as-thistag.sp
Normal file
14
sourcepawn/compiler/tests/ok-base-type-as-thistag.sp
Normal file
@ -0,0 +1,14 @@
|
||||
native CloseHandle(Handle:this);
|
||||
|
||||
methodmap Handle {
|
||||
};
|
||||
|
||||
methodmap Crab < Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
new Crab:x;
|
||||
x.Close();
|
||||
}
|
12
sourcepawn/compiler/tests/ok-ctor-dtor.sp
Normal file
12
sourcepawn/compiler/tests/ok-ctor-dtor.sp
Normal file
@ -0,0 +1,12 @@
|
||||
native Handle:CreateHandle(count);
|
||||
native CloseHandle(Handle:handle);
|
||||
|
||||
methodmap Handle {
|
||||
public Handle() = CreateHandle;
|
||||
public ~Handle() = CloseHandle;
|
||||
};
|
||||
|
||||
public main() {
|
||||
new Handle:handle = Handle(3);
|
||||
delete handle;
|
||||
}
|
14
sourcepawn/compiler/tests/ok-inheritance.sp
Normal file
14
sourcepawn/compiler/tests/ok-inheritance.sp
Normal file
@ -0,0 +1,14 @@
|
||||
native CloseHandle(Handle:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
methodmap Crab < Handle {
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
new Crab:x;
|
||||
x.Close();
|
||||
}
|
14
sourcepawn/compiler/tests/ok-method-on-const.sp
Normal file
14
sourcepawn/compiler/tests/ok-method-on-const.sp
Normal file
@ -0,0 +1,14 @@
|
||||
native CloseHandle(Handle:this);
|
||||
|
||||
enum Handle {
|
||||
INVALID_HANDLE = 0,
|
||||
};
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
INVALID_HANDLE.Close();
|
||||
}
|
16
sourcepawn/compiler/tests/ok-method-on-constref.sp
Normal file
16
sourcepawn/compiler/tests/ok-method-on-constref.sp
Normal file
@ -0,0 +1,16 @@
|
||||
native CloseHandle(Handle:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
f(const &Handle:x)
|
||||
{
|
||||
x.Close()
|
||||
}
|
||||
|
||||
public main()
|
||||
{
|
||||
new Handle:x;
|
||||
f(x)
|
||||
}
|
11
sourcepawn/compiler/tests/ok-method-on-element.sp
Normal file
11
sourcepawn/compiler/tests/ok-method-on-element.sp
Normal file
@ -0,0 +1,11 @@
|
||||
native CloseHandle(Handle:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
new Handle:x[2];
|
||||
x[1].Close();
|
||||
}
|
16
sourcepawn/compiler/tests/ok-method-on-ref.sp
Normal file
16
sourcepawn/compiler/tests/ok-method-on-ref.sp
Normal file
@ -0,0 +1,16 @@
|
||||
native CloseHandle(Handle:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
f(&Handle:x)
|
||||
{
|
||||
x.Close()
|
||||
}
|
||||
|
||||
public main()
|
||||
{
|
||||
new Handle:x;
|
||||
f(x)
|
||||
}
|
13
sourcepawn/compiler/tests/ok-method-on-scalar.sp
Normal file
13
sourcepawn/compiler/tests/ok-method-on-scalar.sp
Normal file
@ -0,0 +1,13 @@
|
||||
native CloneHandle(Handle:this);
|
||||
native CloseHandle(Handle:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Clone() = CloneHandle;
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
new Handle:x;
|
||||
x.Close();
|
||||
}
|
74
sourcepawn/compiler/tests/runtests.py
Normal file
74
sourcepawn/compiler/tests/runtests.py
Normal file
@ -0,0 +1,74 @@
|
||||
# vim: set ts=4 sw=4 tw=99 et:
|
||||
import os, sys
|
||||
import argparse
|
||||
import subprocess
|
||||
|
||||
def run_tests(args):
|
||||
testdir = os.path.dirname(os.path.abspath(__file__))
|
||||
tests = []
|
||||
for filename in os.listdir(testdir):
|
||||
base, ext = os.path.splitext(filename)
|
||||
if ext == '.sp':
|
||||
tests += [base]
|
||||
|
||||
failed = False
|
||||
|
||||
for test in tests:
|
||||
print('Testing {0}...'.format(test))
|
||||
if test.startswith('fail-'):
|
||||
kind = 'fail'
|
||||
elif test.startswith('warn-'):
|
||||
kind = 'warn'
|
||||
elif test.startswith('ok-'):
|
||||
kind = 'pass'
|
||||
|
||||
try:
|
||||
argv = [args.spcomp, os.path.join(testdir, test + '.sp')]
|
||||
p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdout, stderr = p.communicate()
|
||||
stdout = stdout.decode('utf-8')
|
||||
stderr = stderr.decode('utf-8')
|
||||
|
||||
smx_path = test + '.smx'
|
||||
compiled = os.path.exists(smx_path)
|
||||
if compiled:
|
||||
os.unlink(smx_path)
|
||||
|
||||
status = 'ok'
|
||||
if compiled and kind == 'fail':
|
||||
status = 'fail'
|
||||
elif not compiled and kind != 'fail':
|
||||
status = 'fail'
|
||||
|
||||
if status == 'ok' and kind != 'pass':
|
||||
with open(os.path.join(testdir, test + '.txt')) as fp:
|
||||
text = fp.read()
|
||||
if text not in stdout:
|
||||
print('Expected to find text in stdout: >>>')
|
||||
print(text)
|
||||
print('<<<')
|
||||
status = 'fail'
|
||||
|
||||
if status == 'fail':
|
||||
failed = True
|
||||
print('FAILED! Dumping stdout/stderr:')
|
||||
print(stdout)
|
||||
print(stderr)
|
||||
else:
|
||||
print('... OK!')
|
||||
|
||||
except Exception as exn:
|
||||
raise
|
||||
sys.stderr.write('FAILED! {0}\n'.format(exn.message))
|
||||
|
||||
if failed:
|
||||
sys.exit(1)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('spcomp', type=str, help='Path to spcomp')
|
||||
args = parser.parse_args()
|
||||
run_tests(args)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
15
sourcepawn/compiler/tests/warn-bad-upcast.sp
Normal file
15
sourcepawn/compiler/tests/warn-bad-upcast.sp
Normal file
@ -0,0 +1,15 @@
|
||||
native CloseHandle(Handle:this);
|
||||
|
||||
methodmap Handle {
|
||||
public Close() = CloseHandle;
|
||||
};
|
||||
|
||||
methodmap Crab {
|
||||
};
|
||||
|
||||
public main()
|
||||
{
|
||||
new Crab:x;
|
||||
new Handle:y;
|
||||
x = y;
|
||||
}
|
1
sourcepawn/compiler/tests/warn-bad-upcast.txt
Normal file
1
sourcepawn/compiler/tests/warn-bad-upcast.txt
Normal file
@ -0,0 +1 @@
|
||||
tag mismatch
|
Loading…
Reference in New Issue
Block a user