216 lines
6.7 KiB
C
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;
|
|
}
|