diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-02-04 15:23:59 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-02-04 15:23:59 -0500 |
| commit | 98f0c51119f9d42d733f44cb516b1c2bcd9061af (patch) | |
| tree | 39ab4fa635f858b76b9a8bbf84701c2788d5f498 /ast.h | |
Initial commit
Diffstat (limited to 'ast.h')
| -rw-r--r-- | ast.h | 290 |
1 files changed, 290 insertions, 0 deletions
@@ -0,0 +1,290 @@ +#pragma once +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <printf.h> + +#include "files.h" +#include "util.h" + +#define NewAST(_file, _start, _end, ast_tag, ...) (new(ast_t, .file=_file, .start=_start, .end=_end,\ + .tag=ast_tag, .__data.ast_tag={__VA_ARGS__})) +#define NewTypeAST(_file, _start, _end, ast_tag, ...) (new(type_ast_t, .file=_file, .start=_start, .end=_end,\ + .tag=ast_tag, .__data.ast_tag={__VA_ARGS__})) +#define FakeAST(ast_tag, ...) (new(ast_t, .tag=ast_tag, .__data.ast_tag={__VA_ARGS__})) +#define WrapAST(ast, ast_tag, ...) (new(ast_t, .file=(ast)->file, .start=(ast)->start, .end=(ast)->end, .tag=ast_tag, .__data.ast_tag={__VA_ARGS__})) +#define StringAST(ast, _str) WrapAST(ast, StringLiteral, .str=heap_str(_str)) + +struct binding_s; +typedef struct type_ast_s type_ast_t; +typedef struct ast_s ast_t; + +typedef struct { + const char *name; + struct binding_s *binding; +} var_t; + +typedef struct ast_list_s { + ast_t *ast; + struct ast_list_s *next; +} ast_list_t; + +typedef struct arg_list_s { + var_t *var; + type_ast_t *type; + ast_t *default_val; + struct arg_list_s *next; +} arg_list_t; + +#define REVERSE_LIST(list) do { \ + __typeof(list) _prev = NULL; \ + __typeof(list) _next = NULL; \ + auto _current = list; \ + while (_current != NULL) { \ + _next = _current->next; \ + _current->next = _prev; \ + _prev = _current; \ + _current = _next; \ + } \ + list = _prev; \ +} while(0) + +typedef enum { + UNOP_UNKNOWN, + UNOP_NOT=1, UNOP_NEGATIVE, + UNOP_HEAP_ALLOCATE, + UNOP_STACK_REFERENCE, +} unop_e; + +typedef enum { + BINOP_UNKNOWN, + BINOP_POWER=100, BINOP_MULT, BINOP_DIVIDE, BINOP_MOD, BINOP_MOD1, BINOP_PLUS, + BINOP_MINUS, BINOP_CONCAT, BINOP_LSHIFT, BINOP_RSHIFT, BINOP_MIN, + BINOP_MAX, BINOP_EQ, BINOP_NE, BINOP_LT, BINOP_LE, BINOP_GT, BINOP_GE, + BINOP_AND, BINOP_OR, BINOP_XOR, +} binop_e; + +typedef enum { + TypeUnknown, + TypeVar, + TypePointer, + TypeStruct, + TypeTaggedUnion, + TypeArray, + TypeTable, + TypeFunction, +} type_ast_e; + +typedef struct tag_s { + const char *name; + struct type_ast_s *type; + int64_t value; + struct tag_s *next; +} tag_t; + +struct type_ast_s { + type_ast_e tag; + sss_file_t *file; + const char *start, *end; + union { + struct {} TypeUnknown; + struct { + var_t var; + } TypeVar; + struct { + type_ast_t *pointed; + bool is_optional:1, is_stack:1, is_readonly:1; + } TypePointer; + struct { + arg_list_t *fields; + } TypeStruct; + struct { + tag_t *tags; + } TypeTaggedUnion; + struct { + type_ast_t *item; + } TypeArray; + struct { + type_ast_t *key, *value; + } TypeTable; + struct { + arg_list_t *args; + type_ast_t *ret; + } TypeFunction; + } __data; +}; + +typedef enum { + Unknown = 0, + Nil, Bool, Var, + Int, Num, Char, + StringLiteral, StringJoin, Interp, + Declare, Assign, + BinaryOp, UnaryOp, UpdateAssign, + Min, Max, + Array, Table, TableEntry, + FunctionDef, Lambda, + FunctionCall, KeywordArg, + Block, + For, While, If, + Reduction, + Skip, Stop, Pass, + Return, + Extern, + TypeDef, + Index, FieldAccess, + DocTest, + Use, + LinkerDirective, +} ast_e; + +struct ast_s { + ast_e tag; + sss_file_t *file; + const char *start, *end; + union { + struct {} Unknown; + struct { + type_ast_t *type; + } Nil; + struct { + bool b; + } Bool; + struct { + var_t var; + } Var; + struct { + int64_t i; + enum { INT_64BIT, INT_32BIT, INT_16BIT, INT_8BIT } precision; + } Int; + struct { + double n; + enum { NUM_64BIT, NUM_32BIT } precision; + } Num; + struct { + char c; + } Char; + struct { + const char *str; + } StringLiteral; + struct { + ast_list_t *children; + } StringJoin; + struct { + ast_t *value; + bool labelled:1, colorize:1, quote_string:1; + } Interp; + struct { + ast_t *var; + ast_t *value; + } Declare; + struct { + ast_list_t *targets, *values; + } Assign; + struct { + ast_t *lhs; + binop_e op; + ast_t *rhs; + } BinaryOp, UpdateAssign; + struct { + unop_e op; + ast_t *value; + } UnaryOp; + struct { + ast_t *lhs, *rhs, *key; + } Min, Max; + struct { + type_ast_t *type; + ast_list_t *items; + } Array; + struct { + type_ast_t *key_type, *value_type; + ast_t *fallback, *default_value; + ast_list_t *entries; + } Table; + struct { + ast_t *key, *value; + } TableEntry; + struct { + ast_t *name; + arg_list_t *args; + type_ast_t *ret_type; + ast_t *body; + ast_t *cache; + bool is_inline; + } FunctionDef; + struct { + arg_list_t *args; + ast_t *body; + } Lambda; + struct { + ast_t *fn; + ast_list_t *args; + type_ast_t *extern_return_type; + } FunctionCall; + struct { + const char *name; + ast_t *arg; + } KeywordArg; + struct { + ast_list_t *statements; + } Block; + struct { + ast_t *index, *value, *iter, *body; + } For; + struct { + ast_t *condition, *body; + } While; + struct { + ast_t *condition, *body, *else_body; + } If; + struct { + ast_t *iter, *combination, *fallback; + } Reduction; + struct { + const char *target; + } Skip, Stop; + struct {} Pass; + struct { + ast_t *value; + } Return; + struct { + const char *name; + type_ast_t *type; + bool address; + } Extern; + struct { + var_t var; + type_ast_t *type; + ast_t *namespace; + } TypeDef; + struct { + ast_t *indexed, *index; + bool unchecked; + } Index; + struct { + ast_t *fielded; + const char *field; + } FieldAccess; + struct { + ast_t *expr; + const char *output; + bool skip_source:1; + } DocTest; + struct { + const char *path; + sss_file_t *file; + bool main_program; + } Use; + struct { + const char *directive; + } LinkerDirective; + } __data; +}; + +const char *ast_to_str(ast_t *ast); +const char *type_ast_to_str(type_ast_t *ast); +int printf_ast(FILE *stream, const struct printf_info *info, const void *const args[]); +ast_list_t *get_ast_children(ast_t *ast); + +// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 |
