Skip to content

Commit 3e40f02

Browse files
committed
枚举的定义
1 parent d855a76 commit 3e40f02

File tree

9 files changed

+236
-19
lines changed

9 files changed

+236
-19
lines changed

TODO_CN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* 基本库
2020
* 枚举
2121
* 异常非中断编译
22+
* 函数返回值重载
2223

2324
## 已知问题
2425
* [ ] 递归调用的时候,错误地修改了本层函数的值

src/main/antlr/mcfppLexer.g4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ OBJECT:'object';
103103
INTERFACE:'interface';
104104
DATA:'data';
105105
FUNCTION:'func';
106+
ENUM:'enum';
106107

107108
GLOBAL:'global';
108109
VAR:'var';

src/main/antlr/mcfppParser.g4

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ declarations
7373
| extensionFunctionDeclaration
7474
| interfaceDeclaration
7575
| globalDeclaration
76+
| enumDeclaration
7677
;
7778

7879
//全局声明
@@ -190,6 +191,20 @@ extensionFunctionDeclaration
190191
: funcAnnoation? STATIC? FUNCTION (type '.')? Identifier functionParams (ARROW functionReturnType)? '{' functionBody '}'
191192
;
192193

194+
//枚举
195+
enumDeclaration
196+
: ENUM Identifier '{' enumBody '}'
197+
;
198+
199+
enumBody
200+
: enumMember (',' enumMember)*
201+
;
202+
203+
enumMember
204+
: Identifier ('=' intValue)?
205+
;
206+
207+
193208
namespaceID
194209
: (Identifier ( '.' Identifier)* ':')? Identifier
195210
;

src/main/kotlin/top/mcfpp/antlr/McfppTypeVisitor.kt

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package top.mcfpp.antlr
33
import top.mcfpp.Project
44
import top.mcfpp.lang.MCAny
55
import top.mcfpp.model.*
6+
import top.mcfpp.model.Enum
67
import top.mcfpp.model.field.GlobalField
78
import top.mcfpp.model.generic.ClassParam
89
import top.mcfpp.model.generic.GenericClass
@@ -131,9 +132,9 @@ class McfppTypeVisitor: mcfppParserBaseVisitor<Unit>() {
131132
//注册类
132133
val id = ctx.classWithoutNamespace().text
133134
val nsp = GlobalField.localNamespaces[Project.currNamespace]!!
134-
if (nsp.field.hasInterface(id)) {
135+
if (nsp.field.hasDeclaredType(id)) {
135136
//重复声明
136-
LogProcessor.error("Interface has been defined: $id in namespace ${Project.currNamespace}")
137+
LogProcessor.error("Type has been defined: $id in namespace ${Project.currNamespace}")
137138
Interface.currInterface = nsp.field.getInterface(id)
138139
} else {
139140
//如果没有声明过这个类
@@ -180,8 +181,8 @@ class McfppTypeVisitor: mcfppParserBaseVisitor<Unit>() {
180181
//如果没有声明过这个类
181182
Class(id, Project.currNamespace)
182183
}
183-
if(!nsp.field.addClass(id, cls)){
184-
LogProcessor.error("Class has been defined: $id in namespace ${Project.currNamespace}")
184+
if(!nsp.field.hasDeclaredType(id)){
185+
LogProcessor.error("Type has been defined: $id in namespace ${Project.currNamespace}")
185186
return
186187
}
187188
cls.initialize()
@@ -211,14 +212,14 @@ class McfppTypeVisitor: mcfppParserBaseVisitor<Unit>() {
211212
/**
212213
*
213214
*/
214-
override fun visitTemplateDeclaration(ctx: mcfppParser.TemplateDeclarationContext?){
215-
Project.ctx = ctx!!
215+
override fun visitTemplateDeclaration(ctx: mcfppParser.TemplateDeclarationContext){
216+
Project.ctx = ctx
216217
//注册模板
217218
val id = ctx.classWithoutNamespace().text
218219
val nsp = GlobalField.localNamespaces[Project.currNamespace]!!
219-
if (nsp.field.hasTemplate(id)) {
220+
if (nsp.field.hasDeclaredType(id)) {
220221
//重复声明
221-
LogProcessor.error("Template has been defined: $id in namespace ${Project.currNamespace}")
222+
LogProcessor.error("Type has been defined: $id in namespace ${Project.currNamespace}")
222223
DataTemplate.currTemplate = nsp.field.getTemplate(id)
223224
}
224225
val template = DataTemplate(id,Project.currNamespace)
@@ -246,4 +247,28 @@ class McfppTypeVisitor: mcfppParserBaseVisitor<Unit>() {
246247
}
247248
nsp.field.addTemplate(id, template)
248249
}
250+
251+
override fun visitEnumDeclaration(ctx: mcfppParser.EnumDeclarationContext) {
252+
Project.ctx = ctx
253+
//注册枚举
254+
val id = ctx.Identifier().text
255+
val nsp = GlobalField.localNamespaces[Project.currNamespace]!!
256+
if (nsp.field.hasDeclaredType(id)) {
257+
//重复声明
258+
LogProcessor.error("Type has been defined: $id in namespace ${Project.currNamespace}")
259+
}
260+
val enum = Enum(id, Project.currNamespace)
261+
nsp.field.addEnum(id, enum)
262+
//添加成员
263+
for (m in ctx.enumBody().enumMember()) {
264+
val value = if(m.intValue() != null){
265+
//获取enum的int值
266+
m.intValue().text.toInt()
267+
}else{
268+
enum.getNextMemberValue()
269+
}
270+
val member = EnumMember(m.Identifier().text, value)
271+
enum.addMember(member)
272+
}
273+
}
249274
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package top.mcfpp.model
2+
3+
class Enum(var identifier: String, var namespace: String){
4+
5+
var members: HashMap<String, EnumMember> = HashMap()
6+
7+
fun addMember(member: EnumMember){
8+
members[member.identifier] = member
9+
}
10+
11+
fun addMember(identifier: String){
12+
members[identifier] = EnumMember(identifier, getNextMemberValue())
13+
}
14+
15+
fun getNextMemberValue(): Int{
16+
val values = members.map { it.value.value }
17+
var i = values.last() + 1
18+
while (values.contains(i)){
19+
i++
20+
}
21+
return i
22+
}
23+
}
24+
25+
class EnumMember{
26+
var identifier: String
27+
var value: Int
28+
29+
constructor(identifier: String, value: Int) {
30+
this.identifier = identifier
31+
this.value = value
32+
}
33+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package top.mcfpp.model.field
2+
3+
import top.mcfpp.model.Enum
4+
5+
interface IFieldWithEnum {
6+
/**
7+
* 向域中添加一个枚举
8+
*
9+
* @param identifier 枚举的标识符
10+
* @param enum 枚举
11+
* @param force 是否强制添加。如果为true,则即使已经添加过相同标识符的枚举,也会覆盖原来的枚举进行添加。
12+
* @return 是否添加成功。如果已经存在相同标识符的枚举,且不是强制添加则为false
13+
*/
14+
fun addEnum(identifier: String, enum: Enum, force: Boolean = false): Boolean
15+
16+
/**
17+
* 移除一个枚举
18+
*
19+
* @param identifier 这个枚举的标识符
20+
* @return 是否移除成功。如果不存在此枚举,则返回false
21+
*/
22+
fun removeEnum(identifier: String):Boolean
23+
24+
/**
25+
* 获取一个非泛型枚举。可能不存在
26+
*
27+
* @param identifier 枚举的标识符
28+
* @return 获取到的枚举。如果不存在,则返回null
29+
*/
30+
fun getEnum(identifier: String): Enum?
31+
32+
/**
33+
* 是否存在此枚举
34+
*
35+
* @param identifier 枚举的标识符
36+
* @return
37+
*/
38+
fun hasEnum(identifier: String):Boolean
39+
40+
/**
41+
* 是否存在此枚举
42+
*
43+
* @param enum 枚举
44+
* @return
45+
*/
46+
fun hasEnum(enum: Enum): Boolean
47+
48+
fun forEachEnum(operation: (Enum) -> Any?)
49+
}

src/main/kotlin/top/mcfpp/model/field/NamespaceField.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ import kotlin.collections.HashMap
3030
*
3131
* 函数储存在一个列表中
3232
*/
33-
open class NamespaceField: IFieldWithClass, IFieldWithFunction, IFieldWithTemplate, IFieldWithInterface, SimpleFieldWithType {
33+
open class NamespaceField(private val simpleFieldWithType: SimpleFieldWithType = SimpleFieldWithType(), private val simpleFieldWithEnum: SimpleFieldWithEnum = SimpleFieldWithEnum())
34+
: IFieldWithClass, IFieldWithFunction, IFieldWithTemplate, IFieldWithInterface,
35+
IFieldWithType by simpleFieldWithType, IFieldWithEnum by simpleFieldWithEnum {
3436
/**
3537
* 变量
3638
*/
@@ -93,13 +95,11 @@ open class NamespaceField: IFieldWithClass, IFieldWithFunction, IFieldWithTempla
9395
@Nullable
9496
var container: FieldContainer? = GlobalField
9597

96-
constructor()
97-
9898
/**
9999
* 复制一个缓存。
100100
* @param cache 原来的缓存
101101
*/
102-
constructor(cache: NamespaceField) {
102+
constructor(cache: NamespaceField) : this(cache.simpleFieldWithType, cache.simpleFieldWithEnum) {
103103
parent = cache.parent
104104
//变量复制
105105
for (key in cache.vars.keys) {
@@ -420,4 +420,8 @@ open class NamespaceField: IFieldWithClass, IFieldWithFunction, IFieldWithTempla
420420
}
421421

422422

423+
fun hasDeclaredType(identifier: String): Boolean{
424+
return hasEnum(identifier) || hasTemplate(identifier) || hasInterface(identifier) || hasClass(identifier)
425+
}
426+
423427
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package top.mcfpp.model.field
2+
3+
import org.jetbrains.annotations.Nullable
4+
import top.mcfpp.model.Enum
5+
6+
class SimpleFieldWithEnum : IFieldWithEnum {
7+
8+
/**
9+
* 方法
10+
*/
11+
private var enums: ArrayList<Enum> = ArrayList()
12+
13+
/**
14+
* 遍历每一个方法
15+
*
16+
* @param operation 要对方法进行的操作
17+
* @receiver
18+
*/
19+
override fun forEachEnum(operation: (Enum) -> Any?){
20+
for (enum in enums){
21+
operation(enum)
22+
}
23+
}
24+
25+
26+
@Nullable
27+
override fun getEnum(identifier: String): Enum? {
28+
for (e in enums) {
29+
if(e.identifier == identifier){
30+
return e
31+
}
32+
}
33+
return null
34+
}
35+
36+
override fun addEnum(identifier: String, enum: Enum, force: Boolean): Boolean {
37+
if(hasEnum(enum)){
38+
if(force){
39+
enums[enums.indexOf(enum)] = enum
40+
return true
41+
}
42+
return false
43+
}
44+
enums.add(enum)
45+
return true
46+
}
47+
48+
override fun removeEnum(identifier: String): Boolean {
49+
for (e in enums) {
50+
if(e.identifier == identifier){
51+
enums.remove(e)
52+
return true
53+
}
54+
}
55+
return false
56+
}
57+
58+
override fun hasEnum(enum: Enum): Boolean{
59+
return enums.contains(enum)
60+
}
61+
62+
override fun hasEnum(identifier: String): Boolean {
63+
for (e in enums) {
64+
if(e.identifier == identifier){
65+
return true
66+
}
67+
}
68+
return false
69+
}
70+
}

src/test/java/top/mcfpp/test/QAQ.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,35 @@
11
package top.mcfpp.test;
22

3+
import java.util.Arrays;
4+
35
public class QAQ {
46
public static void main(String[] args) {
5-
System.out.println(removeTrailingZeros("51230100"));
7+
System.out.println(findTargetSumWays(new int[]{1,0},1));
8+
}
9+
10+
public static int findTargetSumWays(int[] nums, int target) {
11+
//求和
12+
int sum = 0;
13+
for (int num : nums) {
14+
sum += num;
15+
}
16+
//如果sum小于target或者sum+target为奇数,直接返回0
17+
if (sum < target || (sum - target) % 2 == 1) {
18+
return 0;
19+
}
20+
//求差
21+
target = (sum - target) / 2;
22+
//从小往大找
23+
return solve(nums, target);
624
}
725

8-
public static String removeTrailingZeros(String num) {
9-
for (int i = num.length()-1; i > 0; i --){
10-
if(num.charAt(i) != '0'){
11-
return num.substring(0, i + 1);
12-
}
26+
public static int solve(int[] nums, int target){
27+
//从小往大找
28+
int count = 0;
29+
if(target == 0) count++;
30+
for (int i = 0; i < nums.length; i++) {
31+
count += solve(Arrays.copyOfRange(nums, i + 1, nums.length), target - nums[i]);
1332
}
14-
return num;
33+
return count;
1534
}
1635
}

0 commit comments

Comments
 (0)