🚀 主要機能: • Everything is Box哲学による革新的アーキテクチャ • WebAssemblyブラウザー対応プレイグラウンド • アーティスト協同制作デモ - 複数Boxインスタンス実証 • 視覚的デバッグシステム - DebugBox完全統合 • static box Mainパターン - メモリ安全設計 ⚡ 言語機能: • NOT/AND/OR/除算演算子完全実装 • ジェネリクス/テンプレートシステム • 非同期処理(nowait/await) • try/catchエラーハンドリング • Canvas統合グラフィックス 🎨 ブラウザー体験: • 9種類のインタラクティブデモ • リアルタイムコード実行 • WebCanvas/WebConsole/WebDisplay • モバイル対応完了 🤖 Built with Claude Code collaboration Ready for public release!
271 lines
6.8 KiB
Plaintext
271 lines
6.8 KiB
Plaintext
// ⚙️ LISP Evaluator - eval/apply/環境管理
|
||
// 簡易版LISP評価エンジン
|
||
|
||
NIL = 0
|
||
|
||
// ===== LISP Core関数の再実装(簡単版) =====
|
||
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() { return "(" + me.car.toString() + " . " + me.cdr.toString() + ")" }
|
||
}
|
||
|
||
box SymbolBox {
|
||
name
|
||
init { name }
|
||
SymbolBox(symbolName) {
|
||
me.name = symbolName
|
||
}
|
||
getName() { return me.name }
|
||
toString() { return me.name }
|
||
}
|
||
|
||
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 == "a" or obj == "b" or obj == "c" { return true }
|
||
return false
|
||
}
|
||
|
||
function nullP(obj) { return obj == NIL }
|
||
|
||
// ===== 簡易環境管理(MapBox代替) =====
|
||
box Environment {
|
||
names, values, count
|
||
|
||
init { names, values, count }
|
||
|
||
Environment() {
|
||
me.names = cons(NIL, NIL) // 変数名のリスト
|
||
me.values = cons(NIL, NIL) // 値のリスト
|
||
me.count = 0 // 変数の数
|
||
}
|
||
|
||
// 変数を定義
|
||
define(name, value) {
|
||
me.names = cons(name, me.names)
|
||
me.values = cons(value, me.values)
|
||
me.count = me.count + 1
|
||
}
|
||
|
||
// 変数を検索
|
||
lookup(name) {
|
||
return me.lookupHelper(name, me.names, me.values)
|
||
}
|
||
|
||
lookupHelper(target, nameList, valueList) {
|
||
if nullP(nameList) { return symbol("UNDEFINED") }
|
||
|
||
currentName = car(nameList)
|
||
currentValue = car(valueList)
|
||
|
||
// 名前が一致するかチェック
|
||
if currentName == target {
|
||
return currentValue
|
||
}
|
||
if currentName.toString() == target {
|
||
return currentValue
|
||
}
|
||
|
||
return me.lookupHelper(target, cdr(nameList), cdr(valueList))
|
||
}
|
||
}
|
||
|
||
// ===== 基本的な評価関数 =====
|
||
|
||
// eval - 式を評価
|
||
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 == "a" { return "a" }
|
||
if expr == "b" { return "b" }
|
||
if expr == "c" { return "c" }
|
||
if expr == "hello" { return "hello" }
|
||
if expr == "world" { return "world" }
|
||
|
||
// シンボル(変数)は環境から検索
|
||
return env.lookup(expr.toString())
|
||
}
|
||
|
||
// リスト(関数呼び出し)の場合
|
||
operator = car(expr)
|
||
operands = cdr(expr)
|
||
|
||
// 特殊形式の処理
|
||
opName = operator.toString()
|
||
|
||
// quote - リテラル
|
||
if opName == "quote" {
|
||
return car(operands)
|
||
}
|
||
|
||
// if - 条件分岐
|
||
if opName == "if" {
|
||
condition = lispEval(car(operands), env)
|
||
if not nullP(condition) {
|
||
return lispEval(car(cdr(operands)), env) // then節
|
||
} else {
|
||
return lispEval(car(cdr(cdr(operands))), env) // else節
|
||
}
|
||
}
|
||
|
||
// define - 変数定義
|
||
if opName == "define" {
|
||
varName = car(operands).toString()
|
||
value = lispEval(car(cdr(operands)), env)
|
||
env.define(varName, value)
|
||
return value
|
||
}
|
||
|
||
// 通常の関数呼び出し
|
||
func = lispEval(operator, env)
|
||
args = lispEvalList(operands, env)
|
||
return lispApply(func, args, env)
|
||
}
|
||
|
||
// 引数リストを評価
|
||
function lispEvalList(exprs, env) {
|
||
if nullP(exprs) { return NIL }
|
||
first = lispEval(car(exprs), env)
|
||
rest = lispEvalList(cdr(exprs), env)
|
||
return cons(first, rest)
|
||
}
|
||
|
||
// apply - 関数適用
|
||
function lispApply(func, args, env) {
|
||
funcName = func.toString()
|
||
|
||
// 組み込み関数
|
||
if funcName == "+" {
|
||
return lispAdd(args)
|
||
}
|
||
if funcName == "-" {
|
||
return lispSub(args)
|
||
}
|
||
if funcName == "*" {
|
||
return lispMul(args)
|
||
}
|
||
if funcName == "car" {
|
||
return car(car(args))
|
||
}
|
||
if funcName == "cdr" {
|
||
return cdr(car(args))
|
||
}
|
||
if funcName == "cons" {
|
||
return cons(car(args), car(cdr(args)))
|
||
}
|
||
if funcName == "atom?" {
|
||
return atomP(car(args))
|
||
}
|
||
if funcName == "null?" {
|
||
return nullP(car(args))
|
||
}
|
||
|
||
return symbol("UNKNOWN-FUNCTION")
|
||
}
|
||
|
||
// 算術演算の実装
|
||
function lispAdd(args) {
|
||
if nullP(args) { return 0 }
|
||
return car(args) + lispAdd(cdr(args))
|
||
}
|
||
|
||
function lispSub(args) {
|
||
if nullP(args) { return 0 }
|
||
if nullP(cdr(args)) { return 0 - car(args) } // 単項マイナス
|
||
return car(args) - lispAdd(cdr(args))
|
||
}
|
||
|
||
function lispMul(args) {
|
||
if nullP(args) { return 1 }
|
||
return car(args) * lispMul(cdr(args))
|
||
}
|
||
|
||
// ===== グローバル環境初期化 =====
|
||
function makeGlobalEnv() {
|
||
env = new Environment()
|
||
|
||
// 組み込み関数を定義
|
||
env.define("+", symbol("+"))
|
||
env.define("-", symbol("-"))
|
||
env.define("*", symbol("*"))
|
||
env.define("car", symbol("car"))
|
||
env.define("cdr", symbol("cdr"))
|
||
env.define("cons", symbol("cons"))
|
||
env.define("atom?", symbol("atom?"))
|
||
env.define("null?", symbol("null?"))
|
||
|
||
// 特殊値
|
||
env.define("nil", NIL)
|
||
env.define("t", true)
|
||
|
||
return env
|
||
}
|
||
|
||
// ===== 簡易パーサー(手動構築版) =====
|
||
function parseManual() {
|
||
// (+ 1 2) を手動構築
|
||
expr1 = list3(symbol("+"), 1, 2)
|
||
return expr1
|
||
}
|
||
|
||
// ===== テスト =====
|
||
print("⚙️ === LISP Evaluator Test === ⚙️")
|
||
print("")
|
||
|
||
// 環境準備
|
||
globalEnv = makeGlobalEnv()
|
||
|
||
print("1. Simple arithmetic:")
|
||
// (+ 1 2)
|
||
expr = list3(symbol("+"), 1, 2)
|
||
print(" Expression: " + expr.toString())
|
||
result = lispEval(expr, globalEnv)
|
||
print(" Result: " + result)
|
||
|
||
print("")
|
||
print("2. Nested expression:")
|
||
// (+ 1 (* 2 3))
|
||
inner = list3(symbol("*"), 2, 3)
|
||
expr2 = list3(symbol("+"), 1, inner)
|
||
print(" Expression: " + expr2.toString())
|
||
result2 = lispEval(expr2, globalEnv)
|
||
print(" Result: " + result2)
|
||
|
||
print("")
|
||
print("✅ LISP Evaluator test completed!")
|
||
print("🎯 Ready for full LISP interpreter!") |