0 | module Go.Token
  1 |
  2 | import public Data.Fin
  3 | import Data.List
  4 |
  5 | public export
  6 | data Literal
  7 |   = MkIdentifier
  8 |   | MkInt
  9 |   | MkFloat
 10 |   | MkImag
 11 |   | MkChar
 12 |   | MkString
 13 |
 14 | export
 15 | implementation Show Literal where
 16 |   show = \case
 17 |     MkIdentifier => "IDENT"
 18 |     MkInt => "INT"
 19 |     MkFloat => "FLOAT"
 20 |     MkImag => "IMAG"
 21 |     MkChar => "CHAR"
 22 |     MkString => "STRING"
 23 |
 24 | public export
 25 | data Operator
 26 |   = MkAdd
 27 |   | MkSub
 28 |   | MkMul
 29 |   | MkQuo
 30 |   | MkRem
 31 |   | MkAnd
 32 |   | MkOr
 33 |   | MkXor
 34 |   | MkShl
 35 |   | MkShr
 36 |   | MkAndNot
 37 |   | MkAddAssign
 38 |   | MkSubAssign
 39 |   | MkMulAssign
 40 |   | MkQuoAssign
 41 |   | MkRemAssign
 42 |   | MkAndAssign
 43 |   | MkOrAssign
 44 |   | MkXorAssign
 45 |   | MkShlAssign
 46 |   | MkShrAssign
 47 |   | MkAndNotAssign
 48 |   | MkLogicalAnd
 49 |   | MkLogicalOr
 50 |   | MkArrow
 51 |   | MkInc
 52 |   | MkDec
 53 |   | MkEql
 54 |   | MkLess
 55 |   | MkGreater
 56 |   | MkAssign
 57 |   | MkNot
 58 |   | MkNotEql
 59 |   | MkLessThanOrEqual
 60 |   | MkGreaterThanOrEqual
 61 |   | MkDefine
 62 |   | MkEllipsis
 63 |   | MkLParen
 64 |   | MkLBracket
 65 |   | MkLBrace
 66 |   | MkComma
 67 |   | MkPeriod
 68 |   | MkRParen
 69 |   | MkRBracket
 70 |   | MkRBrace
 71 |   | MkSemicolon
 72 |   | MkColon
 73 |
 74 | export
 75 | implementation Show Operator where
 76 |   show = \case
 77 |     MkAdd => "+"
 78 |     MkSub => "-"
 79 |     MkMul => "*"
 80 |     MkQuo => "/"
 81 |     MkRem => "%"
 82 |     MkAnd => "&"
 83 |     MkOr => "|"
 84 |     MkXor => "^"
 85 |     MkShl => "<<"
 86 |     MkShr => ">>"
 87 |     MkAndNot => "&^"
 88 |     MkAddAssign => "+="
 89 |     MkSubAssign => "-="
 90 |     MkMulAssign => "*="
 91 |     MkQuoAssign => "/="
 92 |     MkRemAssign => "%="
 93 |     MkAndAssign => "&="
 94 |     MkOrAssign => "|="
 95 |     MkXorAssign => "^="
 96 |     MkShlAssign => "<<="
 97 |     MkShrAssign => ">>="
 98 |     MkAndNotAssign => "&^="
 99 |     MkLogicalAnd => "&&"
100 |     MkLogicalOr => "||"
101 |     MkArrow => "<-"
102 |     MkInc => "++"
103 |     MkDec => "--"
104 |     MkEql => "=="
105 |     MkLess => "<"
106 |     MkGreater => ">"
107 |     MkAssign => "="
108 |     MkNot => "!"
109 |     MkNotEql => "!="
110 |     MkLessThanOrEqual => "<="
111 |     MkGreaterThanOrEqual => ">="
112 |     MkDefine => ":="
113 |     MkEllipsis => "..."
114 |     MkLParen => "("
115 |     MkLBracket => "["
116 |     MkLBrace => "{"
117 |     MkComma => ","
118 |     MkPeriod => "."
119 |     MkRParen => ")"
120 |     MkRBracket => "]"
121 |     MkRBrace => "}"
122 |     MkSemicolon => ";"
123 |     MkColon => ":"
124 |
125 | public export
126 | Precedence : Type
127 | Precedence = Fin 8
128 |
129 | export
130 | precedence : Operator -> Precedence
131 | precedence = \case
132 |   MkLogicalOr => 1
133 |   MkLogicalAnd => 2
134 |   MkEql => 3
135 |   MkNotEql => 3
136 |   MkLess => 3
137 |   MkLessThanOrEqual => 3
138 |   MkGreater => 3
139 |   MkGreaterThanOrEqual => 3
140 |   MkAdd => 4
141 |   MkSub => 4
142 |   MkOr => 4
143 |   MkXor => 4
144 |   MkMul => 5
145 |   MkQuo => 5
146 |   MkRem => 5
147 |   MkShl => 5
148 |   MkShr => 5
149 |   MkAnd => 5
150 |   MkAndNot => 5
151 |   _ => last
152 |
153 | public export
154 | data Keyword
155 |   = MkBreak
156 |   | MkCase
157 |   | MkChan
158 |   | MkConst
159 |   | MkContinue
160 |   | MkDefault
161 |   | MkDefer
162 |   | MkElse
163 |   | MkFallthrough
164 |   | MkFor
165 |   | MkFunc
166 |   | MkGo
167 |   | MkGoto
168 |   | MkIf
169 |   | MkImport
170 |   | MkInterface
171 |   | MkMap
172 |   | MkPackage
173 |   | MkRange
174 |   | MkReturn
175 |   | MkSelect
176 |   | MkStruct
177 |   | MkSwitch
178 |   | MkType
179 |   | MkVar
180 |
181 | export
182 | implementation Show Keyword where
183 |   show = \case
184 |     MkBreak => "break"
185 |     MkCase => "case"
186 |     MkChan => "chan"
187 |     MkConst => "const"
188 |     MkContinue => "continue"
189 |     MkDefault => "default"
190 |     MkDefer => "defer"
191 |     MkElse => "else"
192 |     MkFallthrough => "fallthrough"
193 |     MkFor => "for"
194 |     MkFunc => "func"
195 |     MkGo => "go"
196 |     MkGoto => "goto"
197 |     MkIf => "if"
198 |     MkImport => "import"
199 |     MkInterface => "interface"
200 |     MkMap => "map"
201 |     MkPackage => "package"
202 |     MkRange => "range"
203 |     MkReturn => "return"
204 |     MkSelect => "select"
205 |     MkStruct => "struct"
206 |     MkSwitch => "switch"
207 |     MkType => "type"
208 |     MkVar => "var"
209 |
210 | public export
211 | implementation Eq Keyword where
212 |   MkBreak == MkBreak = True
213 |   MkCase == MkCase = True
214 |   MkChan == MkChan = True
215 |   MkConst == MkConst = True
216 |   MkContinue == MkContinue = True
217 |   MkDefault == MkDefault = True
218 |   MkDefer == MkDefer = True
219 |   MkElse == MkElse = True
220 |   MkFallthrough == MkFallthrough = True
221 |   MkFor == MkFor = True
222 |   MkFunc == MkFunc = True
223 |   MkGo == MkGo = True
224 |   MkGoto == MkGoto = True
225 |   MkIf == MkIf = True
226 |   MkImport == MkImport = True
227 |   MkInterface == MkInterface = True
228 |   MkMap == MkMap = True
229 |   MkPackage == MkPackage = True
230 |   MkRange == MkRange = True
231 |   MkReturn == MkReturn = True
232 |   MkSelect == MkSelect = True
233 |   MkStruct == MkStruct = True
234 |   MkSwitch == MkSwitch = True
235 |   MkType == MkType = True
236 |   MkVar == MkVar = True
237 |   _ == _ = False
238 |
239 | public export
240 | keywords : List (String, Keyword)
241 | keywords = map (\a => (show a, a))
242 |   [ MkBreak
243 |   , MkCase
244 |   , MkChan
245 |   , MkConst
246 |   , MkContinue
247 |   , MkDefault
248 |   , MkDefer
249 |   , MkElse
250 |   , MkFallthrough
251 |   , MkFor
252 |   , MkFunc
253 |   , MkGo
254 |   , MkGoto
255 |   , MkIf
256 |   , MkImport
257 |   , MkInterface
258 |   , MkMap
259 |   , MkPackage
260 |   , MkRange
261 |   , MkReturn
262 |   , MkSelect
263 |   , MkStruct
264 |   , MkSwitch
265 |   , MkType
266 |   , MkVar
267 |   ]
268 |
269 | export
270 | getKeyword : String -> Maybe Keyword
271 | getKeyword str = List.lookup str keywords
272 |
273 | public export
274 | data Additional
275 |   = MkTilde
276 |
277 | export
278 | implementation Show Additional where
279 |   show = \case
280 |     MkTilde => "~"
281 |
282 | public export
283 | data Token
284 |   = MkIllegal
285 |   | MkEOF
286 |   | MkComment
287 |   | MkLiteralToken Literal
288 |   | MkOperatorToken Operator
289 |   | MkKeywordToken Keyword
290 |   | MkAdditionalToken Additional
291 |
292 | export
293 | implementation Show Token where
294 |   show = \case
295 |     MkIllegal => "ILLEGAL"
296 |     MkEOF => "EOF"
297 |     MkComment => "COMMENT"
298 |     MkLiteralToken l => show l
299 |     MkOperatorToken o => show o
300 |     MkKeywordToken k => show k
301 |     MkAdditionalToken a => show a
302 |
303 | export
304 | isLiteral : Token -> Bool
305 | isLiteral = \case
306 |   MkLiteralToken _ => True
307 |   _ => False
308 |
309 | export
310 | isOperator : Token -> Bool
311 | isOperator = \case
312 |   MkOperatorToken _ => True
313 |   MkAdditionalToken MkTilde => True
314 |   _ => False
315 |
316 | export
317 | isKeyword : Token -> Bool
318 | isKeyword = \case
319 |   MkOperatorToken _ => True
320 |   _ => False
321 |
322 | export
323 | lookup : String -> Token
324 | lookup str =
325 |   let Just keyword = getKeyword str
326 |         | Nothing => MkLiteralToken MkIdentifier
327 |   in MkKeywordToken keyword
328 |