Skip to content

Commit

Permalink
Bump version to 2.0.0. Refactoring to enable transpiling to JS using …
Browse files Browse the repository at this point in the history
…TeamVM.

- Move reflection using code to the main class.
- Replace direct IO stream usage in the interpreter with interfaces that can be easily implemented using streams, queues etc. **BREAKS COMPATIBILITY** with previous external subprogram libraries.
- Build system improvements.
  • Loading branch information
cyberpython committed Dec 28, 2024
1 parent 8cf8730 commit a9a6bc4
Show file tree
Hide file tree
Showing 21 changed files with 285 additions and 233 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/gradle-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
# The USERNAME and TOKEN need to correspond to the credentials environment variables used in
# the publishing section of your build.gradle
- name: Publish to GitHub Packages
run: ./gradlew publish
run: ./gradlew publishGlossaPublicationToGitHubPackagesRepository
env:
USERNAME: ${{ github.actor }}
TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ devdoc
git-hooks
.classpath
.project
gradle.properties
20 changes: 18 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ dependencies {
}

group = 'com.gmigdos.glossa'
version = '1.0.9'
version = '2.0.0'

application {
// Define the main class for the application.
Expand All @@ -55,6 +55,7 @@ compileJava.dependsOn writeVersionProperties

publishing {
repositories {

maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/cyberpython/glossa-interpreter")
Expand All @@ -63,9 +64,24 @@ publishing {
password = project.findProperty("gpr.key") ?: System.getenv("TOKEN")
}
}

maven {
name = "Forgejo"
allowInsecureProtocol = true
url = uri("${project.findProperty("forgejo.base_url")}/api/packages/${project.findProperty("forgejo.user")}/maven")

credentials(HttpHeaderCredentials) {
name = "Authorization"
value = "token ${project.findProperty('forgejo.token')}"
}

authentication {
header(HttpHeaderAuthentication)
}
}
}
publications {
gpr(MavenPublication) {
glossa(MavenPublication) {
from(components.java)
artifactId = 'glossa-interpreter'
}
Expand Down
45 changes: 8 additions & 37 deletions src/main/antlr/ASTInterpreter.g
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,11 @@ import glossa.messages.Messages;
import glossa.builtinfunctions.BuiltinFunctions;
import glossa.statictypeanalysis.scopetable.*;
import glossa.statictypeanalysis.scopetable.scopes.*;
import glossa.interpreter.io.IInputProvider;
import glossa.interpreter.io.IOutputPrinter;
import glossa.interpreter.symboltable.*;
import glossa.interpreter.symboltable.symbols.*;
import glossa.utils.Point;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayDeque;
import java.math.BigInteger;
import java.math.BigDecimal;
Expand All @@ -99,10 +97,9 @@ import java.util.Iterator;

private SymbolTable currentSymbolTable;

private PrintStream out;
private PrintStream err;
private InputStream in;
private BufferedReader reader;
private IOutputPrinter out;
private IOutputPrinter err;
private IInputProvider reader;
private boolean echoInput;

List<ASTInterpreterListener> listeners;
Expand All @@ -111,7 +108,7 @@ import java.util.Iterator;
private boolean stop;
private boolean finished;

public void init(ScopeTable s, PrintStream out, PrintStream err, InputStream in, boolean echoInput){
public void init(ScopeTable s, IOutputPrinter out, IOutputPrinter err, IInputProvider in, boolean echoInput){
input.reset();

this.stack = new ArrayDeque<SymbolTable>();
Expand All @@ -123,8 +120,7 @@ import java.util.Iterator;

this.out = out;
this.err = err;
this.in = in;
this.reader = new BufferedReader(new InputStreamReader(in));
this.reader = in;
this.echoInput = echoInput;
}

Expand Down Expand Up @@ -215,31 +211,6 @@ import java.util.Iterator;
return this.stack;
}

public void setOutputStream(PrintStream out){
this.out = out;
}

public PrintStream getOutputStream(){
return this.out;
}

public void setErrorStream(PrintStream err){
this.err = err;
}

public PrintStream getErrorStream(){
return this.err;
}

public void setInputStream(InputStream in){
this.in = in;
this.reader = new BufferedReader(new InputStreamReader(in));
}

public InputStream getInputStream(){
return this.in;
}


public void pauseExecution(int line, boolean wasPrintStatement){
this.halt=true;
Expand Down Expand Up @@ -603,7 +574,7 @@ stm : ^( PRINT {
input.seek(resumeAt);
}else{
try{
ExternalSubprograms.getInstance().callProcedure($ID.text, $paramsList.parameters, out, err, in);
ExternalSubprograms.getInstance().callProcedure($ID.text, $paramsList.parameters, out, err, reader);
}catch(ExternalProcedureNotFoundException e){
throw new RuntimeException(String.format(RuntimeMessages.STR_RUNTIME_ERROR_CALL_TO_UNNKOWN_PROCEDURE, $ID.text));
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/antlr/StaticTypeAnalyzer.g
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ import glossa.utils.Point;
private MessageLog msgLog;

private ScopeTable scopeTable;
private Scope currentScope;
private Scope currentScope;
private boolean inConstantDeclaration = false;
private boolean inVariableDeclaration = false;
private boolean inSubprogram = false;
Expand Down
97 changes: 96 additions & 1 deletion src/main/java/glossa/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,21 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import glossa.external.ExternalFunction;
import glossa.external.ExternalProcedure;
import glossa.external.ExternalSubprograms;
import glossa.ui.cli.CLI;
import picocli.CommandLine;
import picocli.CommandLine.Option;
Expand Down Expand Up @@ -70,6 +82,87 @@ static class CmdLineOpts {

}

private static void loadExternalSubprograms() {

File lookupDir = new File(System.getProperty("user.home") + System.getProperty("file.separator") + "ΒΙΒΛΙΟΘΗΚΗ_ΓΛΩΣΣΑΣ");
if (lookupDir.isDirectory()) {

File[] jarFiles = lookupDir.listFiles(
file -> file.getAbsolutePath().toLowerCase().endsWith(".jar")
);

URL[] jarURLs = new URL[jarFiles.length];

for (int i = 0; i < jarURLs.length; i++) {
try {
jarURLs[i] = jarFiles[i].toURI().toURL();
} catch (MalformedURLException mue) {
//ignore jarfile
}
}

ClassLoader loader = URLClassLoader.newInstance(jarURLs);

for (File file : jarFiles) {
try {
try (JarFile jf = new JarFile(file)) {
Enumeration<JarEntry> entries = jf.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.toLowerCase().endsWith(".class")) {
name = name.replaceAll("\\/", ".").substring(0, name.length() - 6);
try {
Class clazz = loader.loadClass(name);
Class[] ifaces = clazz.getInterfaces();
boolean foundExternalFunc = false;
boolean foundExternalProc = false;
for (int i = 0; i < ifaces.length; i++) {
Class iface = ifaces[i];
if (iface.equals(ExternalFunction.class)) {
foundExternalFunc = true;
break;
}
if (iface.equals(ExternalProcedure.class)) {
foundExternalProc = true;
break;
}
}
if (foundExternalFunc) {
Class<? extends ExternalFunction> externalFuncClass = clazz.asSubclass(ExternalFunction.class);
Constructor<? extends ExternalFunction> ctor = externalFuncClass.getConstructor();
ExternalFunction f = ctor.newInstance();
ExternalSubprograms.getInstance().addFunction(f);
} else if (foundExternalProc) {
Class<? extends ExternalProcedure> externalProcClass = clazz.asSubclass(ExternalProcedure.class);
Constructor<? extends ExternalProcedure> ctor = externalProcClass.getConstructor();
ExternalProcedure p = ctor.newInstance();
ExternalSubprograms.getInstance().addProcedure(p);
}
} catch (ClassNotFoundException cnfe) {
//ignore
} catch (NoSuchMethodException nsme) {
//ignore
} catch (InstantiationException ie) {
//ignore
} catch (IllegalAccessException iae) {
//ignore
} catch (InvocationTargetException ite) {
//ignore
}
}
}
} catch (SecurityException | IllegalArgumentException e) {
e.printStackTrace();
}
} catch (IOException ioe) {
}

}

}
}

/**
* @param args the command line arguments
*/
Expand All @@ -89,6 +182,9 @@ public static void main(String[] args) {
}
} else {
if ((opts.sourceFile != null) && opts.sourceFile.isFile()) {

loadExternalSubprograms();

CLI cli = new CLI(opts.interactive);
if (opts.inputFile != null) {
cli.execute(opts.sourceFile, opts.inputFile);
Expand All @@ -106,7 +202,6 @@ public static void main(String[] args) {
System.out.println(WRONG_USAGE);
System.out.println();
printHelpMessage(System.out);
// pe.printStackTrace();
}

}
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/glossa/external/ExternalFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@

package glossa.external;

import glossa.types.Type;
import java.io.PrintStream;
import java.util.List;

import glossa.interpreter.io.IOutputPrinter;
import glossa.types.Type;

/**
*
* @author cyberpython
Expand All @@ -53,5 +54,5 @@ public interface ExternalFunction extends ExternalSubProgram{
* Boolean for boolean
* String for string
*/
public Object execute(List<Object> parameters, PrintStream err);
public Object execute(List<Object> parameters, IOutputPrinter err);
}
7 changes: 4 additions & 3 deletions src/main/java/glossa/external/ExternalProcedure.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@

package glossa.external;

import java.io.InputStream;
import java.io.PrintStream;
import java.util.List;

import glossa.interpreter.io.IInputProvider;
import glossa.interpreter.io.IOutputPrinter;

/**
*
* @author cyberpython
Expand All @@ -50,5 +51,5 @@ public interface ExternalProcedure extends ExternalSubProgram{
* @param in The default input stream (usually System.in)
*
*/
public void execute(List<Object> parameters, PrintStream out, PrintStream err, InputStream in);
public void execute(List<Object> parameters, IOutputPrinter out, IOutputPrinter err, IInputProvider in);
}
Loading

0 comments on commit a9a6bc4

Please sign in to comment.