willbooster-tree-sitter-javascript 8.0.0

JavaScript grammar for tree-sitter
Documentation
#ifndef TREE_SITTER_JAVASCRIPT_FUNCTION_CONTEXT_H_
#define TREE_SITTER_JAVASCRIPT_FUNCTION_CONTEXT_H_

#include "tree_sitter/parser.h"

#include <string.h>

typedef struct {
    unsigned depth;
    uint8_t async[TREE_SITTER_SERIALIZATION_BUFFER_SIZE - 4];
    uint8_t generator[TREE_SITTER_SERIALIZATION_BUFFER_SIZE - 4];
    unsigned generator_bytes;
} FunctionContext;

static bool function_context_async(const FunctionContext *context) {
    unsigned index = context->depth - 1;
    return context->depth && (context->async[index / 8] & (1u << (index % 8)));
}

static bool function_context_generator(const FunctionContext *context) {
    unsigned index = context->depth - 1;
    return context->depth && (context->generator[index / 8] & (1u << (index % 8)));
}

static bool function_context_enter(FunctionContext *context, bool async, bool generator) {
    unsigned context_bytes = (context->depth + 8) / 8;
    unsigned generator_bytes = generator ? context_bytes : context->generator_bytes;
    if (4 + context_bytes + generator_bytes > TREE_SITTER_SERIALIZATION_BUFFER_SIZE) return false;
    unsigned index = context->depth++;
    if (async) context->async[index / 8] |= 1u << (index % 8);
    else context->async[index / 8] &= ~(1u << (index % 8));
    if (generator) context->generator[index / 8] |= 1u << (index % 8);
    else context->generator[index / 8] &= ~(1u << (index % 8));
    context->generator_bytes = generator_bytes;
    return true;
}

static void function_context_leave(FunctionContext *context) {
    if (!context->depth) return;
    unsigned index = --context->depth;
    context->async[index / 8] &= ~(1u << (index % 8));
    context->generator[index / 8] &= ~(1u << (index % 8));
    while (context->generator_bytes && !context->generator[context->generator_bytes - 1]) context->generator_bytes--;
}

static unsigned function_context_serialize(const FunctionContext *context, char *buffer) {
    buffer[0] = (char)(context->depth & 0xff);
    buffer[1] = (char)(context->depth >> 8);
    unsigned context_bytes = (context->depth + 7) / 8;
    memcpy(buffer + 2, context->async, context_bytes);
    memcpy(buffer + 2 + context_bytes, context->generator, context->generator_bytes);
    return 2 + context_bytes + context->generator_bytes;
}

static void function_context_deserialize(FunctionContext *context, const char *buffer, unsigned length) {
    context->depth = length >= 2 ? (unsigned char)buffer[0] | ((unsigned char)buffer[1] << 8) : 0;
    unsigned context_bytes = (context->depth + 7) / 8;
    if (context_bytes) memcpy(context->async, buffer + 2, context_bytes);
    context->generator_bytes = length > 2 + context_bytes ? length - 2 - context_bytes : 0;
    memset(context->generator, 0, sizeof(context->generator));
    if (context->generator_bytes) memcpy(context->generator, buffer + 2 + context_bytes, context->generator_bytes);
}

#endif