DEADSOFTWARE

Добавлены встроенные процедуры
[dsw-obn.git] / oberon.h
index 7fee329106ba6f15a64fa07afbeaf1deff994f35..09a24c98caeaa08f59b50e8b562035b261acd9d7 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;
+
+       int recursive;
+       int initialized;
+       gen_type_t * gen_type;
 };
 
-struct oberon_var_s
+/*
+ * Классы объектов.
+ *   VAR -- переменная.
+ *   TYPE -- тип данных.
+ *   PROC -- процедура.
+ *   PARAM -- параметр процедуры.
+ *   VAR_PARAM -- VAR-параметр процедуры.
+ */
+
+enum
 {
-        char * name;
-        oberon_type_t * type;
-        oberon_var_t * next;
+       OBERON_CLASS_VAR,
+       OBERON_CLASS_TYPE,
+       OBERON_CLASS_PROC,
+       OBERON_CLASS_PARAM,
+       OBERON_CLASS_VAR_PARAM,
+       OBERON_CLASS_CONST,
+       OBERON_CLASS_FIELD
 };
 
+enum
+{
+       OBERON_SYSPROC_ABS
+};
+
+/*
+ * Структура 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;
+       int class;
+
+       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;
+
+       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;
+
+       oberon_scope_t * decl;
+
+       void (* begin)();
 };
 
+/*
+ * Структура oberon_context_s (oberon_context_t) учитывает текущее состояние интерпретатора.
+ * Один экземпляр не может использоваться в нескольких потоках одновременно.
+ * Поля:
+ *   code    -- входной буффер для сканера.
+ *   code_index -- Текущая позия в буффере.
+ *   с       -- последний прочитанный символ.
+ *   token   -- последний прочитанный токен.
+ *   string  -- буфер с прочитанной строкой / идентификатором.
+ *              всегда имеет уникальный адрес и может изменяться.
+ *   integer -- прочитанное целое число.
+ *   decl    -- текущая область видимости.
+ *   mod     -- текущий модуль.
+ *   int_type, bool_type, void_type -- стандартные типы.
+ *   world_scope -- область видимости "мир" - выше модуля.
+ */
+
 struct oberon_context_s
 {
        const char * code;
@@ -42,13 +226,100 @@ struct oberon_context_s
        char * string;
        int integer;
 
+       oberon_scope_t * decl;
        oberon_module_t * mod;
 
-       oberon_type_t * types;
+       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;
+
+       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 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 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;
+       };
+
+       oberon_item_t item;
+       oberon_oper_t oper;
 };
 
 oberon_context_t * oberon_create_context();
+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