Files
hakorune/examples/lisp/cons_box.hako

228 lines
5.4 KiB
Plaintext
Raw Normal View History

// 📦 ConsBox - LISPのcons cell実装
// ペアcar, cdrを表現する基本データ構造
box ConsBox {
car // 最初の要素
cdr // 残りの要素通常は別のConsBoxかNullBox
init {
car, cdr
}
// 基本アクセサ
func getCar() {
return me.car
}
func getCdr() {
return me.cdr
}
func setCar(value) {
me.car = value
}
func setCdr(value) {
me.cdr = value
}
// リストかどうかの判定
func isList() {
// cdrがNullBoxならリストの終端
if (NullBox.check_null(me.cdr)) {
return true
}
// cdrがConsBoxなら再帰的にチェック
// TODO: 型チェックの別の方法が必要
// 暫定的にtrueを返す
return true
// それ以外はドット対
return false
}
// リストの長さを取得
func length() {
if (not me.isList()) {
return -1 // リストでない場合は-1
}
count = 0
current = me
loop(not NullBox.check_null(current)) {
count = count + 1
current = current.getCdr()
}
return count
}
// n番目の要素を取得0ベース
func nth(n) {
if (n < 0) {
return new NullBox()
}
current = me
i = 0
loop(i < n) {
if (NullBox.check_null(current)) {
return new NullBox()
}
current = current.getCdr()
i = i + 1
}
if (NullBox.check_null(current)) {
return new NullBox()
}
return current.getCar()
}
// リストを配列に変換
func toArray() {
result = new ArrayBox()
current = me
loop(not NullBox.check_null(current)) {
result.push(current.getCar())
cdr = current.getCdr()
// ドット対の場合
// TODO: 型チェックの別の方法が必要
// 暫定的にスキップ
current = cdr
}
return result
}
// 文字列表現
func toString() {
// 空リスト
if (NullBox.check_null(me.car) and NullBox.check_null(me.cdr)) {
return "()"
}
result = "("
current = me
first = true
loop(not NullBox.check_null(current)) {
if (not first) {
result = result + " "
}
first = false
// carの表示
car = current.getCar()
if (NullBox.check_null(car)) {
result = result + "nil"
} else {
result = result + car.toString()
}
// cdrの確認
cdr = current.getCdr()
if (NullBox.check_null(cdr)) {
break
}
// ドット対の場合
// TODO: 型チェックの別の方法が必要
// 暫定的にスキップ
current = cdr
}
result = result + ")"
return result
}
// デバッグ用の詳細表示
func debugPrint() {
print("ConsBox {")
print(" car: " + me.car.toString())
print(" cdr: " + me.cdr.toString())
print(" isList: " + me.isList())
if (me.isList()) {
print(" length: " + me.length())
}
print("}")
}
}
// ヘルパー関数:配列からリストを作成
function arrayToList(arr) {
if (arr.length() == 0) {
return new NullBox()
}
// 逆順に構築
result = new NullBox()
i = arr.length() - 1
loop(i >= 0) {
result = new ConsBox(arr.get(i), result)
i = i - 1
}
return result
}
// ヘルパー関数:可変長引数でリストを作成
function list() {
// TODO: 可変長引数のサポートが必要
// 現在は固定数の引数での実装例
return new NullBox()
}
// テストコード
print("🎯 === ConsBox Test ===")
// 基本的なペア
print("📦 基本的なペア (1 . 2):")
pair = new ConsBox(new IntegerBox(1), new IntegerBox(2))
print(pair.toString())
pair.debugPrint()
// リスト (1 2 3)
print("\n📋 リスト (1 2 3):")
list123 = new ConsBox(
new IntegerBox(1),
new ConsBox(
new IntegerBox(2),
new ConsBox(
new IntegerBox(3),
new NullBox()
)
)
)
print(list123.toString())
print("Length: " + list123.length())
print("2nd element: " + list123.nth(1).toString())
// 配列からリストを作成
print("\n🔄 配列からリスト作成:")
arr = new ArrayBox()
arr.push(new StringBox("hello"))
arr.push(new StringBox("world"))
arr.push(new IntegerBox(42))
listFromArray = arrayToList(arr)
print(listFromArray.toString())
// ネストしたリスト ((1 2) (3 4))
print("\n🎯 ネストしたリスト:")
innerList1 = new ConsBox(
new IntegerBox(1),
new ConsBox(new IntegerBox(2), new NullBox())
)
innerList2 = new ConsBox(
new IntegerBox(3),
new ConsBox(new IntegerBox(4), new NullBox())
)
nestedList = new ConsBox(
innerList1,
new ConsBox(innerList2, new NullBox())
)
print(nestedList.toString())
print("\n✅ ConsBox implementation completed!")