
lt.repl.scripting.LatteEngine Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of latte-compiler Show documentation
Show all versions of latte-compiler Show documentation
The latte-lang compiler project, which contains compiler and runtime required library.
The newest version!
package lt.repl.scripting;
import lt.compiler.*;
import lt.compiler.Properties;
import lt.compiler.Scanner;
import lt.compiler.syntactic.AST;
import lt.compiler.syntactic.Expression;
import lt.compiler.syntactic.Statement;
import lt.compiler.syntactic.def.*;
import lt.compiler.syntactic.pre.Import;
import lt.compiler.syntactic.pre.Modifier;
import lt.compiler.syntactic.pre.PackageDeclare;
import lt.lang.Pointer;
import lt.lang.Unit;
import lt.runtime.LtRuntimeException;
import javax.script.*;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
/**
* the script engine
*/
public class LatteEngine implements ScriptEngine {
private static final String SCRIPT_CLASS_NAME = "LATTE_SCRIPTING";
private final LatteEngineFactory factory;
private ScriptContext context;
private final ClassLoader classLoader;
LatteEngine(LatteEngineFactory factory) {
this.factory = factory;
Bindings engineScope = new LatteScope();
context = new LatteContext(engineScope);
classLoader = new MultipleClassLoader(
factory.getClass().getClassLoader(),
Thread.currentThread().getContextClassLoader());
}
public LatteEngine(ClassLoader loader) {
factory = null;
classLoader = loader;
}
@Override
public Object eval(String script, ScriptContext context) throws ScriptException {
return eval(script, context.getBindings(ScriptContext.ENGINE_SCOPE));
}
@Override
public Object eval(Reader reader, ScriptContext context) throws ScriptException {
return eval(readFully(reader), context);
}
@Override
public Object eval(String script) throws ScriptException {
return eval(script, context);
}
@Override
public Object eval(Reader reader) throws ScriptException {
return eval(readFully(reader));
}
@Override
public Object eval(String script, Bindings n) throws ScriptException {
return eval(script, n, new Config()
.setScannerType(Config.SCANNER_TYPE_INDENT)
.setVarNamePrefix("res")
.setEval(false));
}
public Object eval(String script, Bindings n, Config config) throws ScriptException {
List imports = initImports(n);
CL cl = initCL(n);
List recordedMethods = initMethodList(n);
final String scriptName = "latte-scripting.lts";
boolean isLatteScope = n instanceof LatteScope;
boolean recordVarIfPresent = true;
try {
ErrorManager err = new ErrorManager(true);
Scanner scanner;
switch (config.getScannerType()) {
case Config.SCANNER_TYPE_BRACE:
scanner = new BraceScanner(scriptName, new StringReader(script), new Properties(), err);
break;
case Config.SCANNER_TYPE_INDENT:
default:
scanner = new IndentScanner(scriptName, new StringReader(script), new Properties(), err);
}
Parser parser = new Parser(scanner.scan(), err);
List statements = parser.parse();
Statement lastStatement = statements.isEmpty() ? null : statements.get(statements.size() - 1);
String varName = null;
if (null != lastStatement) {
if (lastStatement instanceof VariableDef) {
// variable def
// so, the name can be retrieved
VariableDef v = (VariableDef) lastStatement;
varName = v.getName();
} else if (lastStatement instanceof AST.Assignment) {
// it's an assignment
// the name can be retrieved
AST.Assignment ass = (AST.Assignment) lastStatement;
AST.Access assignTo = ass.assignTo;
if (assignTo.exp == null) {
// assign to the field
varName = assignTo.name;
} else {
// cannot capture the name
// generate a name
varName = config.getVarNamePrefix() + incAndGetResCount(n);
lastStatement = defineAVariable(varName, (Expression) lastStatement);
}
} else if (lastStatement instanceof Expression) {
// the last statement is an expression
// it can be assigned to a variable
// the variable should be generated
varName = config.getVarNamePrefix() + incAndGetResCount(n);
lastStatement = defineAVariable(varName, (Expression) lastStatement);
if (!config.isEval()) {
recordVarIfPresent = false;
}
}
// replace the last statement
statements.remove(statements.size() - 1);
statements.add(lastStatement);
}
List scriptStatements = new ArrayList();
final List defList = new ArrayList();
// buffer these imports and add them if pass compile
List readyToAddIntoImport = new ArrayList();
for (Statement s : statements) {
if (s instanceof ClassDef || s instanceof InterfaceDef || s instanceof FunDef || s instanceof ObjectDef) {
defList.add(s);
} else if (s instanceof Import) {
readyToAddIntoImport.add((Import) s);
} else if (s instanceof PackageDeclare) {
err.SyntaxException("scripts cannot have package declaration", s.line_col());
} else if (s instanceof MethodDef) {
recordedMethods.add((MethodDef) s);
} else {
scriptStatements.add(s);
}
}
// validate innerStatements
// VariableDef might be transformed into assign
for (int i = 0; i < scriptStatements.size(); ++i) {
Statement s = scriptStatements.get(i);
if (s instanceof VariableDef) {
String name = ((VariableDef) s).getName();
boolean found = false;
for (String key : n.keySet()) {
if (key.equals(name)) {
found = true;
break;
}
}
if (found) {
if (((VariableDef) s).getAnnos().isEmpty()
&& ((VariableDef) s).getModifiers().isEmpty()
&& ((VariableDef) s).getInit() != null) {
scriptStatements.set(i, new AST.Assignment(
new AST.Access(null, name, s.line_col()),
"=",
((VariableDef) s).getInit(),
s.line_col()
));
}
}
}
}
// fill the methods
scriptStatements.addAll(recordedMethods);
// parameters and args of the class
List parameters = new ArrayList();
List> paramClasses = new ArrayList>();
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy