MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
lexer.h
Go to the documentation of this file.
1#pragma once
2
3#include <absl/container/flat_hash_map.h>
4#include <fe/lexer.h>
5
6#include "mim/ast/tok.h"
7
8namespace mim::ast {
9
10namespace fs = std::filesystem;
11
12class AST;
13
14class Lexer : public fe::Lexer<3, Lexer> {
15 using Super = fe::Lexer<3, Lexer>;
16
17public:
18 /// Creates a lexer to read `*.mim` files (see [Lexical Structure](@ref lex)).
19 /// If @p md is not `nullptr`, a Markdown output will be generated.
20 Lexer(AST&, std::istream&, const fs::path* path = nullptr, std::ostream* md = nullptr);
21
22 AST& ast() { return ast_; }
23 const fs::path* path() const { return loc_.path; }
24 Tok lex();
25
26private:
27 char32_t next() {
28 auto res = Super::next();
29 if (md_ && out_) {
30 if (res == fe::utf8::EoF) {
31 *md_ << "\n```\n";
32 out_ = false;
33 } else if (res) {
34 bool success = fe::utf8::encode(*md_, res);
35 assert_unused(success);
36 }
37 }
38 return res;
39 }
40
41 Tok tok(Tok::Tag tag) { return {loc_, tag}; }
42 Sym sym();
43 bool lex_id();
44 char8_t lex_char();
45 std::optional<Tok> parse_lit();
46 void parse_digits(int base = 10);
47 bool parse_exp(int base = 10);
48 void eat_comments();
49 bool start_md() const { return ahead(0) == '/' && ahead(1) == '/' && ahead(2) == '/'; }
50 void emit_md(bool start_of_file = false);
51 void md_fence() {
52 if (md_) *md_ << "```\n";
53 }
54
55 AST& ast_;
56 std::ostream* md_;
57 bool out_ = true;
58 fe::SymMap<Tok::Tag> keywords_;
59
60 friend class fe::Lexer<3, Lexer>;
61};
62
63} // namespace mim::ast
Lexer(AST &, std::istream &, const fs::path *path=nullptr, std::ostream *md=nullptr)
Creates a lexer to read *.mim files (see Lexical Structure).
Definition lexer.cpp:12
AST & ast()
Definition lexer.h:22
const fs::path * path() const
Definition lexer.h:23
Definition ast.h:14