Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement enough of SEXP, RDSReader, and Compiler to pass tests #3

Merged
merged 10 commits into from
Jan 24, 2024
48 changes: 48 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .neoconf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"lspconfig": {
"jdtls": {
"java.configuration.runtimes": [
{
"name": "JavaSE-21",
"path": "/home/krikava/.asdf/installs/java/openjdk-21",
"default": true
}
]
}
}
}
3 changes: 3 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@
<include>pom.xml</include>
<include>README.md</include>
</includes>
<excludes>
<exclude>**/*.rds</exclude>
</excludes>
<trimTrailingWhitespace/>
<endWithNewline/>
</format>
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.prlprg.rds.RDSReader;
import org.prlprg.sexp.SEXP;
import org.prlprg.util.IO;

public class Main {

public static void main(String[] args) throws Exception {
new Main().doMain(args);
}

private void doMain(String[] args) throws Exception {
compile(args[0]);
}

private void compile(String file) throws IOException {
try (var input = new FileInputStream(file)) {
compile(input);
}
}

private void compile(InputStream input) throws IOException {
compile(RDSReader.readStream(IO.maybeDecompress(input)));
}

private void compile(SEXP sexp) {
System.out.println(sexp);
}
}
8 changes: 8 additions & 0 deletions src/main/java/org/prlprg/RPlatform.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.prlprg;

public final class RPlatform {
public static final int INT_MAX = ~(1 << 31);

private RPlatform() {
}
}
70 changes: 66 additions & 4 deletions src/main/java/org/prlprg/bc/Bc.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,77 @@
package org.prlprg.bc;

import com.google.common.collect.ImmutableList;
import com.google.common.primitives.ImmutableIntArray;
import org.prlprg.sexp.SEXP;

// TODO: Remove stub with Sexp from branch `filip`
class Sexp {}
import java.util.*;

/** A complete R bytecode, consisting of a version, array of instructions and associated data, and constants. */
public record Bc(BcCode code, ImmutableList<Sexp> constants) {
public record Bc(BcCode code, ConstPool consts) {
/**
* The only version of R bytecodes we support, which is also the latest version.
* The bytecode's version is denoted by the first integer in its code.
*/
static int R_BC_VERSION = 13;
public static final int R_BC_VERSION = 12;

/** Create from the raw GNU-R representation, bytecodes not including the initial version number. */
public static Bc fromRaw(ImmutableIntArray bytecodes, List<SEXP> consts) throws BcFromRawException {
var poolAndMakeIdx = ConstPool.fromRaw(consts);
var pool = poolAndMakeIdx.a();
var makePoolIdx = poolAndMakeIdx.b();
try {
return new Bc(BcCode.fromRaw(bytecodes, makePoolIdx), pool);
} catch (BcFromRawException e) {
throw new BcFromRawException("malformed bytecode\nConstants: " + pool, e);
}
}

@Override
public String toString() {
return code() + "\n" + consts;
}

/** Equivalent to `CodeBuffer` in other projects */
public static class Builder {
private final BcCode.Builder code = new BcCode.Builder();
private final ConstPool.Builder consts = new ConstPool.Builder();

/**
* Append a constant and return its index.
*/
public <S extends SEXP> ConstPool.TypedIdx<S> addConst(S c) {
return consts.add(c);
}

/**
* Append an instruction.
*/
public void addInstr(BcInstr instr) {
code.add(instr);
}

/**
* Append a collection of constants and return its index.
*/
public <S extends SEXP> ImmutableList<ConstPool.TypedIdx<S>> addAllConsts(Collection<? extends S> c) {
return consts.addAll(c);
}

/**
* Append instructions.
*/
public void addAllInstrs(Collection<? extends BcInstr> c) {
code.addAll(c);
}

/**
* Finish building the bytecode.
*
* @return The bytecode.
*/
public Bc build() {
return new Bc(code.build(), consts.build());
}
}

}
37 changes: 36 additions & 1 deletion src/main/java/org/prlprg/bc/BcCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.google.common.collect.ForwardingList;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.ImmutableIntArray;
import com.google.errorprone.annotations.CanIgnoreReturnValue;

import javax.annotation.concurrent.Immutable;
import java.util.Collection;
Expand All @@ -24,6 +26,37 @@ protected List<BcInstr> delegate() {
return instrs;
}

/** Create from the raw GNU-R representation, not including the initial version number.
*
* @param makePoolIdx A function to create pool indices from raw integers
*/
static BcCode fromRaw(ImmutableIntArray bytecodes, ConstPool.MakeIdx makePoolIdx)
throws BcFromRawException {
var builder = new Builder();
int i = 0;
while (i < bytecodes.length()) {
try {
var instrAndI = BcInstrs.fromRaw(bytecodes, i, makePoolIdx);
builder.add(instrAndI.a());
i = instrAndI.b();
} catch (BcFromRawException e) {
throw new BcFromRawException(
"malformed bytecode at " + i + "\nBytecode up to this point: " + builder.build(),
e);
}
}
return builder.build();
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder("=== CODE ===");
for (BcInstr instr : instrs) {
sb.append("\n").append(instr);
}
return sb.toString();
}

/**
* A builder class for creating BcArray instances.
* <p>
Expand All @@ -41,6 +74,7 @@ public Builder() {
/**
* Append an instruction.
*/
@CanIgnoreReturnValue
public Builder add(BcInstr instr) {
builder.add(instr);
return this;
Expand All @@ -49,13 +83,14 @@ public Builder add(BcInstr instr) {
/**
* Append instructions.
*/
@CanIgnoreReturnValue
public Builder addAll(Collection<? extends BcInstr> c) {
builder.addAll(c);
return this;
}

/**
* Build the array.
* Finish building the array.
*
* @return The array.
*/
Expand Down
9 changes: 0 additions & 9 deletions src/main/java/org/prlprg/bc/BcData.java

This file was deleted.

11 changes: 11 additions & 0 deletions src/main/java/org/prlprg/bc/BcFromRawException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.prlprg.bc;

public class BcFromRawException extends RuntimeException {
public BcFromRawException(String message) {
super(message);
}

public BcFromRawException(String message, Throwable cause) {
super(message, cause);
}
}
Loading
Loading