feat: add initial project scaffolding with Makefile, setup.py, C headers, and Python Environment/Template classes
This commit is contained in:
+148
@@ -0,0 +1,148 @@
|
||||
#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 */
|
||||
Reference in New Issue
Block a user