1 | // callableFunctions also includes method names |
2 | static O eval(S text, Collection<S> callableFunctions) { |
3 | ret new Eval(callableFunctions).eval(text); |
4 | } |
5 | |
6 | static O eval(S text) { |
7 | ret new Eval().eval(text); |
8 | } |
9 | |
10 | static Set<S> eval_standardsafefunctions = lithashset("bigint", "compareTo"); |
11 | |
12 | static class Eval { |
13 | // safety switches |
14 | Collection<S> callableFunctions; |
15 | boolean allowReadingStaticFields; |
16 | |
17 | new HashMap<S, O> variables; |
18 | L<S> tok; |
19 | new O _null; |
20 | |
21 | *(Collection<S> *callableFunctions) {} |
22 | *() { callableFunctions = eval_standardsafefunctions; } |
23 | |
24 | void setVar(S id, O value) { |
25 | variables.put(id, or(value, _null)); |
26 | } |
27 | |
28 | O eval(S text) { |
29 | tok = javaTok(text); // XX: better get from parser |
30 | L e = jparse(text, "exp"); |
31 | ret evalExp(e); |
32 | } |
33 | |
34 | O evalExp(L e) { |
35 | // e == [1, 9, "call", "<identifier> ( <explist_opt> )", [1, 3, "identifier"], [5, 7, "quoted"]] |
36 | |
37 | S cl = getString(e, 2); |
38 | |
39 | if (eq(cl, "quoted")) |
40 | ret unquote(get(tok, (int) get(e, 0))); |
41 | |
42 | if (eq(cl, "identifier")) { |
43 | S id = get(tok, (int) get(e, 0)); |
44 | O val = variables.get(id); |
45 | if (val != null) ret val == _null ? null : val; |
46 | if (allowReadingStaticFields) |
47 | ret get(getMainClass(), id); |
48 | else |
49 | fail("Unknown variable: " + id); |
50 | } |
51 | |
52 | if (eq(cl, "call")) { |
53 | ret evalCall(e, getMainClass()); |
54 | } |
55 | |
56 | if (eq(cl, "methodcall")) { |
57 | L e_exp = cast get(e, 4); // submatch 1 |
58 | L e_call = cast get(e, 5); // submatch 2 |
59 | |
60 | O obj = evalExp(e_exp); |
61 | ret evalCall(e_call, obj); |
62 | } |
63 | |
64 | throw fail("woot exp: " + structure(e)); |
65 | } |
66 | |
67 | O evalCall(L e, O obj) { |
68 | L e_name = cast get(e, 4); // submatch 1 |
69 | L e_args = cast get(e, 5); // submatch 2 |
70 | |
71 | S fname = get(tok, (int) get(e_name, 0)); |
72 | L args = evalArgs(e_args); |
73 | |
74 | ret callMethod(obj, fname, args); |
75 | } |
76 | |
77 | L evalArgs(L e) { |
78 | ret litlist(evalExp(e)); // todo... |
79 | } |
80 | |
81 | O callMethod(O obj, S fname, L args) { |
82 | boolean mayCall = mayCallFunction(fname); |
83 | if (!hasMethodNamed(obj, fname)) |
84 | throw fail("Method not defined in " + getClassName(obj) + (mayCall ? "" : ", also not callable") + ": " + fname); |
85 | |
86 | if (!mayCallFunction(fname)) |
87 | throw fail("Not allowed to call method: " + fname); |
88 | |
89 | ret call(obj, fname, toObjectArray(args)); |
90 | } |
91 | |
92 | boolean mayCallFunction(S fname) { |
93 | ret callableFunctions.contains(fname); |
94 | } |
95 | } |
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: | 849 / 1027 |
Referenced in: | [show references] |