DEADSOFTWARE

Добавлено экспортирование объектов в модулях
[dsw-obn.git] / oberon.c
index 6dd84f16b6b9c3108973c087636865c661735bc3..817da1ae02b4f417f9c005f902bd2d26b0f5f3a1 100644 (file)
--- a/oberon.c
+++ b/oberon.c
@@ -52,7 +52,8 @@ enum {
        POINTER,
        TO,
        UPARROW,
-       NIL
+       NIL,
+       IMPORT
 };
 
 // =======================================================================
@@ -108,11 +109,8 @@ oberon_new_type_boolean(int size)
 static oberon_scope_t *
 oberon_open_scope(oberon_context_t * ctx)
 {
-       oberon_scope_t * scope = malloc(sizeof *scope);
-       memset(scope, 0, sizeof *scope);
-
-       oberon_object_t * list = malloc(sizeof *list);
-       memset(list, 0, sizeof *list);
+       oberon_scope_t * scope = calloc(1, sizeof *scope);
+       oberon_object_t * list = calloc(1, sizeof *list);
 
        scope -> ctx = ctx;
        scope -> list = list;
@@ -136,7 +134,7 @@ oberon_close_scope(oberon_scope_t * scope)
 }
 
 static oberon_object_t *
-oberon_define_object(oberon_scope_t * scope, char * name, int class)
+oberon_define_object(oberon_scope_t * scope, char * name, int class, int export, int read_only)
 {
        oberon_object_t * x = scope -> list;
        while(x -> next && strcmp(x -> next -> name, name) != 0)
@@ -153,6 +151,8 @@ oberon_define_object(oberon_scope_t * scope, char * name, int class)
        memset(newvar, 0, sizeof *newvar);
        newvar -> name = name;
        newvar -> class = class;
+       newvar -> export = export;
+       newvar -> read_only = read_only;
        newvar -> local = scope -> local;
        newvar -> parent = scope -> parent;
 
@@ -239,64 +239,24 @@ oberon_find_field(oberon_context_t * ctx, oberon_type_t * rec, char * name)
 }
 
 static oberon_object_t *
-oberon_define_type(oberon_scope_t * scope, char * name, oberon_type_t * type)
+oberon_define_type(oberon_scope_t * scope, char * name, oberon_type_t * type, int export, int read_only)
 {
        oberon_object_t * id;
-       id = oberon_define_object(scope, name, OBERON_CLASS_TYPE);
+       id = oberon_define_object(scope, name, OBERON_CLASS_TYPE, export, read_only);
        id -> type = type;
        oberon_generator_init_type(scope -> ctx, type);
        return id;
 }
 
-/*
-static oberon_type_t *
-oberon_find_type(oberon_scope_t * scope, char * name)
-{
-       oberon_object_t * x = oberon_find_object(scope, name);
-       if(x -> class != OBERON_CLASS_TYPE)
-       {
-               oberon_error(scope -> ctx, "%s not a type", name);
-       }
-
-       return x -> type;
-}
-*/
-
 static oberon_object_t *
-oberon_define_var(oberon_scope_t * scope, int class, char * name, oberon_type_t * type)
+oberon_define_var(oberon_scope_t * scope, int class, char * name, oberon_type_t * type, int export, int read_only)
 {
        oberon_object_t * var;
-       var = oberon_define_object(scope, name, class);
+       var = oberon_define_object(scope, name, class, export, read_only);
        var -> type = type;
        return var;
 }
 
-/*
-static oberon_object_t *
-oberon_find_var(oberon_scope_t * scope, char * name)
-{
-       oberon_object_t * x = oberon_find_object(scope, name);
-
-       if(x -> class != OBERON_CLASS_VAR)
-       {
-               oberon_error(scope -> ctx, "%s not a var", name);
-       }
-
-       return x;
-}
-*/
-
-/*
-static oberon_object_t *
-oberon_define_proc(oberon_scope_t * scope, char * name, oberon_type_t * signature)
-{
-       oberon_object_t * proc;
-       proc = oberon_define_object(scope, name, OBERON_CLASS_PROC);
-       proc -> type = signature;
-       return proc;
-}
-*/
-
 // =======================================================================
 //   SCANER
 // ======================================================================= 
@@ -415,6 +375,10 @@ oberon_read_ident(oberon_context_t * ctx)
        {
                ctx -> token = NIL;
        }
+       else if(strcmp(ident, "IMPORT") == 0)
+       {
+               ctx -> token = IMPORT;
+       }
 }
 
 static void
@@ -731,7 +695,7 @@ oberon_autocast_call(oberon_context_t * ctx, oberon_expr_t * desig)
                oberon_error(ctx, "expected mode CALL");
        }
 
-       if(desig -> item.var -> class != OBERON_CLASS_PROC)
+       if(desig -> item.var -> type -> class != OBERON_TYPE_PROCEDURE)
        {
                oberon_error(ctx, "only procedures can be called");
        }
@@ -780,9 +744,25 @@ oberon_autocast_call(oberon_context_t * ctx, oberon_expr_t * desig)
 static oberon_expr_t *
 oberon_make_call_func(oberon_context_t * ctx, oberon_object_t * proc, int num_args, oberon_expr_t * list_args)
 {
-       if(proc -> class != OBERON_CLASS_PROC)
+       switch(proc -> class)
        {
-               oberon_error(ctx, "not a procedure");
+               case OBERON_CLASS_PROC:
+                       if(proc -> class != OBERON_CLASS_PROC)
+                       {
+                               oberon_error(ctx, "not a procedure");
+                       }
+                       break;
+               case OBERON_CLASS_VAR:
+               case OBERON_CLASS_VAR_PARAM:
+               case OBERON_CLASS_PARAM:
+                       if(proc -> type -> class != OBERON_TYPE_PROCEDURE)
+                       {
+                               oberon_error(ctx, "not a procedure");
+                       }
+                       break;
+               default:
+                       oberon_error(ctx, "not a procedure");
+                       break;
        }
 
        oberon_expr_t * call;
@@ -816,9 +796,25 @@ oberon_make_call_func(oberon_context_t * ctx, oberon_object_t * proc, int num_ar
 static void
 oberon_make_call_proc(oberon_context_t * ctx, oberon_object_t * proc, int num_args, oberon_expr_t * list_args)
 {
-       if(proc -> class != OBERON_CLASS_PROC)
+       switch(proc -> class)
        {
-               oberon_error(ctx, "not a procedure");
+               case OBERON_CLASS_PROC:
+                       if(proc -> class != OBERON_CLASS_PROC)
+                       {
+                               oberon_error(ctx, "not a procedure");
+                       }
+                       break;
+               case OBERON_CLASS_VAR:
+               case OBERON_CLASS_VAR_PARAM:
+               case OBERON_CLASS_PARAM:
+                       if(proc -> type -> class != OBERON_TYPE_PROCEDURE)
+                       {
+                               oberon_error(ctx, "not a procedure");
+                       }
+                       break;
+               default:
+                       oberon_error(ctx, "not a procedure");
+                       break;
        }
 
        if(proc -> sysproc)
@@ -953,6 +949,39 @@ oberon_make_record_selector(oberon_context_t * ctx, oberon_expr_t * expr, char *
        || ((x) == DOT) \
        || ((x) == UPARROW))
 
+static oberon_object_t *
+oberon_qualident(oberon_context_t * ctx, char ** xname, int check)
+{
+       char * name;
+       oberon_object_t * x;
+
+       name = oberon_assert_ident(ctx);
+       x = oberon_find_object(ctx -> decl, name, check);
+
+       if(x != NULL)
+       {
+               if(x -> class == OBERON_CLASS_MODULE)
+               {
+                       oberon_assert_token(ctx, DOT);
+                       name = oberon_assert_ident(ctx);
+                       /* Наличие объектов в левых модулях всегда проверяется */
+                       x = oberon_find_object(x -> module -> decl, name, 1);
+
+                       if(x -> export == 0)
+                       {
+                               oberon_error(ctx, "not exported");
+                       }
+               }
+       }
+
+       if(xname)
+       {
+               *xname = name;
+       }
+
+       return x;
+}
+
 static oberon_expr_t *
 oberon_designator(oberon_context_t * ctx)
 {
@@ -960,8 +989,7 @@ oberon_designator(oberon_context_t * ctx)
        oberon_object_t * var;
        oberon_expr_t * expr;
 
-       name = oberon_assert_ident(ctx);
-       var = oberon_find_object(ctx -> decl, name, 1);
+       var = oberon_qualident(ctx, NULL, 1);
 
        switch(var -> class)
        {
@@ -972,11 +1000,8 @@ oberon_designator(oberon_context_t * ctx)
                case OBERON_CLASS_VAR:
                case OBERON_CLASS_VAR_PARAM:
                case OBERON_CLASS_PARAM:
-                       expr = oberon_new_item(MODE_VAR, var -> type);
-                       break;
                case OBERON_CLASS_PROC:
-                       //expr = oberon_make_call_expr(var, 0, NULL);
-                       expr = oberon_new_item(MODE_CALL, var -> type);
+                       expr = oberon_new_item(MODE_VAR, var -> type);
                        break;
                default:
                        oberon_error(ctx, "invalid designator");
@@ -1023,6 +1048,7 @@ oberon_opt_func_parens(oberon_context_t * ctx, oberon_expr_t * expr)
 {
        assert(expr -> is_item == 1);
 
+       /* Если есть скобки - значит вызов. Если нет, то передаём указатель. */
        if(ctx -> token == LPAREN)
        {
                oberon_assert_token(ctx, LPAREN);
@@ -1048,22 +1074,23 @@ oberon_opt_proc_parens(oberon_context_t * ctx, oberon_expr_t * expr)
 {
        assert(expr -> is_item == 1);
 
+       int num_args = 0;
+       oberon_expr_t * arguments = NULL;
+
        if(ctx -> token == LPAREN)
        {
                oberon_assert_token(ctx, LPAREN);
 
-               int num_args = 0;
-               oberon_expr_t * arguments = NULL;
-
                if(ISEXPR(ctx -> token))
                {
                        oberon_expr_list(ctx, &num_args, &arguments, 0);
                }
 
-               oberon_make_call_proc(ctx, expr -> item.var, num_args, arguments);
-
                oberon_assert_token(ctx, RPAREN);
        }
+
+       /* Вызов происходит даже без скобок */
+       oberon_make_call_proc(ctx, expr -> item.var, num_args, arguments);
 }
 
 static oberon_expr_t *
@@ -1386,16 +1413,53 @@ oberon_assert_ident(oberon_context_t * ctx)
 }
 
 static void
-oberon_var_decl(oberon_context_t * ctx)
+oberon_def(oberon_context_t * ctx, int * export, int * read_only)
+{
+       switch(ctx -> token)
+       {
+               case STAR:
+                       oberon_assert_token(ctx, STAR);
+                       *export = 1;
+                       *read_only = 0;
+                       break;
+               case MINUS:
+                       oberon_assert_token(ctx, MINUS);
+                       *export = 1;
+                       *read_only = 1;
+                       break;
+               default:
+                       *export = 0;
+                       *read_only = 0;
+                       break;
+       }
+}
+
+static oberon_object_t *
+oberon_ident_def(oberon_context_t * ctx, int class)
 {
        char * name;
+       int export;
+       int read_only;
+       oberon_object_t * x;
+
+       name = oberon_assert_ident(ctx);
+       oberon_def(ctx, &export, &read_only);
+
+       x = oberon_define_object(ctx -> decl, name, class, export, read_only);
+       return x;
+}
+
+static void
+oberon_var_decl(oberon_context_t * ctx)
+{
+       oberon_object_t * var;
        oberon_type_t * type;
        type = oberon_new_type_ptr(OBERON_TYPE_VOID);
 
-       name = oberon_assert_ident(ctx);
+       var = oberon_ident_def(ctx, OBERON_CLASS_VAR);
        oberon_assert_token(ctx, COLON);
        oberon_type(ctx, &type);
-       oberon_define_var(ctx -> decl, OBERON_CLASS_VAR, name, type);
+       var -> type = type;
 }
 
 static oberon_object_t *
@@ -1405,11 +1469,11 @@ oberon_make_param(oberon_context_t * ctx, int token, char * name, oberon_type_t
 
        if(token == VAR)
        {
-               param = oberon_define_var(ctx -> decl, OBERON_CLASS_VAR_PARAM, name, type);
+               param = oberon_define_var(ctx -> decl, OBERON_CLASS_VAR_PARAM, name, type, 0, 0);
        }
        else if(token == IDENT)
        {
-               param = oberon_define_var(ctx -> decl, OBERON_CLASS_PARAM, name, type);
+               param = oberon_define_var(ctx -> decl, OBERON_CLASS_PARAM, name, type, 0, 0);
        }
        else
        {
@@ -1467,8 +1531,14 @@ oberon_formal_pars(oberon_context_t * ctx, oberon_type_t * signature)
        if(ctx -> token == COLON)
        {
                oberon_assert_token(ctx, COLON);
-               // TODO get by qualident
-               oberon_type(ctx, &signature -> base);
+
+               oberon_object_t * typeobj;
+               typeobj = oberon_qualident(ctx, NULL, 1);
+               if(typeobj -> class != OBERON_CLASS_TYPE)
+               {
+                       oberon_error(ctx, "function result is not type");
+               }
+               signature -> base = typeobj -> type;
        }
 }
 
@@ -1596,7 +1666,10 @@ oberon_proc_decl(oberon_context_t * ctx)
        }
 
        char * name;
+       int export;
+       int read_only;
        name = oberon_assert_ident(ctx);
+       oberon_def(ctx, &export, &read_only);
 
        oberon_scope_t * proc_scope;
        proc_scope = oberon_open_scope(ctx);
@@ -1627,11 +1700,16 @@ oberon_proc_decl(oberon_context_t * ctx)
                        }
                }
 
+               if(proc -> export != export || proc -> read_only != read_only)
+               {
+                       oberon_error(ctx, "export type not matched");
+               }
+
                oberon_compare_signatures(ctx, proc -> type, signature);
        }
        else
        {
-               proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC);
+               proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC, export, read_only);
                proc -> type = signature;
                proc -> scope = proc_scope;
                oberon_generator_init_proc(ctx, proc);
@@ -1649,15 +1727,12 @@ oberon_proc_decl(oberon_context_t * ctx)
 static void
 oberon_const_decl(oberon_context_t * ctx)
 {
-       char * name;
        oberon_item_t * value;
        oberon_object_t * constant;
 
-       name = oberon_assert_ident(ctx);
+       constant = oberon_ident_def(ctx, OBERON_CLASS_CONST);
        oberon_assert_token(ctx, EQUAL);
        value = oberon_const_expr(ctx);
-
-       constant = oberon_define_object(ctx -> decl, name, OBERON_CLASS_CONST);
        constant -> value = value;
 }
 
@@ -1703,8 +1778,10 @@ oberon_qualident_type(oberon_context_t * ctx, oberon_type_t ** type)
        char * name;
        oberon_object_t * to;
 
-       name = oberon_assert_ident(ctx);
-       to = oberon_find_object(ctx -> decl, name, 0);
+       to = oberon_qualident(ctx, &name, 0);
+
+       //name = oberon_assert_ident(ctx);
+       //to = oberon_find_object(ctx -> decl, name, 0);
 
        if(to != NULL)
        {
@@ -1715,7 +1792,7 @@ oberon_qualident_type(oberon_context_t * ctx, oberon_type_t ** type)
        }
        else
        {
-               to = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE);
+               to = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE, 0, 0);
                to -> type = oberon_new_type_ptr(OBERON_TYPE_VOID);
        }
 
@@ -1824,13 +1901,16 @@ oberon_type_decl(oberon_context_t * ctx)
        char * name;
        oberon_object_t * newtype;
        oberon_type_t * type;
+       int export;
+       int read_only;
 
        name = oberon_assert_ident(ctx);
+       oberon_def(ctx, &export, &read_only);
 
        newtype = oberon_find_object(ctx -> decl, name, 0);
        if(newtype == NULL)
        {
-               newtype = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE);
+               newtype = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE, export, read_only);
                newtype -> type = oberon_new_type_ptr(OBERON_TYPE_VOID);
                assert(newtype -> type);
        }
@@ -1845,6 +1925,9 @@ oberon_type_decl(oberon_context_t * ctx)
                {
                        oberon_error(ctx, "mult definition - already linked");
                }
+
+               newtype -> export = export;
+               newtype -> read_only = read_only;
        }
 
        oberon_assert_token(ctx, EQUAL);
@@ -1996,6 +2079,7 @@ oberon_prevent_recursive_object(oberon_context_t * ctx, oberon_object_t * x)
                        break;
                case OBERON_CLASS_CONST:
                case OBERON_CLASS_PROC:
+               case OBERON_CLASS_MODULE:
                        break;
                default:
                        oberon_error(ctx, "oberon_prevent_recursive_object: wat");
@@ -2114,9 +2198,10 @@ oberon_initialize_object(oberon_context_t * ctx, oberon_object_t * x)
                        break;
                case OBERON_CLASS_CONST:
                case OBERON_CLASS_PROC:
+               case OBERON_CLASS_MODULE:
                        break;
                default:
-                       oberon_error(ctx, "oberon_prevent_recursive_object: wat");
+                       oberon_error(ctx, "oberon_initialize_object: wat");
                        break;
        }
 }
@@ -2250,10 +2335,74 @@ oberon_statement_seq(oberon_context_t * ctx)
        }
 }
 
+static void
+oberon_import_module(oberon_context_t * ctx, char * alias, char * name)
+{
+       oberon_module_t * m = ctx -> module_list;
+       while(m && strcmp(m -> name, name) != 0)
+       {
+               m = m -> next;
+       }
+
+       if(m == NULL)
+       {
+               const char * code;
+               code = ctx -> import_module(name);
+               if(code == NULL)
+               {
+                       oberon_error(ctx, "no such module");
+               }
+
+               m = oberon_compile_module(ctx, code);
+               assert(m);
+       }
+
+       if(m -> ready == 0)
+       {
+               oberon_error(ctx, "cyclic module import");
+       }
+
+       oberon_object_t * ident;
+       ident = oberon_define_object(ctx -> decl, alias, OBERON_CLASS_MODULE, 0, 0);
+       ident -> module = m;
+}
+
+static void
+oberon_import_decl(oberon_context_t * ctx)
+{
+       char * alias;
+       char * name;
+
+       alias = name = oberon_assert_ident(ctx);
+       if(ctx -> token == ASSIGN)
+       {
+               oberon_assert_token(ctx, ASSIGN);
+               name = oberon_assert_ident(ctx);
+       }
+
+       oberon_import_module(ctx, alias, name);
+}
+
+static void
+oberon_import_list(oberon_context_t * ctx)
+{
+       oberon_assert_token(ctx, IMPORT);
+
+       oberon_import_decl(ctx);
+       while(ctx -> token == COMMA)
+       {
+               oberon_assert_token(ctx, COMMA);
+               oberon_import_decl(ctx);
+       }
+
+       oberon_assert_token(ctx, SEMICOLON);
+}
+
 static void
 oberon_parse_module(oberon_context_t * ctx)
 {
-       char *name1, *name2;
+       char * name1;
+       char * name2;
        oberon_read_token(ctx);
 
        oberon_assert_token(ctx, MODULE);
@@ -2261,15 +2410,26 @@ oberon_parse_module(oberon_context_t * ctx)
        oberon_assert_token(ctx, SEMICOLON);
        ctx -> mod -> name = name1;
 
+       oberon_object_t * this_module;
+       this_module = oberon_define_object(ctx -> decl, name1, OBERON_CLASS_MODULE, 0, 0);
+       this_module -> module = ctx -> mod;
+
+       if(ctx -> token == IMPORT)
+       {
+               oberon_import_list(ctx);
+       }
+
+       ctx -> decl -> parent = this_module;
+
        oberon_decl_seq(ctx);
 
+       oberon_generate_begin_module(ctx);
        if(ctx -> token == BEGIN)
        {
                oberon_assert_token(ctx, BEGIN);
-               oberon_generate_begin_module(ctx);
                oberon_statement_seq(ctx);
-               oberon_generate_end_module(ctx);
        }
+       oberon_generate_end_module(ctx);
 
        oberon_assert_token(ctx, END);
        name2 = oberon_assert_ident(ctx);
@@ -2296,34 +2456,23 @@ register_default_types(oberon_context_t * ctx)
        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);
+       oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type, 1, 0);
 
        ctx -> bool_type = oberon_new_type_boolean(sizeof(int));
-       oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type);
+       oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type, 1, 0);
 }
 
 static void
-oberon_new_intrinsic_function(oberon_context_t * ctx, char * name, GenerateFuncCallback generate)
+oberon_new_intrinsic(oberon_context_t * ctx, char * name, GenerateFuncCallback f, GenerateProcCallback p)
 {
        oberon_object_t * proc;
-       proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC);
+       proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC, 1, 0);
        proc -> sysproc = 1;
-       proc -> genfunc = generate;
+       proc -> genfunc = f;
+       proc -> genproc = p;
        proc -> type = oberon_new_type_ptr(OBERON_TYPE_PROCEDURE);
 }
 
-/*
-static void
-oberon_new_intrinsic_procedure(oberon_context_t * ctx, char * name, GenerateProcCallback generate)
-{
-       oberon_object_t * proc;
-       proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC);
-       proc -> sysproc = 1;
-       proc -> genproc = generate;
-       proc -> type = oberon_new_type_ptr(OBERON_TYPE_PROCEDURE);
-}
-*/
-
 static oberon_expr_t *
 oberon_make_abs_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_args)
 {
@@ -2355,19 +2504,20 @@ oberon_make_abs_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_
 }
 
 oberon_context_t *
-oberon_create_context()
+oberon_create_context(ModuleImportCallback import_module)
 {
-       oberon_context_t * ctx = malloc(sizeof *ctx);
-       memset(ctx, 0, sizeof *ctx);
+       oberon_context_t * ctx = calloc(1, sizeof *ctx);
 
        oberon_scope_t * world_scope;
        world_scope = oberon_open_scope(ctx);
        ctx -> world_scope = world_scope;
 
+       ctx -> import_module = import_module;
+
        oberon_generator_init_context(ctx);
 
        register_default_types(ctx);
-       oberon_new_intrinsic_function(ctx, "ABS", oberon_make_abs_call);
+       oberon_new_intrinsic(ctx, "ABS", oberon_make_abs_call, NULL);
 
        return ctx;
 }
@@ -2380,21 +2530,41 @@ oberon_destroy_context(oberon_context_t * ctx)
 }
 
 oberon_module_t *
-oberon_compile_module(oberon_context_t * ctx, const char * code)
+oberon_compile_module(oberon_context_t * ctx, const char * newcode)
 {
-       oberon_module_t * mod = malloc(sizeof *mod);
-       memset(mod, 0, sizeof *mod);
-       ctx -> mod = mod;
+       const char * code = ctx -> code;
+       int code_index = ctx -> code_index;
+       char c = ctx -> c;
+       int token = ctx -> token;
+       char * string = ctx -> string;
+       int integer = ctx -> integer;
+       oberon_scope_t * decl = ctx -> decl;
+       oberon_module_t * mod = ctx -> mod;
 
        oberon_scope_t * module_scope;
        module_scope = oberon_open_scope(ctx);
-       mod -> decl = module_scope;
 
-       oberon_init_scaner(ctx, code);
+       oberon_module_t * module;
+       module = calloc(1, sizeof *module);
+       module -> decl = module_scope;
+       module -> next = ctx -> module_list;
+
+       ctx -> mod = module;
+       ctx -> module_list = module;
+
+       oberon_init_scaner(ctx, newcode);
        oberon_parse_module(ctx);
 
-       oberon_generate_code(ctx);
+       module -> ready = 1;
+
+       ctx -> code = code;
+       ctx -> code_index = code_index;
+       ctx -> c = c;
+       ctx -> token = token;
+       ctx -> string = string;
+       ctx -> integer = integer;
+       ctx -> decl = decl;
+       ctx -> mod = mod;
 
-       ctx -> mod = NULL;
-       return mod;
+       return module;
 }