Haskell:定义语言的解释器

时间:2016-10-02 09:17:43

标签: haskell interpreter

作为定义语言解释器的一部分,我有以下定义:

initCtx :: Context
initCtx = (Map.empty, initEnv)
  where initEnv =
          Map.fromList [ ...
                       , ("+", undefined)
                         ...
                       ]

对于总和操作,我有这个:

evalExpr :: Expr -> Interpreter Value
evalExpr (e1 :+: e2) = do v1 <- eval e1
                      v2 <- eval e2
                      return Interpreter $ (v1 + v2)

exalExpr是由我创建的,但是我需要编写什么来代替undefined以便执行表达式?或者,也许,我正在寻找错误的东西?我当然有更多的操作,但我只需要一个例子。我是Haskell的新手,我几乎需要处理它。

谢谢!

修改

type Env = Map Ident Value
type Primitive = [Value] -> Interpreter Value
type PEnv = Map FunName Primitive
type Context = (Env, PEnv)

这是Expr

data Expr = Number Int
          | String String
          | Array [Expr]
          | Undefined
          | TrueConst
          | FalseConst
          | Var Ident
          | Compr ArrayFor Expr
          | Call FunName [Expr]
          | Assign Ident Expr
          | Comma Expr Expr
          deriving (Eq, Read, Show)

Interpreter

newtype Interpreter a = Interpreter {runInterpreter :: Context -> Either Error (a, Env)}

和价值:

data Value = IntVal Int
           | UndefinedVal
           | TrueVal | FalseVal
           | StringVal String
           | ArrayVal [Value]
           deriving (Eq, Show)

1 个答案:

答案 0 :(得分:1)

好吧,我会捅这个...

所以看起来Context由一对地图组成。看来第一张地图可让您从名称中查找变量的值。第二个允许您查找函数名称并获取相应的可执行代码。

您正在使用Interpreter,好像它是一个monad;我不知道它是否确实存在,但看起来似乎有道理。

所以initCtx开始时没有定义任何变量(Map.empty),并且可能你想在第二张地图中放置一堆预定义函数,例如+。< / p>

查看Primitive的定义,它会获取Value的列表并返回Interpreter次计算。所以我猜它看起来像

addExpr :: [Value] -> Interpreter Value
addExpr [e1, e2] = do
  v1 <- eval e1
  v2 <- eval e2
  return (v1 + v2)

然后你可以写map.fromList [... ("+", addExpr) ...]

除此之外也不太正确。 Value不是数字类型;如果,例如,v1 = StringVal会发生什么?就此而言,如果有人打电话给&#34; +&#34;有不同数量的参数?我们需要在这里进行一些错误检查。

猜测您正在寻找的东西可能看起来像这样:

checkInt :: Value -> Interpreter Int
checkInt (IntVal x) = return x
checkInt _          = Interpreter $ ctx -> Left "Not an integer."

addExpr :: [Value] -> Interpreter Value
addExpr [expr1, expr2] do
  val1 <- eval expr1
  int1 <- checkInt val1

  val2 <- eval expr2
  int2 <- checkInt val2

  return (IntVal $ int1 + int2)
addExpr _ = Interpreter $ ctx -> error "Wrong number of arguments."
相关问题