diff --git a/asm/assembler/assembler.c b/asm/assembler/assembler.c new file mode 100644 index 0000000..f0ed9ad --- /dev/null +++ b/asm/assembler/assembler.c @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#include + +#include "assembler.h" + +extern struct assembler_scope_type class_scope_type; +extern struct assembler_scope_type lambda_scope_type; +extern struct assembler_scope_type msgh_scope_type; +extern struct assembler_scope_type constpool_scope_type; + +static const struct assembler_scope_type *scope_types[] = { + [IVY_ASM_SCOPE_CLASS] = &class_scope_type, + [IVY_ASM_SCOPE_LAMBDA] = &lambda_scope_type, + [IVY_ASM_SCOPE_MSGH] = &msgh_scope_type, + [IVY_ASM_SCOPE_CONSTPOOL] = &constpool_scope_type, +}; +static const size_t nr_scope_types = sizeof scope_types / sizeof scope_types[0]; + +struct ivy_assembler { + FILE *as_fp; + struct assembler_scope *as_scope; +}; + +enum ivy_static ivy_assembler_create(FILE *fp, struct ivy_assembler **as) +{ + struct ivy_assembler *out = malloc(sizeof *out); + + if (!out) { + return IVY_ERR_NO_MEMORY; + } + + memset(out, 0x0, sizeof *out); + + out->as_fp = fp; + + *as = out; + return IVY_OK; +} + +void ivy_assembler_destroy(struct ivy_assembler *as) +{ + free(as); +} + +enum ivy_status ivy_assembler_begin_scope( + struct ivy_assembler *as, enum ivy_assembler_scope_type type) +{ + if (type < 0 || type >= nr_scope_types) { + return IVY_ERR_NOT_SUPPORTED; + } + + const struct assembler_scope_type *type_info = scope_types[type]; + if (!type_info) { + return IVY_ERR_NOT_SUPPORTED; + } + + if (as->as_scope) { + return IVY_ERR_NOT_SUPPORTED; + } + + struct assembler_scope *scope = malloc(type_info->s_scope_size); + if (!scope) { + return IVY_ERR_NO_MEMORY; + } + + scope->s_type = type; + as->as_scope = scope; + + if (type_info->s_init_scope) { + type_info->s_init_scope(as, scope); + } + + return IVY_OK; +} + +enum ivy_status ivy_assembler_end_scope(struct ivy_assembler *as) +{ + if (!as->as_scope) { + return IVY_ERR_NOT_SUPPORTED; + } + + const struct assembler_scope_type *type_info = as->as_scope->s_ops; + if (!type_info) { + return IVY_ERR_NOT_SUPPORTED; + } + + if (type_info->s_finish_scope) { + type_info->s_finish_scope(as, as->as_scope); + } + + free(as->as_scope); + as->as_scope = NULL; + + return IVY_OK; +} + +enum ivy_status ivy_assembler_put_string( + struct ivy_assembler *as, int index, const char *s) +{ + struct assembler_scope *scope = as->as_scope; + + if (!scope) { + return IVY_ERR_NOT_SUPPORTED; + } + + const struct assembler_scope_type *type_info = scope->s_ops; + if (!type_info || !type_info->s_put_string) { + return IVY_ERR_NOT_SUPPORTED; + } + + return type_info->s_put_string(as, scope, index, s); +} + +enum ivy_status ivy_assembler_put_ident( + struct ivy_assembler *as, int index, const char *s) +{ + struct assembler_scope *scope = as->as_scope; + + if (!scope) { + return IVY_ERR_NOT_SUPPORTED; + } + + const struct assembler_scope_type *type_info = scope->s_ops; + if (!type_info || !type_info->s_put_string) { + return IVY_ERR_NOT_SUPPORTED; + } + + return type_info->s_put_string(as, scope, index, s); +} + +enum ivy_status ivy_assembler_put_atom( + struct ivy_assembler *as, int index, const char *s) +{ + struct assembler_scope *scope = as->as_scope; + + if (!scope) { + return IVY_ERR_NOT_SUPPORTED; + } + + const struct assembler_scope_type *type_info = scope->s_ops; + if (!type_info || !type_info->s_put_atom) { + return IVY_ERR_NOT_SUPPORTED; + } + + return type_info->s_put_atom(as, scope, index, s); +} + +enum ivy_status ivy_assembler_put_selector( + struct ivy_assembler *as, int index, struct ivy_selector *sel) +{ + struct assembler_scope *scope = as->as_scope; + + if (!scope) { + return IVY_ERR_NOT_SUPPORTED; + } + + const struct assembler_scope_type *type_info = scope->s_ops; + if (!type_info || !type_info->s_put_selector) { + return IVY_ERR_NOT_SUPPORTED; + } + + return type_info->s_put_selector(as, scope, index, sel); +} + +enum ivy_status ivy_assembler_put_mvar( + struct ivy_assembler *as, int index, const char *name) +{ + struct assembler_scope *scope = as->as_scope; + + if (!scope) { + return IVY_ERR_NOT_SUPPORTED; + } + + const struct assembler_scope_type *type_info = scope->s_ops; + if (!type_info || !type_info->s_put_mvar) { + return IVY_ERR_NOT_SUPPORTED; + } + + return type_info->s_put_mvar(as, scope, index, name); +} + +enum ivy_status ivy_assembler_put_instr( + struct ivy_assembler *as, const struct ivy_instr *i) +{ + struct assembler_scope *scope = as->as_scope; + + if (!scope) { + return IVY_ERR_NOT_SUPPORTED; + } + + const struct assembler_scope_type *type_info = scope->s_ops; + if (!type_info || !type_info->s_put_instr) { + return IVY_ERR_NOT_SUPPORTED; + } + + return type_info->s_put_instr(as, scope, i); +} \ No newline at end of file diff --git a/asm/assembler/assembler.h b/asm/assembler/assembler.h new file mode 100644 index 0000000..f110e53 --- /dev/null +++ b/asm/assembler/assembler.h @@ -0,0 +1,28 @@ +#ifndef _ASSEMBLER_ASSEMBLER_H_ +#define _ASSEMBLER_ASSEMBLER_H_ + +#include +#include + +struct assembler_scope_type; + +struct assembler_scope { + enum ivy_assembler_scope_type s_type; + struct assembler_scope_type *s_ops; +}; + +struct assembler_scope_type { + size_t s_scope_size; + + enum ivy_status(*s_init_scope)(struct ivy_assembler *, struct assembler_scope *); + enum ivy_status(*s_finish_scope)(struct ivy_assembler *, struct assembler_scope *); + + enum ivy_status(*s_put_string)(struct ivy_assembler *, struct assembler_scope *, long, const char *); + enum ivy_status(*s_put_ident)(struct ivy_assembler *, struct assembler_scope *, long, const char *); + enum ivy_status(*s_put_atom)(struct ivy_assembler *, struct assembler_scope *, long, const char *); + enum ivy_status(*s_put_selector)(struct ivy_assembler *, struct assembler_scope *, long, const struct ivy_selector *); + enum ivy_status(*s_put_mvar)(struct ivy_assembler *, struct assembler_scope *, long, const char *); + enum ivy_status(*s_put_instr)(struct ivy_assembler *, struct assembler_scope *, const struct ivy_instr *); +}; + +#endif \ No newline at end of file diff --git a/asm/assembler/class.c b/asm/assembler/class.c new file mode 100644 index 0000000..d22f0fe --- /dev/null +++ b/asm/assembler/class.c @@ -0,0 +1,9 @@ +#include "assembler.h" + +struct class_scope { + +}; + +const struct assembler_scope_type class_scope_type = { + .s_scope_size = sizeof(struct class_scope), +}; \ No newline at end of file diff --git a/asm/assembler.c b/asm/assembler/constpool.c similarity index 100% rename from asm/assembler.c rename to asm/assembler/constpool.c diff --git a/asm/assembler/lambda.c b/asm/assembler/lambda.c new file mode 100644 index 0000000..e69de29 diff --git a/asm/assembler/msgh.c b/asm/assembler/msgh.c new file mode 100644 index 0000000..e69de29 diff --git a/asm/include/ivy/asm/assembler.h b/asm/include/ivy/asm/assembler.h index 1954399..c2c086d 100644 --- a/asm/include/ivy/asm/assembler.h +++ b/asm/include/ivy/asm/assembler.h @@ -3,6 +3,7 @@ #include #include +#include #define IVY_ASM_INDEX_AUTO (-1) @@ -13,14 +14,13 @@ struct ivy_assembler; enum ivy_assembler_scope_type { IVY_ASM_SCOPE_NONE = 0, - IVY_ASM_SCOPE_UNIT, IVY_ASM_SCOPE_CLASS, IVY_ASM_SCOPE_LAMBDA, IVY_ASM_SCOPE_MSGH, IVY_ASM_SCOPE_CONSTPOOL, }; -IVY_API enum ivy_static ivy_assembler_create(struct ivy_assembler **as); +IVY_API enum ivy_static ivy_assembler_create(FILE *out, struct ivy_assembler **as); IVY_API void ivy_assembler_destroy(struct ivy_assembler *as); IVY_API enum ivy_status ivy_assembler_begin_scope(