Files
wehub-resource-sync 41cb1c0170
OpenSSF Scorecard / scorecard (push) Failing after 0s
DCO / dco (push) Failing after 0s
CodeQL SAST / analyze (push) Failing after 1s
Deploy Pages / deploy (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 12:28:05 +08:00

130 lines
4.3 KiB
C
Generated

#include "objectscript_common.h"
#include "tree_sitter/parser.h"
#include <string.h>
// There is no way to extend enums, so keep this in sync with base.h
// All new entries should be appended at the bottom of the list
enum TokenType {
EXTERNAL_METHOD_BODY_CONTENT = OBJECTSCRIPT_CORE_TOKEN_TYPE_MAX,
IRIS_USERNAME,
};
struct ObjectScript_Udl_Scanner {
char in_body;
struct ObjectScript_Core_Scanner core_scanner;
};
static bool lex_fenced_text(TSLexer *lexer,
enum TokenType desired_symbol, char l_delim,
char r_delim) {
int leftRightDiff = 1;
while (!lexer->eof(lexer)) {
if (lexer->lookahead == r_delim) {
leftRightDiff -= 1;
} else if (lexer->lookahead == l_delim) {
leftRightDiff += 1;
}
if (leftRightDiff == 0) {
lexer->result_symbol = desired_symbol;
return true;
}
advance(lexer);
}
return false;
}
/// This is the interesting function. The rest is infrastructure
static bool scan(void *payload, TSLexer *lexer, const bool *valid_symbols) {
// struct Scanner *scanner = (struct Scanner *)payload;
//
// Tree sitter will mark all terminals as valid on error
// The sentinel should never be valid in a good parse, so this ensures
// we are not in error recovery mode
// printf("Lookahead: '%c'. Col %d. Tag is valid? %d", lexer->lookahead,
// lexer->get_column(lexer), valid_symbols[TAG]);
// printf("lexer->lookahead: '%c'\n", lexer->lookahead);
// printf("====\n");
// debug_enum(valid_symbols);
// printf("====\n");
if (valid_symbols[SENTINEL]) {
// printf("Thats not good!\n");
// // TODO: ERROR RECOVERY MODE ?? Why would we be better than TS's
// default? if (iswspace(lexer->lookahead)) {
// skip(lexer);
// eat_whitespace(lexer);
// lexer->result_symbol = _WHITESPACE;
// return true;
// }
return false;
}
if (valid_symbols[EXTERNAL_METHOD_BODY_CONTENT]) {
// A valid method_body is one that is whose text fences
// are evenly balanced (so far only { })
// e.g. VALID: {{{ [^{}]* }}} INVALID: {{{ [^{}]* }
return lex_fenced_text(lexer, EXTERNAL_METHOD_BODY_CONTENT, '{',
'}');
}
if (valid_symbols[IRIS_USERNAME] && !(lexer->lookahead=='}' || lexer->lookahead=='@' || lexer->lookahead=='*')) {
int count=0;
lexer->mark_end(lexer);
while(!lexer->eof(lexer) && !(lexer->lookahead=='}' || lexer->lookahead=='@' || lexer->lookahead=='*') && count<160 ) {
count++;
advance(lexer);
}
if(lexer->lookahead=='}') {
lexer->mark_end(lexer);
lexer->result_symbol = IRIS_USERNAME;
return true;
}
else {
return false;
}
}
struct ObjectScript_Udl_Scanner *scanner =
(struct ObjectScript_Udl_Scanner *)payload;
return ObjectScript_Core_Scanner_scan(&scanner->core_scanner, lexer,
valid_symbols);
}
void *tree_sitter_objectscript_udl_external_scanner_create() {
struct ObjectScript_Udl_Scanner *scanner =
(struct ObjectScript_Udl_Scanner *)calloc(
1, sizeof(struct ObjectScript_Udl_Scanner));
scanner->in_body = 0;
ObjectScript_Core_Scanner_init(&scanner->core_scanner);
scanner->core_scanner.column1_statement_mode = false;
return scanner;
}
bool tree_sitter_objectscript_udl_external_scanner_scan(
void *payload, TSLexer *lexer, const bool *valid_symbols) {
return scan(payload, lexer, valid_symbols);
}
unsigned tree_sitter_objectscript_udl_external_scanner_serialize(void *payload,
char *buffer) {
struct ObjectScript_Udl_Scanner *scanner =
(struct ObjectScript_Udl_Scanner *)payload;
memcpy(buffer, scanner, sizeof(struct ObjectScript_Udl_Scanner));
return sizeof(struct ObjectScript_Udl_Scanner);
}
void tree_sitter_objectscript_udl_external_scanner_deserialize(
void *payload, const char *buffer, unsigned length) {
// This one is a bit funky.
// length includes the sizeof(struct Scanner) and the structs it points to
memcpy(payload, buffer, length);
}
void tree_sitter_objectscript_udl_external_scanner_destroy(void *payload) {
struct ObjectScript_Udl_Scanner *scanner =
(struct ObjectScript_Udl_Scanner *)payload;
free(scanner);
}