123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package in.ocsf.dialij.app.srv;/* kpmy 16.03.2017 */
- import co.paralleluniverse.fibers.Fiber;
- import co.paralleluniverse.fibers.SuspendExecution;
- import groovy.lang.GroovyShell;
- import in.ocsf.dialij.app.obj.Processor;
- import org.apache.log4j.Logger;
- import org.springframework.stereotype.Service;
- import java.io.StringReader;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import java.util.UUID;
- @Service
- public class CompilerService {
- public static class CompileFiber extends Fiber<Object> {
- private String source;
- @Override
- protected Object run() throws SuspendExecution, InterruptedException {
- try {
- BFctx ctx = new BFctx();
- for (int i = 0; i < source.length(); i++)
- ctx.parse(source.charAt(i));
- String code = ctx.close();
- GroovyShell groovyShell = new GroovyShell();
- return groovyShell.evaluate(new StringReader(code));
- } catch (Exception e) {
- return new RuntimeException(e);
- }
- }
- private CompileFiber(String source){
- this.source = source;
- }
- }
- private Logger log = Logger.getLogger(getClass());
- public Processor proxify(Object obj) {
- return (Processor) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
- new Class[]{Processor.class},
- (proxy, method, args) -> {
- try {
- Method m = obj.getClass().getMethod(method.getName());
- return m.invoke(obj, args);
- } catch (InvocationTargetException e) {
- throw new RuntimeException(e.getTargetException());
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- });
- }
- public CompileFiber compile(String source) {
- return new CompileFiber(source);
- }
- private static class BFctx {
- private StringBuilder src = new StringBuilder();
- private int balance;
- BFctx() {
- src.append("package groovy.in.ocsf.dialij.script;\n");
- src.append("def String process(){\n");
- src.append("List<Integer> mem = new ArrayList<>();\n");
- src.append("for(int i = 0; i < 2048; i++) mem.add(0);\n");
- src.append("def int p = 0;\n");
- src.append("def int v = 0;\n");
- src.append("StringBuilder out = new StringBuilder();\n");
- }
- private String close() {
- src.append("return out.toString(); } \n");
- src.append("return this;");
- return src.toString();
- }
- private void parse(char c) {
- switch (c) {
- case '+':
- src.append("v = mem.get(p); v++;\n");
- src.append("mem.set(p, v <= 255 ? v : 0);\n");
- break;
- case '-':
- src.append("v = mem.get(p); v--;\n");
- src.append("mem.set(p, v >= 0 ? v : 255);\n");
- break;
- case '.':
- src.append("v = mem.get(p);\n");
- src.append("out.append((char) v);\n");
- break;
- case '[':
- src.append("v = mem.get(p);\n");
- src.append("while(v > 0){\n");
- balance++;
- break;
- case ']':
- src.append("v = mem.get(p);\n");
- src.append("}\n");
- if(balance >= 0)
- balance--;
- else
- throw new RuntimeException("unbalanced bf");
- break;
- case '>':
- src.append("p++;\n");
- src.append("if (p >= mem.size()) p = 0;\n");
- break;
- case '<':
- src.append("p--;\n");
- src.append("if (p < 0) p = mem.size() - 1;\n");
- break;
- default:
- }
- }
- }
- }
|