Files
Sagittarius/Headers/SagittariusC/SagittariusC.h
T
2026-05-25 16:13:05 +10:00

150 lines
5.8 KiB
C

#ifndef __SAGITTARIUS_C_H_
#define __SAGITTARIUS_C_H_
#include "../Sagittarius.h"
#include <stdbool.h>
#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>(T a, T b){
* return a + b;
* }
* void main(){
* int x = add(1, 2);
* float y = add(3.14f, 2.71f);
* sys.printint(x);
* printfloat(y); // Compiler will resolve printfloat to correct function in sys namespace.
* }
* }
*
*/
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;
bool sagittarius_c_next_word(FILE *f, char *file_name, Sag_Str *out);
/*
* This function performs basic scanning of the source code, which will read the source code and split it into segments, and also perform some basic processing on the segments, such as removing comments and whitespace. The segments are stored in a linked list manner, and the head of the list is returned through the out parameter.
*This function should be called before post processing and parsing the segments.
*/
SAGITTARIUS_API bool sagittarius_c_scan_segments(FILE *f, char *file_name, SagittariusC_Segment **out_head);
/*
* Post process the segments, which will perform some necessary processing on the segments,
* such as combining segments for floats like "3.14f" into a single segment, and also perform some basic checks on the segments to ensure they are well formed. This function should be called before parsing the segments into a syntax tree.
*/
SAGITTARIUS_API bool sagittarius_c_post_process_segments(SagittariusC_Segment *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