summaryrefslogtreecommitdiff
path: root/src/token.h
blob: e99294e18481ec39190bcd161ba78c82cfa24be6 (plain)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#ifndef INCLUDE_token
#define INCLUDE_token

#include <string.h>

/* Token and type definitions shared by lexer, parser, and JIT.
 * The type system uses a base kind plus pointer/array decorations. */
typedef enum {
  TY_INT = 0,
  TY_CHAR = 1,
  TY_BOOL = 2,
} _TYBASE;

typedef struct {
  _TYBASE base;   /* TY_INT, TY_CHAR */
  int ptr_level;  /* 0 for non-pointer, 1 for T*, 2 for T**, ... */
  int array_size; /* -1 for non-array, 0 for unknown size [], >0 for fixed size [N] */
} _TY;

static inline const char *tybase_name(_TYBASE b) {
  switch (b) {
  case TY_INT: return "int";
  case TY_CHAR: return "char";
  case TY_BOOL: return "bool";
  default: return "?";
  }
}

#define _TL(_)                                                                 \
  _(TK_BEGIN, "begin")                                                         \
  _(TK_INT, "int")                                                             \
  _(TK_CHAR, "char")                                                           \
  _(TK_ASSIGN, "=")                                                            \
  _(TK_EQ, "==")                                                               \
  _(TK_NE, "!=")                                                               \
  _(TK_LT, "<")                                                                \
  _(TK_LE, "<=")                                                               \
  _(TK_GT, ">")                                                                \
  _(TK_GE, ">=")                                                               \
  _(TK_RETURN, "return")                                                       \
  _(TK_IF, "if")                                                               \
  _(TK_ELSE, "else")                                                           \
  _(TK_FOR, "for")                                                             \
  _(TK_WHILE, "while")                                                         \
  _(TK_BOOL, "bool")                                                           \
  _(TK_IDENT, "ident")                                                         \
  _(TK_NUMBER, "number")                                                       \
  _(TK_CHARLIT, "charlit")                                                     \
  _(TK_LPAREN, "(")                                                            \
  _(TK_RPAREN, ")")                                                            \
  _(TK_LBRACE, "{")                                                            \
  _(TK_RBRACE, "}")                                                            \
  _(TK_SEMI, ";")                                                              \
  _(TK_PLUS, "+")                                                              \
  _(TK_MINUS, "-")                                                             \
  _(TK_STAR, "*")                                                              \
  _(TK_SLASH, "/")                                                             \
  _(TK_PERCENT, "%")                                                           \
  _(TK_AMP, "&")                                                               \
  _(TK_AND, "&&")                                                              \
  _(TK_BAR, "|")                                                               \
  _(TK_OR, "||")                                                               \
  _(TK_CARET, "^")                                                             \
  _(TK_SHL, "<<")                                                              \
  _(TK_SHR, ">>")                                                              \
  _(TK_BANG, "!")                                                              \
  _(TK_SQUOTE, "'")                                                            \
  _(TK_DQUOTE, "\"")                                                           \
  _(TK_LBRACKET, "[")                                                          \
  _(TK_RBRACKET, "]")                                                          \
  _(TK_STRING, "string")                                                       \
  _(TK_EOF, "eof")                                                             \
  _(TK_COMMA, ",")                                                             \
  _(TK_INVALID, "invalid")                                                     \
  _(TK__COUNT, "<count>")

typedef enum {
#define MAKE_ENUM(_, s) _,
  _TL(MAKE_ENUM)
#undef MAKE_ENUM
} _TK;

static const char *_TN[] = {
#define MAKE_STR(_, s) s,
    _TL(MAKE_STR)
#undef MAKE_STR
};

typedef struct {
  _TK kind;
  int val;    // only valid if kind == TK_NUMBER
  char *lxem; // malloc’d lexeme string, or NULL
} _T;

static _TK checkkw(const char *kw) {
#define _(k, s)                                                                \
  if (strcmp(kw, s) == 0)                                                      \
    return k;
  _TL(_)
#undef _
  return TK_IDENT;
}

#endif /* INCLUDE_token */