tomo/ast.h

267 lines
6.5 KiB
C

#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 ast_list_s {
ast_t *ast;
struct ast_list_s *next;
} ast_list_t;
typedef struct arg_ast_s {
const char *name;
type_ast_t *type;
ast_t *default_val;
struct arg_ast_s *next;
} arg_ast_t;
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 {
UnknownTypeAST,
VarTypeAST,
PointerTypeAST,
ArrayTypeAST,
TableTypeAST,
FunctionTypeAST,
} type_ast_e;
typedef struct tag_ast_s {
const char *name;
arg_ast_t *fields;
int64_t value;
struct tag_ast_s *next;
} tag_ast_t;
struct type_ast_s {
type_ast_e tag;
sss_file_t *file;
const char *start, *end;
union {
struct {} UnknownTypeAST;
struct {
const char *name;
} VarTypeAST;
struct {
type_ast_t *pointed;
bool is_optional:1, is_stack:1, is_readonly:1;
} PointerTypeAST;
struct {
type_ast_t *item;
} ArrayTypeAST;
struct {
type_ast_t *key, *value;
} TableTypeAST;
struct {
arg_ast_t *args;
type_ast_t *ret;
} FunctionTypeAST;
} __data;
};
typedef enum {
Unknown = 0,
Nil, Bool, Var,
Int, Num, Char,
StringLiteral, StringJoin,
Declare, Assign,
BinaryOp, UnaryOp, UpdateAssign,
Min, Max,
Array, Table, TableEntry,
FunctionDef, Lambda,
FunctionCall, KeywordArg,
Block,
For, While, If,
Reduction,
Skip, Stop, Pass,
Return,
Extern,
StructDef,
EnumDef,
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 {
const char *name;
} 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 *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_ast_t *args;
type_ast_t *ret_type;
ast_t *body;
ast_t *cache;
bool is_inline;
} FunctionDef;
struct {
arg_ast_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 {
const char *name;
arg_ast_t *fields;
ast_t *namespace;
} StructDef;
struct {
const char *name;
tag_ast_t *tags;
ast_t *namespace;
} EnumDef;
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