summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorLibravatar Martin Michalec <martin@michalec.dev>2026-02-22 03:18:01 +0000
committerLibravatar Martin Michalec <martin@michalec.dev>2026-02-22 03:18:01 +0000
commitf404d75c6050223a3cbbe9b7775700ca291ff93d (patch)
treecbcec3fec884901b11e32def54f539d3a8a6eb3b /examples
parentadd lexer implementation (diff)
downloadrs274ngc-f404d75c6050223a3cbbe9b7775700ca291ff93d.tar.gz
add lex example
Diffstat (limited to 'examples')
-rw-r--r--examples/lex.c67
-rw-r--r--examples/utils.c77
-rw-r--r--examples/utils.h64
3 files changed, 208 insertions, 0 deletions
diff --git a/examples/lex.c b/examples/lex.c
new file mode 100644
index 0000000..a0f33e7
--- /dev/null
+++ b/examples/lex.c
@@ -0,0 +1,67 @@
1// examples/lex.c
2
3#include <stddef.h>
4#include <stdio.h>
5#include <fcntl.h>
6#include <unistd.h>
7
8#define CMMM__RS274NGC__LEXEME__STRIP_VENDOR
9#define CMMM__RS274NGC__LEXER__STRIP_VENDOR
10
11#include "utils.h"
12#include "cmmm/rs274ngc/lexer.h"
13
14int
15main (int argc, char *argv[])
16{
17 const char *filename;
18 struct cmmm__sv rs274ngc;
19 struct cmmm__arena a = {0};
20
21 if (argc == 1) {
22 filename = "-";
23 rs274ngc = read_until_eof (&a, 0);
24 } else if (argc == 2) {
25 filename = argv[1];
26 int fd = open (filename, O_RDONLY);
27 rs274ngc = mmap_whole (fd);
28 } else {
29 exit (EXIT_FAILURE); // TODO(cmmm): better DIE
30 }
31
32 // printf (SV_FMT, SV_FMTA (rs274ngc));
33 // return 0;
34
35 struct rs274ngc__lexer lexer =
36 rs274ngc__lexer__from_string_view (rs274ngc, filename);
37
38 int line = 1;
39 const char *bol = lexer.lexeme.sv.begin;
40 for (;; rs274ngc__lexer__next_lexeme (&lexer)) {
41 struct rs274ngc__lexeme lexeme = lexer.lexeme;
42
43 if (lexeme.kind == RS274NGC__LEXEME__KIND__END_OF_FILE) {
44 printf ("%s:%d:%ld: %s\n",
45 lexer.filename, line, lexeme.sv.begin - bol,
46 rs274ngc__lexeme__kind_names[lexeme.kind]);
47 break;
48 };
49
50 if (lexeme.kind == RS274NGC__LEXEME__KIND__END_OF_LINE) {
51 printf ("%s:%d:%ld: %s\n",
52 lexer.filename, line, lexeme.sv.begin - bol + 1,
53 rs274ngc__lexeme__kind_names[lexeme.kind]);
54 bol = lexeme.sv.end;
55 line += 1;
56 continue;
57 }
58
59 printf ("%s:%d:%ld-%ld: %s: |"SV_FMT"|\n",
60 lexer.filename, line, lexeme.sv.begin - bol + 1, lexeme.sv.end - bol,
61 rs274ngc__lexeme__kind_names[lexeme.kind], SV_FMTA (lexeme.sv));
62 }
63
64 return EXIT_SUCCESS;
65}
66
67// examples/lex.c ends here
diff --git a/examples/utils.c b/examples/utils.c
new file mode 100644
index 0000000..35c8d98
--- /dev/null
+++ b/examples/utils.c
@@ -0,0 +1,77 @@
1// examples/utils.c
2
3#include <stddef.h>
4#include <sys/stat.h>
5#include <sys/mman.h>
6#include <string.h>
7#include <errno.h>
8#include <unistd.h>
9#include <fcntl.h>
10
11#include "utils.h"
12
13struct cmmm__sv
14mmap_whole (int fd)
15{
16 struct cmmm__sv sv;
17
18 struct stat st;
19 int ret = fstat (fd, &st);
20 UNUSED (ret);
21 ASSERT_MSG (ret != -1, "fstat: %s", strerror (errno));
22 ASSERT (S_ISREG (st.st_mode));
23
24 posix_fadvise (fd, 0, st.st_size, POSIX_FADV_SEQUENTIAL |
25 POSIX_FADV_WILLNEED |
26 POSIX_FADV_NOREUSE);
27
28 sv.begin = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE |
29 MAP_POPULATE |
30 MAP_NONBLOCK, fd, 0);
31 ASSERT_MSG (sv.begin != MAP_FAILED, "mmap: %s", strerror (errno));
32 posix_madvise ((void *) sv.begin, st.st_size, MADV_HUGEPAGE | MADV_WILLNEED);
33
34 sv.end = sv.begin + st.st_size;
35
36 return sv;
37}
38
39struct cmmm__sv
40read_until_eof (ARENA arena, int fd)
41{
42 struct arena__checkpoint checkpoint = arena__checkpoint (arena);
43 size_t reserve = 4096;
44
45 size_t read_total = 0;
46 for (;;) {
47 arena__reserve (arena, reserve, 1);
48 ssize_t bytes_read = read (fd,
49 arena__next_free (arena, 1),
50 arena__room (arena, 1));
51
52 if (bytes_read < 0) {
53 DEBUG ("fstat: %s", strerror (errno));
54 arena__rollback_to (arena, checkpoint);
55 return (struct cmmm__sv) {0};
56 }
57
58 if (bytes_read == 0)
59 break;
60
61 read_total += bytes_read;
62
63 arena__allocate_fast (arena, bytes_read, 1);
64 reserve *= 2;
65 }
66
67 if (arena->tail->free == checkpoint.free)
68 return (struct cmmm__sv) {0};
69
70 char *ptr = arena__coalesce_from_fast (arena, checkpoint, read_total);
71 return (struct cmmm__sv) {
72 .begin = ptr,
73 .end = ptr + read_total,
74 };
75}
76
77// examples/utils.c ends here
diff --git a/examples/utils.h b/examples/utils.h
new file mode 100644
index 0000000..dc48a85
--- /dev/null
+++ b/examples/utils.h
@@ -0,0 +1,64 @@
1// examples/utils.h
2
3#ifndef INCLUDED_UTILS_H
4#define INCLUDED_UTILS_H
5
6#include <stdlib.h>
7#include <stdio.h>
8
9#define CMMM__STRING_VIEW__STRIP_VENDOR
10#define CMMM__STRING_VIEW__SHORT_NAMESPACE
11#define CMMM__ARENA__STRIP_VENDOR
12
13#include "cmmm/string-view.h"
14#include "cmmm/arena.h"
15
16#define NOP() do {} while (0)
17
18#define UNUSED(EXP) ((void) EXP)
19
20#define ARRAY_LENGTH(ARR) (sizeof (ARR)/sizeof (*(ARR)))
21
22#ifndef NDEBUG
23#include <assert.h>
24#define ASSERT assert
25#else
26#define ASSERT(...) NOP ()
27#endif
28
29#define STRINGIFY(ARG) #ARG
30#define TO_STRING(ARG) STRINGIFY (ARG)
31
32#ifndef NDEBUG
33#define DEBUG(FMT, ...) \
34 fprintf (stderr, __FILE__ ":" TO_STRING (__LINE__) ": %s: " FMT "\n", \
35 __func__ __VA_OPT__ (,) __VA_ARGS__)
36#define LOG(FMT, ...) \
37 fprintf (stderr, __FILE__ ":" TO_STRING (__LINE__) ": %s: " FMT "\n", \
38 __func__ __VA_OPT__ (,) __VA_ARGS__)
39#else
40#define DEBUG(...) NOP ()
41#define LOG(FMT, ...) \
42 fprintf (stderr, FMT "\n", __VA_OPT__ (,) __VA_ARGS__)
43#endif
44
45#define ERROR(FMT, ...) LOG ("error: " FMT __VA_OPT__ (,) __VA_ARGS__)
46#define WARNING(FMT, ...) LOG ("warning: " FMT __VA_OPT__ (,) __VA_ARGS__)
47#define NOTICE(FMT, ...) LOG ("notice: " FMT __VA_OPT__ (,) __VA_ARGS__)
48#define INFO(FMT, ...) LOG ("info: " FMT __VA_OPT__ (,) __VA_ARGS__)
49
50#ifndef NDEBUG
51#define ASSERT_MSG(EXP, FMT, ...) do if (!(EXP)) { \
52 DEBUG (FMT __VA_OPT__ (,) __VA_ARGS__); \
53 exit (EXIT_FAILURE); \
54 } while (0)
55#else
56#define ASSERT_MSG(EXP, FMT, ...) NOP ()
57#endif
58
59struct cmmm__sv mmap_whole (int fd);
60struct cmmm__sv read_until_eof (ARENA, int fd);
61
62#endif // INCLUDED_UTILS_H
63
64// examples/utils.c ends here