You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
5.1 KiB
C

#include <stdio.h>
#pragma warning(disable : 4820) // don't care about padding
#pragma warning(disable : 4388) // signed/unsigned mismatch probably doesn't matter
// #pragma warning(disable : 4100) // unused local doesn't matter, because sometimes I want to kee
#pragma warning(disable : 4053) // void operands are used for tricks like applying printf linting to non printf function calls
#pragma warning(disable : 4255) // strange no function prototype given thing?
#pragma warning(disable : 4456) // I shadow local declarations often and it's fine
#pragma warning(disable : 4061) // I don't need to *explicitly* handle everything, having a default: case should mean no more warnings
#pragma warning(disable : 4201) // nameless struct/union occurs
#pragma warning(disable : 4366) // I think unaligned memory addresses are fine to ignore
#pragma warning(disable : 4459) // Local function decl hiding global declaration I think is fine
#pragma warning(disable : 5045) // spectre mitigation??
#pragma warning(disable : 4244) // loss of data warning
#pragma warning(disable : 4101) // unreferenced local variable
#pragma warning(disable : 4100) // unreferenced local variable again?
#pragma warning(disable : 4189) // initialized and not referenced
#pragma warning(disable : 4242) // conversion
#pragma warning(disable : 4457) // hiding function variable happens
#pragma warning(disable : 4668) // __GNU_C__ macro undefined, fixing
#pragma warning(disable : 4996) // fopen is safe. I don't care about fopen_s
#include "md.h"
#include "md.c"
#define DESKTOP
#define WINDOWS
#define RND_IMPLEMENTATION
#include "makeprompt.h"
#include <windows.h> // for sleep.
typedef struct Error {
struct Error *next, *prev;
String8 message;
int line;
} Error;
typedef struct ErrorList {
int count;
Error *first, *last;
} ErrorList;
void ErrorPush(Arena *arena, ErrorList *list, Error message)
{
Error *new_err = PushArrayZero(arena, Error, 1);
*new_err = message;
QueuePush(list->first, list->last, new_err);
list->count += 1;
}
void error_impl(Arena *arena, ErrorList *errors, int line_in_toparse, String8 message)
{
ErrorPush(arena, errors, (Error){.line = line_in_toparse, .message = message});
// this is a function so you can breakpoint here and discover when errors occur
}
#define error(line_in_toparse, fmt_str, ...) error_impl(arena, errors, line_in_toparse, S8Fmt(arena, fmt_str, __VA_ARGS__))
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
Arena *arena = ArenaAlloc();
Sleep(200); // have to wait for console to pop up, super annoying
// Prose is the name for this file format where you describe the souls of characters
// tokenize
typedef struct ProseToken
{
struct ProseToken *next, *prev;
String8 field;
int field_number; // this is -1 if no field_number, e.g if 'Field Text #0:' isn't specified and had no '#', then this would be -1
String8 value; // may be an empty string, if it's trying to be like, an object
int indentation;
int line;
} ProseToken;
ErrorList errors_lit = {0};
ErrorList *errors = &errors_lit;
Npc out = {0};
// all arena allocations done from here are temporary. As it just copies data into Npc
// parse 'playground.txt' into 'out'
{
// read the file
String8 to_parse = LoadEntireFile(arena, S8Lit("playground.txt"));
// tokenize to_parse
ProseToken *tokenized_first = 0;
ProseToken *tokenized_last = 0;
{
String8List as_lines = S8Split(arena, to_parse, 1, &S8Lit("\n"));
int line = 1; // lines start at 1
for (String8Node *cur = as_lines.first; cur; cur = cur->next)
{
int indentation = 0;
while(indentation < cur->string.size && cur->string.str[indentation] == '\t') indentation += 1;
String8 no_funny_business = S8SkipWhitespace(S8ChopWhitespace(cur->string));
if(no_funny_business.size == 0) continue;
String8List along_colon = S8Split(arena, no_funny_business, 1, &S8Lit(":"));
if(along_colon.node_count != 2 && along_colon.node_count != 1) {
error(line, "Requires exactly one ':' on the line to delimit the field and value. Got %d", along_colon.node_count - 1);
} else {
ProseToken *token_out = PushArrayZero(arena, ProseToken, 1);
token_out->field_number = -1;
if(along_colon.node_count == 2)
token_out->value = along_colon.last->string;
token_out->line = line;
token_out->indentation = indentation;
DblPushBack(tokenized_first, tokenized_last, token_out);
}
line += 1;
}
}
}
if (errors->count > 0)
{
printf("Failed with errors:\n");
for (Error *cur = errors->first; cur; cur = cur->next)
{
printf("On line %d of input: %.*s\n", cur->line, S8VArg(cur->message));
}
assert(false);
}
printf("Success.\n");
__debugbreak();
}