This project presents a Perl compiler that compiles Perl into Java bytecode and runs it, providing a method to integrate Perl with Java-based ecosystems.
- Introduction
- Features and Limitations
- Target Audience
- Build Instructions
- Running the JAR File
- Debugging Tools
- Internal Modules
- Milestones
- License
This project aims to develop a Perl compiler that translates Perl code into Java bytecode and executes it on the Java Virtual Machine (JVM). It provides a platform for running Perl scripts in a JVM environment, facilitating integration between Perl and Java.
- Closures: Supports anonymous functions and lexical variable closures.
- Eval-string: Executes Perl code dynamically.
- Statements, Data Types, and Call Context: Handles common Perl statements, data types, and maintains Perl's context sensitivity.
- Java Scripting API (JSR 223): Enables Perl scripts to be executed within Java applications using the
ScriptEngine
interface.
For a detailed feature list, see the FEATURE_MATRIX.md.
- Limited Module Support: Does not support XS modules or many CPAN libraries.
- Syntax Compatibility: May not fully support advanced syntax-changing modules or esoteric Perl features.
- A Complement to Perl: This project complements Perl by enabling its integration with Java environments.
- Java Developers with Perl Knowledge: Provides a method for integrating Perl scripts into Java applications.
- Compiler and Language Enthusiasts: Offers insights into translating high-level languages into JVM bytecode.
- Experimenters and Tinkerers: A tool for experimenting with language interoperability.
-
Ensure you have Maven installed:
- You can download and install Maven from Maven's official website.
-
Compile and Package the Project:
- Run the following Maven command to compile and package the project into a shaded JAR:
mvn clean package
-
Run the JAR:
- After packaging, you can run the JAR file with:
java -jar target/perlonjava-1.0-SNAPSHOT.jar
-
Ensure you have Gradle installed:
- You can download and install Gradle from Gradle's official website.
-
Compile and Package the Project:
- Run the following Gradle command to compile and package the project into a shaded JAR:
gradle clean build
-
Run the JAR:
- After packaging, you can run the JAR file with:
java -jar target/perlonjava-1.0-SNAPSHOT.jar
- JUnit: For testing.
- ASM: For bytecode manipulation.
- ICU4J: For Unicode support.
- FASTJSON v2: For JSON support.
JDBC Database drivers can be added in two ways:
- Using the
Configure.pl
script to add the drivers to the Perl jar file:
The Configure script updates the build configuration to install the JDBC database drivers in the PerlOnJava jar file.
- Locate the driver name - for example using Maven Central search: https://search.maven.org/
- Run
./Configure.pl my-driver-name
to register the drivers - for example:
./Configure.pl aws-mysql-jdbc
- Run the usual
mvn clean package
orgradle clean build
to build with the drivers included - Run your Perl script the usual way:
java -jar target/perlonjava-1.0-SNAPSHOT.jar myscript.pl
- Using the Java classpath to load the drivers dynamically:
- Download the JDBC database driver jar file.
- Run your Perl script with the full class path including the JDBC driver:
java -cp "jdbc-drivers/h2-2.2.224.jar:target/perlonjava-1.0-SNAPSHOT.jar" org.perlonjava.Main myscript.pl
- The project uses the
maven-shade-plugin
for Maven to create a shaded JAR. - The project uses the
com.github.johnrengelman.shadow
plugin for Gradle to create a shaded JAR. - Both Maven and Gradle configurations are set to use Java 21.
-
Show Instructions:
java -jar target/perlonjava-1.0-SNAPSHOT.jar --help
-
Execute Something:
java -jar target/perlonjava-1.0-SNAPSHOT.jar -E ' print 123 '
Setting lib
path with -I
to access Perl modules is optional. Standard modules are included in the jar file.
-
Execute Emitting Debug Information:
java -jar target/perlonjava-1.0-SNAPSHOT.jar --debug -E ' print 123 '
-
Compile Only; Can Be Combined with --debug:
java -jar target/perlonjava-1.0-SNAPSHOT.jar -c -E ' print 123 '
java -jar target/perlonjava-1.0-SNAPSHOT.jar --debug -c -E ' print 123 '
-
Execute and Emit Disassembled ASM Code:
java -jar target/perlonjava-1.0-SNAPSHOT.jar --disassemble -E ' print 123 '
-
Run the Lexer Only:
java -jar target/perlonjava-1.0-SNAPSHOT.jar --tokenize -E ' print 123 '
-
Run the Parser Only:
java -jar target/perlonjava-1.0-SNAPSHOT.jar --parse -E ' print 123 '
/
├── src/
│ ├── main/
│ │ └── perl/
│ │ │ └── lib/
│ │ │ └── Perl modules (strict.pm, etc)
│ │ └── java/
│ │ └── org/
│ │ └── perlonjava/
│ │ ├── Main.java
│ │ ├── ArgumentParser.java
│ │ ├── scriptengine/
│ │ │ ├── PerlScriptEngine.java
│ │ │ └── other script engine classes
│ │ ├── astnode/
│ │ │ ├── Node.java
│ │ │ └── other AST node classes
│ │ ├── lexer/
│ │ │ ├── Lexer.java
│ │ │ └── other lexer classes
│ │ ├── parser/
│ │ │ ├── Parser.java
│ │ │ └── other parser classes
│ │ ├── perlmodule/
│ │ │ ├── Universal.java
│ │ │ └── other internalized Perl module classes
│ │ ├── operators/
│ │ | ├── OperatorHandler.java
│ │ | ├── ArithmeticOperators.java
│ │ | └── other operator handling classes
│ │ ├── io/
│ │ | ├── SocketIO.java
│ │ | └── other io classes
│ │ └── runtime/
│ │ ├── RuntimeScalar.java
│ │ └── other runtime classes
│ └── test/
│ ├── java/
│ │ └── org/
│ │ └── perlonjava/
│ │ └── PerlLanguageProviderTest.java
│ └── resources/
│ └── Perl test files
├── build.gradle
├── pom.xml
├── settings.gradle
├── examples/
│ └── Perl example files
└── misc/
└── project notes
- Lexer: Used to split the code into symbols like space, identifier, operator.
- Parser: Picks up the symbols and organizes them into an Abstract Syntax Tree (AST) of objects like block, subroutine.
- StringParser: Used to parse domain-specific languages within Perl, such as Regex and string interpolation.
- EmitterVisitor: Used to generate the bytecode for the operations within the method. It traverses the AST and generates the corresponding ASM bytecode.
- EmitterContext: Holds the current state of the Symbol Table and calling context (void, scalar, list).
- PrinterVisitor: Provides pretty-print stringification for the AST.
- EmitterMethodCreator: Used to generate the bytecode for the class. The user code is translated into a method, then the generated bytecode is loaded using a custom class loader.
- Representations of AST nodes for code blocks, variable declarations, and operations.
- Runtime: Provides the implementation of the behavior of a Perl scalar variable, Code, Array, Hash.
- ScopedSymbolTable: Manage variable names and their corresponding local variable indices.
- perlmodule: Provides ports of Perl classes implemented in Java, such as
UNIVERSAL
andSymbol
.
- The main method generates the bytecode for the program body.
- The generated method is loaded into a variable as a code reference and executed.
PerlScriptEngine
is a Java class that allows you to execute Perl scripts using the Java Scripting API (JSR 223).
For detailed information on completed and upcoming milestones, see the MILESTONES.md.
This project is licensed under the Perl Artistic License 2.0 - see the LICENSE file for details.
For more details on the relationship with the Perlito compiler, see RELATION_WITH_PERLITO_COMPILER.md.