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

300
LINES

< > BotCompany Repo | #1034737 // GazelleV_LeftArrowScript [backup]

JavaX fragment (include)

1  
// See GazelleV_LeftArrowScriptParser
2  
3  
// TODO: decide whether we allow calling methods/getting fields on
4  
// a null reference (just returning null), or whether we throw a
5  
// NullPointerException. Currently we just return null. Probably
6  
// that's pretty cool. Null propagation as a default, just like in
7  
// JavaX. Just more automatic!
8  
9  
sclass GazelleV_LeftArrowScript {
10  
  // Base = any script element with a reference to its source code
11  
  
12  
  asclass Base is IHasTokenRangeWithSrc {
13  
    TokenRangeWithSrc src;
14  
    
15  
    public void setTokenRangeWithSrc(TokenRangeWithSrc src) { this.src = src; }
16  
    public TokenRangeWithSrc tokenRangeWithSrc() { ret src; }
17  
    
18  
    RuntimeException rethrowWithSrc(Throwable e) {
19  
      if (src != null)
20  
        throw rethrowAndAppendToMessage(e, squareBracketed(str(src)));
21  
      else
22  
        throw rethrow(e);
23  
    }
24  
  }
25  
  
26  
  // Evaluable = a script element that can be evaluated
27  
  
28  
  interface Evaluable extends IF0 {
29  
    public O get(VarContext ctx default new);
30  
    public default LASValueDescriptor returnType() { null; }
31  
    public default Evaluable optimize() { this; }
32  
  }
33  
  
34  
  // Base + Evaluable + explicitly stored return type
35  
  
36  
  asclass BaseEvaluable > Base is Evaluable {
37  
    settable LASValueDescriptor returnType;
38  
  }
39  
  
40  
  /*interface Cmd {
41  
    // returns true if a return was issued
42  
    public bool run(VarContext ctx default new);
43  
  }*/
44  
  
45  
  static new AtomicLong scriptIDCounter;
46  
  static long scriptID() { ret incAtomicLong(scriptIDCounter); }
47  
  
48  
  sclass Script > Base is Evaluable {
49  
    long id = scriptID(); // just for printing
50  
    Map<S, FunctionDef> functionDefs;
51  
    Evaluable[] steps;
52  
    
53  
    public O get(VarContext ctx) {
54  
      O result = null;
55  
      for (step : steps) {
56  
        ping();
57  
        result = step.get(ctx);
58  
        
59  
        // exiting from anything?
60  
        
61  
        var exiting = ctx.exitFromScript;
62  
        if (exiting != null) {
63  
          printVars ifdef ReturnFromScript_debug("Checking exitFromScript",
64  
            +ctx, +exiting, script := this);
65  
            
66  
          // we're the exit point
67  
          if (exiting == this)
68  
            ctx.exitFromScript = null;
69  
            
70  
          // exit further
71  
          break;
72  
        }
73  
      }
74  
      ret result;
75  
    }
76  
    
77  
    S toStringLong() { ret pnlToLines(steps); }
78  
    toString { ret "Script " + n2(id); }
79  
    
80  
    FunctionDef getFunction(S name) { ret mapGet(functionDefs, name); }
81  
  } // end of Script
82  
  
83  
  srecord noeq FunctionDef(S name, LS args, Evaluable body) > Base {
84  
    public O call(VarContext ctx, O... args) {
85  
      var ctx2 = new VarContext(ctx);
86  
      int n = min(l(args), l(this.args));
87  
      for i to n:
88  
        ctx2.put(this.args.get(i), args[i]);
89  
      print ifdef GazelleV_LeftArrowScript_debug(ctx2 := ctx2.vars);
90  
      ret body.get(ctx2);
91  
    }
92  
  }
93  
  
94  
  srecord noeq Assignment(S var, Evaluable expression) > Base is Evaluable {
95  
    public O get(VarContext ctx) {
96  
      O o = expression.get(ctx);
97  
      ctx.set(var, o);
98  
      ret o;
99  
    }
100  
    
101  
    toString { ret var + " <- " + expression; }
102  
  }
103  
  
104  
  persistable sclass NewObject > Base is Evaluable {
105  
    Class c;
106  
    L<Evaluable> args;
107  
    
108  
    *(Class *c) {}
109  
    *(Class *c, L<Evaluable> *args) {}
110  
    
111  
    public O get(VarContext ctx) {
112  
      ret callConstructor(c, mapToArray(args, arg -> arg.get(ctx)));
113  
    }
114  
    
115  
    toString { ret "new " + formatFunctionCall(className(c), args); }
116  
  }
117  
  
118  
  srecord noeq CallFunction(FunctionDef f, L<Evaluable> args) > Base is Evaluable {
119  
    public O get(VarContext ctx) {
120  
      //ping();
121  
      ret f.call(ctx, mapToArray(args, a -> a.get(ctx));
122  
    }
123  
    
124  
    toString { ret formatFunctionCall(f.name, args); }
125  
  }
126  
  
127  
  srecord noeq GetVar(S var) > BaseEvaluable {
128  
    public O get(VarContext ctx) {
129  
      ret ctx.get(var);
130  
    }
131  
    
132  
    toString { ret var; }
133  
  }
134  
  
135  
  srecord noeq Const(O value) > Base is Evaluable {
136  
    public O get(VarContext ctx) {
137  
      ret value;
138  
    }
139  
    
140  
    toString { ret strOrClassName(value); }
141  
    
142  
    public LASValueDescriptor returnType() {
143  
      ret new LASValueDescriptor.KnownValue(value);
144  
    }
145  
  }
146  
  
147  
  srecord noeq GetStaticField(Field field) > Base is Evaluable {
148  
    public O get(VarContext ctx) ctex {
149  
      ret field.get(null);
150  
    }
151  
  }
152  
  
153  
  srecord noeq CallMethodOrGetField(Evaluable target, S name) > Base is Evaluable {
154  
    public O get(VarContext ctx) {
155  
      try {
156  
        O object = target.get(ctx);
157  
        if (object == null)
158  
          null; // throw new NullPointerException();
159  
          
160  
        // could optimize more for sure
161  
        if (canCallWithVarargs(object, name))
162  
          ret call(object, name);
163  
          
164  
        // TODO: better error message when neither field nor method found
165  
        ret _get(object, name);
166  
      } catch e {
167  
        throw rethrowWithSrc(e);
168  
      }
169  
    }
170  
  }
171  
  
172  
  sclass GetVarContext > Base is Evaluable {
173  
    public O get(VarContext ctx) { ret ctx; }
174  
  }
175  
  
176  
  srecord noeq ThrowMethodNotFoundException(CallMethod instruction) > Base is Evaluable {
177  
    public O get(VarContext ctx) {
178  
      fail("Method not found: " + instruction);
179  
    }
180  
  }
181  
  
182  
  srecord noeq ThrowNullPointerException(CallMethod instruction) > Base is Evaluable {
183  
    public O get(VarContext ctx) {
184  
      fail("Null pointer exception: " + instruction);
185  
    }
186  
  }
187  
  
188  
  srecord noeq CallMethod(Evaluable target, S methodName, L<Evaluable> args) > Base is Evaluable {
189  
    public O get(VarContext ctx) {
190  
      ret call(target.get(ctx), methodName, mapToArray(args, arg -> arg.get(ctx)));
191  
    }
192  
    
193  
    toString { ret target + "." + formatFunctionCall(methodName, args); }
194  
    
195  
    public Evaluable optimize() {
196  
      var targetType = target.returnType();
197  
      if (targetType.knownValue()) {
198  
        O o = targetType.value();
199  
        if (o == null) ret new ThrowNullPointerException(this);
200  
        
201  
        Class[] argTypes = new[l(args)];
202  
        for i over args: {
203  
          var type = args.get(i).returnType();
204  
          if (!type.javaClassIsExact())
205  
            this;
206  
          argTypes[i] = type.javaClass();
207  
        }
208  
        
209  
        // TODO: varargs
210  
        var method = findMethod_precise_onTypes(o, methodName, argTypes);
211  
        if (method == null) ret new ThrowMethodNotFoundException(this);
212  
        
213  
        ret new DirectMethodCallOnKnownTarget(o instanceof Class ? null : o, method, args);
214  
      }
215  
      
216  
      this;
217  
    }
218  
  }
219  
  
220  
  srecord noeq DirectMethodCallOnKnownTarget(O target, Method method, L<Evaluable> args) > Base is Evaluable {
221  
    public O get(VarContext ctx) {
222  
      ret invokeMethod(method, target, mapToArray(args, arg -> arg.get(ctx)));
223  
    }
224  
    
225  
    toString { ret (target == null ? "" : target + ".") + formatFunctionCall(str(method), args); }
226  
    
227  
    public LASValueDescriptor returnType() {
228  
      ret LASValueDescriptor.fromClass(method.getReturnType());
229  
    }
230  
  }
231  
  
232  
  srecord noeq While(Evaluable condition, Evaluable body) > Base is Evaluable {
233  
    public O get(VarContext ctx) {
234  
      while (ping() && (Bool) condition.get(ctx)) {
235  
        body.get(ctx);
236  
      }
237  
      
238  
      // while loops don't return anything
239  
      null;
240  
    }
241  
  }
242  
  
243  
  srecord noeq ForEach(Evaluable collection, S var, Evaluable body) > Base is Evaluable {
244  
    public O get(VarContext ctx) {
245  
      var coll = collection.get(ctx);
246  
      Iterator iterator;
247  
      new L out;
248  
      if (coll cast O[])
249  
        for (element : coll) {
250  
          ping();
251  
          ctx.set(var, element);
252  
          out.add(body.get(ctx));
253  
        }
254  
      else if (coll cast Iterable) {
255  
        for (element : coll) {
256  
          ping();
257  
          ctx.set(var, element);
258  
          out.add(body.get(ctx));
259  
        }
260  
      } else if (coll == null) {} // ok
261  
      else
262  
        fail("Not iterable: " + className(coll));
263  
264  
      ctx.unset(var);
265  
      ret out;
266  
    }
267  
  }
268  
  
269  
  srecord noeq IfThen(Evaluable condition, Evaluable body,
270  
    Evaluable elseBranch) > Base is Evaluable {
271  
    
272  
    IfThen(Evaluable condition, Evaluable body) {
273  
      this.condition = condition;
274  
      this.body = body;
275  
    }
276  
    
277  
    public O get(VarContext ctx) {
278  
      if ((Bool) condition.get(ctx))
279  
        ret body.get(ctx);
280  
      else if (elseBranch != null)
281  
        ret elseBranch.get(ctx);
282  
      else
283  
        null;
284  
    }
285  
  }
286  
  
287  
  srecord noeq ReturnFromScript(Script script, Evaluable value) > Base is Evaluable {
288  
    public O get(VarContext ctx) {
289  
      O result = value.get(ctx);
290  
      printVars ifdef ReturnFromScript_debug("ReturnFromScript",
291  
        +result, +ctx, +script);
292  
      ctx.exitFromScript(script);
293  
      ret result;
294  
    }
295  
    
296  
    toString {
297  
      ret formatFunctionCall ReturnFromScript(script, value);
298  
    }
299  
  }
300  
}

Author comment

Began life as a copy of #1033981

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1034737
Snippet name: GazelleV_LeftArrowScript [backup]
Eternal ID of this version: #1034737/1
Text MD5: 3b48664fc921e99eafe8c78903369d21
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-03-08 00:42:43
Source code size: 8898 bytes / 300 lines
Pitched / IR pitched: No / No
Views / Downloads: 147 / 154
Referenced in: [show references]