Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

95
LINES

< > BotCompany Repo | #1002395 // eval - Java expression evaluation function (VERY limited)

JavaX fragment (include)

// callableFunctions also includes method names
static O eval(S text, Collection<S> callableFunctions) {
  ret new Eval(callableFunctions).eval(text);
}

static O eval(S text) {
  ret new Eval().eval(text);
}

static Set<S> eval_standardsafefunctions = lithashset("bigint", "compareTo");

static class Eval {
  // safety switches
  Collection<S> callableFunctions;
  boolean allowReadingStaticFields;
  
  new HashMap<S, O> variables;
  L<S> tok;
  new O _null;
  
  *(Collection<S> *callableFunctions) {}
  *() { callableFunctions = eval_standardsafefunctions; }
  
  void setVar(S id, O value) {
    variables.put(id, or(value, _null));
  }
  
  O eval(S text) {
    tok = javaTok(text); // XX: better get from parser
    L e = jparse(text, "exp");
    ret evalExp(e);
  }
  
  O evalExp(L e) {
    // e == [1, 9, "call", "<identifier> ( <explist_opt> )", [1, 3, "identifier"], [5, 7, "quoted"]]
    
    S cl = getString(e, 2);
    
    if (eq(cl, "quoted"))
      ret unquote(get(tok, (int) get(e, 0)));
      
    if (eq(cl, "identifier")) {
      S id = get(tok, (int) get(e, 0));
      O val = variables.get(id);
      if (val != null) ret val == _null ? null : val;
      if (allowReadingStaticFields)
        ret get(getMainClass(), id);
      else
        fail("Unknown variable: " + id);
    }
      
    if (eq(cl, "call")) {
      ret evalCall(e, getMainClass());
    }
    
    if (eq(cl, "methodcall")) {
      L e_exp = cast get(e, 4); // submatch 1
      L e_call = cast get(e, 5); // submatch 2
      
      O obj = evalExp(e_exp);
      ret evalCall(e_call, obj);
    }
    
    throw fail("woot exp: " + structure(e));
  }
  
  O evalCall(L e, O obj) {
    L e_name = cast get(e, 4); // submatch 1
    L e_args = cast get(e, 5); // submatch 2
    
    S fname = get(tok, (int) get(e_name, 0));
    L args = evalArgs(e_args);
      
    ret callMethod(obj, fname, args);
  }
  
  L evalArgs(L e) {
    ret litlist(evalExp(e)); // todo...
  }
  
  O callMethod(O obj, S fname, L args) {
    boolean mayCall = mayCallFunction(fname);
    if (!hasMethodNamed(obj, fname))
      throw fail("Method not defined in " + getClassName(obj) + (mayCall ? "" : ", also not callable") + ": " + fname);
      
    if (!mayCallFunction(fname))
      throw fail("Not allowed to call method: " + fname);
      
    ret call(obj, fname, toObjectArray(args));
  }
  
  boolean mayCallFunction(S fname) {
    ret callableFunctions.contains(fname);
  }
}

Author comment

Began life as a copy of #1002385

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1002395
Snippet name: eval - Java expression evaluation function (VERY limited)
Eternal ID of this version: #1002395/1
Text MD5: 1d107f3743cf3909caea7d167bc0725c
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-07-28 15:17:31
Source code size: 2546 bytes / 95 lines
Pitched / IR pitched: No / No
Views / Downloads: 755 / 936
Referenced in: [show references]