vessel/web/temple-tokens.c
2025-09-06 22:03:31 +03:00

216 lines
6.7 KiB
C

#include "include/conf.h"
#include "include/temple-tokens.h"
vw_TempleASTNode *vw_TempleASTNode_new_text(const char *start, const char *end) {
if (start >= end) {
return NULL;
}
const size_t len = (size_t)(end - start);
vw_TempleASTNode *node = VS_MALLOC(sizeof(vw_TempleASTNode));
node->type = vw_TempleASTNodeType_text;
node->data.text.text = VS_MALLOC(len + 1);
memcpy(node->data.text.text, start, len);
node->data.text.text[len] = '\0';
node->data.text.len = len;
node->next = NULL;
return node;
}
vw_TempleASTNode *vw_TempleASTNode_new_comment(const char *start, const char *end) {
if (start >= end) {
return NULL;
}
const size_t len = (size_t)(end - start);
vw_TempleASTNode *node = VS_MALLOC(sizeof(vw_TempleASTNode));
node->type = vw_TempleASTNodeType_comment;
node->data.comment.text = VS_MALLOC(len + 1);
memcpy(node->data.comment.text, start, len);
node->data.comment.text[len] = '\0';
node->data.comment.len = len;
node->next = NULL;
return node;
}
vw_TempleASTNode *vw_TempleASTNode_new_unary_expr(vw_TempleASTUnaryOperator operator,
vw_TempleASTNode *operand) {
vw_TempleASTNode *node = malloc(sizeof(vw_TempleASTNode));
node->type = vw_TempleASTNodeType_unary_expr;
node->data.unary.op = operator;
node->data.unary.operand = operand;
node->next = NULL;
return node;
}
const char *vw_TempleASTBinaryOperator_to_str(vw_TempleASTBinaryOperator operator) {
switch (operator) {
case vw_TempleASTBinaryOperator_add:
return "+";
case vw_TempleASTBinaryOperator_sub:
return "-";
case vw_TempleASTBinaryOperator_mul:
return "*";
case vw_TempleASTBinaryOperator_div:
return "/";
case vw_TempleASTBinaryOperator_mod:
return "%";
case vw_TempleASTBinaryOperator_keyword:
return "=";
case vw_TempleASTBinaryOperator_eq:
return "==";
case vw_TempleASTBinaryOperator_neq:
return "!=";
case vw_TempleASTBinaryOperator_lt:
return "<";
case vw_TempleASTBinaryOperator_gt:
return ">";
case vw_TempleASTBinaryOperator_leq:
return "<=";
case vw_TempleASTBinaryOperator_geq:
return ">=";
case vw_TempleASTBinaryOperator_and:
return "&&";
case vw_TempleASTBinaryOperator_or:
return "||";
case vw_TempleASTBinaryOperator_band:
return "&";
case vw_TempleASTBinaryOperator_bor:
return "|";
case vw_TempleASTBinaryOperator_bxor:
return "^";
case vw_TempleASTBinaryOperator_shl:
return "<<";
case vw_TempleASTBinaryOperator_shr:
return ">>";
case vw_TempleASTBinaryOperator_in:
return "@";
}
return "?";
}
const char *vw_TempleASTAssignmentOperator_to_str(vw_TempleASTAssignmentOperator operator) {
switch (operator) {
case vw_TempleASTAssignmentOperator_simple:
return "=";
case vw_TempleASTAssignmentOperator_add:
return "+=";
case vw_TempleASTAssignmentOperator_sub:
return "-=";
case vw_TempleASTAssignmentOperator_mul:
return "*=";
case vw_TempleASTAssignmentOperator_div:
return "/=";
case vw_TempleASTAssignmentOperator_mod:
return "%=";
case vw_TempleASTAssignmentOperator_band:
return "&=";
case vw_TempleASTAssignmentOperator_bor:
return "|=";
case vw_TempleASTAssignmentOperator_bxor:
return "^=";
case vw_TempleASTAssignmentOperator_shl:
return "<<=";
case vw_TempleASTAssignmentOperator_shr:
return ">>=";
}
return "?";
}
const char *vw_TempleASTUnaryOperator_to_str(vw_TempleASTUnaryOperator operator) {
switch (operator) {
case vw_TempleASTUnaryOperator_neg:
return "-";
case vw_TempleASTUnaryOperator_pos:
return "+";
case vw_TempleASTUnaryOperator_not:
return "!";
case vw_TempleASTUnaryOperator_bnot:
return "~";
case vw_TempleASTUnaryOperator_spread:
return "*";
case vw_TempleASTUnaryOperator_kspread:
return "**";
}
return "?";
}
const char *vw_Temple_lex_find_end(const char *start,
const char *end,
const char *closing,
size_t closing_len) {
if (!start || !end || !closing || closing_len == 0) {
return NULL;
}
int parens = 0;
int brackets = 0;
int braces = 0;
bool in_quotes = false;
const char *readp = start;
while (readp <= end) {
const char chr = *readp;
if (in_quotes) {
if (chr == '\\') {
if (readp + 1 <= end) {
++readp;
}
} else if (chr == '"') {
in_quotes = false;
}
} else if (parens == 0 && brackets == 0 && braces == 0 && !in_quotes) {
if ((size_t)(end - readp + 1) >= closing_len &&
strncmp(readp, closing, closing_len) == 0) {
return readp >= start ? readp : NULL;
}
} else {
/* Not inside quotes: check for opening and closing of brackets */
switch (chr) {
case '"':
in_quotes = true;
break;
case '(':
++parens;
break;
case ')':
if (parens == 0) {
return NULL; /* unmatched closing paren */
}
--parens;
break;
case '[':
++brackets;
break;
case ']':
if (brackets == 0) {
return NULL; /* unmatched closing bracket */
}
--brackets;
break;
case '{':
++braces;
break;
case '}':
if (braces == 0) {
return NULL; /* unmatched closing brace */
}
--braces;
break;
default:
break;
}
}
++readp;
}
return NULL;
}