From 2a0d7e7fbb7dcccc65f98301a0627ee47c755f2f Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Tue, 25 Jul 2017 20:51:11 +0300 Subject: [PATCH] =?utf8?q?=D0=9F=D0=B5=D1=80=D0=B2=D1=8B=D0=B5=20=D0=BD?= =?utf8?q?=D0=B0=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20=D0=B1=D1=8D?= =?utf8?q?=D0=BA=D1=8D=D0=BD=D0=B4=D0=B0=20=D0=B4=D0=BB=D1=8F=20jvm?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + Launcher.java | 6 + jvm_test.sh | 15 + make.sh | 5 +- ...enerator-libgccjit.c => generator-dummy.c} | 2 +- ...enerator-libgccjit.h => generator-dummy.h} | 0 src/backends/jvm/generator-jvm.c | 744 ++++++++++++++++++ src/backends/jvm/generator-jvm.h | 41 + src/generator.h | 1 + src/oberon-internals.h | 5 +- src/oberon.c | 3 + src/test.c | 41 +- tst.java | 4 + 13 files changed, 841 insertions(+), 28 deletions(-) create mode 100644 Launcher.java create mode 100755 jvm_test.sh rename src/backends/dummy/{generator-libgccjit.c => generator-dummy.c} (98%) rename src/backends/dummy/{generator-libgccjit.h => generator-dummy.h} (100%) create mode 100644 src/backends/jvm/generator-jvm.c create mode 100644 src/backends/jvm/generator-jvm.h create mode 100644 tst.java diff --git a/.gitignore b/.gitignore index bbbc7ed..6cd2ab3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.out dump.txt +*.j +*.class diff --git a/Launcher.java b/Launcher.java new file mode 100644 index 0000000..220f671 --- /dev/null +++ b/Launcher.java @@ -0,0 +1,6 @@ +class Launcher { + public static void main(String[] args) + throws ClassNotFoundException, InstantiationException, IllegalAccessException { + Class.forName(args[0]).newInstance();; + } +} diff --git a/jvm_test.sh b/jvm_test.sh new file mode 100755 index 0000000..9dce872 --- /dev/null +++ b/jvm_test.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +set -e + +./make.sh jvm +./run.sh +jasmin *.j +proguard -injars . \ + -libraryjars /usr/lib/jvm/java-8-openjdk/jre/lib/rt.jar \ + -dontshrink -dontobfuscate -keep class Test + +java -cp . Launcher Test + +echo Everythin ok! Wheee... + diff --git a/make.sh b/make.sh index 9e4b255..561238e 100755 --- a/make.sh +++ b/make.sh @@ -9,11 +9,14 @@ case "$1" in dummy) $CC $CFLAGS src/*.c src/backends/dummy/*.c ;; + jvm) + $CC $CFLAGS src/*.c src/backends/jvm/*.c + ;; libgccjit) CFLAGS="-lgccjit $CFLAGS" $CC $CFLAGS src/*.c src/backends/libgccjit/*.c ;; ***) echo "use: make.sh " - echo "list of backends: dummy libgccjit" + echo "list of backends: dummy jvm libgccjit" esac diff --git a/src/backends/dummy/generator-libgccjit.c b/src/backends/dummy/generator-dummy.c similarity index 98% rename from src/backends/dummy/generator-libgccjit.c rename to src/backends/dummy/generator-dummy.c index e9b26b5..fc709a0 100644 --- a/src/backends/dummy/generator-libgccjit.c +++ b/src/backends/dummy/generator-dummy.c @@ -5,7 +5,7 @@ #include "../../../include/oberon.h" #include "../../oberon-internals.h" -#include "generator-libgccjit.h" +#include "generator-dummy.h" void oberon_generator_init_context(oberon_context_t * ctx) diff --git a/src/backends/dummy/generator-libgccjit.h b/src/backends/dummy/generator-dummy.h similarity index 100% rename from src/backends/dummy/generator-libgccjit.h rename to src/backends/dummy/generator-dummy.h diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c new file mode 100644 index 0000000..2a2abcd --- /dev/null +++ b/src/backends/jvm/generator-jvm.c @@ -0,0 +1,744 @@ +#include +#include +#include +#include +#include + +#include + +#include "../../../include/oberon.h" +#include "../../oberon-internals.h" +#include "generator-jvm.h" + +char * +new_string(const char * format, ...) +{ + va_list ptr; + va_start(ptr, format); + + char buf[1024]; + vsnprintf(buf, 1024, format, ptr); + + va_end(ptr); + + char * result; + int size; + + size = strlen(buf); + result = GC_MALLOC(size + 1); + memset(result, 0, size); + strncpy(result, buf, size); + + return result; +} + +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; +} + +static char * get_class_full_name(oberon_context_t * ctx, oberon_type_t * type); + +static char * +get_descriptor(oberon_context_t * ctx, oberon_type_t * type) +{ + char * desc; + + switch(type -> class) + { + case OBERON_TYPE_VOID: + return new_string("V"); + break; + case OBERON_TYPE_INTEGER: + switch(type -> size) + { + case 1: + return new_string("B"); + break; + case 2: + return new_string("S"); + break; + case 4: + return new_string("I"); + break; + case 8: + return new_string("J"); + break; + default: + oberon_error(ctx, "get_descriptor: unsupported int size %i", type -> size); + break; + } + break; + case OBERON_TYPE_REAL: + switch(type -> size) + { + case 4: + return new_string("F"); + break; + case 8: + return new_string("D"); + break; + default: + oberon_error(ctx, "get_descriptor: unsupported float size %i", type -> size); + break; + } + break; + case OBERON_TYPE_BOOLEAN: + return new_string("Z"); + break; + case OBERON_TYPE_PROCEDURE: + case OBERON_TYPE_RECORD: + desc = get_class_full_name(ctx, type); + return new_string("L%s;", desc); + break; + case OBERON_TYPE_ARRAY: + desc = get_descriptor(ctx, type -> base); + return new_string("[%s", desc); + break; + default: + oberon_error(ctx, "print_descriptor: unsupported type class %i", type -> class); + break; + } + + return NULL; +} + +static char +get_prefix(oberon_context_t * ctx, oberon_type_t * type) +{ + int size = type -> size; + switch(type -> class) + { + case OBERON_TYPE_BOOLEAN: + case OBERON_TYPE_INTEGER: + return (size <= 4) ? ('i') : ('l'); + break; + case OBERON_TYPE_PROCEDURE: + case OBERON_TYPE_ARRAY: + case OBERON_TYPE_RECORD: + case OBERON_TYPE_POINTER: + return 'a'; + break; + case OBERON_TYPE_REAL: + return (size <= 4) ? ('f') : ('d'); + break; + } + + oberon_error(ctx, "get_prefix: wat"); + return '!'; +} + +static char * +get_field_full_name(oberon_context_t * ctx, oberon_object_t * x) +{ + return new_string("%s/%s", x -> module -> name, x -> name); +} + +static char * +get_class_full_name(oberon_context_t * ctx, oberon_type_t * type) +{ + int rec_id; + char * name = NULL; + + switch(type -> class) + { + case OBERON_TYPE_PROCEDURE: + name = new_string("SYSTEM$PROCEDURE"); + + char * desc; + desc = get_descriptor(ctx, type -> base); + name = new_string("%s$%s", name, desc); + + int num = type -> num_decl; + oberon_object_t * arg = type -> decl; + for(int i = 0; i < num; i++) + { + desc = get_descriptor(ctx, arg -> type); + name = new_string("%s%s", name, desc); + arg = arg -> next; + } + + break; + case OBERON_TYPE_RECORD: + assert(type -> module); + assert(type -> module -> gen_mod); + rec_id = type -> gen_type -> rec_id; + name = new_string("%s$RECORD%i", type -> module -> name, rec_id); + break; + default: + oberon_error(ctx, "get_record_full_name: unk type class %i", type -> class); + break; + } + + return name; +} + +static char * +get_procedure_signature(oberon_context_t * ctx, oberon_type_t * proc) +{ + char * signature; + char * desc; + + signature = new_string("("); + + int num = proc -> num_decl; + oberon_object_t * arg = proc -> decl; + for(int i = 0; i < num; i++) + { + desc = get_descriptor(ctx, arg -> type); + signature = new_string("%s%s", signature, desc); + arg = arg -> next; + } + + desc = get_descriptor(ctx, proc -> base); + signature = new_string("%s)%s", signature, desc); + + return signature; +} + +static void +oberon_generate_procedure_class(oberon_context_t * ctx, oberon_type_t * proc) +{ + FILE * fp; + char * cname; + char * fname; + char * signature; + + cname = get_class_full_name(ctx, proc); + fname = new_string("%s.j", cname); + + fp = fopen(fname, "w"); + + fprintf(fp, ".source SYSTEM\n"); + fprintf(fp, ".class public abstract %s\n", cname); + fprintf(fp, ".super java/lang/Object\n\n"); + + signature = get_procedure_signature(ctx, proc); + + fprintf(fp, ".method public ()V\n"); + fprintf(fp, " aload_0\n"); + fprintf(fp, " invokespecial java/lang/Object/()V\n"); + fprintf(fp, " return\n"); + fprintf(fp, ".end method\n"); + + fprintf(fp, ".method public abstract invoke%s\n", signature); + fprintf(fp, ".end method\n\n"); + + fclose(fp); +} + +static void +oberon_generate_record_class(oberon_context_t * ctx, oberon_type_t * rec) +{ + FILE * fp; + char * cname; + char * fname; + + /* Устанавливаем новоый id */ + rec -> gen_type -> rec_id = rec -> module -> gen_mod -> rec_id; + rec -> module -> gen_mod -> rec_id += 1; + + cname = get_class_full_name(ctx, rec); + fname = new_string("%s.j", cname); + + fp = fopen(fname, "w"); + + fprintf(fp, ".source %s\n", rec -> module -> name); + fprintf(fp, ".class public %s\n", cname); + fprintf(fp, ".super java/lang/Object\n\n"); + + rec -> gen_type -> fp = fp; +} + +void +oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type) +{ + gen_type_t * t = GC_MALLOC(sizeof *t); + memset(t, 0, sizeof *t); + type -> gen_type = t; + + switch(type -> class) + { + case OBERON_TYPE_VOID: + case OBERON_TYPE_INTEGER: + case OBERON_TYPE_BOOLEAN: + case OBERON_TYPE_ARRAY: + case OBERON_TYPE_REAL: + break; + case OBERON_TYPE_RECORD: + oberon_generate_record_class(ctx, type); + break; + case OBERON_TYPE_PROCEDURE: + oberon_generate_procedure_class(ctx, type); + break; + case OBERON_TYPE_POINTER: + assert(type -> base -> class == OBERON_TYPE_VOID); + break; + default: + oberon_error(ctx, "oberon_generator_init_type: unk calss %i", type -> class); + break; + } +} + +static void +oberon_generate_object(oberon_context_t * ctx, FILE * fp, oberon_object_t * x) +{ + char * name; + char * desc; + + name = x -> name; + desc = get_descriptor(ctx, x -> type); + switch(x -> class) + { + case OBERON_CLASS_VAR: + fprintf(fp, ".field public static %s %s\n\n", name, desc); + break; + case OBERON_CLASS_FIELD: + fprintf(fp, ".field public %s %s\n\n", name, desc); + break; + default: + oberon_error(ctx, "oberon_generate_object: unk class %i", x -> class); + break; + } +} + +void +oberon_generator_init_record(oberon_context_t * ctx, oberon_type_t * rec) +{ + FILE * fp; + + fp = rec -> gen_type -> fp; + + int num = rec -> num_decl; + oberon_object_t * field = rec -> decl; + for(int i = 0; i < num; i++) + { + oberon_generate_object(ctx, fp, field); + field = field -> next; + } + + fprintf(fp, ".method public ()V\n"); + fprintf(fp, " aload_0\n"); + fprintf(fp, " invokespecial java/lang/Object/()V\n"); + fprintf(fp, " return\n"); + fprintf(fp, ".end method\n"); + + fclose(fp); +} + +void +oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var) +{ + gen_var_t * v = GC_MALLOC(sizeof *v); + memset(v, 0, sizeof *v); + var -> gen_var = v; + + gen_module_t * m = ctx -> mod -> gen_mod; + + switch(var -> class) + { + case OBERON_CLASS_PARAM: + case OBERON_CLASS_FIELD: + break; + case OBERON_CLASS_VAR: + oberon_generate_object(ctx, m -> fp, var); + break; + default: + oberon_error(ctx, "oberon_generator_init_var: unk var class %i", var -> class); + break; + } +} + +void +oberon_generator_init_proc(oberon_context_t * ctx, oberon_object_t * proc) +{ + gen_proc_t * p = GC_MALLOC(sizeof *p); + memset(p, 0, sizeof *p); + proc -> gen_proc = p; + + if(proc -> local) + { + oberon_error(ctx, "generator: local procedures not implemented"); + } +} + +void +oberon_generator_init_module(oberon_context_t * ctx, oberon_module_t * mod) +{ + gen_module_t * m = GC_MALLOC(sizeof *m); + memset(m, 0, sizeof *m); + mod -> gen_mod = m; + + int fnamesz = strlen(mod -> name) + 3; + char fname[fnamesz + 1]; + snprintf(fname, fnamesz, "%s.j", mod -> name); + + FILE * fp; + fp = fopen(fname, "w"); + assert(fp != NULL); + + fprintf(fp, ".source %s\n", mod -> name); + fprintf(fp, ".class %s\n", mod -> name); + fprintf(fp, ".super java/lang/Object\n\n"); + + m -> fp = fp; +} + +// ======================================================================= +// GENERATOR +// ======================================================================= + +void +oberon_generate_begin_module(oberon_context_t * ctx) +{ + gen_module_t * m = ctx -> mod -> gen_mod; + fprintf(m -> fp, ".method public ()V\n"); + fprintf(m -> fp, " aload_0\n"); + fprintf(m -> fp, " invokespecial java/lang/Object/()V\n"); +} + +void +oberon_generate_end_module(oberon_context_t * ctx) +{ + gen_module_t * m = ctx -> mod -> gen_mod; + + fprintf(m -> fp, " .limit stack 32\n"); + fprintf(m -> fp, " .limit locals 32\n"); + fprintf(m -> fp, " return\n"); + fprintf(m -> fp, ".end method\n"); +} + +void +oberon_generate_begin_proc(oberon_context_t * ctx, oberon_object_t * proc) +{ + gen_module_t * m; + char * signature; + + m = ctx -> mod -> gen_mod; + signature = get_procedure_signature(ctx, proc -> type); + + fprintf(m -> fp, ".method public static %s%s\n", proc -> name, signature); +} + +void +oberon_generate_call_proc(oberon_context_t * ctx, oberon_expr_t * desig) +{ + printf("call proc\n"); +} + +void +oberon_generate_end_proc(oberon_context_t * ctx) +{ + gen_module_t * m; + m = ctx -> mod -> gen_mod; + + fprintf(m -> fp, " .limit stack 32\n"); + fprintf(m -> fp, " .limit locals 32\n"); + fprintf(m -> fp, ".end method\n\n"); +} + +void +oberon_generate_return(oberon_context_t * ctx, oberon_expr_t * expr) +{ + gen_module_t * m; + + m = ctx -> mod -> gen_mod; + + if(expr) + { + oberon_error(ctx, "oberon_generate_return: TODO return expr"); + } + else + { + fprintf(m -> fp, " return\n"); + } +} + +static void +push_int(FILE * fp, long i) +{ + if(i == -1) + { + fprintf(fp, "iconst_m1\n"); + } + else if(i >= 0 && i <= 5) + { + fprintf(fp, "iconst_%li\n", i); + } + else if(i >= -128 && i <= 127) + { + fprintf(fp, "bipush %li\n", i); + } + else if(i >= -32768 && i <= 32767) + { + fprintf(fp, "sipush %li\n", i); + } + else if(i >= -2147483648 && i <= 2147483647) + { + fprintf(fp, "ldc %li\n", i); + } + else + { + fprintf(fp, "ldc2 %li\n", i); + } +} + +static void +push_float(FILE * fp, double f, int size) +{ + if(size <= 4) + { + if(f == 0.0) + { + fprintf(fp, "fconst_0\n"); + } + if(f == 1.0) + { + fprintf(fp, "fconst_1\n"); + } + if(f == 2.0) + { + fprintf(fp, "fconst_2\n"); + } + else + { + fprintf(fp, "ldc %lf\n", f); + } + } + else + { + if(f == 0.0) + { + fprintf(fp, "dconst_0\n"); + } + if(f == 1.0) + { + fprintf(fp, "dconst_1\n"); + } + else + { + fprintf(fp, "ldc2 %lf\n", f); + } + } +} + +static void push_expr(oberon_context_t * ctx, FILE * fp, oberon_expr_t * expr); + +static void +push_var(oberon_context_t * ctx, FILE * fp, oberon_object_t * var) +{ + if(var -> local) + { + int reg = var -> gen_var -> reg; + char prefix = get_prefix(ctx, var -> type); + fprintf(fp, "%cload %i\n", prefix, reg); + } + else + { + char * fullname = get_field_full_name(ctx, var); + char * desc = get_descriptor(ctx, var -> type); + fprintf(fp, "getstatic %s %s\n", fullname, desc); + } +} + +static void +push_item(oberon_context_t * ctx, FILE * fp, oberon_item_t * item) +{ + switch(item -> mode) + { + case MODE_VAR: + push_var(ctx, fp, item -> var); + break; + case MODE_INTEGER: + push_int(fp, item -> integer); + break; + case MODE_BOOLEAN: + push_int(fp, item -> boolean); + break; + case MODE_CALL: + oberon_error(ctx, "push_item: TODO call"); + break; + case MODE_INDEX: + oberon_error(ctx, "push_item: TODO index"); + break; + case MODE_FIELD: + oberon_error(ctx, "push_item: TODO field"); + break; + case MODE_DEREF: + oberon_error(ctx, "push_item: TODO deref"); + break; + case MODE_NIL: + fprintf(fp, "aconst_null\n"); + break; + case MODE_NEW: + oberon_error(ctx, "push_item: TODO new"); + break; + case MODE_REAL: + push_float(fp, item -> real, item -> result -> size); + break; + default: + oberon_error(ctx, "push_item: unk mode %i", item -> mode); + break; + } +} + +static void +push_operator(oberon_context_t * ctx, FILE * fp, oberon_oper_t * oper) +{ + char prefix = get_prefix(ctx, oper -> result); + switch(oper -> op) + { + case OP_UNARY_MINUS: + push_expr(ctx, fp, oper -> left); + fprintf(fp, "%cneg\n", prefix); + break; + case OP_BITWISE_NOT: + push_expr(ctx, fp, oper -> left); + push_int(fp, -1); + fprintf(fp, "%cxor\n", prefix); + break; + + case OP_ADD: + push_expr(ctx, fp, oper -> left); + push_expr(ctx, fp, oper -> right); + fprintf(fp, "%cadd\n", prefix); + break; + case OP_SUB: + push_expr(ctx, fp, oper -> left); + push_expr(ctx, fp, oper -> right); + fprintf(fp, "%csub\n", prefix); + break; + case OP_MUL: + push_expr(ctx, fp, oper -> left); + push_expr(ctx, fp, oper -> right); + fprintf(fp, "%cmul\n", prefix); + break; + case OP_DIV: + push_expr(ctx, fp, oper -> left); + push_expr(ctx, fp, oper -> right); + fprintf(fp, "%cdiv\n", prefix); + break; + case OP_MOD: + push_expr(ctx, fp, oper -> left); + push_expr(ctx, fp, oper -> right); + fprintf(fp, "%crem\n", prefix); + break; + case OP_BITWISE_AND: + push_expr(ctx, fp, oper -> left); + push_expr(ctx, fp, oper -> right); + fprintf(fp, "%cand\n", prefix); + break; + case OP_BITWISE_XOR: + push_expr(ctx, fp, oper -> left); + push_expr(ctx, fp, oper -> right); + fprintf(fp, "%cxor\n", prefix); + break; + case OP_BITWISE_OR: + push_expr(ctx, fp, oper -> left); + push_expr(ctx, fp, oper -> right); + fprintf(fp, "%cor\n", prefix); + break; + + case OP_EQ: + case OP_NEQ: + case OP_LSS: + case OP_LEQ: + case OP_GRT: + case OP_GEQ: + case OP_LOGIC_NOT: + case OP_ABS: + oberon_error(ctx, "push_oper: TODO op %i", oper -> op); + break; + default: + oberon_error(ctx, "push_oper: unk op %i", oper -> op); + break; + } +} + +static void +push_expr(oberon_context_t * ctx, FILE * fp, oberon_expr_t * expr) +{ + if(expr -> is_item) + { + push_item(ctx, fp, (oberon_item_t *) expr); + } + else + { + push_operator(ctx, fp, (oberon_oper_t *) expr); + } +} + +static void +store_expr(oberon_context_t * ctx, FILE * fp, oberon_expr_t * expr) +{ + assert(expr -> is_item); + oberon_item_t * item = (oberon_item_t *) expr; + + char prefix; + switch(item -> mode) + { + case MODE_VAR: + if(item -> var -> local) + { + int reg = item -> var -> gen_var -> reg; + prefix = get_prefix(ctx, item -> result); + fprintf(fp, "%cstore %i\n", prefix, reg); + } + else + { + char * fullname = get_field_full_name(ctx, item -> var); + char * desc = get_descriptor(ctx, item -> result); + fprintf(fp, "putstatic %s %s\n", fullname, desc); + } + break; + default: + oberon_error(ctx, "store_expr: unk mode %i", item -> mode); + break; + } +} + +void +oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst) +{ + gen_module_t * m; + m = ctx -> mod -> gen_mod; + + push_expr(ctx, m -> fp, src); + store_expr(ctx, m -> fp, dst); +} + +void +oberon_generate_code(oberon_context_t * ctx) +{ + printf("generate code\n"); +} + +void +oberon_generator_dump(oberon_context_t * ctx, char * path) +{ + printf("jit: dump code\n"); +} + +void * +oberon_generator_get_procedure(oberon_context_t * ctx, const char * name) +{ + printf("jit: get pointer to procedure %s\n", name); + return NULL; +} + +void * +oberon_generator_get_var(oberon_context_t * ctx, const char * name) +{ + printf("jit: get pointer to var %s\n", name); + return NULL; +} diff --git a/src/backends/jvm/generator-jvm.h b/src/backends/jvm/generator-jvm.h new file mode 100644 index 0000000..9357519 --- /dev/null +++ b/src/backends/jvm/generator-jvm.h @@ -0,0 +1,41 @@ +#define MAX_REGISTERS 256 + +struct gen_register_file { + struct + { + bool used; + } reg[MAX_REGISTERS]; + int max_used; +}; + +struct gen_proc_t +{ + +}; + +struct gen_type_t +{ + int rec_id; + FILE * fp; +}; + +struct gen_var_t +{ + int reg; +}; + +struct gen_block_t +{ + +}; + +struct gen_context_t +{ + gen_module_t * m; +}; + +struct gen_module_t +{ + int rec_id; + FILE * fp; +}; diff --git a/src/generator.h b/src/generator.h index 08df5c8..885b9fa 100644 --- a/src/generator.h +++ b/src/generator.h @@ -7,6 +7,7 @@ void oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type); void oberon_generator_init_record(oberon_context_t * ctx, oberon_type_t * type); void oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var); void oberon_generator_init_proc(oberon_context_t * ctx, oberon_object_t * proc); +void oberon_generator_init_module(oberon_context_t * ctx, oberon_module_t * mod); void oberon_generator_destroy_context(oberon_context_t * ctx); /* diff --git a/src/oberon-internals.h b/src/oberon-internals.h index e265a79..a6174c3 100644 --- a/src/oberon-internals.h +++ b/src/oberon-internals.h @@ -1,6 +1,7 @@ #ifndef OBERON_INTERNALS_H #define OBERON_INTERNALS_H +typedef struct gen_module_t gen_module_t; typedef struct gen_proc_t gen_proc_t; typedef struct gen_type_t gen_type_t; typedef struct gen_var_t gen_var_t; @@ -107,6 +108,8 @@ struct oberon_module_t oberon_scope_t * decl; oberon_module_t * next; + + gen_module_t * gen_mod; }; typedef const char * (*ModuleImportCallback)(const char * name); @@ -168,7 +171,7 @@ enum OP_MOD, OP_BITWISE_AND, OP_BITWISE_XOR, - OP_BITWISE_OP, + OP_BITWISE_OR, OP_LOGIC_AND, OP_LOGIC_OR, diff --git a/src/oberon.c b/src/oberon.c index d636fba..382f4f1 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -2083,6 +2083,7 @@ oberon_type(oberon_context_t * ctx, oberon_type_t ** type) oberon_type_t * rec; rec = *type; rec -> class = OBERON_TYPE_RECORD; + rec -> module = ctx -> mod; oberon_scope_t * record_scope; record_scope = oberon_open_scope(ctx); @@ -2672,6 +2673,8 @@ oberon_parse_module(oberon_context_t * ctx) oberon_assert_token(ctx, SEMICOLON); ctx -> mod -> name = name1; + oberon_generator_init_module(ctx, ctx -> mod); + if(ctx -> token == IMPORT) { oberon_import_list(ctx); diff --git a/src/test.c b/src/test.c index 1c3c8e3..53be586 100644 --- a/src/test.c +++ b/src/test.c @@ -7,40 +7,31 @@ static char source_test[] = "(* Main module *)" "MODULE Test;" - "IMPORT Out;" - "TYPE Ar = ARRAY OF ARRAY OF INTEGER;" - "VAR a : POINTER TO Ar;" + "VAR" + " x : INTEGER;" + " z : BOOLEAN;" "" - "PROCEDURE Ax(VAR x : POINTER TO Ar);" - "BEGIN" - " x[0, 0] := 777;" - "END Ax;" + "PROCEDURE Tier(a, b :INTEGER);" + "END Tier;" "" "BEGIN;" - " NEW(a, 2, 2);" - " a[0, 0] := 666;" - " Out.Open;" - " Out.Int(a[0, 0], 0);" - " Out.Ln;" - "" - " Ax(a);" -// " Out.Int(a[0, 0], 0);" -// " Out.Ln;" + " x := x + 1;" + " z := TRUE;" "END Test." ; static char source_out[] = "MODULE Out;" - "(* Interface to outer program ;) *)" - "VAR" - " Open- : PROCEDURE;" +// "(* Interface to outer program ;) *)" +// "VAR" +// " Open- : PROCEDURE;" // " Char- : PROCEDURE(ch : CHAR);" // " String- : PROCEDURE(str : ARRAY OF CHAR)" // " Int- : PROCEDURE(i, n : LONGINT);" - " Int- : PROCEDURE(i, n : INTEGER);" - " Real- : PROCEDURE(x : REAL; n : INTEGER);" +// " Int- : PROCEDURE(i, n : INTEGER);" +// " Real- : PROCEDURE(x : REAL; n : INTEGER);" // " LongReal- : PROCEDURE(x : LONGREAL; n : INTEGER);" - " Ln- : PROCEDURE;" +// " Ln- : PROCEDURE;" "END Out." ; @@ -131,11 +122,11 @@ main(int argc, char ** argv) oberon_generate_code(ctx); - init_system_modules(); +// init_system_modules(); - oberon_generator_dump(ctx, "dump.txt"); +// oberon_generator_dump(ctx, "dump.txt"); - start_module(); +// start_module(); oberon_destroy_context(ctx); return 0; diff --git a/tst.java b/tst.java new file mode 100644 index 0000000..2dae5b2 --- /dev/null +++ b/tst.java @@ -0,0 +1,4 @@ +public abstract class tst +{ + public abstract void invoke(); +} -- 2.29.2