136 lines
3.1 KiB
Plaintext
136 lines
3.1 KiB
Plaintext
|
|
// 📦 ConsBox - シンプルなLISP cons cell実装
|
|||
|
|
// コンストラクタ引数版
|
|||
|
|
|
|||
|
|
// グローバルなnil値(0を使用)
|
|||
|
|
NIL = 0
|
|||
|
|
|
|||
|
|
box ConsBox {
|
|||
|
|
car
|
|||
|
|
cdr
|
|||
|
|
|
|||
|
|
init { car, cdr }
|
|||
|
|
|
|||
|
|
// コンストラクタ引数対応
|
|||
|
|
ConsBox(a, d) {
|
|||
|
|
me.car = a
|
|||
|
|
me.cdr = d
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getCar() { return me.car }
|
|||
|
|
getCdr() { return me.cdr }
|
|||
|
|
setCar(value) { me.car = value }
|
|||
|
|
setCdr(value) { me.cdr = value }
|
|||
|
|
|
|||
|
|
// 改良されたtoString()メソッド - プロパーリスト対応
|
|||
|
|
toString() {
|
|||
|
|
return "(" + me.toStringList() + ")"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// リスト要素を収集するヘルパーメソッド
|
|||
|
|
toStringList() {
|
|||
|
|
// carの文字列表現
|
|||
|
|
carStr = ""
|
|||
|
|
if me.car == NIL {
|
|||
|
|
carStr = "nil"
|
|||
|
|
} else {
|
|||
|
|
carStr = me.car.toString()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// cdrの処理
|
|||
|
|
if me.cdr == NIL {
|
|||
|
|
// 最後の要素
|
|||
|
|
return carStr
|
|||
|
|
} else {
|
|||
|
|
// cdrがConsBoxの場合はリスト継続
|
|||
|
|
if me.isConsBox(me.cdr) {
|
|||
|
|
return carStr + " " + me.cdr.toStringList()
|
|||
|
|
} else {
|
|||
|
|
// インプロパーリスト
|
|||
|
|
cdrStr = me.cdr.toString()
|
|||
|
|
return carStr + " . " + cdrStr
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ConsBoxかどうかをチェック(改良版)
|
|||
|
|
isConsBox(obj) {
|
|||
|
|
if obj == NIL { return false }
|
|||
|
|
if obj == 0 { return false }
|
|||
|
|
if obj == 1 { return false }
|
|||
|
|
if obj == 2 { return false }
|
|||
|
|
if obj == 3 { return false }
|
|||
|
|
if obj == 4 { return false }
|
|||
|
|
if obj == 5 { return false }
|
|||
|
|
if obj == 6 { return false }
|
|||
|
|
if obj == 7 { return false }
|
|||
|
|
if obj == 8 { return false }
|
|||
|
|
if obj == 9 { return false }
|
|||
|
|
// 文字列チェック(簡易版)
|
|||
|
|
if obj == "a" { return false }
|
|||
|
|
if obj == "b" { return false }
|
|||
|
|
if obj == "c" { return false }
|
|||
|
|
if obj == "" { return false }
|
|||
|
|
// それ以外はConsBoxと仮定
|
|||
|
|
return true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 基本関数
|
|||
|
|
function cons(a, d) {
|
|||
|
|
return new ConsBox(a, d)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function car(pair) {
|
|||
|
|
if pair == NIL { return NIL }
|
|||
|
|
return pair.getCar()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function cdr(pair) {
|
|||
|
|
if pair == NIL { return NIL }
|
|||
|
|
return pair.getCdr()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// リスト作成関数
|
|||
|
|
function list1(a) {
|
|||
|
|
return cons(a, NIL)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function list2(a, b) {
|
|||
|
|
return cons(a, cons(b, NIL))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function list3(a, b, c) {
|
|||
|
|
return cons(a, cons(b, cons(c, NIL)))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// テスト
|
|||
|
|
print("=== Simple ConsBox Test ===")
|
|||
|
|
print("")
|
|||
|
|
|
|||
|
|
// 基本的なcons
|
|||
|
|
print("1. Basic cons cells:")
|
|||
|
|
p1 = cons(1, 2)
|
|||
|
|
print(" (cons 1 2) = " + p1.toString())
|
|||
|
|
p2 = new ConsBox(3, 4)
|
|||
|
|
print(" new ConsBox(3, 4) = " + p2.toString())
|
|||
|
|
|
|||
|
|
// リスト
|
|||
|
|
print("")
|
|||
|
|
print("2. Lists:")
|
|||
|
|
l1 = list3("a", "b", "c")
|
|||
|
|
print(" (list 'a' 'b' 'c') = " + l1.toString())
|
|||
|
|
|
|||
|
|
// car/cdr
|
|||
|
|
print("")
|
|||
|
|
print("3. car/cdr:")
|
|||
|
|
print(" (car l1) = " + car(l1))
|
|||
|
|
print(" (cdr l1) = " + cdr(l1).toString())
|
|||
|
|
|
|||
|
|
// ネスト
|
|||
|
|
print("")
|
|||
|
|
print("4. Nested structures:")
|
|||
|
|
nested = cons(cons(1, 2), cons(3, 4))
|
|||
|
|
print(" ((1 . 2) . (3 . 4)) = " + nested.toString())
|
|||
|
|
|
|||
|
|
print("")
|
|||
|
|
print("✅ Done!")
|