From: DeaDDooMER Date: Mon, 24 Jul 2017 20:08:12 +0000 (+0300) Subject: Изменение структуры проекта X-Git-Url: http://deadsoftware.ru/gitweb?p=dsw-obn.git;a=commitdiff_plain;h=9e6d0f74f74926a9c73d15418c2e9668689061f2 Изменение структуры проекта --- diff --git a/count.sh b/count.sh new file mode 100755 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 index 0000000..b2f24b4 --- /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 diff --git a/make.sh b/make.sh index 1f95bcf..9e4b255 100755 --- 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 " + echo "list of backends: dummy libgccjit" +esac diff --git a/notes b/notes index 0576334..60b17bd 100644 --- 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 index 189369b..0000000 --- a/oberon.h +++ /dev/null @@ -1,345 +0,0 @@ -#ifndef EMBEDED_OBERON_SCRIPT_H -#define EMBEDED_OBERON_SCRIPT_H - -#include - -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 index 0000000..e9b26b5 --- /dev/null +++ b/src/backends/dummy/generator-libgccjit.c @@ -0,0 +1,118 @@ +#include +#include + +#include + +#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 index 0000000..499b90b --- /dev/null +++ b/src/backends/dummy/generator-libgccjit.h @@ -0,0 +1,24 @@ +struct gen_proc_t +{ + +}; + +struct gen_type_t +{ + +}; + +struct gen_var_t +{ + +}; + +struct gen_block_t +{ + +}; + +struct gen_context_t +{ + +}; diff --git a/generator.c b/src/backends/libgccjit/generator-libgccjit.c similarity index 99% rename from generator.c rename to src/backends/libgccjit/generator-libgccjit.c index b0887ae..a3bd277 100644 --- a/generator.c +++ b/src/backends/libgccjit/generator-libgccjit.c @@ -8,8 +8,9 @@ #include -#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 index 0000000..ba79933 --- /dev/null +++ b/src/backends/libgccjit/generator-libgccjit.h @@ -0,0 +1,34 @@ +#include + +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 index 0000000..978f4f6 --- /dev/null +++ b/src/backends/libgccjit/notes @@ -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 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 index 0000000..e265a79 --- /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 16043c2..d636fba 100644 --- a/oberon.c +++ b/src/oberon.c @@ -6,7 +6,9 @@ #include #include -#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 6175148..1c3c8e3 100644 --- a/test.c +++ b/src/test.c @@ -1,9 +1,9 @@ -#include "oberon.h" -#include "generator.h" - +#include #include #include +#include "../include/oberon.h" + static char source_test[] = "(* Main module *)" "MODULE Test;" diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 345e6ae..0000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Test diff --git a/test/Test b/test/Test deleted file mode 100755 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 index 22bad20..0000000 --- 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 deleted file mode 100644 index f40f138..0000000 --- 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 deleted file mode 100755 index 74c6cf1..0000000 --- a/test/make.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -set -e - -voc Test.Mod -m