在构建语言时是否应该区别对待变量和字符串?

Should variables and strings be treated differently in constructing a language?

我目前正在研究一种语言,遇到了一个关于变量声明的问题,为了检查变量在 REPL 中的值,我必须使用引号。

> x := 1
> "x"
1

然而,所需的行为如下:

> x := 1
> x
1

我按以下方式定义了我的 ADT:

data S = Integer Integer | String String | Assign String S | Expr Add [S] 

我可以正确解析所有内容。

parseString :: Parser HVal
parseString = char '"' *> many1 (noneOf "\"") <* char '"' >>= (return . String)

parseAssign :: Parser HVal
parseAssign = do
         var <- many1 letter
         spaces
         string ":="
         spaces
         val <- try (parsersHVal)
         spaces
         return $ Assign var val

不过我认为问题出在评估函数上。

evalHVal :: Env -> HVal -> IOThrowsError HVal
evalHVal env val@(Integer _)  = return $ val
evalHVal env val@(String  _)  = return $ val
evalHVal env (String  val)    = getVar env val >>= \var -> evalHVal env var

如果我保留计算字符串的第一行,REPL 中会出现以下情况,并且我会收到第二行多余的警告:

> x := 1
> "x"
'x'

如果我保留第二行,我会得到从一开始就描述的行为。

在这两种情况下,都必须在变量周围加上引号才能对其进行评估。我意识到我在函数 parseAssign 中使用 many1 letter 而不是 parseString。我尝试将其更改为 parseString 但我得到了相同的行为。

然而,最让我困惑的是,既然所有内容都是作为字符串读入的,那么为什么 many1 letter 不需要像 parseString 那样在 parseAssign 中使用引号?我尝试将 parseString 更改为以下内容 (many1 letter >>= (return . String)),但它既不分配也不允许像以前那样使用字符串。

变量和字符串应该被区别对待。尽管它们在源语言中都是字符串,但它们不能被等同对待,因为它们在语言的数据模型中是不同的。

Should variables and strings be treated differently in constructing a language?

data S = ...

应该是:

data S = ... | Var String

What confuses me the most however is that since everything is read in as a string, then why doesn't many1 letter require quotations in parseAssign like how parseString requires?

这应该是显而易见的。见定义:

parseString = char '"' *>  ...

parseString 的第一部分显然看起来是在解析 char '"'

parseAssign 的定义没有寻找".

I tried changing parseString to the following (many1 letter >>= (return . String)) but it neither assigns nor allows for the use of strings like before.

嗯," 不是 letter,所以它不应该't/wouldn 允许使用引号。此外,它不会“分配”,无论动词是什么意思,因为它缺少 Assign 构造函数以及 parseAssign.

的所有其他关键部分