summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9e6d0f7)
raw | patch | inline | side by side (parent: 9e6d0f7)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Tue, 25 Jul 2017 17:51:11 +0000 (20:51 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Tue, 25 Jul 2017 17:51:11 +0000 (20:51 +0300) |
13 files changed:
.gitignore | patch | blob | history | |
Launcher.java | [new file with mode: 0644] | patch | blob |
jvm_test.sh | [new file with mode: 0755] | patch | blob |
make.sh | patch | blob | history | |
src/backends/dummy/generator-dummy.c | [moved from src/backends/dummy/generator-libgccjit.c with 98% similarity] | patch | blob | history |
src/backends/dummy/generator-dummy.h | [moved from src/backends/dummy/generator-libgccjit.h with 100% similarity] | patch | blob | history |
src/backends/jvm/generator-jvm.c | [new file with mode: 0644] | patch | blob |
src/backends/jvm/generator-jvm.h | [new file with mode: 0644] | patch | blob |
src/generator.h | patch | blob | history | |
src/oberon-internals.h | patch | blob | history | |
src/oberon.c | patch | blob | history | |
src/test.c | patch | blob | history | |
tst.java | [new file with mode: 0644] | patch | blob |
diff --git a/.gitignore b/.gitignore
index bbbc7ed94402c43a37c1fddd5e9bd0d0b86d1a1f..6cd2ab3a081c657a4b4dd104c2c87a7eb72f44b0 100644 (file)
--- a/.gitignore
+++ b/.gitignore
*.out
dump.txt
+*.j
+*.class
diff --git a/Launcher.java b/Launcher.java
--- /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
--- /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...
+
index 9e4b2551b852601b51ca3a7840b8c90d7d226739..561238eda9798416c20e73fb5c80f65c3312c8f5 100755 (executable)
--- a/make.sh
+++ b/make.sh
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 <backend>"
- echo "list of backends: dummy libgccjit"
+ echo "list of backends: dummy jvm libgccjit"
esac
similarity index 98%
rename from src/backends/dummy/generator-libgccjit.c
rename to src/backends/dummy/generator-dummy.c
index e9b26b514b3bcf192b612b9ffdaeb4a8038c07b1..fc709a075baf48e2bb141e671a7059daa4a9d084 100644 (file)
rename from src/backends/dummy/generator-libgccjit.c
rename to src/backends/dummy/generator-dummy.c
index e9b26b514b3bcf192b612b9ffdaeb4a8038c07b1..fc709a075baf48e2bb141e671a7059daa4a9d084 100644 (file)
#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)
similarity index 100%
rename from src/backends/dummy/generator-libgccjit.h
rename to src/backends/dummy/generator-dummy.h
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
--- /dev/null
@@ -0,0 +1,744 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <assert.h>
+
+#include <gc.h>
+
+#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 <init>()V\n");
+ fprintf(fp, " aload_0\n");
+ fprintf(fp, " invokespecial java/lang/Object/<init>()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 <init>()V\n");
+ fprintf(fp, " aload_0\n");
+ fprintf(fp, " invokespecial java/lang/Object/<init>()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 <init>()V\n");
+ fprintf(m -> fp, " aload_0\n");
+ fprintf(m -> fp, " invokespecial java/lang/Object/<init>()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
--- /dev/null
@@ -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 08df5c892abb414e4f376e6829a697554a5b6398..885b9faca57509a697088c697353a5808e3b7296 100644 (file)
--- a/src/generator.h
+++ b/src/generator.h
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 e265a79cc1b39aff1e2a6afa7d3b51913853c756..a6174c36094ea7e23fb510bfc65036953917c743 100644 (file)
--- a/src/oberon-internals.h
+++ b/src/oberon-internals.h
#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;
oberon_scope_t * decl;
oberon_module_t * next;
+
+ gen_module_t * gen_mod;
};
typedef const char * (*ModuleImportCallback)(const char * name);
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 d636fba6b19d253c65a167420a25f21547bef892..382f4f182b2e98ca1032a7f720cc575e58ae9fc5 100644 (file)
--- a/src/oberon.c
+++ b/src/oberon.c
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);
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 1c3c8e39347533eb9db1d0b2e289f0348f77b693..53be5869213c0d3ee4a5e3e7fcd30639cf82ea59 100644 (file)
--- a/src/test.c
+++ b/src/test.c
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."
;
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
--- /dev/null
+++ b/tst.java
@@ -0,0 +1,4 @@
+public abstract class tst
+{
+ public abstract void invoke();
+}