Code and Notes
Table of Contents
This is the Haskell code we looked at during the first lecture, and some relevant notes.
1. Using Haskell
The initial lexer code below was typed live in the lecture. This was done using some low-tech editor technology. There is good support for Haskell in a variety of other editors, e.g. VS Code. We recommend you experiment and discover what setup suits you.
During the lecture this code mostly run and tested using the `ghci` interactive terminal for Haskell. This is a good way to do some exploration. More substantial projects will have a more conventional build system.
2. Lexer
module Lexer where -- Import character-related functions from the standard library. import Data.Char -- A multi-constructor datatype. data Token = LParen | RParen | Semi | LBrace | RBrace | Ident String | Return | Number Integer | Equals deriving (Show, Eq) -- A very simple function. add1 :: Integer -> Integer add1 x = (x + 1) -- my_show :: Token -> String -- my_show tok = case tok of -- Return -> "Return" -- Equals -> "Equals" my_show :: Token -> String my_show Return = "Return" my_show (Number n) = show n -- A type that is equivalent to the builtin list type. data My_List a = Empty_List | Nonempty_List a (My_List a) deriving Show -- Mapping from my list type to the standard one. my_list_to_list :: My_List a -> [a] my_list_to_list Empty_List = [] my_list_to_list (Nonempty_List x xs) = ([x] ++ my_list_to_list xs) -- Mapping from the standard list to my version. -- This allows us to see the real shape of [1, 2] and "3, 4". list_to_my_list :: [a] -> My_List a list_to_my_list [] = Empty_List list_to_my_list (x : xs) = Nonempty_List x (list_to_my_list xs) -- First steps toward defining a lexer. lexer :: String -> [Token] lexer ('{' : cs) = LBrace : lexer cs lexer ('}' : cs) = RBrace : lexer cs lexer ('(' : cs) = LParen : lexer cs lexer (')' : cs) = RParen : lexer cs lexer (';' : cs) = Semi : lexer cs lexer ('=' : cs) = Equals : lexer cs lexer [] = [] lexer (c : cs) = if isDigit c then lex_from_digit (c : cs) else [] lex_from_digit :: String -> [Token] lex_from_digit [] = [] lex_from_digit (c : cs) = undefined