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
 | 
			
		||||
@ -58,8 +55,8 @@ typedef struct libab_basetype_s libab_basetype;
 | 
			
		||||
 * @param n the number of type parameters it has.
 | 
			
		||||
 * @param params the parameters this basetype accepts.
 | 
			
		||||
 */
 | 
			
		||||
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[]);
 | 
			
		||||
/**
 | 
			
		||||
 * Frees the given basetype.
 | 
			
		||||
 * @param basetype the type to free.
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * A function pointer that is called
 | 
			
		||||
 * to execute a certain type of function.
 | 
			
		||||
 */
 | 
			
		||||
typedef void(*libab_function_ptr)();
 | 
			
		||||
typedef void (*libab_function_ptr)();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The variant of the operator that
 | 
			
		||||
@ -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
 | 
			
		||||
@ -31,9 +31,9 @@ void libab_parser_init(libab_parser* parser, libab_table* table);
 | 
			
		||||
 * @param store_into tree pointer to store the new data into.
 | 
			
		||||
 */
 | 
			
		||||
libab_result libab_parser_parse(libab_parser* parser, ll* tokens,
 | 
			
		||||
        const char* string, libab_tree** store_into);
 | 
			
		||||
                                const char* string, libab_tree** store_into);
 | 
			
		||||
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);
 | 
			
		||||
/**
 | 
			
		||||
 * Releases the resources allocated by the parser.
 | 
			
		||||
 * @param parser the parser to release.
 | 
			
		||||
 | 
			
		||||
@ -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"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -115,7 +115,7 @@ int libab_tree_has_vector(libab_tree_variant var);
 | 
			
		||||
/**
 | 
			
		||||
 * Frees the given tree recursively,
 | 
			
		||||
 * deleting the children first and the moving on
 | 
			
		||||
 * to the parents. 
 | 
			
		||||
 * to the parents.
 | 
			
		||||
 * @param tree the tree to free.
 | 
			
		||||
 */
 | 
			
		||||
void libab_tree_free_recursive(libab_tree* tree);
 | 
			
		||||
 | 
			
		||||
@ -39,12 +39,12 @@ struct libab_trie_s {
 | 
			
		||||
    /**
 | 
			
		||||
     * The first search node in this trie.
 | 
			
		||||
     */
 | 
			
		||||
    struct libab_trie_node_s* head;   
 | 
			
		||||
    struct libab_trie_node_s* head;
 | 
			
		||||
    /**
 | 
			
		||||
     * The empty list returned if no value is found.
 | 
			
		||||
     * Note that existing nodes return their own linked
 | 
			
		||||
     * list of values, even if empty. However, for keys
 | 
			
		||||
     * that don't exist as prefixes in the trie, 
 | 
			
		||||
     * that don't exist as prefixes in the trie,
 | 
			
		||||
     * this list is returned to maintain consistency:
 | 
			
		||||
     * a list is always returned containing the values
 | 
			
		||||
     * of the trie associated with the given key.
 | 
			
		||||
@ -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) {}
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
void libab_behavior_free(libab_behavior* behavior) {
 | 
			
		||||
    libab_ref_free(&behavior->type);
 | 
			
		||||
    if(behavior->impl.variant == BIMPL_TREE) {
 | 
			
		||||
    if (behavior->impl.variant == BIMPL_TREE) {
 | 
			
		||||
        libab_ref_free(&behavior->impl.data_u.tree);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								src/debug.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								src/debug.c
									
									
									
									
									
								
							@ -4,30 +4,15 @@ 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];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _debug_print_tree_node(libab_tree* tree, FILE* file) {
 | 
			
		||||
    fprintf(file, "%s", _debug_node_name(tree->variant));
 | 
			
		||||
    if(libab_tree_has_string(tree->variant)) {
 | 
			
		||||
    if (libab_tree_has_string(tree->variant)) {
 | 
			
		||||
        fprintf(file, ": %s", tree->string_value);
 | 
			
		||||
    }
 | 
			
		||||
    fprintf(file, "\n");
 | 
			
		||||
@ -35,11 +20,12 @@ 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)) {
 | 
			
		||||
    if (libab_tree_has_vector(tree->variant)) {
 | 
			
		||||
        vec_foreach(&tree->children, NULL, compare_always,
 | 
			
		||||
                _debug_foreach_print_tree, file, depth + 1);
 | 
			
		||||
                    _debug_foreach_print_tree, file, depth + 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										78
									
								
								src/lexer.c
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								src/lexer.c
									
									
									
									
									
								
							@ -1,49 +1,37 @@
 | 
			
		||||
#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[] = {
 | 
			
		||||
        ".",
 | 
			
		||||
        "[a-zA-Z][a-zA-Z0-9_]*",
 | 
			
		||||
        "[0-9]+(\\.[0-9]*)?",
 | 
			
		||||
        "if",
 | 
			
		||||
        "else",
 | 
			
		||||
        "while",
 | 
			
		||||
        "do",
 | 
			
		||||
        "->",
 | 
			
		||||
        "fun",
 | 
			
		||||
        "return",
 | 
			
		||||
        "let",
 | 
			
		||||
        "be"
 | 
			
		||||
    };
 | 
			
		||||
    const char* words[] = {".",
 | 
			
		||||
                           "[a-zA-Z][a-zA-Z0-9_]*",
 | 
			
		||||
                           "[0-9]+(\\.[0-9]*)?",
 | 
			
		||||
                           "if",
 | 
			
		||||
                           "else",
 | 
			
		||||
                           "while",
 | 
			
		||||
                           "do",
 | 
			
		||||
                           "->",
 | 
			
		||||
                           "fun",
 | 
			
		||||
                           "return",
 | 
			
		||||
                           "let",
 | 
			
		||||
                           "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
 | 
			
		||||
    };
 | 
			
		||||
    const size_t count = sizeof(tokens)/sizeof(libab_lexer_token);
 | 
			
		||||
        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);
 | 
			
		||||
    for(i = 0; i < count && result == LIBAB_SUCCESS; i++) {
 | 
			
		||||
    for (i = 0; i < count && result == LIBAB_SUCCESS; i++) {
 | 
			
		||||
        result = libab_convert_lex_result(
 | 
			
		||||
                eval_config_add(&lexer->config, words[i], tokens[i]));
 | 
			
		||||
            eval_config_add(&lexer->config, words[i], tokens[i]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result != LIBAB_SUCCESS) {
 | 
			
		||||
    if (result != LIBAB_SUCCESS) {
 | 
			
		||||
        eval_config_free(&lexer->config);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -62,19 +50,19 @@ int _lexer_foreach_convert_match(void* data, va_list args) {
 | 
			
		||||
    match* match = data;
 | 
			
		||||
    struct lexer_state* state = va_arg(args, struct lexer_state*);
 | 
			
		||||
    char first_char = state->source[match->from];
 | 
			
		||||
    if(isspace(first_char)) {
 | 
			
		||||
    if (isspace(first_char)) {
 | 
			
		||||
        /* Skip */
 | 
			
		||||
    } else if(first_char == '\n') { 
 | 
			
		||||
    } else if (first_char == '\n') {
 | 
			
		||||
        state->line++;
 | 
			
		||||
        state->line_from = match->to;
 | 
			
		||||
    } else if((new_match = malloc(sizeof(*new_match)))) {
 | 
			
		||||
    } else if ((new_match = malloc(sizeof(*new_match)))) {
 | 
			
		||||
        new_match->type = match->pattern;
 | 
			
		||||
        new_match->from = match->from;
 | 
			
		||||
        new_match->to = match->to;
 | 
			
		||||
        new_match->line_from = state->line_from;
 | 
			
		||||
        new_match->line = state->line;
 | 
			
		||||
        result = libab_convert_ds_result(ll_append(state->matches, new_match));
 | 
			
		||||
        if(result != LIBAB_SUCCESS) {
 | 
			
		||||
        if (result != LIBAB_SUCCESS) {
 | 
			
		||||
            free(new_match);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -96,15 +85,16 @@ libab_result libab_lexer_lex(libab_lexer* lexer, const char* string, ll* lex_int
 | 
			
		||||
    state.source = string;
 | 
			
		||||
 | 
			
		||||
    result = libab_convert_lex_result(
 | 
			
		||||
            eval_all(string, 0, &lexer->config, &raw_matches));
 | 
			
		||||
        eval_all(string, 0, &lexer->config, &raw_matches));
 | 
			
		||||
 | 
			
		||||
    if(result == LIBAB_SUCCESS) {
 | 
			
		||||
        result = (libab_result) ll_foreach(&raw_matches, NULL, compare_always,
 | 
			
		||||
                                           _lexer_foreach_convert_match, &state);
 | 
			
		||||
    if (result == LIBAB_SUCCESS) {
 | 
			
		||||
        result = (libab_result)ll_foreach(&raw_matches, NULL, compare_always,
 | 
			
		||||
                                          _lexer_foreach_convert_match, &state);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result != LIBAB_SUCCESS) {
 | 
			
		||||
        ll_foreach(lex_into, NULL, compare_always, libab_lexer_foreach_match_free);
 | 
			
		||||
    if (result != LIBAB_SUCCESS) {
 | 
			
		||||
        ll_foreach(lex_into, NULL, compare_always,
 | 
			
		||||
                   libab_lexer_foreach_match_free);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ll_foreach(&raw_matches, NULL, compare_always, eval_foreach_match_free);
 | 
			
		||||
@ -116,6 +106,6 @@ libab_result libab_lexer_free(libab_lexer* lexer) {
 | 
			
		||||
    return libab_convert_lex_result(eval_config_free(&lexer->config));
 | 
			
		||||
}
 | 
			
		||||
int libab_lexer_foreach_match_free(void* data, va_list args) {
 | 
			
		||||
    free((libab_lexer_match*) data);
 | 
			
		||||
    free((libab_lexer_match*)data);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -10,11 +10,11 @@ libab_result libab_init(libab* ab) {
 | 
			
		||||
    libab_parser_init(&ab->parser, &ab->table);
 | 
			
		||||
    result = libab_lexer_init(&ab->lexer);
 | 
			
		||||
 | 
			
		||||
    if(result == LIBAB_SUCCESS) {
 | 
			
		||||
    if (result == LIBAB_SUCCESS) {
 | 
			
		||||
        result = libab_register_reserved_operators(&ab->lexer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result != LIBAB_SUCCESS) {
 | 
			
		||||
    if (result != LIBAB_SUCCESS) {
 | 
			
		||||
        libab_table_free(&ab->table);
 | 
			
		||||
        libab_parser_free(&ab->parser);
 | 
			
		||||
        libab_lexer_free(&ab->lexer);
 | 
			
		||||
@ -25,25 +25,29 @@ 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++] = '\\';       
 | 
			
		||||
    while (*from && index < (buffer_size - 2)) {
 | 
			
		||||
        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;
 | 
			
		||||
    if((new_entry = malloc(sizeof(*new_entry)))) {
 | 
			
		||||
    if ((new_entry = malloc(sizeof(*new_entry)))) {
 | 
			
		||||
        new_entry->variant = ENTRY_OP;
 | 
			
		||||
        new_entry->data_u.op.precedence = precedence;
 | 
			
		||||
        new_entry->data_u.op.associativity = associativity;
 | 
			
		||||
@ -53,17 +57,18 @@ libab_result _register_operator(libab* ab, const char* op, libab_operator_varian
 | 
			
		||||
        result = LIBAB_MALLOC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result == LIBAB_SUCCESS) {
 | 
			
		||||
    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) {
 | 
			
		||||
    if (result == LIBAB_SUCCESS) {
 | 
			
		||||
        result = libab_table_put(&ab->table, op, new_entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result != LIBAB_SUCCESS) {
 | 
			
		||||
        if(new_entry)
 | 
			
		||||
    if (result != LIBAB_SUCCESS) {
 | 
			
		||||
        if (new_entry)
 | 
			
		||||
            libab_ref_free(&new_entry->data_u.op.behavior.type);
 | 
			
		||||
        eval_config_remove(&ab->lexer.config, op, TOKEN_OP);
 | 
			
		||||
        free(new_entry);
 | 
			
		||||
@ -72,34 +77,44 @@ 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)))) {
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result == LIBAB_SUCCESS) {
 | 
			
		||||
    if (result == LIBAB_SUCCESS) {
 | 
			
		||||
        result = libab_table_put(&ab->table, name, new_entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result != LIBAB_SUCCESS) {
 | 
			
		||||
        if(new_entry)
 | 
			
		||||
    if (result != LIBAB_SUCCESS) {
 | 
			
		||||
        if (new_entry)
 | 
			
		||||
            libab_ref_free(&new_entry->data_u.function.behavior.type);
 | 
			
		||||
        free(new_entry);
 | 
			
		||||
    }
 | 
			
		||||
@ -107,19 +122,20 @@ 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)))) {
 | 
			
		||||
    if ((new_entry = malloc(sizeof(*new_entry)))) {
 | 
			
		||||
        new_entry->variant = ENTRY_BASETYPE;
 | 
			
		||||
        new_entry->data_u.basetype = basetype;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result == LIBAB_SUCCESS) {
 | 
			
		||||
    if (result == LIBAB_SUCCESS) {
 | 
			
		||||
        result = libab_table_put(&ab->table, name, new_entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result != LIBAB_SUCCESS) {
 | 
			
		||||
    if (result != LIBAB_SUCCESS) {
 | 
			
		||||
        free(new_entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -131,7 +147,7 @@ libab_result libab_create_type(libab* ab, libab_ref* into, const char* type) {
 | 
			
		||||
    ll tokens;
 | 
			
		||||
    ll_init(&tokens);
 | 
			
		||||
    result = libab_lexer_lex(&ab->lexer, type, &tokens);
 | 
			
		||||
    if(result == LIBAB_SUCCESS) {
 | 
			
		||||
    if (result == LIBAB_SUCCESS) {
 | 
			
		||||
        result = libab_parser_parse_type(&ab->parser, &tokens, type, into);
 | 
			
		||||
    }
 | 
			
		||||
    ll_foreach(&tokens, NULL, compare_always, libab_lexer_foreach_match_free);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										659
									
								
								src/parser.c
									
									
									
									
									
								
							
							
						
						
									
										659
									
								
								src/parser.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -2,10 +2,10 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
void libab_parsetype_free(libab_parsetype* type) {
 | 
			
		||||
    if(!(type->variant & LIBABACUS_TYPE_F_RESOLVED)) {
 | 
			
		||||
    if (!(type->variant & LIBABACUS_TYPE_F_RESOLVED)) {
 | 
			
		||||
        free(type->data_u.name);
 | 
			
		||||
    }
 | 
			
		||||
    if(type->variant & LIBABACUS_TYPE_F_PARENT) {
 | 
			
		||||
    if (type->variant & LIBABACUS_TYPE_F_PARENT) {
 | 
			
		||||
        libab_ref_vec_free(&(type->children));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -6,13 +6,14 @@ 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)))) {
 | 
			
		||||
    if ((*node = malloc(sizeof(**node)))) {
 | 
			
		||||
        (*node)->key = *key;
 | 
			
		||||
        (*node)->next = NULL;
 | 
			
		||||
 | 
			
		||||
        if(*(key + 1)) {
 | 
			
		||||
        if (*(key + 1)) {
 | 
			
		||||
            libab_ref_null(&(*node)->ref);
 | 
			
		||||
            result = _libab_ref_trie_put(&(*node)->child, key + 1, ref);
 | 
			
		||||
        } else {
 | 
			
		||||
@ -23,8 +24,9 @@ libab_result _libab_ref_trie_put(libab_ref_trie_node** node, const char* key, li
 | 
			
		||||
        result = LIBAB_MALLOC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result != LIBAB_SUCCESS) {
 | 
			
		||||
        if(*node) libab_ref_free(&(*node)->ref);
 | 
			
		||||
    if (result != LIBAB_SUCCESS) {
 | 
			
		||||
        if (*node)
 | 
			
		||||
            libab_ref_free(&(*node)->ref);
 | 
			
		||||
        free(*node);
 | 
			
		||||
        *node = NULL;
 | 
			
		||||
    }
 | 
			
		||||
@ -32,17 +34,18 @@ 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;
 | 
			
		||||
    while(*key) {
 | 
			
		||||
    while (*key) {
 | 
			
		||||
        search = *key;
 | 
			
		||||
        while(*current && (*current)->key != search) {
 | 
			
		||||
        while (*current && (*current)->key != search) {
 | 
			
		||||
            current = &(*current)->next;
 | 
			
		||||
        }
 | 
			
		||||
        if(*current) {
 | 
			
		||||
            if(*(key + 1)) {
 | 
			
		||||
        if (*current) {
 | 
			
		||||
            if (*(key + 1)) {
 | 
			
		||||
                current = &(*current)->child;
 | 
			
		||||
            } else {
 | 
			
		||||
                libab_ref_free(&(*current)->ref);
 | 
			
		||||
@ -57,15 +60,17 @@ 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) {
 | 
			
		||||
    while (current && *key) {
 | 
			
		||||
        while (current && current->key != *key) {
 | 
			
		||||
            current = current->next;
 | 
			
		||||
        }
 | 
			
		||||
        if(current == NULL) break;
 | 
			
		||||
        if (current == NULL)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        if(*(key + 1)) {
 | 
			
		||||
        if (*(key + 1)) {
 | 
			
		||||
            current = current->child;
 | 
			
		||||
            key++;
 | 
			
		||||
        } else {
 | 
			
		||||
@ -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,9 +5,8 @@ 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);
 | 
			
		||||
    if(vec->data == NULL) {
 | 
			
		||||
    vec->data = malloc(sizeof(*vec->data) * LIBABACUS_REF_VEC_INITIAL_SIZE);
 | 
			
		||||
    if (vec->data == NULL) {
 | 
			
		||||
        result = LIBAB_MALLOC;
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
@ -15,9 +14,10 @@ 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));
 | 
			
		||||
        if(new_memory == NULL) {
 | 
			
		||||
    if (vec->size == vec->capacity) {
 | 
			
		||||
        libab_ref* new_memory =
 | 
			
		||||
            realloc(vec->data, (vec->capacity *= 2) * sizeof(*vec->data));
 | 
			
		||||
        if (new_memory == NULL) {
 | 
			
		||||
            free(vec->data);
 | 
			
		||||
            result = LIBAB_MALLOC;
 | 
			
		||||
        }
 | 
			
		||||
@ -28,30 +28,31 @@ libab_result _libab_ref_vec_try_resize(libab_ref_vec* vec) {
 | 
			
		||||
libab_result libab_ref_vec_insert(libab_ref_vec* vec, libab_ref* data) {
 | 
			
		||||
    libab_result result = _libab_ref_vec_try_resize(vec);
 | 
			
		||||
 | 
			
		||||
    if(result == LIBAB_SUCCESS) {
 | 
			
		||||
    if (result == LIBAB_SUCCESS) {
 | 
			
		||||
        libab_ref_copy(data, &vec->data[vec->size++]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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) {
 | 
			
		||||
    if (result == LIBAB_SUCCESS) {
 | 
			
		||||
        result = libab_ref_new(&vec->data[vec->size], data, free_func);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result == LIBAB_SUCCESS) {
 | 
			
		||||
    if (result == LIBAB_SUCCESS) {
 | 
			
		||||
        vec->size++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const libab_ref* libab_ref_vec_index(libab_ref_vec* vec, size_t index) {
 | 
			
		||||
    const libab_ref* to_return = NULL;
 | 
			
		||||
    if(index < vec->size) {
 | 
			
		||||
    if (index < vec->size) {
 | 
			
		||||
        to_return = &vec->data[index];
 | 
			
		||||
    }
 | 
			
		||||
    return to_return;
 | 
			
		||||
@ -59,7 +60,7 @@ const libab_ref* libab_ref_vec_index(libab_ref_vec* vec, size_t index) {
 | 
			
		||||
 | 
			
		||||
void libab_ref_vec_free(libab_ref_vec* vec) {
 | 
			
		||||
    size_t i = 0;
 | 
			
		||||
    for(; i < vec->size; i++) {
 | 
			
		||||
    for (; i < vec->size; i++) {
 | 
			
		||||
        libab_ref_free(&vec->data[i]);
 | 
			
		||||
    }
 | 
			
		||||
    free(vec->data);
 | 
			
		||||
 | 
			
		||||
@ -2,11 +2,12 @@
 | 
			
		||||
#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;
 | 
			
		||||
    if((ref->count = malloc(sizeof(*(ref->count))))) {
 | 
			
		||||
    if ((ref->count = malloc(sizeof(*(ref->count))))) {
 | 
			
		||||
        ref->count->strong = ref->count->weak = 1;
 | 
			
		||||
        ref->count->free_func = free_func;
 | 
			
		||||
    } else {
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -29,20 +26,20 @@ void libab_ref_null(libab_ref* ref) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _libab_ref_changed(libab_ref* ref) {
 | 
			
		||||
    if(ref->count->strong == 0) {
 | 
			
		||||
    if (ref->count->strong == 0) {
 | 
			
		||||
        ref->count->strong--;
 | 
			
		||||
        if(ref->count->free_func) {
 | 
			
		||||
        if (ref->count->free_func) {
 | 
			
		||||
            ref->count->free_func(ref->data);
 | 
			
		||||
        }
 | 
			
		||||
        free(ref->data);
 | 
			
		||||
    }
 | 
			
		||||
    if(ref->count->weak == 0) {
 | 
			
		||||
    if (ref->count->weak == 0) {
 | 
			
		||||
        free(ref->count);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void libab_ref_weaken(libab_ref* ref) {
 | 
			
		||||
    if(ref->strong) {
 | 
			
		||||
    if (ref->strong) {
 | 
			
		||||
        ref->count->strong--;
 | 
			
		||||
        ref->strong = 0;
 | 
			
		||||
        _libab_ref_changed(ref);
 | 
			
		||||
@ -63,7 +60,7 @@ void libab_ref_copy(const libab_ref* ref, libab_ref* into) {
 | 
			
		||||
 | 
			
		||||
void* libab_ref_get(const libab_ref* ref) {
 | 
			
		||||
    void* to_return = NULL;
 | 
			
		||||
    if(ref->count->strong > 0) {
 | 
			
		||||
    if (ref->count->strong > 0) {
 | 
			
		||||
        to_return = ref->data;
 | 
			
		||||
    }
 | 
			
		||||
    return to_return;
 | 
			
		||||
 | 
			
		||||
@ -2,20 +2,18 @@
 | 
			
		||||
#include "string.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
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 = 
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
const libab_reserved_operator* libab_find_reserved_operator(const char* name) {
 | 
			
		||||
    size_t i;
 | 
			
		||||
    for(i = 0; i < element_count; i++) {
 | 
			
		||||
        if(strcmp(name, libab_reserved_operators[i].op) == 0)
 | 
			
		||||
    for (i = 0; i < element_count; i++) {
 | 
			
		||||
        if (strcmp(name, libab_reserved_operators[i].op) == 0)
 | 
			
		||||
            return &libab_reserved_operators[i];
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
@ -24,9 +22,9 @@ const libab_reserved_operator* libab_find_reserved_operator(const char* name) {
 | 
			
		||||
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));
 | 
			
		||||
    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));
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
@ -34,9 +32,9 @@ libab_result libab_register_reserved_operators(libab_lexer* lexer) {
 | 
			
		||||
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));
 | 
			
		||||
    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));
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										66
									
								
								src/table.c
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								src/table.c
									
									
									
									
									
								
							@ -1,19 +1,21 @@
 | 
			
		||||
#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);
 | 
			
		||||
        to_return = ll_find(matches, data, compare);
 | 
			
		||||
        table = table->parent;
 | 
			
		||||
    } while(table && to_return == NULL);
 | 
			
		||||
    } while (table && to_return == NULL);
 | 
			
		||||
    return to_return;
 | 
			
		||||
}
 | 
			
		||||
libab_table_entry* libab_table_search(libab_table* table, const char* string) {
 | 
			
		||||
@ -21,27 +23,32 @@ libab_table_entry* libab_table_search(libab_table* table, const char* string) {
 | 
			
		||||
    do {
 | 
			
		||||
        to_return = ll_head(libab_trie_get(&table->trie, string));
 | 
			
		||||
        table = table->parent;
 | 
			
		||||
    } while(table && to_return == NULL);
 | 
			
		||||
    } while (table && to_return == NULL);
 | 
			
		||||
    return to_return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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;\
 | 
			
		||||
}
 | 
			
		||||
#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;    \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
    } else if(type == OPERATOR_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);
 | 
			
		||||
    if (type == OPERATOR_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);
 | 
			
		||||
    } else if (type == OPERATOR_PREFIX) {
 | 
			
		||||
        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,15 +87,16 @@ 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) {
 | 
			
		||||
    if(entry->variant == ENTRY_OP) {
 | 
			
		||||
    if (entry->variant == ENTRY_OP) {
 | 
			
		||||
        libab_operator_free(&entry->data_u.op);
 | 
			
		||||
    } else if(entry->variant == ENTRY_FUN) {
 | 
			
		||||
    } else if (entry->variant == ENTRY_FUN) {
 | 
			
		||||
        libab_function_free(&entry->data_u.function);
 | 
			
		||||
    } else if(entry->variant == ENTRY_BASETYPE) {
 | 
			
		||||
    } else if (entry->variant == ENTRY_BASETYPE) {
 | 
			
		||||
        libab_basetype_free(entry->data_u.basetype);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										31
									
								
								src/tree.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								src/tree.c
									
									
									
									
									
								
							@ -3,23 +3,24 @@
 | 
			
		||||
 | 
			
		||||
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_DOWHILE || variant == TREE_FUN ||
 | 
			
		||||
            variant == TREE_RETURN || variant == TREE_RESERVED_OP;
 | 
			
		||||
           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 ||
 | 
			
		||||
            variant == TREE_FUN || variant == TREE_FUN_PARAM ||
 | 
			
		||||
            variant == TREE_RESERVED_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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libab_tree_has_scope(libab_tree_variant variant) {
 | 
			
		||||
    return variant == TREE_BASE || variant == TREE_BLOCK ||
 | 
			
		||||
        variant == TREE_IF || variant == TREE_WHILE ||
 | 
			
		||||
        variant == TREE_DOWHILE || variant == TREE_FUN;
 | 
			
		||||
           variant == TREE_IF || variant == TREE_WHILE ||
 | 
			
		||||
           variant == TREE_DOWHILE || variant == TREE_FUN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int libab_tree_has_type(libab_tree_variant variant) {
 | 
			
		||||
@ -33,9 +34,11 @@ 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_type)
 | 
			
		||||
    if (free_string)
 | 
			
		||||
        free(tree->string_value);
 | 
			
		||||
    if (free_vector)
 | 
			
		||||
        vec_free(&tree->children);
 | 
			
		||||
    if (free_type)
 | 
			
		||||
        libab_ref_free(&tree->type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -45,7 +48,7 @@ int _tree_foreach_free(void* data, va_list args) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void libab_tree_free_recursive(libab_tree* tree) {
 | 
			
		||||
    if(libab_tree_has_vector(tree->variant)) {
 | 
			
		||||
    if (libab_tree_has_vector(tree->variant)) {
 | 
			
		||||
        vec_foreach(&tree->children, NULL, compare_always, _tree_foreach_free);
 | 
			
		||||
    }
 | 
			
		||||
    libab_tree_free(tree);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										53
									
								
								src/trie.c
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								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,31 +8,34 @@ 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)))) {
 | 
			
		||||
    if ((*node = malloc(sizeof(**node)))) {
 | 
			
		||||
        (*node)->key = *key;
 | 
			
		||||
        (*node)->next = NULL;
 | 
			
		||||
        ll_init(&(*node)->values);
 | 
			
		||||
 | 
			
		||||
        if(*(key + 1)) {
 | 
			
		||||
        if (*(key + 1)) {
 | 
			
		||||
            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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(result != LIBAB_SUCCESS) {
 | 
			
		||||
    if (result != LIBAB_SUCCESS) {
 | 
			
		||||
        free(*node);
 | 
			
		||||
        *node = NULL;
 | 
			
		||||
    }
 | 
			
		||||
@ -48,13 +51,13 @@ libab_result libab_trie_put(libab_trie* trie, const char* key, void* value) {
 | 
			
		||||
    libab_result result = LIBAB_SUCCESS;
 | 
			
		||||
    libab_trie_node** current = &trie->head;
 | 
			
		||||
    char search;
 | 
			
		||||
    while(*key) {
 | 
			
		||||
    while (*key) {
 | 
			
		||||
        search = *key;
 | 
			
		||||
        while(*current && (*current)->key != search) {
 | 
			
		||||
        while (*current && (*current)->key != search) {
 | 
			
		||||
            current = &(*current)->next;
 | 
			
		||||
        }
 | 
			
		||||
        if(*current) {
 | 
			
		||||
            if(*(key + 1)) {
 | 
			
		||||
        if (*current) {
 | 
			
		||||
            if (*(key + 1)) {
 | 
			
		||||
                current = &(*current)->child;
 | 
			
		||||
            } else {
 | 
			
		||||
                result = _libab_trie_add(*current, value);
 | 
			
		||||
@ -70,13 +73,14 @@ 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) {
 | 
			
		||||
    libab_trie_node* current = trie->head;
 | 
			
		||||
    while(current && *key) {
 | 
			
		||||
        while(current && current->key != *key) {
 | 
			
		||||
    while (current && *key) {
 | 
			
		||||
        while (current && current->key != *key) {
 | 
			
		||||
            current = current->next;
 | 
			
		||||
        }
 | 
			
		||||
        if(current == NULL) break;
 | 
			
		||||
        
 | 
			
		||||
        if(*(key + 1)) {
 | 
			
		||||
        if (current == NULL)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        if (*(key + 1)) {
 | 
			
		||||
            current = current->child;
 | 
			
		||||
            key++;
 | 
			
		||||
        } else {
 | 
			
		||||
@ -86,24 +90,27 @@ 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);  
 | 
			
		||||
    if (return_code == 0) {
 | 
			
		||||
        return_code = _libab_trie_foreach(node->child, data, compare, foreach);
 | 
			
		||||
    }
 | 
			
		||||
    if(return_code == 0) {
 | 
			
		||||
    if (return_code == 0) {
 | 
			
		||||
        return_code = _libab_trie_foreach(node->next, data, compare, foreach);
 | 
			
		||||
    }
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void libab_trie_free(libab_trie* trie) {
 | 
			
		||||
    _libab_trie_free(trie->head);   
 | 
			
		||||
    _libab_trie_free(trie->head);
 | 
			
		||||
    trie->head = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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); }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										42
									
								
								src/util.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								src/util.c
									
									
									
									
									
								
							@ -3,26 +3,27 @@
 | 
			
		||||
 | 
			
		||||
libab_result libab_convert_lex_result(liblex_result to_convert) {
 | 
			
		||||
    libab_result result = LIBAB_SUCCESS;
 | 
			
		||||
    if(to_convert == LIBLEX_MALLOC) {
 | 
			
		||||
    if (to_convert == LIBLEX_MALLOC) {
 | 
			
		||||
        result = LIBAB_MALLOC;
 | 
			
		||||
    } else if(to_convert == LIBLEX_INVALID) {
 | 
			
		||||
    } else if (to_convert == LIBLEX_INVALID) {
 | 
			
		||||
        result = LIBAB_BAD_PATTERN;
 | 
			
		||||
    } else if(to_convert == LIBLEX_UNRECOGNIZED) {
 | 
			
		||||
    } else if (to_convert == LIBLEX_UNRECOGNIZED) {
 | 
			
		||||
        result = LIBAB_FAILED_MATCH;
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
libab_result libab_convert_ds_result(libds_result to_convert) {
 | 
			
		||||
    libab_result result = LIBAB_SUCCESS;
 | 
			
		||||
    if(to_convert == LIBDS_MALLOC) {
 | 
			
		||||
    if (to_convert == LIBDS_MALLOC) {
 | 
			
		||||
        result = LIBAB_MALLOC;
 | 
			
		||||
    }
 | 
			
		||||
    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) {
 | 
			
		||||
    if ((*destination = malloc(string_length + 1)) == NULL) {
 | 
			
		||||
        result = LIBAB_MALLOC;
 | 
			
		||||
    } else {
 | 
			
		||||
        strncpy(*destination, source + from, string_length);
 | 
			
		||||
@ -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,15 +42,18 @@ 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);
 | 
			
		||||
        if(basetype) {
 | 
			
		||||
    if (resolve_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;
 | 
			
		||||
            to_resolve->variant |= LIBABACUS_TYPE_F_RESOLVED;
 | 
			
		||||
@ -57,17 +62,18 @@ libab_result libab_resolve_parsetype(libab_parsetype* to_resolve, libab_table* s
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(check_parents && result == LIBAB_SUCCESS) {
 | 
			
		||||
        if(to_resolve->variant & LIBABACUS_TYPE_F_PARENT) {
 | 
			
		||||
    if (check_parents && result == LIBAB_SUCCESS) {
 | 
			
		||||
        if (to_resolve->variant & LIBABACUS_TYPE_F_PARENT) {
 | 
			
		||||
            result = _libab_check_parsetype(to_resolve);
 | 
			
		||||
        } else if(to_resolve->data_u.base->count) {
 | 
			
		||||
        } else if (to_resolve->data_u.base->count) {
 | 
			
		||||
            result = LIBAB_BAD_TYPE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    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);
 | 
			
		||||
            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