20 Corresponds to static method invocation


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.

What you want to do with static method call support

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")

How to implement

Let's think about how to implement it in the interpreter. There are no changes to lexical analysis (Lexer) and parsing (Parser).

How to implement the Interpreter

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`.

Try to implement in Java

Move on to implementation. Let's take a look at the changes made to the Interpreter.


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, thend.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.


    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")

To output the hexadecimal representation ff of 255.


    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.

in conclusion

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

20 Corresponds to static method invocation
16 Corresponds to method invocation
Method to search
Corresponds to 17 arrays
Corresponds to Scope
Corresponds to 15 strings
8 Corresponds to multiple arguments
static factory method part 1
10 Corresponds to if statement
14 Corresponds to function expressions
5 Corresponds to prioritizing parentheses
19 Corresponds to object creation
To you who lament that Java's main method is static
9 Corresponds to the return value
12 Corresponds to the while statement
[java] Reasons to use static
No static method getFont error
Benefits of Java static method
Easy to use array.map (&: method)
How to create a method
Use Modifier # isStatic to determine if the [Reflection] method is static.
How to use the link_to method
How to use the include? method
11 Corresponds to comparison and logical operators
How to use the form_with method
[Ruby] Method to count specific characters
[Java] How to use join method
Resilience4j TimeLimiter times out method invocation
Introduction to Design Patterns (Factory Method)
[Ruby] How to use any? Method
I tried to explain the method
Try to extract java public method
How to use Ruby inject method
To not be a static uncle