1
0
mirror of https://github.com/quinton-ashley/java2js synced 2024-12-29 10:11:54 +01:00
This commit is contained in:
Quinton Ashley 2022-02-23 11:26:23 -05:00
parent 0d4f10034f
commit 2b9cc5bf44
5 changed files with 56 additions and 21 deletions

View File

@ -40,6 +40,7 @@ java2js can translate simple Java programs to JavaScript and runs them using a J
The java2js transpiler supports:
- imports
- primitive type casting
- static classes
- static methods
- array literals
@ -54,26 +55,26 @@ The java2js transpiler supports:
This function imports the standard java.lang classes into the global scope. You must use it before translating or running files.
- root (optional) path to the JS JDK folder, by default it is `./jdk` (the java2js JS JDK), for online use on codepen or similar code sharing sites you can use this link as the root path: 'https://unpkg.com/java2js/jdk'
- root: (optional) path to the JS JDK folder, by default it is `./jdk` (the java2js JS JDK), for online use on codepen or similar code sharing sites you can use this link as the root path: 'https://unpkg.com/java2js/jdk'
### await jdk.transpile(javaFile)
Translates a Java class and loads it.
- javaFile is a String with a Java class in it
- javaFile: a String with a Java class in it
returns a String with the JavaScript transpilation of the Java class
### jdk.run(jvmArgs)
Runs the main method with optional JVM arguments.
Runs the main method
- jvmArgs: (optional) String array of JVM arguments.
## Known limitations
- not very good error reporting
- casting to int (truncation) requires parenthesis around the number being cast `int x = (int) (Math.random() * 100);`
- no support for method overloading, though a workaround might be possible by making a function with the og name route to each of the variations of the overloaded function
- no support for private/public methods yet, though this could be done since they are included in modern JavaScript classes

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/x-icon" href="./favicon.ico" />
<title>java2js test</title>
<title>java2js demo</title>
<style>
body,
textarea {
@ -29,7 +29,9 @@
p {
width: inherit;
text-align: center;
font-size: 2vw;
font-size: 3vh;
margin-top: 1vh;
margin-bottom: 1vh;
}
#javaFile {
@ -55,21 +57,21 @@
placeholder="Create a Java class with a main method here..."
></textarea>
<div class="mid" onclick="location.href = 'https:\/\/github.com/quinton-ashley/java2js';">
<img src="favicon.ico" alt="" />
<img src="favicon.ico" />
<p>j</p>
<img src="favicon.ico" alt="" />
<img src="favicon.ico" />
<p>a</p>
<img src="favicon.ico" alt="" />
<img src="favicon.ico" />
<p>v</p>
<img src="favicon.ico" alt="" />
<img src="favicon.ico" />
<p>a</p>
<img src="favicon.ico" alt="" />
<img src="favicon.ico" />
<p>2</p>
<img src="favicon.ico" alt="" />
<img src="favicon.ico" />
<p>j</p>
<img src="favicon.ico" alt="" />
<img src="favicon.ico" />
<p>s</p>
<img src="favicon.ico" alt="" />
<img src="favicon.ico" />
</div>
<textarea
id="javaConsole"

41
jdk.js
View File

@ -219,7 +219,7 @@
});
// cast to int, truncates the number (just removes decimal value)
file = file.replace(/\(int\)\s*/gm, 'Math.floor');
// file = file.replace(/\(int\)\s*/gm, 'Math.floor');
let packageName = (file.match(/package\s+([^;]+)/gm) || [])[1] || 'default';
@ -265,6 +265,7 @@
await jdk.imports[`${packageName}.${className}`].load();
} catch (ror) {
console.error('Failed to load class!\n' + trans);
System.err.println('ERROR: Failed to load class');
return;
}
@ -19167,14 +19168,44 @@
return expr.escapedValue.replace(/'/g, "\\'").replace(/"/g, "'");
case 'CharacterLiteral':
const char = expr.escapedValue.slice(1, -1);
// qashto: they were converting char to number here, no clue why??
if (char.length === 1) return "'" + char + "'";
else if (char.startsWith('\\u')) return parseInt(char.substring(2), 16).toString();
else return unhandledNode(expr, 'Weird char: ' + char);
// return expr.escapedValue.charCodeAt(1).toString(); // equivalent to: `'z'.charCodeAt(0)`
case 'CastExpression':
// TODO: use expr.type to convert?
return parseExpr(expr.expression);
let exp = parseExpr(expr.expression);
let type;
if (expr.expression.node == 'SimpleName') {
type = variableTypes[expr.expression.identifier];
} else if (expr.expression.node == 'CharacterLiteral') {
type = 'char';
} else if (expr.expression.node == 'NumberLiteral') {
type = 'double';
} else if (expr.expression.node == 'StringLiteral') {
type = 'String';
}
let castError = false;
let cast = expr.type.primitiveTypeCode;
if (cast == 'int') {
// if cast to int
if (type == 'char') {
exp += '.charCodeAt(0)';
} else if (/(double|float|short|long)/.test(type)) {
exp = 'Math.floor(' + exp + ')';
} else {
castError = true;
}
} else if (cast == 'char') {
if (/(double|float|short|long)/.test(type)) {
exp = 'String.fromCharCode(' + exp + ')';
} else {
castError = true;
}
}
if (castError) {
System.err.println(`error: incompatible types: ${type} cannot be converted to ${cast}: ${exp}`);
return '';
}
return exp;
case 'ConditionalExpression':
return `${parseExpr(expr.expression)} ? ${parseExpr(expr.thenExpression)} : ${parseExpr(
expr.elseExpression

View File

@ -7,6 +7,7 @@ jdk.imports['java.lang.System'].load = async () => {
System.in = new InputStream();
System.out = new PrintStream();
System.err = System.out;
System.out.onPrint = (length) => {
System.in.mark += length;
};

View File

@ -1,6 +1,6 @@
{
"name": "java2js",
"version": "1.2.0",
"version": "1.2.1",
"description": "Converts Java to JavaScript and runs it with a JS JDK",
"main": "jdk.js",
"scripts": {