|
@@ -2,6 +2,7 @@ package org.ikeran.petal.semantic
|
2
|
2
|
|
3
|
3
|
import java.util.ArrayList
|
4
|
4
|
import java.util.HashMap
|
|
5
|
+import org.slf4j.LoggerFactory
|
5
|
6
|
|
6
|
7
|
/**
|
7
|
8
|
* Types that we know about.
|
|
@@ -31,6 +32,7 @@ abstract class Type(
|
31
|
32
|
val UNKNOWN = UnknownType()
|
32
|
33
|
val ERROR = ErrorType()
|
33
|
34
|
val UNIT = UnitType()
|
|
35
|
+ val NUMLITERAL = NumberLiteralType()
|
34
|
36
|
|
35
|
37
|
val registry = HashMap<String, Type>()
|
36
|
38
|
|
|
@@ -38,17 +40,21 @@ abstract class Type(
|
38
|
40
|
val existing = registry.get(t.name)
|
39
|
41
|
if (existing == null) {
|
40
|
42
|
registry.put(t.name, t)
|
|
43
|
+ logger.info("added ${t.name} -> ${t} to type registry")
|
41
|
44
|
return t
|
42
|
45
|
}
|
43
|
46
|
if (existing is ForwardDeclType && t !is ForwardDeclType) {
|
44
|
47
|
registry.put(t.name, t)
|
45
|
48
|
existing.realType = t
|
|
49
|
+ logger.info("added ${t.name} -> ${t} to type registry, overwriting fwd decl")
|
46
|
50
|
return t
|
47
|
51
|
}
|
|
52
|
+ logger.info("returning existing type ${existing}")
|
48
|
53
|
return existing
|
49
|
54
|
}
|
50
|
55
|
|
51
|
56
|
fun lookup(fqn: String): Type {
|
|
57
|
+ if (registry.size == 0) registerBuiltins()
|
52
|
58
|
val fwd = ForwardDeclType(fqn)
|
53
|
59
|
return register(fwd)
|
54
|
60
|
}
|
|
@@ -70,14 +76,21 @@ abstract class Type(
|
70
|
76
|
register(UNKNOWN)
|
71
|
77
|
register(ERROR)
|
72
|
78
|
register(UNIT)
|
|
79
|
+ register(NUMLITERAL)
|
73
|
80
|
}
|
74
|
81
|
}
|
75
|
82
|
|
76
|
83
|
open fun isValid(): Boolean {
|
77
|
84
|
return true
|
78
|
85
|
}
|
|
86
|
+
|
|
87
|
+ open fun canImplicitConvertTo(other: Type): Boolean {
|
|
88
|
+ return other == this
|
|
89
|
+ }
|
79
|
90
|
}
|
80
|
91
|
|
|
92
|
+val logger = LoggerFactory.getLogger("types")
|
|
93
|
+
|
81
|
94
|
// Special cases
|
82
|
95
|
/** UnknownType is the type initially assigned with eg `let a = someFunc()` and we don't know the func's return type. */
|
83
|
96
|
class UnknownType(): Type("<unknown>") {
|
|
@@ -113,8 +126,18 @@ class ForwardDeclType(name: String): Type(name) {
|
113
|
126
|
return other
|
114
|
127
|
}
|
115
|
128
|
}
|
|
129
|
+class NumberLiteralType: Type("<numeric>") {
|
|
130
|
+ override fun isValid(): Boolean { return false }
|
|
131
|
+ override fun canImplicitConvertTo(other: Type): Boolean {
|
|
132
|
+ logger.info("canImplicitConvertTo(${this} ${javaClass} to ${other} ${other.javaClass})")
|
|
133
|
+ if (other is NumberLiteralType) return true
|
|
134
|
+ if (other is IntType) return true
|
|
135
|
+ if (other is FloatType) return true
|
|
136
|
+ return false
|
|
137
|
+ }
|
|
138
|
+}
|
116
|
139
|
// Builtin types
|
117
|
|
-data class IntType(val signed: Boolean, val size: Int) : Type("${if (signed) "" else "u"}int${size*8}}")
|
|
140
|
+data class IntType(val signed: Boolean, val size: Int) : Type("${if (signed) "" else "u"}int${size*8}")
|
118
|
141
|
data class FloatType(val size: Int) : Type("float${size * 8}") {}
|
119
|
142
|
class StringType : Type("string") {
|
120
|
143
|
override fun equals(other: Any?): Boolean {
|
|
@@ -143,7 +166,7 @@ open class UserDefinedType(name: String = ""): Type(name) {
|
143
|
166
|
}
|
144
|
167
|
open class AggregateType(name: String = "") : Type(name)
|
145
|
168
|
data class ClassType(val shortName: String, val qualifiedName: String) : AggregateType(qualifiedName) {
|
146
|
|
- /** Only class Object should have a null parent. Otherwise, if the parent's null, we'll set it to Object. */
|
|
169
|
+ /** Only class ProtoObject should have a null parent. Otherwise, if the parent's null, we'll set it to Object. */
|
147
|
170
|
var base: Type? = null
|
148
|
171
|
val interfaces = ArrayList<InterfaceType>()
|
149
|
172
|
}
|