Go中的Scheme解释器

时间:2015-07-07 21:26:05

标签: go compiler-construction scheme lisp interpreter

我是一名基本的Go程序员,我一直在看这个小型的Scheme解释器,我一直试图了解它是如何工作的。

我在这里找到了: https://pkelchte.wordpress.com/2013/12/31/scm-go/

我阅读了网页,但我仍然在努力理解它是如何工作的,因为源代码显然是由一个比我更熟悉Go的人编写的。

特别是我正在努力理解这些界限:

pb

我不确定e := expression.(type) // Line 73 部分是什么意思,我认为它是铸造的,但它看起来不像我以前见过的铸造。

.(type)

说实话,我真的不明白这些代码。第73-86行

switch p := procedure.(type) {
case func(...scmer) scmer:
    value = p(args...)
case proc:
    en := &env{make(vars), p.en}
    switch params := p.params.(type) {
    case []scmer:
        for i, param := range params {
            en.vars[param.(symbol)] = args[i]
        }
    default:
        en.vars[params.(symbol)] = args
    }
    value = eval(p.body, en)

我不确定这条线的含义是什么,因为它的语法很奇怪。我得到它的指针,并且括号是因为*。但我不确定那些线路在做什么。

最后有以下几行:

*tokens = (*tokens)[1:] // Line 208

我不知道这些线路是做什么的。第198 - 209行

如果您需要,这是完整的代码,我意识到它长达250行,但我真的很感激尽可能多的解释。

token := (*tokens)[0]
*tokens = (*tokens)[1:]
switch token {
case "(": //a list begins
    L := make([]scmer, 0)
    for (*tokens)[0] != ")" {
        if i := readFrom(tokens); i != symbol("") {
            L = append(L, i)
        }
    }
    *tokens = (*tokens)[1:]
    return L

2 个答案:

答案 0 :(得分:2)

首先是类型切换。您可以更多地了解here

第二个就像在python中一样切片(如果你知道的话,应该很熟悉)

ls = ls[1:]

我们正在跳过第一项并获取切片/列表的其余部分。

正如我从你的评论中看到的那样,我认为尝试golang并不是一个好的起点。

答案 1 :(得分:1)

e := expression.(type)type assertion

switch p := procedure.(type) {(包含以下案例陈述)是type switch

*tokens = (*tokens)[1:]slice expression更改*tokens中存储的值。

token := (*tokens)[0]       // Set token to first element of tokens slice.
*tokens = (*tokens)[1:]     // Update tokens to remove first element.
switch token {              // Switch on token.
case "(": //a list begins   // If token is "("
    L := make([]scmer, 0)       // Make a new, empty slice.
    for (*tokens)[0] != ")" {   // While the first element of tokens is not ")":
                                    // Read from tokens; if not empty symbol:
        if i := readFrom(tokens); i != symbol("") {
            L = append(L, i)        // Add the token read (in i) to L.
        }
    }
    *tokens = (*tokens)[1:]     // Remove the first element from tokens.
    return L                    // Return the newly created slice.