You can now load classes in the previous article "Supports object creation". I would like to take advantage of a class that can be loaded and handle static method calls for that class.
Confirm that you want to support static method calls.
For example, there is the following program.
The first line loads the ʻInteger class into the variable ʻintegerClass
.
I want the second line to call the toHexString
static method of that class and output its return value.
The toHexString
static method returns the integer of the argument as a string in hexadecimal representation.
The argument in the example is 255
, so the output will be ff
.
var integerClass = loadClass("java.lang.Integer")
println(integerClass.toHexString(255))
Let's think about how to implement it in the interpreter. There are no changes to lexical analysis (Lexer) and parsing (Parser).
In the previous article, "Support method calls", instance method calls are supported. Since the syntax of static methods is the same as that of instance methods, the corresponding parts are the same as those of instance methods.
To implement it, refer to what the type of v
is when there is a method call such asv.method ()
.
It separates whether it is an instance method call or a static method call.
If the type of v
isClass <?>
, It is regarded as a static method call.
Any other type is considered an instance method call.
Other types are, for example, String
and ʻInteger`.
Move on to implementation. Let's take a look at the changes made to the Interpreter.
Interpreter.java
An implementation of Interpreter.java.
This is a modification of the func ()
method.
The func ()
method guarantees that the argument value
is callable like a function.
Changed to put ʻif statement under
// Update. The
v in the previous example
v.method () is
d.left. Get the type of
v with
d.left.getClass () . If the type of
v is
Class <?> , It is considered a static method call, otherwise it is considered an instance method call. The ʻif
statement determines what to assign to the mf
field of the MethodFunc
type variable.
If you can prepare the values correctly for the mf
field, you will not be aware of the difference between static method calls and instance method calls.
This is because the method call can be executed by the ʻinvoke method of the
MethodFunc` class.
If the ʻifstatement is true, that is, a static method call, then
d.left itself is assigned to
mf.class_. This is because
d.leftitself represents the type.
Null is assigned to
mf.target. Assigning
null is because it is a static method call and does not require an instance to call the method. If the ʻif
statement is false, that is, an instance method call, it remains the same as implemented in the previous method call.
Interpreter.java
public Func func(Object value) throws Exception {
if (value instanceof Func) {
return (Func) value;
} else if (value instanceof Dotted) {
Dotted d = (Dotted) value;
MethodFunc mf = new MethodFunc();
mf.name = d.right.value;
// Update
Class<?> c = d.left.getClass();
if (c == Class.class.getClass()) {
mf.class_ = (Class<?>) d.left;
mf.target = null;
} else {
mf.class_ = c;
mf.target = d.left;
}
return mf;
} else if (value instanceof Variable) {
Variable v = (Variable) value;
return func(v.value);
} else {
throw new Exception("Not a function");
}
}
That is all for the main changes.
The program below using the above implementation
var integerClass = loadClass("java.lang.Integer")
println(integerClass.toHexString(255))
To output the hexadecimal representation ff
of 255
.
Interpreter.java
public static void main(String[] args) throws Exception {
String text = "";
text += "var integerClass = loadClass(\"java.lang.Integer\")";
text += "println(integerClass.toHexString(255))";
List<Token> tokens = new Lexer().init(text).tokenize();
List<Token> blk = new Parser().init(tokens).block();
new Interpreter().init(blk).run();
// --> ff
}
That's all for the implementation. Thank you very much.
The full source is available here.
Calc https://github.com/quwahara/Calc/tree/article-20-static-method-invocation/Calc/src/main/java
There is a continuation article.
** Read the script from a file and execute it ** http://qiita.com/quwahara/items/bac43cd1df11b025e46a
Recommended Posts