}
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);
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);
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);
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");
}
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);
-/* 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;
}