diff --git a/oberon.h b/oberon.h
index 7fee329106ba6f15a64fa07afbeaf1deff994f35..ef9ad7f1c891223eb2241ef8d4020e3855a50645 100644 (file)
--- a/oberon.h
+++ b/oberon.h
#ifndef EMBEDED_OBERON_SCRIPT_H
#define EMBEDED_OBERON_SCRIPT_H
-enum {
- OBERON_TYPE_INTEGER,
- OBERON_TYPE_BOOLEAN,
+#include <libgccjit.h>
+
+typedef struct gen_proc_s gen_proc_t;
+typedef struct gen_type_s gen_type_t;
+typedef struct gen_var_s gen_var_t;
+typedef struct gen_block_s gen_block_t;
+typedef struct gen_context_s gen_context_t;
+
+struct gen_proc_s
+{
+ gcc_jit_function * gcc_func;
+};
+
+struct gen_type_s
+{
+ gcc_jit_type * gcc_type;
+ gcc_jit_struct * gcc_struct;
+};
+
+struct gen_var_s
+{
+ gcc_jit_lvalue * gcc_lvalue;
+ gcc_jit_param * gcc_param;
+ gcc_jit_field * gcc_field;
+};
+
+struct gen_block_s
+{
+ gcc_jit_block * gcc_block;
+ gen_block_t * up;
+};
+
+struct gen_context_s
+{
+ gcc_jit_context * gcc_context;
+ gcc_jit_result * gcc_result;
+ gen_block_t * block;
+ unsigned record_count;
};
-typedef struct oberon_var_s oberon_var_t;
typedef struct oberon_type_s oberon_type_t;
+typedef struct oberon_object_s oberon_object_t;
typedef struct oberon_module_s oberon_module_t;
typedef struct oberon_context_s oberon_context_t;
+typedef struct oberon_scope_s oberon_scope_t;
+
+typedef struct oberon_item_s oberon_item_t;
+typedef struct oberon_oper_s oberon_oper_t;
+typedef union oberon_expr_u oberon_expr_t;
+
+/*
+ * Структура oberon_scope_s (oberon_type_t) реализует стекообразную
+ * область видимости объектов.
+ * Поля:
+ * ctx -- контекст в котором область видимости была создана;
+ * list -- список объявлений. Первый элемент всегда существует,
+ * но не используется и должен быть пропущен.
+ * up -- ссылка на облась видимости уровнем выше.
+ */
+
+struct oberon_scope_s
+{
+ oberon_context_t * ctx;
+ oberon_object_t * list;
+ oberon_scope_t * up;
+
+ oberon_object_t * parent;
+ int local;
+};
+
+/*
+ * Формы типов данных.
+ * Тип VOID используется как заглушка возврата типа в обычных процедурах
+ */
+
+enum
+{
+ OBERON_TYPE_VOID,
+ OBERON_TYPE_INTEGER,
+ OBERON_TYPE_BOOLEAN,
+ OBERON_TYPE_PROCEDURE,
+ OBERON_TYPE_ARRAY,
+ OBERON_TYPE_RECORD,
+ OBERON_TYPE_POINTER
+};
+
+/*
+ * Структура oberon_type_s (oberon_type_t) описывает типы данных.
+ * Поля:
+ * class -- Форма типа данных (OBERON_TYPE_*).
+ * size -- Размер примитива в байтах или количество ячеек массива.
+ * Ноль для открытых массивов.
+ * num_decl -- Количество объявленых полей в структуре или сигнатуре процедуры.
+ * base -- Базовый тип структуры или тип возврата процедуры.
+ * decl -- Список объявлений. Перебор начинается с первого элемента.
+ *
+ * Таблица использования полей:
+ * class size num_decl base decl
+ * VOID - - - -
+ * INT + - - -
+ * BOOL + - - -
+ * PROC - + + +
+ */
struct oberon_type_s
{
- char * name;
int class;
int size;
- oberon_type_t * next;
+
+ int num_decl;
+ oberon_type_t * base;
+ oberon_object_t * decl;
+
+ oberon_module_t * module;
+
+ int recursive;
+ int initialized;
+ gen_type_t * gen_type;
+};
+
+/*
+ * Классы объектов.
+ * VAR -- переменная.
+ * TYPE -- тип данных.
+ * PROC -- процедура.
+ * PARAM -- параметр процедуры.
+ * VAR_PARAM -- VAR-параметр процедуры.
+ */
+
+enum
+{
+ OBERON_CLASS_VAR,
+ OBERON_CLASS_TYPE,
+ OBERON_CLASS_PROC,
+ OBERON_CLASS_PARAM,
+ OBERON_CLASS_VAR_PARAM,
+ OBERON_CLASS_CONST,
+ OBERON_CLASS_FIELD,
+ OBERON_CLASS_MODULE
};
-struct oberon_var_s
+/*
+ * Структура oberon_object_s (oberon_object_t) описывает все
+ * объявления которые могут иметь имя. От констант, до процедур.
+ * Поля:
+ * name -- имя объекта.
+ * class -- класс объекта (OBERON_CLASS_*).
+ * type -- ссылка на тип переменной, дескриптор типа или сигнатуру процедуры.
+ * next -- ссылка на следующий объект в списке.
+ */
+
+typedef oberon_expr_t * (*GenerateFuncCallback)(oberon_context_t *, int, oberon_expr_t *);
+typedef void (*GenerateProcCallback)(oberon_context_t *, int, oberon_expr_t *);
+
+struct oberon_object_s
{
- char * name;
- oberon_type_t * type;
- oberon_var_t * next;
+ char * name;
+ int class;
+ int export;
+ int read_only;
+
+ int local;
+ int linked;
+ int initialized;
+
+ oberon_object_t * parent;
+
+ oberon_scope_t * scope; // for proc
+ int has_return; // for proc
+ int sysproc;
+ GenerateFuncCallback genfunc;
+ GenerateProcCallback genproc;
+
+ oberon_type_t * type;
+ oberon_item_t * value;
+ oberon_object_t * next;
+
+ oberon_module_t * module;
+
+ gen_var_t * gen_var;
+ gen_proc_t * gen_proc;
};
+/*
+ * Структура oberon_module_s (oberon_module_t) описывает объявление модуля.
+ * Поля:
+ * name -- настоящее имя модуля.
+ * decl -- все глобальные объявления в модуле.
+ * begin -- Указатель на сгенерированный код тела модуля (секция BEGIN).
+ */
+
struct oberon_module_s
{
char * name;
- oberon_var_t * vars;
+ int ready;
+
+ oberon_scope_t * decl;
+
+ oberon_module_t * next;
};
+/*
+ * Структура oberon_context_s (oberon_context_t) учитывает текущее состояние интерпретатора.
+ * Один экземпляр не может использоваться в нескольких потоках одновременно.
+ * Поля:
+ * code -- входной буффер для сканера.
+ * code_index -- Текущая позия в буффере.
+ * с -- последний прочитанный символ.
+ * token -- последний прочитанный токен.
+ * string -- буфер с прочитанной строкой / идентификатором.
+ * всегда имеет уникальный адрес и может изменяться.
+ * integer -- прочитанное целое число.
+ * decl -- текущая область видимости.
+ * mod -- текущий модуль.
+ * int_type, bool_type, void_type -- стандартные типы.
+ * world_scope -- область видимости "мир" - выше модуля.
+ */
+
+typedef const char * (*ModuleImportCallback)(const char * name);
+
struct oberon_context_s
{
+ /*** SCANER DATA ***/
const char * code;
int code_index;
int token;
char * string;
int integer;
+ /*** END SCANER DATA ***/
+ /*** PARSER DATA ***/
+ oberon_scope_t * decl;
oberon_module_t * mod;
+ /*** END PARSER DATA ***/
+
+ oberon_type_t * int_type;
+ oberon_type_t * bool_type;
+ oberon_type_t * void_type;
+ oberon_type_t * void_ptr_type;
+ oberon_scope_t * world_scope;
+ oberon_module_t * module_list;
+ ModuleImportCallback import_module;
+ gen_context_t * gen_context;
+};
+
+enum
+{
+ MODE_VAR,
+ MODE_INTEGER,
+ MODE_BOOLEAN,
+ MODE_CALL,
+ MODE_INDEX,
+ MODE_FIELD,
+ MODE_DEREF,
+ MODE_NIL
+};
+
+enum
+{
+ OP_UNARY_MINUS,
+ OP_BITWISE_NOT,
+ OP_LOGIC_NOT,
+ OP_ABS,
+
+ OP_ADD,
+ OP_SUB,
+ OP_MUL,
+ OP_DIV,
+ OP_MOD,
+ OP_BITWISE_AND,
+ OP_BITWISE_XOR,
+ OP_BITWISE_OP,
+ OP_LOGIC_AND,
+ OP_LOGIC_OR,
+
+ OP_EQ,
+ OP_NEQ,
+ OP_LSS,
+ OP_LEQ,
+ OP_GRT,
+ OP_GEQ
+};
+
+struct oberon_item_s
+{
+ int is_item; // == 1
+ oberon_type_t * result;
+ oberon_expr_t * next;
+ int read_only;
+
+ int mode;
+ int integer;
+ int boolean;
+ oberon_object_t * var;
+
+ oberon_item_t * parent;
+
+ int num_args;
+ oberon_expr_t * args;
+};
+
+struct oberon_oper_s
+{
+ int is_item; // == 0
+ oberon_type_t * result;
+ oberon_expr_t * next;
+ int read_only;
+
+ int op;
+ oberon_expr_t * left;
+ oberon_expr_t * right;
+};
+
+union oberon_expr_u
+{
+ struct {
+ int is_item;
+ oberon_type_t * result;
+ oberon_expr_t * next;
+ int read_only;
+ };
- oberon_type_t * types;
+ oberon_item_t item;
+ oberon_oper_t oper;
};
-oberon_context_t * oberon_create_context();
+oberon_context_t * oberon_create_context(ModuleImportCallback import_module);
+void oberon_destroy_context(oberon_context_t * ctx);
void oberon_register_global_type(oberon_context_t * ctx, oberon_type_t * type);
oberon_module_t * oberon_compile_module(oberon_context_t * ctx, const char * code);
+void oberon_error(oberon_context_t * ctx, const char * fmt, ...);
#endif // EMBEDED_OBERON_SCRIPT_H