script

script.git
git clone git://git.lenczewski.org/script.git
Log | Files | Refs

libscript.h (6173B)


      1 #ifndef LIBSCRIPT_H
      2 #define LIBSCRIPT_H
      3 
      4 #include <assert.h>
      5 #include <errno.h>
      6 #include <stdalign.h>
      7 #include <stdarg.h>
      8 #include <stddef.h>
      9 #include <stdint.h>
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 #include <string.h>
     13 
     14 /* utilities
     15  * ===========================================================================
     16  */
     17 
     18 #define SCRIPT_TO_PARENT(child_ptr, T, member) \
     19 	((child_ptr) ? (T *) ((uintptr_t) child_ptr - offsetof(T, member)) : NULL)
     20 
     21 struct script_flystr {
     22 	uint64_t v;
     23 };
     24 
     25 struct script_list_node {
     26 	struct script_list_node *prev, *next;
     27 };
     28 
     29 #define SCRIPT_FROM_NODE(node, T, member) SCRIPT_TO_PARENT(node, T, member)
     30 
     31 #define SCRIPT_NODE_ITER(node) \
     32 	for (struct script_list_node *it = (node); it; it = it->next)
     33 
     34 #define SCRIPT_NODE_RITER(node) \
     35 	for (struct script_list_node *it = (node); it; it = it->prev)
     36 
     37 struct script_list {
     38 	struct script_list_node *head, *tail;
     39 };
     40 
     41 #define SCRIPT_LIST_ITER(list) SCRIPT_NODE_ITER((list)->head)
     42 #define SCRIPT_LIST_RITER(list) SCRIPT_NODE_RITER((list)->tail)
     43 
     44 /* lexer
     45  * ===========================================================================
     46  */
     47 
     48 enum script_token_type {
     49 	SCR_TOKEN_EOF,
     50 
     51 	/* punctuation */
     52 	SCR_TOKEN_LPAREN	= '(',
     53 	SCR_TOKEN_RPAREN	= ')',
     54 	SCR_TOKEN_LBRACK	= '[',
     55 	SCR_TOKEN_RBRACK	= ']',
     56 	SCR_TOKEN_LBRACE	= '{',
     57 	SCR_TOKEN_RBRACE	= '}',
     58 
     59 	SCR_TOKEN_LANGLE	= '<',
     60 	SCR_TOKEN_RANGLE	= '>',
     61 	SCR_TOKEN_LSLASH	= '\\',
     62 	SCR_TOKEN_RSLASH	= '/',
     63 
     64 	SCR_TOKEN_COLON		= ':',
     65 	SCR_TOKEN_SEMICOLON	= ';',
     66 	SCR_TOKEN_DOT		= '.',
     67 	SCR_TOKEN_COMMA		= ',',
     68 
     69 	SCR_TOKEN_EQUALS	= '=',
     70 	SCR_TOKEN_PLUS		= '+',
     71 	SCR_TOKEN_MINUS		= '-',
     72 	SCR_TOKEN_STAR		= '*',
     73 
     74 	_SCR_TOKEN_MULTICHAR	= 128, /* helper to bump enum values ouside of ascii range */
     75 
     76 	/* multi-char punctuation */
     77 	SCR_TOKEN_DOUBLE_COLON,
     78 	SCR_TOKEN_DOUBLE_EQUALS,
     79 
     80 	/* literals */
     81 	SCR_TOKEN_IDENT,
     82 	SCR_TOKEN_LITERAL_INT,
     83 
     84 	/* keywords */
     85 	SCR_TOKEN_U8,
     86 	SCR_TOKEN_U16,
     87 	SCR_TOKEN_U32,
     88 	SCR_TOKEN_U64,
     89 
     90 	SCR_TOKEN_S8,
     91 	SCR_TOKEN_S16,
     92 	SCR_TOKEN_S32,
     93 	SCR_TOKEN_S64,
     94 
     95 	SCR_TOKEN_F32,
     96 	SCR_TOKEN_F64,
     97 
     98 	SCR_TOKEN_C8,
     99 
    100 	SCR_TOKEN_RETURN,
    101 
    102 	SCR_TOKEN_IF,
    103 	SCR_TOKEN_ELSE,
    104 	SCR_TOKEN_WHILE,
    105 };
    106 
    107 extern char const *
    108 script_token_type_str(enum script_token_type type);
    109 
    110 struct script_token {
    111 	enum script_token_type type;
    112 
    113 	union {
    114 		struct script_flystr ident;
    115 		uint64_t literal_int;
    116 	};
    117 };
    118 
    119 /* parser
    120  * ===========================================================================
    121  */
    122 
    123 enum script_type {
    124 	SCR_TYPE_U8,
    125 	SCR_TYPE_U16,
    126 	SCR_TYPE_U32,
    127 	SCR_TYPE_U64,
    128 
    129 	SCR_TYPE_S8,
    130 	SCR_TYPE_S16,
    131 	SCR_TYPE_S32,
    132 	SCR_TYPE_S64,
    133 
    134 	SCR_TYPE_F32,
    135 	SCR_TYPE_F64,
    136 
    137 	SCR_TYPE_C8,
    138 };
    139 
    140 struct script_typeinfo {
    141 	enum script_type type;
    142 
    143 	size_t size;
    144 	size_t alignment;
    145 };
    146 
    147 enum script_expr_type {
    148 	SCR_EXPR_IDENT,
    149 	SCR_EXPR_LITERAL_INT,
    150 	SCR_EXPR_ASSIGNMENT,
    151 	SCR_EXPR_BINARY_OP,
    152 };
    153 
    154 struct script_expr {
    155 	enum script_expr_type type;
    156 
    157 	struct script_typeinfo *typeinfo;
    158 
    159 	union {
    160 		struct script_flystr ident;
    161 
    162 		uint64_t literal_int;
    163 
    164 		struct {
    165 			struct script_flystr ident;
    166 			struct script_expr *rhs;
    167 		} assignment;
    168 
    169 		struct {
    170 			enum {
    171 				SCR_BINARY_OP_ADD,
    172 				SCR_BINARY_OP_SUB,
    173 				SCR_BINARY_OP_MUL,
    174 				SCR_BINARY_OP_DIV,
    175 				SCR_BINARY_OP_EQU,
    176 			} type;
    177 
    178 			struct script_expr *lhs, *rhs;
    179 		} binary_op;
    180 	};
    181 };
    182 
    183 enum script_stmt_type {
    184 	SCR_STMT_BLOCK,
    185 	SCR_STMT_DECL,
    186 	SCR_STMT_EXPR,
    187 	SCR_STMT_IF_ELSE,
    188 	SCR_STMT_WHILE_LOOP,
    189 	SCR_STMT_RET,
    190 };
    191 
    192 struct script_stmt {
    193 	enum script_stmt_type type;
    194 
    195 	union {
    196 		struct {
    197 			struct script_list children;
    198 		} block;
    199 
    200 		struct {
    201 			struct script_flystr ident;
    202 			struct script_typeinfo *typeinfo;
    203 			struct script_expr *expr;
    204 		} decl;
    205 
    206 		struct script_expr *expr;
    207 
    208 		struct {
    209 			struct script_expr *cond;
    210 			struct script_stmt *if_body, *else_body;
    211 		} if_else;
    212 
    213 		struct {
    214 			struct script_expr *cond;
    215 			struct script_stmt *while_body;
    216 		} while_loop;
    217 
    218 		struct {
    219 			struct script_expr *expr;
    220 		} ret;
    221 	};
    222 
    223 	struct script_list_node list_node;
    224 };
    225 
    226 enum script_symbol_type {
    227 	SCR_SYMBOL_VARIABLE,
    228 };
    229 
    230 struct script_symbol {
    231 	enum script_symbol_type type;
    232 
    233 	struct script_flystr ident;
    234 	struct script_symbol *parent_scope;
    235 
    236 	union {
    237 		struct {
    238 			struct script_typeinfo *typeinfo;
    239 			uintptr_t addr;
    240 		} variable;
    241 	};
    242 
    243 	struct script_list_node list_node;
    244 };
    245 
    246 /* ir
    247  * ===========================================================================
    248  */
    249 
    250 enum script_ir_opcode {
    251 	SCR_IR_LOAD,
    252 	SCR_IR_STORE,
    253 
    254 	SCR_IR_PUSH,
    255 	SCR_IR_POP,
    256 	SCR_IR_RET,
    257 
    258 	SCR_IR_CMP,
    259 	SCR_IR_JMP,
    260 	SCR_IR_JNE,
    261 	SCR_IR_JEQ,
    262 
    263 	SCR_IR_ADD,
    264 	SCR_IR_SUB,
    265 	SCR_IR_MUL,
    266 	SCR_IR_DIV,
    267 };
    268 
    269 extern char const *
    270 script_ir_opcode_str(enum script_ir_opcode opcode);
    271 
    272 enum script_ir_type {
    273 	SCR_IR_TYPE_U8,
    274 	SCR_IR_TYPE_U16,
    275 	SCR_IR_TYPE_U32,
    276 	SCR_IR_TYPE_U64,
    277 
    278 	SCR_IR_TYPE_S8,
    279 	SCR_IR_TYPE_S16,
    280 	SCR_IR_TYPE_S32,
    281 	SCR_IR_TYPE_S64,
    282 
    283 	SCR_IR_TYPE_F32,
    284 	SCR_IR_TYPE_F64,
    285 
    286 	SCR_IR_TYPE_C8,
    287 
    288 	SCR_IR_TYPE_PTR,
    289 };
    290 
    291 extern char const *
    292 script_ir_type_str(enum script_ir_type type);
    293 
    294 struct script_ir_typeinfo {
    295 	enum script_ir_type type;
    296 	size_t size, alignment;
    297 };
    298 
    299 enum script_ir_operand_type {
    300 	SCR_IR_OPERAND_LITERAL,
    301 	SCR_IR_OPERAND_ADDRESS,
    302 	SCR_IR_OPERAND_OFFSET,
    303 };
    304 
    305 struct script_ir_operand {
    306 	enum script_ir_operand_type type;
    307 	union {
    308 		uint64_t literal;
    309 		uintptr_t address;
    310 		int64_t offset;
    311 	};
    312 };
    313 
    314 #define SCRIPT_IR_INST_MAX_OPERANDS 1
    315 
    316 struct script_ir_inst {
    317 	enum script_ir_opcode opcode;
    318 	struct script_ir_typeinfo *typeinfo;
    319 	struct script_ir_operand operands[SCRIPT_IR_INST_MAX_OPERANDS];
    320 	size_t operand_count;
    321 };
    322 
    323 /* libscript
    324  * ===========================================================================
    325  */
    326 
    327 #define SCRIPT_COMPILE_SCRATCH_BYTES 1024
    328 
    329 #define SCRIPT_COMPILE_MAX_IDENTS 4096
    330 
    331 #define SCRIPT_COMPILE_MAX_TOKS 8192
    332 #define SCRIPT_COMPILE_MAX_SYMS 2048
    333 
    334 #define SCRIPT_COMPILE_MAX_STMTS 4096
    335 #define SCRIPT_COMPILE_MAX_EXPRS 4096
    336 
    337 #define SCRIPT_COMPILE_MAX_EXPR_DEPTH 16
    338 
    339 #define SCRIPT_COMPILE_MAX_IR_INSTRS 4096
    340 
    341 struct script_program {
    342 	struct {
    343 		struct script_ir_inst *ptr;
    344 		size_t len;
    345 	} instructions;
    346 
    347 	size_t max_heap_bytes;
    348 };
    349 
    350 extern int
    351 script_compile(char *src, size_t src_len, void *mem, size_t mem_len,
    352 	       struct script_program *out, FILE *errstream, int verbose);
    353 
    354 #endif /* LIBSCRIPT_H */