diff --git a/Headers/Assembler/SagittariusAssembler.h b/Headers/Assembler/SagittariusAssembler.h index 7892055..2608712 100644 --- a/Headers/Assembler/SagittariusAssembler.h +++ b/Headers/Assembler/SagittariusAssembler.h @@ -62,6 +62,9 @@ */ typedef struct Sag_Str{ char* head; + char* file; + uint64_t line; + uint64_t col; // The column where the string starts, counting from 0. This is used for error reporting and debugging purposes. uint64_t start; uint64_t length; } Sag_Str; diff --git a/Headers/SagittariusC/SagittariusC.h b/Headers/SagittariusC/SagittariusC.h new file mode 100644 index 0000000..9a223ea --- /dev/null +++ b/Headers/SagittariusC/SagittariusC.h @@ -0,0 +1,135 @@ +#ifndef __SAGITTARIUS_C_H_ +#define __SAGITTARIUS_C_H_ + +#include "../Sagittarius.h" +#include +#include "../Assembler/SagittariusAssembler.h" + +/** + * Workflow for Sagittarius C compiler: + * + * Scan -> Parse -> Finalize -> Generate Assembly -> Assemble to Program + * + * Finalize tree will perform type checking, name resolution, and other necessary checks and transformations to ensure the tree is ready for code generation. The finalized tree will be used for both generating assembly. + * + * + * This flavor of C is designed to be simple and easy to compile, and it may not support all features of standard C. + * The main purpose of this compiler is to provide a convenient way for developers to write code for Sagittarius VM, and it may have some limitations compared to a full-featured C compiler. + * + * It also supports a simple module system, where you can include other C files as modules. The included files will be compiled together with the main file, and they can share the same namespaces and symbols. + * + * It have no separate function declaration and definition, and all functions don't need to be defined before they are used. + * + * It should also support generic types. + * + * Sample Sagittarius C code: + * + * import sys; + * namespace sample{ + * T add(T a, T b){ + * return a + b; + * } + * void main(){ + * int x = add(1, 2); + * } + * } + * + */ + +typedef struct SagittariusC_SyntaxNode +{ + uint64_t type; + void *data; +} SagittariusC_SyntaxNode; + +typedef struct SagittariusC_SyntaxNode_Root +{ + SagittariusC_SyntaxNode *Children; + uint64_t ChildCount; +} SagittariusC_SyntaxNode_Root; + +typedef struct SagittariusC_SyntaxNode_Namespace +{ + Sag_Str *Name; + SagittariusC_SyntaxNode *Children; + uint64_t ChildCount; +} SagittariusC_SyntaxNode_Namespace; + +typedef struct SagittariusC_SyntaxNode_Import +{ + Sag_Str *namespace; +} SagittariusC_SyntaxNode_Import; + +typedef struct SagittariusC_SyntaxNode_Expression +{ + void *real_expression_node; +} SagittariusC_SyntaxNode_Expression; + +typedef enum SagittariusC_SyntaxNodeType +{ + sag_c_node_root, + sag_c_node_import, + sag_c_node_namespace, + sag_c_node_expression, + sag_c_node_expression_value, + sag_c_node_expression_variable, + sag_c_node_expression_call, + sag_c_node_expression_syscall, + sag_c_node_expression_binary_op, + sag_c_node_expression_unary_op, + sag_c_node_control_if, + sag_c_node_control_while, + sag_c_node_control_for, + sag_c_node_control_return, + sag_c_node_control_break, + sag_c_node_control_continue, + sag_c_node_control_block, + sag_c_node_declaration_variable, + sag_c_node_declaration_function, + sag_c_node_control_switch, + sag_c_node_control_case, + sag_c_node_declaration_struct, + sag_c_node_declaration_enum, + sag_c_node_typedef, + sag_c_node_declaration_function_parameter, + sag_c_node_declaration_function_type, + /** + * asm node is a special node that can be used as a replacement for return statement for a function have return value. + */ + sag_c_node_asm, +} SagittariusC_SyntaxNodeType; +typedef struct SagittariusC_Config +{ + char **include_paths; + uint64_t include_path_count; + char *output_file; + char *temp_dir; + char *assembler_path; + bool obj_only; +} SagittariusC_Config; +typedef struct SagittariusC_Tree_Cache{ + SagittariusC_SyntaxNode_Root **root; + int64_t *ref_count; +} SagittariusC_Tree_Cache; +typedef struct SagittariusC_Segment +{ + Sag_Str *content; + /** + * Null for the first segment, and points to the previous segment for non-first segments. The segments are linked in a doubly linked list manner, and the head and tail of the list are stored in the assembler struct for easy access. + */ + struct SagittariusC_Segment *prev; + /** + * Null for end of segments, and points to the next segment for non-end segments. The segments are linked in a doubly linked list manner, and the head and tail of the list are stored in the assembler struct for easy access. + */ + struct SagittariusC_Segment *next; +} SagittariusC_Segment; +SAGITTARIUS_API bool sagittarius_c_scan_segments(FILE *f, SagittariusC_Segment **out_head); +SAGITTARIUS_API bool sagittarius_c_parse_segments(SagittariusC_Segment *head, SagittariusC_SyntaxNode_Root *out_root); +/** + * By writing the tree to a file, the file is called an object file. + */ +SAGITTARIUS_API bool sagittarius_c_write_tree(SagittariusC_SyntaxNode_Root *root, FILE *f); +SAGITTARIUS_API bool sagittarius_c_compile_tree(SagittariusC_SyntaxNode_Root *root, SagittariusC_Config *config, SagittariusC_SyntaxNode_Root *finalized_root); +SAGITTARIUS_API bool sagittarius_c_tree_to_assembly(SagittariusC_SyntaxNode_Root *root, FILE *f); +SAGITTARIUS_API bool sagittarius_c_assembly_to_program(char *assembly_file, char *program_file); +#endif \ No newline at end of file diff --git a/Source/SagittariusC/main.c b/Source/SagittariusC/main.c new file mode 100644 index 0000000..d8fca76 --- /dev/null +++ b/Source/SagittariusC/main.c @@ -0,0 +1,6 @@ +#include "../../Headers/SagittariusC/SagittariusC.h" + +int main(int ac, char** av) { + + return 0; +} \ No newline at end of file