From 1b1e80133fa142d293160df813e354c171023d20 Mon Sep 17 00:00:00 2001 From: Alumopper <90548686+Alumopper@users.noreply.github.com> Date: Tue, 25 Apr 2023 23:59:38 +0800 Subject: [PATCH 001/128] Create README.md Signed-off-by: Alumopper <90548686+Alumopper@users.noreply.github.com> --- README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..9b95143e --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# 介绍 Introduce +MCFPP是一个能被编译为Minecraft数据包的全新的面向对象的语言。它旨在以类似C系语言的语法,进行数据包的编写,并引入编程中常用的概念,从而使数据包的编 写更加的便利。 + +MCFPP is a brand new objected-oriented language that can be compiled into Minecraft Datapack. It aims to write datapacks in a syntax similar to C language, and introduces commonly used concepts in programming, thereby making the writing of datapacks more efficient. + +这个项目仍然处于早期的开发阶段中,尚不能用于实际运用。部分功能尚未实现,特性可能会在未来的版本中发生变化。库函数尚不齐全。 + +This project is still in the early stage of development and cannot be used for actual use. Some functions have not been implemented, and features may change in future versions. The library is also not complete. + +# 相关工程 Relative Projects +## MCSharp + +MCSharp是一个CSharp库。利用MCSharp,开发者可以使用CSharp进行数据包的开发。但是,此项目因为技术问题已经被停止。MCFPP继承了部分MCSharp的思想。 + +MCSharp is a CSharp library. Using MCSharp, developers can develop datapacks using CSharp. However, this project has been stopped due to technical issues. MCFPP inherits part of the ideas of MCSharp. + +## justMCF + +JustMCF是一个简化mcfunction工程的项目。使用JustMCF,你不但可以使用原版的命令,还可以使用项目设计的简化命令,可以使你的命令更加简洁高效。 + +JustMCF is a project to simplify mcfunction projects. Using JustMCF, you can not only use the original commands, but also use the simplified commands designed by the project, which can make your commands more concise and efficient. + +# 特性 Features +## MCFPP支持基本的逻辑语句 +MCFPP supports basic logical statements +``` +func example(){ + int i = @s.pos[0]; + if(i > 0){ + @s.say("Hello Minecraft!"); + } +} +``` +## MCFPP支持面向对象的编程 +MCFPP supports object-oriented programming +``` +class Example{ + int i; + public Example(int i){ + this.i = i; + } + public func print(){ + sys.print(this.i); + } +} +``` +# 快速开始 QuickStart +MCFPP Guider From 778dae48ae7cb5d30c670bb8ea438ba6ee151889 Mon Sep 17 00:00:00 2001 From: Alumopper <609255325@qq.com> Date: Wed, 3 May 2023 17:26:38 +0800 Subject: [PATCH 002/128] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=92=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20=E7=8E=B0=E5=9C=A8=E5=91=BD=E5=90=8D=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E9=80=9A=E8=BF=87=E5=B7=A5=E7=A8=8B=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=B9=B6=E8=AE=BE=E7=BD=AE=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=E4=B8=BAdefault?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 19 ++++++ build.gradle.kts | 1 + src/main/antlr/mcfpp.g4 | 6 +- src/main/kotlin/top/alumopper/mcfpp/MCFPP.kt | 2 +- .../kotlin/top/alumopper/mcfpp/Project.kt | 43 +++++++++--- .../top/alumopper/mcfpp/io/McfppFileReader.kt | 3 +- .../kotlin/top/alumopper/mcfpp/lang/MCBool.kt | 2 +- .../kotlin/top/alumopper/mcfpp/lang/MCInt.kt | 2 +- .../kotlin/top/alumopper/mcfpp/lang/Number.kt | 1 + .../kotlin/top/alumopper/mcfpp/lib/Cache.kt | 6 +- .../kotlin/top/alumopper/mcfpp/lib/Class.kt | 2 +- .../top/alumopper/mcfpp/lib/Constructor.kt | 10 +-- .../top/alumopper/mcfpp/lib/Function.kt | 50 ++++++++++---- .../top/alumopper/mcfpp/lib/FunctionTag.kt | 12 ++-- .../kotlin/top/alumopper/mcfpp/lib/Global.kt | 6 +- .../alumopper/mcfpp/lib/InternalFunction.kt | 21 +++--- .../alumopper/mcfpp/lib/McfppFileVisitor.kt | 41 +++++------ .../alumopper/mcfpp/lib/McfppImListener.kt | 68 ++++++++++--------- .../alumopper/mcfpp/lib/NativeConstructor.kt | 2 +- .../top/alumopper/mcfpp/lib/NativeFunction.kt | 4 +- .../top/alumopper/mcfpp/test/NashornTest.kt | 15 ++++ test/.mclib | 5 +- test/proj.json | 3 +- test/test.mcfpp | 3 + 24 files changed, 214 insertions(+), 113 deletions(-) create mode 100644 TODO.md create mode 100644 src/main/kotlin/top/alumopper/mcfpp/test/NashornTest.kt diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..4286c385 --- /dev/null +++ b/TODO.md @@ -0,0 +1,19 @@ +# 计划单 +## 进行中 +进行中的任务是短期内可能实现的 +* 内联函数(Inline Function) +* 运算符重载 +* 库调用 +* 类成员和类方法的调用 +* 代码优化 +* native函数和类 + +## 计划中 +计划中的内容将会在不久的将来实现 +* 类的继承 +* 沙箱 + * native的语法糖形式 +* 接口 +* 分版本编译 +* 基本库 +* return和函数的返回值 \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index a68b5509..eb9cf146 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,6 +24,7 @@ dependencies { implementation("com.alibaba.fastjson2:fastjson2:2.0.28") implementation("org.apache.logging.log4j:log4j-api:2.20.0") implementation("org.apache.logging.log4j:log4j-core:2.20.0") + implementation("org.openjdk.nashorn:nashorn-core:15.4") antlr("org.antlr:antlr4:4.12.0") } diff --git a/src/main/antlr/mcfpp.g4 b/src/main/antlr/mcfpp.g4 index 1921addb..82af7ef2 100644 --- a/src/main/antlr/mcfpp.g4 +++ b/src/main/antlr/mcfpp.g4 @@ -62,7 +62,7 @@ classFunctionDeclaration //函数声明 functionDeclaration - : INLINE? functionTag? 'func' namespaceID '(' parameterList? ')' '{' functionBody '}' + : INLINE? functionTag* 'func' namespaceID '(' parameterList? ')' '{' functionBody '}' ; namespaceID @@ -348,7 +348,7 @@ className ; functionTag - : namespaceID + : AT namespaceID ; TargetSelector @@ -417,6 +417,8 @@ STRING : '"' .*? '"' ; +AT:'@'; + // // Whitespace and comments // diff --git a/src/main/kotlin/top/alumopper/mcfpp/MCFPP.kt b/src/main/kotlin/top/alumopper/mcfpp/MCFPP.kt index 10001332..a78a0d5d 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/MCFPP.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/MCFPP.kt @@ -11,8 +11,8 @@ fun main(args: Array) { val start: Long = System.currentTimeMillis() Project.logger.info("Tips: " + UwU.tip) //生成tips val path = args[0] - Project.init() //初始化 Project.readProject(path) //读取 + Project.init() //初始化 Project.analyse() //解析 Project.compile() //编译 Project.optimization() //优化 diff --git a/src/main/kotlin/top/alumopper/mcfpp/Project.kt b/src/main/kotlin/top/alumopper/mcfpp/Project.kt index 0282dc11..ae4ff83c 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/Project.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/Project.kt @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.* import org.apache.logging.log4j.* import top.alumopper.mcfpp.io.McfppFileReader import top.alumopper.mcfpp.lib.* +import top.alumopper.mcfpp.lib.Function import java.io.* /** @@ -18,12 +19,6 @@ object Project { * 工程的根目录 */ lateinit var root: File - - /** - * 工程的名字 - */ - lateinit var name: String - /** * 工程包含的所有文件。以绝对路径保存 */ @@ -34,6 +29,11 @@ object Project { */ var version: String? = null + /** + * 工程的名字 + */ + lateinit var name: String + /** * 数据包的描述。原始Json文本 TODO */ @@ -49,10 +49,15 @@ object Project { */ lateinit var currFile: File + /** + * 工程的名字 + */ + var defaultNamespace: String = "default" + /** * 当前的命名空间 */ - lateinit var currNamespace: String + var currNamespace = defaultNamespace /** * 工程中的总错误数量 @@ -68,8 +73,18 @@ object Project { * 全局缓存 */ var global: Global = Global() + + /** + * 初始化 + */ fun init() { + //全局缓存初始化 global.init() + //初始化mcfpp的tick和load函数 + val mcfppTick = Function("tick","mcfpp") + val mcfppLoad = Function("load","mcfpp") + global.cache.functions.add(mcfppLoad) + global.cache.functions.add(mcfppTick) } /** @@ -116,6 +131,11 @@ object Project { if (description == null) { description = "A datapack compiled by MCFPP" } + defaultNamespace = if(jsonObject.getString("namespace") != null){ + jsonObject.getString("namespace") + }else{ + "default" + } val includesJson: JSONArray = jsonObject.getJSONArray("includes")?: JSONArray() for (i in 0 until includesJson.size) { includes.add(includesJson.getString(i)) @@ -173,15 +193,16 @@ object Project { if (f.parent.size == 0 && f !is Native) { //找到了入口函数 hasEntrance = true - f.commands.add(0, "data modify storage mcfpp:system $name.stack_frame prepend value {}") - logger.debug("Find entrance function:" + (if (f.tag == null) "" else f.tag) + " " + f.name) + f.commands.add(0, "data modify storage mcfpp:system $defaultNamespace.stack_frame prepend value {}") + f.commands.add("data remove storage mcfpp:system $defaultNamespace.stack_frame[0]") + logger.debug("Find entrance function:${f.tags} ${f.name}") } } if (!hasEntrance) { - logger.warn("No valid entrance function in Project $name") + logger.warn("No valid entrance function in Project $defaultNamespace") warningCount++ } - logger.info("Complete compiling project " + root.name + " with [" + errorCount + "] error and [" + warningCount + "] warning") + logger.info("Complete compiling project " + root.name + " with [$errorCount] error and [$warningCount] warning") } /** diff --git a/src/main/kotlin/top/alumopper/mcfpp/io/McfppFileReader.kt b/src/main/kotlin/top/alumopper/mcfpp/io/McfppFileReader.kt index 612ecf9e..a5b7103b 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/io/McfppFileReader.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/io/McfppFileReader.kt @@ -27,7 +27,6 @@ class McfppFileReader(path: String?) : McfppReader() { */ @Throws(IOException::class) fun analyse() { - Project.currNamespace = Project.name Project.currFile = File(path!!) val charStream: CharStream = CharStreams.fromStream(input) val tokens = CommonTokenStream(mcfppLexer(charStream)) @@ -39,7 +38,7 @@ class McfppFileReader(path: String?) : McfppReader() { */ @Throws(IOException::class) fun compile() { - Project.currNamespace = Project.name + Project.currNamespace = Project.defaultNamespace Project.currFile = File(path!!) val charStream: CharStream = CharStreams.fromStream(input) val lexer = mcfppLexer(charStream) diff --git a/src/main/kotlin/top/alumopper/mcfpp/lang/MCBool.kt b/src/main/kotlin/top/alumopper/mcfpp/lang/MCBool.kt index 07825038..9db758a6 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lang/MCBool.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lang/MCBool.kt @@ -207,7 +207,7 @@ class MCBool : Var, OnScoreboard { //变量进栈 Function.addCommand( "execute" + - " store result storage mcfpp:system " + Project.name + ".stack_frame[" + stackIndex + "]." + key + + " store result storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[" + stackIndex + "]." + key + " run scoreboard players operation " + identifier + " " + boolObject + " = " + a.identifier + " " + a.boolObject ) } diff --git a/src/main/kotlin/top/alumopper/mcfpp/lang/MCInt.kt b/src/main/kotlin/top/alumopper/mcfpp/lang/MCInt.kt index d4353123..78861df8 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lang/MCInt.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lang/MCInt.kt @@ -96,7 +96,7 @@ class MCInt : Number { isConcrete = false //变量进栈 Function.addCommand( - "execute store result storage mcfpp:system " + Project.name + ".stack_frame[" + stackIndex + "]." + key + " run " + "execute store result storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[" + stackIndex + "]." + key + " run " + Commands.SbPlayerOperation(this, "=", a as MCInt) ) } diff --git a/src/main/kotlin/top/alumopper/mcfpp/lang/Number.kt b/src/main/kotlin/top/alumopper/mcfpp/lang/Number.kt index 6d8511eb..19918ee2 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lang/Number.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lang/Number.kt @@ -83,6 +83,7 @@ abstract class Number : Var, OnScoreboard { */ abstract fun greaterCommand(a: Number): MCBool? + /** * 这个数是否小于a * @param a 右侧值 diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/Cache.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/Cache.kt index aa84fc5d..5cf072b7 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/Cache.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/Cache.kt @@ -156,7 +156,11 @@ class Cache { if (s is NativeFunction) { println("native " + s.namespace + " -> " + s.javaReferContext!!.text) } else { - println(s.namespaceID) + val n = StringBuilder("") + for(tag in s.tags){ + n.append("@${tag.namespaceID}") + } + println("$n ${s.namespaceID}") for (c in s.commands) { println("\t" + c) } diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/Class.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/Class.kt index 5bd94ec2..d2fcd42d 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/Class.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/Class.kt @@ -107,7 +107,7 @@ open class Class : CacheContainer { @get:Override override val prefix: String - get() = Project.name.toString() + "_class_" + identifier + "_" + get() = Project.defaultNamespace.toString() + "_class_" + identifier + "_" /** * 根据参数列表获取一个类的构造函数 diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/Constructor.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/Constructor.kt index 89782ae6..28898bd1 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/Constructor.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/Constructor.kt @@ -23,14 +23,14 @@ open class Constructor //检查此类中是否已经重复定义一个相同 * @param cls 调用函数的实例 */ @Override - override operator fun invoke(args: ArrayList, lineNo: Int, cls: ClassPointer) { + override fun invoke(args: ArrayList, lineNo: Int, cls: ClassPointer) { //对象创建 Function.addCommand( "execute in minecraft:overworld " + "run summon marker 0 0 0 {Tags:[" + cls.obj!!.tag + ",mcfpp_classPointer_just],data:{pointers:[]}}" ) //给函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") //参数传递 for (i in 0 until params.size) { when (params[i].type) { @@ -38,7 +38,7 @@ open class Constructor //检查此类中是否已经重复定义一个相同 val tg = args[i].cast(params[i].type) as MCInt //参数传递和子函数的参数压栈 Function.addCommand( - "execute store result storage mcfpp:system " + Project.name + ".stack_frame[0]." + params[i].identifier + " run " + "execute store result storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]." + params[i].identifier + " run " + Commands.SbPlayerOperation(MCInt("_param_" + params[i].identifier, this), "=", tg) ) } @@ -55,14 +55,14 @@ open class Constructor //检查此类中是否已经重复定义一个相同 Commands.Function(this) ) //调用完毕,将子函数的栈销毁 - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") //取出栈内的值到记分板 for (`var` in Function.currFunction!!.cache.allVars) { if (`var` is MCInt) { //如果是int取出到记分板 Function.addCommand( "execute store result score " + `var`.identifier + " " + `var`.`object` + " run " - + "data get storage mcfpp:system " + Project.name + ".stack_frame[0]." + `var`.key + + "data get storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]." + `var`.key ) } } diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/Function.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/Function.kt index 5134be29..2c336a87 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/Function.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/Function.kt @@ -5,7 +5,6 @@ import top.alumopper.mcfpp.Project import top.alumopper.mcfpp.command.Commands import top.alumopper.mcfpp.lang.* import java.lang.NullPointerException -import java.util.ArrayList /** * 一个minecraft中的命令函数。 @@ -109,7 +108,7 @@ open class Function : ClassMember, CacheContainer { * 函数的标签 * TODO 函数的标签应该是一个列表 */ - var tag: FunctionTag? = null + var tags: ArrayList = ArrayList() /** * 函数的命名空间。默认为工程文件的明明空间 @@ -195,7 +194,7 @@ open class Function : ClassMember, CacheContainer { } /** - * 创建一个函数,它有指定的标签 + * 创建一个函数,它有指定的命名空间 * @param name 函数的标识符 * @param namespace 函数的命名空间 */ @@ -211,13 +210,27 @@ open class Function : ClassMember, CacheContainer { return name } + fun addTag(tag : FunctionTag):Function{ + if(!tags.contains(tag)){ + tags.add(tag) + } + return this + } + val namespaceID: String /** * 获取这个函数的命名空间id,即xxx:xxx形式。可以用于命令 * @return 函数的命名空间id */ get() { - val re: StringBuilder = StringBuilder("$namespace:$name") + val re: StringBuilder = if(!isClassMember){ + StringBuilder("$namespace:$name") + }else{ + if(isStatic){ + StringBuilder("$namespace:${parentClass!!.identifier}/static/$name") + } + StringBuilder("$namespace:${parentClass!!.identifier}/$name") + } for (p in params) { re.append("_").append(p.type) } @@ -268,9 +281,9 @@ open class Function : ClassMember, CacheContainer { * 调用这个函数 * @param args 函数的参数 */ - open operator fun invoke(args: ArrayList, lineNo: Int) { + open fun invoke(args: ArrayList, lineNo: Int) { //给函数开栈 - addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") //参数传递 for (i in 0 until params.size) { when (params[i].type) { @@ -278,7 +291,7 @@ open class Function : ClassMember, CacheContainer { val tg = args[i].cast(params[i].type) as MCInt //参数传递和子函数的参数压栈 addCommand( - "execute store result storage mcfpp:system " + Project.name + ".stack_frame[0]." + params[i].identifier + " run " + "execute store result storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]." + params[i].identifier + " run " + Commands.SbPlayerOperation(MCInt("_param_" + params[i].identifier, this), "=", tg) ) } @@ -295,21 +308,21 @@ open class Function : ClassMember, CacheContainer { //如果是int取出到记分板 addCommand( "execute store result score " + (args[i] as MCInt).identifier + " " + (args[i] as MCInt).`object` + " run " - + "data get storage mcfpp:system " + Project.name + ".stack_frame[0]." + params[i].identifier + + "data get storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]." + params[i].identifier ) } } } } //调用完毕,将子函数的栈销毁 - addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") //取出栈内的值到记分板 for (`var` in currFunction.cache.allVars) { if (`var` is MCInt) { //如果是int取出到记分板 addCommand( "execute store result score " + `var`.identifier + " " + `var`.`object` + " run " - + "data get storage mcfpp:system " + Project.name + ".stack_frame[0]." + `var`.key + + "data get storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]." + `var`.key ) } } @@ -321,10 +334,20 @@ open class Function : ClassMember, CacheContainer { * @param lineNo 调用此函数的上下文的行数,用于错误日志 * @param cls 调用函数的实例 */ - open operator fun invoke(args: ArrayList, lineNo: Int, cls: ClassPointer) { + open fun invoke(args: ArrayList, lineNo: Int, cls: ClassPointer) { TODO() } + val isEntrance: Boolean + get() { + for (tag in tags){ + if(tags.equals(FunctionTag.TICK) || tags.equals(FunctionTag.LOAD)){ + return true + } + } + return false + } + val cmdStr: String get() { val qwq: StringBuilder = StringBuilder() @@ -339,15 +362,14 @@ open class Function : ClassMember, CacheContainer { get() = Project.currNamespace + "_func_" + name + "_" /** - * 判断两个函数是否相同.判据包括:命名空间ID,是否是类成员,父类,标签和参数列表 + * 判断两个函数是否相同.判据包括:命名空间ID,是否是类成员,父类和参数列表 * @param other 要比较的对象 * @return 若相同,则返回true */ @Override override fun equals(other: Any?): Boolean { if (other is Function) { - if (!((other.tag != null && other.tag!! == tag || other.tag == null && tag == null) && other.isClassMember == isClassMember && other.namespaceID == namespaceID && other.parentClass === parentClass) - ) { + if (!(other.isClassMember == isClassMember && other.namespaceID == namespaceID && other.parentClass === parentClass)) { return false } if (other.params.size == params.size) { diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/FunctionTag.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/FunctionTag.kt index b524380f..cfc894c6 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/FunctionTag.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/FunctionTag.kt @@ -7,7 +7,7 @@ import top.alumopper.mcfpp.Project * 一个函数的标签 */ class FunctionTag( - namespace: String, + namespace: String?, /** * 函数标签的名字 */ @@ -24,9 +24,13 @@ class FunctionTag( var cache: Cache init { - if (tag == "tick" || tag == "load") { - this.namespace = MINECRAFT - } else { + if(namespace == null){ + if (tag == "tick" || tag == "load") { + this.namespace = MINECRAFT + } else { + this.namespace = Project.currNamespace + } + }else{ this.namespace = namespace } cache = Cache(Project.global.cache) diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/Global.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/Global.kt index 3d6575ee..0050382c 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/Global.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/Global.kt @@ -8,7 +8,7 @@ import top.alumopper.mcfpp.Project class Global : CacheContainer { /** - * 全局函数 + * 全局函数和类 */ lateinit var cache: Cache @@ -19,10 +19,12 @@ class Global : CacheContainer { fun init(): Global { cache = Cache(null, this) + functionTags["minecraft:tick"] = FunctionTag.TICK + functionTags["minecraft:load"] = FunctionTag.LOAD return this } @get:Override override val prefix: String - get() = Project.name + "_global_" + get() = Project.defaultNamespace + "_global_" } \ No newline at end of file diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/InternalFunction.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/InternalFunction.kt index c297bde0..44c508fe 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/InternalFunction.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/InternalFunction.kt @@ -14,11 +14,11 @@ import java.util.UUID * * 匿名内部函数和普通的命令函数有一个细小的区别。为了方便起见,我们还是先看一小段代码 * {@snippet : - * * int i = 0; - * * if(qwq){ - * * i ++; - * * } - * * } + * int i = 0; + * if(qwq){ + * i ++; + * } + * } * 如果我们仍然简单采用直接调用函数的方式,将if后面的`i++`单独放在一个函数中, * 我们便会发现编译器抛出了一个异常,表示这个匿名函数中没有定义变量i。但是显然,无论是 * 在if语句还是其他的循环语句中,我们都可以直接调用函数之前已经声明好的变量。 @@ -28,15 +28,12 @@ import java.util.UUID * 因此,这里就是匿名内部函数和普通的函数的主要差异点了。匿名函数类是允许访问它的父函数, * 即声明if、while语句的函数的栈的。 * + * @param prefix 匿名内部函数的前缀。 + * @param parent 这个函数的调用者,即父函数 + * */ class InternalFunction(prefix: String, parent: Function) : Function(prefix + UUID.randomUUID()) { - /** - * 创建一个匿名内部函数,并指定这个函数的调用者。 - * 匿名内部函数的名字为_调用语句的类型_uuid,例如if对应的匿名函数名 - * 为_if_uuid - * @param prefix 匿名内部函数的前缀。 - * @param parent 这个函数的调用者,即父函数 - */ + init { cache.parent = parent.cache setParentFunction(parent) diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFileVisitor.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFileVisitor.kt index ccdfedc9..bb384997 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFileVisitor.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFileVisitor.kt @@ -33,6 +33,8 @@ class McfppFileVisitor : mcfppBaseVisitor() { //命名空间 if (ctx.namespaceDeclaration() != null) { Project.currNamespace = ctx.namespaceDeclaration()!!.Identifier().text + }else{ + Project.currNamespace = Project.defaultNamespace } //文件结构,类和函数 for (t in ctx.typeDeclaration()) { @@ -315,7 +317,7 @@ class McfppFileVisitor : mcfppBaseVisitor() { val f: Function //是否是内联函数 //是否是内联函数 - if (ctx.INLINE() == null) { + if (ctx.INLINE() != null) { //获取函数的文本内容 //函数是否拥有命名空间声明 f = if (ctx.namespaceID().Identifier().size == 1) { @@ -340,22 +342,25 @@ class McfppFileVisitor : mcfppBaseVisitor() { f.addParams(ctx.parameterList()) } //解析函数的tag - if (ctx.functionTag() != null) { - val functionTag: FunctionTag = if (ctx.functionTag()!!.namespaceID().Identifier().size == 1) { - FunctionTag(FunctionTag.MINECRAFT, ctx.functionTag()!!.namespaceID().Identifier(0).text) - } else { - FunctionTag( - ctx.functionTag()!!.namespaceID().Identifier(0).text, - ctx.functionTag()!!.namespaceID().Identifier(1).text - ) - } - if (Project.global.functionTags.containsKey(functionTag.namespaceID)) { - f.tag = Project.global.functionTags[functionTag.namespaceID] - } else { - Project.global.functionTags[functionTag.namespaceID] = functionTag - f.tag = functionTag + if (ctx.functionTag() != null && ctx.functionTag().size != 0) { + for(fTag in ctx.functionTag()){ + //构建函数标签对象 + var functionTag: FunctionTag = if (fTag.namespaceID().Identifier().size == 1) { + FunctionTag(null, fTag.namespaceID().Identifier(0).text) + } else { + FunctionTag( + fTag.namespaceID().Identifier(0).text, + fTag.namespaceID().Identifier(1).text + ) + } + if (Project.global.functionTags.containsKey(functionTag.namespaceID)) { + functionTag = Project.global.functionTags[functionTag.namespaceID]!! + } else { + Project.global.functionTags[functionTag.namespaceID] = functionTag + } + f.tags.add(functionTag) + functionTag.cache.functions.add(f) } - f.tag!!.cache.functions.add(f) } //不是类的成员 f.isClassMember = false @@ -369,9 +374,7 @@ class McfppFileVisitor : mcfppBaseVisitor() { Project.errorCount++ Function.currFunction = Function.nullFunction } - if (f.tag != null && (f.tag!! == FunctionTag.TICK || f.tag!! == FunctionTag.LOAD) && (ctx.parent as mcfppParser.FunctionDeclarationContext).parameterList()!! - .parameter().size != 0 - ) { + if (f.isEntrance && ctx.parameterList()!!.parameter().size != 0) { Project.logger.error( "Entrance function shouldn't have parameter:" + f.namespaceID + " at " + Project.currFile.name + " line: " + ctx.getStart().line diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppImListener.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppImListener.kt index 90a57a53..b284f467 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppImListener.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppImListener.kt @@ -230,6 +230,8 @@ class McfppImListener : mcfppBaseListener() { curr.parent.add(Function.currFunction) } + //region 逻辑语句 + var lastBool: MCBool? = null //if语句的条件 //TODO 条件判断语句实现方式与参考文章有出入,可能存在bug /** @@ -241,9 +243,9 @@ class McfppImListener : mcfppBaseListener() { Function.addCommand("#if start") val parent: mcfppParser.IfStatementContext = ctx.parent as mcfppParser.IfStatementContext //是if语句,获取参数 - val index: Int = parent.ifBlock().indexOf(ctx) + val index = parent.ifBlock().indexOf(ctx) //匿名函数的定义 - val f: Function = InternalFunction("_if_", Function.currFunction) + val f = InternalFunction("_if_", Function.currFunction) Project.global.cache.functions.add(f) if (index == 0) { //第一个if @@ -251,7 +253,7 @@ class McfppImListener : mcfppBaseListener() { if (exp.isConcrete && exp.value) { //函数调用的命令 //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand(Commands.Function(f)) Project.logger.warn( "The condition is always true. " + @@ -265,7 +267,7 @@ class McfppImListener : mcfppBaseListener() { ) } else { //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand( "execute " + "if score " + exp.identifier + " " + SbObject.MCS_boolean + " matches 1 " + @@ -292,7 +294,7 @@ class McfppImListener : mcfppBaseListener() { override fun exitIfBlock(ctx: mcfppParser.IfBlockContext?) { Function.currFunction = Function.currFunction.parent[0] //调用完毕,将子函数的栈销毁 - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") Function.addCommand("#if end") } @@ -309,7 +311,7 @@ class McfppImListener : mcfppBaseListener() { if (lastBool!!.isConcrete && !lastBool!!.value) { //函数调用的命令 //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand("#" + Commands.Function(f)) Project.logger.warn( "The condition is always false. " + @@ -317,7 +319,7 @@ class McfppImListener : mcfppBaseListener() { ) } else if (lastBool!!.isConcrete) { //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand(Commands.Function(f)) Project.logger.warn( "The condition is always true. " + @@ -325,7 +327,7 @@ class McfppImListener : mcfppBaseListener() { ) } else { //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand( "execute " + "unless score " + lastBool!!.identifier + " " + SbObject.MCS_boolean + " matches 1 " + @@ -344,7 +346,7 @@ class McfppImListener : mcfppBaseListener() { override fun exitElseIfStatement(ctx: mcfppParser.ElseIfStatementContext?) { Function.currFunction = Function.currFunction.parent[0] //调用完毕,将子函数的栈销毁 - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") Function.addCommand("#else if end") } @@ -364,7 +366,7 @@ class McfppImListener : mcfppBaseListener() { Project.global.cache.functions.add(f) if (exp.isConcrete && exp.value) { //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand(Commands.Function(f)) Project.logger.warn( "The condition is always true. " + @@ -372,7 +374,7 @@ class McfppImListener : mcfppBaseListener() { ) } else if (exp.isConcrete) { //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand("#" + Commands.Function(f)) Project.logger.warn( "The condition is always false. " + @@ -380,7 +382,7 @@ class McfppImListener : mcfppBaseListener() { ) } else { //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand( "execute " + "if score " + exp.identifier + " " + SbObject.MCS_boolean + " matches 1 " + @@ -388,7 +390,7 @@ class McfppImListener : mcfppBaseListener() { ) } //调用完毕,将子函数的栈销毁 - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") Function.currFunction = f //后续块中的命令解析到递归的函数中 } @@ -406,7 +408,7 @@ class McfppImListener : mcfppBaseListener() { val parent: mcfppParser.WhileStatementContext = ctx.parent as mcfppParser.WhileStatementContext val exp: MCBool = McfppExprVisitor().visit(parent.expression()) as MCBool //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand( "execute " + "if score " + exp.identifier + " " + SbObject.MCS_boolean + " matches 1 " + @@ -414,7 +416,7 @@ class McfppImListener : mcfppBaseListener() { ) //调用完毕,将子函数的栈销毁 Function.currFunction = Function.currFunction.parent[0] - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") Function.addCommand("#while end") } @@ -431,10 +433,10 @@ class McfppImListener : mcfppBaseListener() { f.parent.add(f) Project.global.cache.functions.add(f) //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand(Commands.Function(f)) //调用完毕,将子函数的栈销毁 - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") Function.currFunction = f //后续块中的命令解析到递归的函数中 } @@ -447,7 +449,7 @@ class McfppImListener : mcfppBaseListener() { val exp: MCBool = McfppExprVisitor().visit(ctx.expression()) as MCBool if (exp.isConcrete && exp.value) { //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand(Commands.Function(Function.currFunction)) Project.logger.warn( "The condition is always true. " + @@ -455,7 +457,7 @@ class McfppImListener : mcfppBaseListener() { ) } else if (exp.isConcrete) { //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand("#" + Commands.Function(Function.currFunction)) Project.logger.warn( "The condition is always false. " + @@ -463,17 +465,17 @@ class McfppImListener : mcfppBaseListener() { ) } else { //给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand( "execute " + "if score " + exp.identifier + " " + SbObject.MCS_boolean + " matches 1 " + "run " + Commands.Function(Function.currFunction) ) } - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") //调用完毕,将子函数的栈销毁 Function.currFunction = Function.currFunction.parent[0] - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") Function.addCommand("#do while end") } @@ -484,7 +486,7 @@ class McfppImListener : mcfppBaseListener() { @Override override fun enterForStatement(ctx: mcfppParser.ForStatementContext?) { Function.addCommand("#for start") - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") val forFunc: Function = InternalFunction("_for_", Function.currFunction) forFunc.parent.add(Function.currFunction) Project.global.cache.functions.add(forFunc) @@ -495,7 +497,7 @@ class McfppImListener : mcfppBaseListener() { @Override override fun exitForStatement(ctx: mcfppParser.ForStatementContext?) { Function.currFunction = Function.currFunction.parent[0] - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") Function.addCommand("#for end") } @@ -541,21 +543,21 @@ class McfppImListener : mcfppBaseListener() { f.parent.add(f) Project.global.cache.functions.add(f) if (exp.isConcrete && exp.value) { - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand(Commands.Function(f)) Project.logger.warn( "The condition is always true. " + " at " + Project.currFile.name + " line: " + ctx.getStart().line ) } else if (exp.isConcrete) { - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand("#" + Commands.Function(f)) Project.logger.warn( "The condition is always false. " + " at " + Project.currFile.name + " line: " + ctx.getStart().line ) } else { - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand( "execute " + "if score " + exp.identifier + " " + SbObject.MCS_boolean + " matches 1 " + @@ -563,7 +565,7 @@ class McfppImListener : mcfppBaseListener() { ) } //调用完毕,将子函数的栈销毁。这条命令仍然是在for函数中的。 - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") Function.currFunction = f //后续块中的命令解析到递归的函数中 } @@ -581,16 +583,18 @@ class McfppImListener : mcfppBaseListener() { val parent: mcfppParser.ForStatementContext = ctx.parent as mcfppParser.ForStatementContext val exp: MCBool = McfppExprVisitor().visit(parent.forControl().expression()) as MCBool //这里就需要给子函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand( "execute " + "if score " + exp.identifier + " " + SbObject.MCS_boolean + " matches 1 " + "run " + Commands.Function(Function.currFunction) ) //调用完毕,将子函数的栈销毁 - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") Function.currFunction = Function.currFunction.parent[0] } +//endregion + @Override override fun exitOrgCommand(ctx: mcfppParser.OrgCommandContext) { @@ -621,14 +625,14 @@ class McfppImListener : mcfppBaseListener() { f.parent.add(f) Project.global.cache.functions.add(f) //给函数开栈 - Function.addCommand("data modify storage mcfpp:system " + Project.name + ".stack_frame prepend value {}") + Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}") Function.addCommand( "execute " + "unless score " + temp!!.identifier + " " + SbObject.MCS_boolean + " matches 1 " + "run " + Commands.Function(f) ) //调用完毕,将子函数的栈销毁 - Function.addCommand("data remove storage mcfpp:system " + Project.name + ".stack_frame[0]") + Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]") Function.currFunction = f //后续块中的命令解析到递归的函数中 } } diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/NativeConstructor.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/NativeConstructor.kt index 9f660c85..4c56bdb7 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/NativeConstructor.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/NativeConstructor.kt @@ -5,7 +5,7 @@ import top.alumopper.mcfpp.lang.Var class NativeConstructor(cls: Class) : Constructor(cls), Native { @Override - override operator fun invoke(args: ArrayList, lineNo: Int, cls: ClassPointer) { + override fun invoke(args: ArrayList, lineNo: Int, cls: ClassPointer) { TODO() } } \ No newline at end of file diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/NativeFunction.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/NativeFunction.kt index aa548b21..e06e8c6c 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/NativeFunction.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/NativeFunction.kt @@ -51,7 +51,7 @@ class NativeFunction(name: String, javaMethod: mcfppParser.JavaReferContext?) : } @Override - override operator fun invoke(args: ArrayList, lineNo: Int) { + override fun invoke(args: ArrayList, lineNo: Int) { val argsArray = arrayOfNulls(args.size) args.toArray(argsArray) try { @@ -64,7 +64,7 @@ class NativeFunction(name: String, javaMethod: mcfppParser.JavaReferContext?) : } @Override - override operator fun invoke(args: ArrayList, lineNo: Int, cls: ClassPointer) { + override fun invoke(args: ArrayList, lineNo: Int, cls: ClassPointer) { val argsArray = arrayOfNulls(args.size) args.toArray(argsArray) try { diff --git a/src/main/kotlin/top/alumopper/mcfpp/test/NashornTest.kt b/src/main/kotlin/top/alumopper/mcfpp/test/NashornTest.kt new file mode 100644 index 00000000..5123b549 --- /dev/null +++ b/src/main/kotlin/top/alumopper/mcfpp/test/NashornTest.kt @@ -0,0 +1,15 @@ +package top.alumopper.mcfpp.test + +import javax.script.ScriptEngineManager + + +object Hello { + @Throws(Throwable::class) + @JvmStatic + fun main(args: Array) { + val engineManager = ScriptEngineManager() + val engine = engineManager.getEngineByName("nashorn") + engine.eval("function sum(a, b) { return a + b; }") + println(engine.eval("sum(1, 2);")) + } +} \ No newline at end of file diff --git a/test/.mclib b/test/.mclib index a37f8e33..dedcd292 100644 --- a/test/.mclib +++ b/test/.mclib @@ -1,4 +1,7 @@ [function] -proj:qwq +mcfpp:load +mcfpp:tick +test:qwq +test:_if_de308ca8-c291-43d6-8fb4-7c9690c6c245 [class] [end] diff --git a/test/proj.json b/test/proj.json index b113ad3b..59b90aa3 100644 --- a/test/proj.json +++ b/test/proj.json @@ -2,5 +2,6 @@ "files": [ "*" ], - "description": "qwq" + "description": "qwq", + "namespace": "test" } \ No newline at end of file diff --git a/test/test.mcfpp b/test/test.mcfpp index c68de21f..cbc75de4 100644 --- a/test/test.mcfpp +++ b/test/test.mcfpp @@ -2,4 +2,7 @@ func qwq(){ const int qwq = 9; int p; int i = p + qwq; + if(i == 5){ + int q = i; + } } \ No newline at end of file From cfe02efaeefce927a523b87f40ce374db0119630 Mon Sep 17 00:00:00 2001 From: Alumopper <609255325@qq.com> Date: Wed, 3 May 2023 23:21:23 +0800 Subject: [PATCH 003/128] =?UTF-8?q?logger=E7=9A=84=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/top/alumopper/mcfpp/Project.kt | 37 ++++- .../top/alumopper/mcfpp/command/Commands.kt | 1 - .../kotlin/top/alumopper/mcfpp/lang/Var.kt | 12 +- .../kotlin/top/alumopper/mcfpp/lib/Cache.kt | 13 +- .../top/alumopper/mcfpp/lib/Function.kt | 29 ++-- .../alumopper/mcfpp/lib/McfppExprVisitor.kt | 81 +++++------ .../alumopper/mcfpp/lib/McfppFileVisitor.kt | 90 ++++-------- .../alumopper/mcfpp/lib/McfppFuncVisitor.kt | 1 + .../alumopper/mcfpp/lib/McfppImListener.kt | 129 +++++++----------- 9 files changed, 165 insertions(+), 228 deletions(-) diff --git a/src/main/kotlin/top/alumopper/mcfpp/Project.kt b/src/main/kotlin/top/alumopper/mcfpp/Project.kt index ae4ff83c..7bf40b4b 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/Project.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/Project.kt @@ -1,6 +1,7 @@ package top.alumopper.mcfpp import com.alibaba.fastjson2.* +import org.antlr.v4.runtime.ParserRuleContext import org.apache.logging.log4j.* import top.alumopper.mcfpp.io.McfppFileReader import top.alumopper.mcfpp.lib.* @@ -12,9 +13,11 @@ import java.io.* * 同时,这个工程文件的名字也是此文件编译生成的数据包的命名空间。 */ object Project { - var logger: Logger = LogManager.getLogger("mcfpp") + private var logger: Logger = LogManager.getLogger("mcfpp") //TODO config + var ctx: ParserRuleContext? = null + /** * 工程的根目录 */ @@ -37,7 +40,7 @@ object Project { /** * 数据包的描述。原始Json文本 TODO */ - var description: String? = null + private var description: String? = null /** * 工程包含的所有引用 @@ -62,12 +65,12 @@ object Project { /** * 工程中的总错误数量 */ - var errorCount = 0 + private var errorCount = 0 /** * 工程中的总警告数量 */ - var warningCount = 0 + private var warningCount = 0 /** * 全局缓存 @@ -251,6 +254,32 @@ object Project { } } + fun debug(msg: String){ + logger.debug( + msg + " at " + currFile.name + " line: " + ctx!!.getStart().line + ) + } + + fun info(msg: String){ + logger.info( + msg + " at " + currFile.name + " line: " + ctx!!.getStart().line + ) + } + + fun warn(msg: String){ + logger.warn( + msg + " at " + currFile.name + " line: " + ctx!!.getStart().line + ) + warningCount ++ + } + + fun error(msg: String){ + logger.error( + msg + " at " + currFile.name + " line: " + ctx!!.getStart().line + ) + errorCount ++ + } + /** * 获取数据包版本 * @param version 版本字符串 diff --git a/src/main/kotlin/top/alumopper/mcfpp/command/Commands.kt b/src/main/kotlin/top/alumopper/mcfpp/command/Commands.kt index 22e5867e..35798b91 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/command/Commands.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/command/Commands.kt @@ -9,7 +9,6 @@ import top.alumopper.mcfpp.lang.MCInt * 尽量不要打开或编辑这个文件,不然会感受痛苦。 * 尽量少地使用这个文件中的内容 */ -@Deprecated("") object Commands { fun Function(function: Function): String { return "function " + function.namespaceID.lowercase(Locale.getDefault()) diff --git a/src/main/kotlin/top/alumopper/mcfpp/lang/Var.kt b/src/main/kotlin/top/alumopper/mcfpp/lang/Var.kt index 16db0e27..40576b1b 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lang/Var.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lang/Var.kt @@ -149,11 +149,7 @@ abstract class Var : ClassMember, Cloneable { //取出类 val type: Class? = Project.global.cache.classes.getOrDefault(cls, null) if (type == null) { - Project.logger.error( - "Undefined class:" + cls + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.errorCount++ + Project.error("Undefined class:$cls") } assert(type != null) `var` = ClassPointer(type!!, container, ctx.Identifier().text) @@ -196,11 +192,7 @@ abstract class Var : ClassMember, Cloneable { //取出类 val type: Class? = Project.global.cache.classes.getOrDefault(clsType, null) if (type == null) { - Project.logger.error( - "Undefined class:" + clsType + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.errorCount++ + Project.error("Undefined class:$clsType") } assert(type != null) val classPointer = ClassPointer(type!!, cls, ctx.Identifier().text) diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/Cache.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/Cache.kt index 5cf072b7..8a7fda55 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/Cache.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/Cache.kt @@ -8,20 +8,19 @@ import java.util.* /** * 一个缓存。在编译过程中,编译器读取到的变量,函数等会以键值对的方式储存在其中。键为函数的id或者变量的 * 标识符,而值则是这个函数或者变量的对象。 + * * 缓存应该是一个链式的结构,主要分为如下几种情况:

- * 类的静态变量 ---> 类的成员变量 --> 函数 ---> 匿名内部函数

- * 类的静态变量 ---> 静态函数 ---> 匿名内部函数

- * 函数 ---> 匿名内部函数

- * 寻找变量的时候,应当从当前的作用域开始寻找。

+ * * 类的静态变量 ---> 类的成员变量 --> 函数 ---> 匿名内部函数

* + * * 类的静态变量 ---> 静态函数 ---> 匿名内部函数

+ * + * * 函数 ---> 匿名内部函数

+ * 寻找变量的时候,应当从当前的作用域开始寻找。

* * 变量和类都分别储存在一张哈希表中,键名即它在声明的时候的名字,而值则代表了它的对象。 * 值得注意的是,变量声明时的名字虽然和最终编译出的名字有关,但不相同。 * - * - * * 函数储存在一个列表中 - * */ class Cache { /** diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/Function.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/Function.kt index 2c336a87..63835778 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/Function.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/Function.kt @@ -44,19 +44,19 @@ import java.lang.NullPointerException * * } * * } * 位置①:现在父函数还没调用 funA,堆栈情况是:

- * low address [ [父函数栈帧] ... ] high address

+ * low address [ \[父函数栈帧] ... ] high address

* (执行 funA(?) )

* 位置②:当父函数调用 funA 时,会从栈顶开一块新的空间来保存 funA 的栈帧,堆栈情况是:

- * low address [ [funA栈帧] [父函数栈帧] ... ] high address

+ * low address [ \[funA栈帧] \[父函数栈帧] ... ] high address

* (执行 a = a + 1)

* (执行 funB(a) )

* 位置③:当 funA 调用 funB 时,会从栈顶开一块新的空间来保存 funB 的栈帧,堆栈情况是:

- * low address [ [funB栈帧] [funA栈帧] [父函数栈帧] ... ] high address

+ * low address [ \[funB栈帧] \[funA栈帧] \[父函数栈帧] ... ] high address

* (执行 a = a + 2)

* 位置④:funB 调用结束,funB 的栈帧被销毁,程序回到 funA 继续执行,堆栈情况是:

- * low address [ [funA栈帧] [父函数栈帧] ... ] high address

+ * low address [ \[funA栈帧] \[父函数栈帧] ... ] high address

* 位置⑤:funA 调用结束,funA 的栈帧被销毁,程序回到 父函数 继续执行,堆栈情况是:

- * low address [ [父函数栈帧] ... ] high address

+ * low address [ \[父函数栈帧] ... ] high address

* 我们会发现,funA 和 funB 使用的变量都叫 a,但它们的位置是不同的,此处当前函数只会在属于自己的栈帧的内存空间上 * 操作,不同函数之间的变量之所以不会互相干扰,也是因为它们在栈中使用的位置不同,此 a 非彼 a * @@ -186,10 +186,10 @@ open class Function : ClassMember, CacheContainer { namespace = cls.namespace parentClass = cls isClassMember = true - if (isStatic) { - cache = Cache(cls.cache, this) + cache = if (isStatic) { + Cache(cls.cache, this) } else { - cache = Cache(cls.staticCache, this) + Cache(cls.staticCache, this) } } @@ -206,7 +206,7 @@ open class Function : ClassMember, CacheContainer { * 获取这个函数的id,它包含了这个函数的路径和函数的标识符。每一个函数的id都是唯一的 * @return 函数id */ - fun GetID(): String { + fun getID(): String { return name } @@ -404,10 +404,11 @@ open class Function : ClassMember, CacheContainer { /** * 当一个函数被break或continue截断的时候,使用此标记,表示此函数执行完毕后的函数应当重新建立一个匿名内部函数, * 从而实现break和continue的逻辑控制。 - * 即同时满足isEnd == false和isLastFunctionEnd = 2的时候进入新的匿名break/continue内部函数 - * 0 未截断 - * 1 被截断,需要进入匿名函数 - * 2 被截断,但是已经在匿名函数里面了 + * + * 即同时满足isEnd == false和isLastFunctionEnd = 2的时候进入新的匿名break/continue内部函数
+ * * 0 未截断 + * * 1 被截断,需要进入匿名函数 + * * 2 被截断,但是已经在匿名函数里面了 */ var isLastFunctionEnd = 0 @@ -428,7 +429,7 @@ open class Function : ClassMember, CacheContainer { */ fun addCommand(str: String?) { if(this.equals(nullFunction)){ - Project.logger.warn("Unexpected command added to NullFunction") + Project.warn("Unexpected command added to NullFunction") throw NullPointerException() } if (!currFunction.isEnd) { diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppExprVisitor.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppExprVisitor.kt index bc1ed9dd..1e5fa881 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppExprVisitor.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppExprVisitor.kt @@ -19,6 +19,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { */ @Override override fun visitExpression(ctx: mcfppParser.ExpressionContext): Var? { + Project.ctx = ctx return visit(ctx.conditionalOrExpression()) } //TODO 三目表达式。可能会实现,但是泠雪是懒狐,不想做。 @@ -37,6 +38,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { */ @Override override fun visitConditionalOrExpression(ctx: mcfppParser.ConditionalOrExpressionContext): Var? { + Project.ctx = ctx var re: Var? = visit(ctx.conditionalAndExpression(0)) for (i in 1 until ctx.conditionalAndExpression().size) { val b: Var? = visit(ctx.conditionalAndExpression(i)) @@ -57,6 +59,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { //和 @Override override fun visitConditionalAndExpression(ctx: mcfppParser.ConditionalAndExpressionContext): Var? { + Project.ctx = ctx var re: Var? = visit(ctx.equalityExpression(0)) for (i in 1 until ctx.equalityExpression().size) { val b: Var? = visit(ctx.equalityExpression(i)) @@ -77,6 +80,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { //等于或不等于 @Override override fun visitEqualityExpression(ctx: mcfppParser.EqualityExpressionContext): Var? { + Project.ctx = ctx var re: Var? = visit(ctx.relationalExpression(0)) for (i in 1 until ctx.relationalExpression().size) { val b: Var? = visit(ctx.relationalExpression(i)) @@ -104,6 +108,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { */ @Override override fun visitRelationalExpression(ctx: mcfppParser.RelationalExpressionContext): Var? { + Project.ctx = ctx var re: Var? = visit(ctx.additiveExpression(0)) if (ctx.additiveExpression().size != 1) { val b: Var? = visit(ctx.additiveExpression(1)) @@ -128,6 +133,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { */ @Override override fun visitAdditiveExpression(ctx: mcfppParser.AdditiveExpressionContext): Var? { + Project.ctx = ctx var re: Var? = visit(ctx.multiplicativeExpression(0)) for (i in 1 until ctx.multiplicativeExpression().size) { val b: Var? = visit(ctx.multiplicativeExpression(i)) @@ -160,6 +166,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { //乘法 @Override override fun visitMultiplicativeExpression(ctx: mcfppParser.MultiplicativeExpressionContext): Var? { + Project.ctx = ctx var re: Var? = visit(ctx.unaryExpression(0)) for (i in 1 until ctx.unaryExpression().size) { val b: Var? = visit(ctx.unaryExpression(i)) @@ -198,6 +205,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { */ @Override override fun visitUnaryExpression(ctx: mcfppParser.UnaryExpressionContext): Var? { + Project.ctx = ctx return if (ctx.basicExpression() != null) { visit(ctx.basicExpression()) } else if (ctx.unaryExpression() != null) { @@ -220,6 +228,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { */ @Override override fun visitCastExpression(ctx: mcfppParser.CastExpressionContext): Var? { + Project.ctx = ctx val a: Var? = visit(ctx.unaryExpression()) return a!!.cast(ctx.type().text) } @@ -232,6 +241,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { //基本表达式 @Override override fun visitBasicExpression(ctx: mcfppParser.BasicExpressionContext): Var? { + Project.ctx = ctx return if (ctx.primary() != null) { visit(ctx.primary()) } else { @@ -242,19 +252,22 @@ class McfppExprVisitor : mcfppBaseVisitor() { @Override override fun visitVarWithSelector(ctx: mcfppParser.VarWithSelectorContext): Var? { + Project.ctx = ctx + Project.ctx = ctx var curr: CanSelectMember curr = if (ctx.`var`() != null) { //Var - Function.currFunction!!.getVar(ctx.text) as ClassPointer + if(Function.currFunction.getVar(ctx.text) is ClassPointer){ + Function.currFunction.getVar(ctx.text) as ClassPointer + }else{ + Project.error(ctx.text + "is not a class pointer") + throw ArgumentNotMatchException(ctx.text + "is not a class pointer") + } } else { //ClassName - val qwq: Class? = Project.global.cache.classes.getOrDefault(ctx.className().text, null) + val qwq: Class? = Project.global.cache.classes[ctx.className().text] if (qwq == null) { - Project.logger.error( - "Undefined class:" + ctx.className().text + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.errorCount++ + Project.error("Undefined class:" + ctx.className().text) } ClassType(qwq!!) } @@ -264,11 +277,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { while (i < ctx.selector().size) { member = curr.getVarMember(ctx.selector(i).text.substring(1)) if (member == null) { - Project.logger.error( - "Undefined member " + ctx.selector(i).text + " in class " + curr.Class()!!.identifier + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.errorCount++ + Project.error("Undefined member " + ctx.selector(i).text + " in class " + curr.Class()!!.identifier) } i++ curr = (member as CanSelectMember?)!! @@ -283,6 +292,7 @@ class McfppExprVisitor : mcfppBaseVisitor() { */ @Override override fun visitPrimary(ctx: mcfppParser.PrimaryContext): Var? { + Project.ctx = ctx if (ctx.`var`() != null) { //变量 return visit(ctx.`var`()) @@ -306,23 +316,20 @@ class McfppExprVisitor : mcfppBaseVisitor() { */ @Override override fun visitVar(ctx: mcfppParser.VarContext): Var? { + Project.ctx = ctx return if (ctx.Identifier() != null) { // Identifier identifierSuffix* if (ctx.identifierSuffix() == null || ctx.identifierSuffix().size == 0) { //没有数组选取 val qwq: String = ctx.Identifier().text - val re: Var? = Function.currFunction!!.getVar(qwq) + val re: Var? = Function.currFunction.getVar(qwq) //TODO 从类的成员中选取。待定特性。 /* if(re == null && Function.currFunction.Class() != null){ re = Function.currFunction.Class().getMemberVar(ctx.getText()); } */if (re == null) { - Project.logger.error( - "Undefined variable:" + qwq + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.errorCount++ + Project.error("Undefined variable:$qwq") } re } else { @@ -343,13 +350,10 @@ class McfppExprVisitor : mcfppBaseVisitor() { @Override override fun visitConstructorCall(ctx: mcfppParser.ConstructorCallContext): Var? { + Project.ctx = ctx val cls: Class? = Project.global.cache.classes.getOrDefault(ctx.className().text, null) if (cls == null) { - Project.logger.error( - "Undefined class:" + ctx.className().text + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.errorCount++ + Project.error("Undefined class:" + ctx.className().text) } //获取参数列表 //参数获取 @@ -366,44 +370,23 @@ class McfppExprVisitor : mcfppBaseVisitor() { return try { cls.newInstance(args) } catch (e: InvocationTargetException) { - Project.logger.error( - "Catch Exception when instantiate native class: " + cls.cls + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.logger.error(e.message + " " + e.cause + "\n") + Project.error("Catch Exception when instantiate native class: " + cls.cls + "\n" + e.message + " " + e.cause + "\n") throw RuntimeException(e) } catch (e: InstantiationException) { - Project.logger.error( - "Catch Exception when instantiate native class: " + cls.cls + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.logger.error(e.message + " " + e.cause + "\n") + Project.error("Catch Exception when instantiate native class: " + cls.cls + "\n" + e.message + " " + e.cause + "\n") throw RuntimeException(e) } catch (e: IllegalAccessException) { - Project.logger.error( - "Catch Exception when instantiate native class: " + cls.cls + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.logger.error(e.message + " " + e.cause + "\n") + Project.error("Catch Exception when instantiate native class: " + cls.cls + "\n" + e.message + " " + e.cause + "\n") throw RuntimeException(e) } catch (e: NoSuchMethodException) { - Project.logger.error( - "Catch Exception when instantiate native class: " + cls.cls + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.logger.error(e.message + " " + e.cause + "\n") + Project.error("Catch Exception when instantiate native class: " + cls.cls + "\n" + e.message + " " + e.cause + "\n") throw RuntimeException(e) } } cls!! val constructor = cls.getConstructor(FunctionParam.getVarTypes(args)) if (constructor == null) { - Project.logger.error( - "No constructor like: " + FunctionParam.getVarTypes(args) + " defined in class " + ctx.className() - .text + - " at " + Project.currFile.name + " line: " + ctx.getStart().line - ) - Project.errorCount++ + Project.error("No constructor like: " + FunctionParam.getVarTypes(args) + " defined in class " + ctx.className().text) throw FunctionNotDefineException() } //调用构造函数 diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFileVisitor.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFileVisitor.kt index bb384997..e459490b 100644 --- a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFileVisitor.kt +++ b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFileVisitor.kt @@ -14,6 +14,7 @@ import java.util.* * 在编译工程之前,应当首先将所有文件中的资源全部遍历一次并写入缓存。 */ class McfppFileVisitor : mcfppBaseVisitor() { + /** * 遍历整个文件。一个文件包含了命名空间的声明,函数的声明,类的声明以及全局变量的声明。全局变量是可以跨文件调用的。 *
@@ -30,6 +31,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      */
     @Override
     override fun visitCompilationUnit(ctx: mcfppParser.CompilationUnitContext): Any? {
+        Project.ctx = ctx
         //命名空间
         if (ctx.namespaceDeclaration() != null) {
             Project.currNamespace = ctx.namespaceDeclaration()!!.Identifier().text
@@ -50,6 +52,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      */
     @Override
     override fun visitTypeDeclaration(ctx: mcfppParser.TypeDeclarationContext): Any? {
+        Project.ctx = ctx
         visit(ctx.classOrFunctionDeclaration())
         return null
     }
@@ -68,6 +71,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      */
     @Override
     override fun visitClassOrFunctionDeclaration(ctx: mcfppParser.ClassOrFunctionDeclarationContext): Any? {
+        Project.ctx = ctx
         if (ctx.classDeclaration() != null) {
             visit(ctx.classDeclaration())
         } else if (ctx.functionDeclaration() != null) {
@@ -86,15 +90,12 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      * @return null
      */
     override fun visitNativeClassDeclaration(ctx: mcfppParser.NativeClassDeclarationContext): Any? {
+        Project.ctx = ctx
         //注册类
         val identifier: String = ctx.className().text
         return if (Project.global.cache.classes.containsKey(identifier)) {
             //重复声明
-            Project.logger.error(
-                "The class has extended " + Class.currClass!!.identifier +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
-            Project.errorCount++
+            Project.error("The class has extended " + Class.currClass!!.identifier)
             throw ClassDuplicationException()
         } else {
             //获取它指向的java类
@@ -123,15 +124,12 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      */
     @Override
     override fun visitClassDeclaration(ctx: mcfppParser.ClassDeclarationContext): Any? {
+        Project.ctx = ctx
         //注册类
         val identifier: String = ctx.className(0).text
         if (Project.global.cache.classes.containsKey(identifier)) {
             //重复声明
-            Project.logger.error(
-                "The class has extended " + Class.currClass!!.identifier +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
-            Project.errorCount++
+            Project.error("The class has extended " + Class.currClass!!.identifier)
             throw ClassDuplicationException()
         } else {
             //如果没有声明过这个类
@@ -145,11 +143,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
                 if (Project.global.cache.classes.containsKey(ctx.className(1).text)) {
                     cls.parent = Project.global.cache.classes[ctx.className(1).text]
                 } else {
-                    Project.logger.error(
-                        "Undefined class: " + ctx.className(1).text +
-                                " at " + Project.currFile.name + " line: " + ctx.getStart().line
-                    )
-                    Project.errorCount++
+                    Project.error("Undefined class: " + ctx.className(1).text)
                 }
             }
             Project.global.cache.classes[identifier] = cls
@@ -193,6 +187,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
 
     @Override
     override fun visitStaticClassMemberDeclaration(ctx: mcfppParser.StaticClassMemberDeclarationContext): Any? {
+        Project.ctx = ctx
         val m = visit(ctx.classMember()) as ClassMember
         //访问修饰符
         if (ctx.accessModifier() != null) {
@@ -215,6 +210,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      */
     @Override
     override fun visitClassMemberDeclaration(ctx: mcfppParser.ClassMemberDeclarationContext): Any? {
+        Project.ctx = ctx
         val m = visit(ctx.classMember()) as ClassMember
         //访问修饰符
         if (ctx.accessModifier() != null) {
@@ -228,6 +224,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
 
     @Override
     override fun visitClassMember(ctx: mcfppParser.ClassMemberContext): Any? {
+        Project.ctx = ctx
         return if (ctx.nativeFuncDeclaration() != null) {
             visit(ctx.nativeFuncDeclaration())
         } else if (ctx.classFunctionDeclaration() != null) {
@@ -248,6 +245,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      */
     @Override
     override fun visitClassFunctionDeclaration(ctx: mcfppParser.ClassFunctionDeclarationContext): Any {
+        Project.ctx = ctx
         //创建函数对象
         val f = Function(
             ctx.Identifier().text,
@@ -263,12 +261,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
                 f
             )
         ) {
-            Project.logger.error(
-                "Already defined function:" + ctx.Identifier()
-                    .text + "in class " + Class.currClass!!.identifier +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
-            Project.errorCount++
+            Project.error("Already defined function:" + ctx.Identifier().text + "in class " + Class.currClass!!.identifier)
             Function.currFunction = Function.nullFunction
         }
         return f
@@ -281,6 +274,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      */
     @Override
     override fun visitConstructorDeclaration(ctx: mcfppParser.ConstructorDeclarationContext): Any? {
+        Project.ctx = ctx
         //是构造函数
         //创建构造函数对象,注册函数
         var f: Constructor? = null
@@ -288,10 +282,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
             f = Constructor(Class.currClass!!)
             Class.currClass!!.addConstructor(f)
         } catch (e: FunctionDuplicationException) {
-            Project.logger.error(
-                "Already defined function: " + ctx.className().text + "(" + ctx.parameterList().text + ")" +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.error("Already defined function: " + ctx.className().text + "(" + ctx.parameterList().text + ")")
         }
         assert(f != null)
         if (ctx.parameterList() != null) {
@@ -302,6 +293,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
 
     @Override
     override fun visitNativeConstructorDeclaration(ctx: mcfppParser.NativeConstructorDeclarationContext?): Any? {
+        Project.ctx = ctx
         //TODO
         throw TODOException("")
     }
@@ -313,6 +305,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      */
     @Override
     override fun visitFunctionDeclaration(ctx: mcfppParser.FunctionDeclarationContext): Any? {
+        Project.ctx = ctx
         //创建函数对象
         val f: Function
         //是否是内联函数
@@ -367,19 +360,11 @@ class McfppFileVisitor : mcfppBaseVisitor() {
         if (Project.global.cache.getFunction(f.namespace, f.name, f.paramTypeList) == null) {
             Project.global.cache.functions.add(f)
         } else {
-            Project.logger.error(
-                "Already defined function:" + f.namespaceID +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
-            Project.errorCount++
+            Project.error("Already defined function:" + f.namespaceID)
             Function.currFunction = Function.nullFunction
         }
         if (f.isEntrance && ctx.parameterList()!!.parameter().size != 0) {
-            Project.logger.error(
-                "Entrance function shouldn't have parameter:" + f.namespaceID +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
-            Project.errorCount++
+            Project.error("Entrance function shouldn't have parameter:" + f.namespaceID)
         }
         return null
     }
@@ -391,25 +376,17 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      */
     @Override
     override fun visitNativeFuncDeclaration(ctx: mcfppParser.NativeFuncDeclarationContext): Any? {
+        Project.ctx = ctx
         val nf: NativeFunction = try {
             NativeFunction(ctx.Identifier().text, ctx.javaRefer())
         } catch (e: IllegalFormatException) {
-            Project.logger.error(
-                "Illegal Java Method Name:" + e.message +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.error("Illegal Java Method Name:" + e.message)
             return null
         } catch (e: ClassNotFoundException) {
-            Project.logger.error(
-                "Cannot find java class:" + e.message +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.error("Cannot find java class:" + e.message)
             return null
         } catch (e: NoSuchMethodException) {
-            Project.logger.error(
-                "No such method:" + e.message +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.error("No such method:" + e.message)
             return null
         }
         if (ctx.parameterList() != null) {
@@ -421,11 +398,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
             if (!Project.global.cache.functions.contains(nf)) {
                 Project.global.cache.functions.add(nf)
             } else {
-                Project.logger.error(
-                    "Already defined function:" + ctx.Identifier().text +
-                            " at " + Project.currFile.name + " line: " + ctx.getStart().line
-                )
-                Project.errorCount++
+                Project.error("Already defined function:" + ctx.Identifier().text)
                 Function.currFunction = Function.nullFunction
             }
             return nf
@@ -443,6 +416,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
      */
     @Override
     override fun visitFieldDeclaration(ctx: mcfppParser.FieldDeclarationContext): Any {
+        Project.ctx = ctx
         //变量生成
         val `var`: Var = Var.build(ctx, Class.currClass!!)!!
         //只有可能是类变量
@@ -450,11 +424,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
                 ctx.Identifier().text
             ) || Class.currClass!!.staticCache!!.containVar(ctx.Identifier().text)
         ) {
-            Project.logger.error(
-                "Duplicate defined variable name:" + ctx.Identifier().text +
-                        " at " + Project.currFile.name + " line:" + ctx.getStart().line
-            )
-            Project.errorCount++
+            Project.error("Duplicate defined variable name:" + ctx.Identifier().text)
             throw VariableDuplicationException()
         }
         //变量的初始化
@@ -466,11 +436,7 @@ class McfppFileVisitor : mcfppBaseVisitor() {
             try {
                 `var`.assign(init)
             } catch (e: VariableConverseException) {
-                Project.logger.error(
-                    "Cannot convert " + init.javaClass + " to " + `var`.javaClass +
-                            " at " + Class.currClass!!.identifier + " line:" + ctx.getStart().line
-                )
-                Project.errorCount++
+                Project.error("Cannot convert " + init.javaClass + " to " + `var`.javaClass)
                 Function.currFunction = Function.nullFunction
                 throw VariableConverseException()
             }
diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFuncVisitor.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFuncVisitor.kt
index db9b6e5a..d6b0ea48 100644
--- a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFuncVisitor.kt
+++ b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppFuncVisitor.kt
@@ -8,6 +8,7 @@ import top.alumopper.mcfpp.Project
  */
 class McfppFuncVisitor : mcfppBaseVisitor() {
     fun getFunction(ctx: mcfppParser.FunctionCallContext, args: ArrayList): Function? {
+        Project.ctx = ctx
         return if (ctx.namespaceID() != null && ctx.basicExpression() == null) {
             val qwq: Function? = if (ctx.namespaceID().Identifier().size == 1) {
                 Project.global.cache.getFunction(Project.currNamespace, ctx.namespaceID().Identifier(0).text, args)
diff --git a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppImListener.kt b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppImListener.kt
index b284f467..7ac389a6 100644
--- a/src/main/kotlin/top/alumopper/mcfpp/lib/McfppImListener.kt
+++ b/src/main/kotlin/top/alumopper/mcfpp/lib/McfppImListener.kt
@@ -14,6 +14,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun enterFunctionBody(ctx: mcfppParser.FunctionBodyContext) {
+        Project.ctx = ctx
         var f: Function
         //获取函数对象
         if (ctx.parent.parent !is mcfppParser.ClassMemberContext) {
@@ -63,6 +64,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitFunctionBody(ctx: mcfppParser.FunctionBodyContext?) {
+        Project.ctx = ctx
         if (Class.currClass == null) {
             //不在类中
             Function.currFunction = Function.nullFunction
@@ -77,6 +79,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitNamespaceDeclaration(ctx: mcfppParser.NamespaceDeclarationContext) {
+        Project.ctx = ctx
         Project.currNamespace = ctx.Identifier().text
     }
 
@@ -86,8 +89,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitFieldDeclaration(ctx: mcfppParser.FieldDeclarationContext) {
-        //变量生成
-
+        Project.ctx = ctx
         //变量生成
         val `var`: Var = if (ctx.parent is mcfppParser.ClassMemberContext) {
             return
@@ -98,11 +100,7 @@ class McfppImListener : mcfppBaseListener() {
         //变量注册
         //一定是函数变量
         if (!Function.currFunction.cache.putVar(ctx.Identifier().text, `var`)) {
-            Project.logger.error(
-                "Duplicate defined variable name:" + ctx.Identifier().text +
-                        " at " + Project.currFile.name + " line:" + ctx.getStart().line
-            )
-            Project.errorCount++
+            Project.error("Duplicate defined variable name:" + ctx.Identifier().text)
             throw VariableDuplicationException()
         }
         Function.addCommand(
@@ -115,11 +113,7 @@ class McfppImListener : mcfppBaseListener() {
             try {
                 `var`.assign(init)
             } catch (e: VariableConverseException) {
-                Project.logger.error(
-                    "Cannot convert " + init.javaClass + " to " + `var`.javaClass +
-                            " at " + Function.currFunction.GetID() + " line:" + ctx.getStart().line
-                )
-                Project.errorCount++
+                Project.error("Cannot convert " + init.javaClass + " to " + `var`.javaClass)
                 throw VariableConverseException()
             }
         }
@@ -131,14 +125,11 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitStatementExpression(ctx: mcfppParser.StatementExpressionContext) {
+        Project.ctx = ctx
         Function.addCommand("#" + ctx.text)
         val left: Var = McfppExprVisitor().visit(ctx.basicExpression())!!
         if (left.isConst == Var.ConstStatus.ASSIGNED) {
-            Project.logger.error(
-                "Cannot assign a constant repeatedly: " + left.key +
-                        " at " + Function.currFunction.GetID() + " line:" + ctx.getStart().line
-            )
-            Project.errorCount++
+            Project.error("Cannot assign a constant repeatedly: " + left.key)
             throw ConstChangeException()
         } else if (left.isConst == Var.ConstStatus.NULL) {
             left.isConst = Var.ConstStatus.ASSIGNED
@@ -147,11 +138,7 @@ class McfppImListener : mcfppBaseListener() {
         try {
             left.assign(right)
         } catch (e: VariableConverseException) {
-            Project.logger.error(
-                "Cannot convert " + right.javaClass + " to " + left.javaClass +
-                        " at " + Function.currFunction.GetID() + " line:" + ctx.getStart().line
-            )
-            Project.errorCount++
+            Project.error("Cannot convert " + right.javaClass + " to " + left.javaClass)
             throw VariableConverseException()
         }
     }
@@ -162,14 +149,11 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitSelfAddOrMinusStatement(ctx: mcfppParser.SelfAddOrMinusStatementContext) {
+        Project.ctx = ctx
         Function.addCommand("#" + ctx.text)
         val re: Var? = Function.currFunction.getVar(ctx.selfAddOrMinusExpression().Identifier().text)
         if (re == null) {
-            Project.logger.error(
-                "Undefined variable:" + ctx.selfAddOrMinusExpression().Identifier().text +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
-            Project.errorCount++
+            Project.error("Undefined variable:" + ctx.selfAddOrMinusExpression().Identifier().text)
             throw VariableNotDefineException()
         }
         if (ctx.selfAddOrMinusExpression().op.text.equals("++")) {
@@ -198,6 +182,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitFunctionCall(ctx: mcfppParser.FunctionCallContext) {
+        Project.ctx = ctx
         Function.addCommand("#" + ctx.text)
         //参数获取
         val args: ArrayList = ArrayList()
@@ -208,10 +193,7 @@ class McfppImListener : mcfppBaseListener() {
         //函数对象获取
         val curr = McfppFuncVisitor().getFunction(ctx, FunctionParam.getVarTypes(args))
         if (curr == null) {
-            Project.logger.error(
-                "Function " + ctx.text + " not defined " +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.error("Function " + ctx.text + " not defined ")
             throw FunctionNotDefineException()
         }
         if (curr is NativeFunction) {
@@ -240,6 +222,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun enterIfBlock(ctx: mcfppParser.IfBlockContext) {
+        Project.ctx = ctx
         Function.addCommand("#if start")
         val parent: mcfppParser.IfStatementContext = ctx.parent as mcfppParser.IfStatementContext
         //是if语句,获取参数
@@ -255,16 +238,10 @@ class McfppImListener : mcfppBaseListener() {
                 //给子函数开栈
                 Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
                 Function.addCommand(Commands.Function(f))
-                Project.logger.warn(
-                    "The condition is always true. " +
-                            " at " + Project.currFile.name + " line: " + ctx.getStart().line
-                )
+                Project.warn("The condition is always true. ")
             } else if (exp.isConcrete) {
                 Function.addCommand("#" + Commands.Function(f))
-                Project.logger.warn(
-                    "The condition is always false. " +
-                            " at " + Project.currFile.name + " line: " + ctx.getStart().line
-                )
+                Project.warn("The condition is always false. ")
             } else {
                 //给子函数开栈
                 Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
@@ -292,6 +269,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitIfBlock(ctx: mcfppParser.IfBlockContext?) {
+        Project.ctx = ctx
         Function.currFunction = Function.currFunction.parent[0]
         //调用完毕,将子函数的栈销毁
         Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]")
@@ -304,6 +282,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun enterElseIfStatement(ctx: mcfppParser.ElseIfStatementContext) {
+        Project.ctx = ctx
         Function.addCommand("#else if start")
         //匿名函数的定义
         val f: Function = InternalFunction("_if_", Function.currFunction)
@@ -313,18 +292,12 @@ class McfppImListener : mcfppBaseListener() {
             //给子函数开栈
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
             Function.addCommand("#" + Commands.Function(f))
-            Project.logger.warn(
-                "The condition is always false. " +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.warn("The condition is always false. ")
         } else if (lastBool!!.isConcrete) {
             //给子函数开栈
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
             Function.addCommand(Commands.Function(f))
-            Project.logger.warn(
-                "The condition is always true. " +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.warn("The condition is always true. ")
         } else {
             //给子函数开栈
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
@@ -344,6 +317,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitElseIfStatement(ctx: mcfppParser.ElseIfStatementContext?) {
+        Project.ctx = ctx
         Function.currFunction = Function.currFunction.parent[0]
         //调用完毕,将子函数的栈销毁
         Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]")
@@ -356,6 +330,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun enterWhileBlock(ctx: mcfppParser.WhileBlockContext) {
+        Project.ctx = ctx
         Function.addCommand("#while start")
         val parent: mcfppParser.WhileStatementContext = ctx.parent as mcfppParser.WhileStatementContext
         val exp: MCBool = McfppExprVisitor().visit(parent.expression()) as MCBool
@@ -368,18 +343,12 @@ class McfppImListener : mcfppBaseListener() {
             //给子函数开栈
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
             Function.addCommand(Commands.Function(f))
-            Project.logger.warn(
-                "The condition is always true. " +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.warn("The condition is always true. ")
         } else if (exp.isConcrete) {
             //给子函数开栈
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
             Function.addCommand("#" + Commands.Function(f))
-            Project.logger.warn(
-                "The condition is always false. " +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.warn("The condition is always false. ")
         } else {
             //给子函数开栈
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
@@ -400,6 +369,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitWhileBlock(ctx: mcfppParser.WhileBlockContext) {
+        Project.ctx = ctx
         if (!Function.isBreak && Function.isLastFunctionEnd != 0) {
             Function.currFunction = Function.currFunction.parent[0]
         }
@@ -426,6 +396,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun enterDoWhileBlock(ctx: mcfppParser.DoWhileBlockContext?) {
+        Project.ctx = ctx
         Function.addCommand("#do while start")
         //匿名函数的定义
         val f: Function = InternalFunction("_dowhile_", Function.currFunction)
@@ -446,23 +417,18 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitDoWhileStatement(ctx: mcfppParser.DoWhileStatementContext) {
+        Project.ctx = ctx
         val exp: MCBool = McfppExprVisitor().visit(ctx.expression()) as MCBool
         if (exp.isConcrete && exp.value) {
             //给子函数开栈
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
             Function.addCommand(Commands.Function(Function.currFunction))
-            Project.logger.warn(
-                "The condition is always true. " +
-                        " at " + Project.currFile.name + " line: " + ctx.getStop().line
-            )
+            Project.warn("The condition is always true. ")
         } else if (exp.isConcrete) {
             //给子函数开栈
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
             Function.addCommand("#" + Commands.Function(Function.currFunction))
-            Project.logger.warn(
-                "The condition is always false. " +
-                        " at " + Project.currFile.name + " line: " + ctx.getStop().line
-            )
+            Project.warn("The condition is always false. ")
         } else {
             //给子函数开栈
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
@@ -485,6 +451,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun enterForStatement(ctx: mcfppParser.ForStatementContext?) {
+        Project.ctx = ctx
         Function.addCommand("#for start")
         Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
         val forFunc: Function = InternalFunction("_for_", Function.currFunction)
@@ -496,6 +463,7 @@ class McfppImListener : mcfppBaseListener() {
 
     @Override
     override fun exitForStatement(ctx: mcfppParser.ForStatementContext?) {
+        Project.ctx = ctx
         Function.currFunction = Function.currFunction.parent[0]
         Function.addCommand("data remove storage mcfpp:system " + Project.defaultNamespace + ".stack_frame[0]")
         Function.addCommand("#for end")
@@ -514,6 +482,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun enterForUpdate(ctx: mcfppParser.ForUpdateContext?) {
+        Project.ctx = ctx
         Function.currFunction = InternalFunction("_forblock_", Function.currFunction)
     }
 
@@ -525,6 +494,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitForUpdate(ctx: mcfppParser.ForUpdateContext?) {
+        Project.ctx = ctx
         forupdate = Function.currFunction
         Function.currFunction = forupdate!!.parent[0]
     }
@@ -535,6 +505,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun enterForBlock(ctx: mcfppParser.ForBlockContext) {
+        Project.ctx = ctx
         val parent: mcfppParser.ForStatementContext = ctx.parent as mcfppParser.ForStatementContext
         val exp: MCBool = McfppExprVisitor().visit(parent.forControl().expression()) as MCBool
         //匿名函数的定义。这里才是正式的for函数哦喵
@@ -545,17 +516,11 @@ class McfppImListener : mcfppBaseListener() {
         if (exp.isConcrete && exp.value) {
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
             Function.addCommand(Commands.Function(f))
-            Project.logger.warn(
-                "The condition is always true. " +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.warn( "The condition is always true. ")
         } else if (exp.isConcrete) {
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
             Function.addCommand("#" + Commands.Function(f))
-            Project.logger.warn(
-                "The condition is always false. " +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.warn("The condition is always false. ")
         } else {
             Function.addCommand("data modify storage mcfpp:system " + Project.defaultNamespace + ".stack_frame prepend value {}")
             Function.addCommand(
@@ -575,6 +540,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitForBlock(ctx: mcfppParser.ForBlockContext) {
+        Project.ctx = ctx
         //for update的命令压入
         Function.currFunction.commands.addAll(forupdate!!.commands)
         forupdate = null
@@ -598,6 +564,7 @@ class McfppImListener : mcfppBaseListener() {
 
     @Override
     override fun exitOrgCommand(ctx: mcfppParser.OrgCommandContext) {
+        Project.ctx = ctx
         Function.addCommand(ctx.text.substring(1))
     }
 
@@ -607,11 +574,9 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun enterStatement(ctx: mcfppParser.StatementContext) {
+        Project.ctx = ctx
         if (Function.currFunction.isEnd) {
-            Project.logger.warn(
-                "Unreachable code: " + ctx.text +
-                        " at " + Project.currFile.name + " line: " + ctx.getStart().line
-            )
+            Project.warn("Unreachable code: " + ctx.text)
         }
         if (Function.isLastFunctionEnd == 1) {
             //循环经历了break语句的洗礼,后面的语句需要全部放在匿名函数中。
@@ -640,11 +605,9 @@ class McfppImListener : mcfppBaseListener() {
     private var temp: MCBool? = null
     @Override
     override fun exitControlStatement(ctx: mcfppParser.ControlStatementContext) {
+        Project.ctx = ctx
         if (!inLoopStatement(ctx)) {
-            Project.logger.error(
-                "'continue' or 'break' can only be used in loop statements: " +
-                        " at " + Project.currFile.getName() + " line: " + ctx.getStart().line
-            )
+            Project.error("'continue' or 'break' can only be used in loop statements: ")
             throw SyntaxException()
         }
         if (Function.currFunction.isEnd || Function.isLastFunctionEnd != 0) {
@@ -667,10 +630,11 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitBlock(ctx: mcfppParser.BlockContext) {
+        Project.ctx = ctx
         if (!Function.currFunction.isEnd && Function.isLastFunctionEnd == 2) {
             if (ctx.parent is mcfppParser.IfBlockContext) {
                 //如果是if语句,出栈
-                Function.currFunction = Function.currFunction.parent.get(0)
+                Function.currFunction = Function.currFunction.parent[0]
                 Function.isLastFunctionEnd = 1
             }
             if (ctx.parent is mcfppParser.ForBlockContext
@@ -678,7 +642,7 @@ class McfppImListener : mcfppBaseListener() {
                 || ctx.parent is mcfppParser.DoWhileBlockContext
             ) {
                 //是循环语句,出栈的同时重置isLastFunctionEnd标志
-                Function.currFunction = Function.currFunction.parent.get(0)
+                Function.currFunction = Function.currFunction.parent[0]
                 Function.isLastFunctionEnd = 0
             }
         }
@@ -690,6 +654,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun enterClassBody(ctx: mcfppParser.ClassBodyContext) {
+        Project.ctx = ctx
         //获取类的对象
         val parent: mcfppParser.ClassDeclarationContext = ctx.parent as mcfppParser.ClassDeclarationContext
         val identifier: String = parent.className(0).text
@@ -704,6 +669,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitClassBody(ctx: mcfppParser.ClassBodyContext?) {
+        Project.ctx = ctx
         Class.currClass = null
         Function.currFunction = Function.nullFunction
     }
@@ -714,6 +680,7 @@ class McfppImListener : mcfppBaseListener() {
      */
     @Override
     override fun exitClassMemberDeclaration(ctx: mcfppParser.ClassMemberDeclarationContext) {
+        Project.ctx = ctx
         val memberContext: mcfppParser.ClassMemberContext = ctx.classMember()
         if (memberContext.classFunctionDeclaration() != null) {
             //函数声明由函数的listener处理

From f21263146d5dd99be3631609aa3840bea53904cf Mon Sep 17 00:00:00 2001
From: Alumopper <90548686+Alumopper@users.noreply.github.com>
Date: Fri, 5 May 2023 21:02:44 +0800
Subject: [PATCH 004/128] Update README.md

Signed-off-by: Alumopper <90548686+Alumopper@users.noreply.github.com>
---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 9b95143e..2de23a46 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+![](https://user-images.githubusercontent.com/90548686/236462051-b901f99c-bdef-435c-8ca2-0dda37b25285.png)
 # 介绍 Introduce
 MCFPP是一个能被编译为Minecraft数据包的全新的面向对象的语言。它旨在以类似C系语言的语法,进行数据包的编写,并引入编程中常用的概念,从而使数据包的编 写更加的便利。
 

From bd3ea8be675bf30d1a974266b21511f67b1293d7 Mon Sep 17 00:00:00 2001
From: Alumopper <609255325@qq.com>
Date: Sun, 7 May 2023 21:59:28 +0800
Subject: [PATCH 005/128] =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E6=88=90=E5=91=98?=
 =?UTF-8?q?=E7=9A=84=E8=AE=BF=E9=97=AE=E5=92=8C=E4=BF=AE=E6=94=B9=20?=
 =?UTF-8?q?=E5=8C=85=E5=90=8D=E4=BF=AE=E6=94=B9=20=E4=BB=A3=E7=A0=81?=
 =?UTF-8?q?=E6=95=B4=E7=90=86=E5=92=8C=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .idea/misc.xml                                |   3 +
 build.gradle.kts                              |   3 +-
 gradle.properties                             |   2 +
 log4j2.properties                             |   7 +
 src/main/antlr/mcfpp.g4                       |   7 +-
 .../alumopper/mcfpp/command/package-info.kt   |   5 -
 .../alumopper/mcfpp/lang/CanSelectMember.kt   |  13 -
 .../top/alumopper/mcfpp/lang/ClassObject.kt   |  96 -------
 .../top/alumopper/mcfpp/lang/ClassPointer.kt  | 134 ----------
 .../top/alumopper/mcfpp/lang/ClassType.kt     |  53 ----
 .../kotlin/top/alumopper/mcfpp/lang/Entity.kt |   3 -
 .../top/alumopper/mcfpp/lang/JsonText.kt      |   3 -
 .../kotlin/top/alumopper/mcfpp/lib/Native.kt  |   3 -
 .../alumopper/mcfpp/lib/NativeConstructor.kt  |  11 -
 .../top/alumopper/mcfpp/package-info.kt       |   2 -
 .../kotlin/top/{alumopper => }/mcfpp/MCFPP.kt |  10 +-
 .../top/{alumopper => }/mcfpp/Project.kt      |  22 +-
 .../{alumopper => }/mcfpp/command/Commands.kt |   6 +-
 .../kotlin/top/mcfpp/command/package-info.kt  |   5 +
 .../exception/ArgumentNotMatchException.kt    |   2 +-
 .../exception/ClassDuplicationException.kt    |   2 +-
 .../mcfpp/exception/ConstChangeException.kt   |   2 +-
 .../ExecuteCommandListEndException.kt         |   2 +-
 .../exception/FunctionDuplicationException.kt |   2 +-
 .../exception/FunctionNotDefineException.kt   |   2 +-
 .../mcfpp/exception/IllegalFormatException.kt |   2 +-
 .../exception/IllegalFunctionNameException.kt |   2 +-
 .../mcfpp/exception/SyntaxException.kt        |   2 +-
 .../mcfpp/exception/TODOException.kt          |   2 +-
 .../exception/VariableConverseException.kt    |   2 +-
 .../exception/VariableDuplicationException.kt |   2 +-
 .../exception/VariableNotDefineException.kt   |   2 +-
 .../mcfpp/exception/package-info.kt           |   2 +-
 .../mcfpp/io/DatapackCreator.kt               |  28 +-
 .../mcfpp/io/McfppFileReader.kt               |   8 +-
 .../{alumopper => }/mcfpp/io/McfppReader.kt   |   2 +-
 .../kotlin/top/mcfpp/lang/CanSelectMember.kt  |  41 +++
 src/main/kotlin/top/mcfpp/lang/ClassObject.kt |  92 +++++++
 .../kotlin/top/mcfpp/lang/ClassPointer.kt     | 152 +++++++++++
 src/main/kotlin/top/mcfpp/lang/ClassType.kt   |  83 ++++++
 src/main/kotlin/top/mcfpp/lang/Entity.kt      |   3 +
 .../mcfpp/lang/INativeClass.kt                |   4 +-
 src/main/kotlin/top/mcfpp/lang/JsonText.kt    |   3 +
 .../top/{alumopper => }/mcfpp/lang/MCBool.kt  |  73 +++---
 .../top/{alumopper => }/mcfpp/lang/MCInt.kt   | 244 ++++++++----------
 .../{alumopper => }/mcfpp/lang/MCString.kt    |   9 +-
 .../mcfpp/lang/NativeClassObject.kt           |  12 +-
 .../top/{alumopper => }/mcfpp/lang/Number.kt  |  24 +-
 .../mcfpp/lang/OnScoreboard.kt                |   2 +-
 .../{alumopper => }/mcfpp/lang/SbObject.kt    |  10 +-
 .../top/{alumopper => }/mcfpp/lang/SbValue.kt |   9 +-
 .../{alumopper => }/mcfpp/lang/Selector.kt    |   8 +-
 .../top/{alumopper => }/mcfpp/lang/Var.kt     |  49 ++--
 .../top/{alumopper => }/mcfpp/lib/Cache.kt    |  10 +-
 .../mcfpp/lib/CacheContainer.kt               |   2 +-
 .../top/{alumopper => }/mcfpp/lib/Class.kt    |  68 ++---
 .../{alumopper => }/mcfpp/lib/ClassMember.kt  |   7 +-
 .../{alumopper => }/mcfpp/lib/Constructor.kt  |  44 ++--
 .../top/{alumopper => }/mcfpp/lib/Function.kt |  15 +-
 .../mcfpp/lib/FunctionParam.kt                |   4 +-
 .../{alumopper => }/mcfpp/lib/FunctionTag.kt  |   4 +-
 .../top/{alumopper => }/mcfpp/lib/Global.kt   |   4 +-
 .../mcfpp/lib/InlineFunction.kt               |   6 +-
 .../mcfpp/lib/InternalFunction.kt             |   4 +-
 .../mcfpp/lib/McfppExprVisitor.kt             |  91 ++++---
 .../mcfpp/lib/McfppFileVisitor.kt             |  24 +-
 .../mcfpp/lib/McfppFuncVisitor.kt             |   4 +-
 .../mcfpp/lib/McfppImListener.kt              |  19 +-
 src/main/kotlin/top/mcfpp/lib/Native.kt       |   3 +
 .../{alumopper => }/mcfpp/lib/NativeClass.kt  |   8 +-
 .../kotlin/top/mcfpp/lib/NativeConstructor.kt |  11 +
 .../mcfpp/lib/NativeFunction.kt               |  12 +-
 .../top/{alumopper => }/mcfpp/lib/UwU.kt      |   2 +-
 .../{alumopper => }/mcfpp/lib/package-info.kt |   2 +-
 src/main/kotlin/top/mcfpp/package-info.kt     |   2 +
 .../{alumopper => }/mcfpp/test/NashornTest.kt |   2 +-
 .../{alumopper => }/mcfpp/test/NativeTest1.kt |   8 +-
 test/.mclib                                   |   2 +-
 test/test.mcfpp                               |  14 +-
 79 files changed, 881 insertions(+), 763 deletions(-)
 create mode 100644 log4j2.properties
 delete mode 100644 src/main/kotlin/top/alumopper/mcfpp/command/package-info.kt
 delete mode 100644 src/main/kotlin/top/alumopper/mcfpp/lang/CanSelectMember.kt
 delete mode 100644 src/main/kotlin/top/alumopper/mcfpp/lang/ClassObject.kt
 delete mode 100644 src/main/kotlin/top/alumopper/mcfpp/lang/ClassPointer.kt
 delete mode 100644 src/main/kotlin/top/alumopper/mcfpp/lang/ClassType.kt
 delete mode 100644 src/main/kotlin/top/alumopper/mcfpp/lang/Entity.kt
 delete mode 100644 src/main/kotlin/top/alumopper/mcfpp/lang/JsonText.kt
 delete mode 100644 src/main/kotlin/top/alumopper/mcfpp/lib/Native.kt
 delete mode 100644 src/main/kotlin/top/alumopper/mcfpp/lib/NativeConstructor.kt
 delete mode 100644 src/main/kotlin/top/alumopper/mcfpp/package-info.kt
 rename src/main/kotlin/top/{alumopper => }/mcfpp/MCFPP.kt (67%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/Project.kt (93%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/command/Commands.kt (90%)
 create mode 100644 src/main/kotlin/top/mcfpp/command/package-info.kt
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/ArgumentNotMatchException.kt (81%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/ClassDuplicationException.kt (67%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/ConstChangeException.kt (72%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/ExecuteCommandListEndException.kt (84%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/FunctionDuplicationException.kt (75%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/FunctionNotDefineException.kt (68%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/IllegalFormatException.kt (76%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/IllegalFunctionNameException.kt (75%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/SyntaxException.kt (71%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/TODOException.kt (89%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/VariableConverseException.kt (75%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/VariableDuplicationException.kt (81%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/VariableNotDefineException.kt (68%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/exception/package-info.kt (87%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/io/DatapackCreator.kt (79%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/io/McfppFileReader.kt (94%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/io/McfppReader.kt (92%)
 create mode 100644 src/main/kotlin/top/mcfpp/lang/CanSelectMember.kt
 create mode 100644 src/main/kotlin/top/mcfpp/lang/ClassObject.kt
 create mode 100644 src/main/kotlin/top/mcfpp/lang/ClassPointer.kt
 create mode 100644 src/main/kotlin/top/mcfpp/lang/ClassType.kt
 create mode 100644 src/main/kotlin/top/mcfpp/lang/Entity.kt
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/INativeClass.kt (86%)
 create mode 100644 src/main/kotlin/top/mcfpp/lang/JsonText.kt
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/MCBool.kt (80%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/MCInt.kt (62%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/MCString.kt (81%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/NativeClassObject.kt (84%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/Number.kt (75%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/OnScoreboard.kt (80%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/SbObject.kt (92%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/SbValue.kt (62%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/Selector.kt (77%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lang/Var.kt (87%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/Cache.kt (97%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/CacheContainer.kt (90%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/Class.kt (79%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/ClassMember.kt (62%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/Constructor.kt (63%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/Function.kt (97%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/FunctionParam.kt (94%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/FunctionTag.kt (95%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/Global.kt (88%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/InlineFunction.kt (76%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/InternalFunction.kt (97%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/McfppExprVisitor.kt (86%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/McfppFileVisitor.kt (96%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/McfppFuncVisitor.kt (93%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/McfppImListener.kt (98%)
 create mode 100644 src/main/kotlin/top/mcfpp/lib/Native.kt
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/NativeClass.kt (81%)
 create mode 100644 src/main/kotlin/top/mcfpp/lib/NativeConstructor.kt
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/NativeFunction.kt (87%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/UwU.kt (98%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/lib/package-info.kt (75%)
 create mode 100644 src/main/kotlin/top/mcfpp/package-info.kt
 rename src/main/kotlin/top/{alumopper => }/mcfpp/test/NashornTest.kt (91%)
 rename src/main/kotlin/top/{alumopper => }/mcfpp/test/NativeTest1.kt (73%)

diff --git a/.idea/misc.xml b/.idea/misc.xml
index f5e42907..2c10b89b 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -4,6 +4,9 @@
   
     
   
+  
+