muon/include/lang/object.h
2022-05-27 09:10:37 -05:00

505 lines
14 KiB
C

#ifndef MUON_LANG_OBJECT_H
#define MUON_LANG_OBJECT_H
#include <stdarg.h>
#include <stdio.h>
#include "compilers.h"
#include "iterator.h"
#include "lang/types.h"
enum obj_type {
/* meta object types */
obj_any = 0, // used for argument type checking
obj_default, // used for function lookup
/* singleton object types */
obj_null,
obj_meson,
obj_disabler,
obj_machine, // this won't be a singleton object when cross compilaton is implemented
/* simple object types */
obj_bool,
obj_file,
obj_feature_opt,
/* complex object types */
_obj_aos_start,
obj_number = _obj_aos_start,
obj_string,
obj_array,
obj_dict,
obj_compiler,
obj_build_target,
obj_custom_target,
obj_subproject,
obj_dependency,
obj_external_program,
obj_external_library,
obj_run_result,
obj_configuration_data,
obj_test,
obj_module,
obj_install_target,
obj_environment,
obj_include_directory,
obj_option,
obj_generator,
obj_generated_list,
obj_alias_target,
obj_both_libs,
obj_typeinfo,
obj_type_count,
};
enum obj_typechecking_type {
ARG_TYPE_NULL = obj_type_count + 1,
obj_typechecking_type_tag = 1 << 29,
ARG_TYPE_ARRAY_OF = 1 << 30,
ARG_TYPE_GLOB = 1 << 28,
tc_bool = obj_typechecking_type_tag | (1 << 0),
tc_file = obj_typechecking_type_tag | (1 << 1),
tc_number = obj_typechecking_type_tag | (1 << 2),
tc_string = obj_typechecking_type_tag | (1 << 3),
tc_array = obj_typechecking_type_tag | (1 << 4),
tc_dict = obj_typechecking_type_tag | (1 << 5),
tc_compiler = obj_typechecking_type_tag | (1 << 6),
tc_build_target = obj_typechecking_type_tag | (1 << 7),
tc_custom_target = obj_typechecking_type_tag | (1 << 8),
tc_subproject = obj_typechecking_type_tag | (1 << 9),
tc_dependency = obj_typechecking_type_tag | (1 << 10),
tc_feature_opt = obj_typechecking_type_tag | (1 << 11),
tc_external_program = obj_typechecking_type_tag | (1 << 12),
tc_external_library = obj_typechecking_type_tag | (1 << 13),
tc_run_result = obj_typechecking_type_tag | (1 << 14),
tc_configuration_data = obj_typechecking_type_tag | (1 << 15),
tc_test = obj_typechecking_type_tag | (1 << 16),
tc_module = obj_typechecking_type_tag | (1 << 17),
tc_install_target = obj_typechecking_type_tag | (1 << 18),
tc_environment = obj_typechecking_type_tag | (1 << 19),
tc_include_directory = obj_typechecking_type_tag | (1 << 20),
tc_option = obj_typechecking_type_tag | (1 << 21),
tc_generator = obj_typechecking_type_tag | (1 << 22),
tc_generated_list = obj_typechecking_type_tag | (1 << 23),
tc_alias_target = obj_typechecking_type_tag | (1 << 24),
tc_both_libs = obj_typechecking_type_tag | (1 << 25),
tc_disabler = obj_typechecking_type_tag | (1 << 26),
tc_any = tc_bool | tc_file | tc_number | tc_string | tc_array | tc_dict
| tc_compiler | tc_build_target | tc_custom_target
| tc_subproject | tc_dependency | tc_feature_opt
| tc_external_program | tc_external_library | tc_run_result
| tc_configuration_data | tc_test | tc_module
| tc_install_target | tc_environment | tc_include_directory
| tc_option | tc_generator | tc_generated_list
| tc_alias_target | tc_both_libs | tc_disabler,
tc_exe = tc_string | tc_file | tc_external_program | tc_build_target | tc_custom_target | tc_both_libs,
tc_dep = tc_dependency | tc_external_library,
tc_coercible_env = tc_environment | tc_string | tc_array | tc_dict,
tc_coercible_files = tc_string | tc_custom_target | tc_build_target | tc_file | tc_both_libs,
tc_coercible_inc = tc_string | tc_include_directory,
tc_command_array = ARG_TYPE_ARRAY_OF | tc_exe,
tc_depends_kw = ARG_TYPE_ARRAY_OF | tc_build_target | tc_custom_target | tc_both_libs,
tc_install_mode_kw = ARG_TYPE_ARRAY_OF | tc_string | tc_number | tc_bool,
tc_required_kw = tc_bool | tc_feature_opt,
tc_link_with_kw = ARG_TYPE_ARRAY_OF | tc_build_target | tc_custom_target | tc_file | tc_string | tc_both_libs,
tc_message = ARG_TYPE_GLOB | tc_string | tc_bool | tc_number | tc_array | tc_dict, // doesn't handle nested types
};
struct obj_typechecking_type_to_obj_type {
enum obj_type type;
enum obj_typechecking_type tc;
};
struct obj_typeinfo {
uint32_t type, subtype;
};
extern const struct obj_typechecking_type_to_obj_type typemap[27];
#if __STDC_VERSION__ >= 201112L
_Static_assert(!(ARG_TYPE_NULL & ARG_TYPE_GLOB), "ARG_TYPE_NULL to big");
#endif
enum tgt_type {
tgt_executable = 1 << 0,
tgt_static_library = 1 << 1,
tgt_dynamic_library = 1 << 2,
tgt_shared_module = 1 << 3,
};
enum tgt_type_count { tgt_type_count = 4, }; // keep in sync
enum feature_opt_state {
feature_opt_auto,
feature_opt_enabled,
feature_opt_disabled,
};
enum module {
module_fs,
module_python,
module_python3,
module_pkgconfig,
module_count,
};
enum str_flags {
str_flag_big = 1 << 0,
};
struct str {
const char *s;
uint32_t len;
enum str_flags flags;
};
struct obj_internal {
enum obj_type t;
uint32_t val;
};
struct obj_subproject {
uint32_t id;
bool found;
};
struct obj_module {
enum module module;
bool found;
};
struct obj_array {
obj val; // obj_any
obj next; // obj_array
obj tail; // obj_array
uint32_t len;
bool have_next;
};
struct obj_dict {
obj key; // obj_string
obj val; // obj_any
obj next; // obj_array
obj tail; // obj_array
uint32_t len;
bool have_next;
};
enum build_tgt_flags {
build_tgt_flag_export_dynamic = 1 << 0,
build_tgt_flag_pic = 1 << 1,
build_tgt_generated_include = 1 << 2,
build_tgt_flag_build_by_default = 1 << 3,
build_tgt_flag_visibility = 1 << 4,
build_tgt_flag_installed = 1 << 5,
};
struct obj_build_target {
obj name; // obj_string
obj build_name; // obj_string
obj build_path; // obj_string
obj private_path; // obj_string
obj cwd; // obj_string
obj build_dir; // obj_string
obj soname; // obj_string
obj src; // obj_array
obj link_with; // obj_array
obj link_whole; // obj_array
obj include_directories; // obj_array
obj deps; // obj_array
obj args; // obj_dict
obj link_args; // obj_array
obj link_depends; // obj_array
obj order_deps; // obj_array
obj generated_pc; // obj_string
obj override_options; // obj_array
enum compiler_visibility_type visibility;
enum build_tgt_flags flags;
enum tgt_type type;
};
struct obj_both_libs {
obj static_lib; // obj_build_target
obj dynamic_lib; // obj_build_target
};
enum custom_target_flags {
custom_target_capture = 1 << 0,
custom_target_build_always_stale = 1 << 1,
custom_target_build_by_default = 1 << 2,
custom_target_feed = 1 << 3,
};
struct obj_custom_target {
obj name; // obj_string
obj args; // obj_array
obj input; // obj_array
obj output; // obj_array
obj depends; // obj_array
obj private_path; // obj_string
obj env; // str | list[str] | dict[str] | env
enum custom_target_flags flags;
};
struct obj_alias_target {
obj name; // obj_string
obj depends; // obj_array
};
enum dependency_type {
dependency_type_declared,
dependency_type_pkgconf,
dependency_type_threads,
};
enum dep_flags {
dep_flag_found = 1 << 0,
// partial dependencies
dep_flag_no_compile_args = 1 << 2,
dep_flag_no_includes = 1 << 3,
dep_flag_no_link_args = 1 << 4,
dep_flag_no_links = 1 << 5,
dep_flag_no_sources = 1 << 6,
dep_flag_parts = dep_flag_no_compile_args
| dep_flag_no_includes
| dep_flag_no_link_args
| dep_flag_no_links
| dep_flag_no_sources,
};
enum include_type {
include_type_preserve,
include_type_system,
include_type_non_system,
};
struct obj_dependency {
obj name; // obj_string
obj version; // obj_string
obj link_with; // obj_array
obj link_with_not_found; // obj_array
obj link_args; // obj_array
obj include_directories; // obj_array
obj variables; // obj_dict
obj sources; // obj_array
obj deps; // obj_array
obj compile_args; // obj_array
enum dep_flags flags;
enum dependency_type type;
enum include_type include_type;
};
struct obj_external_program {
bool found;
obj full_path;
obj ver;
};
struct obj_external_library {
obj full_path;
bool found;
};
enum run_result_flags {
run_result_flag_from_compile = 1 << 0,
run_result_flag_compile_ok = 1 << 1,
};
struct obj_run_result {
obj out;
obj err;
int32_t status;
enum run_result_flags flags;
};
struct obj_configuration_data {
obj dict; // obj_dict
};
enum test_category {
test_category_test,
test_category_benchmark,
};
struct obj_test {
obj name; // obj_string
obj exe; // obj_string
obj args; // obj_array
obj env; // obj_array
obj suites; // obj_array
obj workdir; // obj_string
obj depends; // obj_array of obj_string
bool should_fail, is_parallel;
enum test_category category;
};
struct obj_compiler {
obj name;
obj ver;
obj libdirs;
enum compiler_type type;
enum compiler_language lang;
};
struct obj_install_target {
obj src;
obj dest;
obj mode;
bool build_target;
};
struct obj_environment {
obj env; // dict
};
struct obj_include_directory {
obj path;
bool is_system;
};
enum build_option_type {
op_string,
op_boolean,
op_combo,
op_integer,
op_array,
op_feature,
build_option_type_count,
};
enum option_value_source {
option_value_source_unset,
option_value_source_default,
option_value_source_yield,
option_value_source_default_options,
option_value_source_subproject_default_options,
option_value_source_override_options,
option_value_source_deprecated_rename,
option_value_source_commandline,
};
struct obj_option {
obj name;
obj val;
obj choices;
obj max;
obj min;
obj deprecated;
obj description;
enum option_value_source source;
enum build_option_type type;
bool yield;
};
struct obj_generator {
obj output;
obj raw_command;
obj depfile;
obj depends;
bool capture;
bool feed;
};
struct obj_generated_list {
obj generator; // obj_generator
obj input; // obj_array of obj_file
obj extra_arguments; // obj_array of obj_string
obj preserve_path_from; // obj_string
};
void make_obj(struct workspace *wk, obj *id, enum obj_type type);
enum obj_type get_obj_type(struct workspace *wk, obj id);
uint32_t obj_type_to_tc_type(enum obj_type t);
bool get_obj_bool(struct workspace *wk, obj o);
void set_obj_bool(struct workspace *wk, obj o, bool v);
int64_t get_obj_number(struct workspace *wk, obj o);
void set_obj_number(struct workspace *wk, obj o, int64_t v);
obj *get_obj_file(struct workspace *wk, obj o);
const char *get_file_path(struct workspace *wk, obj o);
const struct str *get_str(struct workspace *wk, obj s);
enum feature_opt_state get_obj_feature_opt(struct workspace *wk, obj fo);
void set_obj_feature_opt(struct workspace *wk, obj fo, enum feature_opt_state state);
#define OBJ_GETTER(type) struct type *get_ ## type(struct workspace *wk, obj o)
OBJ_GETTER(obj_array);
OBJ_GETTER(obj_dict);
OBJ_GETTER(obj_compiler);
OBJ_GETTER(obj_build_target);
OBJ_GETTER(obj_custom_target);
OBJ_GETTER(obj_subproject);
OBJ_GETTER(obj_dependency);
OBJ_GETTER(obj_external_program);
OBJ_GETTER(obj_external_library);
OBJ_GETTER(obj_run_result);
OBJ_GETTER(obj_configuration_data);
OBJ_GETTER(obj_test);
OBJ_GETTER(obj_module);
OBJ_GETTER(obj_install_target);
OBJ_GETTER(obj_environment);
OBJ_GETTER(obj_include_directory);
OBJ_GETTER(obj_option);
OBJ_GETTER(obj_generator);
OBJ_GETTER(obj_generated_list);
OBJ_GETTER(obj_alias_target);
OBJ_GETTER(obj_both_libs);
OBJ_GETTER(obj_typeinfo);
#undef OBJ_GETTER
const char *obj_type_to_s(enum obj_type t);
void obj_to_s(struct workspace *wk, obj o, char *buf, uint32_t len);
bool obj_equal(struct workspace *wk, obj left, obj right);
bool obj_clone(struct workspace *wk_src, struct workspace *wk_dest, obj val, obj *ret);
bool obj_vsnprintf(struct workspace *wk, char *out_buf, uint32_t buflen, const char *fmt, va_list ap)
__attribute__ ((format(printf, 4, 0)));
bool obj_snprintf(struct workspace *wk, char *out_buf, uint32_t buflen, const char *fmt, ...)
__attribute__ ((format(printf, 4, 5)));
bool obj_vfprintf(struct workspace *wk, FILE *f, const char *fmt, va_list ap)
__attribute__ ((format(printf, 3, 0)));
bool obj_fprintf(struct workspace *wk, FILE *f, const char *fmt, ...)
__attribute__ ((format(printf, 3, 4)));
bool obj_printf(struct workspace *wk, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
typedef enum iteration_result (*obj_array_iterator)(struct workspace *wk, void *ctx, obj val);
void obj_array_push(struct workspace *wk, obj arr, obj child);
bool obj_array_foreach(struct workspace *wk, obj arr, void *ctx, obj_array_iterator cb);
bool obj_array_foreach_flat(struct workspace *wk, obj arr, void *usr_ctx, obj_array_iterator cb);
bool obj_array_in(struct workspace *wk, obj arr, obj val);
bool obj_array_index_of(struct workspace *wk, obj arr, obj val, uint32_t *idx);
void obj_array_index(struct workspace *wk, obj arr, int64_t i, obj *res);
void obj_array_extend(struct workspace *wk, obj arr, obj arr2);
void obj_array_extend_nodup(struct workspace *wk, obj arr, obj arr2);
void obj_array_dup(struct workspace *wk, obj arr, obj *res);
bool obj_array_join(struct workspace *wk, bool flat, obj arr, obj join, obj *res);
void obj_array_set(struct workspace *wk, obj arr, int64_t i, obj v);
void obj_array_dedup(struct workspace *wk, obj arr, obj *res);
void obj_array_flatten(struct workspace *wk, obj arr, obj *res);
bool obj_array_flatten_one(struct workspace *wk, obj val, obj *res);
typedef enum iteration_result (*obj_dict_iterator)(struct workspace *wk, void *ctx, obj key, obj val);
bool obj_dict_foreach(struct workspace *wk, obj dict, void *ctx, obj_dict_iterator cb);
bool obj_dict_in(struct workspace *wk, obj dict, obj key);
bool obj_dict_index(struct workspace *wk, obj dict, obj key, obj *res);
bool obj_dict_index_strn(struct workspace *wk, obj dict, const char *str, uint32_t len, obj *res);
void obj_dict_set(struct workspace *wk, obj dict, obj key, obj val);
void obj_dict_dup(struct workspace *wk, obj dict, obj *res);
void obj_dict_merge(struct workspace *wk, obj dict, obj dict2, obj *res);
void obj_dict_merge_nodup(struct workspace *wk, obj dict, obj dict2);
void obj_dict_index_values(struct workspace *wk, obj dict, uint32_t i, obj *res);
void obj_dict_seti(struct workspace *wk, obj dict, uint32_t key, obj val);
bool obj_dict_geti(struct workspace *wk, obj dict, uint32_t key, obj *val);
bool obj_iterable_foreach(struct workspace *wk, obj dict_or_array, void *ctx, obj_dict_iterator cb);
#endif