需要帮助,开发基于Java的脚本语言?

时间:2013-07-11 20:41:30

标签: java programming-languages

我刚刚开始研究一种名为XScript的编程语言。它的设计使我可以从Java应用程序运行它,但也可以通过Java应用程序重新编程它。我的想法是,我可以在游戏中创建虚拟计算机,或者随着时间的推移自行开发的程序。到目前为止,我有以下代码。据我所知,由于专有软件,可能需要对名称进行更改,但现在还可以。

人工主类:

import com.x.lang.XLoader;


public class Main {
    public static void main(String[] args) {
        XLoader xl = new XLoader();

        xl.exec("/Users/Nathan/Desktop/XScript/test.xls");
    }
}

XLoader(加载并执行XScript):

package com.x.lang;

import java.io.File;

import com.x.lang.object.XObject;

public class XLoader {
    XObject xo;
    public String fileLocation;

    public void exec(String fl) {
        fileLocation = fl;

        XObject xo = new XObject(new File(fileLocation));
        xo.exec();
    }
}

存储语言键功能的XCommandHub:

package com.x.lang;

import com.x.lang.keyword.Print;
import com.x.lang.keyword.Set;
import com.x.lang.object.XCommand;
import com.x.lang.object.XObject;

public class XCommandHub {
    public XCommand xc[] = new XCommand[2];

    public XCommandHub(XObject x) {
            xc[0] = new Print(x);
        xc[1] = new Set(x);
    }
    public XCommand getCommand(String s) {
        for (int i = 0; i < 2; i++) {
            if (xc[i].getCommandName() == s) {
                return xc[i];
            }
        }
        return null;
    }
}

定义关键字的XCommand类:

package com.x.lang.object;

public abstract class XCommand {
    private String commandName;
    public XObject xobject;

    public XCommand (String cn, XObject x) {
        commandName = cn;
        commandName += ": ";
        xobject = x;
    }
    public abstract void exec(XVar xv);

    public String getCommandName() {
        return commandName;
    }
}

XVar类定义所有变量:

package com.x.lang.object;

public class XVar {
    private String var1;
    public String name;

    public XVar(String s) {
        var1 = s;
    }
    public String getStringValue() {
        if (this.var1 != null) {
            return var1;
        }
        return " ";
    }
    public int getIntValue() {
        if (this.var1 != null) {
            return Integer.parseInt(var1);
        }
        return 0;
    }
    public void setName(String s) {
        name = s;
    }
}

XObject类实际执行命令:

package com.x.lang.object;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import com.x.lang.XCommandHub;

public class XObject {
    public XVar xvars[] = new XVar[150];
    public int varCount = 0;
    public File f;
    XCommandHub x;

    public XObject (File file) {
            f = file;
        x = new XCommandHub(this);
    }
    public void addVar(XVar var, String name) {
        xvars[varCount] = var;
        xvars[varCount].setName(name);
        varCount++;
    }
    public XVar getVar(String varName) {
        for (int i = 0; i < varCount; i++) {
            if (xvars[i].name == varName) {
                return xvars[i];
            }
        }
        return null;
    }
    public void exec() {
        try (BufferedReader br = new BufferedReader(new FileReader(f))) {
            String sCurrentLine;

            while ((sCurrentLine = br.readLine()) != null) {
                for (int i = 0; i < 2; i++) {
                    if (sCurrentLine.startsWith(x.xc[i].getCommandName()))
                    try {
                        x.getCommand(x.xc[i].getCommandName()).exec(new XVar(sCurrentLine.split(": ")[1]));
                    } catch (ArrayIndexOutOfBoundsException e) {
                        x.getCommand(x.xc[i].getCommandName()).exec(new XVar(" "));
                    }
                }
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

定义我迄今为止编程的命令的两个类:

package com.x.lang.keyword;

import com.x.lang.object.XCommand;
import com.x.lang.object.XObject;
import com.x.lang.object.XVar;

public class Print extends XCommand {
    public Print(XObject x) {
        super("print", x);
    }
    @Override
    public void exec(XVar xv) {
        if (xv.getStringValue().startsWith("%")) {
            try {
                System.out.println(xobject.getVar(xv.getStringValue().substring(1)).getStringValue());
            } catch (NullPointerException e) {
                System.out.println(xv.getStringValue());
            }
        }
        else {
            System.out.println(xv.getStringValue());
        }
    }
}


package com.x.lang.keyword;

import com.x.lang.object.XCommand;
import com.x.lang.object.XObject;
import com.x.lang.object.XVar;

public class Set extends XCommand {
    public Set(XObject x) {
        super("set", x);
    }
    @Override
    public void exec(XVar xv) {
        String[] add = xv.getStringValue().split("=");
        xobject.addVar(new XVar(add[1]), add[0]);
    }
}

到目前为止,我已经编程了,我试图让用户能够打印他们在代码中声明的变量。一个基本的.xls(X语言脚本)可能看起来像这样:

set: x=Hello StackOverflow
print: This was programmed in XScript!
print: 
print: %x

但是,当我尝试从数组中检索变量x时,print类中存在NullPointerException。该程序返回“%x”而不是“Hello StackOverflow”,因为我故意抓住了异常,但我不知道它是如何产生的。

由于 Doctor_N

1 个答案:

答案 0 :(得分:1)

您的代码永远找不到它要查找的变量:

public XVar getVar(String varName) {
    for (int i = 0; i < varCount; i++) {
        if (xvars[i].name == varName) {
            return xvars[i];
        }
    }

    return null;
}

此功能几乎总是返回null,因为您使用==比较字符串而不使用.equals==比较引用(内存地址),并且您要比较的参数和字符串极不可能指向同一位置。因此,您几乎总是返回null

因此,此行始终会生成NullPointerException

System.out.println(xobject.getVar(xv.getStringValue().substring(1)).getStringValue());

这是因为您有效地在getStringValue()上致电null

我建议将if更改为:

if(xvars[i] != null && xvars[i].name.equals(varName)) {
    ...
}