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: The java2js transpiler supports:
- imports - imports
- primitive type casting
- static classes - static classes
- static methods - static methods
- array literals - 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. 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) ### await jdk.transpile(javaFile)
Translates a Java class and loads it. 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 returns a String with the JavaScript transpilation of the Java class
### jdk.run(jvmArgs) ### jdk.run(jvmArgs)
Runs the main method with optional JVM arguments. Runs the main method
- jvmArgs: (optional) String array of JVM arguments.
## Known limitations ## Known limitations
- not very good error reporting - 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 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 - 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> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" type="image/x-icon" href="./favicon.ico" /> <link rel="icon" type="image/x-icon" href="./favicon.ico" />
<title>java2js test</title> <title>java2js demo</title>
<style> <style>
body, body,
textarea { textarea {
@ -29,7 +29,9 @@
p { p {
width: inherit; width: inherit;
text-align: center; text-align: center;
font-size: 2vw; font-size: 3vh;
margin-top: 1vh;
margin-bottom: 1vh;
} }
#javaFile { #javaFile {
@ -55,21 +57,21 @@
placeholder="Create a Java class with a main method here..." placeholder="Create a Java class with a main method here..."
></textarea> ></textarea>
<div class="mid" onclick="location.href = 'https:\/\/github.com/quinton-ashley/java2js';"> <div class="mid" onclick="location.href = 'https:\/\/github.com/quinton-ashley/java2js';">
<img src="favicon.ico" alt="" /> <img src="favicon.ico" />
<p>j</p> <p>j</p>
<img src="favicon.ico" alt="" /> <img src="favicon.ico" />
<p>a</p> <p>a</p>
<img src="favicon.ico" alt="" /> <img src="favicon.ico" />
<p>v</p> <p>v</p>
<img src="favicon.ico" alt="" /> <img src="favicon.ico" />
<p>a</p> <p>a</p>
<img src="favicon.ico" alt="" /> <img src="favicon.ico" />
<p>2</p> <p>2</p>
<img src="favicon.ico" alt="" /> <img src="favicon.ico" />
<p>j</p> <p>j</p>
<img src="favicon.ico" alt="" /> <img src="favicon.ico" />
<p>s</p> <p>s</p>
<img src="favicon.ico" alt="" /> <img src="favicon.ico" />
</div> </div>
<textarea <textarea
id="javaConsole" id="javaConsole"

41
jdk.js
View File

@ -219,7 +219,7 @@
}); });
// cast to int, truncates the number (just removes decimal value) // 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'; let packageName = (file.match(/package\s+([^;]+)/gm) || [])[1] || 'default';
@ -265,6 +265,7 @@
await jdk.imports[`${packageName}.${className}`].load(); await jdk.imports[`${packageName}.${className}`].load();
} catch (ror) { } catch (ror) {
console.error('Failed to load class!\n' + trans); console.error('Failed to load class!\n' + trans);
System.err.println('ERROR: Failed to load class');
return; return;
} }
@ -19167,14 +19168,44 @@
return expr.escapedValue.replace(/'/g, "\\'").replace(/"/g, "'"); return expr.escapedValue.replace(/'/g, "\\'").replace(/"/g, "'");
case 'CharacterLiteral': case 'CharacterLiteral':
const char = expr.escapedValue.slice(1, -1); const char = expr.escapedValue.slice(1, -1);
// qashto: they were converting char to number here, no clue why??
if (char.length === 1) return "'" + char + "'"; if (char.length === 1) return "'" + char + "'";
else if (char.startsWith('\\u')) return parseInt(char.substring(2), 16).toString(); else if (char.startsWith('\\u')) return parseInt(char.substring(2), 16).toString();
else return unhandledNode(expr, 'Weird char: ' + char); else return unhandledNode(expr, 'Weird char: ' + char);
// return expr.escapedValue.charCodeAt(1).toString(); // equivalent to: `'z'.charCodeAt(0)`
case 'CastExpression': case 'CastExpression':
// TODO: use expr.type to convert? let exp = parseExpr(expr.expression);
return 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': case 'ConditionalExpression':
return `${parseExpr(expr.expression)} ? ${parseExpr(expr.thenExpression)} : ${parseExpr( return `${parseExpr(expr.expression)} ? ${parseExpr(expr.thenExpression)} : ${parseExpr(
expr.elseExpression expr.elseExpression

View File

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

View File

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