I'm currently working on a language and have come to an issue regarding variable declarations in that to check what value a variable is in the REPL, I must use quotation marks.
> x := 1
> "x"
1
The desired behaviour however would be the following:
> x := 1
> x
1
I have defined my ADT in the following way:
data S = Integer Integer | String String | Assign String S | Expr Add [S]
I can parse everything correctly.
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
I think however that the problem is done to the evaluation functions.
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
If I keep the first line that evaluates a string, the following occurs in the REPL and I receive a warning that the second line is redundant:
> x := 1
> "x"
'x'
If I keep the second line however I get the behaviour as described from the beginning.
In both cases, quotations around the variable have to be placed in order to evaluate it. I recongise though that I use many1 letter
rather than parseString
in the function parseAssign
. I have tried changing this to parseString
but I obtain the same behaviour.
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? I tried changing parseString
to the following (many1 letter >>= (return . String)
) but it neither assigns nor allows for the use of strings like before.
Should variables and strings be treated differently in constructing a language?
Yes
data S = ...
Should be:
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?
That should be obvious. See the definition:
parseString = char '"' *> ...
The very first part of parseString clearly looks to parse char '"'
.
The definition of parseAssign does not look for "
.
I tried changing parseString to the following (many1 letter >>= (return . String)) but it neither assigns nor allows for the use of strings like before.
Well "
is not a letter
so it shouldn't/wouldn't allow for a quotation mark. More, it wouldn't "assign", whatever that verb means, because it lacks the Assign
constructor along with all the other critical parts of parseAssign
.