Skip to content

Commit a20228d

Browse files
Merge pull request #41 from themuffinator/codex/implement-script-management-functions-in-l_script.c
Wrap scripts around precompiled sources
2 parents b2b21ab + 6c04ec2 commit a20228d

File tree

2 files changed

+277
-66
lines changed

2 files changed

+277
-66
lines changed

src/botlib/precomp/l_script.c

Lines changed: 275 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ typedef enum { qfalse = 0, qtrue = 1 } qboolean;
6161
#define Q_stricmp strcasecmp
6262
#define Log_Write BotLib_LogWrite
6363

64+
extern int PC_ExpectTokenString(pc_source_t *source, char *string);
65+
extern int PC_ExpectTokenType(pc_source_t *source, int type, int subtype, pc_token_t *token);
66+
extern int PC_ExpectAnyToken(pc_source_t *source, pc_token_t *token);
67+
6468
static void PS_AppendDiagnostic(pc_script_t *script,
6569
pc_error_level_t level,
6670
const char *message)
@@ -133,6 +137,81 @@ static void PS_ReportDiagnostic(pc_script_t *script,
133137
PS_AppendDiagnostic(script, level, text);
134138
}
135139

140+
static void PS_SyncDiagnosticsFromSource(pc_script_t *script)
141+
{
142+
if (script == NULL || script->source == NULL)
143+
{
144+
return;
145+
}
146+
147+
const pc_diagnostic_t *head = PC_GetDiagnostics(script->source);
148+
const pc_diagnostic_t *cursor = head;
149+
if (script->last_source_diagnostic != NULL)
150+
{
151+
cursor = script->last_source_diagnostic->next;
152+
}
153+
154+
int saved_line = script->line;
155+
while (cursor != NULL)
156+
{
157+
script->line = cursor->line;
158+
PS_AppendDiagnostic(script, cursor->level, cursor->message);
159+
script->last_source_diagnostic = cursor;
160+
cursor = cursor->next;
161+
}
162+
script->line = saved_line;
163+
}
164+
165+
pc_script_t *PS_CreateScriptFromSource(pc_source_t *source)
166+
{
167+
if (source == NULL)
168+
{
169+
return NULL;
170+
}
171+
172+
pc_script_t *script = (pc_script_t *)calloc(1, sizeof(pc_script_t));
173+
if (script == NULL)
174+
{
175+
BotLib_Print(PRT_FATAL, "PS_CreateScriptFromSource: out of memory\n");
176+
return NULL;
177+
}
178+
179+
script->source = source;
180+
script->line = 1;
181+
script->lastline = 1;
182+
script->tokenavailable = 0;
183+
script->diagnostics = NULL;
184+
script->diagnostics_tail = NULL;
185+
script->last_source_diagnostic = NULL;
186+
script->punctuations = default_punctuations;
187+
188+
PS_SyncDiagnosticsFromSource(script);
189+
190+
return script;
191+
}
192+
193+
void PS_FreeScript(pc_script_t *script)
194+
{
195+
if (script == NULL)
196+
{
197+
return;
198+
}
199+
200+
pc_diagnostic_t *diag = script->diagnostics;
201+
while (diag != NULL)
202+
{
203+
pc_diagnostic_t *next = diag->next;
204+
if (diag->message != NULL)
205+
{
206+
free((void *)diag->message);
207+
}
208+
free(diag);
209+
diag = next;
210+
}
211+
212+
free(script);
213+
}
214+
136215
static int COM_Compress(char *data_p)
137216
{
138217
if (data_p == NULL)
@@ -985,11 +1064,45 @@ int PS_ReadPrimitive(pc_script_t *script, pc_token_t *token)
9851064
//============================================================================
9861065
int PS_ReadToken(pc_script_t *script, pc_token_t *token)
9871066
{
988-
//if there is a token available (from UnreadToken)
989-
if (script->tokenavailable)
990-
{
991-
script->tokenavailable = 0;
992-
memcpy(token, &script->token, sizeof(pc_token_t));
1067+
if (script == NULL || token == NULL)
1068+
{
1069+
return 0;
1070+
}
1071+
1072+
if (script->source != NULL)
1073+
{
1074+
if (script->tokenavailable)
1075+
{
1076+
script->tokenavailable = 0;
1077+
memcpy(token, &script->token, sizeof(pc_token_t));
1078+
return 1;
1079+
}
1080+
1081+
script->lastline = script->line;
1082+
int result = PC_ReadToken(script->source, token);
1083+
PS_SyncDiagnosticsFromSource(script);
1084+
if (!result)
1085+
{
1086+
return 0;
1087+
}
1088+
1089+
if (token->linescrossed > 0)
1090+
{
1091+
script->lastline = token->line - token->linescrossed;
1092+
}
1093+
script->line = token->line;
1094+
memcpy(&script->token, token, sizeof(pc_token_t));
1095+
script->tokenavailable = 0;
1096+
script->whitespace_p = NULL;
1097+
script->endwhitespace_p = NULL;
1098+
return 1;
1099+
}
1100+
1101+
//if there is a token available (from UnreadToken)
1102+
if (script->tokenavailable)
1103+
{
1104+
script->tokenavailable = 0;
1105+
memcpy(token, &script->token, sizeof(pc_token_t));
9931106
return 1;
9941107
} //end if
9951108
//save script pointer
@@ -1057,22 +1170,47 @@ int PS_ReadToken(pc_script_t *script, pc_token_t *token)
10571170
// Returns: -
10581171
// Changes Globals: -
10591172
//============================================================================
1060-
int PS_ExpectTokenString(pc_script_t *script, char *string)
1173+
int PS_ExpectTokenString(pc_script_t *script, const char *string)
10611174
{
1062-
pc_token_t token;
1175+
if (script == NULL || string == NULL)
1176+
{
1177+
return 0;
1178+
}
10631179

1064-
if (!PS_ReadToken(script, &token))
1065-
{
1066-
ScriptError(script, "couldn't find expected %s", string);
1067-
return 0;
1068-
} //end if
1180+
if (script->source != NULL)
1181+
{
1182+
pc_token_t peek;
1183+
int has_peek = PC_PeekToken(script->source, &peek);
1184+
int result = PC_ExpectTokenString(script->source, (char *)string);
1185+
PS_SyncDiagnosticsFromSource(script);
1186+
if (has_peek)
1187+
{
1188+
script->lastline = script->line;
1189+
if (peek.linescrossed > 0)
1190+
{
1191+
script->lastline = peek.line - peek.linescrossed;
1192+
}
1193+
script->line = peek.line;
1194+
memcpy(&script->token, &peek, sizeof(pc_token_t));
1195+
script->tokenavailable = 0;
1196+
}
1197+
return result != 0;
1198+
}
10691199

1070-
if (strcmp(token.string, string))
1071-
{
1072-
ScriptError(script, "expected %s, found %s", string, token.string);
1073-
return 0;
1074-
} //end if
1075-
return 1;
1200+
pc_token_t token;
1201+
1202+
if (!PS_ReadToken(script, &token))
1203+
{
1204+
ScriptError(script, "couldn't find expected %s", string);
1205+
return 0;
1206+
} //end if
1207+
1208+
if (strcmp(token.string, string))
1209+
{
1210+
ScriptError(script, "expected %s, found %s", string, token.string);
1211+
return 0;
1212+
} //end if
1213+
return 1;
10761214
} //end of the function PS_ExpectToken
10771215
//============================================================================
10781216
//
@@ -1082,55 +1220,81 @@ int PS_ExpectTokenString(pc_script_t *script, char *string)
10821220
//============================================================================
10831221
int PS_ExpectTokenType(pc_script_t *script, int type, int subtype, pc_token_t *token)
10841222
{
1085-
char str[MAX_TOKEN];
1223+
if (script == NULL)
1224+
{
1225+
return 0;
1226+
}
10861227

1087-
if (!PS_ReadToken(script, token))
1088-
{
1089-
ScriptError(script, "couldn't read expected token");
1090-
return 0;
1091-
} //end if
1228+
if (script->source != NULL)
1229+
{
1230+
pc_token_t local;
1231+
if (token == NULL)
1232+
{
1233+
memset(&local, 0, sizeof(local));
1234+
token = &local;
1235+
}
1236+
int result = PC_ExpectTokenType(script->source, type, subtype, token);
1237+
PS_SyncDiagnosticsFromSource(script);
1238+
script->lastline = script->line;
1239+
if (token->linescrossed > 0)
1240+
{
1241+
script->lastline = token->line - token->linescrossed;
1242+
}
1243+
script->line = token->line;
1244+
memcpy(&script->token, token, sizeof(pc_token_t));
1245+
script->tokenavailable = 0;
1246+
return result != 0;
1247+
}
10921248

1093-
if (token->type != type)
1094-
{
1095-
if (type == TT_STRING) strcpy(str, "string");
1096-
if (type == TT_LITERAL) strcpy(str, "literal");
1097-
if (type == TT_NUMBER) strcpy(str, "number");
1098-
if (type == TT_NAME) strcpy(str, "name");
1099-
if (type == TT_PUNCTUATION) strcpy(str, "punctuation");
1100-
ScriptError(script, "expected a %s, found %s", str, token->string);
1101-
return 0;
1102-
} //end if
1103-
if (token->type == TT_NUMBER)
1104-
{
1105-
if ((token->subtype & subtype) != subtype)
1106-
{
1107-
if (subtype & TT_DECIMAL) strcpy(str, "decimal");
1108-
if (subtype & TT_HEX) strcpy(str, "hex");
1109-
if (subtype & TT_OCTAL) strcpy(str, "octal");
1110-
if (subtype & TT_BINARY) strcpy(str, "binary");
1111-
if (subtype & TT_LONG) strcat(str, " long");
1112-
if (subtype & TT_UNSIGNED) strcat(str, " unsigned");
1113-
if (subtype & TT_FLOAT) strcat(str, " float");
1114-
if (subtype & TT_INTEGER) strcat(str, " integer");
1115-
ScriptError(script, "expected %s, found %s", str, token->string);
1116-
return 0;
1117-
} //end if
1118-
} //end if
1119-
else if (token->type == TT_PUNCTUATION)
1120-
{
1121-
if (subtype < 0)
1122-
{
1123-
ScriptError(script, "BUG: wrong punctuation subtype");
1124-
return 0;
1125-
} //end if
1126-
if (token->subtype != subtype)
1127-
{
1128-
ScriptError(script, "expected %s, found %s",
1129-
script->punctuations[subtype], token->string);
1130-
return 0;
1131-
} //end if
1132-
} //end else if
1133-
return 1;
1249+
char str[MAX_TOKEN];
1250+
1251+
if (!PS_ReadToken(script, token))
1252+
{
1253+
ScriptError(script, "couldn't read expected token");
1254+
return 0;
1255+
} //end if
1256+
1257+
if (token->type != type)
1258+
{
1259+
if (type == TT_STRING) strcpy(str, "string");
1260+
if (type == TT_LITERAL) strcpy(str, "literal");
1261+
if (type == TT_NUMBER) strcpy(str, "number");
1262+
if (type == TT_NAME) strcpy(str, "name");
1263+
if (type == TT_PUNCTUATION) strcpy(str, "punctuation");
1264+
ScriptError(script, "expected a %s, found %s", str, token->string);
1265+
return 0;
1266+
} //end if
1267+
if (token->type == TT_NUMBER)
1268+
{
1269+
if ((token->subtype & subtype) != subtype)
1270+
{
1271+
if (subtype & TT_DECIMAL) strcpy(str, "decimal");
1272+
if (subtype & TT_HEX) strcpy(str, "hex");
1273+
if (subtype & TT_OCTAL) strcpy(str, "octal");
1274+
if (subtype & TT_BINARY) strcpy(str, "binary");
1275+
if (subtype & TT_LONG) strcat(str, " long");
1276+
if (subtype & TT_UNSIGNED) strcat(str, " unsigned");
1277+
if (subtype & TT_FLOAT) strcat(str, " float");
1278+
if (subtype & TT_INTEGER) strcat(str, " integer");
1279+
ScriptError(script, "expected %s, found %s", str, token->string);
1280+
return 0;
1281+
} //end if
1282+
} //end if
1283+
else if (token->type == TT_PUNCTUATION)
1284+
{
1285+
if (subtype < 0)
1286+
{
1287+
ScriptError(script, "BUG: wrong punctuation subtype");
1288+
return 0;
1289+
} //end if
1290+
if (token->subtype != subtype)
1291+
{
1292+
ScriptError(script, "expected %s, found %s",
1293+
script->punctuations[subtype], token->string);
1294+
return 0;
1295+
} //end if
1296+
} //end else if
1297+
return 1;
11341298
} //end of the function PS_ExpectTokenType
11351299
//============================================================================
11361300
//
@@ -1195,8 +1359,53 @@ int PS_CheckTokenType(pc_script_t *script, int type, int subtype, pc_token_t *to
11951359
// Returns: -
11961360
// Changes Globals: -
11971361
//============================================================================
1198-
int PS_SkipUntilString(pc_script_t *script, char *string)
1362+
int PS_SkipUntilString(pc_script_t *script, const char *string)
11991363
{
1364+
if (script == NULL || string == NULL)
1365+
{
1366+
return 0;
1367+
}
1368+
1369+
if (script->source != NULL)
1370+
{
1371+
pc_token_t token;
1372+
while (PC_PeekToken(script->source, &token))
1373+
{
1374+
if (!strcmp(token.string, string))
1375+
{
1376+
int result = PC_ExpectTokenString(script->source, (char *)string);
1377+
PS_SyncDiagnosticsFromSource(script);
1378+
script->lastline = script->line;
1379+
if (token.linescrossed > 0)
1380+
{
1381+
script->lastline = token.line - token.linescrossed;
1382+
}
1383+
script->line = token.line;
1384+
memcpy(&script->token, &token, sizeof(pc_token_t));
1385+
script->tokenavailable = 0;
1386+
return result != 0;
1387+
}
1388+
1389+
if (!PC_ExpectAnyToken(script->source, &token))
1390+
{
1391+
PS_SyncDiagnosticsFromSource(script);
1392+
return 0;
1393+
}
1394+
1395+
PS_SyncDiagnosticsFromSource(script);
1396+
script->lastline = script->line;
1397+
if (token.linescrossed > 0)
1398+
{
1399+
script->lastline = token.line - token.linescrossed;
1400+
}
1401+
script->line = token.line;
1402+
memcpy(&script->token, &token, sizeof(pc_token_t));
1403+
script->tokenavailable = 0;
1404+
}
1405+
PS_SyncDiagnosticsFromSource(script);
1406+
return 0;
1407+
}
1408+
12001409
pc_token_t token;
12011410

12021411
while(PS_ReadToken(script, &token))

src/botlib/precomp/l_script.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,9 @@ typedef struct pc_script_s {
162162
const pc_punctuation_t **punctuationtable;
163163
pc_diagnostic_t *diagnostics;
164164
pc_diagnostic_t *diagnostics_tail;
165+
const pc_diagnostic_t *last_source_diagnostic;
165166
pc_token_t token;
167+
pc_source_t *source;
166168
struct pc_script_s *next;
167169
} pc_script_t;
168170

0 commit comments

Comments
 (0)