// 🚀 Enhanced LISP - 変数定義・条件分岐対応版
// define, if, quote などの特殊形式を実装

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 }
    toString() { 
        if me.cdr == NIL {
            return "(" + me.car.toString() + ")"
        } else {
            if me.isConsBox(me.cdr) {
                return "(" + me.car.toString() + " " + me.cdr.toStringList() + ")"
            } else {
                return "(" + me.car.toString() + " . " + me.cdr.toString() + ")"
            }
        }
    }
    
    toStringList() {
        if me.cdr == NIL {
            return me.car.toString()
        } else {
            if me.isConsBox(me.cdr) {
                return me.car.toString() + " " + me.cdr.toStringList()
            } else {
                return me.car.toString() + " . " + me.cdr.toString()
            }
        }
    }
    
    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 == "+" { return false }
        if obj == "-" { return false }
        if obj == "*" { return false }
        if obj == "x" { return false }
        if obj == "y" { return false }
        return true
    }
}

box SymbolBox {
    name
    init { name }
    SymbolBox(symbolName) { 
        me.name = symbolName 
    }
    toString() { return me.name }
}

// ===== 環境管理（変数の保存・検索） =====
box Environment {
    names
    values
    
    init { names, values }
    
    Environment() {
        me.names = NIL
        me.values = NIL
    }
    
    // 変数を定義
    define(name, value) {
        me.names = cons(name, me.names)
        me.values = cons(value, me.values)
    }
    
    // 変数を検索
    lookup(targetName) {
        return me.lookupHelper(targetName, me.names, me.values)
    }
    
    lookupHelper(target, nameList, valueList) {
        if nameList == NIL { 
            return symbol("UNDEFINED")
        }
        
        // 安全なcar/cdr呼び出し
        if nameList == NIL { return symbol("UNDEFINED") }
        if valueList == NIL { return symbol("UNDEFINED") }
        
        currentName = car(nameList)
        currentValue = car(valueList)
        
        if currentName == target {
            return currentValue
        }
        
        nextNames = cdr(nameList)
        nextValues = cdr(valueList)
        return me.lookupHelper(target, nextNames, nextValues)
    }
}

// ===== 基本関数 =====
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 symbol(name) { return new SymbolBox(name) }
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))) }

function atomP(obj) {
    if obj == NIL { return true }
    if obj == 0 or obj == 1 or obj == 2 or obj == 3 or obj == 4 { return true }
    if obj == 5 or obj == 6 or obj == 7 or obj == 8 or obj == 9 { return true }
    if obj == "+" or obj == "-" or obj == "*" { return true }
    if obj == "x" or obj == "y" or obj == "hello" { return true }
    return false
}

// ===== 拡張評価器 =====
function lispEval(expr, env) {
    // アトムの場合
    if atomP(expr) {
        // 数値リテラル
        if expr == 0 { return 0 }
        if expr == 1 { return 1 }
        if expr == 2 { return 2 }
        if expr == 3 { return 3 }
        if expr == 4 { return 4 }
        if expr == 5 { return 5 }
        if expr == 6 { return 6 }
        if expr == 7 { return 7 }
        if expr == 8 { return 8 }
        if expr == 9 { return 9 }
        
        // 文字列リテラル
        if expr == "hello" { return "hello" }
        if expr == "world" { return "world" }
        if expr == "true" { return true }
        if expr == "false" { return false }
        
        // シンボル（変数）は環境から検索
        return env.lookup(expr)
    }
    
    // リスト（関数呼び出し）の場合
    operator = car(expr)
    operands = cdr(expr)
    
    // 特殊形式の処理
    if operator == "quote" {
        return car(operands)
    }
    
    if operator == "define" {
        varName = car(operands)
        value = lispEval(car(cdr(operands)), env)
        env.define(varName, value)
        return value
    }
    
    if operator == "if" {
        condition = lispEval(car(operands), env)
        thenExpr = car(cdr(operands))
        elseExpr = car(cdr(cdr(operands)))
        
        if condition != NIL and condition != false {
            return lispEval(thenExpr, env)
        } else {
            return lispEval(elseExpr, env)
        }
    }
    
    // 通常の関数呼び出し
    if operator == "+" {
        arg1 = lispEval(car(operands), env)
        arg2 = lispEval(car(cdr(operands)), env)
        return arg1 + arg2
    }
    
    if operator == "-" {
        arg1 = lispEval(car(operands), env)
        arg2 = lispEval(car(cdr(operands)), env)
        return arg1 - arg2
    }
    
    if operator == "*" {
        arg1 = lispEval(car(operands), env)
        arg2 = lispEval(car(cdr(operands)), env)
        return arg1 * arg2
    }
    
    if operator == "=" {
        arg1 = lispEval(car(operands), env)
        arg2 = lispEval(car(cdr(operands)), env)
        if arg1 == arg2 { return true } else { return false }
    }
    
    if operator == ">" {
        arg1 = lispEval(car(operands), env)
        arg2 = lispEval(car(cdr(operands)), env)
        if arg1 > arg2 { return true } else { return false }
    }
    
    return symbol("UNKNOWN-OP")
}

// ===== テスト =====
print("🚀 === Enhanced LISP Test === 🚀")
print("")

// 環境を作成
env = new Environment()

print("1. Variable definition and lookup:")
// (define x 42)
defineExpr = list3("define", "x", 42)
print("   " + defineExpr.toString())
result = lispEval(defineExpr, env)
print("   → " + result)

// x を参照
print("   x")
xValue = lispEval("x", env)
print("   → " + xValue)

print("")
print("2. Using variables in expressions:")
// (+ x 10)
expr1 = list3("+", "x", 10)
print("   " + expr1.toString())
result1 = lispEval(expr1, env)
print("   → " + result1)

print("")
print("3. Conditional expressions:")
// (if (> x 40) "big" "small")
condition = list3(">", "x", 40)
ifExpr = list3("if", condition, "big")  // else省略版
print("   (if (> x 40) \"big\")")
result2 = lispEval(ifExpr, env)
print("   → " + result2)

print("")
print("4. Quote (literal data):")
// (quote (1 2 3))
listData = list3(1, 2, 3)
quoteExpr = list2("quote", listData)
print("   " + quoteExpr.toString())
result3 = lispEval(quoteExpr, env)
print("   → " + result3.toString())

print("")
print("✅ Enhanced LISP interpreter working!")
print("🎯 Variables, conditionals, and quotes implemented!")