class constants added and class instances for integral types
This commit is contained in:
parent
f885300d18
commit
47c061d2b4
24
docs/OOP.md
24
docs/OOP.md
@ -40,14 +40,28 @@ Class is the object, naturally, with class:
|
|||||||
|
|
||||||
Classes can be compared:
|
Classes can be compared:
|
||||||
|
|
||||||
println(1.21::class == Math.PI::class)
|
assert(1.21::class == Math.PI::class)
|
||||||
println(3.14::class == 1::class)
|
assert(3.14::class != 1::class)
|
||||||
println(π::class)
|
assert(π::class == Real)
|
||||||
>>> true
|
π::class
|
||||||
>>> false
|
|
||||||
>>> Real
|
>>> Real
|
||||||
|
|
||||||
|
Note `Real` class: it is global variable for Real class; there are such class instances for all built-in types:
|
||||||
|
|
||||||
|
assert("Hello"::class == String)
|
||||||
|
assert(1970::class == Int)
|
||||||
|
assert(true::class == Bool)
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
|
More complex is singleton classes, because you don't need to compare their class
|
||||||
|
instances and generally don't need them at all, these are normally just Obj:
|
||||||
|
|
||||||
|
null::class
|
||||||
|
>>> Obj
|
||||||
|
|
||||||
|
At this time, `Obj` can't be accessed as a class.
|
||||||
|
|
||||||
|
|
||||||
### Methods in-depth
|
### Methods in-depth
|
||||||
|
|
||||||
Regular methods are called on instances as usual `instance.method()`. The method resolution order is
|
Regular methods are called on instances as usual `instance.method()`. The method resolution order is
|
||||||
|
25
docs/Real.md
Normal file
25
docs/Real.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Real built-in class
|
||||||
|
|
||||||
|
Class that supports double-precision math. Woks much like double in other languages. We honor no floats, so it is '
|
||||||
|
Real'.
|
||||||
|
|
||||||
|
It's class in Ling is `Real`:
|
||||||
|
|
||||||
|
(π/2)::class
|
||||||
|
>>> Real
|
||||||
|
|
||||||
|
you can use it's class to ensure type:
|
||||||
|
|
||||||
|
1.71::class == Real
|
||||||
|
>>> true
|
||||||
|
|
||||||
|
## Member functions
|
||||||
|
|
||||||
|
| name | meaning | type |
|
||||||
|
|--------------|------------------------------------|------|
|
||||||
|
| `roundToInt` | round to nearest int like round(x) | Int |
|
||||||
|
| | | |
|
||||||
|
| | | |
|
||||||
|
| | | |
|
||||||
|
| | | |
|
||||||
|
| | | |
|
@ -13,6 +13,12 @@ data class Arguments(val list: List<Info>): Iterable<Obj> {
|
|||||||
return list.first().value
|
return list.first().value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun <reified T: Obj>required(index: Int, context: Context): T {
|
||||||
|
if( list.size <= index ) context.raiseError("Expected at least ${index+1} argument, got ${list.size}")
|
||||||
|
return (list[index].value as? T)
|
||||||
|
?: context.raiseError("Expected type ${T::class.simpleName}, got ${list[index].value::class.simpleName}")
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val EMPTY = Arguments(emptyList())
|
val EMPTY = Arguments(emptyList())
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ class Context(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T> addConst(value: T, vararg names: String) {
|
inline fun <reified T> addConstWithAliases(value: T, vararg names: String) {
|
||||||
val obj = Obj.from(value)
|
val obj = Obj.from(value)
|
||||||
for (name in names) {
|
for (name in names) {
|
||||||
addItem(
|
addItem(
|
||||||
@ -78,6 +78,8 @@ class Context(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addConst(name: String,value: Obj) = addItem(name, false, value)
|
||||||
|
|
||||||
suspend fun eval(code: String): Obj =
|
suspend fun eval(code: String): Obj =
|
||||||
Compiler().compile(code.toSource()).execute(this)
|
Compiler().compile(code.toSource()).execute(this)
|
||||||
|
|
||||||
|
@ -190,6 +190,13 @@ data class ObjString(val value: String) : Obj() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = value
|
override fun toString(): String = value
|
||||||
|
|
||||||
|
override val objClass: ObjClass
|
||||||
|
get() = type
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val type = ObjClass("String")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Numeric {
|
interface Numeric {
|
||||||
@ -273,10 +280,14 @@ data class ObjInt(var value: Long) : Obj(), Numeric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = value.toString()
|
override fun toString(): String = value.toString()
|
||||||
|
|
||||||
|
override val objClass: ObjClass = type
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val type = ObjClass("Int")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
|
||||||
@SerialName("bool")
|
|
||||||
data class ObjBool(val value: Boolean) : Obj() {
|
data class ObjBool(val value: Boolean) : Obj() {
|
||||||
override val asStr by lazy { ObjString(value.toString()) }
|
override val asStr by lazy { ObjString(value.toString()) }
|
||||||
|
|
||||||
@ -286,6 +297,12 @@ data class ObjBool(val value: Boolean) : Obj() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = value.toString()
|
override fun toString(): String = value.toString()
|
||||||
|
|
||||||
|
override val objClass: ObjClass = type
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val type = ObjClass("Bool")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ObjNamespace(val name: String) : Obj() {
|
data class ObjNamespace(val name: String) : Obj() {
|
||||||
@ -300,3 +317,4 @@ open class ObjError(val context: Context, val message: String) : Obj() {
|
|||||||
|
|
||||||
class ObjNullPointerError(context: Context) : ObjError(context, "object is null")
|
class ObjNullPointerError(context: Context) : ObjError(context, "object is null")
|
||||||
|
|
||||||
|
class ObjAssertionError(context: Context, message: String) : ObjError(context, message)
|
||||||
|
@ -21,8 +21,8 @@ class Script(
|
|||||||
val defaultContext: Context = Context().apply {
|
val defaultContext: Context = Context().apply {
|
||||||
addFn("println") {
|
addFn("println") {
|
||||||
print("yn: ")
|
print("yn: ")
|
||||||
for( (i,a) in args.withIndex() ) {
|
for ((i, a) in args.withIndex()) {
|
||||||
if( i > 0 ) print(' ' + a.asStr.value)
|
if (i > 0) print(' ' + a.asStr.value)
|
||||||
else print(a.asStr.value)
|
else print(a.asStr.value)
|
||||||
}
|
}
|
||||||
println()
|
println()
|
||||||
@ -30,28 +30,39 @@ class Script(
|
|||||||
}
|
}
|
||||||
addFn("floor") {
|
addFn("floor") {
|
||||||
val x = args.firstAndOnly()
|
val x = args.firstAndOnly()
|
||||||
if( x is ObjInt ) x
|
if (x is ObjInt) x
|
||||||
else ObjReal(floor(x.toDouble()))
|
else ObjReal(floor(x.toDouble()))
|
||||||
}
|
}
|
||||||
addFn("ceil") {
|
addFn("ceil") {
|
||||||
val x = args.firstAndOnly()
|
val x = args.firstAndOnly()
|
||||||
if( x is ObjInt ) x
|
if (x is ObjInt) x
|
||||||
else ObjReal(ceil(x.toDouble()))
|
else ObjReal(ceil(x.toDouble()))
|
||||||
}
|
}
|
||||||
addFn("round") {
|
addFn("round") {
|
||||||
val x = args.firstAndOnly()
|
val x = args.firstAndOnly()
|
||||||
if( x is ObjInt ) x
|
if (x is ObjInt) x
|
||||||
else ObjReal(round(x.toDouble()))
|
else ObjReal(round(x.toDouble()))
|
||||||
}
|
}
|
||||||
addFn("sin") {
|
addFn("sin") {
|
||||||
sin(args.firstAndOnly().toDouble())
|
sin(args.firstAndOnly().toDouble())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addFn("assert") {
|
||||||
|
val cond = args.required<ObjBool>(0, this)
|
||||||
|
if( !cond.value == true )
|
||||||
|
raiseError(ObjAssertionError(this,"Assertion failed"))
|
||||||
|
}
|
||||||
|
|
||||||
|
addConst("Real", ObjReal.type)
|
||||||
|
addConst("String", ObjString.type)
|
||||||
|
addConst("Int", ObjInt.type)
|
||||||
|
addConst("Bool", ObjBool.type)
|
||||||
val pi = ObjReal(PI)
|
val pi = ObjReal(PI)
|
||||||
val z = pi.objClass
|
val z = pi.objClass
|
||||||
println("PI class $z")
|
println("PI class $z")
|
||||||
addConst(pi, "π")
|
addConst("π", pi)
|
||||||
getOrCreateNamespace("Math").apply {
|
getOrCreateNamespace("Math").apply {
|
||||||
addConst( "PI", pi)
|
addConst("PI", pi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,13 @@ class BookTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testsFromOOPrinciples() = runTest {
|
fun testsFromOOP() = runTest {
|
||||||
runDocTests("../docs/OOP.md")
|
runDocTests("../docs/OOP.md")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFromReal() = runTest {
|
||||||
|
runDocTests("../docs/real.md")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user