diff --git a/error.c b/error.c index 98a3af7..453c1c9 100644 --- a/error.c +++ b/error.c @@ -181,6 +181,7 @@ static struct { ERR_SPECIAL_RANGE, "Line specials with values higher than 255 require #nocompact." }, { ERR_EVENT_NEEDS_3_ARG, "Event scripts must have 3 arguments." }, // [BB] { ERR_LIBRARY_NOT_FIRST, "#library must come before anything else." }, + { ERR_TEXT, "%s" }, { ERR_NONE, NULL } }; diff --git a/error.h b/error.h index d7e696b..7c6e8ed 100644 --- a/error.h +++ b/error.h @@ -20,6 +20,7 @@ typedef enum { ERR_NONE = 0, + ERR_TEXT = 1, ERR_NO_SYMBOL_MEM = 10, ERR_IDENTIFIER_TOO_LONG, ERR_STRING_TOO_LONG, diff --git a/parse.c b/parse.c index 7a926da..fdf94a5 100644 --- a/parse.c +++ b/parse.c @@ -73,6 +73,19 @@ typedef struct prefunc_s char *source; } prefunc_t; +typedef struct label_s +{ + char name[32]; + int addr; +} label_t; + +typedef struct goto_s +{ + struct label_s *lptr; + int addr; + int line; +} goto_t; + // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -157,6 +170,9 @@ static void UnspeculateFunction(symbolNode_t *sym); static void AddScriptFuncRef(symbolNode_t *sym, int address, int argcount); static void CheckForUndefinedFunctions(void); static void SkipBraceBlock(int depth); +static void DoLabel(void); +static void DoGoto(void); +static void ChkUndefGotos(void); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- @@ -194,6 +210,10 @@ static symbolNode_t *InsideFunction; static prefunc_t *FillinFunctions; static prefunc_t **FillinFunctionsLatest = &FillinFunctions; static boolean ArrayHasStrings; +static label_t Labels[256]; +static goto_t Gotos[1024]; +static int lCount; +static int gCount; static int AdjustStmtLevel[] = { @@ -787,6 +807,8 @@ static void OuterScript(void) CountScript(scriptType); PC_AddScript(scriptNumber, scriptType, scriptFlags, ScriptVarCount); pc_LastAppendedCommand = PCD_NOP; + lCount = 0; + gCount = 0; if(ProcessStatement(STMT_SCRIPT) == NO) { ERR_Error(ERR_INVALID_STATEMENT, YES); @@ -797,6 +819,7 @@ static void OuterScript(void) } PC_SetScriptVarCount(scriptNumber, scriptType, ScriptVarCount, ScriptArrayCount, ScriptArraySize); pa_ScriptCount++; + ChkUndefGotos(); } //========================================================================== @@ -964,6 +987,8 @@ static void OuterFunction(void) TK_TokenMustBe(TK_LBRACE, ERR_MISSING_LBRACE); TK_NextToken(); + lCount = 0; + gCount = 0; do {} while(ProcessStatement(STMT_SCRIPT) == YES); if(pc_LastAppendedCommand != PCD_RETURNVOID && @@ -986,6 +1011,7 @@ static void OuterFunction(void) PC_AddFunction(sym, ScriptArrayCount, ScriptArraySize); UnspeculateFunction(sym); InsideFunction = NULL; + ChkUndefGotos(); } //========================================================================== @@ -1361,6 +1387,14 @@ static boolean ProcessStatement(statement_t owner) case TK_IDENTIFIER: LeadingIdentifier(); break; + case TK_LABEL: + DoLabel(); + TK_NextToken(); + break; + case TK_GOTO: + DoGoto(); + TK_NextToken(); + break; case TK_PRINT: case TK_PRINTBOLD: case TK_LOG: @@ -4843,3 +4877,105 @@ void SkipBraceBlock(int depth) } } while (depth > 0); } + +// Borg +// GOTO support + +static void DoLabel(void) +{ +label_t *lptr; +int i; + +for(i=0;iaddr,Gotos[i].addr); + } + return; + } +if(lCount>255) + { + ERR_Error(ERR_TEXT,YES,"Too many labels defined."); + return; + } +i=lCount++; +strcpy(Labels[i].name,tk_String); +Labels[i].addr=pc_Address; +} + +static void DoGoto(void) +{ +label_t *lptr; +int i; + +TK_NextTokenMustBe(TK_IDENTIFIER,ERR_INVALID_IDENTIFIER); +for(i=0;i255) + { + ERR_Error(ERR_TEXT,YES,"Too many labels defined."); + return; + } +i=lCount++; +strcpy(Labels[i].name,tk_String); +Labels[i].addr=-1; +no_addr: +lptr=&Labels[i]; +if(gCount>1023) + { + ERR_Error(ERR_TEXT,YES,"Too many goto jumps."); + return; + } +i=gCount++; +Gotos[i].lptr=lptr; +Gotos[i].line=tk_Line; +PC_AppendCmd(PCD_GOTO); +Gotos[i].addr=pc_Address; +PC_SkipInt(); +TK_NextTokenMustBe(TK_SEMICOLON,ERR_MISSING_SEMICOLON); +} + +void ChkUndefGotos(void) +{ +int i; +char ok=1; + +for(i=0;i