2024-02-04 12:23:59 -08:00
# pragma once
2024-03-18 09:49:38 -07:00
// Logic defining ASTs (abstract syntax trees) to represent code
2024-09-17 22:11:50 -07:00
# include <err.h>
2024-09-13 11:23:24 -07:00
# include <gc/cord.h>
2024-09-17 22:11:50 -07:00
# include <printf.h>
2024-02-04 12:23:59 -08:00
# include <stdbool.h>
# include <stdint.h>
# include <stdlib.h>
2024-09-17 12:17:13 -07:00
# include "stdlib/datatypes.h"
2024-09-13 17:18:08 -07:00
# include "stdlib/files.h"
# include "stdlib/util.h"
2024-02-04 12:23:59 -08:00
# 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__}))
2024-07-26 10:30:24 -07:00
# define TextAST(ast, _str) WrapAST(ast, TextLiteral, .str=GC_strdup(_str))
2024-09-17 22:11:50 -07:00
# define Match(x, _tag) ((x)->tag == _tag ? &(x)->__data._tag : (errx(1, __FILE__ ":%d This was supposed to be a " # _tag "\n", __LINE__), &(x)->__data._tag))
2024-02-04 12:23:59 -08:00
2024-09-17 22:10:34 -07:00
# 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 )
2024-02-04 12:23:59 -08:00
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 ;
2024-02-07 21:52:18 -08:00
typedef struct arg_ast_s {
const char * name ;
2024-02-04 12:23:59 -08:00
type_ast_t * type ;
2024-02-23 09:50:01 -08:00
ast_t * value ;
2024-02-07 21:52:18 -08:00
struct arg_ast_s * next ;
} arg_ast_t ;
2024-02-04 12:23:59 -08:00
2024-05-01 10:53:51 -07:00
typedef struct when_clause_s {
2025-03-06 15:37:08 -08:00
ast_t * pattern , * body ;
2024-05-01 10:53:51 -07:00
struct when_clause_s * next ;
} when_clause_t ;
2024-02-04 12:23:59 -08:00
typedef enum {
BINOP_UNKNOWN ,
BINOP_POWER = 100 , BINOP_MULT , BINOP_DIVIDE , BINOP_MOD , BINOP_MOD1 , BINOP_PLUS ,
2024-11-03 12:48:13 -08:00
BINOP_MINUS , BINOP_CONCAT , BINOP_LSHIFT , BINOP_ULSHIFT , BINOP_RSHIFT , BINOP_URSHIFT , BINOP_MIN ,
2024-02-04 12:23:59 -08:00
BINOP_MAX , BINOP_EQ , BINOP_NE , BINOP_LT , BINOP_LE , BINOP_GT , BINOP_GE ,
2024-04-02 10:08:06 -07:00
BINOP_CMP ,
2024-02-04 12:23:59 -08:00
BINOP_AND , BINOP_OR , BINOP_XOR ,
} binop_e ;
2024-07-01 08:12:00 -07:00
extern const char * binop_method_names [ BINOP_XOR + 1 ] ;
2024-02-04 12:23:59 -08:00
typedef enum {
2024-02-05 10:22:30 -08:00
UnknownTypeAST ,
VarTypeAST ,
PointerTypeAST ,
ArrayTypeAST ,
2024-08-10 12:15:38 -07:00
SetTypeAST ,
2024-02-05 10:22:30 -08:00
TableTypeAST ,
FunctionTypeAST ,
2024-09-10 22:31:31 -07:00
OptionalTypeAST ,
2025-01-02 17:29:55 -08:00
MutexedTypeAST ,
2024-02-04 12:23:59 -08:00
} type_ast_e ;
2024-02-07 21:52:18 -08:00
typedef struct tag_ast_s {
2024-02-04 12:23:59 -08:00
const char * name ;
2024-02-07 21:52:18 -08:00
arg_ast_t * fields ;
2024-02-24 12:24:44 -08:00
bool secret : 1 ;
2024-02-07 21:52:18 -08:00
struct tag_ast_s * next ;
} tag_ast_t ;
2024-02-04 12:23:59 -08:00
struct type_ast_s {
type_ast_e tag ;
2024-02-11 16:06:42 -08:00
file_t * file ;
2024-02-04 12:23:59 -08:00
const char * start , * end ;
union {
2024-02-05 10:22:30 -08:00
struct { } UnknownTypeAST ;
2024-02-04 12:23:59 -08:00
struct {
2024-02-07 21:52:18 -08:00
const char * name ;
2024-02-05 10:22:30 -08:00
} VarTypeAST ;
2024-02-04 12:23:59 -08:00
struct {
type_ast_t * pointed ;
2024-12-18 11:44:37 -08:00
bool is_stack : 1 ;
2024-02-05 10:22:30 -08:00
} PointerTypeAST ;
2024-02-04 12:23:59 -08:00
struct {
type_ast_t * item ;
2025-01-02 13:24:07 -08:00
} ArrayTypeAST ;
2024-02-04 12:23:59 -08:00
struct {
type_ast_t * key , * value ;
2024-12-06 12:18:25 -08:00
ast_t * default_value ;
2024-02-05 10:22:30 -08:00
} TableTypeAST ;
2024-08-10 12:15:38 -07:00
struct {
type_ast_t * item ;
} SetTypeAST ;
2024-02-04 12:23:59 -08:00
struct {
2024-02-07 21:52:18 -08:00
arg_ast_t * args ;
2024-02-04 12:23:59 -08:00
type_ast_t * ret ;
2024-02-05 10:22:30 -08:00
} FunctionTypeAST ;
2024-09-10 22:31:31 -07:00
struct {
type_ast_t * type ;
2025-01-02 17:29:55 -08:00
} OptionalTypeAST , MutexedTypeAST ;
2024-02-04 12:23:59 -08:00
} __data ;
} ;
typedef enum {
Unknown = 0 ,
2024-11-24 13:36:27 -08:00
None , Bool , Var ,
2024-02-11 21:41:49 -08:00
Int , Num ,
2024-07-04 13:23:05 -07:00
TextLiteral , TextJoin , PrintStatement ,
2025-03-15 11:22:11 -07:00
Path ,
2024-02-04 12:23:59 -08:00
Declare , Assign ,
2024-02-17 13:56:19 -08:00
BinaryOp , UpdateAssign ,
2025-01-02 17:29:55 -08:00
Not , Negative , HeapAllocate , StackReference , Mutexed , Holding ,
2024-02-04 12:23:59 -08:00
Min , Max ,
2025-01-02 13:24:07 -08:00
Array , Set , Table , TableEntry , Comprehension ,
2025-03-10 09:42:45 -07:00
FunctionDef , Lambda , ConvertDef ,
2024-02-29 10:49:24 -08:00
FunctionCall , MethodCall ,
2024-02-04 12:23:59 -08:00
Block ,
2024-11-03 09:20:53 -08:00
For , While , If , When , Repeat ,
2024-02-04 12:23:59 -08:00
Reduction ,
Skip , Stop , Pass ,
2024-07-04 15:00:01 -07:00
Defer ,
2024-02-04 12:23:59 -08:00
Return ,
Extern ,
2024-05-12 17:13:19 -07:00
StructDef , EnumDef , LangDef ,
2024-09-11 21:13:53 -07:00
Index , FieldAccess , Optional , NonOptional ,
2024-11-17 11:49:03 -08:00
Moment ,
2024-02-04 12:23:59 -08:00
DocTest ,
2024-08-22 11:02:48 -07:00
Use ,
2024-02-25 13:02:36 -08:00
InlineCCode ,
2025-02-07 17:25:48 -08:00
Deserialize ,
2024-02-04 12:23:59 -08:00
} ast_e ;
struct ast_s {
ast_e tag ;
2024-02-11 16:06:42 -08:00
file_t * file ;
2024-02-04 12:23:59 -08:00
const char * start , * end ;
union {
struct { } Unknown ;
struct {
type_ast_t * type ;
2024-11-24 13:36:27 -08:00
} None ;
2024-02-04 12:23:59 -08:00
struct {
bool b ;
} Bool ;
struct {
2024-02-07 21:52:18 -08:00
const char * name ;
2024-02-04 12:23:59 -08:00
} Var ;
struct {
2024-08-12 22:30:25 -07:00
const char * str ;
2024-02-04 12:23:59 -08:00
} Int ;
struct {
double n ;
} Num ;
struct {
2024-02-11 12:31:30 -08:00
CORD cord ;
2024-03-03 15:15:45 -08:00
} TextLiteral ;
2024-02-04 12:23:59 -08:00
struct {
2024-03-09 15:22:12 -08:00
const char * lang ;
2024-02-04 12:23:59 -08:00
ast_list_t * children ;
2024-03-03 15:15:45 -08:00
} TextJoin ;
2025-03-15 11:22:11 -07:00
struct {
const char * path ;
} Path ;
2024-07-04 13:23:05 -07:00
struct {
ast_list_t * to_print ;
} PrintStatement ;
2024-02-04 12:23:59 -08:00
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 {
ast_t * value ;
2025-01-02 13:24:07 -08:00
} Not , Negative , HeapAllocate , StackReference , Mutexed ;
2025-01-02 17:29:55 -08:00
struct {
ast_t * mutexed , * body ;
} Holding ;
2024-02-04 12:23:59 -08:00
struct {
ast_t * lhs , * rhs , * key ;
} Min , Max ;
struct {
2024-08-11 11:47:34 -07:00
type_ast_t * item_type ;
2024-02-04 12:23:59 -08:00
ast_list_t * items ;
} Array ;
struct {
2024-08-10 12:15:38 -07:00
type_ast_t * item_type ;
ast_list_t * items ;
} Set ;
struct {
2024-02-04 12:23:59 -08:00
type_ast_t * key_type , * value_type ;
2024-12-06 12:18:25 -08:00
ast_t * default_value ;
2024-08-10 13:03:41 -07:00
ast_t * fallback ;
2024-02-04 12:23:59 -08:00
ast_list_t * entries ;
} Table ;
struct {
ast_t * key , * value ;
} TableEntry ;
2024-03-17 11:46:36 -07:00
struct {
2024-07-13 14:17:58 -07:00
ast_list_t * vars ;
ast_t * expr , * iter , * filter ;
2024-03-17 11:46:36 -07:00
} Comprehension ;
2024-02-04 12:23:59 -08:00
struct {
ast_t * name ;
2024-02-07 21:52:18 -08:00
arg_ast_t * args ;
2024-02-04 12:23:59 -08:00
type_ast_t * ret_type ;
ast_t * body ;
ast_t * cache ;
2024-04-17 10:44:01 -07:00
bool is_inline ;
2024-02-04 12:23:59 -08:00
} FunctionDef ;
2025-03-10 09:42:45 -07:00
struct {
arg_ast_t * args ;
type_ast_t * ret_type ;
ast_t * body ;
ast_t * cache ;
bool is_inline ;
} ConvertDef ;
2024-02-04 12:23:59 -08:00
struct {
2024-02-07 21:52:18 -08:00
arg_ast_t * args ;
2024-10-09 10:26:28 -07:00
type_ast_t * ret_type ;
2024-02-04 12:23:59 -08:00
ast_t * body ;
2024-06-06 13:28:53 -07:00
int64_t id ;
2024-02-04 12:23:59 -08:00
} Lambda ;
struct {
ast_t * fn ;
2024-02-23 09:50:01 -08:00
arg_ast_t * args ;
2024-02-04 12:23:59 -08:00
} FunctionCall ;
2024-02-29 10:49:24 -08:00
struct {
const char * name ;
ast_t * self ;
arg_ast_t * args ;
} MethodCall ;
2024-02-04 12:23:59 -08:00
struct {
ast_list_t * statements ;
} Block ;
struct {
2024-07-13 14:17:58 -07:00
ast_list_t * vars ;
ast_t * iter , * body , * empty ;
2024-02-04 12:23:59 -08:00
} For ;
struct {
ast_t * condition , * body ;
} While ;
2024-11-03 09:20:53 -08:00
struct {
ast_t * body ;
} Repeat ;
2024-02-04 12:23:59 -08:00
struct {
ast_t * condition , * body , * else_body ;
} If ;
2024-02-22 09:45:12 -08:00
struct {
ast_t * subject ;
when_clause_t * clauses ;
ast_t * else_body ;
} When ;
2024-02-04 12:23:59 -08:00
struct {
2024-11-08 11:10:19 -08:00
ast_t * iter , * key ;
binop_e op ;
2024-02-04 12:23:59 -08:00
} Reduction ;
struct {
const char * target ;
} Skip , Stop ;
struct { } Pass ;
2024-07-04 15:00:01 -07:00
struct {
ast_t * body ;
} Defer ;
2024-02-04 12:23:59 -08:00
struct {
ast_t * value ;
} Return ;
struct {
const char * name ;
type_ast_t * type ;
} Extern ;
struct {
2024-02-07 21:52:18 -08:00
const char * name ;
arg_ast_t * fields ;
ast_t * namespace ;
2025-03-16 10:35:58 -07:00
bool secret : 1 , external : 1 , opaque : 1 ;
2024-02-07 21:52:18 -08:00
} StructDef ;
struct {
const char * name ;
tag_ast_t * tags ;
2024-02-04 12:23:59 -08:00
ast_t * namespace ;
2024-02-07 21:52:18 -08:00
} EnumDef ;
2024-03-09 15:22:12 -08:00
struct {
const char * name ;
ast_t * namespace ;
} LangDef ;
2024-02-04 12:23:59 -08:00
struct {
ast_t * indexed , * index ;
bool unchecked ;
} Index ;
struct {
ast_t * fielded ;
const char * field ;
} FieldAccess ;
2024-04-30 10:18:47 -07:00
struct {
ast_t * value ;
2024-09-11 21:13:53 -07:00
} Optional , NonOptional ;
2024-09-30 10:55:55 -07:00
struct {
2024-11-17 11:49:03 -08:00
Moment_t moment ;
} Moment ;
2024-02-04 12:23:59 -08:00
struct {
ast_t * expr ;
const char * output ;
bool skip_source : 1 ;
} DocTest ;
2024-06-13 10:17:51 -07:00
struct {
2024-09-27 11:56:24 -07:00
ast_t * var ;
2024-09-04 10:48:26 -07:00
const char * path ;
2024-09-18 12:39:22 -07:00
enum { USE_LOCAL , USE_MODULE , USE_SHARED_OBJECT , USE_HEADER , USE_C_CODE , USE_ASM } what ;
2024-02-04 12:23:59 -08:00
} Use ;
2024-02-25 13:02:36 -08:00
struct {
CORD code ;
2024-09-12 11:27:13 -07:00
struct type_s * type ;
type_ast_t * type_ast ;
2024-02-25 13:02:36 -08:00
} InlineCCode ;
2024-11-29 15:09:12 -08:00
struct {
ast_t * value ;
type_ast_t * type ;
} Deserialize ;
2024-02-04 12:23:59 -08:00
} __data ;
} ;
2024-03-24 16:04:57 -07:00
CORD ast_to_xml ( ast_t * ast ) ;
CORD type_ast_to_xml ( type_ast_t * ast ) ;
2024-02-04 12:23:59 -08:00
int printf_ast ( FILE * stream , const struct printf_info * info , const void * const args [ ] ) ;
2024-09-08 14:17:15 -07:00
PUREFUNC bool is_idempotent ( ast_t * ast ) ;
2024-09-17 12:17:13 -07:00
void visit_topologically ( ast_list_t * ast , Closure_t fn ) ;
2024-02-04 12:23:59 -08:00
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0