#ifndef STACK_GRAPHS_H_
#define STACK_GRAPHS_H_
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#define SG_NULL_HANDLE 0
#define SG_LIST_EMPTY_HANDLE 4294967295
#define SG_ROOT_NODE_ID 1
#define SG_JUMP_TO_NODE_ID 2
enum sg_deque_direction {
SG_DEQUE_FORWARDS,
SG_DEQUE_BACKWARDS,
};
enum sg_node_kind {
SG_NODE_KIND_DROP_SCOPES,
SG_NODE_KIND_JUMP_TO,
SG_NODE_KIND_POP_SCOPED_SYMBOL,
SG_NODE_KIND_POP_SYMBOL,
SG_NODE_KIND_PUSH_SCOPED_SYMBOL,
SG_NODE_KIND_PUSH_SYMBOL,
SG_NODE_KIND_ROOT,
SG_NODE_KIND_SCOPE,
};
enum sg_result {
SG_RESULT_SUCCESS,
SG_RESULT_CANCELLED,
};
struct sg_partial_path_arena;
struct sg_partial_path_database;
struct sg_partial_path_list;
struct sg_stack_graph;
struct sg_symbol {
const char *symbol;
size_t symbol_len;
};
struct sg_symbols {
const struct sg_symbol *symbols;
size_t count;
};
typedef uint32_t sg_symbol_handle;
struct sg_string {
const char *content;
size_t length;
};
struct sg_strings {
const struct sg_string *strings;
size_t count;
};
typedef uint32_t sg_string_handle;
struct sg_file {
const char *name;
size_t name_len;
};
struct sg_files {
const struct sg_file *files;
size_t count;
};
typedef uint32_t sg_file_handle;
struct sg_node_id {
sg_file_handle file;
uint32_t local_id;
};
struct sg_node {
enum sg_node_kind kind;
struct sg_node_id id;
sg_symbol_handle symbol;
struct sg_node_id scope;
bool is_endpoint;
};
struct sg_nodes {
const struct sg_node *nodes;
size_t count;
};
typedef uint32_t sg_node_handle;
struct sg_edge {
sg_node_handle source;
sg_node_handle sink;
int32_t precedence;
};
struct sg_offset {
size_t utf8_offset;
size_t utf16_offset;
size_t grapheme_offset;
};
struct sg_utf8_bounds {
size_t start;
size_t end;
};
struct sg_position {
size_t line;
struct sg_offset column;
struct sg_utf8_bounds containing_line;
struct sg_utf8_bounds trimmed_line;
};
struct sg_span {
struct sg_position start;
struct sg_position end;
};
struct sg_source_info {
struct sg_span span;
sg_string_handle syntax_type;
sg_string_handle containing_line;
struct sg_span definiens_span;
sg_string_handle fully_qualified_name;
};
struct sg_source_infos {
const struct sg_source_info *infos;
size_t count;
};
struct sg_node_source_info {
sg_node_handle node;
struct sg_source_info source_info;
};
typedef uint32_t sg_partial_scope_stack_cell_handle;
typedef uint32_t sg_scope_stack_variable;
struct sg_partial_scope_stack {
sg_partial_scope_stack_cell_handle cells;
enum sg_deque_direction direction;
uint32_t length;
sg_scope_stack_variable variable;
};
struct sg_partial_scoped_symbol {
sg_symbol_handle symbol;
struct sg_partial_scope_stack scopes;
};
typedef uint32_t sg_partial_symbol_stack_cell_handle;
struct sg_partial_symbol_stack_cell {
struct sg_partial_scoped_symbol head;
sg_partial_symbol_stack_cell_handle tail;
sg_partial_symbol_stack_cell_handle reversed;
};
struct sg_partial_symbol_stack_cells {
const struct sg_partial_symbol_stack_cell *cells;
size_t count;
};
typedef uint32_t sg_symbol_stack_variable;
struct sg_partial_symbol_stack {
sg_partial_symbol_stack_cell_handle cells;
enum sg_deque_direction direction;
uint32_t length;
sg_symbol_stack_variable variable;
};
struct sg_partial_scope_stack_cell {
sg_node_handle head;
sg_partial_scope_stack_cell_handle tail;
sg_partial_scope_stack_cell_handle reversed;
};
struct sg_partial_scope_stack_cells {
const struct sg_partial_scope_stack_cell *cells;
size_t count;
};
struct sg_partial_path_edge {
struct sg_node_id source_node_id;
int32_t precedence;
};
typedef uint32_t sg_partial_path_edge_list_cell_handle;
struct sg_partial_path_edge_list_cell {
struct sg_partial_path_edge head;
sg_partial_path_edge_list_cell_handle tail;
sg_partial_path_edge_list_cell_handle reversed;
};
struct sg_partial_path_edge_list_cells {
const struct sg_partial_path_edge_list_cell *cells;
size_t count;
};
struct sg_partial_path_edge_list {
sg_partial_path_edge_list_cell_handle cells;
enum sg_deque_direction direction;
uint32_t length;
};
struct sg_partial_path {
sg_node_handle start_node;
sg_node_handle end_node;
struct sg_partial_symbol_stack symbol_stack_precondition;
struct sg_partial_symbol_stack symbol_stack_postcondition;
struct sg_partial_scope_stack scope_stack_precondition;
struct sg_partial_scope_stack scope_stack_postcondition;
struct sg_partial_path_edge_list edges;
};
struct sg_stitcher_config {
bool detect_similar_paths;
};
struct sg_partial_paths {
const struct sg_partial_path *paths;
size_t count;
};
typedef uint32_t sg_partial_path_handle;
struct sg_node_handle_set {
const uint32_t *elements;
size_t length;
};
struct sg_forward_partial_path_stitcher {
const struct sg_partial_path *previous_phase_partial_paths;
size_t previous_phase_partial_paths_length;
bool is_complete;
};
#define SG_ROOT_NODE_HANDLE 1
#define SG_JUMP_TO_NODE_HANDLE 2
#ifdef __cplusplus
extern "C" {
#endif
struct sg_stack_graph *sg_stack_graph_new(void);
void sg_stack_graph_free(struct sg_stack_graph *graph);
struct sg_partial_path_arena *sg_partial_path_arena_new(void);
void sg_partial_path_arena_free(struct sg_partial_path_arena *partials);
struct sg_partial_path_database *sg_partial_path_database_new(void);
void sg_partial_path_database_free(struct sg_partial_path_database *db);
void sg_partial_path_database_ensure_both_directions(struct sg_partial_path_database *db,
struct sg_partial_path_arena *partials);
void sg_partial_path_database_ensure_forwards(struct sg_partial_path_database *db,
struct sg_partial_path_arena *partials);
struct sg_symbols sg_stack_graph_symbols(const struct sg_stack_graph *graph);
void sg_stack_graph_add_symbols(struct sg_stack_graph *graph,
size_t count,
const char *symbols,
const size_t *lengths,
sg_symbol_handle *handles_out);
struct sg_strings sg_stack_graph_strings(const struct sg_stack_graph *graph);
void sg_stack_graph_add_strings(struct sg_stack_graph *graph,
size_t count,
const char *strings,
const size_t *lengths,
sg_string_handle *handles_out);
struct sg_files sg_stack_graph_files(const struct sg_stack_graph *graph);
void sg_stack_graph_add_files(struct sg_stack_graph *graph,
size_t count,
const char *files,
const size_t *lengths,
sg_file_handle *handles_out);
struct sg_nodes sg_stack_graph_nodes(const struct sg_stack_graph *graph);
void sg_stack_graph_get_or_create_nodes(struct sg_stack_graph *graph,
size_t count,
const struct sg_node *nodes,
sg_node_handle *handles_out);
void sg_stack_graph_add_edges(struct sg_stack_graph *graph,
size_t count,
const struct sg_edge *edges);
struct sg_source_infos sg_stack_graph_source_infos(const struct sg_stack_graph *graph);
void sg_stack_graph_add_source_infos(struct sg_stack_graph *graph,
size_t count,
const struct sg_node_source_info *infos);
struct sg_partial_symbol_stack_cells sg_partial_path_arena_partial_symbol_stack_cells(const struct sg_partial_path_arena *partials);
void sg_partial_path_arena_add_partial_symbol_stacks(struct sg_partial_path_arena *partials,
size_t count,
const struct sg_partial_scoped_symbol *symbols,
const size_t *lengths,
const sg_symbol_stack_variable *variables,
struct sg_partial_symbol_stack *out);
struct sg_partial_scope_stack_cells sg_partial_path_arena_partial_scope_stack_cells(const struct sg_partial_path_arena *partials);
void sg_partial_path_arena_add_partial_scope_stacks(struct sg_partial_path_arena *partials,
size_t count,
const sg_node_handle *scopes,
const size_t *lengths,
const sg_scope_stack_variable *variables,
struct sg_partial_scope_stack *out);
struct sg_partial_path_edge_list_cells sg_partial_path_arena_partial_path_edge_list_cells(const struct sg_partial_path_arena *partials);
void sg_partial_path_arena_add_partial_path_edge_lists(struct sg_partial_path_arena *partials,
size_t count,
const struct sg_partial_path_edge *edges,
const size_t *lengths,
struct sg_partial_path_edge_list *out);
struct sg_partial_path_list *sg_partial_path_list_new(void);
void sg_partial_path_list_free(struct sg_partial_path_list *partial_path_list);
size_t sg_partial_path_list_count(const struct sg_partial_path_list *partial_path_list);
const struct sg_partial_path *sg_partial_path_list_paths(const struct sg_partial_path_list *partial_path_list);
enum sg_result sg_partial_path_arena_find_partial_paths_in_file(const struct sg_stack_graph *graph,
struct sg_partial_path_arena *partials,
sg_file_handle file,
struct sg_partial_path_list *partial_path_list,
const struct sg_stitcher_config *stitcher_config,
const size_t *cancellation_flag);
enum sg_result sg_partial_path_arena_find_all_complete_paths(const struct sg_stack_graph *graph,
struct sg_partial_path_arena *partials,
size_t starting_node_count,
const sg_node_handle *starting_nodes,
struct sg_partial_path_list *path_list,
const struct sg_stitcher_config *stitcher_config,
const size_t *cancellation_flag);
struct sg_partial_paths sg_partial_path_database_partial_paths(const struct sg_partial_path_database *db);
void sg_partial_path_database_add_partial_paths(const struct sg_stack_graph *graph,
struct sg_partial_path_arena *partials,
struct sg_partial_path_database *db,
size_t count,
const struct sg_partial_path *paths,
sg_partial_path_handle *out);
void sg_partial_path_database_find_local_nodes(struct sg_partial_path_database *db);
void sg_partial_path_database_mark_local_nodes(struct sg_partial_path_database *db,
size_t count,
const sg_node_handle *nodes);
struct sg_node_handle_set sg_partial_path_database_local_nodes(const struct sg_partial_path_database *db);
struct sg_forward_partial_path_stitcher *sg_forward_partial_path_stitcher_from_nodes(const struct sg_stack_graph *graph,
struct sg_partial_path_arena *partials,
size_t count,
const sg_node_handle *starting_nodes);
struct sg_forward_partial_path_stitcher *sg_forward_partial_path_stitcher_from_partial_paths(const struct sg_stack_graph *graph,
struct sg_partial_path_arena *partials,
size_t count,
const struct sg_partial_path *initial_partial_paths);
void sg_forward_partial_path_stitcher_set_similar_path_detection(struct sg_forward_partial_path_stitcher *stitcher,
bool detect_similar_paths);
void sg_forward_partial_path_stitcher_set_max_work_per_phase(struct sg_forward_partial_path_stitcher *stitcher,
size_t max_work);
void sg_forward_partial_path_stitcher_process_next_phase(const struct sg_stack_graph *graph,
struct sg_partial_path_arena *partials,
struct sg_partial_path_database *db,
struct sg_forward_partial_path_stitcher *stitcher);
void sg_forward_partial_path_stitcher_free(struct sg_forward_partial_path_stitcher *stitcher);
#ifdef __cplusplus
} #endif
#endif