types.h (7282B)
#pragma once
#include <libgccjit.h>
#include <stdlib.h>
#include <stdbool.h>
typedef enum {
TOKEN_IDENT = 1006,
TOKEN_LPAREN,
TOKEN_RPAREN,
TOKEN_LBRACE,
TOKEN_RBRACE,
TOKEN_LBRACKET,
TOKEN_RBRACKET,
TOKEN_EQUAL,
TOKEN_SEMICOLON,
TOKEN_PERCENT,
TOKEN_COMMA,
TOKEN_STRUCT,
TOKEN_EXTEND,
TOKEN_FX,
TOKEN_FN,
TOKEN_INT_LITERAL,
TOKEN_FLOAT_LITERAL,
TOKEN_STRING_LITERAL,
TOKEN_BOOL_TRUE_LITERAL,
TOKEN_BOOL_FALSE_LITERAL,
TOKEN_COMP_TIME,
TOKEN_VARIADIC,
TOKEN_SLASH,
TOKEN_STAR,
TOKEN_PLUS,
TOKEN_PLUSPLUS,
TOKEN_MINUS,
TOKEN_MINUSMINUS,
TOKEN_EQUALITY,
TOKEN_INEQUALITY,
TOKEN_BANG,
TOKEN_LT,
TOKEN_GT,
TOKEN_LT_EQ,
TOKEN_GT_EQ,
TOKEN_IF,
TOKEN_ELSE,
TOKEN_WHILE,
TOKEN_FOR,
TOKEN_BREAK,
TOKEN_CONTINUE,
TOKEN_RETURN,
TOKEN_UNKNOWN, // NOTE: also update print_token
TOKEN_EOF
} TokenType; // NOTE also update token_type_str!
const char* token_type_str(TokenType t);
typedef struct {
size_t start;
size_t end;
size_t line;
size_t col;
TokenType type;
} Token;
typedef struct {
Token* tokens;
size_t token_count;
size_t token_cap;
size_t pos;
size_t line;
size_t col;
const char* src;
size_t src_len;
const char* filename;
} Lexer;
typedef enum {
NODE_PROGRAM = 11,
NODE_FUNCTION_DECL,
NODE_PARAM,
NODE_VAR_DECL,
NODE_VAR_ASSIGN,
NODE_BLOCK,
NODE_CALL_EXPR,
NODE_RETURN,
NODE_BREAK,
NODE_CONTINUE,
NODE_INT_LITERAL,
NODE_FLOAT_LITERAL,
NODE_STRING_LITERAL,
NODE_BOOL_LITERAL,
NODE_IDENT,
NODE_TYPE,
NODE_BINARY_EXPR,
NODE_UNARY_EXPR,
NODE_EXPR_STATEMENT,
NODE_SUBSCRIPT_EXPR,
NODE_IF,
NODE_WHILE,
NODE_FOR,
NODE_EMPTY_STATEMENT,
NODE_UNKNOWN,
} NodeType; // note: if changed, edit node_type_str!
const char* node_type_str(NodeType);
void print_node_type_str(NodeType);
/*
typedef enum {
OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD,
OP_POS, OP_NEG, OP_INC, OP_DEC,
OP_BITAND, OP_BITOR, OP_BITXOR, OP_BITNOT,
OP_SHL, OP_SHR,
OP_LOGAND, OP_LOGOR, OP_LOGNOT,
OP_LT, OP_LE, OP_GT, OP_GE, OP_EQ, OP_NE,
OP_ASSIGN, OP_ADD_ASSIGN, OP_SUB_ASSIGN,
OP_MUL_ASSIGN, OP_DIV_ASSIGN, OP_MOD_ASSIGN,
OP_SHL_ASSIGN, OP_SHR_ASSIGN,
OP_AND_ASSIGN, OP_XOR_ASSIGN, OP_OR_ASSIGN,
OP_CONDITIONAL, OP_COMMA,
OP_ADDR, OP_DEREF, OP_MEMBER, OP_PTR_MEMBER,
OP_SUBSCRIPT, OP_CALL,
OP_SIZEOF, OP_ALIGNOF
} OpType;
*/
typedef enum {
OP_PLUS = 300,
OP_MINUS,
OP_MUL,
OP_DIV,
OP_MOD,
OP_BIT_AND, // & ampersand
OP_BIT_OR, // |
OP_ASSIGN,
OP_EQUALITY, // ==
OP_INEQUALITY, // !=
OP_LT_EQ,
OP_GT_EQ,
OP_LT,
OP_GT,
} OpType;
typedef enum {
OPER_MINUS = 0,
OPER_BANG,
OPER_PREINC,
OPER_PREDEC,
OPER_POSTINC,
OPER_POSTDEC,
} UnaryOp;
typedef struct {
size_t start;
size_t end;
} Span;
typedef struct Node {
NodeType type;
struct Node* next;
struct Scope* scope;
const char* filename;
size_t line, col;
/* NOTE we will eventually add spans for condition info, etc. to print out in errors */
union {
/* clang-format off */
struct { struct Node** decl; size_t len, cap; } program;
struct { Span name; struct Node* return_type; struct Node** params; size_t p_cap, p_len; struct Node* body; bool exported; } function_decl;
struct { Span name; struct Node* type; } param;
struct { struct Node* cond; struct Node* then_body; struct Node* else_body; } if_statement;
struct { struct Node* cond; struct Node* body; } while_statement;
struct { struct Node* init; struct Node* cond; struct Node* increment; struct Node* body; } for_statement;
struct { struct Node** stmts; size_t cap, len; } block;
struct { Span name; struct Node* type; struct Node* init; } var_decl;
struct { struct Node* lhs; struct Node* rhs; } var_assign;
struct { struct Node* callee; struct Node** args; size_t cap, len; } call_expr;
struct { struct Node* expr; } ret;
struct { struct Node* expr; } cont;
struct { struct Node* expr; } expr_statement;
struct { OpType op; struct Node* lhs; struct Node* rhs; } binary_expr;
struct { UnaryOp op; struct Node* operand; bool is_postfix; } unary_expr;
struct { struct Node* array; struct Node* index; } subscript_expr;
struct { double value; } number;
struct { bool value; } boolean;
struct { Span value; } string;
struct { Span name; } ident;
struct { Span name; bool is_comp_time; bool is_variadic; } ident_type;
/* clang-format on */
} data;
} Node;
typedef struct {
Token* tokens;
size_t token_count;
size_t pos;
const char* src;
size_t src_len;
const char* filename;
} Parser;
typedef struct {
Node* node;
const char* src;
} Ast;
typedef struct {
Node** items;
size_t len, cap;
} NodeVec;
typedef enum {
// todo distinguish local/exported/param
SYMTYPE_VOID = 108,
SYMTYPE_INT,
SYMTYPE_I8,
SYMTYPE_I16,
SYMTYPE_I32,
SYMTYPE_I64,
SYMTYPE_I128,
SYMTYPE_UINT,
SYMTYPE_U8,
SYMTYPE_U16,
SYMTYPE_U32,
SYMTYPE_U64,
SYMTYPE_U128,
SYMTYPE_F32,
SYMTYPE_F64,
SYMTYPE_F128,
SYMTYPE_FLOAT,
SYMTYPE_STR,
SYMTYPE_CHR,
SYMTYPE_BOOL,
SYMTYPE_STRUCT,
SYMTYPE_USER,
SYMTYPE_ARRAY,
SYMTYPE_ENUM,
SYMTYPE_FUNC,
SYMTYPE_TODO,
} SymbolType; // note also update type_kind_str!
const char* type_kind_str(SymbolType);
typedef enum {
ENUM_VALUE_INT,
ENUM_VALUE_STRING,
} EnumValueKind;
typedef struct StructField {
char* name;
struct Type* type;
} StructField;
typedef struct EnumField {
char* name;
EnumValueKind kind;
union { // not used?
int int_value;
char* string_value;
} val;
} EnumField;
typedef struct StructMethod {
char* name;
struct Type* return_type;
struct Type** param_types;
int params_count;
int params_cap;
// TODO add ptr to func decl of this struct method
} StructMethod;
typedef struct Type {
SymbolType type;
// union {
// struct StructType {
// const char* struct_name;
// int fields_count;
// int methods_count;
// StructField* fields;
// StructMethod* methods;
// } struct_t;
// struct ArrayType {
// int array_size; // -1 or fixed
// struct Type* of_type;
// bool dynamic;
// } array_t;
// struct EnumType {
// const char* enum_name;
// const int fields_count;
// EnumField* fields;
// EnumValueKind value_kind;
// } enum_t;
// };
} TypeInfo;
typedef struct Symbol {
Span name;
Node* decl;
TypeInfo* type; // todo print all found in gen
gcc_jit_type* ctype;
const char* english_type;
bool is_variadic;
bool is_comp_time;
union {
gcc_jit_function* funcvalue;
gcc_jit_lvalue* lvalue;
gcc_jit_param* param;
gcc_jit_rvalue* const_rvalue;
} d;
} Symbol;
// @later NOTE: our symbols are a list, there is an argument to be made to change to a linked list;
// as a linked list will outperform an allocated list up to 12-16 elements, or so.
// @later NOTE: also consider their relation between each other and the rest of the compiler is a bit of a circulas mess;
// which is fine as long as we're boostrapping and getting it off the ground.
typedef struct Scope {
struct Node* owner;
struct Scope* parent;
Symbol** symbols;
size_t len;
size_t cap;
struct Scope** children;
size_t ch_len;
size_t ch_cap;
int depth;
int id;
} Scope;