1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | internal AST_Parameters* parseParameters(Tokenizer* tokenizer) {
TemporaryPoolScope tempPool; // NOTE(Jake): Same as TemporaryPool in HH but immediately uses a g_allocator variable and resets when it goes out of scope
// Nobody would have more than 255 parameters in a function surely.
Array<Token> parameters(255, tempPool);
Array<Token> values(255, tempPool);
for (s32 parameterCount = 0;;++parameterCount)
{
Token left = getToken(tokenizer);
if (left.type == TOKEN_PAREN_CLOSE)
{
break;
}
if (!requireToken(left, TOKEN_IDENTIFIER))
{
return NULL;
}
if (!requireToken(tokenizer, TOKEN_EQUAL))
{
return NULL;
}
Token right = getToken(tokenizer);
if (!(right.type == TOKEN_IDENTIFIER
|| right.type == TOKEN_STRING))
{
lexError(right, "Parameter %d is invalid. Expected identifier or string, instead got '%*.*s'", parameterCount, right.length, right.length, right.data);
return NULL;
}
parameters.push(left);
values.push(right);
}
if (parameters.used == 0)
{
return NULL;
}
AST_Parameters* ast = pushStructCurrent(AST_Parameters);
ast->type = AST_PARAMETERS;
ast->values = pushArrayStructCurrent(Token, values.used);
ast->parameters = pushArrayStructCurrent(Token, parameters.used);
for(s32 i = 0; i < values.used; ++i)
{
ast->values[i] = values.data[i];
ast->parameters[i] = values.data[i];
}
return ast;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | StringLinkedList getFilesRecursive(String directory, Error* error)
{
wchar_t szBaseDir[MAX_PATH];
mbstowcs(szBaseDir, directory.data, MAX_PATH);
const u32 directoryLimit = 100;
wchar_t szDirectories[directoryLimit][MAX_PATH+10];
u32 directories = 0;
u32 files = 0;
StringCchCopy(szDirectories[directories++], MAX_PATH, szBaseDir);
StringLinkedList list = {};
while (directories > 0)
{
--directories;
wchar_t currentDirectory[MAX_PATH];
StringCchCopy(currentDirectory, MAX_PATH, szDirectories[directories]);
wchar_t currentDirectoryWSearch[MAX_PATH];
StringCchCopy(currentDirectoryWSearch, MAX_PATH, currentDirectory);
StringCchCat(currentDirectoryWSearch, MAX_PATH, TEXT("\\*"));
WIN32_FIND_DATA ffd;
HANDLE hFind = FindFirstFile(currentDirectoryWSearch, &ffd);
DWORD dLastError = GetLastError();
if (hFind == INVALID_HANDLE_VALUE || dLastError == ERROR_FILE_NOT_FOUND)
{
if (error)
{
if (dLastError == ERROR_FILE_NOT_FOUND)
{
error->errorCode = DIRECTORY_NO_FILES;
}
else
{
error->errorCode = DIRECTORY_INVALID_DIR;
}
}
StringLinkedList list_null = {};
return list_null;
}
do
{
if (wcscmp(ffd.cFileName, TEXT(".")) != 0 && wcscmp(ffd.cFileName, TEXT("..")) != 0)
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// Push this directory to be searched next iteration.
StringCchCopy(szDirectories[directories], MAX_PATH, currentDirectory);
StringCchCat(szDirectories[directories], MAX_PATH, TEXT("\\"));
StringCchCat(szDirectories[directories], MAX_PATH, ffd.cFileName);
++directories;
}
else
{
wchar_t filepath[MAX_PATH];
// todo(Jake): Check if .fel file
StringCchCopy(filepath, ArrayCount(filepath), currentDirectory);
StringCchCat(filepath, ArrayCount(filepath), TEXT("\\"));
StringCchCat(filepath, ArrayCount(filepath), ffd.cFileName);
String string = WcharToUTF8String(filepath);
list.add(string);
++files;
}
}
}
while (FindNextFile(hFind, &ffd) != 0);
FindClose(hFind);
}
return list;
inline String WcharToUTF8String(LPCWSTR string) {
String result = {};
u32 stringLength = wcslen(string);
result.length = WideCharToMultiByte(CP_UTF8, 0, string, stringLength, NULL, 0, NULL, NULL);
result.data = (char*)pushSizeCurrent(result.length + 1);
WideCharToMultiByte(CP_UTF8, 0, string, stringLength, result.data, result.length, NULL, NULL);
return result;
}
|
1 2 3 4 5 6 | struct Bucket
{
Item* items;
u32 count;
Bucket* next;
};
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | Bucket* Collect()
{
Bucket* result = Allocate(sizeof(Bucket));
const u32 MaxItemsPerBucket = 1024;
Bucket* current = result;
current->items = Allocate(MaxItemsPerBucket * sizeof(Item))
current->count = 0;
current->next = 0;
while (...more files...)
{
if (current->count == MaxItemsPerBucket)
{
Bucket* next = Allocate(sizeof(Bucket));
next->items = Allocate(MaxItemsPerBucket * sizeof(Item))
next->count = 0;
next->next = 0;
current->next = next;
current = next;
}
Item* item = current->items[current->count++];
item->name = ...;
item->whatever = ...;
}
return result;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 | ProcessItems(Bucket* bucket)
{
while (bucket)
{
for (u32 i=0; i<bucket->count; i++)
{
Item* item = bucket->items + i;
... do something with item ...
}
bucket = bucket->next;
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #define MAX_PARAMETER_COUNT 32
internal AST_Parameters* parseParameters(Tokenizer* tokenizer) {
Array<Token>* parameters = NULL;
Array<Token>* values = NULL;
for (s32 parameterCount = 0;;++parameterCount)
{
Token left = getToken(tokenizer);
if (left.type == TOKEN_PAREN_CLOSE)
{
break;
}
else if (left.type == TOKEN_COMMA)
{
// Get identifier
left = getToken(tokenizer);
}
if (!requireToken(left, TOKEN_IDENTIFIER))
{
return NULL;
}
if (!requireToken(tokenizer, TOKEN_EQUAL))
{
return NULL;
}
Token right = getToken(tokenizer);
if (!(right.type == TOKEN_IDENTIFIER
|| right.type == TOKEN_STRING))
{
lexError(right, "Parameter %d is invalid. Expected identifier or string, instead got '%*.*s'", parameterCount, right.length, right.length, right.data);
return NULL;
}
if (parameters == NULL && values == NULL)
{
parameters = Array<Token>::create(MAX_PARAMETER_COUNT);
values = Array<Token>::create(MAX_PARAMETER_COUNT);
}
if (parameters->used == parameters->size)
{
lexError(right, "Maximum allowed parameters for function or component is %d.", MAX_PARAMETER_COUNT);
return NULL;
}
parameters->push(left);
values->push(right);
}
if (parameters == NULL || values == NULL)
{
return NULL;
}
AST_Parameters* ast = pushStructCurrent(AST_Parameters);
ast->type = AST_PARAMETERS;
ast->values = values;
ast->parameters = parameters;
return ast;
}
#undef MAX_PARAMETER_COUNT
|