#ifndef __SAGITTARIUS_ASSEMBLER_H_ #define __SAGITTARIUS_ASSEMBLER_H_ #include "../Sagittarius.h" #include /** * * The file format of assembly code for Sagittarius is as follows: * * Label: * : * Special Labels: * * These labels are section indicators, and they indicate the beginning of a section. The content of the section will be determined by the label, and the assembler will handle the content accordingly: * * .code: * Code section, where instructions are placed. The program counter starts from the beginning of this section. * .data: * Data section, where data is placed. The data in this section can be accessed by instructions, and the offset of the data is determined by the order of the data in this section. * .const: * Constant section, when the program is being assembled, the assembler will replace the label in the code with the value from constant section. Constant data won't be included in the final program. * * To use a label, simply use the label name in the code. The assembler will replace the label with the offset of the label in the final program. For example: * `set 0 data_0` * * Note: special labels cannot be used as normal labels, and normal labels cannot have the same name as special labels. * * * * Format of instruction: * ... * * Format of data: * * Data types: * - string * - base64 * - file * * Instruction alias: * * set. is an alias for set instruction, which sets the register to the value of the specified type. The assembler will convert the value to the corresponding type and then generate the set instruction. For example: * * Comments: * * Any text after a semicolon (;) and hash (#) is considered a comment and will be ignored by the assembler. * * Example: * .code: * start: * set.uint64 syscal_printf_arg0 data_0 * set.int32 16 0x123 * .data: * data_0 string "Hello, World!" * .code: * set.float 24 3.14 * add int32 8 16 32 * syscall syscall_printf_namespace syscall_printf_func * .const: * syscall_printf_namespace 0 * syscall_printf_func 0 * syscal_printf_arg0 40 */ 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; typedef struct Sag_IntermediateInst{ SagittariusInst inst; Sag_Str* label; Sag_Str* args; uint64_t arg_count; } Sag_IntermediateInst; typedef struct Sag_IntermediateProgram{ Sag_IntermediateInst* insts; uint64_t inst_count; Sag_Str* data; uint64_t data_count; Sag_Str* Consts; uint64_t Consts_count; } Sag_IntermediateProgram; bool Sag_NextWord(FILE* f, Sag_Str* out); bool Sag_MatchStr(Sag_Str* str, char** match_list, uint64_t match_count, uint64_t* out_index); bool Sag_Scan(FILE* f, Sag_IntermediateProgram* out); bool Sag_Combine(Sag_IntermediateProgram* L, Sag_IntermediateProgram* R, Sag_IntermediateProgram* out); bool Sag_Finalize(Sag_IntermediateProgram* intermediate, SagittariusProgram* out); bool Sag_WriteProgram(FILE* f, SagittariusProgram* program); #endif