Skip to content

Latest commit

 

History

History
77 lines (70 loc) · 2.74 KB

File metadata and controls

77 lines (70 loc) · 2.74 KB

4.6总决赛

我们的 Monkey 解释器现在功能齐全。 它支持数学表达式、变量绑定、函数以及这些函数的应用、条件、返回语句甚至高级概念,如高阶函数和闭包。 然后是不同的数据类型:整数、布尔值、字符串、数组和哈希。 我们可以为自己感到自豪。

但是……但是……我们的解释器仍然没有通过所有编程语言测试中最基本的测试:打印一些东西。 是的,我们的 Monkey 翻译器无法与外界交流。 甚至像 Bash 和 Brainfuck 这样的编程语言流氓也设法做到了这一点。 我们必须做什么很清楚。 我们必须添加最后一个内置函数:puts。

puts 将新行中的给定参数打印到 STDOUT。 它对作为参数传入的对象调用 Inspect() 方法并打印这些调用的返回值。 Inspect() 方法是 Object 接口的一部分,因此我们对象系统中的每个实体都支持它。 使用 puts 应该看起来像这样:

>> puts("Hello!")
Hello!
>> puts(1234)
1234
>> puts(fn(x) { x * x })
fn(x) {
(x * x)
}

puts 是一个可变参数函数。 它接受无限数量的参数并将每个参数打印在单独的行上:

>> puts("hello", "world", "how", "are", "you")
hello
world
how
are
you

当然,puts 就是打印东西而不是产生值,所以我们需要确保它返回 NULL:

>> let putsReturnValue = puts("foobar");
foobar
>> putsReturnValue
null

这也意味着我们的 REPL 将在我们期望的输出之外打印空值。 所以它看起来像这样:

>> puts("Hello!")
Hello!
null

现在,这些信息和规范足以完成我们的最后一项任务。你准备好了吗?

在这里,这是本节一直在构建的内容,这是 puts 的完整、有效的实现:

// evaluator/builtins.go

import (
    "fmt"
    "monkey/object"
    "unicode/utf8"
)

var builtins = map[string]*object.Builtin{
// [...]
    "puts": &object.Builtin{
        Fn: func(args ...object.Object) object.Object {
            for _, arg := range args {
                fmt.Println(arg.Inspect())
            }

            return NULL
        },
    },
}

有了这个,我们做到了。 我们完成了。 即使您之前对我们的小庆祝活动持谨慎态度并且对它们不屑一顾,现在也该去寻找一顶有趣的派对帽并戴上它了。

在第三章中,我们将 Monkey 编程语言带入了生活。 它开始呼吸。 通过我们的最后一次更改,我们让它说话了。 现在,Monkey 终于成为一种真正的编程语言:

$ go run main.go
Hello mrnugget! This is the Monkey programming language!
Feel free to type in commands
>> puts("Hello World!")
Hello World!
null
>>
< 4.5哈希对象 > 资源