//-------------------------------------------------------------------------------------------------- // // @ CopyRight Roberti & Parau Enterprises, Inc. 2021-2023 // // This work is licensed under the Creative Commons Attribution-NoDerivatives 4.0 International License. // To view a copy of this license, visit http://creativecommons.org/licenses/by-nd/4.0/ // or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. // //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- // // DVMacroJSApi class - one per thread // //-------------------------------------------------------------------------------------------------- package framework; import java.lang.reflect.Field; import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; import java.util.regex.*; import java.lang.reflect.Field; import org.graalvm.polyglot.*; import framework.DVMacros.Macro; public class DVMacroJSApi { protected DVMacroJSApi(DVParseInput parseInput, DVMacros macros) { this.parseInput= parseInput; this.macros= macros; this.context= Context.newBuilder("js") .engine(macros.getJSEngine()) .allowHostClassLookup(c -> c.equals("framework.DVMacroJSApi") || c.equals("java.math.BigInteger") || c.equals("java.math.BigDecimal") || c.equals("java.util.regex.Pattern") || c.equals("java.util.regex.Matcher")) .allowHostClassLoading(true) .allowHostAccess(HostAccess.ALL) .allowPolyglotAccess(PolyglotAccess.ALL) .resourceLimits(ResourceLimits.newBuilder() .statementLimit(Integer.MAX_VALUE, null) .build()) .build(); this.context.getBindings("js").putMember("__dvasm", this); //this.context.getBindings("js").putMember("__dvarc", macros.getMacroUtil()); /* this.context= Context.newBuilder("js") .engine(macros.getJSEngine()) .allowAllAccess(true) .allowCreateProcess(false) .allowCreateThread(false) .allowEnvironmentAccess(EnvironmentAccess.NONE) .allowExperimentalOptions(false) .allowHostClassLookup(c -> c.equals("framework.DVMacroJSApi") || c.equals("java.math.BigInteger") || c.equals("java.math.BigDecimal") || c.equals("java.util.regex.Pattern") || c.equals("java.util.regex.Matcher")) .allowHostClassLoading(true) .allowHostAccess(HostAccess.ALL) .allowIO(false) .allowNativeAccess(false) .allowPolyglotAccess(PolyglotAccess.NONE) .build(); */ } // // Line insert method // public void insertLine(String line) { this.parseInput.insertLine((line + "\n").getBytes()); } // // Insert line formatted // public void formatLine(String lbl, String opCode, String parm, String comm) { this.parseInput.formatLine(lbl, opCode, parm, comm); } // // Insert line formatted - shift indent left // public void formatLeft(String lbl, String opCode, String parm, String comm) { this.parseInput.formatLeft(lbl, opCode, parm, comm); } // // Insert indented comment // public void formatComm(String comm, int indent) { this.parseInput.formatComm(comm, indent); } // // Set indentation // public void setIndentIn() { this.parseInput.setIndentIn(); } public void setIndentOut() { this.parseInput.setIndentOut(); } // // Start and end macro methods // protected void startMacro(DVStatements.Statement evalOwner, String macroName, String evalParm, String jsCode) { this.evalOwner= evalOwner; ((DVThread) DVThread.currentThread()).setEvalOwner(evalOwner); this.parseInput.startMacro(macroName, evalOwner); this.macroName= macroName; this.evalParm= evalParm; this.jsCode= jsCode; } protected void endMacro() { this.parseInput.endMacro(); } // // Get inline/architecture macro // protected DVMacros.Macro getMacro(String macroName) { DVMacros.Macro macro= null; if (this.inlineMacroSet != null) macro= this.inlineMacroSet.get(macroName); return macro; } // // Add inline macro // protected void addInlineMacro(DVStatements.Statement owner, DVMacros.Macro macro) { if (this.inlineMacroSet == null) this.inlineMacroSet= new HashMap(); if (this.inlineMacroSet.putIfAbsent(macro.macroName, macro) != null) owner.putError(String.format("In-line macro [%s] already exists - new macro definition ignored", macro.macroName)); } // // Methods available to all Javascript Macros // // // Return bindings // protected Context getContext() { return this.context; } // // Get current macro name // public String getMacroName() { return this.macroName; } // // Get parm string - to be called by macro // public String getEvalParm() { return this.evalParm; } // // Return current JSMacro code // public String getCode() { return this.jsCode; } // // Get/Set environment // public String[] getEnv() { return this.macros.getEnv(); } protected void setEnv(DVMacros macros) { this.macros= macros; } // // Statement putInfo interface // public void putInfo(String msg) { this.evalOwner.putInfo(msg); } // // Statement putWarning interface // public void putWarning(String msg) { this.evalOwner.putWarning(msg); } // // Statement putError interface // public void putError(String msg) { this.evalOwner.putError(msg); } // // Statement put/get global object // public void putJSGlobal(String name, Object object) { this.jSGlobal.put(name, object); } public Object getJSGlobal(String name) { return this.jSGlobal.get(name); } public Object dropJSGlobal(String name) { return this.jSGlobal.remove(name); } public String getLanguage() { return "ASM"; } public String getNewLabel() { this.labelNo++; return String.format("Asm%06d", this.labelNo); } // // Class fields // private final DVParseInput parseInput; private Context context; protected DVMacros macros= null; private DVStatements.Statement evalOwner; private String macroName; private String evalParm; private String jsCode; private HashMap inlineMacroSet; private HashMap jSGlobal= new HashMap(); private int labelNo= 0; private final Pattern expRegister= Pattern.compile( "(?.*)(?[0-9]+)[-](?[0-9]+)$"); }