#ifndef _H_MORPH_TOKEN #define _H_MORPH_TOKEN #include "loc.h" #include #include typedef enum token_type_e { TT_NONE = 0, TT_KW, TT_OP, TT_PUSH_STR, TT_PUSH_CSTR, TT_PUSH_MEM, TT_PUSH_CHAR, TT_PUSH_INT, TT_PUSH_FLOAT, } token_type_t; typedef enum kw_type_e { // Include will be tokeniser level KW_NONE = 0, KW_FN, KW_DO, KW_END, KW_WITH, KW_RETURNS, KW_STRUCT, KW_ENUM, KW_IF, KW_ELSE, KW_WHILE, KW_CONST, KW_MEMORY, KW_COUNT__, } kw_type_t; typedef enum op_type_e { OP_NONE = 0, // Math OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, // Comparison OP_EQ, OP_GT, OP_LT, OP_GE, OP_LE, OP_NE, // Bit manipulation OP_SHR, OP_SHL, OP_OR, OP_AND, OP_NOT, // stack ops OP_DUP, OP_SWAP, OP_DROP, OP_OVER, OP_ROT, // memory // NOTE: Even if you load a 1 byte value into the stack, // it will still take up the full 8 bytes (or 4, if you're using a 32 bit system) OP_LOAD8, OP_STORE8, OP_LOAD16, OP_STORE16, OP_LOAD32, OP_STORE32, OP_LOAD64, OP_STORE64, // syscalls OP_SYSCALL0, OP_SYSCALL1, OP_SYSCALL2, OP_SYSCALL3, OP_SYSCALL4, OP_SYSCALL5, OP_SYSCALL6, // Builtins/Internals OP_ARGC, OP_ARGV, OP_CAST_PTR, OP_CAST_INT, OP_CAST_BOOL, OP_HERE, OP_PRINT, OP_COUNT__ } op_type_t; typedef struct token_s { token_type_t type; loc_t loc; union { op_type_t op_type; kw_type_t kw_type; // NOTE: PUSH_CSTR and PUSH_STR will use the same data, // it will just output slightly different assembly const char* str_v; const char char_v; ssize_t int_v; // NOTE: For PUSH_MEM. It will push the offset of the memory, // that is assigned for that specific memory, from the `memory` label. size_t offset_v; double float_v; }; } token_t; extern const char* OP_LIST[]; extern const char* KW_LIST[]; #endif // _H_MORPH_TOKEN