summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7bff937)
raw | patch | inline | side by side (parent: 7bff937)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 24 Jul 2017 19:31:35 +0000 (22:31 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 24 Jul 2017 19:31:35 +0000 (22:31 +0300) |
generator.c | patch | blob | history | |
notes | patch | blob | history | |
oberon.c | patch | blob | history | |
oberon.h | patch | blob | history | |
test.c | patch | blob | history | |
test/Test | patch | blob | history | |
test/Test.Mod | patch | blob | history | |
test/Test.c | patch | blob | history |
diff --git a/generator.c b/generator.c
index 673ac3381818c09270f17e002b26b8d1b29ad24c..24529e0e26add6f595560626773029ce65f903e6 100644 (file)
--- a/generator.c
+++ b/generator.c
}
else if(item -> mode == MODE_FIELD)
{
+ printf("lvalue_from_item: %s\n", item -> var -> name);
gen_var_t * gen_var = item -> var -> gen_var;
gcc_jit_field * gcc_field = gen_var -> gcc_field;
gcc_jit_lvalue * parent = lvalue_from_item(ctx, item -> parent);
left = gcc_jit_lvalue_access_field(parent, NULL, gcc_field);
}
+ else if(item -> mode == MODE_DEREF)
+ {
+ gcc_jit_rvalue * parent = rvalue_from_item(ctx, item -> parent);
+ left = gcc_jit_rvalue_dereference(parent, NULL);
+ }
else
{
oberon_error(ctx, "invalid lvalue expression");
gcc_jit_rvalue * parent = rvalue_from_item(ctx, item -> parent);
right = gcc_jit_rvalue_access_field(parent, NULL, gcc_field);
}
+ else if(item -> mode == MODE_DEREF)
+ {
+ gcc_jit_lvalue * left = lvalue_from_item(ctx, item);
+ right = gcc_jit_lvalue_as_rvalue(left);
+ }
+ else if(item -> mode == MODE_NIL)
+ {
+ gcc_jit_type * type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID_PTR);
+ right = gcc_jit_context_null(gcc_context, type);
+ }
else
{
oberon_error(ctx, "rvalue_from_item: invalid mode %i", item -> mode);
@@ -536,6 +552,18 @@ oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_
gcc_jit_rvalue * right;
right = rvalue_from_expr(ctx, src);
+ if(src -> is_item)
+ {
+ if(src -> item.mode == MODE_NIL)
+ {
+ gen_context_t * gen_context = ctx -> gen_context;
+ gcc_jit_context * gcc_context = gen_context -> gcc_context;
+ gen_type_t * gen_type = dst -> result -> gen_type;
+ gcc_jit_type * cast_to_type = gen_type -> gcc_type;
+ right = gcc_jit_context_new_cast(gcc_context, NULL, right, cast_to_type);
+ }
+ }
+
gen_context_t * gen_context = ctx -> gen_context;
gcc_jit_block * gcc_block = gen_context -> gcc_block;
gcc_jit_block_add_assignment(gcc_block, NULL, left, right);
index 3e23e6b973ffde1b6c92741b58b5938ea9949e5a..0dd194e9e6e6057ced4ec2518616dd9f63622934 100644 (file)
--- a/notes
+++ b/notes
+- хреновая проверка типов-указателей
- нету процедуры NEW
- не реализовано расширение типа record
-- не реализованы многомерные массивы
+- не реализована краткая форма многомерных массивов и краткой формы доступа к ним (* [1, 2, 3] - компилится, но вычисляется только первый аргумент *)
- не реализованы локальные объявления в процедурах
- не работает присваивание к переменным-процедурам.
- не понятен результат присваивания статических структур (* reca := recb; *)
+- не понятен результат присваивания статических массивов (* arr1 := arr2; *)
- не реализованы var-параметры в генераторе
- не реализованы процедуры "наперёд"
+- нету типа set
- не реализована свёртка констант
- не реализован автокаст (libgccjit сам разруливает)
- не протестированы типы разнных размеров
-
-- похоже record инициализируется дважды в некоторых случаях
diff --git a/oberon.c b/oberon.c
index f4a711f5da3156912e43afb4bc8887dd076936a3..dfed94a274ad3991d56ab8adf5223fabac446e38 100644 (file)
--- a/oberon.c
+++ b/oberon.c
RBRACE,
RECORD,
POINTER,
- TO
+ TO,
+ UPARROW,
+ NIL
};
// =======================================================================
{
ctx -> token = TO;
}
+ else if(strcmp(ident, "NIL") == 0)
+ {
+ ctx -> token = NIL;
+ }
}
static void
ctx -> token = RBRACE;
oberon_get_char(ctx);
break;
+ case '^':
+ ctx -> token = UPARROW;
+ oberon_get_char(ctx);
+ break;
default:
oberon_error(ctx, "invalid char");
break;
|| ((x) == TRUE) \
|| ((x) == FALSE))
-#define ISSELECTOR(x) \
- (((x) == LBRACE) \
- || ((x) == DOT))
-
static oberon_expr_t *
-oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, int num_indexes, oberon_expr_t * indexes)
+oberno_make_dereferencing(oberon_context_t * ctx, oberon_expr_t * expr)
{
- assert(desig -> is_item == 1);
-
- if(desig -> item.mode != MODE_VAR)
+ if(expr -> result -> class != OBERON_TYPE_POINTER)
{
- oberon_error(ctx, "not MODE_VAR");
+ oberon_error(ctx, "not a pointer");
}
- int class = desig -> item.var -> class;
- switch(class)
+ assert(expr -> is_item);
+
+ oberon_expr_t * selector;
+ selector = oberon_new_item(MODE_DEREF, expr -> result -> base);
+ selector -> item.parent = (oberon_item_t *) expr;
+
+ return selector;
+}
+
+static oberon_expr_t *
+oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, int num_indexes, oberon_expr_t * indexes)
+{
+ if(desig -> result -> class == OBERON_TYPE_POINTER)
{
- case OBERON_CLASS_VAR:
- case OBERON_CLASS_VAR_PARAM:
- case OBERON_CLASS_PARAM:
- break;
- default:
- oberon_error(ctx, "not variable");
- break;
+ desig = oberno_make_dereferencing(ctx, desig);
}
- oberon_type_t * type = desig -> item.var -> type;
- if(type -> class != OBERON_TYPE_ARRAY)
+ assert(desig -> is_item);
+
+ if(desig -> result -> class != OBERON_TYPE_ARRAY)
{
oberon_error(ctx, "not array");
}
-// int dim = desig -> item.var -> type -> dim;
-// if(num_indexes != dim)
-// {
-// oberon_error(ctx, "dimesions not matched");
-// }
+ oberon_type_t * base;
+ base = desig -> result -> base;
- oberon_type_t * base = desig -> item.var -> type -> base;
+ // TODO check ranges
oberon_expr_t * selector;
selector = oberon_new_item(MODE_INDEX, base);
@@ -778,10 +785,14 @@ oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, int nu
static oberon_expr_t *
oberon_make_record_selector(oberon_context_t * ctx, oberon_expr_t * expr, char * name)
{
+ if(expr -> result -> class == OBERON_TYPE_POINTER)
+ {
+ expr = oberno_make_dereferencing(ctx, expr);
+ }
+
assert(expr -> is_item == 1);
- int class = expr -> result -> class;
- if(class != OBERON_TYPE_RECORD)
+ if(expr -> result -> class != OBERON_TYPE_RECORD)
{
oberon_error(ctx, "not record");
}
@@ -799,6 +810,11 @@ oberon_make_record_selector(oberon_context_t * ctx, oberon_expr_t * expr, char *
return selector;
}
+#define ISSELECTOR(x) \
+ (((x) == LBRACE) \
+ || ((x) == DOT) \
+ || ((x) == UPARROW))
+
static oberon_expr_t *
oberon_designator(oberon_context_t * ctx)
{
oberon_assert_token(ctx, RBRACE);
expr = oberon_make_array_selector(ctx, expr, num_indexes, indexes);
break;
+ case UPARROW:
+ oberon_assert_token(ctx, UPARROW);
+ expr = oberno_make_dereferencing(ctx, expr);
+ break;
default:
oberon_error(ctx, "oberon_designator: wat");
break;
expr = oberon_factor(ctx);
expr = oberon_make_unary_op(ctx, NOT, expr);
break;
+ case NIL:
+ oberon_assert_token(ctx, NIL);
+ expr = oberon_new_item(MODE_NIL, ctx -> void_ptr_type);
+ break;
default:
oberon_error(ctx, "invalid expression");
}
if(type -> class == OBERON_TYPE_POINTER)
{
- if(type -> base -> class == OBERON_TYPE_RECORD)
- {
- oberon_generator_init_type(ctx, type -> base);
- oberon_generator_init_type(ctx, type);
- }
- else
- {
- oberon_initialize_type(ctx, type -> base);
- oberon_generator_init_type(ctx, type);
- }
+ oberon_initialize_type(ctx, type -> base);
+ oberon_generator_init_type(ctx, type);
}
else if(type -> class == OBERON_TYPE_ARRAY)
{
ctx -> void_type = oberon_new_type_ptr(OBERON_TYPE_VOID);
oberon_generator_init_type(ctx, ctx -> void_type);
+ ctx -> void_ptr_type = oberon_new_type_ptr(OBERON_TYPE_POINTER);
+ ctx -> void_ptr_type -> base = ctx -> void_type;
+ oberon_generator_init_type(ctx, ctx -> void_ptr_type);
+
ctx -> int_type = oberon_new_type_integer(sizeof(int));
oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type);
diff --git a/oberon.h b/oberon.h
index 93f80a8e78dc3fc2ccb5ea306ed26ce54a7c74f6..02547cd70be76f7ffdaeb60097fa5fe89cc5dd87 100644 (file)
--- a/oberon.h
+++ b/oberon.h
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;
MODE_BOOLEAN,
MODE_CALL,
MODE_INDEX,
- MODE_FIELD
+ MODE_FIELD,
+ MODE_DEREF,
+ MODE_NIL
};
enum
index 432307f51ba6e983b25400f43e593e2e8e555fdf..b934af876ca2bde9d44397015f95c7ce70953bd5 100644 (file)
--- a/test.c
+++ b/test.c
static const char source[] =
"MODULE Test;"
"TYPE"
- " Int = INTEGER;"
- " PArray2D = POINTER TO Array2D;"
- " Array2D = ARRAY 3 OF ARRAY 3 OF INTEGER;"
- " PAP2D = ARRAY 4 OF POINTER TO ARRAY 5 OF INTEGER;"
- " Object = POINTER TO ObjectDesc;"
- " ObjectDesc = RECORD"
- " value : Array2D;"
- " value2 : PArray2D;"
- " doStuff : Proc;"
- " next : Object;"
+ " MyRec = POINTER TO MyRecDesc;"
+ " MyRecDesc = RECORD"
+ " a : INTEGER;"
" END;"
- " Proc = PROCEDURE(self : Object; i : Int);"
"VAR"
- " i : Int;"
- " a2 : Array2D;"
- " p2 : PArray2D;"
- " po : Object;"
- " do : ObjectDesc;"
- " stuffProc : Proc;"
- " pap2 : PAP2D;"
- " "
+ " r : MyRec;"
"BEGIN;"
+ " r := NIL;"
+ " r.a := 1;"
"END Test."
;
diff --git a/test/Test b/test/Test
index 2c0d9836ae6b2a1da66ff6035c51c769e557a57c..09dbea89f6a56f7f03fd224992382247908ac664 100755 (executable)
Binary files a/test/Test and b/test/Test differ
Binary files a/test/Test and b/test/Test differ
diff --git a/test/Test.Mod b/test/Test.Mod
index 5454854a7ecfcc81ec3c6b7e53a5d4de297173f3..41e1faeb099b8b10a52e4abd8a4822de32c9c08e 100644 (file)
--- a/test/Test.Mod
+++ b/test/Test.Mod
MODULE Test;
+IMPORT Out;
+
TYPE
- MyArr = POINTER TO ARRAY OF MyArr;
+ MyArr = ARRAY 3 OF POINTER TO ARRAY 6 OF INTEGER;
+
+VAR
+ a : MyArr;
+
+BEGIN
+ Out.Open;
+
+ NEW(a[0]);
+ a[0][0] := 1;
+ Out.Int(a[0][0], 0);
+ Out.Ln;
+ Out.Flush;
END Test.
diff --git a/test/Test.c b/test/Test.c
index c1cde1214ebe48b9550515f502d30fb6f1aff2ab..22b0e5bd3ff0cbc2179f75cfe1da48159b9fb4b6 100644 (file)
--- a/test/Test.c
+++ b/test/Test.c
-/* voc 2.1.0 [2017/06/08] for gcc LP64 on arch xtpam */
+/* voc 2.1.0 [2017/07/17] for gcc LP64 on arch xtpam */
#define SHORTINT INT8
#define INTEGER INT16
#define SET UINT32
#include "SYSTEM.h"
-
-struct Test__1 {
- char _prvt0[1];
-};
+#include "Out.h"
typedef
- struct Test__1 *Test_MyRecDesc;
+ INT16 (*Test_MyArr[3])[6];
+
+static Test_MyArr Test_a;
-export ADDRESS *Test__1__typ;
+static void EnumPtrs(void (*P)(void*))
+{
+ __ENUMP(Test_a, 3, P);
+}
-__TDESC(Test__1, 1, 0) = {__TDFLDS("", 1), {-8}};
export int main(int argc, char **argv)
{
__INIT(argc, argv);
- __REGMAIN("Test", 0);
- __INITYP(Test__1, Test__1, 0);
+ __MODULE_IMPORT(Out);
+ __REGMAIN("Test", EnumPtrs);
/* BEGIN */
+ Out_Open();
+ Test_a[0] = __NEWARR(NIL, 2, 2, 1, 0, ((INT64)(6)));
+ (*Test_a[0])[0] = 1;
+ Out_Int((*Test_a[0])[0], 0);
+ Out_Ln();
+ Out_Flush();
__FINI;
}