1+ import { compileFromSource , typeCheck } from 'java-slang' ;
2+ import { BinaryWriter } from 'java-slang/dist/compiler/binary-writer' ;
13import setupJVM , { parseBin } from 'java-slang/dist/jvm' ;
24import { createModuleProxy , loadCachedFiles } from 'java-slang/dist/jvm/utils/integration' ;
35import { Context } from 'js-slang' ;
@@ -9,6 +11,33 @@ import DisplayBufferService from './DisplayBufferService';
911export async function javaRun ( javaCode : string , context : Context ) {
1012 let compiled = { } ;
1113
14+ const stderr = ( type : 'TypeCheck' | 'Compile' | 'Runtime' , msg : string ) => {
15+ context . errors . push ( {
16+ type : type as any ,
17+ severity : 'Error' as any ,
18+ location : { start : { line : - 1 , column : - 1 } , end : { line : - 1 , column : - 1 } } ,
19+ explain : ( ) => msg ,
20+ elaborate : ( ) => msg
21+ } ) ;
22+ } ;
23+
24+ const typeCheckResult = typeCheck ( javaCode ) ;
25+ if ( typeCheckResult . hasTypeErrors ) {
26+ const typeErrMsg = typeCheckResult . errorMsgs . join ( '\n' ) ;
27+ stderr ( 'TypeCheck' , typeErrMsg ) ;
28+ return Promise . resolve ( { status : 'error' } ) ;
29+ }
30+
31+ try {
32+ const classFile = compileFromSource ( javaCode ) ;
33+ compiled = {
34+ 'Main.class' : Buffer . from ( new BinaryWriter ( ) . generateBinary ( classFile ) ) . toString ( 'base64' )
35+ } ;
36+ } catch ( e ) {
37+ stderr ( 'Compile' , e ) ;
38+ return Promise . resolve ( { status : 'error' } ) ;
39+ }
40+
1241 let files = { } ;
1342 let buffer : string [ ] = [ ] ;
1443
@@ -46,6 +75,7 @@ export async function javaRun(javaCode: string, context: Context) {
4675 }
4776 return parseBin ( new DataView ( bytes . buffer ) ) ;
4877 } ;
78+
4979 const loadNatives = async ( path : string ) => {
5080 // dynamic load modules
5181 if ( path . startsWith ( 'modules' ) ) {
@@ -56,6 +86,7 @@ export async function javaRun(javaCode: string, context: Context) {
5686 }
5787 return await import ( `java-slang/dist/jvm/stdlib/${ path } .js` ) ;
5888 } ;
89+
5990 const stdout = ( str : string ) => {
6091 if ( str . endsWith ( '\n' ) ) {
6192 buffer . push ( str ) ;
@@ -67,33 +98,6 @@ export async function javaRun(javaCode: string, context: Context) {
6798 buffer . push ( str ) ;
6899 }
69100 } ;
70- const stderr = ( msg : string ) => {
71- context . errors . push ( {
72- type : 'Runtime' as any ,
73- severity : 'Error' as any ,
74- location : {
75- start : {
76- line : - 1 ,
77- column : - 1
78- } ,
79- end : {
80- line : - 1 ,
81- column : - 1
82- }
83- } ,
84- explain : ( ) => msg ,
85- elaborate : ( ) => msg
86- } ) ;
87- } ;
88-
89- // FIXME: Remove when the compiler is working
90- try {
91- const json = JSON . parse ( javaCode ) ;
92- compiled = json ;
93- } catch ( e ) {
94- stderr ( e ) ;
95- return Promise . resolve ( { status : 'error' } ) ;
96- }
97101
98102 // load cached classfiles from IndexedDB
99103 return loadCachedFiles ( ( ) =>
@@ -119,12 +123,20 @@ export async function javaRun(javaCode: string, context: Context) {
119123 readFileSync : readClassFiles ,
120124 readFile : loadNatives ,
121125 stdout,
122- stderr,
126+ stderr : ( msg : string ) => stderr ( 'Runtime' , msg ) ,
123127 onFinish : ( ) => {
124128 resolve (
125129 context . errors . length
126130 ? { status : 'error' }
127- : { status : 'finished' , context, value : '' }
131+ : {
132+ status : 'finished' ,
133+ context,
134+ value : new ( class {
135+ toString ( ) {
136+ return ' ' ;
137+ }
138+ } ) ( )
139+ }
128140 ) ;
129141 }
130142 } ,
0 commit comments