-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtokenizer.hs
More file actions
68 lines (56 loc) · 1.65 KB
/
tokenizer.hs
File metadata and controls
68 lines (56 loc) · 1.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
{-# LANGUAGE LambdaCase #-}
module Tokenizer where
import Data.Char
data Operator
= Add
| Sub
| Mult
| Div
deriving (Eq, Show)
data Token
= TokInt Int
| TokIdent String
| TokOp Operator
| TokAssign
| TokEnd
| TokLParen
| TokRParen
deriving (Eq, Show)
getTokOp :: Token -> Maybe Operator
getTokOp = \case
TokOp x -> Just x
_ -> Nothing
getTokInt :: Token -> Maybe Int
getTokInt = \case
TokInt x -> Just x
_ -> Nothing
getTokIdent :: Token -> Maybe String
getTokIdent = \case
TokIdent x -> Just x
_ -> Nothing
{----------------------------------}
tokenize :: String -> [Token]
tokenize [] = []
tokenize (x : xs) | isSpace x = tokenize xs
| isDigit x = integer (x : xs)
| isAlpha x = idenitfier (x : xs)
| x == '#' = comment (x : xs)
| x `elem` "+-*/" = TokOp (operator x) : tokenize xs
| x == '=' = TokAssign : tokenize xs
| x == ';' = TokEnd : tokenize xs
| x == '(' = TokLParen : tokenize xs
| x == ')' = TokRParen : tokenize xs
where
integer :: String -> [Token]
integer xs = TokInt (read digs) : tokenize rest
where (digs, rest) = span isDigit xs
idenitfier :: String -> [Token]
idenitfier xs = TokIdent ident : tokenize rest
where (ident, rest) = span isAlphaNum xs
comment :: String -> [Token]
comment = tokenize . dropWhile (/= '\n')
operator :: Char -> Operator
operator x | x == '+' = Add
| x == '-' = Sub
| x == '*' = Mult
| x == '/' = Div