From 38beed5b74da03aaaaf0132e62ec21c1bc7f5944 Mon Sep 17 00:00:00 2001 From: Lance Date: Sat, 21 Mar 2026 06:54:10 +0800 Subject: [PATCH] chore: initial commit --- .gitignore | 36 +++ .idea/.gitignore | 10 + .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/editor.xml | 346 +++++++++++++++++++++++++++ .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/viridian.iml | 2 + CMakeLists.txt | 30 +++ src/common/vector.c | 3 + src/common/vector.h | 15 ++ src/main.c | 17 ++ src/parser/streams/file_stream.c | 44 ++++ src/parser/streams/file_stream.h | 7 + src/parser/streams/stream.c | 13 + src/parser/streams/stream.h | 21 ++ src/parser/tokenizer/parser.c | 39 +++ src/parser/tokenizer/parser.h | 15 ++ src/parser/tokenizer/tokens.h | 18 ++ 18 files changed, 636 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/editor.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/viridian.iml create mode 100644 CMakeLists.txt create mode 100644 src/common/vector.c create mode 100644 src/common/vector.h create mode 100644 src/main.c create mode 100644 src/parser/streams/file_stream.c create mode 100644 src/parser/streams/file_stream.h create mode 100644 src/parser/streams/stream.c create mode 100644 src/parser/streams/stream.h create mode 100644 src/parser/tokenizer/parser.c create mode 100644 src/parser/tokenizer/parser.h create mode 100644 src/parser/tokenizer/tokens.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..83562f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# CLion project files +.idea/workspace.xml +.idea/tasks.xml +.idea/dictionaries +.idea/vcs.xml +.idea/jsLibraryMappings.xml +cmake-build-*/ + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..2e29928 --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,346 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0b76fe5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..1001087 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/viridian.iml b/.idea/viridian.iml new file mode 100644 index 0000000..4c94235 --- /dev/null +++ b/.idea/viridian.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7c63332 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 4.1) +project(viridian C) + +set(CMAKE_C_STANDARD 17) +include(FetchContent) + +FetchContent_Declare( + SDL + GIT_REPOSITORY https://github.com/libsdl-org/SDL.git + GIT_TAG release-3.4.2 + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE +) +FetchContent_MakeAvailable(SDL) + + +add_executable(viridian src/main.c + src/parser/tokenizer/tokens.h + src/parser/streams/stream.h + src/parser/streams/file_stream.c + src/parser/streams/file_stream.h + src/parser/streams/stream.c + src/parser/tokenizer/parser.c + src/parser/tokenizer/parser.h + src/common/vector.c + src/common/vector.h) +target_link_libraries(viridian PRIVATE SDL3::SDL3) +target_include_directories(viridian PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}/src/common" +) \ No newline at end of file diff --git a/src/common/vector.c b/src/common/vector.c new file mode 100644 index 0000000..b9c5f37 --- /dev/null +++ b/src/common/vector.c @@ -0,0 +1,3 @@ +#include "vector.h" + +void \ No newline at end of file diff --git a/src/common/vector.h b/src/common/vector.h new file mode 100644 index 0000000..0579b54 --- /dev/null +++ b/src/common/vector.h @@ -0,0 +1,15 @@ +#ifndef VIRIDIAN_VECTOR_H +#define VIRIDIAN_VECTOR_H +#include + +typedef struct Vector Vector; +struct Vector { + char *data; + size_t size; + size_t capacity; +}; + +Vector* VectorCreate(size_t capacity); +void VectorPush(const Vector* vector, char c); + +#endif //VIRIDIAN_VECTOR_H \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..f31b633 --- /dev/null +++ b/src/main.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "parser/streams/file_stream.h" +#include "parser/streams/stream.h" +#include "parser/tokenizer/parser.h" +#include "parser/tokenizer/parser.h" + +int main(void) { + Stream *stream = CreateFileStream("sample.html"); + + ParseStream(stream); + + StreamClose(stream); + return 0; +} \ No newline at end of file diff --git a/src/parser/streams/file_stream.c b/src/parser/streams/file_stream.c new file mode 100644 index 0000000..ab68445 --- /dev/null +++ b/src/parser/streams/file_stream.c @@ -0,0 +1,44 @@ +#include +#include +#include "file_stream.h" +#include "stream.h" + +static ssize_t FileRead(const Stream *stream, void *buffer, const size_t count) { + FILE *file = stream->state; + const size_t bytes_read = fread(buffer, 1, count, file); + return bytes_read == 0 && ferror(file) ? -1 : (ssize_t) bytes_read; +} + +static ssize_t FileWrite(const Stream *stream, const void *buffer, const size_t count) { + FILE *file = stream->state; + const size_t bytes_written = fwrite(buffer, 1, count, file); + return bytes_written == 0 && ferror(file) ? -1 : (ssize_t) bytes_written; +} + +static void FileClose(const Stream *stream) { + FILE *file = stream->state; + fclose(file); +} + +static const StreamVTable FileStreamVTable = { + .read = FileRead, + .write = FileWrite, + .close = FileClose, +}; + +Stream* CreateFileStream(const char *path) { + FILE *file = fopen(path, "r+b"); + if (!file) { + return NULL; + } + + Stream *stream = malloc(sizeof(Stream)); + if (!stream) { + fclose(file); + return NULL; + } + + stream->vtable = &FileStreamVTable; + stream->state = file; + return stream; +} \ No newline at end of file diff --git a/src/parser/streams/file_stream.h b/src/parser/streams/file_stream.h new file mode 100644 index 0000000..8e45949 --- /dev/null +++ b/src/parser/streams/file_stream.h @@ -0,0 +1,7 @@ +#ifndef VIRIDIAN_FILE_STREAM_H +#define VIRIDIAN_FILE_STREAM_H +#include "stream.h" + +Stream* CreateFileStream(const char* path); + +#endif //VIRIDIAN_FILE_STREAM_H \ No newline at end of file diff --git a/src/parser/streams/stream.c b/src/parser/streams/stream.c new file mode 100644 index 0000000..d9eaf7a --- /dev/null +++ b/src/parser/streams/stream.c @@ -0,0 +1,13 @@ +#include "stream.h" + +ssize_t StreamRead(const Stream *stream, void *buffer, const size_t count) { + return stream->vtable->read(stream, buffer, count); +} + +ssize_t StreamWrite(const Stream *stream, const void *buffer, const size_t count) { + return stream->vtable->write(stream, buffer, count); +} + +void StreamClose(const Stream *stream) { + stream->vtable->close(stream); +} \ No newline at end of file diff --git a/src/parser/streams/stream.h b/src/parser/streams/stream.h new file mode 100644 index 0000000..4a7ed0f --- /dev/null +++ b/src/parser/streams/stream.h @@ -0,0 +1,21 @@ +#ifndef VIRIDIAN_STREAM_H +#define VIRIDIAN_STREAM_H +#include + +typedef struct StreamVTable StreamVTable; +typedef struct Stream Stream; +struct StreamVTable { + ssize_t (*read)(const Stream *stream, void *buffer, size_t count); + ssize_t (*write)(const Stream *stream, const void *buffer, size_t count); + void (*close)(const Stream *stream); +}; +struct Stream { + const StreamVTable *vtable; + void *state; +}; + +ssize_t StreamRead(const Stream *stream, void *buffer, size_t count); +ssize_t StreamWrite(const Stream *stream, const void *buffer, size_t count); +void StreamClose(const Stream *stream); + +#endif //VIRIDIAN_STREAM_H \ No newline at end of file diff --git a/src/parser/tokenizer/parser.c b/src/parser/tokenizer/parser.c new file mode 100644 index 0000000..7445ed4 --- /dev/null +++ b/src/parser/tokenizer/parser.c @@ -0,0 +1,39 @@ +#include "parser.h" + +#include +#include +#include + +typedef enum { + SCANNING_FOR_TOKENS, + IN_DECLARATION, + IN_TAG_START, + IN_TAG_END, + IN_DATA, +} ParserState; + +ParserResult ParseStream(const Stream *stream) { + ParserResult result = { + .tokens = NULL, + .length = 0, + }; + const size_t BUFFER_SIZE = 16; + char *read_buffer = malloc(BUFFER_SIZE); + + ssize_t read_bytes; + size_t buffer_read_count = 0; + ParserState state = SCANNING_FOR_TOKENS; + while ((read_bytes = StreamRead(stream, read_buffer, BUFFER_SIZE)) > 0) { + assert(read_bytes <= BUFFER_SIZE); + printf("read_bytes = %zu\n", read_bytes); + printf("[%lu] ", buffer_read_count); + for (size_t i = 0; i < read_bytes; i++) { + printf("%c", read_buffer[i]); + } + printf("\n"); + buffer_read_count++; + } + + free(read_buffer); + return result; +} diff --git a/src/parser/tokenizer/parser.h b/src/parser/tokenizer/parser.h new file mode 100644 index 0000000..a9c4878 --- /dev/null +++ b/src/parser/tokenizer/parser.h @@ -0,0 +1,15 @@ +#ifndef VIRIDIAN_PARSER_H +#define VIRIDIAN_PARSER_H +#include +#include "tokens.h" +#include "../streams/stream.h" + +typedef struct ParserResult ParserResult; +struct ParserResult { + Token *tokens; + size_t length; +}; + +ParserResult ParseStream(const Stream *stream); + +#endif //VIRIDIAN_PARSER_H \ No newline at end of file diff --git a/src/parser/tokenizer/tokens.h b/src/parser/tokenizer/tokens.h new file mode 100644 index 0000000..a5b8350 --- /dev/null +++ b/src/parser/tokenizer/tokens.h @@ -0,0 +1,18 @@ +#ifndef VIRIDIAN_TOKENS_H +#define VIRIDIAN_TOKENS_H + +typedef enum { + META_DECLARATION, // + TAG_START, // + TAG_END, // + DATA, +} TokenType; + +typedef struct Token Token; +struct Token { + TokenType type; + const char *content; + size_t content_size; +}; + +#endif \ No newline at end of file