proc create_source_code_location(String* file, int line, int col) -> Source_Code_Location* {
    if (!file)
        return nullptr;

    Source_Code_Location* ret = new(Source_Code_Location);
    ret->file   = file;
    ret->line   = line;
    ret->column = col;
    return ret;
}

proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char* {
    switch (type) {
    case(Lisp_Object_Type::Nil):       return "nil";
    case(Lisp_Object_Type::T):         return "t";
    case(Lisp_Object_Type::Number):    return "number";
    case(Lisp_Object_Type::String):    return "string";
    case(Lisp_Object_Type::Symbol):    return "symbol";
    case(Lisp_Object_Type::Keyword):   return "keyword";
    case(Lisp_Object_Type::Function):  return "function";
    case(Lisp_Object_Type::CFunction): return "C-function";
    case(Lisp_Object_Type::Pair):      return "pair";
    }
    return "unknown";
}

proc create_positional_argument_list(int initial_capacity) -> Positional_Arguments* {
    Positional_Arguments* ret = new(Positional_Arguments);
    ret->identifiers = (String**)malloc(initial_capacity * sizeof(String*));
    ret->next_index = 0;
    ret->length = initial_capacity;
    return ret;
}

proc append_to_positional_argument_list(Positional_Arguments* args, String* identifier) -> void {
    if (args->next_index == args->length) {
        args->length *= 2;
        args->identifiers = (String**)realloc(args->identifiers, args->length * sizeof(String*));
    }
    args->identifiers[args->next_index++] = identifier;
}

proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments* {
    Keyword_Arguments* ret = new(Keyword_Arguments);
    ret->identifiers = (String**)malloc(initial_capacity * sizeof(String*));
    ret->values = create_Lisp_Object_array_list(initial_capacity);
    ret->next_index = 0;
    ret->length = initial_capacity;
    return ret;
}

proc append_to_keyword_argument_list(Keyword_Arguments* args,
                                     String* identifier,
                                     Lisp_Object* default_value) -> void
{
    if (args->next_index == args->length) {
        args->length *= 2;
        args->identifiers = (String**)realloc(args->identifiers, args->length * sizeof(String*));
    }

    args->identifiers[args->next_index++] = identifier;
    append_to_array_list(args->values, default_value);
}
