182 lines
5.4 KiB
C
182 lines
5.4 KiB
C
#ifndef AST_H
|
|
#define AST_H
|
|
|
|
#include "scope.h"
|
|
#include <stdlib.h>
|
|
|
|
// The type of an `AST`.
|
|
typedef enum {
|
|
// Primitive types.
|
|
AST_TYPE_NUM, // A number (float).
|
|
AST_TYPE_STR, // A string
|
|
AST_TYPE_INT, // An integer.
|
|
AST_TYPE_SYM, // A symbol.
|
|
AST_TYPE_EXC, // Exception.
|
|
|
|
// Collection types:
|
|
AST_TYPE_VEC, // A vector (fixed size, fixed type).
|
|
AST_TYPE_LIST, // A list (variable size, variable type).
|
|
|
|
// Misc. types.
|
|
AST_TYPE_BIF, // Built-in function.
|
|
AST_TYPE_CALL, // A function call.
|
|
AST_TYPE_VDEF, // A variable definition.
|
|
AST_TYPE_VREF, // A variable reference.
|
|
AST_TYPE_BLOCK, // A block of code (scope).
|
|
AST_TYPE_FDEF, // A function definition.
|
|
AST_TYPE_LAMBDA, // An anonymous function definition.
|
|
AST_TYPE_ARG, // A definition argument.
|
|
AST_TYPE_MAX = AST_TYPE_ARG,
|
|
} ASTType;
|
|
|
|
// An Abstract Syntax Tree.
|
|
typedef struct {
|
|
ASTType type; // The type of the `AST`.
|
|
void* data; // The data of the `AST`.
|
|
Scope* scope; // The scope of the `AST`.
|
|
} AST;
|
|
|
|
// Create a new `AST`.
|
|
AST* ast_init(ASTType type, void* data);
|
|
// Create a new `AST` with a specified scope.
|
|
AST* ast_init_scope(ASTType type, void* data, Scope* scope);
|
|
// Destroy an `AST`.
|
|
void ast_destroy(AST* ast);
|
|
|
|
// A number.
|
|
typedef double ASTNumData;
|
|
|
|
// Create a new `ASTNumData`.
|
|
ASTNumData* ast_num_data_init(double val);
|
|
// Destroy an `ASTNumData`.
|
|
void ast_num_data_destroy(ASTNumData* num);
|
|
|
|
// An exception.
|
|
typedef struct ASTEXCDATA {
|
|
const char* msg; // The exception message.
|
|
AST* trace; // The previous exception.
|
|
} ASTExcData;
|
|
// Create a new `ASTExecData. `msg` should be static.
|
|
ASTExcData* ast_exc_data_init(const char* msg, AST* trace);
|
|
// Destroy an `ASTExecData`.
|
|
void ast_exc_data_destroy(ASTExcData* exc);
|
|
|
|
// Argument list as anonymous struct.
|
|
#define ARGS \
|
|
struct { \
|
|
size_t argc; \
|
|
AST** argv; \
|
|
}
|
|
|
|
// Parameter list as anonymous struct.
|
|
#define PARS \
|
|
struct { \
|
|
size_t parc; \
|
|
AST** parv; \
|
|
}
|
|
|
|
// A built-in function.
|
|
typedef AST* (*ASTBIFData)(size_t argc, AST** argv, Scope* scope);
|
|
|
|
// Create a built-in function.
|
|
ASTBIFData* ast_bif_data_init(AST* fn(size_t, AST**, Scope*));
|
|
// Destroy an `ASTBIFData`.
|
|
void ast_bif_data_destroy(ASTBIFData* bif);
|
|
|
|
// A lambda.
|
|
typedef struct {
|
|
PARS; // The parameters the lambda can accept.
|
|
AST* body; // The body expression to be executed.
|
|
} ASTLambdaData;
|
|
|
|
// Creates a new `ASTLambdaData`.
|
|
ASTLambdaData* ast_lambda_data_init(size_t parc, AST** parv, AST* body);
|
|
// Destroy an `ASTLambdaData`.
|
|
void ast_lambda_data_destroy(ASTLambdaData*);
|
|
|
|
// A call.
|
|
typedef struct {
|
|
ARGS; // The arguments the call is made with.
|
|
AST* to; // The expression the call is to (probably either lambda or
|
|
// builtin).
|
|
} ASTCallData;
|
|
|
|
// Create a new `ASTCallData`.
|
|
ASTCallData* ast_call_data_init(size_t argc, AST** argv, AST* to);
|
|
// Destroy an `ASTCallData`.
|
|
void ast_call_data_destroy(ASTCallData* call);
|
|
|
|
// A variable definition. Associates a name with an expression.
|
|
typedef struct {
|
|
char* name;
|
|
AST* exp;
|
|
} ASTVDefData;
|
|
|
|
// Create a new `ASTVDefData`.
|
|
ASTVDefData* ast_vdef_data_init(char* name, AST* exp);
|
|
// Destroy an `ASTVDefData`.
|
|
void ast_vdef_data_destroy(ASTVDefData* vdef);
|
|
|
|
// A variable reference.
|
|
typedef struct {
|
|
char* to; // What the reference's to.
|
|
} ASTVrefData;
|
|
|
|
// Create a new `ASTVRefData`.
|
|
ASTVrefData* ast_vref_data_init(char* to);
|
|
// Destroy an `ASTVRefData`.
|
|
void ast_vref_data_destroy(ASTVrefData* call);
|
|
|
|
// A code block.
|
|
typedef struct {
|
|
AST** inside; // What's inside the block.
|
|
size_t ln; // How many ASTs are in the block.
|
|
} ASTBlockData;
|
|
|
|
// Create a new `ASTBlockData`.
|
|
ASTBlockData* ast_block_data_init(AST** inside, size_t ln);
|
|
// Destroy an `ASTBlockData`, recursively.
|
|
void ast_block_data_destroy(ASTBlockData* block);
|
|
// Destroy an `ASTBlockData`.
|
|
void ast_block_data_destroy_psv(ASTBlockData* block);
|
|
|
|
typedef struct {
|
|
char* name; // Function name.
|
|
ARGS; // Function args.
|
|
AST* body; // Function body.
|
|
} ASTFDefData;
|
|
|
|
// Create a new `ASTFDefData`.
|
|
ASTFDefData* ast_fdef_data_init(char* name, size_t argc, AST** argv, AST* body);
|
|
// Destroy an `ASTFDefData`, recursively.
|
|
void ast_fdef_data_destroy(ASTFDefData* fdef);
|
|
// Destroy an `ASTFDefData`.
|
|
void ast_fdef_data_destroy_psv(ASTFDefData* fdef);
|
|
|
|
typedef struct {
|
|
char* name; // Argument name.
|
|
} ASTArgData;
|
|
|
|
// Create a new `ASTArgData`.
|
|
ASTArgData* ast_arg_data_init(char* name);
|
|
// Destroy an `ASTArgData`.
|
|
void ast_arg_data_destroy(ASTArgData* arg);
|
|
|
|
/*
|
|
// Represents a function as data.
|
|
typedef struct {
|
|
ARGS;
|
|
AST* body;
|
|
} ASTLambdaData;
|
|
|
|
// Creates a new `ASTLambdaData`.
|
|
ASTLambdaData* ast_lambda_data_init(size_t argc, AST** argv, AST* body);
|
|
// Destroy an `ASTLambdaData`.
|
|
void ast_lambda_data_destroy(ASTLambdaData*);
|
|
|
|
*/
|
|
// Find a name in the scope.
|
|
AST* ast_find(Scope* scope, char* name);
|
|
|
|
#endif
|