148 lines
3.3 KiB
C
148 lines
3.3 KiB
C
|
|
#ifndef RINJA_H
|
||
|
|
#define RINJA_H
|
||
|
|
|
||
|
|
#define PY_SSIZE_T_CLEAN
|
||
|
|
#include <Python.h>
|
||
|
|
|
||
|
|
/* retoor <retoor@molodetz.nl> */
|
||
|
|
|
||
|
|
typedef enum {
|
||
|
|
TOKEN_TEXT,
|
||
|
|
TOKEN_VAR_START, TOKEN_VAR_END,
|
||
|
|
TOKEN_BLOCK_START, TOKEN_BLOCK_END,
|
||
|
|
TOKEN_COMMENT_START, TOKEN_COMMENT_END,
|
||
|
|
TOKEN_IDENTIFIER, TOKEN_STRING, TOKEN_NUMBER, TOKEN_OPERATOR,
|
||
|
|
TOKEN_EOF
|
||
|
|
} TokenType;
|
||
|
|
|
||
|
|
typedef struct {
|
||
|
|
TokenType type;
|
||
|
|
const char *start;
|
||
|
|
size_t length;
|
||
|
|
int line;
|
||
|
|
int column;
|
||
|
|
} Token;
|
||
|
|
|
||
|
|
typedef struct {
|
||
|
|
const char *source;
|
||
|
|
const char *current;
|
||
|
|
int line;
|
||
|
|
int column;
|
||
|
|
} Tokenizer;
|
||
|
|
|
||
|
|
typedef enum {
|
||
|
|
EXPR_LITERAL,
|
||
|
|
EXPR_VARIABLE,
|
||
|
|
EXPR_GETATTR,
|
||
|
|
EXPR_GETITEM,
|
||
|
|
EXPR_CALL,
|
||
|
|
EXPR_FILTER,
|
||
|
|
EXPR_TEST,
|
||
|
|
EXPR_BINOP,
|
||
|
|
EXPR_UNOP,
|
||
|
|
EXPR_CONDITIONAL,
|
||
|
|
EXPR_LIST,
|
||
|
|
EXPR_DICT,
|
||
|
|
EXPR_TUPLE
|
||
|
|
} ExpressionType;
|
||
|
|
|
||
|
|
typedef struct Expression {
|
||
|
|
ExpressionType type;
|
||
|
|
union {
|
||
|
|
PyObject* literal;
|
||
|
|
char* identifier;
|
||
|
|
struct {
|
||
|
|
struct Expression* left;
|
||
|
|
char* op;
|
||
|
|
struct Expression* right;
|
||
|
|
} binop;
|
||
|
|
struct {
|
||
|
|
struct Expression* target;
|
||
|
|
char* attr;
|
||
|
|
} getattr;
|
||
|
|
struct {
|
||
|
|
struct Expression* target;
|
||
|
|
struct Expression* arg;
|
||
|
|
} getitem;
|
||
|
|
struct {
|
||
|
|
struct Expression* func;
|
||
|
|
struct Expression** args;
|
||
|
|
int arg_count;
|
||
|
|
} call;
|
||
|
|
struct {
|
||
|
|
struct Expression* target;
|
||
|
|
char* name;
|
||
|
|
struct Expression** args;
|
||
|
|
int arg_count;
|
||
|
|
} filter;
|
||
|
|
struct {
|
||
|
|
struct Expression** items;
|
||
|
|
int count;
|
||
|
|
} list;
|
||
|
|
} data;
|
||
|
|
} Expression;
|
||
|
|
|
||
|
|
typedef enum {
|
||
|
|
NODE_ROOT,
|
||
|
|
NODE_TEXT,
|
||
|
|
NODE_VARIABLE,
|
||
|
|
NODE_IF,
|
||
|
|
NODE_FOR,
|
||
|
|
NODE_WHILE,
|
||
|
|
NODE_BLOCK,
|
||
|
|
NODE_EXTENDS,
|
||
|
|
NODE_INCLUDE,
|
||
|
|
NODE_IMPORT,
|
||
|
|
NODE_MACRO,
|
||
|
|
NODE_SET,
|
||
|
|
NODE_WITH,
|
||
|
|
NODE_FILTER_BLOCK,
|
||
|
|
NODE_CALL,
|
||
|
|
NODE_AUTOESCAPE,
|
||
|
|
NODE_RAW,
|
||
|
|
NODE_DO,
|
||
|
|
NODE_BREAK,
|
||
|
|
NODE_CONTINUE,
|
||
|
|
NODE_MARKDOWN,
|
||
|
|
NODE_LINKIFY,
|
||
|
|
NODE_EMOJI
|
||
|
|
} NodeType;
|
||
|
|
|
||
|
|
typedef struct ASTNode {
|
||
|
|
NodeType type;
|
||
|
|
struct ASTNode *next;
|
||
|
|
struct ASTNode *child;
|
||
|
|
struct ASTNode *alternate; /* else / elif */
|
||
|
|
const char* start;
|
||
|
|
size_t length;
|
||
|
|
char* name;
|
||
|
|
Expression* expr;
|
||
|
|
int trim_left;
|
||
|
|
int trim_right;
|
||
|
|
} ASTNode;
|
||
|
|
|
||
|
|
typedef struct {
|
||
|
|
char* buffer;
|
||
|
|
size_t length;
|
||
|
|
size_t capacity;
|
||
|
|
} StringBuilder;
|
||
|
|
|
||
|
|
/* Function prototypes */
|
||
|
|
void tokenizer_init(Tokenizer* t, const char* source);
|
||
|
|
int tokenizer_is_at_end(Tokenizer* t);
|
||
|
|
Token next_token(Tokenizer* t, int in_expression);
|
||
|
|
Token peek_token(Tokenizer* t, int in_expression);
|
||
|
|
|
||
|
|
ASTNode* parse(const char* source);
|
||
|
|
void free_ast(ASTNode* node);
|
||
|
|
void free_expression(Expression* expr);
|
||
|
|
|
||
|
|
PyObject* render_ast(ASTNode* root, PyObject* context, PyObject* filters, PyObject* tests, PyObject* env);
|
||
|
|
PyObject* apply_builtin_filter(const char* name, PyObject* val, Expression** args, int arg_count, PyObject* context, PyObject* filters, PyObject* tests, PyObject* env);
|
||
|
|
PyObject* apply_builtin_test(const char* name, PyObject* val, PyObject* tests);
|
||
|
|
|
||
|
|
void sb_init(StringBuilder* sb);
|
||
|
|
void sb_append(StringBuilder* sb, const char* text, size_t len);
|
||
|
|
void sb_free(StringBuilder* sb);
|
||
|
|
|
||
|
|
#endif /* RINJA_H */
|