summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e763da8)
raw | patch | inline | side by side (parent: e763da8)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 24 Jul 2017 20:08:12 +0000 (23:08 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 24 Jul 2017 20:08:12 +0000 (23:08 +0300) |
19 files changed:
diff --git a/count.sh b/count.sh
--- /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
--- /dev/null
+++ b/include/oberon.h
@@ -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
index 1f95bcf593d5824856bf83e51bd355a2315c2a85..9e4b2551b852601b51ca3a7840b8c90d7d226739 100755 (executable)
--- a/make.sh
+++ b/make.sh
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
index 0576334c3d003d72efdf80e9946f50d4f68ef97d..60b17bda4932bb27322d9bae00b186974f032d5f 100644 (file)
--- a/notes
+++ b/notes
-- открытые массивы работкают криво как статические аргументы процедур
- Случай 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
--- 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
--- /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
--- /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)
rename from generator.c
rename to src/backends/libgccjit/generator-libgccjit.c
index b0887aee7c82587beed212c50e56cac179a32b72..a3bd2772c90fc1d50c7d9c3fd040051b60c6f7d4 100644 (file)
--- a/generator.c
#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
--- /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
--- /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
diff --git a/generator.h b/src/generator.h
diff --git a/src/oberon-internals.h b/src/oberon-internals.h
--- /dev/null
+++ b/src/oberon-internals.h
@@ -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
diff --git a/oberon.c b/src/oberon.c
similarity index 99%
rename from oberon.c
rename to src/oberon.c
index 16043c2f7aa0e4bdcd658130a5765b126b385b11..d636fba6b19d253c65a167420a25f21547bef892 100644 (file)
rename from oberon.c
rename to src/oberon.c
index 16043c2f7aa0e4bdcd658130a5765b126b385b11..d636fba6b19d253c65a167420a25f21547bef892 100644 (file)
--- a/oberon.c
+++ b/src/oberon.c
#include <assert.h>
#include <stdbool.h>
-#include "oberon.h"
+#include "../include/oberon.h"
+
+#include "oberon-internals.h"
#include "generator.h"
enum {
diff --git a/test.c b/src/test.c
similarity index 98%
rename from test.c
rename to src/test.c
index 6175148f461c4c0db1ff690997928e56f560544f..1c3c8e39347533eb9db1d0b2e289f0348f77b693 100644 (file)
rename from test.c
rename to src/test.c
index 6175148f461c4c0db1ff690997928e56f560544f..1c3c8e39347533eb9db1d0b2e289f0348f77b693 100644 (file)
--- a/test.c
+++ b/src/test.c
-#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
--- a/test/.gitignore
+++ /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
index 1bf0d5a..0000000
Binary files a/test/Test and /dev/null differ
diff --git a/test/Test.Mod b/test/Test.Mod
--- a/test/Test.Mod
+++ /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
--- a/test/Test.c
+++ /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
--- a/test/make.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-set -e
-
-voc Test.Mod -m