9b4aa785创建于 1月20日历史提交
package egg

interface Expression {
    func evaluate(env: Env): Object
    func toString(): String
}

// 值表达式
class ValueExpression <: Expression {
    var value: Object

    public init(value: Object) {
        this.value = value
    }

    public override func evaluate(env: Env): Object {
        return this.value
    }

    public override func toString(): String {
        try {
            match (this.value) {
                case str: Value<String> => "${str.value}"
                case num: Value<Float64> => "${num.value}"
                case num: Value<Int64> => "${num.value}"
                case bool: Value<Bool> => "${bool.value}"
                case _ => "unknown"
            }
        } catch (e: Exception) {
            throw EvaluateException("字符串转换错误")
        }
    }
}

// 标识符表达式
class WordExpression <: Expression {
    var name: String

    public init(name: String) {
        this.name = name
    }

    public override func evaluate(env: Env): Object {
        let value = env.get(this.name)
        return value.getOrThrow({=> EvaluateException("未定义的变量: ${this.name}")})
    }

    public override func toString(): String {
        return this.name
    }
}

// 应用表达式
class ApplyExpression <: Expression {
    var op: Expression
    var args: Array<Expression>

    public init(op: Expression, args: Array<Expression>) {
        this.op = op
        this.args = args
    }

    func getArgList(args: Array<Expression>, env: Env): Array<Object> {
        let argList = Array<Object>(args.size, repeat: Object())
        for (i in 0..args.size) {
            let arg = args[i]
            let value = arg.evaluate(env)
            argList[i] = value
        }
        return argList
    }

    public override func evaluate(env: Env): Object {
        let opValue: Object = this.op.evaluate(env)

        if (opValue is SpecialForm) {
            let spcialOp = (opValue as SpecialForm).getOrThrow({=> EvaluateException("操作符不是一个特殊形式")})
            return spcialOp.apply(this.args, env)
        } else if (opValue is EggFunction) {
            let argList = getArgList(this.args, env)
            let eggOp = (opValue as EggFunction).getOrThrow({=> EvaluateException("操作符不是一个函数")})
            return eggOp.apply(argList)
        } else {
            throw EvaluateException("操作符不是一个函数或特殊形式" + this.op.toString())
        }
    }

    public override func toString(): String {
        let argStrs = Array<String>(this.args.size, repeat: "")
        for (i in 0..this.args.size) {
            argStrs[i] = this.args[i].toString() + " "
        }
        return "(${this.op.toString()} ${argStrs.toString()})"
    }
}

class EvaluateException <: Exception {
    public init(message: String) {
        super(message)
    }
}