Format the code with clang-format.
This commit is contained in:
parent
22ed67f0a4
commit
5d3130d39d
3
.clang-format
Normal file
3
.clang-format
Normal file
|
@ -0,0 +1,3 @@
|
|||
BasedOnStyle: LLVM
|
||||
PointerAlignment: Left
|
||||
IndentWidth: 4
|
|
@ -1,17 +1,14 @@
|
|||
#ifndef LIBABACUS_BASETYPE_H
|
||||
#define LIBABACUS_BASETYPE_H
|
||||
|
||||
#include "vec.h"
|
||||
#include "result.h"
|
||||
#include "vec.h"
|
||||
|
||||
/**
|
||||
* An enum that represents the various
|
||||
* types of the basetype parameters.
|
||||
*/
|
||||
enum libab_basetype_variant_e {
|
||||
BT_NAME,
|
||||
BT_LIST
|
||||
};
|
||||
enum libab_basetype_variant_e { BT_NAME, BT_LIST };
|
||||
|
||||
/**
|
||||
* A struct that holds information about the basetype
|
||||
|
|
|
@ -22,10 +22,7 @@ enum libab_operator_variant_e {
|
|||
/**
|
||||
* The variant of the implementation of a behavior.
|
||||
*/
|
||||
enum libab_behavior_variant_e {
|
||||
BIMPL_INTERNAL,
|
||||
BIMPL_TREE
|
||||
};
|
||||
enum libab_behavior_variant_e { BIMPL_INTERNAL, BIMPL_TREE };
|
||||
|
||||
/**
|
||||
* A struct that represents the implementation of a behavior.
|
||||
|
|
|
@ -90,7 +90,8 @@ libab_result libab_lexer_init(libab_lexer* lexer);
|
|||
* @param lex_into the list which should be populated with matches.
|
||||
* @return the result of the operation.
|
||||
*/
|
||||
libab_result libab_lexer_lex(libab_lexer* lexer, const char* string, ll* lext_into);
|
||||
libab_result libab_lexer_lex(libab_lexer* lexer, const char* string,
|
||||
ll* lext_into);
|
||||
/**
|
||||
* Releases the memory associated with the given lexer,
|
||||
* removing all registered patterns from it.
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef LIBABACUS_H
|
||||
#define LIBABACUS_H
|
||||
|
||||
#include "custom.h"
|
||||
#include "ht.h"
|
||||
#include "lexer.h"
|
||||
#include "table.h"
|
||||
#include "parser.h"
|
||||
#include "result.h"
|
||||
#include "custom.h"
|
||||
#include "table.h"
|
||||
|
||||
/**
|
||||
* The main struct of libabacus,
|
||||
|
@ -50,7 +50,10 @@ libab_result libab_init(libab* ab);
|
|||
* @param func the function that describes the functionality of the operator.
|
||||
* @return the result of the initialization.
|
||||
*/
|
||||
libab_result libab_register_operator_infix(libab* ab, const char* op, int precedence, int associativity, libab_ref* type, libab_function_ptr func);
|
||||
libab_result libab_register_operator_infix(libab* ab, const char* op,
|
||||
int precedence, int associativity,
|
||||
libab_ref* type,
|
||||
libab_function_ptr func);
|
||||
/**
|
||||
* Registers an operation with libabacus that appears
|
||||
* before its operand.
|
||||
|
@ -60,7 +63,9 @@ libab_result libab_register_operator_infix(libab* ab, const char* op, int preced
|
|||
* @param func the function that describes the functionality of the operator.
|
||||
* @return the result of the registration.
|
||||
*/
|
||||
libab_result libab_register_operator_prefix(libab* ab, const char* op, libab_ref* type, libab_function_ptr func);
|
||||
libab_result libab_register_operator_prefix(libab* ab, const char* op,
|
||||
libab_ref* type,
|
||||
libab_function_ptr func);
|
||||
/**
|
||||
* Registers an operation with libabacus that appears
|
||||
* after its operand.
|
||||
|
@ -70,7 +75,9 @@ libab_result libab_register_operator_prefix(libab* ab, const char* op, libab_ref
|
|||
* @param func the function that describes the functionality of the operator.
|
||||
* @return the result of the registration.
|
||||
*/
|
||||
libab_result libab_register_operator_postfix(libab* ab, const char* op, libab_ref* type, libab_function_ptr func);
|
||||
libab_result libab_register_operator_postfix(libab* ab, const char* op,
|
||||
libab_ref* type,
|
||||
libab_function_ptr func);
|
||||
|
||||
/**
|
||||
* Registers a function with libabacus.
|
||||
|
@ -80,7 +87,8 @@ libab_result libab_register_operator_postfix(libab* ab, const char* op, libab_re
|
|||
* @param func the function that describes the functionality of the function.
|
||||
* @return the result of the registration.
|
||||
*/
|
||||
libab_result libab_register_function(libab* ab, const char* name, libab_ref* type, libab_function_ptr func);
|
||||
libab_result libab_register_function(libab* ab, const char* name,
|
||||
libab_ref* type, libab_function_ptr func);
|
||||
/**
|
||||
* Registers a base type with abacus.
|
||||
* @param ab the libabacus instance used to keep state.
|
||||
|
@ -88,7 +96,8 @@ libab_result libab_register_function(libab* ab, const char* name, libab_ref* typ
|
|||
* @param basetype the basetype to register.
|
||||
* @return the result of the registration.
|
||||
*/
|
||||
libab_result libab_register_basetype(libab* ab, const char* name, libab_basetype* basetype);
|
||||
libab_result libab_register_basetype(libab* ab, const char* name,
|
||||
libab_basetype* basetype);
|
||||
/**
|
||||
* Constructs and resolves a parse type, similarly to how it's done in the
|
||||
* parser.
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef LIBABACUS_PARSER_H
|
||||
#define LIBABACUS_PARSER_H
|
||||
|
||||
#include "table.h"
|
||||
#include "ll.h"
|
||||
#include "tree.h"
|
||||
#include "parsetype.h"
|
||||
#include "table.h"
|
||||
#include "tree.h"
|
||||
|
||||
/**
|
||||
* The parser that is used by libabacus
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef LIBABACUS_PARSETYPE_H
|
||||
#define LIBABACUS_PARSETYPE_H
|
||||
|
||||
#include "result.h"
|
||||
#include "ref_vec.h"
|
||||
#include "basetype.h"
|
||||
#include "ref_vec.h"
|
||||
#include "result.h"
|
||||
|
||||
#define LIBABACUS_TYPE_F_PARENT (1)
|
||||
#define LIBABACUS_TYPE_F_PLACE (1 << 1)
|
||||
|
|
|
@ -62,14 +62,16 @@ void libab_ref_trie_init(libab_ref_trie* trie);
|
|||
* @param ref the reference to insert.
|
||||
* @return the result of the insertion.
|
||||
*/
|
||||
libab_result libab_ref_trie_put(libab_ref_trie* trie, const char* key, libab_ref* ref);
|
||||
libab_result libab_ref_trie_put(libab_ref_trie* trie, const char* key,
|
||||
libab_ref* ref);
|
||||
/**
|
||||
* Retreives a reference under the given key in the trie.
|
||||
* @param trie the trie to retreive from.
|
||||
* @param key the key to look under.
|
||||
* @return a reference stored under the given key. This can be a NULL reference.
|
||||
*/
|
||||
const libab_ref* libab_ref_trie_get(const libab_ref_trie* trie, const char* key);
|
||||
const libab_ref* libab_ref_trie_get(const libab_ref_trie* trie,
|
||||
const char* key);
|
||||
/**
|
||||
* Releases the trie, decrementing the refcounts of all
|
||||
* the values stored inside.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef LIBABACUS_REF_VEC_H
|
||||
#define LIBABACUS_REF_VEC_H
|
||||
|
||||
#include "result.h"
|
||||
#include "refcount.h"
|
||||
#include "result.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LIBABACUS_REF_VEC_INITIAL_SIZE 4
|
||||
|
@ -50,10 +50,11 @@ libab_result libab_ref_vec_insert(libab_ref_vec* vec, libab_ref* data);
|
|||
* @param free_func the function called to release the value (besides free)
|
||||
* @return the result of the insertion.
|
||||
*/
|
||||
libab_result libab_ref_vec_insert_value(libab_ref_vec* vec, void* data, void (*free_func)(void*));
|
||||
libab_result libab_ref_vec_insert_value(libab_ref_vec* vec, void* data,
|
||||
void (*free_func)(void*));
|
||||
/**
|
||||
* Returns the value at the given index in the vector, or null or the value doesn't
|
||||
* exist.
|
||||
* Returns the value at the given index in the vector, or null or the value
|
||||
* doesn't exist.
|
||||
* @param vec the vector to get a value from.
|
||||
* @param index the index to look at.
|
||||
* @return the reference stored at the given index.
|
||||
|
|
|
@ -53,10 +53,12 @@ typedef struct libab_ref_count_s libab_ref_count;
|
|||
* Creates a new referene, using the given data and free function.
|
||||
* @param ref the reference to initialize with the given data.
|
||||
* @param data the data to reference count.
|
||||
* @param free_func the function to use to realease the data when refcount reaches 0.
|
||||
* @param free_func the function to use to realease the data when refcount
|
||||
* reaches 0.
|
||||
* @return the result of the construction of the reference.
|
||||
*/
|
||||
libab_result libab_ref_new(libab_ref* ref, void* data, void (*free_func)(void* data));
|
||||
libab_result libab_ref_new(libab_ref* ref, void* data,
|
||||
void (*free_func)(void* data));
|
||||
/**
|
||||
* Creates a reference to NULL. This does
|
||||
* not require a memory allocation.
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef LIBABACUS_RESERVED_H
|
||||
#define LIBABACUS_RESERVED_H
|
||||
|
||||
#include "result.h"
|
||||
#include "parsetype.h"
|
||||
#include "tree.h"
|
||||
#include "libabacus.h"
|
||||
#include "parsetype.h"
|
||||
#include "result.h"
|
||||
#include "tree.h"
|
||||
|
||||
/**
|
||||
* Struct that represents a reserved operator that contains
|
||||
|
@ -31,7 +31,8 @@ typedef struct libab_reserved_operator_s libab_reserved_operator;
|
|||
* Attempts to find a reserved operator with the given name.
|
||||
* This function operates under the assumption that there are
|
||||
* few reserved operators in libabacus. As such, it does effectively
|
||||
* a polynomial time search - strcmp for every element until the operator is found.
|
||||
* a polynomial time search - strcmp for every element until the operator is
|
||||
* found.
|
||||
* @param name the name to search for.
|
||||
* @return the reserved operator, if it is found.
|
||||
*/
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef LIBABACUS_TABLE_H
|
||||
#define LIBABACUS_TABLE_H
|
||||
|
||||
#include "result.h"
|
||||
#include "custom.h"
|
||||
#include "trie.h"
|
||||
#include "basetype.h"
|
||||
#include "custom.h"
|
||||
#include "result.h"
|
||||
#include "trie.h"
|
||||
|
||||
/**
|
||||
* A struct that represents a structure
|
||||
|
@ -72,7 +72,9 @@ void libab_table_init(libab_table* table);
|
|||
* @param compare the comparison function to use.
|
||||
* @return the table entry, or NULL if an entry was not found.
|
||||
*/
|
||||
libab_table_entry* libab_table_search_filter(libab_table* table, const char* string, void* data, compare_func compare);
|
||||
libab_table_entry* libab_table_search_filter(libab_table* table,
|
||||
const char* string, void* data,
|
||||
compare_func compare);
|
||||
/**
|
||||
* Searches for the given string in the table.
|
||||
* @param table the table to search.
|
||||
|
@ -88,7 +90,8 @@ libab_table_entry* libab_table_search(libab_table* table, const char* string);
|
|||
* @param type the type of operator to search for (infix, prefix, postfix)
|
||||
* @return the found operator, or NULL if it was not found.
|
||||
*/
|
||||
libab_operator* libab_table_search_operator(libab_table* table, const char* string, int type);
|
||||
libab_operator* libab_table_search_operator(libab_table* table,
|
||||
const char* string, int type);
|
||||
/**
|
||||
* Searches for the given string in the table, returning a value only
|
||||
* if it is a function.
|
||||
|
@ -96,7 +99,8 @@ libab_operator* libab_table_search_operator(libab_table* table, const char* stri
|
|||
* @param string the string to search for.
|
||||
* @return the found function, or NULL if it was not found.
|
||||
*/
|
||||
libab_function* libab_table_search_function(libab_table* table, const char* string);
|
||||
libab_function* libab_table_search_function(libab_table* table,
|
||||
const char* string);
|
||||
/**
|
||||
* Searches for the given basetype in the table, returning a value
|
||||
* only if it's a basetype.
|
||||
|
@ -104,7 +108,8 @@ libab_function* libab_table_search_function(libab_table* table, const char* stri
|
|||
* @param string the string to search for.
|
||||
* @return the found basetype, or NULL if it was not found.
|
||||
*/
|
||||
libab_basetype* libab_table_search_basetype(libab_table* table, const char* string);
|
||||
libab_basetype* libab_table_search_basetype(libab_table* table,
|
||||
const char* string);
|
||||
/**
|
||||
* Stores the given entry in the table under the given key.
|
||||
* @param table the table to store the entry into.
|
||||
|
@ -112,7 +117,8 @@ libab_basetype* libab_table_search_basetype(libab_table* table, const char* stri
|
|||
* @param entry the new entry to put into the table.
|
||||
* @return the result of the insertion, which could be LIBAB_MALLOC.
|
||||
*/
|
||||
libab_result libab_table_put(libab_table* table, const char* string, libab_table_entry* entry);
|
||||
libab_result libab_table_put(libab_table* table, const char* string,
|
||||
libab_table_entry* entry);
|
||||
/**
|
||||
* Frees the resources allocated by the
|
||||
* given table.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef LIBABACUS_TREE_H
|
||||
#define LIBABACUS_TREE_H
|
||||
|
||||
#include "result.h"
|
||||
#include "parsetype.h"
|
||||
#include "result.h"
|
||||
#include "vec.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -58,7 +58,8 @@ typedef struct libab_trie_node_s libab_trie_node;
|
|||
void libab_trie_init(libab_trie* trie);
|
||||
libab_result libab_trie_put(libab_trie* trie, const char* key, void* value);
|
||||
const ll* libab_trie_get(const libab_trie* trie, const char* key);
|
||||
int libab_trie_foreach(const libab_trie* trie, void* data, compare_func compare, foreach_func foreach);
|
||||
int libab_trie_foreach(const libab_trie* trie, void* data, compare_func compare,
|
||||
foreach_func foreach);
|
||||
void libab_trie_free(libab_trie* trie);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include "libds.h"
|
||||
#include "liblex.h"
|
||||
#include "result.h"
|
||||
#include "parsetype.h"
|
||||
#include "result.h"
|
||||
#include "table.h"
|
||||
#include <string.h>
|
||||
|
||||
|
@ -21,15 +21,16 @@ libab_result libab_convert_lex_result(liblex_result to_convert);
|
|||
*/
|
||||
libab_result libab_convert_ds_result(libds_result to_convert);
|
||||
/**
|
||||
* Copies a range of the given string into a new, null-terminated string allocated
|
||||
* on the heap.
|
||||
* Copies a range of the given string into a new, null-terminated string
|
||||
* allocated on the heap.
|
||||
* @param destination the pointer to populate with the newly created string.
|
||||
* @param source the source from which to pull character information from.
|
||||
* @param from the index (inclusive) at which to begin copying.
|
||||
* @param to the index (exclusive) at which to end copying.
|
||||
* @return the result of the operation.
|
||||
*/
|
||||
libab_result libab_copy_string_range(char** destination, const char* source, size_t from, size_t to);
|
||||
libab_result libab_copy_string_range(char** destination, const char* source,
|
||||
size_t from, size_t to);
|
||||
/**
|
||||
* Copies the given string, starting at 0 and copying length bytes.
|
||||
* @param destination the pointer to populate with the newly created string.
|
||||
|
@ -37,7 +38,8 @@ libab_result libab_copy_string_range(char** destination, const char* source, siz
|
|||
* @param length the number of bytes to copy.
|
||||
* @return the result of the operation.
|
||||
*/
|
||||
libab_result libab_copy_string_size(char** destination, const char* source, size_t length);
|
||||
libab_result libab_copy_string_size(char** destination, const char* source,
|
||||
size_t length);
|
||||
/**
|
||||
* Copies the entire string into a null-terminated string allocated
|
||||
* on the heap.
|
||||
|
@ -52,6 +54,7 @@ libab_result libab_copy_string(char** destination, const char* source);
|
|||
* @param to_resolve the parsetype to resolve.
|
||||
* @param scope the scope to use for resolving the type info.
|
||||
*/
|
||||
libab_result libab_resolve_parsetype(libab_parsetype* to_resolve, libab_table* scope);
|
||||
libab_result libab_resolve_parsetype(libab_parsetype* to_resolve,
|
||||
libab_table* scope);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef LIBABACUS_VALUE_H
|
||||
#define LIBABACUS_VALUE_H
|
||||
|
||||
#include "result.h"
|
||||
#include "refcount.h"
|
||||
#include "result.h"
|
||||
|
||||
/**
|
||||
* A struct that represents a value.
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void libab_basetype_init(libab_basetype* basetype,
|
||||
int n, const libab_basetype_param params[]) {
|
||||
void libab_basetype_init(libab_basetype* basetype, int n,
|
||||
const libab_basetype_param params[]) {
|
||||
basetype->params = params;
|
||||
basetype->count = n;
|
||||
}
|
||||
void libab_basetype_free(libab_basetype* basetype) {
|
||||
|
||||
}
|
||||
void libab_basetype_free(libab_basetype* basetype) {}
|
||||
|
|
24
src/debug.c
24
src/debug.c
|
@ -4,24 +4,9 @@ int _debug_foreach_print_tree(void* data, va_list args);
|
|||
|
||||
const char* _debug_node_name(libab_tree_variant var) {
|
||||
static const char* names[] = {
|
||||
"none",
|
||||
"base",
|
||||
"id",
|
||||
"num",
|
||||
"op",
|
||||
"reserved_op",
|
||||
"prefix_op",
|
||||
"postfix_op",
|
||||
"block",
|
||||
"void",
|
||||
"if",
|
||||
"while",
|
||||
"dowhile",
|
||||
"call",
|
||||
"fun",
|
||||
"fun_param",
|
||||
"return"
|
||||
};
|
||||
"none", "base", "id", "num", "op", "reserved_op",
|
||||
"prefix_op", "postfix_op", "block", "void", "if", "while",
|
||||
"dowhile", "call", "fun", "fun_param", "return"};
|
||||
return names[var];
|
||||
}
|
||||
|
||||
|
@ -35,7 +20,8 @@ void _debug_print_tree_node(libab_tree* tree, FILE* file) {
|
|||
|
||||
void _debug_print_tree(libab_tree* tree, FILE* file, int depth) {
|
||||
int i = depth;
|
||||
while(i--) printf(" ");
|
||||
while (i--)
|
||||
printf(" ");
|
||||
_debug_print_tree_node(tree, file);
|
||||
if (libab_tree_has_vector(tree->variant)) {
|
||||
vec_foreach(&tree->children, NULL, compare_always,
|
||||
|
|
30
src/lexer.c
30
src/lexer.c
|
@ -1,14 +1,13 @@
|
|||
#include "lexer.h"
|
||||
#include "ll.h"
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
libab_result libab_lexer_init(libab_lexer* lexer) {
|
||||
size_t i;
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
const char* words[] = {
|
||||
".",
|
||||
const char* words[] = {".",
|
||||
"[a-zA-Z][a-zA-Z0-9_]*",
|
||||
"[0-9]+(\\.[0-9]*)?",
|
||||
"if",
|
||||
|
@ -19,22 +18,11 @@ libab_result libab_lexer_init(libab_lexer* lexer) {
|
|||
"fun",
|
||||
"return",
|
||||
"let",
|
||||
"be"
|
||||
};
|
||||
"be"};
|
||||
libab_lexer_token tokens[] = {
|
||||
TOKEN_CHAR,
|
||||
TOKEN_ID,
|
||||
TOKEN_NUM,
|
||||
TOKEN_KW_IF,
|
||||
TOKEN_KW_ELSE,
|
||||
TOKEN_KW_WHILE,
|
||||
TOKEN_KW_DO,
|
||||
TOKEN_KW_ARROW,
|
||||
TOKEN_KW_FUN,
|
||||
TOKEN_KW_RETURN,
|
||||
TOKEN_KW_LET,
|
||||
TOKEN_KW_BE
|
||||
};
|
||||
TOKEN_CHAR, TOKEN_ID, TOKEN_NUM, TOKEN_KW_IF,
|
||||
TOKEN_KW_ELSE, TOKEN_KW_WHILE, TOKEN_KW_DO, TOKEN_KW_ARROW,
|
||||
TOKEN_KW_FUN, TOKEN_KW_RETURN, TOKEN_KW_LET, TOKEN_KW_BE};
|
||||
const size_t count = sizeof(tokens) / sizeof(libab_lexer_token);
|
||||
|
||||
eval_config_init(&lexer->config);
|
||||
|
@ -83,7 +71,8 @@ int _lexer_foreach_convert_match(void* data, va_list args) {
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_lexer_lex(libab_lexer* lexer, const char* string, ll* lex_into) {
|
||||
libab_result libab_lexer_lex(libab_lexer* lexer, const char* string,
|
||||
ll* lex_into) {
|
||||
libab_result result;
|
||||
ll raw_matches;
|
||||
struct lexer_state state;
|
||||
|
@ -104,7 +93,8 @@ libab_result libab_lexer_lex(libab_lexer* lexer, const char* string, ll* lex_int
|
|||
}
|
||||
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
ll_foreach(lex_into, NULL, compare_always, libab_lexer_foreach_match_free);
|
||||
ll_foreach(lex_into, NULL, compare_always,
|
||||
libab_lexer_foreach_match_free);
|
||||
}
|
||||
|
||||
ll_foreach(&raw_matches, NULL, compare_always, eval_foreach_match_free);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "libabacus.h"
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
#include "reserved.h"
|
||||
#include "lexer.h"
|
||||
#include "reserved.h"
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
libab_result libab_init(libab* ab) {
|
||||
libab_result result;
|
||||
|
@ -26,20 +26,24 @@ libab_result libab_init(libab* ab) {
|
|||
void _sanitize(char* to, const char* from, size_t buffer_size) {
|
||||
size_t index = 0;
|
||||
while (*from && index < (buffer_size - 2)) {
|
||||
if(*from == '+' || *from == '*' || *from == '\\') to[index++] = '\\';
|
||||
if (*from == '+' || *from == '*' || *from == '\\')
|
||||
to[index++] = '\\';
|
||||
to[index++] = *(from++);
|
||||
}
|
||||
to[index] = '\0';
|
||||
}
|
||||
|
||||
void _initialize_behavior(libab* ab, libab_behavior* behavior,
|
||||
libab_ref* type, libab_function_ptr func) {
|
||||
void _initialize_behavior(libab* ab, libab_behavior* behavior, libab_ref* type,
|
||||
libab_function_ptr func) {
|
||||
behavior->impl.variant = BIMPL_INTERNAL;
|
||||
behavior->impl.data_u.internal = func;
|
||||
libab_ref_copy(type, &behavior->type);
|
||||
}
|
||||
|
||||
libab_result _register_operator(libab* ab, const char* op, libab_operator_variant token_type, int precedence, int associativity, libab_ref* type, libab_function_ptr func) {
|
||||
libab_result _register_operator(libab* ab, const char* op,
|
||||
libab_operator_variant token_type,
|
||||
int precedence, int associativity,
|
||||
libab_ref* type, libab_function_ptr func) {
|
||||
char op_buffer[8];
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_table_entry* new_entry;
|
||||
|
@ -55,7 +59,8 @@ libab_result _register_operator(libab* ab, const char* op, libab_operator_varian
|
|||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
_sanitize(op_buffer, op, 8);
|
||||
result = libab_convert_lex_result(eval_config_add(&ab->lexer.config, op_buffer, TOKEN_OP));
|
||||
result = libab_convert_lex_result(
|
||||
eval_config_add(&ab->lexer.config, op_buffer, TOKEN_OP));
|
||||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
|
@ -72,24 +77,34 @@ libab_result _register_operator(libab* ab, const char* op, libab_operator_varian
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_register_operator_infix(libab* ab, const char* op, int precedence, int associativity, libab_ref* type, libab_function_ptr func) {
|
||||
return _register_operator(ab, op, OPERATOR_INFIX, precedence, associativity, type, func);
|
||||
libab_result libab_register_operator_infix(libab* ab, const char* op,
|
||||
int precedence, int associativity,
|
||||
libab_ref* type,
|
||||
libab_function_ptr func) {
|
||||
return _register_operator(ab, op, OPERATOR_INFIX, precedence, associativity,
|
||||
type, func);
|
||||
}
|
||||
|
||||
libab_result libab_register_operator_prefix(libab* ab, const char* op, libab_ref* type, libab_function_ptr func) {
|
||||
libab_result libab_register_operator_prefix(libab* ab, const char* op,
|
||||
libab_ref* type,
|
||||
libab_function_ptr func) {
|
||||
return _register_operator(ab, op, OPERATOR_PREFIX, 0, 0, type, func);
|
||||
}
|
||||
|
||||
libab_result libab_register_operator_postfix(libab* ab, const char* op, libab_ref* type, libab_function_ptr func) {
|
||||
libab_result libab_register_operator_postfix(libab* ab, const char* op,
|
||||
libab_ref* type,
|
||||
libab_function_ptr func) {
|
||||
return _register_operator(ab, op, OPERATOR_POSTFIX, 0, 0, type, func);
|
||||
}
|
||||
|
||||
libab_result libab_register_function(libab* ab, const char* name, libab_ref* type, libab_function_ptr func) {
|
||||
libab_result libab_register_function(libab* ab, const char* name,
|
||||
libab_ref* type, libab_function_ptr func) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_table_entry* new_entry;
|
||||
if ((new_entry = malloc(sizeof(*new_entry)))) {
|
||||
new_entry->variant = ENTRY_FUN;
|
||||
_initialize_behavior(ab, &(new_entry->data_u.function.behavior), type, func);
|
||||
_initialize_behavior(ab, &(new_entry->data_u.function.behavior), type,
|
||||
func);
|
||||
} else {
|
||||
result = LIBAB_MALLOC;
|
||||
}
|
||||
|
@ -107,7 +122,8 @@ libab_result libab_register_function(libab* ab, const char* name, libab_ref* typ
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_register_basetype(libab* ab, const char* name, libab_basetype* basetype) {
|
||||
libab_result libab_register_basetype(libab* ab, const char* name,
|
||||
libab_basetype* basetype) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_table_entry* new_entry;
|
||||
if ((new_entry = malloc(sizeof(*new_entry)))) {
|
||||
|
|
309
src/parser.c
309
src/parser.c
|
@ -1,10 +1,10 @@
|
|||
#include "parser.h"
|
||||
#include "util.h"
|
||||
#include "result.h"
|
||||
#include "lexer.h"
|
||||
#include "reserved.h"
|
||||
#include "result.h"
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "reserved.h"
|
||||
|
||||
struct parser_state {
|
||||
ll_node* current_node;
|
||||
|
@ -20,7 +20,8 @@ struct operator_data {
|
|||
};
|
||||
|
||||
/* Utilities */
|
||||
#define PARSE_CHILD(result, state, parse_function, parse_into, into) do {\
|
||||
#define PARSE_CHILD(result, state, parse_function, parse_into, into) \
|
||||
do { \
|
||||
result = parse_function(state, &parse_into); \
|
||||
if (result == LIBAB_SUCCESS) { \
|
||||
result = libab_convert_ds_result(vec_add(into, parse_into)); \
|
||||
|
@ -33,7 +34,8 @@ struct operator_data {
|
|||
void _parser_extract_token_buffer(struct parser_state* state, char* buffer,
|
||||
size_t length, libab_lexer_match* match) {
|
||||
size_t token_size = match->to - match->from;
|
||||
size_t buffer_length = (token_size < (length - 1)) ? token_size : (length - 1);
|
||||
size_t buffer_length =
|
||||
(token_size < (length - 1)) ? token_size : (length - 1);
|
||||
strncpy(buffer, state->string + match->from, buffer_length);
|
||||
buffer[buffer_length] = '\0';
|
||||
}
|
||||
|
@ -44,18 +46,21 @@ int _parser_foreach_free_tree(void* data, va_list args) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
libab_result _parser_extract_token(struct parser_state* state, char** into, libab_lexer_match* match) {
|
||||
libab_result _parser_extract_token(struct parser_state* state, char** into,
|
||||
libab_lexer_match* match) {
|
||||
return libab_copy_string_range(into, state->string, match->from, match->to);
|
||||
}
|
||||
|
||||
/* State functions */
|
||||
void _parser_state_update(struct parser_state* state) {
|
||||
state->current_match = state->current_node ? state->current_node->data : NULL;
|
||||
if(state->current_match) state->last_match = state->current_match;
|
||||
state->current_match =
|
||||
state->current_node ? state->current_node->data : NULL;
|
||||
if (state->current_match)
|
||||
state->last_match = state->current_match;
|
||||
}
|
||||
|
||||
void _parser_state_init(struct parser_state* state,
|
||||
ll* tokens, const char* string, libab_table* table) {
|
||||
void _parser_state_init(struct parser_state* state, ll* tokens,
|
||||
const char* string, libab_table* table) {
|
||||
state->last_match = NULL;
|
||||
state->current_node = tokens->head;
|
||||
state->string = string;
|
||||
|
@ -112,18 +117,22 @@ libab_result _parser_consume_type(struct parser_state* state,
|
|||
/* Basic Tree Constructors */
|
||||
|
||||
libab_result _parse_block(struct parser_state*, libab_tree**, int);
|
||||
libab_result _parse_expression(struct parser_state* state, libab_tree** store_into);
|
||||
libab_result _parse_expression(struct parser_state* state,
|
||||
libab_tree** store_into);
|
||||
libab_result _parse_type(struct parser_state* state, libab_ref* ref);
|
||||
|
||||
libab_result _parse_braced_block(struct parser_state* state, libab_tree** store_into) {
|
||||
libab_result _parse_braced_block(struct parser_state* state,
|
||||
libab_tree** store_into) {
|
||||
return _parse_block(state, store_into, 1);
|
||||
}
|
||||
|
||||
libab_result _parser_allocate_type(libab_parsetype** into, const char* source, size_t from, size_t to) {
|
||||
libab_result _parser_allocate_type(libab_parsetype** into, const char* source,
|
||||
size_t from, size_t to) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
if ((*into = malloc(sizeof(**into)))) {
|
||||
(*into)->variant = 0;
|
||||
result = libab_copy_string_range(&(*into)->data_u.name, source, from, to);
|
||||
result =
|
||||
libab_copy_string_range(&(*into)->data_u.name, source, from, to);
|
||||
} else {
|
||||
result = LIBAB_MALLOC;
|
||||
}
|
||||
|
@ -135,7 +144,8 @@ libab_result _parser_allocate_type(libab_parsetype** into, const char* source, s
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parser_append_type(struct parser_state* state, libab_ref_vec* into) {
|
||||
libab_result _parser_append_type(struct parser_state* state,
|
||||
libab_ref_vec* into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_ref temp;
|
||||
result = _parse_type(state, &temp);
|
||||
|
@ -146,10 +156,12 @@ libab_result _parser_append_type(struct parser_state* state, libab_ref_vec* into
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parse_type_list(struct parser_state* state, libab_ref_vec* into, char end_char) {
|
||||
libab_result _parse_type_list(struct parser_state* state, libab_ref_vec* into,
|
||||
char end_char) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
int is_parenth, is_comma;
|
||||
while(result == LIBAB_SUCCESS && !_parser_eof(state) && !_parser_is_char(state, end_char)) {
|
||||
while (result == LIBAB_SUCCESS && !_parser_eof(state) &&
|
||||
!_parser_is_char(state, end_char)) {
|
||||
result = _parser_append_type(state, into);
|
||||
is_parenth = _parser_is_char(state, end_char);
|
||||
is_comma = _parser_is_char(state, ',');
|
||||
|
@ -170,7 +182,8 @@ libab_result _parse_type_list(struct parser_state* state, libab_ref_vec* into, c
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parse_type_id(struct parser_state* state, libab_parsetype** into) {
|
||||
libab_result _parse_type_id(struct parser_state* state,
|
||||
libab_parsetype** into) {
|
||||
libab_result result;
|
||||
int placeholder_flag = 0;
|
||||
*into = NULL;
|
||||
|
@ -182,7 +195,8 @@ libab_result _parse_type_id(struct parser_state* state, libab_parsetype** into)
|
|||
|
||||
if (_parser_is_type(state, TOKEN_ID)) {
|
||||
result = _parser_allocate_type(into, state->string,
|
||||
state->current_match->from, state->current_match->to);
|
||||
state->current_match->from,
|
||||
state->current_match->to);
|
||||
} else {
|
||||
result = _parser_consume_type(state, TOKEN_ID);
|
||||
}
|
||||
|
@ -282,7 +296,8 @@ libab_result _parse_type_array(struct parser_state* state,
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parse_type_raw(struct parser_state* state, libab_parsetype** into) {
|
||||
libab_result _parse_type_raw(struct parser_state* state,
|
||||
libab_parsetype** into) {
|
||||
libab_result result;
|
||||
if (_parser_is_type(state, TOKEN_ID) || _parser_is_char(state, '\'')) {
|
||||
result = _parse_type_id(state, into);
|
||||
|
@ -297,9 +312,7 @@ libab_result _parse_type_raw(struct parser_state* state, libab_parsetype** into)
|
|||
return result;
|
||||
}
|
||||
|
||||
void _parse_type_free(void* data) {
|
||||
libab_parsetype_free(data);
|
||||
}
|
||||
void _parse_type_free(void* data) { libab_parsetype_free(data); }
|
||||
|
||||
libab_result _parse_type(struct parser_state* state, libab_ref* into) {
|
||||
libab_parsetype* store_into;
|
||||
|
@ -314,7 +327,8 @@ libab_result _parse_type(struct parser_state* state, libab_ref* into) {
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parser_allocate_node(libab_lexer_match* match, libab_tree** into) {
|
||||
libab_result _parser_allocate_node(libab_lexer_match* match,
|
||||
libab_tree** into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
if (((*into) = malloc(sizeof(**into))) == NULL) {
|
||||
result = LIBAB_MALLOC;
|
||||
|
@ -327,7 +341,9 @@ libab_result _parser_allocate_node(libab_lexer_match* match, libab_tree** into)
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parser_construct_node_string(struct parser_state* state, libab_lexer_match* match, libab_tree** into) {
|
||||
libab_result _parser_construct_node_string(struct parser_state* state,
|
||||
libab_lexer_match* match,
|
||||
libab_tree** into) {
|
||||
libab_result result = _parser_allocate_node(match, into);
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
|
@ -342,7 +358,8 @@ libab_result _parser_construct_node_string(struct parser_state* state, libab_lex
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parser_construct_node_vec(libab_lexer_match* match, libab_tree** into) {
|
||||
libab_result _parser_construct_node_vec(libab_lexer_match* match,
|
||||
libab_tree** into) {
|
||||
libab_result result = _parser_allocate_node(match, into);
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
|
@ -357,8 +374,11 @@ libab_result _parser_construct_node_vec(libab_lexer_match* match, libab_tree** i
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parser_construct_node_both(struct parser_state* state, libab_lexer_match* match, libab_tree** store_into) {
|
||||
libab_result result = _parser_construct_node_string(state, match, store_into);
|
||||
libab_result _parser_construct_node_both(struct parser_state* state,
|
||||
libab_lexer_match* match,
|
||||
libab_tree** store_into) {
|
||||
libab_result result =
|
||||
_parser_construct_node_string(state, match, store_into);
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
result = libab_convert_ds_result(vec_init(&(*store_into)->children));
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
|
@ -401,8 +421,8 @@ libab_result _parse_if(struct parser_state* state, libab_tree** store_into) {
|
|||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
PARSE_CHILD(result, state, _parse_expression,
|
||||
condition, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_expression, condition,
|
||||
&(*store_into)->children);
|
||||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
|
@ -410,33 +430,36 @@ libab_result _parse_if(struct parser_state* state, libab_tree** store_into) {
|
|||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
PARSE_CHILD(result, state, _parse_expression,
|
||||
if_branch, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_expression, if_branch,
|
||||
&(*store_into)->children);
|
||||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
if (_parser_is_type(state, TOKEN_KW_ELSE)) {
|
||||
_parser_state_step(state);
|
||||
PARSE_CHILD(result, state, _parse_expression,
|
||||
else_branch, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_expression, else_branch,
|
||||
&(*store_into)->children);
|
||||
} else {
|
||||
PARSE_CHILD(result, state, _parse_void,
|
||||
else_branch, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_void, else_branch,
|
||||
&(*store_into)->children);
|
||||
}
|
||||
}
|
||||
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
if(*store_into) libab_tree_free_recursive(*store_into);
|
||||
if (*store_into)
|
||||
libab_tree_free_recursive(*store_into);
|
||||
*store_into = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _parse_fun_param(struct parser_state* state, libab_tree** store_into) {
|
||||
libab_result _parse_fun_param(struct parser_state* state,
|
||||
libab_tree** store_into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
if (_parser_is_type(state, TOKEN_ID)) {
|
||||
result = _parser_construct_node_string(state, state->current_match, store_into);
|
||||
result = _parser_construct_node_string(state, state->current_match,
|
||||
store_into);
|
||||
} else {
|
||||
result = LIBAB_UNEXPECTED;
|
||||
}
|
||||
|
@ -460,13 +483,15 @@ libab_result _parse_fun_param(struct parser_state* state, libab_tree** store_int
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parse_def_fun(struct parser_state* state, libab_tree** store_into) {
|
||||
libab_result _parse_def_fun(struct parser_state* state,
|
||||
libab_tree** store_into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_tree* temp;
|
||||
if (_parser_is_type(state, TOKEN_KW_LET)) {
|
||||
_parser_state_step(state);
|
||||
if (!_parser_eof(state)) {
|
||||
result = _parser_construct_node_both(state, state->current_match, store_into);
|
||||
result = _parser_construct_node_both(state, state->current_match,
|
||||
store_into);
|
||||
} else {
|
||||
result = LIBAB_UNEXPECTED;
|
||||
}
|
||||
|
@ -491,7 +516,8 @@ libab_result _parse_def_fun(struct parser_state* state, libab_tree** store_into)
|
|||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
PARSE_CHILD(result, state, _parse_expression, temp, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_expression, temp,
|
||||
&(*store_into)->children);
|
||||
}
|
||||
|
||||
if (result != LIBAB_SUCCESS && *store_into) {
|
||||
|
@ -509,7 +535,8 @@ libab_result _parse_fun(struct parser_state* state, libab_tree** store_into) {
|
|||
result = _parser_consume_type(state, TOKEN_KW_FUN);
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
if (_parser_is_type(state, TOKEN_ID)) {
|
||||
result = _parser_construct_node_both(state, state->current_match, store_into);
|
||||
result = _parser_construct_node_both(state, state->current_match,
|
||||
store_into);
|
||||
} else {
|
||||
result = LIBAB_UNEXPECTED;
|
||||
}
|
||||
|
@ -520,8 +547,10 @@ libab_result _parse_fun(struct parser_state* state, libab_tree** store_into) {
|
|||
(*store_into)->variant = TREE_FUN;
|
||||
result = _parser_consume_char(state, '(');
|
||||
}
|
||||
while(result == LIBAB_SUCCESS && !_parser_eof(state) && !_parser_is_char(state, ')')) {
|
||||
PARSE_CHILD(result, state, _parse_fun_param, temp, &(*store_into)->children);
|
||||
while (result == LIBAB_SUCCESS && !_parser_eof(state) &&
|
||||
!_parser_is_char(state, ')')) {
|
||||
PARSE_CHILD(result, state, _parse_fun_param, temp,
|
||||
&(*store_into)->children);
|
||||
is_parenth = _parser_is_char(state, ')');
|
||||
is_comma = _parser_is_char(state, ',');
|
||||
if (result == LIBAB_SUCCESS && !(is_parenth || is_comma)) {
|
||||
|
@ -548,7 +577,8 @@ libab_result _parse_fun(struct parser_state* state, libab_tree** store_into) {
|
|||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
PARSE_CHILD(result, state, _parse_braced_block, temp, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_braced_block, temp,
|
||||
&(*store_into)->children);
|
||||
}
|
||||
|
||||
if (result != LIBAB_SUCCESS && *store_into) {
|
||||
|
@ -559,7 +589,8 @@ libab_result _parse_fun(struct parser_state* state, libab_tree** store_into) {
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parse_return(struct parser_state* state, libab_tree** store_into) {
|
||||
libab_result _parse_return(struct parser_state* state,
|
||||
libab_tree** store_into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_tree* child = NULL;
|
||||
if (_parser_is_type(state, TOKEN_KW_RETURN)) {
|
||||
|
@ -573,11 +604,13 @@ libab_result _parse_return(struct parser_state* state, libab_tree** store_into)
|
|||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
PARSE_CHILD(result, state, _parse_expression, child, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_expression, child,
|
||||
&(*store_into)->children);
|
||||
}
|
||||
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
if(*store_into) libab_tree_free_recursive(*store_into);
|
||||
if (*store_into)
|
||||
libab_tree_free_recursive(*store_into);
|
||||
*store_into = NULL;
|
||||
}
|
||||
|
||||
|
@ -604,7 +637,8 @@ libab_result _parse_while(struct parser_state* state, libab_tree** store_into) {
|
|||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
PARSE_CHILD(result, state, _parse_expression, condition, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_expression, condition,
|
||||
&(*store_into)->children);
|
||||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
|
@ -612,18 +646,21 @@ libab_result _parse_while(struct parser_state* state, libab_tree** store_into) {
|
|||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
PARSE_CHILD(result, state, _parse_expression, value, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_expression, value,
|
||||
&(*store_into)->children);
|
||||
}
|
||||
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
if(*store_into) libab_tree_free_recursive(*store_into);
|
||||
if (*store_into)
|
||||
libab_tree_free_recursive(*store_into);
|
||||
*store_into = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _parse_dowhile(struct parser_state* state, libab_tree** store_into) {
|
||||
libab_result _parse_dowhile(struct parser_state* state,
|
||||
libab_tree** store_into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_tree* value = NULL;
|
||||
libab_tree* condition = NULL;
|
||||
|
@ -639,7 +676,8 @@ libab_result _parse_dowhile(struct parser_state* state, libab_tree** store_into)
|
|||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
PARSE_CHILD(result, state, _parse_expression, value, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_expression, value,
|
||||
&(*store_into)->children);
|
||||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
|
@ -651,7 +689,8 @@ libab_result _parse_dowhile(struct parser_state* state, libab_tree** store_into)
|
|||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
PARSE_CHILD(result, state, _parse_expression, condition, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_expression, condition,
|
||||
&(*store_into)->children);
|
||||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
|
@ -675,10 +714,13 @@ libab_result _parse_call(struct parser_state* state, libab_tree** store_into) {
|
|||
result = LIBAB_UNEXPECTED;
|
||||
}
|
||||
|
||||
while(result == LIBAB_SUCCESS && !_parser_eof(state) && !_parser_is_char(state, ')')) {
|
||||
PARSE_CHILD(result, state, _parse_expression, temp, &(*store_into)->children);
|
||||
while (result == LIBAB_SUCCESS && !_parser_eof(state) &&
|
||||
!_parser_is_char(state, ')')) {
|
||||
PARSE_CHILD(result, state, _parse_expression, temp,
|
||||
&(*store_into)->children);
|
||||
|
||||
if(result == LIBAB_SUCCESS && !(_parser_is_char(state, ')') || _parser_is_char(state, ','))) {
|
||||
if (result == LIBAB_SUCCESS &&
|
||||
!(_parser_is_char(state, ')') || _parser_is_char(state, ','))) {
|
||||
result = LIBAB_UNEXPECTED;
|
||||
} else if (_parser_is_char(state, ',')) {
|
||||
_parser_state_step(state);
|
||||
|
@ -689,7 +731,8 @@ libab_result _parse_call(struct parser_state* state, libab_tree** store_into) {
|
|||
}
|
||||
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
if(*store_into) libab_tree_free_recursive(*store_into);
|
||||
if (*store_into)
|
||||
libab_tree_free_recursive(*store_into);
|
||||
*store_into = NULL;
|
||||
}
|
||||
|
||||
|
@ -712,9 +755,11 @@ libab_result _parser_append_call(struct parser_state* state, ll* append_to) {
|
|||
libab_result _parse_atom(struct parser_state* state, libab_tree** store_into) {
|
||||
libab_result result;
|
||||
if (_parser_is_type(state, TOKEN_NUM) || _parser_is_type(state, TOKEN_ID)) {
|
||||
result = _parser_construct_node_string(state, state->current_match, store_into);
|
||||
result = _parser_construct_node_string(state, state->current_match,
|
||||
store_into);
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
(*store_into)->variant = (state->current_match->type == TOKEN_NUM) ? TREE_NUM : TREE_ID;
|
||||
(*store_into)->variant =
|
||||
(state->current_match->type == TOKEN_NUM) ? TREE_NUM : TREE_ID;
|
||||
}
|
||||
_parser_state_step(state);
|
||||
} else if (_parser_is_type(state, TOKEN_KW_IF)) {
|
||||
|
@ -750,7 +795,8 @@ libab_result _parser_append_atom(struct parser_state* state, ll* append_to) {
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parser_construct_op(struct parser_state* state, libab_lexer_match* match, libab_tree** into) {
|
||||
libab_result _parser_construct_op(struct parser_state* state,
|
||||
libab_lexer_match* match, libab_tree** into) {
|
||||
libab_result result = _parser_construct_node_both(state, match, into);
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
|
@ -767,7 +813,8 @@ libab_result _parser_construct_op(struct parser_state* state, libab_lexer_match*
|
|||
|
||||
return result;
|
||||
}
|
||||
libab_result _parser_append_op_node(struct parser_state* state, libab_lexer_match* match, ll* append_to) {
|
||||
libab_result _parser_append_op_node(struct parser_state* state,
|
||||
libab_lexer_match* match, ll* append_to) {
|
||||
libab_result result;
|
||||
libab_tree* new_tree = NULL;
|
||||
result = _parser_construct_op(state, match, &new_tree);
|
||||
|
@ -781,26 +828,26 @@ libab_result _parser_append_op_node(struct parser_state* state, libab_lexer_matc
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Expression-specific utility functions */
|
||||
|
||||
int _parser_match_is_op(libab_lexer_match* match) {
|
||||
return match->type == TOKEN_OP ||
|
||||
match->type == TOKEN_OP_INFIX ||
|
||||
match->type == TOKEN_OP_PREFIX ||
|
||||
match->type == TOKEN_OP_POSTFIX ||
|
||||
return match->type == TOKEN_OP || match->type == TOKEN_OP_INFIX ||
|
||||
match->type == TOKEN_OP_PREFIX || match->type == TOKEN_OP_POSTFIX ||
|
||||
match->type == TOKEN_OP_RESERVED;
|
||||
}
|
||||
|
||||
libab_result _parser_pop_brackets(struct parser_state* state, ll* pop_from, ll* push_to, char bracket, int* success) {
|
||||
libab_result _parser_pop_brackets(struct parser_state* state, ll* pop_from,
|
||||
ll* push_to, char bracket, int* success) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_lexer_match* remaining_match;
|
||||
while(result == LIBAB_SUCCESS && pop_from->tail && _parser_match_is_op(pop_from->tail->data)) {
|
||||
while (result == LIBAB_SUCCESS && pop_from->tail &&
|
||||
_parser_match_is_op(pop_from->tail->data)) {
|
||||
libab_lexer_match* new_match = ll_poptail(pop_from);
|
||||
result = _parser_append_op_node(state, new_match, push_to);
|
||||
}
|
||||
remaining_match = (pop_from->tail) ? pop_from->tail->data : NULL;
|
||||
*success = remaining_match && (remaining_match->type == TOKEN_CHAR) && (state->string[remaining_match->from] == bracket);
|
||||
*success = remaining_match && (remaining_match->type == TOKEN_CHAR) &&
|
||||
(state->string[remaining_match->from] == bracket);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -815,32 +862,40 @@ enum parser_expression_type {
|
|||
};
|
||||
|
||||
int _parser_can_prefix_follow(enum parser_expression_type type) {
|
||||
return type == EXPR_OPEN_PARENTH || type == EXPR_OP_PREFIX || type == EXPR_OP_INFIX || type == EXPR_NONE;
|
||||
return type == EXPR_OPEN_PARENTH || type == EXPR_OP_PREFIX ||
|
||||
type == EXPR_OP_INFIX || type == EXPR_NONE;
|
||||
}
|
||||
|
||||
int _parser_can_postfix_follow(enum parser_expression_type type) {
|
||||
return type == EXPR_CLOSE_PARENTH || type == EXPR_ATOM || type == EXPR_OP_POSTFIX;
|
||||
return type == EXPR_CLOSE_PARENTH || type == EXPR_ATOM ||
|
||||
type == EXPR_OP_POSTFIX;
|
||||
}
|
||||
|
||||
int _parser_can_atom_follow(enum parser_expression_type type) {
|
||||
return !(type == EXPR_CLOSE_PARENTH || type == EXPR_OP_POSTFIX || type == EXPR_ATOM);
|
||||
return !(type == EXPR_CLOSE_PARENTH || type == EXPR_OP_POSTFIX ||
|
||||
type == EXPR_ATOM);
|
||||
}
|
||||
|
||||
void _parser_find_operator_infix(struct parser_state* state, libab_lexer_match* match, struct operator_data* data) {
|
||||
void _parser_find_operator_infix(struct parser_state* state,
|
||||
libab_lexer_match* match,
|
||||
struct operator_data* data) {
|
||||
char op_buffer[8];
|
||||
_parser_extract_token_buffer(state, op_buffer, 8, match);
|
||||
if (match->type != TOKEN_OP_RESERVED) {
|
||||
libab_operator* operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_INFIX);
|
||||
libab_operator* operator= libab_table_search_operator(
|
||||
state->base_table, op_buffer, OPERATOR_INFIX);
|
||||
data->associativity = operator->associativity;
|
||||
data->precedence = operator->precedence;
|
||||
} else {
|
||||
const libab_reserved_operator* operator = libab_find_reserved_operator(op_buffer);
|
||||
const libab_reserved_operator* operator=
|
||||
libab_find_reserved_operator(op_buffer);
|
||||
data->associativity = operator->associativity;
|
||||
data->precedence = operator->precedence;
|
||||
}
|
||||
}
|
||||
|
||||
libab_result _parser_expression_tree(struct parser_state* state, ll* source, libab_tree** into) {
|
||||
libab_result _parser_expression_tree(struct parser_state* state, ll* source,
|
||||
libab_tree** into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_tree* top = ll_poptail(source);
|
||||
if (top == NULL) {
|
||||
|
@ -862,13 +917,16 @@ libab_result _parser_expression_tree(struct parser_state* state, ll* source, lib
|
|||
}
|
||||
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
if(left) libab_tree_free_recursive(left);
|
||||
if(right) libab_tree_free_recursive(right);
|
||||
if (left)
|
||||
libab_tree_free_recursive(left);
|
||||
if (right)
|
||||
libab_tree_free_recursive(right);
|
||||
libab_tree_free(top);
|
||||
free(top);
|
||||
top = NULL;
|
||||
}
|
||||
} else if(top->variant == TREE_PREFIX_OP || top->variant == TREE_POSTFIX_OP || top->variant == TREE_CALL) {
|
||||
} else if (top->variant == TREE_PREFIX_OP ||
|
||||
top->variant == TREE_POSTFIX_OP || top->variant == TREE_CALL) {
|
||||
libab_tree* child = NULL;
|
||||
|
||||
result = _parser_expression_tree(state, source, &child);
|
||||
|
@ -878,8 +936,10 @@ libab_result _parser_expression_tree(struct parser_state* state, ll* source, lib
|
|||
}
|
||||
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
if(child) libab_tree_free_recursive(child);
|
||||
if(top->variant == TREE_PREFIX_OP || top->variant == TREE_POSTFIX_OP) {
|
||||
if (child)
|
||||
libab_tree_free_recursive(child);
|
||||
if (top->variant == TREE_PREFIX_OP ||
|
||||
top->variant == TREE_POSTFIX_OP) {
|
||||
libab_tree_free(top);
|
||||
free(top);
|
||||
} else {
|
||||
|
@ -892,27 +952,34 @@ libab_result _parser_expression_tree(struct parser_state* state, ll* source, lib
|
|||
return result;
|
||||
}
|
||||
|
||||
int _parser_match_is_postfix_op(struct parser_state* state, libab_lexer_match* match) {
|
||||
int _parser_match_is_postfix_op(struct parser_state* state,
|
||||
libab_lexer_match* match) {
|
||||
int is_postfix = 0;
|
||||
libab_operator* operator;
|
||||
char op_buffer[8];
|
||||
_parser_extract_token_buffer(state, op_buffer, 8, match);
|
||||
operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_POSTFIX);
|
||||
if(operator) is_postfix = 1;
|
||||
operator= libab_table_search_operator(state->base_table, op_buffer,
|
||||
OPERATOR_POSTFIX);
|
||||
if (operator)
|
||||
is_postfix = 1;
|
||||
return is_postfix;
|
||||
}
|
||||
|
||||
int _parser_match_is_prefix_op(struct parser_state* state, libab_lexer_match* match) {
|
||||
int _parser_match_is_prefix_op(struct parser_state* state,
|
||||
libab_lexer_match* match) {
|
||||
int is_prefix = 0;
|
||||
libab_operator* operator;
|
||||
char op_buffer[8];
|
||||
_parser_extract_token_buffer(state, op_buffer, 8, match);
|
||||
operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_PREFIX);
|
||||
if(operator) is_prefix = 1;
|
||||
operator= libab_table_search_operator(state->base_table, op_buffer,
|
||||
OPERATOR_PREFIX);
|
||||
if (operator)
|
||||
is_prefix = 1;
|
||||
return is_prefix;
|
||||
}
|
||||
|
||||
int _parser_match_is_infix_op(struct parser_state* state, libab_lexer_match* match) {
|
||||
int _parser_match_is_infix_op(struct parser_state* state,
|
||||
libab_lexer_match* match) {
|
||||
int is_infix = 0;
|
||||
if (match->type == TOKEN_OP_RESERVED) {
|
||||
is_infix = 1;
|
||||
|
@ -920,13 +987,16 @@ int _parser_match_is_infix_op(struct parser_state* state, libab_lexer_match* mat
|
|||
libab_operator* operator;
|
||||
char op_buffer[8];
|
||||
_parser_extract_token_buffer(state, op_buffer, 8, match);
|
||||
operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_INFIX);
|
||||
if(operator) is_infix = 1;
|
||||
operator= libab_table_search_operator(state->base_table, op_buffer,
|
||||
OPERATOR_INFIX);
|
||||
if (operator)
|
||||
is_infix = 1;
|
||||
}
|
||||
return is_infix;
|
||||
}
|
||||
|
||||
libab_result _parse_expression(struct parser_state* state, libab_tree** store_into) {
|
||||
libab_result _parse_expression(struct parser_state* state,
|
||||
libab_tree** store_into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
struct operator_data operator;
|
||||
struct operator_data other_operator;
|
||||
|
@ -946,16 +1016,21 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in
|
|||
if (_parser_is_type(state, TOKEN_CHAR) && current_char != '{') {
|
||||
if (current_char == '(' && _parser_can_postfix_follow(last_type)) {
|
||||
result = _parser_append_call(state, &out_stack);
|
||||
if(result != LIBAB_SUCCESS) break;
|
||||
if (result != LIBAB_SUCCESS)
|
||||
break;
|
||||
new_type = EXPR_OP_POSTFIX;
|
||||
} else if (current_char == '(') {
|
||||
result = libab_convert_ds_result(ll_append(&op_stack, new_token));
|
||||
if(result != LIBAB_SUCCESS) break;
|
||||
result =
|
||||
libab_convert_ds_result(ll_append(&op_stack, new_token));
|
||||
if (result != LIBAB_SUCCESS)
|
||||
break;
|
||||
_parser_state_step(state);
|
||||
new_type = EXPR_OPEN_PARENTH;
|
||||
} else if (current_char == ')') {
|
||||
result = _parser_pop_brackets(state, &op_stack, &out_stack, '(', &pop_success);
|
||||
if(result != LIBAB_SUCCESS || !pop_success) break;
|
||||
result = _parser_pop_brackets(state, &op_stack, &out_stack, '(',
|
||||
&pop_success);
|
||||
if (result != LIBAB_SUCCESS || !pop_success)
|
||||
break;
|
||||
ll_poptail(&op_stack);
|
||||
_parser_state_step(state);
|
||||
new_type = EXPR_CLOSE_PARENTH;
|
||||
|
@ -966,7 +1041,8 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in
|
|||
_parser_can_prefix_follow(last_type)) {
|
||||
new_token->type = TOKEN_OP_PREFIX;
|
||||
result = libab_convert_ds_result(ll_append(&op_stack, new_token));
|
||||
if(result != LIBAB_SUCCESS) break;
|
||||
if (result != LIBAB_SUCCESS)
|
||||
break;
|
||||
_parser_state_step(state);
|
||||
new_type = EXPR_OP_PREFIX;
|
||||
} else if (_parser_match_is_postfix_op(state, new_token) &&
|
||||
|
@ -983,9 +1059,11 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in
|
|||
|
||||
while (result == LIBAB_SUCCESS && op_stack.tail &&
|
||||
_parser_match_is_op(op_stack.tail->data)) {
|
||||
_parser_find_operator_infix(state, op_stack.tail->data, &other_operator);
|
||||
_parser_find_operator_infix(state, op_stack.tail->data,
|
||||
&other_operator);
|
||||
|
||||
if(((libab_lexer_match*)op_stack.tail->data)->type == TOKEN_OP_PREFIX ||
|
||||
if (((libab_lexer_match*)op_stack.tail->data)->type ==
|
||||
TOKEN_OP_PREFIX ||
|
||||
(operator.associativity == - 1 &&
|
||||
operator.precedence <= other_operator.precedence) ||
|
||||
(operator.associativity == 1 &&
|
||||
|
@ -997,11 +1075,13 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in
|
|||
}
|
||||
}
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
result = libab_convert_ds_result(ll_append(&op_stack, new_token));
|
||||
result =
|
||||
libab_convert_ds_result(ll_append(&op_stack, new_token));
|
||||
}
|
||||
new_type = EXPR_OP_INFIX;
|
||||
} else {
|
||||
if(!_parser_can_atom_follow(last_type)) break;
|
||||
if (!_parser_can_atom_follow(last_type))
|
||||
break;
|
||||
result = _parser_append_atom(state, &out_stack);
|
||||
new_type = EXPR_ATOM;
|
||||
}
|
||||
|
@ -1038,8 +1118,8 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _parse_block(struct parser_state* state,
|
||||
libab_tree** store_into, int expect_braces) {
|
||||
libab_result _parse_block(struct parser_state* state, libab_tree** store_into,
|
||||
int expect_braces) {
|
||||
libab_result result;
|
||||
libab_tree* temp = NULL;
|
||||
result = _parser_construct_node_vec(state->current_match, store_into);
|
||||
|
@ -1047,12 +1127,13 @@ libab_result _parse_block(struct parser_state* state,
|
|||
(*store_into)->variant = TREE_BLOCK;
|
||||
}
|
||||
|
||||
if(expect_braces && result == LIBAB_SUCCESS) result = _parser_consume_char(state, '{');
|
||||
if (expect_braces && result == LIBAB_SUCCESS)
|
||||
result = _parser_consume_char(state, '{');
|
||||
|
||||
while(result == LIBAB_SUCCESS &&
|
||||
!_parser_eof(state) &&
|
||||
while (result == LIBAB_SUCCESS && !_parser_eof(state) &&
|
||||
!(expect_braces && _parser_is_char(state, '}'))) {
|
||||
PARSE_CHILD(result, state, _parse_expression, temp, &(*store_into)->children);
|
||||
PARSE_CHILD(result, state, _parse_expression, temp,
|
||||
&(*store_into)->children);
|
||||
if (_parser_is_char(state, ';')) {
|
||||
temp = NULL;
|
||||
_parser_state_step(state);
|
||||
|
@ -1063,7 +1144,8 @@ libab_result _parse_block(struct parser_state* state,
|
|||
PARSE_CHILD(result, state, _parse_void, temp, &(*store_into)->children);
|
||||
}
|
||||
|
||||
if(expect_braces && result == LIBAB_SUCCESS) result = _parser_consume_char(state, '}');
|
||||
if (expect_braces && result == LIBAB_SUCCESS)
|
||||
result = _parser_consume_char(state, '}');
|
||||
|
||||
if (result != LIBAB_SUCCESS && *store_into) {
|
||||
libab_tree_free_recursive(*store_into);
|
||||
|
@ -1090,12 +1172,11 @@ libab_result libab_parser_parse(libab_parser* parser, ll* tokens,
|
|||
return result;
|
||||
}
|
||||
libab_result libab_parser_parse_type(libab_parser* parser, ll* tokens,
|
||||
const char* string, libab_ref* store_into) {
|
||||
const char* string,
|
||||
libab_ref* store_into) {
|
||||
struct parser_state state;
|
||||
_parser_state_init(&state, tokens, string, parser->base_table);
|
||||
|
||||
return _parse_type(&state, store_into);
|
||||
}
|
||||
void libab_parser_free(libab_parser* parser) {
|
||||
parser->base_table = NULL;
|
||||
}
|
||||
void libab_parser_free(libab_parser* parser) { parser->base_table = NULL; }
|
||||
|
|
|
@ -6,7 +6,8 @@ void libab_ref_trie_init(libab_ref_trie* trie) {
|
|||
trie->head = NULL;
|
||||
}
|
||||
|
||||
libab_result _libab_ref_trie_put(libab_ref_trie_node** node, const char* key, libab_ref* ref) {
|
||||
libab_result _libab_ref_trie_put(libab_ref_trie_node** node, const char* key,
|
||||
libab_ref* ref) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
if ((*node = malloc(sizeof(**node)))) {
|
||||
(*node)->key = *key;
|
||||
|
@ -24,7 +25,8 @@ libab_result _libab_ref_trie_put(libab_ref_trie_node** node, const char* key, li
|
|||
}
|
||||
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
if(*node) libab_ref_free(&(*node)->ref);
|
||||
if (*node)
|
||||
libab_ref_free(&(*node)->ref);
|
||||
free(*node);
|
||||
*node = NULL;
|
||||
}
|
||||
|
@ -32,7 +34,8 @@ libab_result _libab_ref_trie_put(libab_ref_trie_node** node, const char* key, li
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_ref_trie_put(libab_ref_trie* trie, const char* key, libab_ref* ref) {
|
||||
libab_result libab_ref_trie_put(libab_ref_trie* trie, const char* key,
|
||||
libab_ref* ref) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_ref_trie_node** current = &trie->head;
|
||||
char search;
|
||||
|
@ -57,13 +60,15 @@ libab_result libab_ref_trie_put(libab_ref_trie* trie, const char* key, libab_ref
|
|||
return result;
|
||||
}
|
||||
|
||||
const libab_ref* libab_ref_trie_get(const libab_ref_trie* trie, const char* key) {
|
||||
const libab_ref* libab_ref_trie_get(const libab_ref_trie* trie,
|
||||
const char* key) {
|
||||
libab_ref_trie_node* current = trie->head;
|
||||
while (current && *key) {
|
||||
while (current && current->key != *key) {
|
||||
current = current->next;
|
||||
}
|
||||
if(current == NULL) break;
|
||||
if (current == NULL)
|
||||
break;
|
||||
|
||||
if (*(key + 1)) {
|
||||
current = current->child;
|
||||
|
@ -76,7 +81,8 @@ const libab_ref* libab_ref_trie_get(const libab_ref_trie* trie, const char* key)
|
|||
}
|
||||
|
||||
void _libab_ref_trie_free(libab_ref_trie_node* node) {
|
||||
if(node == NULL) return;
|
||||
if (node == NULL)
|
||||
return;
|
||||
_libab_ref_trie_free(node->next);
|
||||
_libab_ref_trie_free(node->child);
|
||||
libab_ref_free(&node->ref);
|
||||
|
|
|
@ -5,8 +5,7 @@ libab_result libab_ref_vec_init(libab_ref_vec* vec) {
|
|||
libab_result result = LIBAB_SUCCESS;
|
||||
vec->capacity = LIBABACUS_REF_VEC_INITIAL_SIZE;
|
||||
vec->size = 0;
|
||||
vec->data =
|
||||
malloc(sizeof(*vec->data) * LIBABACUS_REF_VEC_INITIAL_SIZE);
|
||||
vec->data = malloc(sizeof(*vec->data) * LIBABACUS_REF_VEC_INITIAL_SIZE);
|
||||
if (vec->data == NULL) {
|
||||
result = LIBAB_MALLOC;
|
||||
}
|
||||
|
@ -16,7 +15,8 @@ libab_result libab_ref_vec_init(libab_ref_vec* vec) {
|
|||
libab_result _libab_ref_vec_try_resize(libab_ref_vec* vec) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
if (vec->size == vec->capacity) {
|
||||
libab_ref* new_memory = realloc(vec->data, (vec->capacity *= 2) * sizeof(*vec->data));
|
||||
libab_ref* new_memory =
|
||||
realloc(vec->data, (vec->capacity *= 2) * sizeof(*vec->data));
|
||||
if (new_memory == NULL) {
|
||||
free(vec->data);
|
||||
result = LIBAB_MALLOC;
|
||||
|
@ -35,7 +35,8 @@ libab_result libab_ref_vec_insert(libab_ref_vec* vec, libab_ref* data) {
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_ref_vec_insert_value(libab_ref_vec* vec, void* data, void (*free_func)(void*)) {
|
||||
libab_result libab_ref_vec_insert_value(libab_ref_vec* vec, void* data,
|
||||
void (*free_func)(void*)) {
|
||||
libab_result result = _libab_ref_vec_try_resize(vec);
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
libab_result libab_ref_new(libab_ref* ref, void* data, void (*free_func)(void* data)) {
|
||||
libab_result libab_ref_new(libab_ref* ref, void* data,
|
||||
void (*free_func)(void* data)) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
ref->strong = 1;
|
||||
ref->data = data;
|
||||
|
@ -15,11 +16,7 @@ libab_result libab_ref_new(libab_ref* ref, void* data, void (*free_func)(void* d
|
|||
return result;
|
||||
}
|
||||
|
||||
static libab_ref_count null_count = {
|
||||
NULL,
|
||||
0,
|
||||
1
|
||||
};
|
||||
static libab_ref_count null_count = {NULL, 0, 1};
|
||||
|
||||
void libab_ref_null(libab_ref* ref) {
|
||||
ref->strong = 0;
|
||||
|
|
|
@ -2,13 +2,11 @@
|
|||
#include "string.h"
|
||||
#include "util.h"
|
||||
|
||||
static const libab_reserved_operator libab_reserved_operators[] = {
|
||||
{
|
||||
static const libab_reserved_operator libab_reserved_operators[] = {{
|
||||
"=", /* Assignment */
|
||||
0, /* Lowest precedence */
|
||||
1 /* Right associative, a = b = 6 should be a = (b = 6) */
|
||||
}
|
||||
};
|
||||
}};
|
||||
static const size_t element_count =
|
||||
sizeof(libab_reserved_operators) / sizeof(libab_reserved_operator);
|
||||
|
||||
|
@ -25,8 +23,8 @@ libab_result libab_register_reserved_operators(libab_lexer* lexer) {
|
|||
libab_result result = LIBAB_SUCCESS;
|
||||
size_t i;
|
||||
for (i = 0; i < element_count && result == LIBAB_SUCCESS; i++) {
|
||||
result = libab_convert_lex_result(eval_config_add(&lexer->config,
|
||||
libab_reserved_operators[i].op, TOKEN_OP_RESERVED));
|
||||
result = libab_convert_lex_result(eval_config_add(
|
||||
&lexer->config, libab_reserved_operators[i].op, TOKEN_OP_RESERVED));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -35,8 +33,8 @@ libab_result libab_remove_reserved_operators(libab_lexer* lexer) {
|
|||
libab_result result = LIBAB_SUCCESS;
|
||||
size_t i;
|
||||
for (i = 0; i < element_count && result == LIBAB_SUCCESS; i++) {
|
||||
result = libab_convert_lex_result(eval_config_remove(&lexer->config,
|
||||
libab_reserved_operators[i].op, TOKEN_OP_RESERVED));
|
||||
result = libab_convert_lex_result(eval_config_remove(
|
||||
&lexer->config, libab_reserved_operators[i].op, TOKEN_OP_RESERVED));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
42
src/table.c
42
src/table.c
|
@ -1,13 +1,15 @@
|
|||
#include "table.h"
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
#include "lexer.h"
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void libab_table_init(libab_table* table) {
|
||||
libab_trie_init(&table->trie);
|
||||
table->parent = NULL;
|
||||
}
|
||||
libab_table_entry* libab_table_search_filter(libab_table* table, const char* string, void* data, compare_func compare) {
|
||||
libab_table_entry* libab_table_search_filter(libab_table* table,
|
||||
const char* string, void* data,
|
||||
compare_func compare) {
|
||||
void* to_return = NULL;
|
||||
do {
|
||||
const ll* matches = libab_trie_get(&table->trie, string);
|
||||
|
@ -25,7 +27,8 @@ libab_table_entry* libab_table_search(libab_table* table, const char* string) {
|
|||
return to_return;
|
||||
}
|
||||
|
||||
#define OP_TYPE_COMPARATOR(NAME, TYPE) int NAME(const void* left, const void* right) {\
|
||||
#define OP_TYPE_COMPARATOR(NAME, TYPE) \
|
||||
int NAME(const void* left, const void* right) { \
|
||||
const libab_table_entry* entry = right; \
|
||||
return entry->variant == ENTRY_OP && entry->data_u.op.type == TYPE; \
|
||||
}
|
||||
|
@ -34,14 +37,18 @@ OP_TYPE_COMPARATOR(_table_compare_prefix, OPERATOR_PREFIX)
|
|||
OP_TYPE_COMPARATOR(_table_compare_infix, OPERATOR_INFIX)
|
||||
OP_TYPE_COMPARATOR(_table_compare_postfix, OPERATOR_POSTFIX)
|
||||
|
||||
libab_operator* libab_table_search_operator(libab_table* table, const char* string, int type) {
|
||||
libab_operator* libab_table_search_operator(libab_table* table,
|
||||
const char* string, int type) {
|
||||
libab_table_entry* entry = NULL;
|
||||
if (type == OPERATOR_PREFIX) {
|
||||
entry = libab_table_search_filter(table, string, NULL, _table_compare_prefix);
|
||||
entry = libab_table_search_filter(table, string, NULL,
|
||||
_table_compare_prefix);
|
||||
} else if (type == OPERATOR_INFIX) {
|
||||
entry = libab_table_search_filter(table, string, NULL, _table_compare_infix);
|
||||
entry = libab_table_search_filter(table, string, NULL,
|
||||
_table_compare_infix);
|
||||
} else if (type == OPERATOR_PREFIX) {
|
||||
entry = libab_table_search_filter(table, string, NULL, _table_compare_postfix);
|
||||
entry = libab_table_search_filter(table, string, NULL,
|
||||
_table_compare_postfix);
|
||||
}
|
||||
return entry ? &entry->data_u.op : NULL;
|
||||
}
|
||||
|
@ -51,8 +58,10 @@ int _table_compare_function(const void* left, const void* right) {
|
|||
return entry->variant == ENTRY_FUN;
|
||||
}
|
||||
|
||||
libab_function* libab_table_search_function(libab_table* table, const char* string) {
|
||||
libab_table_entry* entry = libab_table_search_filter(table, string, NULL, _table_compare_function);
|
||||
libab_function* libab_table_search_function(libab_table* table,
|
||||
const char* string) {
|
||||
libab_table_entry* entry =
|
||||
libab_table_search_filter(table, string, NULL, _table_compare_function);
|
||||
return entry ? &entry->data_u.function : NULL;
|
||||
}
|
||||
|
||||
|
@ -61,13 +70,15 @@ int _table_compare_basetype(const void* left, const void* right) {
|
|||
return entry->variant == ENTRY_BASETYPE;
|
||||
}
|
||||
|
||||
libab_basetype* libab_table_search_basetype(libab_table* table, const char* string) {
|
||||
libab_table_entry* entry = libab_table_search_filter(table, string, NULL, _table_compare_basetype);
|
||||
libab_basetype* libab_table_search_basetype(libab_table* table,
|
||||
const char* string) {
|
||||
libab_table_entry* entry =
|
||||
libab_table_search_filter(table, string, NULL, _table_compare_basetype);
|
||||
return entry ? entry->data_u.basetype : NULL;
|
||||
}
|
||||
|
||||
|
||||
libab_result libab_table_put(libab_table* table, const char* string, libab_table_entry* entry) {
|
||||
libab_result libab_table_put(libab_table* table, const char* string,
|
||||
libab_table_entry* entry) {
|
||||
return libab_trie_put(&table->trie, string, entry);
|
||||
}
|
||||
int _table_foreach_entry_free(void* data, va_list args) {
|
||||
|
@ -76,7 +87,8 @@ int _table_foreach_entry_free(void* data, va_list args) {
|
|||
return 0;
|
||||
}
|
||||
void libab_table_free(libab_table* table) {
|
||||
libab_trie_foreach(&table->trie, NULL, compare_always, _table_foreach_entry_free);
|
||||
libab_trie_foreach(&table->trie, NULL, compare_always,
|
||||
_table_foreach_entry_free);
|
||||
libab_trie_free(&table->trie);
|
||||
}
|
||||
void libab_table_entry_free(libab_table_entry* entry) {
|
||||
|
|
15
src/tree.c
15
src/tree.c
|
@ -3,15 +3,16 @@
|
|||
|
||||
int libab_tree_has_vector(libab_tree_variant variant) {
|
||||
return variant == TREE_BASE || variant == TREE_OP ||
|
||||
variant == TREE_PREFIX_OP || variant == TREE_POSTFIX_OP || variant == TREE_BLOCK ||
|
||||
variant == TREE_IF || variant == TREE_CALL || variant == TREE_WHILE ||
|
||||
variant == TREE_PREFIX_OP || variant == TREE_POSTFIX_OP ||
|
||||
variant == TREE_BLOCK || variant == TREE_IF ||
|
||||
variant == TREE_CALL || variant == TREE_WHILE ||
|
||||
variant == TREE_DOWHILE || variant == TREE_FUN ||
|
||||
variant == TREE_RETURN || variant == TREE_RESERVED_OP;
|
||||
}
|
||||
|
||||
int libab_tree_has_string(libab_tree_variant variant) {
|
||||
return variant == TREE_ID || variant == TREE_NUM ||
|
||||
variant == TREE_OP || variant == TREE_PREFIX_OP || variant == TREE_POSTFIX_OP ||
|
||||
return variant == TREE_ID || variant == TREE_NUM || variant == TREE_OP ||
|
||||
variant == TREE_PREFIX_OP || variant == TREE_POSTFIX_OP ||
|
||||
variant == TREE_FUN || variant == TREE_FUN_PARAM ||
|
||||
variant == TREE_RESERVED_OP;
|
||||
}
|
||||
|
@ -33,8 +34,10 @@ void libab_tree_free(libab_tree* tree) {
|
|||
free_vector = libab_tree_has_vector(tree->variant);
|
||||
free_string = libab_tree_has_string(tree->variant);
|
||||
free_type = libab_tree_has_type(tree->variant);
|
||||
if(free_string) free(tree->string_value);
|
||||
if(free_vector) vec_free(&tree->children);
|
||||
if (free_string)
|
||||
free(tree->string_value);
|
||||
if (free_vector)
|
||||
vec_free(&tree->children);
|
||||
if (free_type)
|
||||
libab_ref_free(&tree->type);
|
||||
}
|
||||
|
|
23
src/trie.c
23
src/trie.c
|
@ -1,6 +1,6 @@
|
|||
#include "trie.h"
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void libab_trie_init(libab_trie* trie) {
|
||||
trie->head = NULL;
|
||||
|
@ -8,14 +8,16 @@ void libab_trie_init(libab_trie* trie) {
|
|||
}
|
||||
|
||||
void _libab_trie_free(libab_trie_node* to_free) {
|
||||
if(to_free == NULL) return;
|
||||
if (to_free == NULL)
|
||||
return;
|
||||
_libab_trie_free(to_free->next);
|
||||
_libab_trie_free(to_free->child);
|
||||
ll_free(&to_free->values);
|
||||
free(to_free);
|
||||
}
|
||||
|
||||
libab_result _libab_trie_put(libab_trie_node** node, const char* key, void* value) {
|
||||
libab_result _libab_trie_put(libab_trie_node** node, const char* key,
|
||||
void* value) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
if ((*node = malloc(sizeof(**node)))) {
|
||||
(*node)->key = *key;
|
||||
|
@ -26,7 +28,8 @@ libab_result _libab_trie_put(libab_trie_node** node, const char* key, void* valu
|
|||
result = _libab_trie_put(&(*node)->child, key + 1, value);
|
||||
} else {
|
||||
(*node)->child = NULL;
|
||||
result = libab_convert_ds_result(ll_append(&(*node)->values, value));
|
||||
result =
|
||||
libab_convert_ds_result(ll_append(&(*node)->values, value));
|
||||
}
|
||||
} else {
|
||||
result = LIBAB_MALLOC;
|
||||
|
@ -74,7 +77,8 @@ const ll* libab_trie_get(const libab_trie* trie, const char* key) {
|
|||
while (current && current->key != *key) {
|
||||
current = current->next;
|
||||
}
|
||||
if(current == NULL) break;
|
||||
if (current == NULL)
|
||||
break;
|
||||
|
||||
if (*(key + 1)) {
|
||||
current = current->child;
|
||||
|
@ -86,9 +90,11 @@ const ll* libab_trie_get(const libab_trie* trie, const char* key) {
|
|||
return &trie->empty_list;
|
||||
}
|
||||
|
||||
int _libab_trie_foreach(libab_trie_node* node, void* data, compare_func compare, foreach_func foreach) {
|
||||
int _libab_trie_foreach(libab_trie_node* node, void* data, compare_func compare,
|
||||
foreach_func foreach) {
|
||||
int return_code;
|
||||
if(node == NULL) return 0;
|
||||
if (node == NULL)
|
||||
return 0;
|
||||
return_code = ll_foreach(&node->values, data, compare, foreach);
|
||||
if (return_code == 0) {
|
||||
return_code = _libab_trie_foreach(node->child, data, compare, foreach);
|
||||
|
@ -99,7 +105,8 @@ int _libab_trie_foreach(libab_trie_node* node, void* data, compare_func compare,
|
|||
return return_code;
|
||||
}
|
||||
|
||||
int libab_trie_foreach(const libab_trie* trie, void* data, compare_func compare, foreach_func foreach) {
|
||||
int libab_trie_foreach(const libab_trie* trie, void* data, compare_func compare,
|
||||
foreach_func foreach) {
|
||||
return _libab_trie_foreach(trie->head, data, compare, foreach);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,4 @@ libab_result libab_array_insert(libab_array* array, libab_ref* value) {
|
|||
return libab_ref_vec_insert(&array->elems, value);
|
||||
}
|
||||
|
||||
void libab_array_free(libab_array* array) {
|
||||
libab_ref_vec_free(&array->elems);
|
||||
}
|
||||
void libab_array_free(libab_array* array) { libab_ref_vec_free(&array->elems); }
|
||||
|
|
18
src/util.c
18
src/util.c
|
@ -19,7 +19,8 @@ libab_result libab_convert_ds_result(libds_result to_convert) {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
libab_result libab_copy_string_range(char** destination, const char* source, size_t from, size_t to) {
|
||||
libab_result libab_copy_string_range(char** destination, const char* source,
|
||||
size_t from, size_t to) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
size_t string_length = to - from;
|
||||
if ((*destination = malloc(string_length + 1)) == NULL) {
|
||||
|
@ -30,7 +31,8 @@ libab_result libab_copy_string_range(char** destination, const char* source, siz
|
|||
}
|
||||
return result;
|
||||
}
|
||||
libab_result libab_copy_string_size(char** destination, const char* source, size_t length) {
|
||||
libab_result libab_copy_string_size(char** destination, const char* source,
|
||||
size_t length) {
|
||||
return libab_copy_string_range(destination, source, 0, length);
|
||||
}
|
||||
libab_result libab_copy_string(char** destination, const char* source) {
|
||||
|
@ -40,14 +42,17 @@ libab_result _libab_check_parsetype(libab_parsetype* to_check) {
|
|||
libab_result result = LIBAB_SUCCESS;
|
||||
return result;
|
||||
}
|
||||
libab_result libab_resolve_parsetype(libab_parsetype* to_resolve, libab_table* scope) {
|
||||
libab_result libab_resolve_parsetype(libab_parsetype* to_resolve,
|
||||
libab_table* scope) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
int resolve_name, check_parents;
|
||||
size_t index = 0;
|
||||
resolve_name = !(to_resolve->variant & (LIBABACUS_TYPE_F_RESOLVED | LIBABACUS_TYPE_F_PLACE));
|
||||
resolve_name = !(to_resolve->variant &
|
||||
(LIBABACUS_TYPE_F_RESOLVED | LIBABACUS_TYPE_F_PLACE));
|
||||
check_parents = !(to_resolve->variant & LIBABACUS_TYPE_F_PLACE);
|
||||
if (resolve_name) {
|
||||
libab_basetype* basetype = libab_table_search_basetype(scope, to_resolve->data_u.name);
|
||||
libab_basetype* basetype =
|
||||
libab_table_search_basetype(scope, to_resolve->data_u.name);
|
||||
if (basetype) {
|
||||
free(to_resolve->data_u.name);
|
||||
to_resolve->data_u.base = basetype;
|
||||
|
@ -67,7 +72,8 @@ libab_result libab_resolve_parsetype(libab_parsetype* to_resolve, libab_table* s
|
|||
|
||||
if (to_resolve->variant & LIBABACUS_TYPE_F_PARENT) {
|
||||
while (result == LIBAB_SUCCESS && index < to_resolve->children.size) {
|
||||
result = libab_resolve_parsetype(libab_ref_get(&to_resolve->children.data[index]), scope);
|
||||
result = libab_resolve_parsetype(
|
||||
libab_ref_get(&to_resolve->children.data[index]), scope);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,5 +12,6 @@ void libab_value_free(libab_value* value) {
|
|||
libab_ref_free(&value->type);
|
||||
value_type = libab_ref_get(&value->type);
|
||||
free_function = value_type->data_u.base->free_function;
|
||||
if(free_function) free_function(value->data);
|
||||
if (free_function)
|
||||
free_function(value->data);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user