Skip to content

Commit

Permalink
GroovyEngine: added support for function and and class implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed Jan 27, 2020
1 parent 104ba60 commit f445ed8
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 30 deletions.
26 changes: 13 additions & 13 deletions builtins/src/main/java/org/jline/builtins/ConsoleEngineImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public boolean hasCommand(String name) {
public boolean hasAlias(String name) {
return aliases.containsKey(name);
}

@Override
public String getAlias(String name) {
return aliases.getOrDefault(name, null);
Expand Down Expand Up @@ -188,11 +188,11 @@ public Completers.SystemCompleter compileCompleters() {
out.addAliases(aliasCommand);
return out;
}

private Set<String> variables() {
return engine.find().keySet();
return engine.find().keySet();
}

@Override
public List<Completer> scriptCompleters() {
List<Completer> out = new ArrayList<>();
Expand All @@ -204,7 +204,7 @@ public List<Completer> scriptCompleters() {
));
return out;
}

@SuppressWarnings("unchecked")
@Override
public List<String> scripts() {
Expand All @@ -226,7 +226,7 @@ public List<String> scripts() {
out.add(name.substring(0, name.lastIndexOf(".")));
}
} catch (Exception e) {
println(e);
println(e);
}
return out;
}
Expand Down Expand Up @@ -297,9 +297,9 @@ private List<String> scriptExtensions() {
List<String> extensions = new ArrayList<>();
extensions.addAll(engine.getExtensions());
extensions.add(scriptExtension);
return extensions;
return extensions;
}

private class ScriptFile {
private File script;
private String extension = "";
Expand Down Expand Up @@ -504,7 +504,7 @@ public Object execute(ParsedLine pl) throws Exception {
if (file.execute()) {
out = file.getResult();
} else {
String line = pl.line();
String line = pl.line().trim();
if (isCodeBlock(line)) {
StringBuilder sb = new StringBuilder();
for (String s: line.split("\n|\n\r")) {
Expand Down Expand Up @@ -791,7 +791,7 @@ private Object aliascmd(Builtins.CommandInput input) {
try {
List<String> args = opt.args();
if (args.isEmpty()) {
out = aliases;
out = aliases;
} else if (args.size() == 1) {
out = aliases.getOrDefault(args.get(0), null);
} else {
Expand Down Expand Up @@ -820,12 +820,12 @@ private Object unalias(Builtins.CommandInput input) {
for (String a : opt.args()) {
if (aliases.containsKey(a)) {
aliases.remove(a);
}
}
}
} catch (Exception e) {
exception = e;
} finally {
engine.persist(aliasFile, aliases);
engine.persist(aliasFile, aliases);
}
return out;
}
Expand Down Expand Up @@ -877,7 +877,7 @@ private List<Completer> prntCompleter(String command) {

private static class AliasValueCompleter implements Completer {
private final Map<String,String> aliases;

public AliasValueCompleter(Map<String,String> aliases) {
this.aliases = aliases;
}
Expand Down
30 changes: 15 additions & 15 deletions builtins/src/main/java/org/jline/builtins/SystemRegistryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public enum Command {EXIT
private final Map<Command,CommandMethods> commandExecute = new HashMap<>();
private Map<String, List<String>> commandInfos = new HashMap<>();
private Exception exception;

public SystemRegistryImpl(Parser parser, Terminal terminal, ConfigurationPath configPath) {
this.parser = parser;
this.terminal = terminal;
Expand Down Expand Up @@ -109,7 +109,7 @@ public Set<String> commandNames() {
out.addAll(localCommandNames());
return out;
}

private Set<String> localCommandNames() {
return nameCommand.keySet();
}
Expand Down Expand Up @@ -173,7 +173,7 @@ public List<String> commandInfo(String command) {
public boolean hasCommand(String command) {
return registryId(command) > -1 || isLocalCommand(command);
}

private boolean isLocalCommand(String command) {
return nameCommand.containsKey(command) || aliasCommand.containsKey(command);
}
Expand All @@ -190,17 +190,17 @@ public Completers.SystemCompleter compileCompleters() {
out.compile();
return out;
}

@Override
public Completer completer() {
List<Completer> completers = new ArrayList<>();
List<Completer> completers = new ArrayList<>();
completers.add(compileCompleters());
if (consoleId > -1) {
completers.addAll(consoleEngine().scriptCompleters());
}
return new AggregateCompleter(completers);
}

private Widgets.CmdDesc localCommandDescription(String command) {
if (!isLocalCommand(command)) {
throw new IllegalArgumentException();
Expand All @@ -213,7 +213,7 @@ private Widgets.CmdDesc localCommandDescription(String command) {
} catch (Exception e) {
consoleEngine().println(e);
}
return null;
return null;
}

@Override
Expand Down Expand Up @@ -245,7 +245,7 @@ public Widgets.CmdDesc commandDescription(Widgets.CmdLine line) {
}
return out;
}

@Override
public Object invoke(String command, Object... args) throws Exception {
Object out = null;
Expand All @@ -260,7 +260,7 @@ public Object invoke(String command, Object... args) throws Exception {
}
return out;
}

@Override
public Object execute(String command, String[] args) throws Exception {
Object out = null;
Expand All @@ -272,7 +272,7 @@ public Object execute(String command, String[] args) throws Exception {
}
return out;
}

public Object localExecute(String command, String[] args) throws Exception {
if (!isLocalCommand(command)) {
throw new IllegalArgumentException();
Expand All @@ -287,7 +287,7 @@ public Object localExecute(String command, String[] args) throws Exception {
@Override
public Object execute(String line) throws Exception {
ParsedLine pl = parser.parse(line, 0, ParseContext.ACCEPT_LINE);
if (pl.line().isEmpty() || pl.line().startsWith("#")) {
if (pl.line().isEmpty() || pl.line().trim().startsWith("#")) {
return null;
}
String cmd = ConsoleEngine.plainCommand(Parser.getCommand(pl.word()));
Expand Down Expand Up @@ -381,7 +381,7 @@ private void printCommands(Collection<String> commands, int max) {
private String doCommandInfo(List<String> info) {
return info.size() > 0 ? info.get(0) : " ";
}

private boolean isInArgs(List<String> args, String name) {
return args.isEmpty() || args.contains(name);
}
Expand Down Expand Up @@ -448,11 +448,11 @@ private Object help(Builtins.CommandInput input) {
}
} else {
printCommands(consoleEngine().scripts(), max);
}
}
}
return null;
}

private Object exit(Builtins.CommandInput input) {
final String[] usage = {
"exit - exit from app/script",
Expand All @@ -479,7 +479,7 @@ private List<OptDesc> commandOptions(String command) {
}
return null;
}

private List<String> registryNames() {
List<String> out = new ArrayList<>();
out.add("Builtins");
Expand Down
67 changes: 65 additions & 2 deletions groovy/src/main/java/org/jline/script/GroovyEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import java.io.File;
import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jline.groovy.Utils;
import org.jline.reader.ScriptEngine;
Expand All @@ -30,10 +32,17 @@
* @author <a href="mailto:matti.rintanikkola@gmail.com">Matti Rinta-Nikkola</a>
*/
public class GroovyEngine implements ScriptEngine {
private static final String REGEX_SYSTEM_VAR = "[A-Z]{1}[A-Z_]*";
private static final String REGEX_SYSTEM_VAR = "[A-Z]+[A-Z_]*";
private static final String REGEX_VAR = "[a-zA-Z_]+[a-zA-Z0-9_]*";
private static final Pattern PATTERN_FUNCTION_DEF=Pattern.compile("^def\\s+(" + REGEX_VAR + ")\\s*\\(([a-zA-Z0-9_ ,]*)\\)\\s*\\{(.*)?\\}(|\n)$"
, Pattern.DOTALL);
private static final Pattern PATTERN_CLASS_DEF=Pattern.compile("^class\\s+(" + REGEX_VAR + ")\\ .*?\\{.*?\\}(|\n)$"
, Pattern.DOTALL);
private GroovyShell shell;
private Binding sharedData;
private Map<String,String> imports = new HashMap<String,String>();
private Map<String,String> imports = new HashMap<>();
private Map<String,String> methods = new HashMap<>();
private Map<String,String> classes = new HashMap<>();

public GroovyEngine() {
this.sharedData = new Binding();
Expand Down Expand Up @@ -137,11 +146,32 @@ public Object execute(String statement) throws Exception {
imports.put(p[1].replaceAll(";", ""), statement);
} else if (statement.equals("import")) {
out = new ArrayList<>(imports.keySet());
} else if (functionDef(statement)) {
// do nothing
} else if (statement.equals("def")) {
out = methods;
} else if (statement.matches("def\\s+" + REGEX_VAR)) {
String name = statement.split("\\s+")[1];
if (methods.containsKey(name)) {
out = "def " + name + methods.get(name);
}
} else if (classDef(statement)) {
// do nothing
} else if (statement.equals("class")) {
out = classes.values();
} else if (statement.matches("class\\s+" + REGEX_VAR)) {
String name = statement.split("\\s+")[1];
if (classes.containsKey(name)) {
out = classes.get(name);
}
} else {
String e = "";
for (Map.Entry<String, String> entry : imports.entrySet()) {
e += entry.getValue()+"\n";
}
for (String c : classes.values()) {
e += c;
}
e += statement;
out = shell.evaluate(e);
}
Expand Down Expand Up @@ -172,6 +202,27 @@ private List<String> internalFind(String var) {
return out;
}

private boolean functionDef (String statement) throws Exception{
boolean out = false;
Matcher m = PATTERN_FUNCTION_DEF.matcher(statement);
if(m.matches()){
out = true;
put(m.group(1), execute("{" + m.group(2) + "->" + m.group(3) + "}"));
methods.put(m.group(1), "(" + m.group(2) + ")" + "{" + m.group(3) + "}");
}
return out;
}

private boolean classDef (String statement) throws Exception{
boolean out = false;
Matcher m = PATTERN_CLASS_DEF.matcher(statement);
if(m.matches()){
out = true;
classes.put(m.group(1), statement);
}
return out;
}

private void del(String var) {
if (var == null) {
return;
Expand All @@ -180,13 +231,25 @@ private void del(String var) {
imports.remove(var);
} else if (sharedData.hasVariable(var)) {
sharedData.getVariables().remove(var);
if (methods.containsKey(var)) {
methods.remove(var);
}
} else if (!var.contains(".") && var.contains("*")) {
for (String v : internalFind(var)){
if (sharedData.hasVariable(v) && !v.equals("_") && !v.matches(REGEX_SYSTEM_VAR)) {
sharedData.getVariables().remove(v);
if (methods.containsKey(v)) {
methods.remove(v);
}
}
if (classes.containsKey(v)) {
classes.remove(v);
}
}
}
if (classes.containsKey(var)) {
classes.remove(var);
}
}

@Override
Expand Down

0 comments on commit f445ed8

Please sign in to comment.