DEADSOFTWARE

Изменение структуры проекта
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 24 Jul 2017 20:08:12 +0000 (23:08 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 24 Jul 2017 20:08:12 +0000 (23:08 +0300)
19 files changed:
count.sh [new file with mode: 0755]
include/oberon.h [new file with mode: 0644]
make.sh
notes
oberon.h [deleted file]
src/backends/dummy/generator-libgccjit.c [new file with mode: 0644]
src/backends/dummy/generator-libgccjit.h [new file with mode: 0644]
src/backends/libgccjit/generator-libgccjit.c [moved from generator.c with 99% similarity]
src/backends/libgccjit/generator-libgccjit.h [new file with mode: 0644]
src/backends/libgccjit/notes [new file with mode: 0644]
src/generator.h [moved from generator.h with 100% similarity]
src/oberon-internals.h [new file with mode: 0644]
src/oberon.c [moved from oberon.c with 99% similarity]
src/test.c [moved from test.c with 98% similarity]
test/.gitignore [deleted file]
test/Test [deleted file]
test/Test.Mod [deleted file]
test/Test.c [deleted file]
test/make.sh [deleted file]

diff --git a/count.sh b/count.sh
new file mode 100755 (executable)
index 0000000..a07d822
--- /dev/null
+++ b/count.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+wc -l $(find . -name '*.c' -or -name '*.h')
diff --git a/include/oberon.h b/include/oberon.h
new file mode 100644 (file)
index 0000000..b2f24b4
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef OBERON_H
+#define OBERON_H
+
+typedef struct oberon_type_t oberon_type_t;
+
+typedef struct oberon_module_t oberon_module_t;
+
+typedef struct oberon_context_t oberon_context_t;
+
+typedef const char * (*ModuleImportCallback)(const char * name);
+
+extern oberon_context_t *
+oberon_create_context(ModuleImportCallback import_module);
+
+extern void
+oberon_destroy_context(oberon_context_t * ctx);
+
+extern oberon_module_t *
+oberon_compile_module(oberon_context_t * ctx, const char * code);
+
+extern void
+oberon_generate_code(oberon_context_t * ctx);
+
+extern void
+oberon_generator_dump(oberon_context_t * ctx, char * path);
+
+extern void *
+oberon_generator_get_procedure(oberon_context_t * ctx, const char * name);
+
+extern void *
+oberon_generator_get_var(oberon_context_t * ctx, const char * name);
+
+#endif // OBERON_H
diff --git a/make.sh b/make.sh
index 1f95bcf593d5824856bf83e51bd355a2315c2a85..9e4b2551b852601b51ca3a7840b8c90d7d226739 100755 (executable)
--- a/make.sh
+++ b/make.sh
@@ -2,4 +2,18 @@
 
 set -e
 
-cc -g -Wall -Werror -std=c11 -lgccjit -lgc *.c
+CC="gcc"
+CFLAGS="-g -Wall -Werror -std=c11 -lgc"
+
+case "$1" in
+  dummy)
+    $CC $CFLAGS src/*.c src/backends/dummy/*.c
+  ;;
+  libgccjit)
+    CFLAGS="-lgccjit $CFLAGS"
+    $CC $CFLAGS src/*.c src/backends/libgccjit/*.c
+  ;;
+  ***)
+    echo "use: make.sh <backend>"
+    echo "list of backends: dummy libgccjit"
+esac
diff --git a/notes b/notes
index 0576334c3d003d72efdf80e9946f50d4f68ef97d..60b17bda4932bb27322d9bae00b186974f032d5f 100644 (file)
--- a/notes
+++ b/notes
@@ -1,67 +1,15 @@
-- открытые массивы работкают криво как статические аргументы процедур
-    Случай 1: не проходит проверки libgccjit
-    (*
-     TYPE Ar = ARRAY OF INTEGER;
-     VAR a : POINTER TO Ar;
-
-     (* так же и с VAR-параметром *)
-     PROCEDURE Ax(x : Ar);
-     END Ax;
-
-     Ax(a);
-     *)
-    Случай 2: массив должен быть указателем, да и ещё копироваться
-    (*
-     TYPE Ar = ARRAY OF INTEGER;
-     VAR a : POINTER TO Ar;
-
-     (* при использовании VAR-параметра работает *)
-     PROCEDURE Ax(x : Ar);
-     END Ax;
-
-     Ax(a^);
-     *)
-
 - нет символов и строк
 - нужен автокаст int -> real для DIV. Да и вообще каст типов.
 
 - нету операторов if, while и т.д.
 
-- импортируемые модули не инициализируются (секция begin)
 - нету типа set
 - не реализована свёртка констант
 - не протестированы типы разнных размеров
 
-- не реализовано расширение типа record:
-    libgccjit не умеет в классы. Проверки в рантайме надо делать вручную.
-- нет проверок границ массивов в рантайме:
-    Потому что как минимум нет дескрипторов типа.
-    Возможно можно заюзать это:
-      https://gcc.gnu.org/onlinedocs/gcc/Pointer-Bounds-Checker-builtins.html
-- При вычислении размера структур не учитывается вравнивание.
-    в libgccjit нет средств получения размера типов, в т.ч. структур
-    Как происходит выравнивание и есть ли оно вообще по дефолту - не понятно:
-      Нужно ли для получения выровненных структур использовать gcc_jit_type_get_aligned?
-        Пересекается с этим:
-          https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html
-    Требуемые выравнивания для типов можно получить через встроинную функцию __alignof__(T)
-      https://gcc.gnu.org/onlinedocs/gcc/Alignment.html
-    Возможный алгоритм выравнивания:
-      https://stackoverflow.com/questions/6963998/how-does-gcc-calculate-the-required-space-for-a-structure
-      http://www.rendoc.tech/questions/834444/how-does-gcc-calculate-the-required-space-for-a-structure
-    Есть ещё что-то для проверки границ объектов:
-      https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
-- не понятен результат присваивания статических/разыменованных структур и массивов
-    (* reca := recb; *) - побайтовое копирование?
-- не реализовано присваивание процедур к переменным-процедурам:
-    в libgccjit нет средств получения указателя на функцию.
-    Как решение-костыль - получение указателя в основной программе и сохранение в переменной.
-- не реализован автокаст:
-    Не критично: libgccjit сам разруливает типы разных размеров.
-- не реализованы локальные процедуры:
-    libgccjit не умеет в локальные функции.
-    Обойти можно костылём как в jvm.
-- нет проверок переполнения как в рантайме, так и в компилтайме.
+- не реализовано расширение типа record
+- не реализован автокаст
+- нет проверок переполнения в компилтайме.
     Возможно можно заюзать это:
       https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
 
diff --git a/oberon.h b/oberon.h
deleted file mode 100644 (file)
index 189369b..0000000
--- a/oberon.h
+++ /dev/null
@@ -1,345 +0,0 @@
-#ifndef EMBEDED_OBERON_SCRIPT_H
-#define EMBEDED_OBERON_SCRIPT_H
-
-#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;
-       gcc_jit_lvalue * gcc_alloc;
-};
-
-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_REAL
-};
-
-/*
- * Структура 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
-{
-       int class;
-       int size;
-
-       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
-};
-
-/*
- * Структура 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 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;
-       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;
-
-       char c;
-       int token;
-       char * string;
-       long integer;
-       double real;
-       /*** 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 * real_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,
-       MODE_NEW,
-       MODE_REAL
-};
-
-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;
-       long integer;
-       double real;
-       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_item_t item;
-       oberon_oper_t oper;
-};
-
-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
diff --git a/src/backends/dummy/generator-libgccjit.c b/src/backends/dummy/generator-libgccjit.c
new file mode 100644 (file)
index 0000000..e9b26b5
--- /dev/null
@@ -0,0 +1,118 @@
+#include <string.h>
+#include <assert.h>
+
+#include <gc.h>
+
+#include "../../../include/oberon.h"
+#include "../../oberon-internals.h"
+#include "generator-libgccjit.h"
+
+void
+oberon_generator_init_context(oberon_context_t * ctx)
+{
+       gen_context_t * gen_context = GC_MALLOC(sizeof *gen_context);
+       memset(gen_context, 0, sizeof *gen_context);
+
+       ctx -> gen_context = gen_context;
+}
+
+void
+oberon_generator_destroy_context(oberon_context_t * ctx)
+{
+       ctx -> gen_context = NULL;
+}
+
+void
+oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type)
+{
+       type -> gen_type = NULL;
+}
+
+void
+oberon_generator_init_record(oberon_context_t * ctx, oberon_type_t * type)
+{
+       assert(type -> class == OBERON_TYPE_RECORD);
+       // init record fields
+}
+
+void
+oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var)
+{
+       var -> gen_var = NULL;
+}
+
+void
+oberon_generator_init_proc(oberon_context_t * ctx, oberon_object_t * proc)
+{
+       proc -> gen_proc = NULL;
+}
+
+// =======================================================================
+//   GENERATOR
+// ======================================================================= 
+
+void
+oberon_generate_begin_module(oberon_context_t * ctx)
+{
+
+}
+
+void
+oberon_generate_end_module(oberon_context_t * ctx)
+{
+
+}
+
+void
+oberon_generate_begin_proc(oberon_context_t * ctx, oberon_object_t * proc)
+{
+
+}
+
+void
+oberon_generate_call_proc(oberon_context_t * ctx, oberon_expr_t * desig)
+{
+
+}
+
+void
+oberon_generate_end_proc(oberon_context_t * ctx)
+{
+
+}
+
+void
+oberon_generate_return(oberon_context_t * ctx, oberon_expr_t * expr)
+{
+
+}
+
+void
+oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)
+{
+
+}
+
+void
+oberon_generate_code(oberon_context_t * ctx)
+{
+
+}
+
+void
+oberon_generator_dump(oberon_context_t * ctx, char * path)
+{
+
+}
+
+void *
+oberon_generator_get_procedure(oberon_context_t * ctx, const char * name)
+{
+       return NULL;
+}
+
+void *
+oberon_generator_get_var(oberon_context_t * ctx, const char * name)
+{
+       return NULL;
+}
diff --git a/src/backends/dummy/generator-libgccjit.h b/src/backends/dummy/generator-libgccjit.h
new file mode 100644 (file)
index 0000000..499b90b
--- /dev/null
@@ -0,0 +1,24 @@
+struct gen_proc_t
+{
+
+};
+
+struct gen_type_t
+{
+
+};
+
+struct gen_var_t
+{
+
+};
+
+struct gen_block_t
+{
+
+};
+
+struct gen_context_t
+{
+
+};
similarity index 99%
rename from generator.c
rename to src/backends/libgccjit/generator-libgccjit.c
index b0887aee7c82587beed212c50e56cac179a32b72..a3bd2772c90fc1d50c7d9c3fd040051b60c6f7d4 100644 (file)
@@ -8,8 +8,9 @@
 
 #include <gc.h>
 
-#include "oberon.h"
-#include "generator.h"
+#include "../../../include/oberon.h"
+#include "../../oberon-internals.h"
+#include "generator-libgccjit.h"
 
 // =======================================================================
 //   INTERNAL FUNCTIONS
diff --git a/src/backends/libgccjit/generator-libgccjit.h b/src/backends/libgccjit/generator-libgccjit.h
new file mode 100644 (file)
index 0000000..ba79933
--- /dev/null
@@ -0,0 +1,34 @@
+#include <libgccjit.h>
+
+struct gen_proc_t
+{
+        gcc_jit_function * gcc_func;
+};
+
+struct gen_type_t
+{
+        gcc_jit_type * gcc_type;
+        gcc_jit_struct * gcc_struct;
+};
+
+struct gen_var_t
+{
+        gcc_jit_lvalue * gcc_lvalue;
+        gcc_jit_param * gcc_param;
+        gcc_jit_field * gcc_field;
+};
+
+struct gen_block_t
+{
+        gcc_jit_block * gcc_block;
+        gen_block_t * up;
+};
+
+struct gen_context_t
+{
+        gcc_jit_context * gcc_context;
+        gcc_jit_result * gcc_result;
+        gen_block_t * block;
+        unsigned record_count;
+        gcc_jit_lvalue * gcc_alloc;
+};
diff --git a/src/backends/libgccjit/notes b/src/backends/libgccjit/notes
new file mode 100644 (file)
index 0000000..978f4f6
--- /dev/null
@@ -0,0 +1,63 @@
+# 24.07.2017
+
+- libgccjit годится разве что для хелловорлдов.
+    Переходим на jvm.
+
+- открытые массивы работкают криво как статические аргументы процедур
+    Случай 1: не проходит проверки libgccjit
+    (*
+     TYPE Ar = ARRAY OF INTEGER;
+     VAR a : POINTER TO Ar;
+
+     (* так же и с VAR-параметром *)
+     PROCEDURE Ax(x : Ar);
+     END Ax;
+
+     Ax(a);
+     *)
+    Случай 2: массив должен быть указателем, да и ещё копироваться
+    (*
+     TYPE Ar = ARRAY OF INTEGER;
+     VAR a : POINTER TO Ar;
+
+     (* при использовании VAR-параметра работает *)
+     PROCEDURE Ax(x : Ar);
+     END Ax;
+
+     Ax(a^);
+     *)
+
+- импортируемые модули не инициализируются (секция begin)
+
+- не реализовано расширение типа record:
+    libgccjit не умеет в классы. Проверки в рантайме надо делать вручную.
+- нет проверок границ массивов в рантайме:
+    Потому что как минимум нет дескрипторов типа.
+    Возможно можно заюзать это:
+      https://gcc.gnu.org/onlinedocs/gcc/Pointer-Bounds-Checker-builtins.html
+- При вычислении размера структур не учитывается вравнивание.
+    в libgccjit нет средств получения размера типов, в т.ч. структур
+    Как происходит выравнивание и есть ли оно вообще по дефолту - не понятно:
+      Нужно ли для получения выровненных структур использовать gcc_jit_type_get_aligned?
+        Пересекается с этим:
+          https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html
+    Требуемые выравнивания для типов можно получить через встроинную функцию __alignof__(T)
+      https://gcc.gnu.org/onlinedocs/gcc/Alignment.html
+    Возможный алгоритм выравнивания:
+      https://stackoverflow.com/questions/6963998/how-does-gcc-calculate-the-required-space-for-a-structure
+      http://www.rendoc.tech/questions/834444/how-does-gcc-calculate-the-required-space-for-a-structure
+    Есть ещё что-то для проверки границ объектов:
+      https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
+- не понятен результат присваивания статических/разыменованных структур и массивов
+    (* reca := recb; *) - побайтовое копирование?
+- не реализовано присваивание процедур к переменным-процедурам:
+    в libgccjit нет средств получения указателя на функцию.
+    Как решение-костыль - получение указателя в основной программе и сохранение в переменной.
+- не реализован автокаст:
+    Не критично: libgccjit сам разруливает типы разных размеров.
+- не реализованы локальные процедуры:
+    libgccjit не умеет в локальные функции.
+    Обойти можно костылём как в jvm.
+- нет проверок переполнения как в рантайме, так и в компилтайме.
+    Возможно можно заюзать это:
+      https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
similarity index 100%
rename from generator.h
rename to src/generator.h
diff --git a/src/oberon-internals.h b/src/oberon-internals.h
new file mode 100644 (file)
index 0000000..e265a79
--- /dev/null
@@ -0,0 +1,230 @@
+#ifndef OBERON_INTERNALS_H
+#define OBERON_INTERNALS_H
+
+typedef struct gen_proc_t gen_proc_t;
+typedef struct gen_type_t gen_type_t;
+typedef struct gen_var_t gen_var_t;
+typedef struct gen_block_t gen_block_t;
+typedef struct gen_context_t gen_context_t;
+
+typedef struct oberon_type_t oberon_type_t;
+typedef struct oberon_object_t oberon_object_t;
+typedef struct oberon_module_t oberon_module_t;
+typedef struct oberon_context_t oberon_context_t;
+typedef struct oberon_scope_t oberon_scope_t;
+
+typedef struct oberon_item_t oberon_item_t;
+typedef struct oberon_oper_t oberon_oper_t;
+typedef union oberon_expr_t oberon_expr_t;
+
+struct oberon_scope_t
+{
+       oberon_context_t * ctx;
+       oberon_object_t * list;
+       oberon_scope_t * up;
+
+       oberon_object_t * parent;
+       int local;
+};
+
+enum
+{
+       OBERON_TYPE_VOID,
+       OBERON_TYPE_INTEGER,
+       OBERON_TYPE_BOOLEAN,
+       OBERON_TYPE_PROCEDURE,
+       OBERON_TYPE_ARRAY,
+       OBERON_TYPE_RECORD,
+       OBERON_TYPE_POINTER,
+       OBERON_TYPE_REAL
+};
+
+struct oberon_type_t
+{
+       int class;
+       int size;
+
+       int num_decl;
+       oberon_type_t * base;
+       oberon_object_t * decl;
+
+       oberon_module_t * module;
+
+       int recursive;
+       int initialized;
+       gen_type_t * gen_type;
+};
+
+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
+};
+
+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_t
+{
+       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;
+};
+
+struct oberon_module_t
+{
+       char * name;
+       int ready;
+
+       oberon_scope_t * decl;
+
+       oberon_module_t * next;
+};
+
+typedef const char * (*ModuleImportCallback)(const char * name);
+
+struct oberon_context_t
+{
+       /*** SCANER DATA ***/
+       const char * code;
+       int code_index;
+
+       char c;
+       int token;
+       char * string;
+       long integer;
+       double real;
+       /*** 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 * real_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,
+       MODE_NEW,
+       MODE_REAL
+};
+
+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_t
+{
+       int is_item; // == 1
+       oberon_type_t * result;
+       oberon_expr_t * next;
+       int read_only;
+
+       int mode;
+       long integer;
+       double real;
+       int boolean;
+       oberon_object_t * var;
+
+       oberon_item_t * parent;
+
+       int num_args;
+       oberon_expr_t * args;
+};
+
+struct oberon_oper_t
+{
+       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_t
+{
+       struct {
+               int is_item;
+               oberon_type_t * result;
+               oberon_expr_t * next;
+               int read_only;
+       };
+
+       oberon_item_t item;
+       oberon_oper_t oper;
+};
+
+extern void
+oberon_error(oberon_context_t * ctx, const char * fmt, ...);
+
+#endif // OBERON_INTERNALS_H
similarity index 99%
rename from oberon.c
rename to src/oberon.c
index 16043c2f7aa0e4bdcd658130a5765b126b385b11..d636fba6b19d253c65a167420a25f21547bef892 100644 (file)
--- a/oberon.c
@@ -6,7 +6,9 @@
 #include <assert.h>
 #include <stdbool.h>
 
-#include "oberon.h"
+#include "../include/oberon.h"
+
+#include "oberon-internals.h"
 #include "generator.h"
 
 enum {
similarity index 98%
rename from test.c
rename to src/test.c
index 6175148f461c4c0db1ff690997928e56f560544f..1c3c8e39347533eb9db1d0b2e289f0348f77b693 100644 (file)
--- a/test.c
@@ -1,9 +1,9 @@
-#include "oberon.h"
-#include "generator.h"
-
+#include <stdio.h>
 #include <string.h>
 #include <assert.h>
 
+#include "../include/oberon.h"
+
 static char source_test[] =
        "(* Main module *)"
        "MODULE Test;"
diff --git a/test/.gitignore b/test/.gitignore
deleted file mode 100644 (file)
index 345e6ae..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Test
diff --git a/test/Test b/test/Test
deleted file mode 100755 (executable)
index 1bf0d5a..0000000
Binary files a/test/Test and /dev/null differ
diff --git a/test/Test.Mod b/test/Test.Mod
deleted file mode 100644 (file)
index 22bad20..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-MODULE Test;
-
-IMPORT Out;
-
-VAR
-  a : ARRAY 3 OF INTEGER;
-
-PROCEDURE Ax(VAR x : ARRAY OF INTEGER);
-BEGIN
-END Ax;
-
-BEGIN
-  Out.Open;
-  Ax(a);
-  Out.Flush;
-END Test.
diff --git a/test/Test.c b/test/Test.c
deleted file mode 100644 (file)
index f40f138..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* voc 2.1.0 [2017/07/17] for gcc LP64 on arch xtpam */
-
-#define SHORTINT INT8
-#define INTEGER  INT16
-#define LONGINT  INT32
-#define SET      UINT32
-
-#include "SYSTEM.h"
-#include "Out.h"
-
-
-static INT16 Test_a[3];
-
-
-static void Test_Ax (INT16 *x, ADDRESS x__len);
-
-
-static void Test_Ax (INT16 *x, ADDRESS x__len)
-{
-}
-
-
-export int main(int argc, char **argv)
-{
-       __INIT(argc, argv);
-       __MODULE_IMPORT(Out);
-       __REGMAIN("Test", 0);
-/* BEGIN */
-       Out_Open();
-       Test_Ax((void*)Test_a, 3);
-       Out_Flush();
-       __FINI;
-}
diff --git a/test/make.sh b/test/make.sh
deleted file mode 100755 (executable)
index 74c6cf1..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-set -e
-
-voc Test.Mod -m